You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
T007 batch P: the rulings of 5982436447 in #1144 (12.4a's hint line and history limit, 16.3a's in-repo refusal and served-repo limit, F16.1's note) and the T100 follow-on (plan 034) - #1230
This PR is bookkeeping only (T007 batch P). It records in #1144 (add-neutral-product-standalone-operability) what Brett Heap's multi-choice word of 2026-10-04, and the holder's rulings recorded with it, imply. It also carries the plan-034 lines that follow from them. Plan 034 was read at maind0af2574, which follows batch O's landing (#1228 → 596a9a90). The branch merges main0e01ca85, which is #1231 (T083's evidence; T082, T083 and T100 ticked).
RULED (Brett Heap, multiple choice, 2026-10-04): three findings from the holder's adversarial reviews of T104 (openDox-code#84) and T100 (openDox-code#82, landed as 38d3350e). […]
#656 comment 5982436447, and its extension on this PR's review, 5983805990: "Refuse inline scripts (Recommended)", with the holder's ruling 5984069416 applying it to launcher chains, and the holder's 5985046107 (C1 and C4, after an adversarial review of openDox-code#86) applying both to launcher grammar and option values, and the holder's 5985553609 reading "a real file" by what it forbids to run. The T100 follow-on's claim is 5982447319, and this batch's is 5983109372.
This PR adds six AMENDED — T007 Batch P paragraphs to #1144's tasks.md, plus a third dated note to requirement 17 in the spec delta. Each paragraph goes after the last addendum at its site, and none edits ratified text.
12.4a, after batch N's (item 1, B3). Ubuntu's default snap browser, a Flatpak browser and a Windows browser opened from WSL cannot open the private copy's file:// URL while the state directory is the hidden default. The token is never printed, so such a browser has no other way in.
The start prints ONE more line, with no token and no URL that carries one. It says that such a browser should be used with OPENDOX_STATE_DIR set to a folder that is not hidden.
The openDox root's README documents it, and release 1 ships with the limit.
Nothing else in batch N's addendum moves. Carried out by T104 (the line) and T076 (the README).
12.4a, after the first (the holder's B7). The page drops the fragment with history.replaceState, which cleans only session history. A browser's persistent history can still keep …/index.html#console_token=<token>.
That history is the same user's data as the 0600 copy, so it is an accepted limit, with no code change.
The fragment still never reaches a request line, a server log or a Referer. Carried out by T104.
16.3a, after batch M's text (item 2, A2). A trust names a digest of the binding's record, so a trusted binding whose broker runs an in-repo program stayed trusted after a pull changed the program.
The rule: a binding's command may not name a file inside the served repository, so the broker lives outside it. Every member of the command is judged, the program and each argument alike, so a script handed to an outside interpreter is caught; a relative path is judged against the served root.
Such a binding is refused by name where trust is recorded (add, edit, trust, set-credential) and where it is checked, before any spawn, and it reads untrusted. The refusal names the remedy.
Wrappers (5983805990). Brett's second word, asked on Copilot's r4179024140, extends the rule:
a binding whose program is a shell or an interpreter given an inline script (sh -c, bash -c, python -c, node -e) is refused the same way;
the program must be a real file outside the served repository, read by what it forbids to run (the holder's 5985553609): an inline script or a file inside the repository is refused at trust and before any spawn, while a program that cannot be found runs nothing, is not refused at trust, and is refused as broker_unreachable when its start fails (a trust-time existence check stays open for Brett, and F16.1 has no case for it). Every path the command names, the program and each argument alike, is judged both as named and as it resolves (links followed, a bare program name looked up on PATH, a relative path against the root), when trust is recorded and before any spawn;
a common launcher (env, nice, nohup, timeout, stdbuf, setsid, xargs and the like) is unwrapped to the program it starts, which those rules then judge (the holder's ruling 5984069416, implementing 5983805990). Its own options are judged with it, read by GNU getopt_long's grammar (the holder's 5985046107, C1 and C4): a long option by its unambiguous prefix (env --chd=… is --chdir), an ambiguous or unknown one refused by name; an option that names a path (env --chdir/-C, xargs -a/--arg-file, in any spelling) is judged as the command's paths are, so a launcher can neither start the broker inside the repository nor let the repository decide its arguments; and the string env -S carries is split and judged only when it holds no backslash and no $, and is otherwise refused as unreadable, as an inline script is;
every broker starts with its working directory outside it and with an environment that points away from it: no PWD, OLDPWD or other variable naming a path inside it, and no path-list entry (PATH, PYTHONPATH, …) inside it, each judged as named and as resolved;
a launcher's own assignment (env NAME=value) whose value is a path inside the repository, or a path list with an entry inside it, is refused by name, not dropped, at trust and before any spawn;
a path given to the program that finally runs as an option's value, after = (--require=<repo>/x) or attached to a single-dash option (-I<repo>/lib), is judged and refused inside the repository, an output path too (5985046107, C4);
an accepted release-1 limit: a general program outside the repository that runs code from its own arguments (awk, find -exec), and any other path embedded inside an option string given to the program that finally runs (NODE_OPTIONS=--require=…), never a launcher's own option, are not judged by the argv check, since the trusted argv is digested and the working directory and environment point away from the repository;
sh -c "pass show key" becomes ["pass", "show", "key"].
Carried out by the T100 follow-on, an openDox-code PR with no task of its own, which lands before T087.
16.3a, after the first (item 3, A14). It clarifies "No trust is ever written into, or read from, a tree a clone could carry": that tree is the SERVED repository.
A state directory inside some OTHER git checkout is an accepted release-1 limit, with no code change. A check for any enclosing checkout would refuse a home directory kept in git, which holds the default state directory.
Carried out by T100, as landed.
F16.1, after batch M's block (the holder's A8), a note with no line changed. The block already says that with a directory that holds the trust file replaced by a symbolic link, every binding reads untrusted.
T100 as landed (38d3350e) read a state directory that is itself a symbolic link to this user's own 0700 directory. Its suite's case passed only because the target was writable by others.
F16.1, after the A8 note (item 2, A2's cases). The command is unchanged. Batch M's named file, tests/test_model_binding_trust.py, also asserts three things:
a binding whose command names a file under the served root, as its program or as an interpreter's script argument (absolute and relative), is refused by add, edit, trust and set-credential, and the refusal names the remedy;
a trust recorded before the rule does not admit that binding, before or after its program is edited: the catalog lists it with available: false, a turn is refused before any spawn, and no marker file appears;
an inline-script wrapper (["sh", "-c", "exec ./tools/broker.py"], python -c, and through each named launcher in an option-bearing form, ["env", "-i", "python3", "-c", "…"], nice -n 5, nohup, timeout -s KILL 5, stdbuf -oL, setsid -w, xargs -n 1, a nested chain, and a string that env -S splits) is refused the same way, with no marker file, and a pre-rule trust of it reads untrusted (available: false);
an alias is judged both as named and as it resolves, for the program and an interpreter's script argument alike: a link outside the root into it, a bare name resolved through a PATH entry under the root, and an in-repo link that points outside are each refused, and an earlier trust does not admit them (available: false);
a broker that is a real file outside the repository is still reached, and it starts with its working directory outside the served root and with no variable or path-list entry naming a path inside it. The test starts opendox at the served root, with PATH, PYTHONPATH and NODE_PATH entries and a scalar variable inside it, so an inherited one would show. A launcher's own assignment or working-directory option naming a path inside the root (env PYTHONPATH=tools …, env --chdir=<root> …, env -C <root> …, and each through both alias directions) is refused, with no marker file.
four commands from 5985046107 (C1 and C4), each refused by name with no marker file: perl -I<root>/lib <outside>/broker.pl and xargs -a <root>/args <outside>/broker and env --chd=<root> <outside>/broker, each as a command that names a file inside the served repository, and env -S 'sh\_-c\_id' as an inline script, since the split string is unreadable. Four more, from 5985046107's other clauses: <outside>/broker --config=<root>/conf and <outside>/broker -o<root>/out (an option's = value, and an output path, the accepted strictness), each as a command that names a file inside the served repository, and env --i <outside>/broker and env --d <outside>/broker (ambiguous) and env --no-such-option <outside>/broker (unknown), each refused by name, fail-closed. And the rest of C1's test list, each refused as an inline script: a bundled env -iS "python3 -c '…'", timeout --sig KILL 5 python3 -c … and stdbuf --out=L python3 -c … (not as unknown options), and env -S '$BROKER'. That last one is written without braces, because a binding refuses any {name} outside its closed placeholder vocabulary when it is declared, so ${VAR} would be refused by that rule first.
These cases fail until the follow-on lands. T089 runs them at T087's pin.
Requirement 17, spec delta, a third dated note after batch M's, in the form batches K and M used: "AMENDED 2026-10-04 ON BRETT HEAP'S RULING, AFTER RATIFICATION, BY ITS OWN RATIFIER (T007 BATCH P)", citing 5982436447 item 2 and 5983805990. A2 narrows one sentence of batch M's note: "turns reach a configured endpoint once its configuration is trusted". The new note records that a configuration whose command names a file inside the served repository is refused even when it is trusted. The same holds when its program is a shell or an interpreter given an inline script. The program must be a real file outside the served repository, and every broker starts outside it. It says the title, the SHALL paragraph, the notes of batches K and M, and all four scenarios stand. It adds one paragraph and edits no ratified line. This is in its own commit, 843db317, on the holder's word ("A2 note: yes").
Where each ruling goes.
A2 (a dated note and task-line addenda). It narrows one sentence of batch M's dated note in requirement 17, so it takes a dated note there in batch M's form, beside its addenda at 16.3a and F16.1. Copilot's review at 44755f30 and the holder agreed.
The rest (task-line addenda only). The spec delta has no sentence that B3, B7, A14 or A8 narrows:
The state-directory rule is 16.3a's own text. Batch M's note says only that trust lives "in the operator's own state, never in the repository".
No requirement or scenario names the console token's delivery.console_token, file:// and OPENDOX_STATE_DIR each occur 0 times in the spec delta.
A8 changes no line.
Plan 034
T007:
§ Format: sixteen batches, T007.A to T007.P;
"What can start" and T007's intro;
the per-batch citations;
batch P's bullet and its Ruled: entry;
its After, by batch line. It names the landing by slice: P3-P's pin, which carries P3-C's openDox-code#84 and P3-T's follow-on. A task id in that field would read as a predecessor;
T100's new "Follow-on" bullet. It names A2 and A8, and A14 as a limit with no code change. T100's Ruled: line cites 5982436447;
T101's After: note;
T087's note.
T104: a bullet records B3 (the hint line, and T076's README), B2 (refuse by name on a platform without the POSIX primitives, as openDox-code#69 does) and B7. Its falsifier's start-print case adds B3's hint line, with no token. Its Ruled: line cites 5982436447.
T083 landed ticked in T083: 16.6 and F16.1 at openDox-code 38d3350e; tick T082, T083 and T100 (plan 034) #1231, with its F16.1 run at 38d3350e. Batch P therefore keeps T083 as landed and adds one bullet to its entry. The bullet says the run predates the T100 follow-on, so it shows neither F16.1's batch P cases nor A8's case as ruled: that case passed there only because the link's target was writable by others. T089's run at T087's pin covers both.
The box table reads F16.1 → T083 (at 38d3350e), T089 (batch P's cases, at T087's pin).
plan.md's graph line, its phase-3 lanes paragraph, tasks.md's phase table and the follow-on bullet say the same.
Earlier heads of this PR (15b4cb7c to c1b7da6c) had T083 wait for the follow-on, which was Copilot's first option on r4178868158. With T083 landed, the merge 626207e3 switches to Copilot's second option: narrow T083's run and map the valid run to T089.
T076: a bullet, a review criterion and a Ruled: citation for B3's README text: the browser limit and the OPENDOX_STATE_DIR remedy. The P3-O row names the same. openDox#17's head 554e97ec already carries the text.
F16.1 everywhere it is named (T089, the checkpoint row, plan.md's release map, spec.md's US3 independent test): "as batches M and P amend it".
spec.md's US3 scenario 6 excludes a binding whose command names a file inside the served repository, citing batch P's note. FR-009 states A2 as batch P's note reads it, and SC-003's F16.1 includes batch P's A2 cases.
T087: its After: gains T007 (batch P: …), and the P3-P row's depends on cell gains T007 batch P. Batch P lands before T087, and so before T089.
The rest of tasks.md:
the phase-0 order;
the phase-3 slice intro;
§ "Ruled amendments": its heading, its intro (batch P adds a third note to requirement 17), two P rows (12.4a; requirement 17, 16.3a and F16.1), and a closing sentence. That sentence says B2 needs no File add-neutral-product-standalone-operability: open the BUILD arc, recording ten rulings #1144 line, because 12.4a already requires a start to be refused by name when no safe copy can be written.
spec.md: a new "Session 2026-10-04" under Clarifications. It records the three answers and the holder's B2, B7 and A8, in the form of the sessions before it, and says which batch records them.
plan.md:
batches A–P in the graph;
the PHASE 3 line;
T087's graph line: after batch P and the T100 follow-on;
the amendments list, and why P lands before T087;
Principle V's "A to P", which cites this batch's gate.
Gates
Each gate ran at 051f9945, the head, and at mainc8d80020 (#1232), which 93de1054 merges, and at cc39e235 (on the identical tree of aaa99be8, before a message-only amend), bcdb185e, d08249a2, fbc4254b, 7b11ce8f, bb9e46b7, 739a72f0, 90d6ba93 and 84113a44 against the same main. It also ran at 6fe3dcba, 907b97bd, ec4655d2, 1bcbc592, b87df185, 93014cbe, 18576c29, dbea008e, b5f31eea, bb39c313, 29254ad5, 5fd7478f, b74c9d0d, 6efccad2, 70885b61 and 626207e3 against main0e01ca85, which 626207e3 merges, and earlier at c1b7da6c, bf8d587b, 843db317, 15b4cb7c and bd4345a5 against maind0af2574. Every run used two full clones of the same kind. Each clone sits in a directory named openxFactory, with remote.origin.url set to opensoft/openxFactory.
validate-code-surface.py, validate-target-release.py and validate-pin-registrations.py;
validate-document-catalog.py, with 0 errors and 0 warnings.
pytest -q tests/doc-health/test_modified_block_currency_self_gate.py tests/sequenced_after reports 306 passed at bd4345a5, at 843db317 (the spec-delta note), at bf8d587b, at c1b7da6c, at 626207e3, at 70885b61, at 6efccad2, at b74c9d0d, at 5fd7478f, at 29254ad5, at bb39c313, at b5f31eea, at dbea008e, at 18576c29, at 93014cbe, at b87df185, at 1bcbc592, at ec4655d2, at 907b97bd, at 6fe3dcba, at 84113a44, at 90d6ba93, at 739a72f0, at bb9e46b7, at 7b11ce8f, at fbc4254b, at d08249a2, at bcdb185e, at cc39e235 and at 051f9945.
The plan's consistency checks. Brett-wip 64462366 widens the persisted parser in opensoft/brett-wip (handoffs/xFactory/attachments/lane-opendox/r1plan/tools/) to batch P, in the form of batch O's 55abdb2e: BATCHES = "ABCDEFGHIJKLMNOP", every [A-O] made [A-P], plus its docstring and the README line. Batch P adds no single-writer file, so the chain tools are unchanged.
The A–O parser reads mainc8d80020 at 96 tasks, 111 nodes and 272 edges.
The widened tools read this branch at 96 tasks, 112 nodes and 274 edges. The two new edges are T087 → T007.P and T007 → T007.P. The tools also find:
no cycles, as written or with the Lands-with groups merged;
0 chain gaps, and 47 chaindirect pairs;
0 of 83 arrow mismatches;
no phase gaps (T099 follows T089 by design);
in sharedfiles, 5 pairs NOT ORDERED, the same as on main;
qcheck 27 of 27.
The widened parser refuses main until this PR lands ("names no line for ['P']"), as it did for batches K to O.
Review
Copilot at
verdict
threads
answered in
257133ac
Changes recommended
T083 could close F16.1 on a run at 38d3350e, where A8's case passes for the wrong reason (r4178868158)
15b4cb7c: T083's F16.1 run follows the follow-on; the F16.1 note says a run at 38d3350e closes nothing. Answered and resolved
15b4cb7c
Changes recommended
plan.md's graph and lanes (r4178882493) and tasks.md's phase-3 order (r4178882527) still put T083 straight after T100
44755f30: every summary names the follow-on before T083. Both answered and resolved
44755f30
Needs a closer look, no findings
two previously-missed notes: A2 narrows batch M's requirement-17 note; T076's task text lacks B3's README work
f656b065 (T076, P3-O) and 843db317 (the third dated note, on the holder's "A2 note: yes"). Answered on the PR
843db317
Changes recommended
the body still said no spec-delta sentence was narrowed (r4178915635); two previously-missed notes: F16.1 had no A2 case, and US3 scenario 6 still reached a trusted in-repo broker
bf8d587b: F16.1's A2 cases, US3 scenario 6 narrowed, and this body rewritten. Answered and resolved, and on the PR
bf8d587b
Changes recommended
T007's intro still counted five #1144 paragraphs (r4178935172)
586fa2c9: it counts six, two at F16.1, plus the requirement-17 note. Answered and resolved
586fa2c9
Changes recommended
SC-003 named F16.1 only with batch M's line (r4178956099)
c1b7da6c: SC-003 names batch P's A2 cases, and FR-009 states A2 as batch P's note reads it. Answered and resolved
c1b7da6c
(reviewed with the merge)
—
626207e3 merges main0e01ca85 (#1231) and points batch P at T089's run, since T083 landed ticked
b475b95b
Changes recommended
F16.1's case for a pre-rule trust of an in-repo binding did not assert available: false (r4178971358, r4179006472)
70885b61: it reads untrusted, listed available: false, and a turn is refused before any spawn. Both answered and resolved
70885b61
Changes recommended
a shell or interpreter wrapper (sh -c 'exec ./tools/broker.py') evades A2's argv path check (r4179024140)
asked of the holder, and Brett ruled "Refuse inline scripts (Recommended)" (5983805990); 6efccad2 records it in 16.3a, F16.1's cases, requirement 17's note and the plan. Answered and resolved
6efccad2
Changes recommended
a lexical check passes a link or a PATH entry that leads into the root, and the working-directory case could pass vacuously (r4179109720)
b74c9d0d: the program is judged by the path it resolves to, at recording and before spawn; F16.1 gains both aliases; the working-directory case starts opendox at the served root. Answered and resolved
b74c9d0d
Changes recommended
an in-repo link pointing outside could be retargeted by a pull (r4179123170); the gate record stopped at 6efccad2 (r4179123179)
5fd7478f: the named path and the resolved path both lie outside, and F16.1 gains the reverse link; every gate re-run at 5fd7478f and cited here. Both answered and resolved
5fd7478f
Changes recommended
a script handed to an outside interpreter (["python3", "tools/broker.py"]) escapes a program-only check (r4179138294)
29254ad5: every member of the command is judged, a relative path against the served root; F16.1 tests the interpreter's script argument, absolute and relative. Answered and resolved
29254ad5
Changes recommended
the alias cases exercised only the program, so an outside link into the root passed as an interpreter's script argument (r4179152884)
bb39c313: every path the command names is judged as named and as resolved; F16.1's alias case covers the program and the script argument alike. Answered and resolved
bb39c313
Needs a closer look, no findings
one previously-missed note: the inline-script case did not assert that a pre-rule trust reads untrusted
b5f31eea: it reads untrusted, available: false, as the direct in-repo case does. Answered on the PR
b5f31eea
Changes recommended
a launcher chain (["/usr/bin/env", "python3", "-c", "…"]) carries an inline script past the wrapper rule (r4179187252)
asked of the holder, who ruled 5984069416; 277b9578 and dbea008e record it: launchers unwrapped, PWD/OLDPWD dropped, argument-running programs an accepted limit. Answered and resolved
dbea008e
Changes recommended
PYTHONPATH and the like could still load in-repo code (r4179236753); only an env chain was tested (r4179249042); a previously-missed note: FR-009 lacked the named-and-resolved rule for arguments
18576c29: the environment drops every variable and path-list entry inside the repository; the launcher case runs over all six named launchers with options; FR-009 states the rule. Answered and resolved
18576c29
Changes recommended
no nested launcher chain was tested (r4179270459); the environment case planted only PATH and PYTHONPATH (r4179270489)
93014cbe: a nested chain (env nice -n 5 timeout 5 python3 -c …), and NODE_PATH plus a scalar variable inside the root. Both answered and resolved
93014cbe
Changes recommended
environment paths were judged only as named, so an outside link into the root in PYTHONPATH or a scalar variable would pass (r4179290208)
c419a75f and b87df185: environment paths are judged as named and as resolved, with outside-link fixtures for a path-list entry and a scalar variable. Answered and resolved
b87df185
Changes recommended
loader options such as NODE_OPTIONS=--require=…, inherited or set by env, could still load in-repo code (r4179308849)
1bcbc592, under the holder's standing rule: a launcher's assignments are judged as the environment is (F16.1 adds env PYTHONPATH=tools), and a path embedded inside an option string joins the recorded limit. Answered and resolved
1bcbc592
Changes recommended
the fixture named a host-absolute path, /outside/broker.py (r4179329854); a previously-missed note: FR-009 lacked the resolved-environment and assignment rules
ec4655d2: the fixture names a mktemp -d scratch directory, and FR-009 carries both rules. Answered and resolved
ec4655d2
Changes recommended
the assignment case had no alias (r4179346502); FR-009 lacked the option-string limit (r4179346514); previously-missed notes: /bin/sh and /usr/bin/env in the added examples (Principle IV)
907b97bd: aliased PYTHONPATH and scalar assignments, FR-009's limit, and bare sh and env. Answered and resolved
907b97bd
Changes recommended
the environment fixtures lacked the reverse link (r4179366541)
6fe3dcba: an in-repo link pointing outside, for a PYTHONPATH entry and a scalar, inherited and assigned. Answered and resolved
6fe3dcba
Changes recommended
the option-string limit also covered a known launcher's own options, so env --chdir=<root> python3 <outside>/broker.py started the broker inside the repository against the working-directory rule (r4179386143, r4179386206, r4179386250)
93de1054 merges mainc8d80020 (#1232); 84113a44, under the holder's 5984069416: a launcher's own options are judged with it (env --chdir/-C as a command path, env -S split before it is judged), the limit covers only options given to the program that finally runs, and F16.1 adds the --chdir cases (both forms, both alias directions) and an env -S case. Answered and resolved
84113a44
Changes recommended
the gate record stopped at 6fe3dcba (r4179522953)
this body: every gate re-ran at 84113a44 against mainc8d80020, all identical to main. No file changed. Answered and resolved
84113a44 (again)
Changes recommended
the option-string limit still exempted a path attached to a single-dash option of the final program (-I<repo>/lib), which the holder's later 5985046107 (C4) refuses (r4179629725)
90d6ba93 mirrors 5985046107's C1 and C4 in 16.3a, requirement 17's note, FR-009, F16.1, the session record, the T100 follow-on bullet and the P row: launcher options by GNU getopt_long (ambiguous or unknown refused), xargs -a judged, env -S split only without a backslash or $, and option values after = or attached to a single-dash option judged. F16.1 gains four commands, each with its expected refusal. Answered and resolved
90d6ba93
Changes recommended
F16.1 had no command for a final program's --option=<root>/… value or the output-path strictness (r4179671883), and none for an ambiguous or unknown launcher option (r4179671907)
739a72f0: <outside>/broker --config=<root>/conf, <outside>/broker -o<root>/out, env --i <outside>/broker and env --no-such-option <outside>/broker, each with its expected refusal. Both answered and resolved
739a72f0
Needs a closer look, no findings
two previously-missed notes: F16.1's launcher inline-script case did not run through xargs, which 16.3a now names; a missing relative pronoun in the T100 follow-on bullet's env -S clause
bb9e46b7: ["xargs", "-n", "1", "python3", "-c", "…"] joins the launcher list, and the clause reads "a string that env -S splits". Answered on the PR
bb9e46b7
Needs a closer look, no findings
one previously-missed note: F16.1 lacked the rest of 5985046107's C1 test list (--d, a ${VAR} split string, a bundled -iS, and timeout and stdbuf abbreviations)
7b11ce8f: all five, each with its expected refusal; the $ case is written $BROKER, since the binding's closed placeholder vocabulary refuses {VAR} first. Answered on the PR
7b11ce8f
Needs a closer look, no findings
two previously-missed notes: batch P required "a real file" at trust while openDox-code#86 refuses a missing program only when its start fails; FR-009's code-from-arguments limit read on in-repo programs and inline scripts
asked of the holder, who ruled (a) 5985553609: "a real file" is read by what it forbids to run, a missing program is refused as broker_unreachable when its start fails, and a trust-time check stays open for Brett; fbc4254b records it in 16.3a, requirement 17's note, FR-009, the session record, the T100 bullet and the P row. 1c78a6bd scopes FR-009's limit to a general program outside the repository, never an inline script, and 371d2150 rewraps one line. Answered on the PR
fbc4254b
Changes recommended
requirement 17's note concluded a trusted configuration needs a real-file broker, which batch H's brokerless env:/keyring and none paths do not run (r4179784787); the session record called the trust-time check open beside "Nothing is open" (r4179784816); its provenance summary omitted 5985553609 (r4179784832)
d08249a2: the conclusion binds a configuration that runs a credential broker, and one that runs none is outside the note; the check is no open work of release 1; the summary lists 5985553609. All three answered and resolved
d08249a2
Needs a closer look, no findings
two previously-missed notes: requirement 17's note said a launcher's assignments are "judged as the environment is", which could read as dropping them while F16.1 and FR-009 refuse them; the T100 follow-on bullet lacked the assignment refusal and the option-string limit
bcdb185e: the note says an in-repository env NAME=value is refused by name, not dropped, and the bullet carries the refusal and the limit. Answered on the PR
bcdb185e
Changes recommended
requirement 17's note said "Such a configuration is refused" right after its accepted-limit sentence, so it read as refusing the accepted cases (r4179835039)
cc39e235: the note names the refused class (a command or launcher naming a path inside the repository, an inline script, an unreadable split string), its remedies, and says the accepted limits are not part of it. Answered and resolved
cc39e235
Changes recommended
the note's refused class left out an ambiguous or unknown launcher option (r4179861847); previously-missed notes: F16.1's PATH-entry alias ran as an interpreter's script argument, which no interpreter looks up on PATH; P3-P's slice row did not name the T100 follow-on
051f9945: the refused class lists all three kinds; the PATH alias is the program's case only; P3-P's cell names the follow-on. The thread answered and resolved, the notes answered on the PR
For the holder
The third dated note to requirement 17 (843db317) follows your "A2 note: yes". It is its own commit, so you can review or drop it alone.
Where batch P lands. P lands before T087, so it delays neither openDox-code PR.
T102's follow-on has landed (openDox-code#85 → c4b55cc4). Plan 034 still records it as a PR to come. That record is outside this batch, and the next ticks PR can update it.
A launcher's own options, under your standing rule. Copilot's three threads at 6fe3dcba found env --chdir=<root> under the option-string limit, which would start the broker inside the repository. Your 5984069416 unwraps launchers "with their flags" and keeps the working directory outside the repository, so 84113a44 judges a launcher's own path options as command paths, and the limit covers only options given to the program that finally runs. My env -S addition at 84113a44 is now governed by your 5985046107 (C1): the string is split and judged only when it holds no backslash and no $, and is otherwise refused as unreadable.
5985046107 mirrored (90d6ba93). C1 and C4 are in all six places you named and in the session record. C2, C3 and C5 are openDox-code#86's code and change no text here. F16.1's four new commands name the refusal each expects: a file inside the served repository for perl -I, xargs -a and env --chd=, and an inline script for the unreadable env -S. Those are openDox-code#86's REASON_IN_REPOSITORY and REASON_INLINE_SCRIPT at 96ae8816. 739a72f0 adds four more on Copilot's request: an option's = value and an output path (a file inside the served repository), and an ambiguous and an unknown env option, which F16.1 says only are "refused by name, fail-closed", as the ruling does. openDox-code#86 has no reason for that refusal yet, and F16.1 names none. 7b11ce8f adds the rest of C1's test list (--d, -iS, timeout --sig, stdbuf --out=, and a $ split string). The ${VAR} form can't go through F16.1's four commands, because a binding's closed placeholder vocabulary refuses {VAR} when it is declared, before any broker rule. So F16.1 uses $BROKER, which the same C1 clause refuses as unreadable. The braced form stays a test for openDox-code#86's own unit level.
"A real file", your 5985553609 (a). It is in 16.3a, requirement 17's note and FR-009, and cited in the P row. One wording choice is mine. Your ruling says a missing program is refused "before any spawn" by broker_unreachable. At openDox-code#86's 96ae8816, that refusal ("the credential broker could not be started") comes from subprocess.Popen raising OSError, which is the start failing. So batch P says it is refused "when its start fails". Nothing runs either way. A broker installed later is judged before it is started, like any other.
Landing
It touches openspec/changes/, so it lands under a Rule 6 LANDING/LANDED window. It is bookkeeping, so it carries no Arc: trailer (R1Q20 (a)) and no closing keyword. The holder posts READY and lands it.
Record batch P's rulings and align the standalone-operation specification, trust requirements, tests, documentation, and execution plan with the resulting broker-safety and browser-accessibility limits.
New Features:
Document the accepted browser-accessibility limit and its OPENDOX_STATE_DIR remedy for standalone console startup.
Record the new trust restrictions requiring credential brokers to run from real files outside the served repository, including inline-script and launcher handling.
Add coverage for repository-path, wrapper, alias, environment, launcher-option, and linked-state-directory trust cases to the F16.1 specification.
Enhancements:
Clarify persistent browser-history and non-served-checkout state-directory limits.
Amend requirement 17 and related release criteria to reflect the new broker-trust rulings and accepted release-1 limits.
Update plan 034 with batch P, follow-on sequencing, dependency relationships, landing records, and validation ownership.
Documentation:
Record the 2026-10-04 rulings and their provenance in the feature specification and planning documents.
Update the root README deliverables and task records to include the browser limitation guidance.
Tests:
Expand the F16.1 test requirements to cover in-repository brokers, inline scripts, launcher chains, aliases, environment and working-directory isolation, option parsing, and symlinked state directories.
Chores:
Add T007 batch P bookkeeping across the OpenSpec change, task ledger, dependency graph, release map, and amendment tables.
…) and the T100 follow-on in plan 034 (plan 034)
Batch P records in #1144's tasks.md what Brett Heap's multi-choice word
of 2026-10-04 (5982436447) and the holder's rulings recorded with it
imply, as task-line addenda in T007's form. No requirement or scenario
text is narrowed, and no ratified line is edited.
- 12.4a, after batch N's: item 1, B3, "Hint line, accepted limit". Snap
and Flatpak browsers, and a Windows browser opened from WSL, cannot
open the private copy's file:// URL under the hidden default state
directory; the start prints one more line, with no token, naming
OPENDOX_STATE_DIR. And the holder's B7: persistent browser history
keeps the fragment, the same user's data as the 0600 copy, an accepted
limit.
- 16.3a, after batch M's text: item 2, A2, "Refuse in-repo programs". A
binding's command may not name a file inside the served repository.
And item 3, A14, "Served repo only, limit": the box's "a tree a clone
could carry" is the served repository; a state directory inside some
other git checkout is an accepted limit.
- F16.1, after batch M's block: the holder's A8, a note with no line
changed. A state directory that is itself a symbolic link trusts
nothing, as the block says, and the T100 follow-on aligns the code.
Plan 034 takes T007's batch-P bookkeeping (sixteen batches, P before
T087), records batch O's landing (#1228 -> 596a9a9), records the T100
follow-on as an openDox-code landing with no task, before T087 and T101's
version bump, in the form of T102's follow-on, notes B2, B3 and B7 in
T104, and adds spec.md's Session 2026-10-04.
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This bookkeeping PR adds T007 batch P to record the 2026-10-04 rulings in #1144, documenting console-token delivery/history limits, served-repository trust boundaries, and symlinked state-directory behavior, while propagating the new batch and T100 follow-on dependencies through plan 034 and the clarification record without changing ratified requirements or scenarios.
Sequence diagram for rejecting unsafe T100 bindings
sequenceDiagram
participant Operator
participant CLI
participant TrustStore
participant Broker
Operator->>CLI: add
CLI->>TrustStore: add
TrustStore-->>CLI: Refuse in-repo program
Operator->>CLI: trust
CLI->>TrustStore: trust
TrustStore-->>CLI: Refuse symlinked state directory
CLI->>Broker: spawn
Note over CLI,Broker: Spawn occurs only after validation
Loading
File-Level Changes
Change
Details
Files
Records the 2026-10-04 rulings and holder findings as five bookkeeping amendments to the ratified OpenSpec task text.
Adds the 12.4a hint-line accepted limit for browsers unable to open the private file URL, plus the persistent-history accepted limit.
Adds 16.3a clarifications forbidding broker programs inside the served repository and limiting the repository check to that served tree.
Adds the F16.1 note that a state directory that is itself a symlink trusts nothing.
Preserves ratified requirement and scenario text while linking each amendment to its implementing task or follow-on.
Connects the rulings to the T104 implementation, T076 README, and T100 follow-on.
specs/034-opendox-standalone-operation/spec.md
Tips and commands
Interacting with Sourcery
Trigger a new review: Comment @sourcery-ai review on the pull request.
Continue discussions: Reply directly to Sourcery's review comments.
Generate a GitHub issue from a review comment: Ask Sourcery to create an
issue from a review comment by replying to it. You can also reply to a
review comment with @sourcery-ai issue to create an issue from it.
Generate a pull request title: Write @sourcery-ai anywhere in the pull
request title to generate a title at any time. You can also comment @sourcery-ai title on the pull request to (re-)generate the title at any time.
Generate a pull request summary: Write @sourcery-ai summary anywhere in
the pull request body to generate a PR summary at any time exactly where you
want it. You can also comment @sourcery-ai summary on the pull request to
(re-)generate the summary at any time.
Generate reviewer's guide: Comment @sourcery-ai guide on the pull
request to (re-)generate the reviewer's guide at any time.
Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
pull request to resolve all Sourcery comments. Useful if you've already
addressed all the comments and don't want to see them anymore.
Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
request to dismiss all existing Sourcery reviews. Especially useful if you
want to start fresh with a new review - don't forget to comment @sourcery-ai review to trigger a new review!
… case passes at 38d3350e for the wrong reason (plan 034)
Copilot r4178868158: the follow-on was ordered only before T087 and
T101, so T083 could close F16.1 on a run at 38d3350e, where the case of
a state directory replaced by a symbolic link passes only because the
link's target is writable by others (the holder's A8). T083 now carries
a line ordering its F16.1 run after the follow-on (no task of the plan,
so outside the After field), the P3-N row says so, and T100's follow-on
bullet, batch P's bullet and its Ruled-amendments row name T083's run.
#1144's F16.1 note says the runs by T083 and T089 at a commit carrying
the follow-on hold the realization, and a run at 38d3350e closes
nothing.
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This new refusal narrows requirement 17's ratified batch-M note, contrary to the PR's claim that no spec-delta sentence is narrowed. That note still says turns reach an endpoint once the configuration is trusted (specs/neutral-product-standalone-operability/spec.md:686-688), but a trusted binding whose broker is in-repo must now be refused. Add the proposed dated note qualifying that promise; otherwise the ratified requirement and 16.3a prescribe conflicting behavior.
…-on (plan 034)
Copilot r4178882493 and r4178882527: plan.md's graph line and its
phase-3 lanes paragraph, and tasks.md's phase-3 order and phase table,
still put T083 straight after T100. Each now names the binding-trust
follow-on (no task) before T083, as T083's own line and the P3-N row
do. The graph line keeps its arrows task to task, so arrowcheck reads
0 of 83 mismatches.
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A2 does narrow the ratified requirement-17 note: the spec currently says that turns reach the endpoint once the configuration is trusted (specs/neutral-product-standalone-operability/spec.md:686–688), but this addendum refuses a still-trusted configuration when its command names an in-repository file. Leaving that sentence unchanged makes the spec and task contract disagree. Add a dated requirement-17 note qualifying endpoint reachability with this new command-location condition, as was done for the earlier trust ruling.
T076 omits README browser limitation and OPENDOX_STATE_DIR requirements
T076 does not actually include this README work. Its task at lines 2326–2349 only requires documenting the install/start command and its pre-cut stand-in; it never requires the browser limitation or OPENDOX_STATE_DIR workaround. As written, T076 can be completed while the README requirement recorded here is omitted. Add the wording and review criterion explicitly to T076 (and its P3-O summary).
…STATE_DIR remedy (plan 034)
Copilot's previously-missed note at 44755f3: batch P says the openDox
root's README documents B3's limit, but T076's task text never asked for
it. T076 gains a bullet (snap, Flatpak and WSL Windows browsers; set
OPENDOX_STATE_DIR to a folder that is not hidden; an accepted limit,
worded as T104's hint line), a review criterion in its falsifier, and
5982436447 item 1 in its Ruled line. The P3-O row names the same.
openDox#17's head 554e97ec already carries the text.
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…6447, item 2) (plan 034)
Copilot's previously-missed note at 44755f3, and the holder's word on
it ("A2 note: yes"): batch M's dated note says a trusted configuration's
turns reach its endpoint, and A2 refuses a trusted configuration whose
command names a file inside the served repository. The spec delta gains
a third dated note in requirement 17's body, after batch M's, in batch
K's and batch M's form: AMENDED 2026-10-04 ON BRETT HEAP'S RULING, AFTER
RATIFICATION, BY ITS OWN RATIFIER (T007 BATCH P). It narrows batch M's
note in that one respect, and says the title, the SHALL paragraph, batch
K's and batch M's notes and all four scenarios stand. It adds one
paragraph and edits no ratified line. #1144's 16.3a addendum, plan 034's
T007 lines, the P row, plan.md's amendments list and spec.md's Session
2026-10-04 name the note.
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A2 adds a security-relevant refusal, but the amendment explicitly leaves the falsifier unchanged. The existing F16.1 block only covers trust state, trust-file safety, and the served-root state-directory check; it never requires a trusted binding whose broker resolves inside the served repository to be rejected on each record/check path. T083 and T089 could therefore pass without proving this new rule. Amend F16.1 and the follow-on plan to name these cases.
Narrow US3 criterion 6 to exclude commands inside served repositories
This records that item 2 narrows the trusted-binding behavior, but US3 acceptance criterion 6 at lines 538–546 still says a binding trusted via add, edit, or trust is reached, without excluding a command inside the served repository. Narrow that criterion as well; otherwise this feature spec prescribes both reaching and refusing the same trusted binding.
…in-repo broker (plan 034)
Copilot's two previously-missed notes at 843db31:
- A2 had no falsifier: F16.1's runs by T083 and T089 could pass without
proving it. #1144's F16.1 gains a batch P addendum. The command is
unchanged; batch M's named file, tests/test_model_binding_trust.py,
also asserts that a binding whose command names a program under the
served root is refused by add, edit, trust and set-credential, naming
the remedy, that a trust recorded before the rule does not admit it
once the program is edited (no marker file), and that a broker outside
the repository is still reached. T100's follow-on bullet says its cases
extend that file. T083's falsifier, the T089 checkpoint, the P3-N and
checkpoint rows, plan.md's release map and graph line, and spec.md's
US3 independent test read "as batches M and P amend it". T083 waits on
T007 (batch P), and P now lands before T083 and T087.
- spec.md's US3 scenario 6 said a trusted binding is reached; it now
excludes one whose command names a file inside the served repository,
citing batch P's note and 5982436447 item 2.
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Answers to Copilot's "previously missed" notes on #1230. They are not threads, so they are answered here.
At 44755f30:
A2 narrows requirement 17's batch M note. Agreed, and the holder agreed ("A2 note: yes"). 843db317 adds a third dated note after batch M's, in the form batches K and M used. It records that a configuration whose command names a file inside the served repository is refused even when it is trusted. It says the title, the SHALL paragraph, the notes of batches K and M, and all four scenarios stand, and it edits no ratified line.
T076 lacked B3's README work.f656b065 gives T076 a bullet for the browser limit and its OPENDOX_STATE_DIR remedy, a review criterion, and 5982436447 item 1 in its Ruled: line. The P3-O row names the same.
an in-repo broker is refused by add, edit, trust and set-credential, and the refusal names the remedy;
a trust recorded before the rule does not admit that broker once its program is edited, and no marker file appears;
a broker outside the repository is still reached.
T100's follow-on bullet says its cases go in that file. T083 waits on T007 (batch P). Every reference to F16.1 now reads "as batches M and P amend it".
US3 scenario 6 still reached a trusted in-repo broker.bf8d587b narrows it. A binding declared or trusted is reached unless its command names a file inside the served repository. Such a binding is refused by name, both when trust would be recorded and before any spawn, citing batch P's note and 5982436447 item 2.
…(plan 034)
Copilot r4178935172: the intro still said five. Batch P adds six
AMENDED paragraphs to #1144's tasks.md (two at 12.4a, two at 16.3a, two
at F16.1: A8's note and A2's cases) and the third dated note to
requirement 17.
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…an 034)
Copilot r4178956099: SC-003, the phase-3 exit, named F16.1 only with
batch M's line. It now says that line's named file holds batch P's A2
cases too. FR-009, which restates requirement 17 as batches K and M read
it, also states A2 as batch P's note reads it: a binding whose command
names a file inside the served repository is refused by name even when
trusted, naming the remedy (5982436447, item 2; 16.3a).
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A line break left by 7b11ce8's heading edit; no word changed.
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…r's 5985553609 (plan 034)
Copilot's previously-missed note at 7b11ce8: batch P required "a real
file outside the served repository" when trust is recorded, while
openDox-code#86 refuses a program that cannot be found only when its
start fails. The holder's ruling 5985553609 (a) reads Brett's
5983805990 by what it forbids to RUN, narrowing and extending neither:
no configuration whose program is not a real file outside the served
repository ever runs. An inline script, or a file inside the repository
(as named and as resolved, through a launcher, a link, a PATH entry or
an option's value), is refused by name at trust and again before any
spawn, as batch P already says. A program that cannot be found runs
nothing: it is not refused at trust, and when its broker is started the
start fails and it is refused by the existing named refusal
broker_unreachable ("the credential broker could not be started", the
Popen OSError path at openDox-code#86's 96ae8816). A broker installed
later is judged before it is started, like any other. A trust-time
existence check stays open for Brett, as a follow-on that moves no box
of release 1, and F16.1 gains no missing-program case.
Recorded in #1144's 16.3a batch P addendum, requirement 17's batch P
dated note (rewrapped), FR-009, the session record, the T100 follow-on
bullet and Ruled line, and the Ruled-amendments P row (cites
5985553609).
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Copilot's two previously-missed notes at 7b11ce8f are fixed at fbc4254b.
Missing executables (tasks.md:3467). Asked of the holder, who ruled (a), 5985553609. Brett's "The program must be a real file outside the served repository" (5983805990) is read by what it forbids to RUN: no configuration whose program is not a real file outside the served repository ever runs. Concretely:
An inline script, or a file inside the repository (as named and as resolved, through a launcher, a link, a PATH entry or an option's value), is refused by name at trust and again before any spawn, as batch P already said.
A program that cannot be found runs nothing. It is not refused at trust. When its broker is started, the start fails and it is refused by the existing named refusal broker_unreachable ("the credential broker could not be started", the PopenOSError path at openDox-code#86's 96ae8816).
A broker installed later is judged before it is started, like any other.
A trust-time existence check stays open for Brett, as a follow-on that would move no release-1 box. F16.1 gains no missing-program case.
fbc4254b records this in 16.3a, requirement 17's batch P note, FR-009, the session record, the T100 follow-on bullet and Ruled line, and the Ruled-amendments P row, which cites 5985553609.
FR-009's blanket limit (spec.md:813). Fixed in 1c78a6bd. The limit now reads as the batch-P note and 16.3a do: a general program outside the repository that runs code from its own arguments (awk, find -exec), other than a shell or an interpreter given an inline script. It no longer contradicts FR-009's own SHALLs.
…ly; record notes (plan 034)
Copilot at fbc4254:
- r4179784787: requirement 17's batch P note concluded that a trusted
configuration reaches its endpoint "only when its broker is a real
file", which read as making a broker mandatory. Batch H lets a record
whose reference the built-in resolver takes (`env:`, the OS keyring)
run no broker, and the auth kind `none` forbids `broker_argv`. The
conclusion now binds a configuration that runs a credential broker,
and says a configuration that runs none is outside the note.
- r4179784816: the session record called the trust-time existence check
"open" beside "Nothing is open"; it now says it is no open work of
release 1, a possible follow-on for Brett Heap that moves no box.
- r4179784832: the provenance summary now lists the holder's 5985553609
beside 5984069416 and 5985046107.
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
“Judged as the environment is” points to the preceding behavior of dropping unsafe inherited variables/entries, but the batch-P falsifier requires an unsafe launcher assignment to be refused by add, edit, trust, and set-credential before any spawn (tasks.md:3819-3830), and FR-009 explicitly requires refusal. State that distinction here; otherwise the requirement note permits sanitizing env PYTHONPATH=tools … and continuing, while its falsifier requires rejection.
Clarify env assignment refusal and embedded option handling
The follow-on summary drops two required parts of the same rule: env NAME=value must be refused when it carries an in-repository scalar/path-list value, while other embedded option strings such as NODE_OPTIONS=--require=… remain an accepted limit. FR-009 (spec.md:803-821) and the authoritative 16.3a addendum (openspec/.../tasks.md:3521-3539) state both. Mirror them here so this task does not permit sanitizing an unsafe launcher assignment or imply that every embedded option path is inspected.
… note and the follow-on bullet (plan 034)
Copilot's previously-missed notes at d08249a:
- requirement 17's batch P note said a launcher's own assignments are
"judged as the environment is", which could read as dropping them,
while F16.1 and FR-009 refuse one. The note now says an `env
NAME=value` assignment whose value is a path inside the repository, or
a path list with an entry inside it, is not dropped but refused by
name, at trust and before any spawn, judged as named and as resolved.
- the T100 follow-on bullet now carries that refusal, and the accepted
limit for any other path embedded in an option string of the program
that finally runs (`NODE_OPTIONS=--require=…`), as FR-009 and 16.3a
state them.
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Copilot's two previously-missed notes at d08249a2 are fixed in bcdb185e:
Launcher assignments (requirement 17's note, spec.md:726). "Judged as the environment is" could be read as dropping an assignment. The note now says an env NAME=value assignment is not dropped but refused by name, at trust and again before any spawn, when its value is a path inside the repository or a path list with an entry inside it. Each is judged both as named and as it resolves. This matches F16.1's assignment cases and FR-009.
The T100 follow-on bullet (tasks.md:2878). It now carries both parts, as FR-009 and 16.3a state them:
the same refusal of an in-repository env NAME=value assignment (Copilot r4179308849);
the accepted release-1 limit for any other path embedded in an option string of the program that finally runs, such as NODE_OPTIONS=--require=….
…034)
Copilot r4179835039 at bcdb185: "Such a configuration is refused by
name" followed the accepted-limit sentence, so the note read as both
accepting those cases and refusing them. It now names the refused class:
a configuration whose command or launcher names a path inside the served
repository, or whose program is given an inline script or an unreadable
split string. Its remedy is a broker installed outside the repository,
or, for an inline script, the broker program named itself
(REMEDY_IN_REPOSITORY and REMEDY_INLINE_SCRIPT in openDox-code#86 at
96ae8816), and the accepted limits are not part of that class.
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The wording requires every listed alias to be tested as both the program and an interpreter’s script argument, but only argv[0] is resolved through PATH; python3 <script> and sh <script> do not search PATH for the script. Limit the PATH fixture to the program case while retaining both program/script coverage for the symlink fixtures, otherwise this test requirement cannot be implemented as written.
This issue also appears on line 3859 of the same file.
The slice table omits the T100 follow-on from T087’s dependencies, even though the T087 task and plan graph require that no-task landing before the pin. “Every phase-3 openDox-code slice” does not include this separate follow-on, so this row can schedule a pin that lacks batch P’s implementation. Add the follow-on explicitly to this cell.
… PATH alias is the program's; T087's slice names the follow-on (plan 034)
Copilot at cc39e23:
- r4179861847: requirement 17's note presented its refused class as
exhaustive and left out an ambiguous or unknown launcher option. It
now lists that too, says the refusal names its remedy, and says the
accepted limits are not refused by this note.
- a previously-missed note: F16.1's alias cases ran each alias for the
program and for an interpreter's script argument, but an interpreter
does not look its script argument up on PATH. The PATH-entry alias is
now the program's case only; both link cases keep both forms.
- a previously-missed note: the P3-P slice row's dependency cell said
"every phase-3 openDox-code slice", which does not include the T100
follow-on, a no-task landing. It now names the follow-on
(openDox-code#86) beside T007 batch P, as T087's entry and the plan
graph do.
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Copilot's two previously-missed notes at cc39e235 are fixed in 051f9945:
The PATH alias fixture (tasks.md:3799). An interpreter does not look its script argument up on PATH, so F16.1's PATH-entry alias case is now for the program only. The two symbolic-link alias cases still run both as the program and as ["python3", "<link>"]. I found no second PATH fixture at line 3859; that line holds the env -S and option-value cases, which name no PATH lookup.
T087's slice row (tasks.md:4190). P3-P's dependency cell now names the T100 follow-on (openDox-code#86, no task) beside T007 batch P, as T087's entry and the plan graph already do. The plan tools still read 96 tasks, 112 nodes and 274 edges, with 0 of 83 arrow mismatches.
READY at 051f994 — Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Holder: T007 batch P. It is bookkeeping, with no Arc trailer, and records in #1144 the rulings of 5982436447, A2's launcher rule (5983805990, 5984069416), the adversarial review's C1 and C4 (5985046107), and what "a real file" means (5985553609).
Content. 16.3a, F16.1, requirement 17's batch P note, FR-009, the T100 follow-on bullet and the P row agree with the rulings as written.
One wording choice, accepted. The writer wrote "refused when its start fails" where the holder's 5985553609 says "before any spawn". At openDox-code#86, broker_unreachable is the start failing, so the writer's words are the accurate ones, and nothing runs either way.
Checks and review. All checks are green, pytest-suite and openxdox-consumer-gate included. Copilot at the head says "Approval recommended" with no findings. 37 threads, none unresolved.
Gates. Identical to main c8d80020:
the pinned --all gate returns 0 with the 1 accepted exception, and --change returns 0;
doc-health 31/22/69/20; pytest 306 passed; box census 125;
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
This PR is bookkeeping only (T007 batch P). It records in #1144 (
add-neutral-product-standalone-operability) what Brett Heap's multi-choice word of 2026-10-04, and the holder's rulings recorded with it, imply. It also carries the plan-034 lines that follow from them. Plan 034 was read atmaind0af2574, which follows batch O's landing (#1228 →596a9a90). The branch mergesmain0e01ca85, which is #1231 (T083's evidence; T082, T083 and T100 ticked).#656comment5982436447, and its extension on this PR's review,5983805990: "Refuse inline scripts (Recommended)", with the holder's ruling5984069416applying it to launcher chains, and the holder's5985046107(C1 and C4, after an adversarial review of openDox-code#86) applying both to launcher grammar and option values, and the holder's5985553609reading "a real file" by what it forbids to run. The T100 follow-on's claim is5982447319, and this batch's is5983109372.The #1144 amendments
This PR adds six
AMENDED — T007 Batch Pparagraphs to #1144'stasks.md, plus a third dated note to requirement 17 in the spec delta. Each paragraph goes after the last addendum at its site, and none edits ratified text.file://URL while the state directory is the hidden default. The token is never printed, so such a browser has no other way in.OPENDOX_STATE_DIRset to a folder that is not hidden.history.replaceState, which cleans only session history. A browser's persistent history can still keep…/index.html#console_token=<token>.Referer. Carried out by T104.add,edit,trust,set-credential) and where it is checked, before any spawn, and it reads untrusted. The refusal names the remedy.5983805990). Brett's second word, asked on Copilot'sr4179024140, extends the rule:sh -c,bash -c,python -c,node -e) is refused the same way;5985553609): an inline script or a file inside the repository is refused at trust and before any spawn, while a program that cannot be found runs nothing, is not refused at trust, and is refused asbroker_unreachablewhen its start fails (a trust-time existence check stays open for Brett, and F16.1 has no case for it). Every path the command names, the program and each argument alike, is judged both as named and as it resolves (links followed, a bare program name looked up onPATH, a relative path against the root), when trust is recorded and before any spawn;env,nice,nohup,timeout,stdbuf,setsid,xargsand the like) is unwrapped to the program it starts, which those rules then judge (the holder's ruling5984069416, implementing5983805990). Its own options are judged with it, read by GNUgetopt_long's grammar (the holder's5985046107, C1 and C4): a long option by its unambiguous prefix (env --chd=…is--chdir), an ambiguous or unknown one refused by name; an option that names a path (env --chdir/-C,xargs -a/--arg-file, in any spelling) is judged as the command's paths are, so a launcher can neither start the broker inside the repository nor let the repository decide its arguments; and the stringenv -Scarries is split and judged only when it holds no backslash and no$, and is otherwise refused as unreadable, as an inline script is;PWD,OLDPWDor other variable naming a path inside it, and no path-list entry (PATH,PYTHONPATH, …) inside it, each judged as named and as resolved;env NAME=value) whose value is a path inside the repository, or a path list with an entry inside it, is refused by name, not dropped, at trust and before any spawn;=(--require=<repo>/x) or attached to a single-dash option (-I<repo>/lib), is judged and refused inside the repository, an output path too (5985046107, C4);awk,find -exec), and any other path embedded inside an option string given to the program that finally runs (NODE_OPTIONS=--require=…), never a launcher's own option, are not judged by the argv check, since the trusted argv is digested and the working directory and environment point away from the repository;sh -c "pass show key"becomes["pass", "show", "key"].38d3350e) read a state directory that is itself a symbolic link to this user's own 0700 directory. Its suite's case passed only because the target was writable by others.38d3350e(T083: 16.6 and F16.1 at openDox-code 38d3350e; tick T082, T083 and T100 (plan 034) #1231) predates it, and plan 034 records that.tests/test_model_binding_trust.py, also asserts three things:add,edit,trustandset-credential, and the refusal names the remedy;available: false, a turn is refused before any spawn, and no marker file appears;["sh", "-c", "exec ./tools/broker.py"],python -c, and through each named launcher in an option-bearing form,["env", "-i", "python3", "-c", "…"],nice -n 5,nohup,timeout -s KILL 5,stdbuf -oL,setsid -w,xargs -n 1, a nested chain, and a string thatenv -Ssplits) is refused the same way, with no marker file, and a pre-rule trust of it reads untrusted (available: false);PATHentry under the root, and an in-repo link that points outside are each refused, and an earlier trust does not admit them (available: false);opendoxat the served root, withPATH,PYTHONPATHandNODE_PATHentries and a scalar variable inside it, so an inherited one would show. A launcher's own assignment or working-directory option naming a path inside the root (env PYTHONPATH=tools …,env --chdir=<root> …,env -C <root> …, and each through both alias directions) is refused, with no marker file.5985046107(C1 and C4), each refused by name with no marker file:perl -I<root>/lib <outside>/broker.plandxargs -a <root>/args <outside>/brokerandenv --chd=<root> <outside>/broker, each as a command that names a file inside the served repository, andenv -S 'sh\_-c\_id'as an inline script, since the split string is unreadable. Four more, from5985046107's other clauses:<outside>/broker --config=<root>/confand<outside>/broker -o<root>/out(an option's=value, and an output path, the accepted strictness), each as a command that names a file inside the served repository, andenv --i <outside>/brokerandenv --d <outside>/broker(ambiguous) andenv --no-such-option <outside>/broker(unknown), each refused by name, fail-closed. And the rest of C1's test list, each refused as an inline script: a bundledenv -iS "python3 -c '…'",timeout --sig KILL 5 python3 -c …andstdbuf --out=L python3 -c …(not as unknown options), andenv -S '$BROKER'. That last one is written without braces, because a binding refuses any{name}outside its closed placeholder vocabulary when it is declared, so${VAR}would be refused by that rule first.These cases fail until the follow-on lands. T089 runs them at T087's pin.
5982436447item 2 and5983805990. A2 narrows one sentence of batch M's note: "turns reach a configured endpoint once its configuration is trusted". The new note records that a configuration whose command names a file inside the served repository is refused even when it is trusted. The same holds when its program is a shell or an interpreter given an inline script. The program must be a real file outside the served repository, and every broker starts outside it. It says the title, the SHALL paragraph, the notes of batches K and M, and all four scenarios stand. It adds one paragraph and edits no ratified line. This is in its own commit,843db317, on the holder's word ("A2 note: yes").Where each ruling goes.
44755f30and the holder agreed.console_token,file://andOPENDOX_STATE_DIReach occur 0 times in the spec delta.Plan 034
T007.AtoT007.P;Ruled:entry;After, by batchline. It names the landing by slice: P3-P's pin, which carries P3-C's openDox-code#84 and P3-T's follow-on. A task id in that field would read as a predecessor;596a9a90), recorded in theLanded:line and on O's bullet;5982447319), no task of this plan, landing before T087. It changes the shipped package, so by T101's rule it also lands before T101's version bump. It is recorded in three places:Ruled:line cites5982436447;After:note;Ruled:line cites5982436447.38d3350e. Batch P therefore keeps T083 as landed and adds one bullet to its entry. The bullet says the run predates the T100 follow-on, so it shows neither F16.1's batch P cases nor A8's case as ruled: that case passed there only because the link's target was writable by others. T089's run at T087's pin covers both.F16.1 → T083 (at 38d3350e), T089 (batch P's cases, at T087's pin).15b4cb7ctoc1b7da6c) had T083 wait for the follow-on, which was Copilot's first option onr4178868158. With T083 landed, the merge626207e3switches to Copilot's second option: narrow T083's run and map the valid run to T089.Ruled:citation for B3's README text: the browser limit and theOPENDOX_STATE_DIRremedy. The P3-O row names the same. openDox#17's head554e97ecalready carries the text.After:gainsT007 (batch P: …), and the P3-P row'sdepends oncell gainsT007 batch P. Batch P lands before T087, and so before T089.tasks.md:spec.md: a new "Session 2026-10-04" under Clarifications. It records the three answers and the holder's B2, B7 and A8, in the form of the sessions before it, and says which batch records them.plan.md:Gates
Each gate ran at
051f9945, the head, and atmainc8d80020(#1232), which93de1054merges, and atcc39e235(on the identical tree ofaaa99be8, before a message-only amend),bcdb185e,d08249a2,fbc4254b,7b11ce8f,bb9e46b7,739a72f0,90d6ba93and84113a44against the samemain. It also ran at6fe3dcba,907b97bd,ec4655d2,1bcbc592,b87df185,93014cbe,18576c29,dbea008e,b5f31eea,bb39c313,29254ad5,5fd7478f,b74c9d0d,6efccad2,70885b61and626207e3againstmain0e01ca85, which626207e3merges, and earlier atc1b7da6c,bf8d587b,843db317,15b4cb7candbd4345a5againstmaind0af2574. Every run used two full clones of the same kind. Each clone sits in a directory namedopenxFactory, withremote.origin.urlset to opensoft/openxFactory.mainc8d80020051f9945python3 scripts/validate-openspec-cli-pin.py --all --strict(pinned 1.12.0)110 passed, 1 failed (111 items),0 UNDISPOSITIONED failures, with 1 accepted exception (add-chain-attestation)… --change add-neutral-product-standalone-operability1 passed, 0 failed,validated --strict cleanpython3 scripts/doc-health.py --single-repo . --as-of 2026-10-04box_census.pyover #1144'stasks.mdtotal 125: 105[ ], 11[x], 9[~]These also pass on both, with identical output:
proposal-support.py . verify add-neutral-product-standalone-operability;validate-sequenced-after.py . --ledger-diff(229 rows);validate-code-surface.py,validate-target-release.pyandvalidate-pin-registrations.py;validate-document-catalog.py, with 0 errors and 0 warnings.pytest -q tests/doc-health/test_modified_block_currency_self_gate.py tests/sequenced_afterreports 306 passed atbd4345a5, at843db317(the spec-delta note), atbf8d587b, atc1b7da6c, at626207e3, at70885b61, at6efccad2, atb74c9d0d, at5fd7478f, at29254ad5, atbb39c313, atb5f31eea, atdbea008e, at18576c29, at93014cbe, atb87df185, at1bcbc592, atec4655d2, at907b97bd, at6fe3dcba, at84113a44, at90d6ba93, at739a72f0, atbb9e46b7, at7b11ce8f, atfbc4254b, atd08249a2, atbcdb185e, atcc39e235and at051f9945.The plan's consistency checks. Brett-wip
64462366widens the persisted parser in opensoft/brett-wip (handoffs/xFactory/attachments/lane-opendox/r1plan/tools/) to batch P, in the form of batch O's55abdb2e:BATCHES = "ABCDEFGHIJKLMNOP", every[A-O]made[A-P], plus its docstring and the README line. Batch P adds no single-writer file, so the chain tools are unchanged.mainc8d80020at 96 tasks, 111 nodes and 272 edges.chaindirectpairs;sharedfiles, 5 pairs NOT ORDERED, the same as onmain;mainuntil this PR lands ("names no line for ['P']"), as it did for batches K to O.Review
257133ac38d3350e, where A8's case passes for the wrong reason (r4178868158)15b4cb7c: T083's F16.1 run follows the follow-on; the F16.1 note says a run at38d3350ecloses nothing. Answered and resolved15b4cb7cr4178882493) and tasks.md's phase-3 order (r4178882527) still put T083 straight after T10044755f30: every summary names the follow-on before T083. Both answered and resolved44755f30f656b065(T076, P3-O) and843db317(the third dated note, on the holder's "A2 note: yes"). Answered on the PR843db317r4178915635); two previously-missed notes: F16.1 had no A2 case, and US3 scenario 6 still reached a trusted in-repo brokerbf8d587b: F16.1's A2 cases, US3 scenario 6 narrowed, and this body rewritten. Answered and resolved, and on the PRbf8d587br4178935172)586fa2c9: it counts six, two at F16.1, plus the requirement-17 note. Answered and resolved586fa2c9r4178956099)c1b7da6c: SC-003 names batch P's A2 cases, and FR-009 states A2 as batch P's note reads it. Answered and resolvedc1b7da6c626207e3mergesmain0e01ca85(#1231) and points batch P at T089's run, since T083 landed tickedb475b95bavailable: false(r4178971358,r4179006472)70885b61: it reads untrusted, listedavailable: false, and a turn is refused before any spawn. Both answered and resolved70885b61sh -c 'exec ./tools/broker.py') evades A2's argv path check (r4179024140)5983805990);6efccad2records it in 16.3a, F16.1's cases, requirement 17's note and the plan. Answered and resolved6efccad2PATHentry that leads into the root, and the working-directory case could pass vacuously (r4179109720)b74c9d0d: the program is judged by the path it resolves to, at recording and before spawn; F16.1 gains both aliases; the working-directory case startsopendoxat the served root. Answered and resolvedb74c9d0dr4179123170); the gate record stopped at6efccad2(r4179123179)5fd7478f: the named path and the resolved path both lie outside, and F16.1 gains the reverse link; every gate re-run at5fd7478fand cited here. Both answered and resolved5fd7478f["python3", "tools/broker.py"]) escapes a program-only check (r4179138294)29254ad5: every member of the command is judged, a relative path against the served root; F16.1 tests the interpreter's script argument, absolute and relative. Answered and resolved29254ad5r4179152884)bb39c313: every path the command names is judged as named and as resolved; F16.1's alias case covers the program and the script argument alike. Answered and resolvedbb39c313b5f31eea: it reads untrusted,available: false, as the direct in-repo case does. Answered on the PRb5f31eea["/usr/bin/env", "python3", "-c", "…"]) carries an inline script past the wrapper rule (r4179187252)5984069416;277b9578anddbea008erecord it: launchers unwrapped,PWD/OLDPWDdropped, argument-running programs an accepted limit. Answered and resolveddbea008ePYTHONPATHand the like could still load in-repo code (r4179236753); only anenvchain was tested (r4179249042); a previously-missed note: FR-009 lacked the named-and-resolved rule for arguments18576c29: the environment drops every variable and path-list entry inside the repository; the launcher case runs over all six named launchers with options; FR-009 states the rule. Answered and resolved18576c29r4179270459); the environment case planted onlyPATHandPYTHONPATH(r4179270489)93014cbe: a nested chain (env nice -n 5 timeout 5 python3 -c …), andNODE_PATHplus a scalar variable inside the root. Both answered and resolved93014cbePYTHONPATHor a scalar variable would pass (r4179290208)c419a75fandb87df185: environment paths are judged as named and as resolved, with outside-link fixtures for a path-list entry and a scalar variable. Answered and resolvedb87df185NODE_OPTIONS=--require=…, inherited or set byenv, could still load in-repo code (r4179308849)1bcbc592, under the holder's standing rule: a launcher's assignments are judged as the environment is (F16.1 addsenv PYTHONPATH=tools), and a path embedded inside an option string joins the recorded limit. Answered and resolved1bcbc592/outside/broker.py(r4179329854); a previously-missed note: FR-009 lacked the resolved-environment and assignment rulesec4655d2: the fixture names amktemp -dscratch directory, and FR-009 carries both rules. Answered and resolvedec4655d2r4179346502); FR-009 lacked the option-string limit (r4179346514); previously-missed notes:/bin/shand/usr/bin/envin the added examples (Principle IV)907b97bd: aliasedPYTHONPATHand scalar assignments, FR-009's limit, and bareshandenv. Answered and resolved907b97bdr4179366541)6fe3dcba: an in-repo link pointing outside, for aPYTHONPATHentry and a scalar, inherited and assigned. Answered and resolved6fe3dcbaenv --chdir=<root> python3 <outside>/broker.pystarted the broker inside the repository against the working-directory rule (r4179386143,r4179386206,r4179386250)93de1054mergesmainc8d80020(#1232);84113a44, under the holder's5984069416: a launcher's own options are judged with it (env --chdir/-Cas a command path,env -Ssplit before it is judged), the limit covers only options given to the program that finally runs, and F16.1 adds the--chdircases (both forms, both alias directions) and anenv -Scase. Answered and resolved84113a446fe3dcba(r4179522953)84113a44againstmainc8d80020, all identical tomain. No file changed. Answered and resolved84113a44(again)-I<repo>/lib), which the holder's later5985046107(C4) refuses (r4179629725)90d6ba93mirrors5985046107's C1 and C4 in 16.3a, requirement 17's note, FR-009, F16.1, the session record, the T100 follow-on bullet and the P row: launcher options by GNUgetopt_long(ambiguous or unknown refused),xargs -ajudged,env -Ssplit only without a backslash or$, and option values after=or attached to a single-dash option judged. F16.1 gains four commands, each with its expected refusal. Answered and resolved90d6ba93--option=<root>/…value or the output-path strictness (r4179671883), and none for an ambiguous or unknown launcher option (r4179671907)739a72f0:<outside>/broker --config=<root>/conf,<outside>/broker -o<root>/out,env --i <outside>/brokerandenv --no-such-option <outside>/broker, each with its expected refusal. Both answered and resolved739a72f0xargs, which 16.3a now names; a missing relative pronoun in the T100 follow-on bullet'senv -Sclausebb9e46b7:["xargs", "-n", "1", "python3", "-c", "…"]joins the launcher list, and the clause reads "a string thatenv -Ssplits". Answered on the PRbb9e46b75985046107's C1 test list (--d, a${VAR}split string, a bundled-iS, andtimeoutandstdbufabbreviations)7b11ce8f: all five, each with its expected refusal; the$case is written$BROKER, since the binding's closed placeholder vocabulary refuses{VAR}first. Answered on the PR7b11ce8f5985553609: "a real file" is read by what it forbids to run, a missing program is refused asbroker_unreachablewhen its start fails, and a trust-time check stays open for Brett;fbc4254brecords it in 16.3a, requirement 17's note, FR-009, the session record, the T100 bullet and the P row.1c78a6bdscopes FR-009's limit to a general program outside the repository, never an inline script, and371d2150rewraps one line. Answered on the PRfbc4254benv:/keyring andnonepaths do not run (r4179784787); the session record called the trust-time check open beside "Nothing is open" (r4179784816); its provenance summary omitted5985553609(r4179784832)d08249a2: the conclusion binds a configuration that runs a credential broker, and one that runs none is outside the note; the check is no open work of release 1; the summary lists5985553609. All three answered and resolvedd08249a2bcdb185e: the note says an in-repositoryenv NAME=valueis refused by name, not dropped, and the bullet carries the refusal and the limit. Answered on the PRbcdb185er4179835039)cc39e235: the note names the refused class (a command or launcher naming a path inside the repository, an inline script, an unreadable split string), its remedies, and says the accepted limits are not part of it. Answered and resolvedcc39e235r4179861847); previously-missed notes: F16.1'sPATH-entry alias ran as an interpreter's script argument, which no interpreter looks up onPATH; P3-P's slice row did not name the T100 follow-on051f9945: the refused class lists all three kinds; thePATHalias is the program's case only; P3-P's cell names the follow-on. The thread answered and resolved, the notes answered on the PRFor the holder
843db317) follows your "A2 note: yes". It is its own commit, so you can review or drop it alone.38d3350edoes not show F16.1's batch P cases or A8's case as ruled. Batch P gives that to T089's run at T087's pin, as T083: 16.6 and F16.1 at openDox-code 38d3350e; tick T082, T083 and T100 (plan 034) #1231's own line "T089 runs F16.1 again" does, and the box table names both tasks. If you want F16.1's box to close only at T089, that is T097's ticking, and nothing here changes it.tests/test_model_binding_trust.py. That is the file F16.1 runs, and File add-neutral-product-standalone-operability: open the BUILD arc, recording ten rulings #1144's F16.1 and T100's follow-on bullet now say so.c4b55cc4). Plan 034 still records it as a PR to come. That record is outside this batch, and the next ticks PR can update it.6fe3dcbafoundenv --chdir=<root>under the option-string limit, which would start the broker inside the repository. Your5984069416unwraps launchers "with their flags" and keeps the working directory outside the repository, so84113a44judges a launcher's own path options as command paths, and the limit covers only options given to the program that finally runs. Myenv -Saddition at84113a44is now governed by your5985046107(C1): the string is split and judged only when it holds no backslash and no$, and is otherwise refused as unreadable.5985046107mirrored (90d6ba93). C1 and C4 are in all six places you named and in the session record. C2, C3 and C5 are openDox-code#86's code and change no text here. F16.1's four new commands name the refusal each expects: a file inside the served repository forperl -I,xargs -aandenv --chd=, and an inline script for the unreadableenv -S. Those are openDox-code#86'sREASON_IN_REPOSITORYandREASON_INLINE_SCRIPTat96ae8816.739a72f0adds four more on Copilot's request: an option's=value and an output path (a file inside the served repository), and an ambiguous and an unknownenvoption, which F16.1 says only are "refused by name, fail-closed", as the ruling does. openDox-code#86 has no reason for that refusal yet, and F16.1 names none.7b11ce8fadds the rest of C1's test list (--d,-iS,timeout --sig,stdbuf --out=, and a$split string). The${VAR}form can't go through F16.1's four commands, because a binding's closed placeholder vocabulary refuses{VAR}when it is declared, before any broker rule. So F16.1 uses$BROKER, which the same C1 clause refuses as unreadable. The braced form stays a test for openDox-code#86's own unit level.5985553609(a). It is in 16.3a, requirement 17's note and FR-009, and cited in the P row. One wording choice is mine. Your ruling says a missing program is refused "before any spawn" bybroker_unreachable. At openDox-code#86's96ae8816, that refusal ("the credential broker could not be started") comes fromsubprocess.PopenraisingOSError, which is the start failing. So batch P says it is refused "when its start fails". Nothing runs either way. A broker installed later is judged before it is started, like any other.Landing
It touches
openspec/changes/, so it lands under a Rule 6LANDING/LANDEDwindow. It is bookkeeping, so it carries noArc:trailer (R1Q20 (a)) and no closing keyword. The holder posts READY and lands it.🤖 Generated with Claude Code
Summary by Sourcery
Record batch P's rulings and align the standalone-operation specification, trust requirements, tests, documentation, and execution plan with the resulting broker-safety and browser-accessibility limits.
New Features:
Enhancements:
Documentation:
Tests:
Chores: