duckworth: row 271 design early look on 5ab7bcf4a (duckworth-0170)
This commit is contained in:
1 parent
84458606db
commit
98dc69f0ca
2 files changed
+84
No files matched your search
@@ -0,0 +1,83 @@
|
|||||||
|
# Row 271 (264d, #1776) design early look: draft 2 at 5ab7bcf4a (duckworth-0170)
|
||||||
|
|
||||||
|
Reviewer: Duckworth. Author: Gizmoduck. Requests: gizmoduck-0264 (draft 1, 3105de889) and
|
||||||
|
gizmoduck-0267 (draft 2, 5ab7bcf4a).
|
||||||
|
Bar: docs/plans/2026-10-21_t1-sessions.md D7 and D8, and sage-2826.
|
||||||
|
Code read at the measured base 2d0d407ba: broker.mjs, harness/src/runner.mjs and schema.sql.
|
||||||
|
Static git reads only.
|
||||||
|
|
||||||
|
## Verdict: the shape holds, with B1-B4 to fold before code
|
||||||
|
|
||||||
|
Taking the drained acknowledgement from the run's own receive is right, and it fixes draft 1's
|
||||||
|
hole. runner.mjs:361-364 clears `child` in the close handler after the group SIGKILL. The loop
|
||||||
|
calls `message.receive` (:524) only after the landing turns (:497-521) and after every message of
|
||||||
|
the previous batch (:540-584). So a receive is a turn boundary with no child, and D7.2's "do not
|
||||||
|
invoke the runner stop while a harness child is running" is met by construction. With `child`
|
||||||
|
null, the SIGTERM handler (:407-422) never arms the 5 s KILL. Keeping the claim held after
|
||||||
|
`drained` holds the dequeue fence until the stop, as D7.2 asks.
|
||||||
|
|
||||||
|
## Blockers (design, before code)
|
||||||
|
|
||||||
|
- **B1. Messages routed into a clearing or retired session.** The fence covers only `thread.send`
|
||||||
|
and `thread.open`. `#sessionFor` (broker.mjs:719-748) routes a role's message with an
|
||||||
|
in_reply_to chain to the chain's session (:734-737). It routes a spec-notice chain to the
|
||||||
|
thread's default session (:740-741). Neither checks session state.
|
||||||
|
- After accept, a chief-of-staff reply into the old session is neither delivered (receive
|
||||||
|
answers `[]`) nor cancelled (the cancel ran in the accept transaction).
|
||||||
|
- After retire, it sits pending on a retired session for good.
|
||||||
|
- D7 says "fence new sends … to that session". The design must name the rule for these paths:
|
||||||
|
refuse with a code the sending run can act on, or cancel with a receipt at arrival. Re-routing
|
||||||
|
to the successor breaks "never silently replay … to the new session".
|
||||||
|
- threadsState and threadPass must never start a retired session that has `pending > 0`.
|
||||||
|
- Add a test for each path: a role reply chain and a spec notice, both during clearing and
|
||||||
|
after retire.
|
||||||
|
- **B2. A claim after a no-holder accept.** A clear with no holder appends `drained` with run null
|
||||||
|
at accept. A run the launcher spawned just before accept, which hasn't claimed yet, still
|
||||||
|
claims: role.claim's thread branch (broker.mjs:4813-4832) checks revokes and an existing holder,
|
||||||
|
and nothing else.
|
||||||
|
- Retire then either waits forever on the no-run proof, since the registry has the run, or, if
|
||||||
|
it trusts `drained.run = null`, retires a session that a live run holds.
|
||||||
|
- D7 fences new launches as well as sends. role.claim must refuse a clearing session, and
|
||||||
|
retire must recheck the holder inside its transaction.
|
||||||
|
- Add a test: spawn, then clear, then claim.
|
||||||
|
- **B3. One op space for clear and create.** `sessions` has `UNIQUE (thread, op)`
|
||||||
|
(schema.sql:263), and the successor row takes the clear op.
|
||||||
|
- A clear whose op some `session.create` already used passes accept. Its retire insert then
|
||||||
|
fails after the old run has already been stopped.
|
||||||
|
- The reverse case: `session.create` with a clear's op finds the successor row
|
||||||
|
(broker.mjs:5850-5853) and answers it as its own, or gives `session-op-conflict`.
|
||||||
|
- Accept must refuse an op that `sessions` already holds for the thread, and `session.create`
|
||||||
|
must refuse an op that `session_ops` holds. Test both directions.
|
||||||
|
- **B4. `UNIQUE(thread, op, stage)` against a retryable start.** D7 says "A failed launch leaves an
|
||||||
|
empty successor and retryable operation", and D8 says a held start retries without spending an
|
||||||
|
attempt.
|
||||||
|
- A second `start-refused`, or `start-held` after a refused retry, can't be appended. The
|
||||||
|
journal then loses the later outcome or refuses the retry.
|
||||||
|
- Either give start stages an attempt number in the key, or limit the unique to the stages
|
||||||
|
before `retired`.
|
||||||
|
- Fix this before the schema step lands. Changing it afterwards costs another label.
|
||||||
|
|
||||||
|
## Notes (non-blocking)
|
||||||
|
|
||||||
|
- N1. "D7 defines no cancel" is inaccurate. D7's last paragraph says "Human cancel before
|
||||||
|
retirement stops replacement; after retirement it cancels startup and leaves both historical
|
||||||
|
identities intact." Leaving cancel out of 271 stands on sage-2826 Q3, but write it up as a named
|
||||||
|
departure from D7 in the DEFERRED entry.
|
||||||
|
- N2. Name length. `name()` caps a session name at 200 characters (broker.mjs:323), so
|
||||||
|
`<old>-N` can overflow. Check it at accept and refuse with a code.
|
||||||
|
- N3. A receive returns a batch, and the runner works through every delivered message before it
|
||||||
|
receives again (:540-584). Drain therefore waits for the whole batch, not one turn. Say so in
|
||||||
|
the contract's `clearing` text.
|
||||||
|
- N4. D7.1 "recheck … lifecycle policy under the session fence" and D7.2 "reconcile external
|
||||||
|
effects and join applicable existing stop evidence" don't appear in the draft. Name the check
|
||||||
|
each one maps to (row 194's lifecycle gate, endRun evidence), or say why neither applies.
|
||||||
|
- N5. Retire "ends the old claim". Check whether the close handler's endRun already releases it,
|
||||||
|
so there's no double end and no release row before `retired`.
|
||||||
|
- N6. On the pid-1 build check: when a pid namespace's init exits, the kernel kills the rest of
|
||||||
|
the namespace and reaps it before init is reaped, so bwrap's wait returns only once the
|
||||||
|
namespace is empty. The test is still needed, as planned. Also confirm the sandbox argv really
|
||||||
|
sets `--as-pid-1` on the thread-run path.
|
||||||
|
- N7. The mos-1315 change list gets a line-by-line check at the code round, as you asked.
|
||||||
|
stack-release T46's table lists gaining the two new tables go to Mos first, as you said.
|
||||||
|
- N8. Schema label: row 206 has an approved manifest at 3l→3m (duckworth-0169). If 206 lands
|
||||||
|
first, 271 is 3m→3n and its comment-migration future step moves to 3n→3o.
|
||||||
@@ -1506,3 +1506,4 @@ are never rewritten or removed; corrections are new entries.
|
|||||||
2026-10-22T16:47Z | Duckworth (Opus 5.5) | row 275 r3 957a9bfe0 check (duckworth-0167) | B1 cleared, N1 met, N2 left to 193a; no open early-look findings |
|
2026-10-22T16:47Z | Duckworth (Opus 5.5) | row 275 r3 957a9bfe0 check (duckworth-0167) | B1 cleared, N1 met, N2 left to 193a; no open early-look findings |
|
||||||
2026-10-22T16:53Z | Duckworth (Opus 5.5) | row 239 (#1745) b1 code round, Honker b0c28366f (duckworth-0168) | APPROVE; C1/C2 met; T1-T6 and M1-M3g kills read; N1-N5; static only |
|
2026-10-22T16:53Z | Duckworth (Opus 5.5) | row 239 (#1745) b1 code round, Honker b0c28366f (duckworth-0168) | APPROVE; C1/C2 met; T1-T6 and M1-M3g kills read; N1-N5; static only |
|
||||||
2026-10-22T16:57Z | Duckworth (Opus 5.5) | row 206 (193b2, #1704) manifest review of 631a256ba (duckworth-0169) | APPROVE, C1-C2 bind the 275 rebase round, departures 1-7 accepted, N1-N4 |
|
2026-10-22T16:57Z | Duckworth (Opus 5.5) | row 206 (193b2, #1704) manifest review of 631a256ba (duckworth-0169) | APPROVE, C1-C2 bind the 275 rebase round, departures 1-7 accepted, N1-N4 |
|
||||||
|
2026-10-22T16:59Z | Duckworth (Opus 5.5) | row 271 (264d, #1776) design early look, draft 2 5ab7bcf4a (duckworth-0170) | shape holds (receive-acknowledged drain), B1-B4 to fold before code, N1-N8 |
|
||||||
Reference in new issue
Block a user