Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
e0298cf
T085: openDox's own defaults for the two doxBench seams, and the work…
brettheap Oct 2, 2026
83213eb
T085: answer the same rail under the status-exemption lock (Copilot r…
brettheap Oct 2, 2026
ef0c554
T081, 16.4: "no model configured" is a state, shown before any turn (…
brettheap Oct 2, 2026
0a12dc5
T081: a turn with no model port is refused before step 5 reads the sc…
brettheap Oct 2, 2026
38a4bba
T081: probe the rail's remedy verdict over a failure beside an empty …
brettheap Oct 2, 2026
9061b22
T081: the remedy is for an EMPTY catalog and is announced; test the t…
brettheap Oct 2, 2026
947411f
T082, 16.5: every other surface works with no model (plan 034)
brettheap Oct 2, 2026
92275fc
T082: a whole-corpus check names only what the corpus lists
brettheap Oct 2, 2026
dcdb755
T082: re-pin the triple's floors, three below two greens of one tree
brettheap Oct 2, 2026
7332be5
Merge main into T082 after T081, T079, T080 and T070 landed (main 113…
brettheap Oct 3, 2026
c002fac
Merge main e49b17c3 (T084, openDox-code#77) into T082: remove the fiv…
brettheap Oct 3, 2026
7af4c99
T082: T084's scope-default settings set reads the single declaration
brettheap Oct 3, 2026
87a753a
Merge main 390e2c28 (T103, openDox-code#80) into T082
brettheap Oct 3, 2026
c670377
T082: re-pin the CI floors from two greens of 87a753a8
brettheap Oct 3, 2026
7a02206
T082: the twin home-factory docstrings name the settings exclusion
brettheap Oct 3, 2026
a25606b
Merge main 0116293a (T102, openDox-code#81) into T082
brettheap Oct 3, 2026
0b0f038
T082: re-pin the CI floors from two greens of a25606bb
brettheap Oct 3, 2026
47e8bb9
T082: generation keeps the no-omp PATH; check()'s docstring states it…
brettheap Oct 3, 2026
c6689c5
T082: set per-process values aside on /capabilities only
brettheap Oct 3, 2026
9948dc2
Merge main c4b55cc4 (T102 follow-on, openDox-code#85) into T082
brettheap Oct 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,31 @@ jobs:
# margin lets through is up to three tests that stop being
# COLLECTED at all, and a lost file is dozens of tests, never
# three.
MIN_SELECTED: "2476"
MIN_PASSED: "2465"
#
# RE-PINNED BY plan 034 T082 (Copilot at openDox-code#76 947411fd,
# r4170556888). Since T037, the cases added by later changes had
# left these floors where they were, so the declared three-test
# margin had grown to several hundred. T082 adds 34 cases and
# re-pins by the rule above: three below the lower of two greens
# of one tree. The tree is `a25606bb`, T082 after merging `main`
# at `0116293a` (T084, T103 and T102 included). Read from run
# 37152269851: attempt 1 (job 111288409713) and its re-run (job
# 111296677742). Both printed `triple: selected=3980 passed=3969
# skipped=11 failures=0 errors=0`, so no jitter was measured, and
# three below is 3977 / 3966. A local run of the same tree read
# 3803 passed and 177 skipped (3980 selected), with no PostgreSQL
# service, so the runtime cases skip there. That is a check, not
# the source.
MIN_SELECTED: "3977"
MIN_PASSED: "3966"
# EXACT — the load-bearing number. Moves only with its reason.
#
# HELD AT 11 by plan 034 T082. While T082 was stacked ahead of T084
# this pin read 16: five of `tests/test_chat_model_configuration.py`'s
# 16.5 cases ran as strict xfails naming T084, and JUnit writes an
# xfail as a skip. T084 landed (openDox-code#77, `e49b17c3`), T082
# merged `main` and removed the five markers in that merge, and the
# five now pass. So T082 adds no skip.
EXPECT_SKIPPED: "11"
run: |
python3 - <<'PY' > triple.env
Expand Down
13 changes: 8 additions & 5 deletions src/opendox/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@
# below, beside `build_parser()`.
# Neither module names `openxdox` or `ideation_dashboard`, so this import adds
# no reach: `corpus_adapter` is stdlib-only (F4.1's own scan proves it), and
# `local_git_adapter` names only `opendox.runtime.config` and
# `opendox.corpus_adapter` besides the stdlib.
# `local_git_adapter` names only `opendox.runtime.config`,
# `opendox.corpus_adapter` and `opendox.doxbench_intake` (itself stdlib-only,
# with the `doxbench_binding` it reads; plan 034 T082) besides the stdlib.
from opendox import corpus_adapter # noqa: E402
from opendox.runtime import local_git_adapter # noqa: E402
# THE INSTALL SHAPE (plan 034 T070; #1144 13.4-13.6): `generate-and-open`
Expand Down Expand Up @@ -1305,9 +1306,11 @@ def _default_home_factory(root):
already shows worktree bytes, so the standalone default matches it rather
than reading the session's git HEAD. `WorkingTreeCorpus`
(`local_git_adapter.py`) is `LocalGitCorpus` with `list_documents`/`read`
aimed at the filesystem instead of a resolved commit; see its own
docstring for what stays unchanged (`resolve`, `classify`, `check`,
`write_back`) and what does not.
aimed at the filesystem instead of a resolved commit, and with openDox's
own settings documents (`doxbench_intake.SETTINGS_DOCUMENTS`, plan 034
T082) left out of its listing and out of a whole-corpus `check`; see its
own docstring for what stays unchanged (`resolve`, `classify`,
`write_back`, and a `check` of named subjects) and what does not.

A FRESH ADAPTER EVERY CALL, ON PURPOSE: nothing here is held onto across
calls, so there is no listing cache keyed on whatever HEAD was at an
Expand Down
10 changes: 5 additions & 5 deletions src/opendox/default_columns.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,10 @@
from opendox import defaults
from opendox.column_seams import GATE_RECORDS_REFUSAL
# openDox's OWN SETTINGS DOCUMENTS, never a tile's editable material (plan 034
# T084, adversarial review 2, M1). Both modules are stdlib-only at import.
from opendox.doxbench_binding import DEFAULT_BINDINGS_RELPATH
from opendox.doxbench_intake import DEFAULT_DECLARATIONS_RELPATH
# T084, adversarial review 2, M1). Imported, not copied: the list is declared
# once, beside the two paths it names (plan 034 T082). `doxbench_intake` is
# stdlib-only at import.
from opendox.doxbench_intake import SETTINGS_DOCUMENTS as _SETTINGS_DOCUMENTS
from opendox.boundary import GATE_SIDE_EFFECT, BoundaryViolation, HumanGate, Refusal
from opendox.doxbench_scope_types import (
ScopeConfinementError,
Expand Down Expand Up @@ -367,8 +368,7 @@ def _section(key: str, label: str, note: str, references: Iterable[Any], *,
#: refuses them whatever section carries them. An in-root symlink that reaches
#: one is treated as the document it reaches (`_settings_test`). The corpus
#: scan's own exclusion (openDox-code#76) is a second layer, not this one.
SETTINGS_DOCUMENTS: frozenset[str] = frozenset({
DEFAULT_BINDINGS_RELPATH, DEFAULT_DECLARATIONS_RELPATH})
SETTINGS_DOCUMENTS: frozenset[str] = frozenset(_SETTINGS_DOCUMENTS)

_SETTINGS_SECTION = ("settings", "openDox's own settings documents",
"the install's settings: readable here, and never "
Expand Down
14 changes: 14 additions & 0 deletions src/opendox/doxbench_intake.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,20 @@
#: install has approved and which are still waiting on a human.
DEFAULT_DECLARATIONS_RELPATH = "ideation/dashboard/model-declarations.yaml"

#: openDox's OWN SETTINGS DOCUMENTS, at their default paths: the model bindings
#: (`doxbench_binding.DEFAULT_BINDINGS_RELPATH`) and the declarations above.
#: Each lives in the served checkout on purpose, where its operator can read
#: and commit it. But each is a model's configuration and not one of the user's
#: documents, so openDox's standalone corpus default lists neither: this is
#: the default of `runtime.local_git_adapter.WorkingTreeCorpus`'s `excluded`.
#: Configuring a model then changes no document, no generated snapshot and no
#: view (#1144 16.5, "every other surface ... answers exactly as it does with a
#: model configured"; plan 034 T082). Without this rule, `opendox model-binding
#: add` added its own bindings document to the corpus as a `source` document. A
#: host that brings its own corpus adapter decides for itself.
SETTINGS_DOCUMENTS: tuple[str, ...] = (
binding_mod.DEFAULT_BINDINGS_RELPATH, DEFAULT_DECLARATIONS_RELPATH)

#: How long an approval is good for. A POLICY CONSTANT, not an operator input:
#: `credential-contracts` holds that a grant without `expires_at` is invalid, and
#: an expiry a requester chooses is an expiry that is always far away. Ninety
Expand Down
66 changes: 62 additions & 4 deletions src/opendox/runtime/local_git_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@
from typing import IO

from opendox.runtime import config
# openDox's own settings documents, which `WorkingTreeCorpus` (the standalone
# default) leaves out of its listing (plan 034 T082). Imported, not copied: the
# list is declared once, beside the two paths it names. `doxbench_intake` and
# the `doxbench_binding` it reads import the standard library only, so this
# module still costs the standard library alone to import.
from opendox.doxbench_intake import SETTINGS_DOCUMENTS
from opendox.corpus_adapter import (
CORPUS_ABSENT,
CORPUS_READ_ONLY,
Expand Down Expand Up @@ -3013,8 +3019,10 @@ class WorkingTreeCorpus(LocalGitCorpus):
matches it instead of reading a commit a local session has since edited
past.

`resolve()`, `check()` and `write_back()` are UNCHANGED, inherited from
`LocalGitCorpus` exactly. So is `classify()`: its header read
`resolve()` and `write_back()` are UNCHANGED, inherited from
`LocalGitCorpus` exactly. So is `check()`, except that a WHOLE-corpus
check leaves out the paths `excluded` names (see below). So is
`classify()`: its header read
(`_header_of`) goes THROUGH `self.read()`, which is why overriding `read`
alone is enough to make classification see the same bytes this adapter
lists and serves. Only WHERE `list_documents`/`read` get their bytes
Expand Down Expand Up @@ -3081,15 +3089,65 @@ class WorkingTreeCorpus(LocalGitCorpus):
`WorkingTreeCorpus()`, hands every standalone caller an adapter whose
`classify` obliges them, and `authoring.required_header_fields()` answers
them. Nothing else about the class changes: a document without them is
still listed and read, and `classify` reports what is missing."""
still listed and read, and `classify` reports what is missing.

OPENDOX'S OWN SETTINGS DOCUMENTS ARE NOT LISTED (plan 034 T082; #1144
16.5, RULED by the holder 2026-10-02, option (a)). `excluded` names the
paths the listing leaves out, by EXACT corpus-relative key, whether the
file is tracked or untracked and whatever revision the listing reads. Its
default is `doxbench_intake.SETTINGS_DOCUMENTS`: the model bindings
document and the intake declarations document, at their default paths.
`opendox model-binding add` writes the first into the checkout, where its
operator can read and commit it. Before this rule it joined the corpus as
a `source` document, so the snapshot, the generated output and every view
changed the moment a model was configured. This class's only constructor
is openDox's standalone default (`cli.py`'s and `serve.py`'s
`_default_home_factory`), so the default is that default's rule. A host
that brings its own corpus adapter decides for itself, and `excluded=()`
lists everything. A path left out is still a file, and the source route
still serves it by name: the rule is about what the corpus LISTS, not
what exists."""

def __init__(self, *, executable: str = "git",
write_path: str | None = WRITE_PATH,
kind_field: str | None = None,
required_fields: tuple[str, ...] = NEUTRAL_FIELDS) -> None:
required_fields: tuple[str, ...] = NEUTRAL_FIELDS,
excluded: tuple[str, ...] = SETTINGS_DOCUMENTS) -> None:
super().__init__(executable=executable, write_path=write_path,
kind_field=kind_field,
required_fields=required_fields)
self._excluded = frozenset(excluded)

def list_documents(self, corpus: ResolvedCorpus,
scope: str = SCOPE_ALL) -> tuple[DocumentId, ...]:
"""The parent's listing, minus `excluded`. Applied here, after both
of `_list_documents_bound`'s branches, so a pinned revision leaves
the same paths out as the working tree does."""
listed = super().list_documents(corpus, scope)
if not self._excluded:
return listed
return tuple(d for d in listed if d.key not in self._excluded)

def check(self, corpus: ResolvedCorpus,
subjects: tuple[DocumentId, ...] | None = None) -> tuple[Finding, ...]:
Comment thread
brettheap marked this conversation as resolved.
"""The parent's verdict, over the documents this corpus LISTS.

`subjects=None` means the whole corpus (`CorpusAdapter.check`), and
an excluded path is not in the corpus this class lists. So a finding
on an excluded path is left out of a whole-corpus check, and an
edited, committed bindings document is not reported as an uncommitted
document the corpus does not hold (Copilot at openDox-code#76,
r4170556938). THAT IS ALL THIS FILTER DOES: every other finding the
parent reports stands as it did before T082, including one on a
tracked path deleted from the working tree, which the listing omits
(`_list_documents_bound`) and the parent's diff still reports as a
divergence from the resolved commit. A subject the caller NAMES is
answered whether or not it is excluded: asking about one file by name
is not asking about the corpus."""
findings = super().check(corpus, subjects)
if subjects is not None or not self._excluded:
return findings
return tuple(f for f in findings if f.subject not in self._excluded)

def _list_documents_bound(self, git: GitRunner, corpus: ResolvedCorpus,
scope: str) -> tuple[DocumentId, ...]:
Expand Down
8 changes: 5 additions & 3 deletions src/opendox/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -1913,9 +1913,11 @@ def _default_home_factory(root):
already shows worktree bytes, so the standalone default matches it rather
than reading the session's git HEAD. `WorkingTreeCorpus`
(`local_git_adapter.py`) is `LocalGitCorpus` with `list_documents`/`read`
aimed at the filesystem instead of a resolved commit; see its own
docstring for what stays unchanged (`resolve`, `classify`, `check`,
`write_back`) and what does not.
aimed at the filesystem instead of a resolved commit, and with openDox's
own settings documents (`doxbench_intake.SETTINGS_DOCUMENTS`, plan 034
T082) left out of its listing and out of a whole-corpus `check`; see its
own docstring for what stays unchanged (`resolve`, `classify`,
`write_back`, and a `check` of named subjects) and what does not.

A FRESH ADAPTER EVERY CALL, ON PURPOSE: nothing here is held onto across
calls, so there is no listing cache keyed on whatever HEAD was at an
Expand Down
Loading
Loading