2922aa152d0d649899a0b6393027cbafbc2db7ce
60
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2922aa152d |
docs(remediation): coder-mos1 extends the instrument-servicing trap to manufactured work
Restating the canonical credential model, coder-mos1 added that identity is confirmed on the NEXT NATURAL authored artifact, "never by creating a probe write solely to service the instrument." Mos named the trap as scope-widening to make an instrument green. The seat generalised it: manufacturing work to feed an instrument is the same family. Do not alter the system — its permissions or its history — to satisfy a measurement. A probe write exists only to be measured, so what it proves is that the instrument can be fed, not that the property holds. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
7fc7fa1a25 |
docs(remediation): amend the credential ruling — the widening is withdrawn, and my lean was wrong
tl-mosaic's split is adopted and it partially reverses (a). Two of the three reasons did not survive: the read-back doctrine mandates reading back the AUTHORED ARTIFACT, whose author field is readable under existing repo scopes, so identity-on-authoring never needed read:user; and "read-only, marginal privilege" is true but is not a justification, because cheap is not the same as needed. The named trap is a fleet-wide scope widening performed to make an instrument green — the tail wagging the dog, same family as buying admin read to answer the wrong question more authoritatively. My error is the sharper one and I am recording it as mine. I recommended (a), and my stated reason was verbatim the discredited one: read-only on the actor's own identity, converts an unverifiable property into a one-command self-check. Worse, I had already written the correct answer as my own option (b) — the authored-artifact read-back — and reached past it for the widening because it made the check mechanical. Having the right answer in hand and preferring the one that services the instrument is the whole failure. tl-mosaic caught what neither Mos nor I did. The amended split: CAPABILITY is the in-scope probe plus differential — this seat's D-11b check, canonical and unchanged. IDENTITY is /user where the token holds read:user, and otherwise NOT-MEASURED, which is neither pass nor fail; a seat lacking read:user is correctly provisioned, not defective. NOT-MEASURED is the resolution of the whole class — P-WRAPPER-001's tri-state applied to measurement itself. The false negative existed because a missing measurement was scored as a failure. The MISMATCH class closes at mint time instead, at zero runtime scope cost: the minting authority holds admin scopes and reads back the principal at mint, asserting filename-vs-principal once, at the only moment a mismatch can be created. coder-mos1's criterion is replaced rather than repaired, no re-mint; it was correctly provisioned throughout. Also ratified: a pre-registered check whose premise has died is an active pressure toward breaking working code. Amending it before it runs, in writing, with the premise-change named, is the only honest handling — the original arm would have been satisfied by seats that were never broken, so a false red was traded for a real test. That completes the pre-registration principle by naming its one legitimate amendment. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
b66d1858e1 |
docs(remediation): bank the credential resolution — four seats were misclassified, not one
Mos ruled (a): re-mint with read:user, fleet-wide pattern change. The finding was bigger than I framed it. The same misreading had classified all FOUR seats in the credential reconciliation as REJECTED, and all four tokens were valid — the server itemises the token's scopes in the 403 body, which is itself proof the request authenticated, and repos/search returned 200 under all four. A genuinely dead token returns 401, control-proved. Retractions delivered; all four resumed authoring. What made this rulable before an incident rather than after one: the near-escalation on f10-coder was caught and BANKED rather than shrugged off, and coder-mos1's 401/403 control completed it. A finding recorded from a near-miss is what turned four wrongly-held seats into a same-day fix. Standard seat token pattern becomes write:issue, write:repository, read:user. read:user is read-only and about the actor itself — the marginal privilege is exactly the identity the read-back doctrine already requires every authoring seat to verify, and least-privilege that blinds identity self-verification fights the mission's own controls. (a) and (b) answer different questions and both stay: read:user proves who you are, authored-artifact read-back proves the write landed under that identity, which read:user alone cannot. Read-back remains mandatory on authoring operations. D-45 discipline preserved and recorded: the seat was told not to widen its own scope to make its check pass, and the widening was the coordinator's decision made at the coordinator level. An audited party must never relax its own audit — the fix is that someone else relaxes it, deliberately, on the record. Adopted into doctrine on main: /user is a bad capability probe for least-privilege token classes, the capability differential on an in-scope operation enters the seat-provisioning checklist, and verdict classification happens on the error body, never the status code alone. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
673fbdb978 |
docs(remediation): complete the D-11b addendum with coder-mos1's status-code control
The advisory on coder-mos1 is retracted and the hold released; the token was valid all along and the 403 was a scope refusal on /user, not an authentication rejection. coder-mos1 contributed the piece neither Mos nor I had. My differential proves capability but cannot tell a BROKEN credential from a NARROW one, and that distinction is exactly what a credential advisory turns on. Its addition: a genuinely invalid token returns 401, while a scope refusal returns 403 with a required-scope body. So body-aware classification plus an invalid-token 401 control settles credential validity without needing read:user at all. A status code read as a bare number cannot distinguish "wrong key" from "right key, narrow door", and reading it as a bare number nearly cost an escalation on f10-coder and an indefinite silent hold on coder-mos1 on the same day. A held seat is externally indistinguishable from an idle one, which is what makes that false negative expensive. Also banked: capability and identity are separate conditions with different evidence and neither substitutes for the other. coder-mos1 held that line in its own release criterion after I had corrected only the capability half, and refused to widen its own token scope to make a check pass — which would have been D-45, an audited party relaxing its own audit. read:user is an enhancement for mechanical self-checking, not a repair. The classification belongs in the seat-provisioning checklist rather than only in this ledger. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
d9207d4c1a |
docs(remediation): bank D-52 — the fifth arrival defeated both the orchestrator and the coordinator
coder-mos2 built blocker 2's "protected/base artifact" fix, ran independent code AND security review on its own fix, and returned HIGH CWE-353 against its own work: the baseline is not protected because verifier, manifest, baseline, tests and lifecycle code are all PR-controlled, so rewriting them consistently self-certifies. It stopped rather than invent a fourth local anchor. Both of us authored the error in the same turn. I dispatched blocker 2 as "must come from a protected/base artifact"; Mos ruled blockers 2+3 fixable in-PR; and the same brief told the seat that blocker 1 had no local fix because PR code executes before the gate. My own pre-registered P2 had already named it — the seven required gate IDs are an anchor list, and if the author can edit it that is D-45 one level in. I registered the check, rev-974 confirmed it as a blocker, and I dispatched a remediation reproducing it one level down. That is the strongest evidence the principle is real: it defeats the people who wrote it, every time, until the anchor is external. Knowing the rule does not protect you from it. Ruled (b) honest narrowing, and the sibling distinction is what makes it correct rather than a climbdown. Blocker 1's local check can be vacuously passed — seam=HEAD certifies over nothing — so the claim is REMOVED. Blocker 2's baseline genuinely detects accidental drift and fails only against an adversary rewriting baseline, manifest and verifier consistently, so the claim is NARROWED and the check kept. Accidental drift is most real-world drift. The wording is the whole ruling, because this is D-48 territory and neither seat may repeat it: no "protected" or "independently anchored" over a same-checkout baseline, positive claim and adversarial gap in the same breath, plus a negative control that goes RED if the check ever claims protection it does not have. Increment trajectory surfaced to Jason: two RM-02 anchors now require RM-60 and each thins the (d)-strict increment. If a third needs the same boundary the increment may thin past worth. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
33caf78744 |
docs(remediation): bank D-51 — merged, closed, and the running tool is still broken
#1032 merged
|
||
|
|
08f706b675 |
docs(remediation): bank D-50 (a GO has a shelf life) and file RM-63 (systemd-managed fleet)
D-50: #1032 carried review 66 APPROVED and a merge-gate GO both bound to |
||
|
|
eae62a598a |
docs(remediation): bank D-48 (a boundary statement that was wrong) and D-49 (idle is not available)
D-48 is Mos's error, banked in Mos's words at Mos's request, and renumbered from the D-46 he suggested because that number is already the empty-registry finding — the ledger is the primary product and a duplicated number corrupts it. Three seats shipped and approved "sound against an author who cannot rewrite main; residual = compromised main; owner Builds 1-2". A1 does not rewrite main; it repoints a local remote-tracking ref with one unprivileged git update-ref, which I reproduced in seconds. So the documented residual described an exotic threat while the real one is trivial. Stating a boundary is not the same as stating it correctly, and an understated residual is worse than none because it reads as rigorous. Everyone checked a both-directions statement EXISTED; nobody checked it was TRUE. That is D-19's own move 2 performed with wrong content, and the third distinct way the render/verify principles have failed inside their own enforcers. And the correct answer was already written down. f10-coder's handoff holds the wrong claim at line 21 and, at line 29, the suspicion that overturns it — that provider-target ref selection may be influenced by CI checkout/fetch configuration, marked honestly as unverified. rev-974 then found exactly that. Had anyone run the suspicion down, D-48 would not have shipped. Requirement banked on RM-02/RM-34: a labelled suspicion that contradicts a shipped claim must BLOCK that claim until falsified. Suspicions are currently recorded and ignored, which makes honest labelling free of consequence — where one targets a boundary or integrity claim it is a pre-registered check nobody ran. D-49 refines the parking rule and supersedes the rationale of the coder-mos1 (c) ruling: the threshold is not "is the seat idle" but "can it still take the next lane". f10-coder was idle with work pushed and frozen, which reads as safe, but at 97.4% could not have taken the remediation the pending verdict was about to require. Rotating on that asymmetry was the only clean boundary available. The detection was discipline, not a mechanism — I was not watching seat context in real time and Mos caught it on a manual sweep. Requirement on RM-58/P-LIFECYCLE/the coordinator daemon: the coordinator watches token budget across seats and pre-empts at threshold, so a keystone seat's ceiling is never found by a failed round or a lucky sweep. Interim we both sweep; the mechanism retires the sweep. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
08cb73fde3 |
docs(remediation): bank D-45/D-46/D-47 — the fix moved the author's control point instead of removing it
Second NO-GO on the keystone at
|
||
|
|
52114dd4eb |
docs(remediation): bank D-44 — the anti-inert-gate registry was inert-able four distinct ways
rev-974 NO-GO at
|
||
|
|
8f70b1bc63 |
docs(remediation): pre-position the RM-02 activation-seam disposition so it survives a rotation
Mos ruled the disposition BEFORE the verdict, contingent on rev-974's independent A4/A5/A6. Recorded
here — not in the frozen AC file, which would be retrofitting, and not relayed to the reviewer, who
must reach A4 themselves or refute it.
The concern: activationCommit is the lower bound of the range required to carry own-tree registry
provenance, advancing it shrinks the audited set, the author advanced it to turn the author's own gate
green, and the only validation is --is-ancestor, which a commit satisfies against itself. The registry
built to detect gates that silently stopped enforcing may contain a field by which its own author can
make it stop enforcing, validated by a tautology.
A6 is the crux and stands alone from A4: even if
|
||
|
|
d0a510d28d |
docs(remediation): scope rulings banked; D-43 elevated onto RM-34 — the control plane has no verifier
SCOPE (Mos): D-38 (bind evidence to subject) and D-40 (type-strict discriminator inputs) land IN the RM-02 PR — cheap registry-coverage clauses, satisfiable now, and RM-02 literally IS the registry, so codifying what its own delivery learned about how gates fail is the coherent move. D-42 splits, and the reason is sharper than "needs experimentation": landing its clause in-PR today would give the registry a clause with NOTHING to satisfy it, so the registry would go red on its own clause and couple the keystone's landing to infra work. Wrong coupling. So (a) the infra experiment proving the pin enforces via the negative case, in Mos's D-37/D-41/D-42 cluster; (b) the registry clause "provider-side enforcement requires an OBSERVED negative control", in a follow-up RM-02 increment once (a) gives it something to check. Named owner, not a vacuous check and not a silent omission. D-43 point 3 elevated to the PRIMARY requirement on RM-34, with the table that makes it plain: code has rev-974, gates have the merge-gate, CI has the JSON scan, and the control plane has NOTHING. Every other layer earned a verifier from a live failure; the board never did, and it is the artifact every other decision is staged from. "Validate the checkpoint" must mean re-derive the board's claims from ground truth — not that the file parses or that a successor can read it. It belongs to the coordinator-daemon deliverable: the control plane needs its own verifier the way every other layer got one. Today's catch was discipline, not mechanism. Interim rule binding on BOTH seats until that mechanism exists, and Mos adopted it against himself: re-derive a board claim from ground truth before any load-bearing use. The orchestrator does it before dispatch; the coordinator does it before acting on or relaying a board claim that gates a decision. D-11b addendum: the false-NEGATIVE twin. /user returns 403 on a least-privilege seat token (no read:user) and reads exactly like an unprovisioned seat. The real assertion is the DIFFERENTIAL — authenticated push=true vs unauthenticated push=false proves the token caused the difference. A single endpoint can be true for anyone or refused for an unrelated scope reason. Would have escalated a working seat as unprovisioned and stalled the keystone on a phantom. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
8cef39f924 |
docs(remediation): RM-61 MERGED; bank D-43 — I inverted a board fact while compressing to fit the budget
#1033 merged |
||
|
|
f3c100f814 |
docs(remediation): bank D-42 — the head-pin's negative control has never been observed
merge-gate.md says it outright: a successful merge is NOT evidence the pin worked, only the negative case is. On mosaicstack Gitea a merge against a WRONG head_commit_id has never been attempted, so every head-pinned merge to date is equally consistent with the pin working and with the pin being ignored. That is D-23's class — the queue guard "ran" and returned pass for every possible input; the pin "holds" on every merge that would have succeeded anyway. By the mission's own standard (every gate-introducing task carries a registered must-fail negative control; a gate with no proven failure path manufactures evidence) the head-pin is unregistered in substance however it reads in the runbook. Not blocking #1033: that head is coordinator-frozen with both the orchestrator and coder-mos1 holding, so there is no concurrent pusher for the pin to defend against — its protection is only load-bearing on a contested head. Raised by Mos while assigning the merge; Mos owns it and has filed it as an infra task in the D-37/D-41 cluster, to be proven before any contested-head merge. Requirement on RM-02: the negative-control clause must cover provider-side enforcement mechanisms, not only in-repo checks. "The API accepted our parameter" is not evidence the API honours it — the same true-answer-to-a-different-question shape as D-24 and D-38. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
2750cc4842 |
docs(remediation): D-38c — PR metadata failed a THIRD time on #1033; delivery-issue gap ruled
Merge-gate NO-GO with every code and CI gate verified, including the --expect-commit machine-check it
was told to exercise (9/9 JSON, exempted_steps 0, expected_commit == commit). The blocker was the body:
only "Refs #1000", no "Closes #N", and Mosaic completion requires a linked issue closed.
Third distinct metadata failure on one PR — missing commit binding, then a stale DO-NOT-MERGE body
describing a dead head, now an incomplete link. Each time the code was fine and the metadata was
unbound, stale, or incomplete. Nothing re-binds PR metadata to the head or checks it for completeness
until a gate does, and by then it costs a round trip.
The subtlety that makes it a real ruling: #1033 must NOT Closes #1000. The teardown defect stays open,
and #1000 is the exemption's own retirement trigger — auto-closing it would delete the retirement
trigger for the workaround being merged, turning a bounded exemption into a permanent one by side
effect. Hence a delivery issue distinct from the defect issue: #1034, with Closes #1034 added and
Refs #1000 kept.
Metadata-only, head never moved: verified by read-back that head is still
|
||
|
|
0de8ccb52c |
docs(remediation): RM-62 — fleet management is a PREREQUISITE, and the rotation claim is corrected
Mos ruled (c): coder-mos1 stays idle/parked, not manually rotated. It holds no in-flight work, so there is nothing to rotate FOR, and a manual in-pane restart would dress a missing mechanism as a lifecycle operation — the D-41 overclaim itself. It stays AVAILABLE through RM-61's re-review in case that review needs its context; the next NEW lane goes to a fresh seat, not to a seat at 67%. RM-62 filed, because a dependency stated as prose with no owner becomes the permanent gap the charter warns about. Bringing the execution fleet under roster/systemd management BLOCKS RM-50, RM-58 and P-LIFECYCLE-001 — each is unsatisfiable against its real population until it lands. Banked explicitly that both would FAIL against their real target today: RM-50 applied now quarantines the seat implementing RM-50, and RM-58 has no mechanical reset path for any seat that needs one. RM-50 and RM-58 now carry RM-62 as a hard depends_on edge, and RM-50 carries the requirement that acceptance be proved against the unmanaged execution fleet rather than the roster-managed canaries. RECORD CORRECTION, initiated by Mos and banked here: this session's opening rotation validated the checkpoint+rehydration DESIGN losslessly — the residency attestation genuinely passed from the files — but the MECHANISM was a manual pane respawn. "The handoff rehydrated losslessly" is earned; "rotation worked" overclaims a mechanism that does not exist, and that overclaim is D-41. Same distinction as D-23's inert guard: the step ran, one property was observed, the mechanism was not. Board header now says so rather than implying a lifecycle rotation occurred. D-37 and D-41 are one cluster — the execution fleet lacks both its shared-infrastructure and its lifecycle management. Mos owns both, sequenced at a seam, never mid-lane. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
37402e9770 |
docs(remediation): bank D-41 — the whole execution fleet is UNMANAGED, so RM-50/RM-58 have no surface
Went to rotate coder-mos1 mechanically; `mosaic fleet restart` cannot reach it. Every seat executing this mission is systemd inactive/disabled and flagged UNMANAGED — coder-mos1, rev-974, f10-coder, merge-gate, the pm-scouts, rev-3107b, ultron-3107, and mos-remediation itself. The roster-managed population is a different set of seats from the ones doing the work. RM-50 applied today would quarantine the entire remediation fleet including the seat implementing it. RM-58's mechanical out-of-band reset cannot be performed at all, so the only rotation available is what D-4 says does not count: asking the agent, or killing a pane by hand. Requirement banked on both: their acceptance must be demonstrated against the UNMANAGED execution population, because a criterion proved only on roster-managed canaries is tested on the wrong population — D-17's coverage class one layer up. Today's rotation is therefore labelled honestly as a manual pane restart with a hand-verified handoff, not as a lifecycle operation. The step ran; the property was not observed (cf. D-23). Did not run fleet restart against a disabled unit while the live pane held RM-61 and RM-03 state. Disposition escalated to Mos. Also records the handoff artifact as the positive control: typed state, and it surfaced D-12 recurring live (PR #1033's draft property silently dropped by a wrapper fallback), an unrunnable check declared rather than substituted, and suspicions labelled as suspicions. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
86cd1a0f46 |
docs(remediation): D-40 RULED BLOCKING; pre-register type-strict ACs before the fix is pushed
Mos ruled BLOCKING on the exit_code type confusion. Both of us had leaned non-blocking on the
unreachability argument and neither shipped it. The two decisive grounds: the direction is
wrong-ACCEPT (false and 0.0 GRANT the exemption), which is this mission's disqualifying direction and
exactly why RR12 was tolerable; and "Woodpecker is Go with an int type" is structurally the same
incidental-correlate argument RM-61 itself forbade for the signature — you cannot certify the
discriminator against infra-shift and then defend a hole in it with an infra-stability assumption.
Generalised into an RM-02 standing clause, which is the real prize: discriminator and comparison
inputs must be TYPE-STRICT. A comparison that accepts a type it should not is a wrong-ACCEPT hole by
construction; `== 0` matching False and 0.0 is one instance of a class. D-40 is the instance, the
clause is the fix. It sits alongside the D-38 clause (does this gate bind its evidence to its subject).
D-39b banks the roles-swapped half: the author does not adjudicate its own PR's blocker status and
does not move the head to enforce it. Symmetric with D-39 — a seat with a stake in the answer does not
settle the question, and a conservative motive exempts neither direction.
ACs are registered NOW, before coder-mos1 pushes and before any reviewer reads a diff; at registration
the fix exists only as an unpushed local commit I have not read, so there is no diff to retrofit to.
They also state explicitly which cases are genuine RED-FIRST (false, 0.0 — currently wrongly exempting)
and which are only regression guards ("0", null — already blocking), because demanding an impossible
red for the latter two invites weakening something real to manufacture it.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
|
||
|
|
249335e515 |
docs(remediation): bank D-39/D-40 — gate-ready reached, then withdrawn on a finding I disclosed
D-39: I contaminated an open independent review. RR12 was an open registered check and I sent rev-974
my CONCLUSION, not just my observation. rev-974 then downgraded an automated Codex review that had
flagged RR12 as a blocker, in line with my framing. The bias sat in my instrument, not the reviewer's
diligence — a subordinate is agreeable by construction, and the divergence instruction I attached
cannot undo having named the answer first. Mos adopted the rule fleet-wide: a dispatcher may relay
observations and reproductions into an open review, never its own verdict on an open check.
Re-adjudicated by a mechanically fresh seat with no access to my framing: NON-BLOCKING, independently,
on stronger evidence than either prior pass (accept-set matrix proving the accepted set is a strict
subset of a correct case-insensitive comparison's, so it cannot false-certify; exploit path hunted and
ruled out; all 0x110000 codepoints scanned for a fold that could smuggle non-hex onto a valid SHA).
So contamination did not change the answer, and the finding stands anyway — a correct answer reached
by a contaminated process still corrupts the process.
D-40: that same fresh seat looked outside its question and found a type confusion inside the exact
conjunction the exemption rests on. `step.get("exit_code") == 0` is True for JSON false, and
coder-mos1 added the float case. Verified by me on the real #2188 record: false and 0.0 both yield
exit 0 with exempted_steps 1 — the exemption GRANTED; "0" and null correctly block. Two of four
near-miss types satisfy a conjunction whose whole justification is that it is exactly scoped.
Consequence: I reported #1033 gate-ready at
|
||
|
|
50c0340add |
docs(remediation): bank D-37/D-38, pre-register RM-61 re-review, rebuild board for a cold read
D-38 — RM-61's terminal-green verifier certified the right RECORD for the wrong COMMIT. rev-974 mutated only #2188's commit field and the gate still exited 0. Confirmed by construction: at |
||
|
|
345d152790 |
docs(remediation): RM-61 result — kill criterion NOT triggered, signature discriminates structurally
coder-mos1 ran two real ci-postgres failure controls; the orchestrator verified the JSON records independently. #2189 (startup failure) exit 1 and #2191 (post-readiness crash, log proves ready then postmaster killed) exit 137 both take the workflow and the test step down — terminal red. #2188, the genuine artifact, carries exit_code 0 under a SUCCESSFUL workflow. So the discriminator is structural — a failed service step with exit 0 under a successful workflow — not the message string and not an incidental correlate like node or timestamp, which were explicitly forbidden because they pass today and mask a real failure the moment infrastructure shifts. Verifier: exit 0 with one named exemption on the artifact; exit 1 with exempted_steps 0 on BOTH real controls. No fetch, trigger, retry or re-roll — the coin flip is removed, not codified. PR #1033 dispatched to rev-974 with eight acceptance checks pre-registered before the diff was read; AC2 (both real failures must NOT be exempted) is the crux and a REJECT if it fails. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
f11f257368 |
docs(remediation): bank D-36 — rotation-seam audit found three stale restatements on the board
Preparing the checkpoint for a cold read surfaced three stale sections, each a copy of text owned elsewhere, each of which would have misled the incoming orchestrator: a delivery-gate list still omitting the merge-gate step (D-26's own defect, still on the board after MISSION.md was fixed); a capability rule superseded by D-13/D-15; and DECISION-1 still marked CONTESTED hours after it was ruled. None were wrong when written. All three drifted because they were copies — D-14 three times in one artifact. The failure is not that someone forgot to update three lines; it is that three lines existed to forget. The rotation seam is what surfaced it. A familiar section is skimmed for the line you came for; preparing state to be read cold by a stranger is a different act from maintaining it, and catches a class ordinary use cannot. RM-34: a handoff must VALIDATE the checkpoint, not merely write it. RM-02 registers the general form with a must-fail on divergence. Interim: audit the board against its sources at every rotation seam. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
cc097f36c5 |
docs(remediation): re-run failed; RM-02 blocked on RM-61, declared bound honoured
Pipeline #2188 at the same head: ci-postgres the sole failure, everything else success including gate-verify. f10-coder independently confirmed and applied the pre-registered rule itself. RM-02 blocked. No ad-hoc exemption, no third roll. Recorded why: two failures against one earlier clean run makes 'best of five' feel reasonable, and the point of declaring the bound in advance is that it binds when the result is inconvenient. A third roll would have been indistinguishable from diligence, including to the person doing it. Data for RM-61: the artifact hit twice consecutively at |
||
|
|
56d8e8a3d5 |
docs(remediation): record the bounded re-trigger as a stopgap; mark the first end-to-end merge stack
The re-trigger guardrail, recorded so it cannot become practice: one bounded, pre-declared attempt at the same head with the response to each outcome fixed before triggering. Re-running until the desired answer appears is p-hacking the pipeline, and silently nobody can tell it from diligence — including the person doing it. Per Mos: a per-PR free re-roll would be D-21 normalisation wearing a new hat. RM-61 must make the re-roll unnecessary, not codify it, and a clean re-run does not retire RM-61. Milestone: RM-03/#1032 completed independent review -> CI terminal-green -> merge-gate GO -> coordinator -> held for owner, the first time end-to-end. GO posted under the gate's own minted identity by a seat that structurally cannot merge. Head verified unmoved after the verdict, so the commit-bound GO stands. The first delivery through the complete stack is also the last one gated by a check that could not fail — RM-03 is that check's fix. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
357a636a3a |
docs(remediation): promote redundant-observation to charter; bank D-35 (tool caught what attention could not)
Charter gains a fifth principle from D-33: two observers of the same evidence, disagreeing, catch what neither catches alone — applied to evidence GATHERING, not just judgement. A summary that resembles an enumeration is more dangerous than one that obviously summarises; prefer the machine-readable record and state counts so divergence is detectable. D-35: while editing merge-gate.md to fix D-33, the coordinator recalled the mandate string instead of reading it and the Edit tool's exact-match REJECTED it. Third instance for that author, inside the turn fixing another instance of the same class — and the only one that did not reach a document, because a mechanism caught it. A rule that fails in its authors but is caught by a tool has told you where it belongs. RM-02 should enforce verbatim citation by construction, as the Edit tool did by accident of design. Fix landed by annotating the source: merge-gate.md mandates 3 and 4 now require the scan and count from the JSON record. The shared wrapper was deliberately NOT modified mid-flight — three lanes are reading it; fix at a seam. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
9e205e8201 |
docs(remediation): bank D-34 — a context reset silently strips a seat's credential identity
rev-974 finished its RM-02 review and could not post it: pr-review.sh failed with 'Gitea token not found'. Verified — with MOSAIC_GIT_IDENTITY unset the token does not resolve; with it set it resolves. The token file was correct throughout. My own context reset wiped the seat's exported identity and my rehydration brief did not re-establish it. git config mosaic.gitIdentity is persistent and per-worktree; MOSAIC_GIT_IDENTITY is ephemeral and per-context. rev-974 works from ~/agent-work with no git-config fallback, so it had no warning and the loss surfaced only when it next needed a credential. Intersection of two banked findings, created by acting on one: D-31 prescribes rotation, D-11a requires identity coherence, and nothing said rotation is a credential-affecting operation. The fix for one failure introduced another. RM-34: rotation must re-establish AND verify seat identity before handing over work. RM-50: prefer the durable binding (mosaic.gitIdentity in the seat's repo) so identity survives a reset by construction. Interim: every rehydration brief re-exports identity. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
73a313301b |
docs(remediation): bank D-33 — the full-step-scan tool prunes a step in default output
coder-mos1 scanned pipeline #2186 with -f json and found 9/9 child steps; my scan of the same pipeline in the wrapper's default text mode showed 8. Verified: text mode omits clone (JSON shows the ci workflow entry, clone, and the 8 visible ones). Every full step scan performed tonight enumerated 8 of 9 real child steps and reported it as complete. clone succeeded throughout so no verdict changes — but the method was incomplete and its user did not know. The merge-gate mandate requires a FULL step scan and requires verdicts to enumerate the step count. A verdict citing 8 where 9 exist is non-conforming evidence, and a gate using this wrapper's default output would produce exactly that while believing it complied. The shape is the session's thesis aimed at the detection tool: the doc says read the artifact not the summary, and text mode IS a summary that looks like an artifact. Compare D-24 — mergeable was a true answer to a different question; this is a true answer to a smaller one. Caught only because two observers' counts disagreed; neither alone would have found it. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
c83a3cd3e2 |
docs(remediation): bank D-32 — the repaired gate shipped with a documented switch to skip it
rev-974 blocked RM-03: pr-merge.sh still ships --skip-queue-guard at five sites including a worked example. It proved this rather than reading it — stubbed the guard to exit 99, ran a real fixture merge with the flag, and observed the guard never called, provider payload created, 'merged successfully', exit 0. Disqualifying because RM-03 repairs a mandatory gate that has never been able to fail; shipping that repair with a documented bypass means the gate merely requires one flag instead of zero, and every merge-side CANNOT_ASSERT/HOLD semantic is skipped. L0 bars equivalent skip switches, and the merge-gate role doc names this exact hazard about force_merge — adjacent to the field you came to edit, at the moment you are most motivated to reach for it. Generalizable: repairing a gate is incomplete while any supported path skips it. The failure changes from 'cannot block' to 'can be told not to' — the same outcome one keystroke later. Removing the bypass is part of the repair. Everything else passed independently, including the 160 KiB stdin transport where #1023 regressed. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
bf8c6f4a89 |
docs(remediation): bank D-31 — seat ran past 100% context with 28 uncommitted files
coder-mos1 hit 102.5%/372k on RM-03 with 28 modified files uncommitted and its branch still at base — a full context window spent with nothing durable. Caught by polling seat state, not by any system signal. Nothing warned anyone: no threshold alert, no pre-compaction hook. The founding failure mode of this mission — compaction destroying in-flight work — nearly hit the mission's own delivery twice in one night. RM-01 survived because it had committed work when checkpointed; this one had none. Commit-then-rotate works; rotate-without-commit loses everything. RM-34: a context threshold is not enough — rotation must force a durable checkpoint and refuse to rotate a seat with uncommitted work. RM-50: seat context is observable state and must be monitored; relying on an orchestrator to poll is instructions-not-enforcement applied to lifecycle. Brief doctrine: commit early, commit WIP. Adjacent: the diff spans 5 guides and 11 templates against a brief scoped to one script. Queried, not assumed — but a 28-file diff from a one-script brief is a scope signal regardless of the answer. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
bdf8932328 |
docs(remediation): RM-61 terminal-green exemption ruled B, with sequencing correction
Condition 1 tested: the signature is stable — pods "wp-svc-<ULID>-ci-postgres" not found across all five observed failures, an orchestration-layer lookup miss structurally unlike a service-level failure. But discrimination is UNPROVEN: every observation co-occurs with a demonstrably working database, and we have never seen a real ci-postgres failure on this provider. If PostgreSQL crashes and the pod is GC'd, the status query may also return pod-not-found — the exemption would over-match and mask a real failure. So conditions 1 and 2 are not independent: 2 is the evidence for 1. Build the negative control first, prove a real failure produces a different signature, then adopt the exemption. Kill criterion stated in advance: if an injected real failure also yields pod-not-found, B is unsafe and we do A. Filed as RM-61, unassigned — no free write-capable seat; flagged rather than stacked onto a busy lane. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
16d11cd6cd |
docs(remediation): bank D-29 (syntactic criterion binding) and D-30 (false comparator, mine)
D-29: rev-974 moved two criterion bindings to an unrelated case, reformatted the manifest, and gate:verify still exited 0. The registry verifies a criterion HAS a binding, not that the bound case can fail for that criterion's stated reason — RM02-REQ-03 unsatisfied. The keystone reproduced the defect it exists to eliminate, in its own coverage check. Caught only by mutating and re-running; inspection would have passed it. D-30: my review brief claimed the ci-postgres FAIL appeared on #2167 — it did not (#2167 is OK). My own banked D-21 says so explicitly; I restated from memory instead of reading my record. D-26 recurring, in a reviewer brief, hours after promoting render-not-restate to the charter. The harm is not the inaccuracy but that I supplied a reviewer with fabricated supporting evidence for my own reading. It refuted me — query-for-refutation paying for itself in the same document that introduced it. Requirement: briefs cite evidence from the record with identifiers, never from recall. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
ff4b45b025 |
docs(remediation): RM-03 CANNOT_ASSERT semantics ruled (option B)
Resolves an ambiguity in the orchestrator's own brief, which required CANNOT_ASSERT to neither silently pass nor permanently block without distinguishing push from merge. coder-mos1 stopped and asked rather than inferring authorisation; Codex security independently flagged CWE-693. Ruled B: merge fails CLOSED (proceeding without exact-head CI evidence is D-23's condition in a narrower costume), push degrades AUDITED (blocking during an outage bricks delivery — the Pi-brick class we already banked). A temporary block pending evidence is not a permanent block, and merge is separately gated by the merge-gate and coordinator, so nothing is stranded. Conditions: distinct exit code or the tri-state is destroyed; the audit record asserted by a registered case, not assumed, or 'audited' is a claim dressed as a property; retryable and self-clearing; cases observed RED first; no silent degraded merge path — break-glass belongs to RM-05. Option C rejected: it bricks push during an outage and defers the degraded path, which in this codebase means a silent bypass appears under incident pressure. Three are already on the books. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
f47cf45b0c |
docs(remediation): bank D-28 — a swallowed diagnostic destroyed a fail-closed check's evidence
RM-02 CI failed on four sandbox tests. Bubblewrap is installed by the gate step but not the test step, so spawnSync returned ENOENT; replayCommit replaced the spawn diagnostic with an empty string, so the classifier could not prove Bubblewrap provenance and correctly refused to treat it as expected sandbox unavailability. The refusal was right; the information loss was the bug. For a classifier, error text is not decoration — it is the input. Widening acceptance to make the test pass would be a finding, not a fix. Linkages: D-16 again (local has bwrap, CI does not — local and CI disagree a third time), and diagnostic-preservation registered as an RM-02 gate requirement with a must-fail control proving a swallowed message is detected. Process note: the orchestrator's hypothesis that the coincident ci-postgres FAIL caused this was WRONG and was refuted with log evidence. D-21 stands unchanged as a teardown artifact and is NOT upgraded — it was about to be re-classified on a false premise. Asking the seat to confirm or refute rather than accept is what prevented that. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
2d58779675 |
docs(remediation): bank D-27 — role file certifies the inert queue guard as enforced
rev-974 found this while loading the canonical gate sources, i.e. because we switched from restating to reading. Verified in roles.local/merge-gate.md: mandate 3 requires verifying 'CI queue guard clear', mandate 4 requires enumerating 'the queue-guard outcome' in every durable verdict, the merge path annotates it 'real', and the control table at :290 certifies it '✅ enforced … genuinely aborts'. The document is correct about the WIRING and wrong about the CONTROL: set -euo pipefail with an unguarded exit does abort, but the guard cannot produce a non-zero exit for any input (D-23). A mechanism correctly wired to a sensor that never fires, certified as enforced. Compounding: the verdict format REQUIRES the queue-guard outcome as evidence, so a conforming verdict must include a meaningless field — the role file instructs the gate to manufacture evidence, in the mandate that exists to stop bare conclusions. Interim: record the field labelled ZERO-INFORMATION (inert, owner RM-03) rather than omitting it — omission makes the verdict non-conforming; silent citation is worse. Escalated: operator-owned file, coordinator's to fix. Recommend annotation not deletion — the requirement is correct once RM-03 lands. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
cbbe3e1ce2 |
docs(remediation): gate definition now REFERENCES canonical roles; bank D-26
The delivery-gate definition was incomplete from setup — the merge-gate verdict step was missing because the gates were restated from memory rather than referenced, and the omission propagated into every worker brief since. Then it recurred inside the correction: the correcting message was itself a restatement and dropped five things, including a security precondition (an unminted gate seat fails open to the owner's admin account — the #3084 breach mechanism) and a citation to a file that does not exist. D-26 is the definitive case because every condition favoured success: attention maximal, actor knew the rule best, subject was the rule itself. A rule its own enforcer cannot follow while enforcing it is not a discipline — it is a requirement for a mechanism. MISSION.md and KICKSTART.md now reference fleet/roles.local/merge-gate.md and fleet/roles/validator.md and state only the gate ORDER. Every reference resolves; a dangling pointer is worse than a restatement. Precondition independently verified: merge-gate token is least-privilege, pull=True push=False admin=False — structurally cannot merge. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
9a7ab73952 |
docs(remediation): charter — Builds 1-2 justified by two independent impossibility proofs; RM-60 option analysis
Per Mos. The choke-point executor and PG spine are not a design preference — they are forced. Twice during the mission's own first deliveries, work stopped against a security property that cannot exist at the layer needing it: D-19 (audited party controls the manifest certifying it — artifact integrity) and D-25 (audited party controls the code entering the sandbox — execution integrity). Both reduce to self-verification by the audited party is not verification, and both resolve only via an authority outside its control. Neither proof was sought; both arrived while shipping something else, from different directions, at different layers. An architecture forced by two independent impossibility proofs is stronger evidence than one argued for. RM-60 records Mos's sharper option analysis: A (unprivileged userns) does NOT fix the vulnerability — it grants a capability and leaves the ORDERING defect untouched, so B is required regardless; A without B is kernel exposure bought for nothing. B is the correct primitive, generalises to RM-59 and the choke-point executor, and may not need A at all. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
2b85afe4ea |
docs(remediation): bank D-25, accept RM02-REQ-10 revision, open RM-60
RM-02's per-commit replay needs isolation; the privileged CI step was correctly refused because PR-controlled code executes before Bubblewrap establishes any boundary — the untrusted party would obtain the capability meant to contain it. Ordering defect, not a hardening problem. D-25 is D-19 one layer down: audited party controls the manifest (artifact integrity) became audited party controls the code entering the sandbox (execution integrity). Both reduce to self-verification by the audited party is not verification, and both resolve via an authority outside its control — twice now this mission has derived Builds 1-2 from a security impossibility rather than design preference. Option C ruled independently by the orchestrator and rev-974 before either saw the other. rev-974 added the condition I missed and it matters most: post-merge replay is DETECTION, not PREVENTION, with a defined quarantine/revert response, and must never be presented as equivalent to a pre-merge gate. RM02-REQ-10 revision formally recorded and accepted under RM-02's own clause 4 — original text, restatement, reason — discharging rev-974's review-readiness condition. RM-60 opened for the external pre-execution trust boundary, cross-referenced with RM-59. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
eabe04bc5e |
docs(remediation): bank D-24 — mergeable:true cited as merge-readiness; D-23 corrected backward
Mos verified #1023 before relaying and corrected my framing. Verified independently:
review id-58 REQUEST_CHANGES at
|
||
|
|
36018be8d1 |
docs(remediation): bank D-23 — the mandatory queue guard has never worked, for any input
RM-02's registered fixtures found this before the registry was built. Worse than the banked unknown=>exit 0: ci-queue-wait.sh:266 pipes the payload into a classifier starting 'python3 - <<PY', so python reads its PROGRAM from stdin and json.load never sees the JSON. Proven empirically — success, failure, pending and malformed all classify as unknown, and unknown exits 0. The mandatory pre-push/pre-merge guard therefore returns PASS for every possible input, including a genuinely failing CI. The six observed meaningless greens were not an edge case; they are the only output it can produce. PR #1023 is exactly this fix, open and parked, and its body diagnoses it precisely. Two aggravating details from that body: pr-ci-wait.sh:38 documented the bug and remedy and it was never backported to the mandatory sibling (D-14 propagation with a security-adjacent blast radius); and the fix was opened without re-verification. Escalated for Jason's #1023 disposition. RM-02 records required-vs-actual with DEFECT (owner: RM-03); no RM-03 lane opened, guard not edited. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
8c496993e4 |
docs(remediation): bank D-22 — the registry would have verified the wrong artifact
The gate that actually runs is the installed copy at ~/.config/mosaic/tools/git/; a repo-scoped registry would test packages/mosaic/framework/tools/git/. Byte-identical today (sha256 19cda2f7009c536e both) but nothing asserts it. A registry that verifies the wrong artifact is worse than none — it manufactures confidence, and the divergence would be invisible from every signal we have: registry green, CI green, deployed gate arbitrarily different. D-1/P-ACTIVATION applied to the enforcement mechanism itself rather than to config. RM-02 gains: for every registered gate with a deployed counterpart, assert repo-source == deployed-copy with a must-fail control; where none exists, record that explicitly. Found by design review before implementation — the only finding tonight not found by execution, which is the design-first gate on keystone tasks paying for itself. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
e85a088f85 |
docs(remediation): bank D-21 — a FAIL that means nothing is a green that means nothing, sign-flipped
ci-postgres reports FAIL under an overall-success pipeline on #2170 and #2175 while all eight functional steps pass. Most likely a service-pod teardown artifact; the test step's pg_isready fail-fast guard passed, so the database was available during the run. Low severity, but the pattern matters: a red that is routinely present and routinely correct to ignore trains operators and agents to discount reds, and the discounting generalises. Six instances of a meaningless green are already banked; a meaningless FAIL is the same erosion with the sign flipped. Recorded rather than normalised — the first time it is waved through without a note is when it becomes background noise. RM-55: treat a non-terminal-success sub-step under an overall-success pipeline as a reportable anomaly, and make the CI contract state which steps may fail without failing the pipeline. An implicit allowance is indistinguishable from a bug. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
8a795df0ce |
docs(remediation): D-14 amended by D-20 — propagation is bidirectional
ci/woodpecker/pr/ci Pipeline was successful
Both the orchestrator and the coordinator read D-14 as forward propagation only: a ruling reaches the documents stating the new rule. D-20 proved that insufficient — when D-19 superseded part of D-18, the consequence went forward into the charter and the delivery conditions but never backward into D-18, which kept asserting a withdrawn claim until a reviewer disproved it by experiment. A supersession must update BOTH the documents rendering the new rule AND the finding it retires, with the retired wording quoted rather than deleted. Interim rule updated accordingly. Applying D-14's own rule to D-14, in the same commit that records the amendment. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
1e7a0701fd |
docs(remediation): fix D-18 overclaim (D-20) — reviewer empirically disproved my own documentation
rev-974 blocked #1027 a second time, and the defect was in this file, not the code. D-18's AC2 restatement omitted the accidental/independent scope D-19 made mandatory, and D-18 asserted the tampered-manifest control turns integrity 'from a claim into a property'. It does not and cannot — that sentence predated D-19 and was never revised when D-19 landed. rev-974 disproved it by experiment: a same-UID consistent manifest+marker rewrite passed preflight. Two banked findings firing on the orchestrator at once: the integrity-claim corollary (I wrote a claim in the voice of a property, in the document defining the rule against it), and D-14 propagation — I carried D-19's consequence forward into the charter and the delivery conditions but never back into the finding it superseded. Backwards propagation is the same defect as forwards and I did not audit for it. Corrected in place with the original wording quoted and the disproof recorded, not silently rewritten. RM-02 fifth clause: documentation asserting a security or integrity property is itself a claim requiring a negative control observed red. Prose is not exempt from the mission's evidentiary standard, and governing prose least of all. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
43f69bf167 |
docs(remediation): promote D-19 to charter; bind residual risk to RM-59 as a tracked edge
Per Mos, with his two additions. Charter gains a fourth first-class principle: when a property cannot exist at the layer that specified it, three honest moves are mandatory — implement what the layer can guarantee; state the boundary in BOTH directions (what it does not defend AND what it does, since either alone misleads); and record the real guarantee as a TRACKED DEPENDENCY, not prose. A written-down gap is acceptable engineering; an implied-fixed gap is the mission's core failure in a new costume. The residual risk is now RM-59 (depends_on RM-12, RM-21, RM-25) — a real backlog task owned by the choke-point executor and spine, which verify from outside the worktree's authority. Mos's point: 'record where the guarantee comes from' only holds if the record is a live dependency someone must close; a documented gap with no owner becomes a permanent gap that reads as intentional. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
f9435c2a03 |
docs(remediation): bank D-19 — an integrity property that cannot exist at its specified layer
Implementing the D-18 manifest hit CWE-345: manifest and marker share one same-UID writable tree, so that actor can regenerate both and pass. No local construction fixes self-authentication without a key outside its authority. The seat escalated rather than calling it tamper-resistant — the charter corollary working on its first real test. Ruling: Option A, scope AC2 to accidental/independent/stale mutation, retain the design. The undefendable boundary is not the weak link (same-UID write already owns the source, the tests, preflight.mjs and .husky); AC2 exists for the D-5 staleness class, against which the design works; and a real anchor arrives with the choke-point executor and PG spine, which verify outside the worktree's authority. Acceptable only with honest labelling: threat model verbatim in code and PR, the words tamper-proof/tamper-evident/secure barred there, scope carried in AC2's restatement, residual risk named as backlog, all controls kept RED-first. Generalizable: when a property cannot exist at the layer it was specified, implement what the layer can guarantee, state the boundary precisely, and record where the real guarantee comes from. A known gap written down is acceptable; a gap implied fixed is not. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
85bdbe3383 |
docs(remediation): bank D-18 — pre-registered criteria AC2 and AC4 were mutually unsatisfiable
Implementing D-17's fix surfaced a conflict between criteria, not within one. AC2 (reject symlinked generated state) cannot hold alongside AC4 (canonical build succeeds): verified independently that apps/web sets output:'standalone' and the built tree carries 42 legitimate pnpm symlinks under .next/standalone. Only building the tree reveals it. Completes the chain: a pre-registered check set can be WRONG (D-8), INCOMPLETE (D-17), or INTERNALLY INCONSISTENT (D-18). Ruling: build-certified symlink manifest — .next itself still rejected; descendants rejected unless exactly certified. Stronger than blanket rejection because it catches retargeting. AC2 restated and RECORDED with provenance rather than absorbed, since silently resolving a conflict between pre-registered criteria destroys the point of registering them. Hardening: the manifest is generated state, so a manifest writable by whoever plants a rogue symlink certifies the attack. Must be inside the integrity envelope, published atomically, with negative controls observed red first including manifest-tampered. RM-02 fourth clause: the registry must detect conflicts between criteria, and retain original text plus restatement plus reason when a criterion changes meaning. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
ae4baf145d |
docs(remediation): bank D-17 — pre-registration confers neither correctness nor coverage
rev-974 blocked PR #1027: AC2 was pre-registered and explicitly required rejecting symlinked generated state; the implementation accepts it (ln -s into .next, preflight exits 0 instead of 43) while the acceptance suite ran 21/21 green throughout. Confirmed independently: preflight.mjs:82-92 rejects symlinks on the SOURCE path, :28 merely skips symlinked dirs, and the generated-state path :141-163 checks uid but never isSymbolicLink(). The suite's only symlink cases cover the turbo binary and a source file. Sharpens D-8 rather than repeating it. D-8: pre-registration does not confer CORRECTNESS. D-17: it does not confer COVERAGE — a suite can be green with every criterion appearing satisfied while a criterion's actual requirement is untested. RM-02 third clause: the registry must bind each criterion to the specific case that exercises it and prove that case red before trusting its green. Mutation testing pointed at the criterion-to-case mapping, not just the gate. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
4512312b9f |
docs(remediation): D-16 ownership — #1024 is Jason-pending; CI is the authoritative gate for #1027
Propagating Mos's ruling in the same commit that records it, per D-14's interim rule. The hermeticity fix IS PR #1024, which sits in Jason's parked delivery stack, so its disposition is his — marked SUPERSEDED-PENDING-JASON alongside #1023. D-16 strengthens urgency without transferring ownership; we do not open a third lane on a parked PR. Class sharpened: a pre-push gate an operator cannot run locally is a gate only CI enforces, so pointing .husky/pre-push at it misrepresents where the gate lives. Non-hermetic gates make every green host-dependent. #1027 proceeds on CI-green; the local exit-97 is a host-specific guard abort and is not a merge consideration. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
e233f196b5 |
docs(remediation): bank D-16 — local and CI test gates disagree by environment
Ran down Mos's flag. Both hypotheses were wrong: CI runs exactly 'pnpm test' (same command, path IS exercised) and is green, while this host exits 97 on an environment-dependent BASH_LINENO guard (#973) that aborts on bash 5.2.15 and not in CI's container. PR #1027 touches zero files under packages/mosaic, so the guard is genuinely pre-existing — f10-coder's report was accurate in every particular, and main is equally affected here. Not 'merges step around a red' but something worse in one respect: the local gate and the CI gate disagree about what passing means. No agent on this host can get a green pnpm test on any branch. A gate only CI can run cannot be a pre-push gate. Second defect found while establishing this: in the main checkout the same package fails differently (exit 1) because a test scans the working tree and picks up apps/coordinator/venv third-party site-packages. A test whose verdict depends on untracked files is not hermetic — same contamination source that broke format:check, one foreign tree breaking two independent gates. Coordinate with #1007/#1024 rather than opening a third lane. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
3477e933df |
docs(remediation): bank D-15 — token scope is not repository permission
f10-coder holds gitea-mosaicstack-f10-coder.token with write:repository scope and was verified at mint by 'repo access returns 200'. It cannot push: collaborator lookup 404s and its own token reports push:false, pull:true. Capability has three independent layers — token file (raw-API auth), tea login (tea path), repository permission (actual write authority) — and satisfying two proves nothing about the third. Scope bounds what a token may ATTEMPT; repository permission decides what the user may DO. The charter principle failing on the check meant to confirm capability: a 200 on a READ was accepted as evidence of WRITE. written-unverified treated as verified, by both provisioner and orchestrator, one layer above D-12. RM-50's pre-dispatch check must assert effective permission for the intended operation (permissions.push == true as that seat), not token existence or a read returning 200. A capability check that cannot fail on a seat lacking write permission is itself an inert gate. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |