Plan 282fabbb (Filbert) and the six adversarial rounds (Rocko, r6 80cde839). Lead item 15: Gate F first, then A1 and A2 as separate reviewed commits. Co-Authored-By: Claude Opus 5.5 <[email protected]>
171 lines
10 KiB
Markdown
171 lines
10 KiB
Markdown
# Queue as data — adversarial review, round 4
|
||
|
||
VERDICT: revise
|
||
|
||
Rocko for Sage, 2026-09-26. Plan SHA-256 verified before reading:
|
||
`14dccfd07325347b1905320ecc739f50d9729a509fbf2355ab52822567cee63f`.
|
||
Target: active section 8, based on `124b6f9e…0d26`, against round-three
|
||
T1–T8. Sage's confirmed choices in 8.15 are accepted. No policy decision
|
||
is reopened. This report is the only write for this review; no code,
|
||
runtime, token or git state was changed.
|
||
|
||
Most previous findings now have concrete dispositions. Four remaining
|
||
findings are below; F1/F2 are the main blockers. A small fifth consistency
|
||
fix is included for the builder. Failure schedules are design analysis,
|
||
not executed fault-injection tests against queue code that does not exist.
|
||
|
||
## 1. High — the HEAD/shared-index gap can make another normal commit roll back the queue
|
||
|
||
**Where:** 8.12 steps 6–7; remaining part of T5.
|
||
|
||
The private index prevents sweeping unrelated staged files into *this*
|
||
commit, and expected-old-value update-ref correctly detects an earlier
|
||
HEAD change. It does not protect the interval after the branch update.
|
||
|
||
**Concrete schedule:**
|
||
|
||
1. Shared index and HEAD contain queue revision 10. Another seat has staged
|
||
an unrelated source change, obeying “seats never stage queue files.”
|
||
2. Lead creates and publishes commit C with queue revision 12 using the
|
||
temporary index and update-ref. The shared index still holds revision 10.
|
||
3. Before step 7, the other seat commits its shared index. Its parent is C,
|
||
but its tree includes queue revision 10, unintentionally reverting the
|
||
queue. It never explicitly staged a queue change.
|
||
4. Lead's step 7 updates the shared index to revision 12, now against the
|
||
other seat's later HEAD. Or step 7 fails on index.lock and leaves the
|
||
rollback staged against C until manual intervention.
|
||
|
||
**Fix:** retain the approved private-index/exact-tree approach, but add an
|
||
explicit cooperative exclusive *git integration* interval covering HEAD
|
||
publication and shared-index reconciliation. All ordinary commit writers
|
||
must participate, not just queue writers. If reconciliation fails, leave a
|
||
clear maintenance hold against further commits until the shared index is
|
||
correctly rebased/reconciled against the actual HEAD. Recheck HEAD and the
|
||
queue entries before touching them; do not overwrite later staging using
|
||
only the initial guard. No queue lock need be held across tests/git.
|
||
|
||
**Acceptance:** pause immediately after update-ref, attempt an ordinary
|
||
commit of unrelated staged source, and prove the protocol prevents the
|
||
rollback. Also cover step-7 index-lock failure, changed HEAD, and later
|
||
staging of a queue path. Preserving unrelated index entries alone is not
|
||
enough; their relationship to HEAD matters.
|
||
|
||
## 2. Medium — unlocked reads can falsely diagnose lost history during a normal write
|
||
|
||
**Where:** 8.4 unlocked reads, 8.5 witness comparison; T1/T2 follow-through.
|
||
|
||
**Concrete schedule:** a reader loads queue revision 10. The writer
|
||
durably replaces queue.json and the witness with revision 11. The reader
|
||
then loads witness 11 and compares it to its earlier queue bytes. The
|
||
comparison says “history lost,” although no history was lost. Reversing
|
||
read order gives the opposite transient mixture: witness 10, queue 11.
|
||
Atomic replacement of each file does not make the pair an atomic read.
|
||
|
||
**Fix:** give reads a coherent snapshot protocol. Simplest is the existing
|
||
queue lock; alternatively perform bounded re-reads and validate that the
|
||
witness did not change across reading the queue, with a retry/busy result
|
||
for concurrent change. A read-only transient mismatch must not recommend
|
||
accept-history before rechecking a stable pair. Preserve the distinction
|
||
between an actual unconfirmed tail and a writer still publishing.
|
||
|
||
Also distinguish `verify --snapshot` from canonical witness-aware verify:
|
||
the former checks the supplied immutable pair; it cannot certify live
|
||
witness continuity and should not claim it does.
|
||
|
||
**Acceptance:** reader paused between queue/witness reads in both orders;
|
||
writer paused before and after witness rename; true rollback; deleted
|
||
witness. Normal writers must not provoke a history-reset diagnostic.
|
||
|
||
## 3. Medium — first commit and snapshot verification have no complete bootstrap path
|
||
|
||
**Where:** 8.2 genesis and 8.12 steps 3–5; residual T5/T8.
|
||
|
||
**Scenario:** genesis succeeds, but HEAD has no queue.json yet. The commit
|
||
script requires HEAD's committed queue log and requires the snapshot to
|
||
extend it. There is no declared empty-base/genesis exception. If queue
|
||
code itself has not been committed first, HEAD's archived queue tests and
|
||
validator also do not exist. The script cannot perform the first queue
|
||
commit as specified.
|
||
|
||
There is also an execution-context omission: `git archive H` extracted
|
||
into a temp directory has no git object database. Its snapshot verifier
|
||
cannot read `HEAD`/H's queue blob from that directory unless the caller
|
||
passes the base bytes or an explicit source repository. The snapshot
|
||
exception permits execution there, but does not supply those bytes.
|
||
|
||
**Fix:** specify the bootstrap sequence: approved queue implementation
|
||
committed first under normal source integration; then verified genesis
|
||
committed with a narrowly defined absent-base exception, requiring exactly
|
||
the reviewed genesis (and any explicitly allowed migration operations).
|
||
Supply the base queue blob and commit/tree identity to the isolated
|
||
validator, or explicitly read them from the canonical object database.
|
||
Do not resolve them from an ambient unrelated cwd.
|
||
|
||
The temporary index must be a valid index or a nonexistent file path;
|
||
`mktemp` creates an empty file, so specify initialization accordingly rather
|
||
than assuming every git operation accepts that as an index. These are
|
||
bounded implementation details, not a request for another commit feature.
|
||
|
||
**Acceptance:** fresh implementation-only HEAD, first genesis commit,
|
||
later extending commit, missing base in a non-bootstrap case, and archived
|
||
validator execution outside any repository.
|
||
|
||
## 4. Medium — no parentSession does not prove a fresh session
|
||
|
||
**Where:** 8.11 pins and negative controls; residual T6.
|
||
|
||
**Scenario:** a normal previously used Pi session is resumed. Its original
|
||
header still has no parentSession; that field describes a fork, not every
|
||
resume. The audit interval begins at Jason's new instruction, so prior
|
||
coaching/user turns can be outside the counted chain. The listed negative
|
||
control “resumed or forked session (parentSession present)” fails to cover
|
||
ordinary resume.
|
||
|
||
**Fix:** keep the new execution-trace checks, which are good. Separately
|
||
prove freshness from the actual launch: new session id/file created for
|
||
that launch, header timing consistent with it, and no earlier user/model
|
||
history, inherited compaction or branch-summary context. Pin these before
|
||
the instruction and after the observed work. Test an ordinary resumed
|
||
session whose header has no parentSession, not only a fork.
|
||
|
||
An input on an abandoned branch can still have coached the same agent
|
||
before it retraces a branch. For the deliberately short Gate G interval,
|
||
the conservative manual rule is to reject additional user input anywhere
|
||
in that session during the interval, while following the active ancestry
|
||
for the execution trace. Alternatively exclude branching in the demo.
|
||
Neither choice requires a checker package or new runtime identity.
|
||
|
||
## 5. Low — generated outcome IDs can violate the declared op length
|
||
|
||
**Where:** 8.6 and 8.9.
|
||
|
||
An external request op may be 80 characters, but appending `.outcome` makes
|
||
the system-generated op 88 characters. If log entries share the declared
|
||
op schema, a valid request can never record its outcome. Define separate
|
||
external/internal length limits or reserve the suffix budget in accepted
|
||
request IDs, and test both boundaries. The reserved suffix otherwise
|
||
provides a reasonable one-attempt/one-outcome identity scheme.
|
||
|
||
## T1–T8 disposition
|
||
|
||
| Prior finding | Round-four assessment |
|
||
|---|---|
|
||
| T1 durability | Substantively addressed: platform assumptions, distinct barriers, no success/POST after failed persistence, sync, and explicit power-loss evidence limits. Witness reads still need F2. |
|
||
| T2 git rollback | Addressed within the accepted cooperative model: branch pin, baseline check, witness, preservation/reconciliation and explicit accept-history with lost-range guarantee withdrawal. F2 prevents false diagnoses; F1 prevents ordinary integration from creating rollback. |
|
||
| T3 lock cleanup | Addressed: complete checked temp record, host-first classification, full record/inode release and same rules for gate cleanup. Retain manual quiescence when removing a classified stale gate. |
|
||
| T4 review uncertainty | Addressed at design level: requesting blocks across the row, no negative resolution, explicit duplicate-risk abandonment, immutable attempts, conflict handling, reserved outcome identity and move-to-review linkage. F5 is a schema consistency correction. Bound pre-send identity GET and resolution GET too, not just POST, when implementing. |
|
||
| T5 integration | Partly addressed: exact prospective bytes, isolated index, source-tree tests and expected-HEAD publication. F1 and F3 remain. |
|
||
| T6 Gate G | Execution trace, results, timing, successful work and cooperative context audit are substantially improved. Freshness/branch-input proof remains F4. |
|
||
| T7 coverage | Addressed: fail/incomplete/reduced-pass; no full liveness claim; unknown PID and legacy age are explicit. Approved reduced scope is respected. |
|
||
| T8 consistency | Ordinary-add fields, claim lifecycle/J5 precedence, pinned working briefs and B context-file scope are addressed. Genesis-to-first-commit is F3. |
|
||
|
||
The witness is treated as an approved check value, not challenged as a new
|
||
architecture. Same-seat concurrency and same-user history rewriting remain
|
||
the accepted limits; this review does not request authenticated authority.
|
||
The remaining fixes are bounded lead/builder decisions. No new Jason
|
||
ruling is needed to close them.
|
||
|
||
This review was completed while waiting for Darkwing's pinned #1509 6b
|
||
handoff. That review retains priority as soon as it arrives. No conclusion
|
||
about 6b or restart approval follows from this queue review.
|