chore: la troisieme ronde adverse a rendu son rapport, le Result le porte

Le Result disait que la troisieme passe n'avait pas rapporte et que
56072df n'avait donc pas de revue tierce. C'est faux depuis qu'elle a
rendu : elle refute 226db18 sur exactement le point trouve par
enumeration, reproduit independamment, confirme que 56072df le corrige,
et ne trouve rien d'autre. Sa porte et son balayage anti-triche sont
consignes.

Son unique observation - le rejeu capture lastState au lieu de le
relire - a ete sondee : la remise a lieu tant que la barriere TIENT, et
aucun ordonnancement ou la capture differe d'une relecture n'a pu etre
construit. La relecture a ete ecrite puis RETIREE, faute de test qui
discrimine ; elle est consignee en suivi, pas en correctif.
This commit is contained in:
Sylvain Duchesne
2026-09-24 13:55:01 +02:00
parent c3e07d2ce4
commit 6de87a9edd
@@ -106,7 +106,7 @@ VERIFIED: there is no sign-out, `disconnect` or `session_stop` path in `src`; `s
## Result ## Result
Status: done, with one caveat named under the adversarial rounds: the third adversarial pass, launched on `226db18`, had not reported when this was written, so `56072df` carries no third-party review. `1.0.0-dev.10`, major on the conservative reading. Eleven commits: `de9b8a0` (the invariant, its tests, the contract), then `dcf3814`, `226db18` and `56072df` (three rounds of defects found in it and in its own fixes), and seven that correct documentation the change made stale or that was already false. Whole change: **12 files, 902 insertions, 223 deletions** (`git diff 2da26c5..HEAD --shortstat`). One independent adversarial pass was run on the delivered state. Status: done. Three independent adversarial passes, all three reported. `1.0.0-dev.10`, major on the conservative reading. Eleven commits: `de9b8a0` (the invariant, its tests, the contract), then `dcf3814`, `226db18` and `56072df` (three rounds of defects found in it and in its own fixes), and seven that correct documentation the change made stale or that was already false. Whole change: **12 files, 902 insertions, 223 deletions** (`git diff 2da26c5..HEAD --shortstat`). One independent adversarial pass was run on the delivered state.
### The invariant, in one sentence, and where it is written ### The invariant, in one sentence, and where it is written
@@ -177,7 +177,11 @@ Fixed at the source in `226db18`: a failed establish FORGETS its barrier, as `re
Fixed in `56072df` at the WRITE, not by restoring the mask: `if (type === "State" && entry.establishing)`. **`lastState !== null` now IMPLIES an attempt stands, at every write as well as at every clear**, so the two cannot disagree and no reader has to re-impose it. The push is still fanned out to listeners - a caller may want the change signal; only the BARRIER is a claim about the document. Pinned by "a State that lands AFTER the call was reported failed is not a barrier"; dropping the guard kills exactly it. Fixed in `56072df` at the WRITE, not by restoring the mask: `if (type === "State" && entry.establishing)`. **`lastState !== null` now IMPLIES an attempt stands, at every write as well as at every clear**, so the two cannot disagree and no reader has to re-impose it. The push is still fanned out to listeners - a caller may want the change signal; only the BARRIER is a claim about the document. Pinned by "a State that lands AFTER the call was reported failed is not a barrier"; dropping the guard kills exactly it.
**The fix was re-reviewed rather than trusted.** Two independent adversarial passes reported: the first on `de9b8a0` (three findings, all confirmed and fixed), the second on `dcf3814` (one finding, confirmed and fixed). **A third was launched on `226db18` and its report had not arrived when this was written** - stated plainly rather than claimed as a verdict. What that pass was asked to attack first is the question `56072df` answers: I put the same question to the code myself, by enumerating every write, and it is what found the third defect. The next reviewer should still take that pass's report when it lands, and treat `56072df` as unreviewed by a third party until then. **The fix was re-reviewed rather than trusted, three times**, each pass on the previous one's fix rather than on the original - because twice in this task family a fix had traded one bug for a worse one, and here it did so twice more.
**The third pass reported after this Result was first written, and its verdict is recorded here rather than left in a transcript.** It REFUTED `226db18` on exactly the point I had already found by enumeration - reproduced independently on a pristine `226db18` extract, `docChannel = {"state":"none","barrierCrossed":true}` and `getSyncState = "synced"` - and confirmed that `56072df` fixes it, its own probe passing and the pin test dying when the guard is mutated away. **It found no other defect**: the superseded-rejection attack, the strictness-costing-a-success attack, `stillStanding`, `incarnation`, `disowned()` and `resetOpenedRepos` all resisted. Its independent gate: `bun test` x8 -> `461 pass / 0 fail` every run; both `tsc` exit 0; `lint.py` 0 ERROR; `open-repo.test.ts` x15 and `subscribe.test.ts` x12 with no flake and the `>=150 / <60` pair never close. Its **anti-cheat sweep of `2da26c5..HEAD`**: 0 tests removed, 0 `.skip`/`.todo`, 0 `any` / `@ts-ignore` / `as unknown as` added in `src`, 0 `expect(` lines deleted, 57 added. It ran every probe on `git archive` extracts and never wrote to the project tree.
**Its one non-defect observation, checked rather than filed on trust.** `subscribeDocUnguarded`'s replay CAPTURES `lastState` and delivers it a microtask later instead of re-reading it, so in principle a joiner could be handed a barrier forgotten in between. I probed it: the delivery happens while the barrier still STANDS (the rejection's continuation is several microtask hops behind the replay's), and I could not construct any ordering where the capture and a re-read differ. I wrote the re-read anyway, could not make a test discriminate, and **reverted it** rather than ship an unpinned behaviour claim into a task whose whole lesson is that a claim carries its measurement. It is a follow-up below, stated as what it is: not a defect today, and not proven safe for all orderings either.
### Mutation-tested, eleven ways ### Mutation-tested, eleven ways
@@ -233,5 +237,6 @@ Killed by the adversarial round's own three: **R1** restoring `"synced"` on `bar
- `forgetEverything()` (test-only) never clears `surface/inbox.ts:314` `seenByInbox`, `inbox-drain.ts:25` `running`, `branch-registers.ts:743` `openInboxInFlight` or `connect.ts:94` `inFlight`. Cross-test leakage waiting to happen. - `forgetEverything()` (test-only) never clears `surface/inbox.ts:314` `seenByInbox`, `inbox-drain.ts:25` `running`, `branch-registers.ts:743` `openInboxInFlight` or `connect.ts:94` `inFlight`. Cross-test leakage waiting to happen.
- Two `@provenance` lines I added carry an em dash, because `docs/api-contract.md:23` documents the em dash as that annotation's note separator. Two other lines in the diff carry a pre-existing `->` arrow I did not introduce. Everything else I authored is ASCII. - Two `@provenance` lines I added carry an em dash, because `docs/api-contract.md:23` documents the em dash as that annotation's note separator. Two other lines in the diff carry a pre-existing `->` arrow I did not introduce. Everything else I authored is ASCII.
- `.project/concepts/app-contract/_debt.md` now carries six markers, one of them from this work (`surface/subscribe.ts`, and the contract review it asks for was done). Consolidating the file is its own chore. - `.project/concepts/app-contract/_debt.md` now carries six markers, one of them from this work (`surface/subscribe.ts`, and the contract review it asks for was done). Consolidating the file is its own chore.
- `surface/subscribe.ts`'s replay captures `lastState` rather than re-reading it inside the microtask. No ordering could be constructed where that differs from a re-read (see above), so it is not a defect today; it is the one path that could in principle hand out a barrier after it was forgotten, and a re-read is a four-line hardening if someone can build the case for it.
- `docs/internal-contract.md:7` still names `surface/watch-shape.ts`, `surface/read-model.ts` and a `storeRegistry` namespace listing three removed symbols. Pre-existing, outside section 6, left alone as that document's own note says. - `docs/internal-contract.md:7` still names `surface/watch-shape.ts`, `surface/read-model.ts` and a `storeRegistry` namespace listing three removed symbols. Pre-existing, outside section 6, left alone as that document's own note says.