Reconcile docs with reality; fix module graph, token compare, health #1
@@ -1716,3 +1716,77 @@ Fixed in the phase brief: the terminal phase now states the marker, when to
|
||||
write it, and that it is exclusive with asking to go back.
|
||||
`TestTerminalPhaseNamesTheCompletionSignal` also asserts the negative, so a
|
||||
phase that can still ask is never told to finish instead.
|
||||
|
||||
### F41: harness chrome counted as agent progress
|
||||
|
||||
Run 5's review agent produced nothing after 02:12. The 02:46 renewal was
|
||||
granted anyway, and the lease moved to 03:16. Each renewal window bought
|
||||
another 30 minutes, so recovery by expiry had no bound.
|
||||
|
||||
Reproduced the worker's stored `progress_sha` byte for byte from the live pane,
|
||||
so the branch taken at `cmd/orchestra-worker/main.go:1020` was
|
||||
`progress != l.ProgressSHA`. Not `IsBusy`: the 200-line capture held zero
|
||||
`esc to interrupt` markers, so `AgentStatus` returned `idle`. Not an empty
|
||||
baseline either: it held `3d93ca89`.
|
||||
|
||||
`PaneProgress` dropped prompt lines only, so Claude Code's status footer stayed
|
||||
in the digest. The mutable fields there are the rolling usage percentage, the
|
||||
context counter, and the version notice. A 180-second sample showed no churn, so
|
||||
this leaked intermittently rather than constantly. One tick inside a window was
|
||||
enough.
|
||||
|
||||
Fixed in `2417a39`. `PaneProgress` cuts from the editor's lower rule and then
|
||||
trims the spinner summary and version notice above it. `AgentStatus` still reads
|
||||
the raw capture, so the busy markers living in the footer are unaffected.
|
||||
|
||||
Proven live in both directions on the first window after deployment: the
|
||||
03:13:48 renewal took version 28, the 03:16:13 window was refused, the lease
|
||||
expired at 03:18:43, and review relaunched at 03:20:14 with the F40 brief. The
|
||||
relaunched pane then showed a new footer field, `5h: 15%`, which the old digest
|
||||
would have counted as work.
|
||||
|
||||
Lease TTL moved to 5 minutes in the same commit, from `domain.LeaseTTL`, with
|
||||
renewal at half of it. Reclaiming a stalled pane happens only at expiry.
|
||||
|
||||
### F42: the result commit refused the completion marker
|
||||
|
||||
The relaunched review agent wrote `.orchestra/done` at 03:20:48, 34 seconds
|
||||
after launch. The worker recognised it, confirmed the agent idle, and then
|
||||
failed the result commit once every five seconds:
|
||||
|
||||
```text
|
||||
stage result: The following paths are ignored by one of your .gitignore files:
|
||||
.orchestra/done
|
||||
```
|
||||
|
||||
`internal/herdr/adapter.go:132` writes `.orchestra/.gitignore` containing `*`,
|
||||
so the marker is ignored. The staging step passed `:!.orchestra/done`, and git
|
||||
refuses an add whose pathspec names an ignored path. Reproduced in a scratch
|
||||
repo on git 2.55.0, both the failing and the working form.
|
||||
|
||||
Fixed in `dcd9af4`: the exclusion names the directory, `:!.orchestra`. That
|
||||
holds whether or not the inner `.gitignore` exists.
|
||||
|
||||
The failure retried for 22 minutes with the task stuck in review and nothing
|
||||
observable outside the journal, because each identical error overwrote the
|
||||
single `last_error` slot. F18, again, and the second time in one night that it
|
||||
turned a five-second loop into archaeology.
|
||||
|
||||
### Run 5 reached TaskCompleted
|
||||
|
||||
On the first tick after the `dcd9af4` restart at 06:47:50:
|
||||
|
||||
- task state `completed`, lease released, `.orchestra/done` removed
|
||||
- pane closed, no `orchestra-*` sessions left on the tmux socket
|
||||
- result branch pushed:
|
||||
`refs/heads/orchestra/scratch/orchestra-06g4a4f0tfxkzhje48n05xn1hg-73a2e4fd`
|
||||
at `fb15c61`
|
||||
|
||||
Two links of the tail did not run, and neither is a defect. The deployed
|
||||
`test-e2e` project declares only `id`, `machine_affinity`, `repo` and
|
||||
`worktree_root`, so no quality gate exists to run. The deployed `config.jsonc`
|
||||
has no `sources` and no `delivery` keys, so no PR could be opened.
|
||||
|
||||
Proven chain: review, done recognised, finalise, result branch pushed,
|
||||
`TaskCompleted`. Submission, human PR review and merge remain unproven, and they
|
||||
need registry configuration rather than code.
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
# Handoff: run 5 reached TaskCompleted, plan machinery is designed and frozen
|
||||
|
||||
Written 2026-08-28, 06:55 local (02:55 UTC). Read with `BURNIN.md` (the ledger,
|
||||
now current through F42), `PLAN-SPEC-DESIGN.md` (the locked design for the next
|
||||
change), `HANDOFF-2026-08-28-burnin-4.md` (the session before this one),
|
||||
`AUDIT.md` and `CLAUDE.md`.
|
||||
|
||||
Everything below was observed live unless it says otherwise.
|
||||
|
||||
## The headline
|
||||
|
||||
Run 5 finished. Task `06G4A4F0TFXKZHJE48N05XN1HG`, issue `kami/test-e2e#5`,
|
||||
reached `TaskCompleted` at 06:48 after two defects were found and fixed in the
|
||||
completion tail.
|
||||
|
||||
```text
|
||||
frame -> research -> plan -> implement -> review -> done -> finalise -> pushed -> completed
|
||||
```
|
||||
|
||||
Two defects, both live-proven fixed:
|
||||
|
||||
- **F41**: harness chrome counted as agent progress, so a stalled lease renewed
|
||||
without bound.
|
||||
- **F42**: the result commit refused the completion marker, so completion could
|
||||
never happen.
|
||||
|
||||
## Deployed state
|
||||
|
||||
| Half | Revision | Evidence |
|
||||
|---|---|---|
|
||||
| Worker, workpc systemd | `dcd9af4` | PID 3634937, started 06:47:50, sha256 `25b41562…`, journal prints the revision at startup |
|
||||
| Coordinator, homesrv container | `bcaf0cc` | **stale**, see below |
|
||||
|
||||
Branch `webui-and-audit-reconciliation`, HEAD `dcd9af4`.
|
||||
|
||||
```text
|
||||
revision dcd9af4806376caf091e18f669ab52f1ba0dc9df
|
||||
sha256 25b415629d4a02dca7abe202245ac13f5bdb43b501bc17e371dba75b44f6cebb
|
||||
```
|
||||
|
||||
**Confirm the running worker, not the installed file.** Two restarts silently
|
||||
did not happen tonight. `sudo install` landed the new binary while the old
|
||||
process kept serving from the unlinked inode. `/proc/<pid>/exe` showed
|
||||
`(deleted)` and the old hash both times. Check
|
||||
`sha256sum /proc/$(systemctl show -p MainPID --value orchestra-worker)/exe`,
|
||||
never just the path.
|
||||
|
||||
The second missed restart cost run 5 its retry budget: the pre-F42 worker kept
|
||||
failing until the router marked the task `failed`.
|
||||
|
||||
## The coordinator is behind, deliberately
|
||||
|
||||
`2417a39` moved lease TTL to 5 minutes via `domain.LeaseTTL`, and the
|
||||
coordinator issues the initial lease at `internal/router/router.go:318`. That
|
||||
half still runs `bcaf0cc`, so new leases arrive with a 30-minute TTL. Worker
|
||||
renewals send `ttl=300` explicitly, which is why run 5 recovered anyway.
|
||||
|
||||
Rebuild when convenient, from a detached worktree, never with
|
||||
`docker compose build`:
|
||||
|
||||
```text
|
||||
git worktree add --detach /tmp/orchestra-build-dcd9af4 dcd9af4
|
||||
docker build --build-arg BUILD_REVISION=dcd9af4… -f $T/Dockerfile.api -t orchestra-web-ui-orchestra-api $T
|
||||
docker compose up -d --no-deps orchestra-api
|
||||
```
|
||||
|
||||
## What this session found
|
||||
|
||||
### F41, harness chrome counted as progress
|
||||
|
||||
The 02:46 renewal was granted against a pane idle since 02:12. Reproduced the
|
||||
worker's stored `progress_sha` byte for byte from the live pane, so the branch
|
||||
taken was `progress != l.ProgressSHA`, not `IsBusy` and not an empty baseline.
|
||||
|
||||
`PaneProgress` hashed Claude Code's status footer, whose usage percentage,
|
||||
context counter and version notice all move on their own schedule.
|
||||
|
||||
Fixed in `2417a39`. Live-proven in both directions on the first window after
|
||||
deployment: renewal at 03:13:48, refusal at 03:16:13, expiry at 03:18:43,
|
||||
relaunch at 03:20:14.
|
||||
|
||||
### F42, the result commit refused the completion marker
|
||||
|
||||
`.orchestra/.gitignore` contains `*`, so `.orchestra/done` is ignored, and git
|
||||
refuses an add whose pathspec names an ignored path. The staging step named the
|
||||
marker. Every completion attempt failed, once every five seconds, for 22
|
||||
minutes.
|
||||
|
||||
Fixed in `dcd9af4` by excluding the directory rather than the file. Reproduced
|
||||
both forms in a scratch repo on git 2.55.0 before changing anything.
|
||||
|
||||
### F18 is now the clear top item
|
||||
|
||||
Both defects tonight were five-second retry loops whose only trace was the
|
||||
journal, because each identical error overwrote the single `last_error` slot.
|
||||
`health` in the worker state file was `{}` throughout. The bounded
|
||||
recent-observation ring described in the previous handoff is the fix. This
|
||||
session adds a second concrete instance of the cost.
|
||||
|
||||
## Where the completion tail stops
|
||||
|
||||
Proven: review, done recognised, agent confirmed idle, finalise, result branch
|
||||
pushed, `TaskCompleted`.
|
||||
|
||||
Not proven, and not defects:
|
||||
|
||||
- **No quality gate ran.** The deployed `test-e2e` project declares only `id`,
|
||||
`machine_affinity`, `repo` and `worktree_root`.
|
||||
- **No PR was opened.** The deployed `config.jsonc` has no `sources` and no
|
||||
`delivery` keys. `internal/provider/gitea_pr.go` implements PR creation, but
|
||||
nothing points this project at a Gitea remote.
|
||||
|
||||
Submission, human PR review and merge need registry configuration, not code.
|
||||
That is the cheapest remaining burn-in, and it is a config edit plus one task.
|
||||
|
||||
## The next change is designed and frozen
|
||||
|
||||
`PLAN-SPEC-DESIGN.md` holds the operator-approved design for the ACE-FCA plan
|
||||
gap. No implementation exists yet, by explicit instruction: the design must not
|
||||
land while the completion tail is still being observed.
|
||||
|
||||
Shape, in one paragraph each:
|
||||
|
||||
- **`plan.md`**, sealed through the existing path and referenced by the existing
|
||||
`t.PlanRef`. 128 KiB total bound, structural validation by required headings
|
||||
and phase blocks, no per-line cap. `DecodePlan` keeps the JSON path for refs
|
||||
already in the CAS.
|
||||
- **Research ids.** `Finding{ID, Claim, Evidence, Confidence}`, unique ids,
|
||||
confidence limited to `fact|inference|assumption`. The schema at
|
||||
`agentctx.go:167` already promises these and the struct drops them today.
|
||||
- **Progress that Orchestra establishes.** The implementer may write only
|
||||
`status: "ready_for_verification"`. The worker reads that phase's automated
|
||||
verification from the accepted plan, runs it, and records
|
||||
`PlanPhaseVerified`. An agent cannot write `verified`.
|
||||
- **Verification allowlist.** Plan commands are argv, executed without a shell,
|
||||
matched against a per-project policy. Absent policy refuses everything.
|
||||
- **Mismatch as a typed request.** `PlanMismatchRequest` supersedes or reopens
|
||||
research and planning. No new agent-askable backward transition.
|
||||
|
||||
The live proof ladder is in the note. Steps 1 and 3 are the rungs that matter
|
||||
for smaller local models. The implement launch contains the plan verbatim, and
|
||||
a rotated successor still receives it whole with phase state intact.
|
||||
|
||||
## Things that will bite
|
||||
|
||||
- **Verify the running worker binary, not the installed one.** Twice tonight.
|
||||
- **The worker state file is a cache, not truth.** It read `state failed` for
|
||||
run 5 while the coordinator still held the task as leasable. I reported the
|
||||
cache as fact. The coordinator disagreed and was right.
|
||||
- **`rm` and `cp` are interactive in this shell.** A plain `rm` prompts, appears
|
||||
to succeed, and leaves the file. Use `/bin/rm -f` and `install`.
|
||||
- **Another session owns 20-plus uncommitted paths**, including `AUDIT.md`,
|
||||
`deploy/build.sh`, `web/` and `internal/authn/`. Commit by path. Never
|
||||
`git add -A`.
|
||||
- **No network from this sandbox.** `curl` to raw.githubusercontent.com times
|
||||
out. `WebFetch` against a `github.com/blob/...` URL works.
|
||||
- **Secrets are guarded.** Reading `.env` or `printenv` of a token through the
|
||||
shell is blocked. The working recipe is expanding the token inside the
|
||||
container in a single remote command, as `HANDOFF-2026-08-28-burnin-4.md`
|
||||
records.
|
||||
- **`/tmp` is tmpfs with a 10-day sweep.** Check `/tmp/test-e2e` and
|
||||
`/tmp/test-e2e-worktrees` exist before every run.
|
||||
- **Two stale monitors** may still be armed from this session, tailing the
|
||||
worker journal. They are session-local and die with it.
|
||||
|
||||
## What I would do next, in order
|
||||
|
||||
1. Rebuild `orchestra-api` at `dcd9af4` so the 5-minute TTL applies at issuance.
|
||||
2. Fix F18 as a bounded observation ring, since two more instances landed
|
||||
tonight.
|
||||
3. Configure `test-e2e` with a Gitea remote and a quality gate, then run one
|
||||
task to prove submission, human review and merge.
|
||||
4. Implement `PLAN-SPEC-DESIGN.md` exactly as written, including the allowlist.
|
||||
|
||||
Steps 1 through 3 are burn-in and observability. Step 4 is the only new
|
||||
behaviour, and its design no longer needs an architecture pass.
|
||||
@@ -0,0 +1,249 @@
|
||||
# Locked design: plan.md, durable plan state, verified progress
|
||||
|
||||
Written 2026-08-28 while run 5's completion tail is still open. **No
|
||||
implementation until run 5 reaches a terminal outcome.** This file is a note,
|
||||
not code, and is deliberately uncommitted.
|
||||
|
||||
Approved by the operator with three amendments folded in. Markdown plan with
|
||||
structural validation, stable research finding ids, and progress that Orchestra
|
||||
establishes rather than the implementer asserting.
|
||||
|
||||
The project-level verification allowlist was added on the second pass.
|
||||
|
||||
## Ground truth this design starts from
|
||||
|
||||
Verified in the tree at `2417a39`, not assumed.
|
||||
|
||||
| Concern | Where | Behaviour today |
|
||||
|---|---|---|
|
||||
| Research artifact | `internal/workphase/workphase.go` | `Findings{Claim,Evidence}`, 64 items, 500 chars, single line |
|
||||
| Plan artifact | same | `Changes{Target,Intent}`, `Verification[]`, `Risks[]`, `DecisionsNeeded[]`, same bounds |
|
||||
| Advertised research schema | `internal/agentctx/agentctx.go:167` | promises `findings[].id` and `findings[].confidence`; struct has neither, both dropped silently |
|
||||
| Seal path | `cmd/orchestra-worker/main.go:1833` | worker decodes, refuses locally through `answerRefusedPhase` (F39), then `AdvancePhase` |
|
||||
| Storage | `internal/store/store.go:961`, `cmd/orchestra/main.go:467` | content-addressed CAS, format-agnostic, 4 MiB body cap |
|
||||
| Refs | `internal/store/store.go:282` | reducer sets `t.ResearchRef` / `t.PlanRef` |
|
||||
| Implement launch | `internal/agentctx/agentctx.go:418` | `renderSealed` flattens every field through `collapse()` to one bullet line |
|
||||
| Plan progress | none | no state exists; `workphase` doc points at `continuity.Handoff` |
|
||||
| Rotation progress | `internal/continuity/continuity.go:113` | `Remaining[]`, `Action`, `Learned[]`, 200 chars per line, unlinked to any plan item |
|
||||
| Phase graph | `internal/domain/workphase.go:35` | `implement → review` only; no route back |
|
||||
| Quality gate execution | `cmd/orchestra-worker/main.go:955` | `exec.CommandContext(ctx, "sh", "-c", gateCommand)`, `Dir = worktree`, operator-authored string |
|
||||
|
||||
The last row is the security baseline. The gate command is operator-authored,
|
||||
from the project registry or the task. A plan-authored command is agent-authored,
|
||||
so it must not inherit that envelope unchanged.
|
||||
|
||||
## 1. Sealed specification: `plan.md`
|
||||
|
||||
- Markdown, sealed through the existing path, referenced by the existing
|
||||
`t.PlanRef`. No new storage, no new event type for sealing.
|
||||
- Bound: 128 KiB total. No per-line cap. The 500-character single-line rule is
|
||||
what makes a specification impossible today.
|
||||
- `phaseSealFile[plan]` and `phaseArtifact[plan]` become `plan.md`.
|
||||
- `DecodePlan` keeps the JSON path for refs already in the CAS. New seals must be
|
||||
markdown.
|
||||
- `phaseSealSchema[plan]` states the required outline. Run 5 proved the planner
|
||||
follows that block (F38), so it is the delivery mechanism for the structure.
|
||||
|
||||
Required sections, validated by presence and shape:
|
||||
|
||||
```
|
||||
# <name> implementation plan
|
||||
## Overview
|
||||
## Current state
|
||||
## Desired end state
|
||||
## Non-goals
|
||||
## Approach
|
||||
## Phase <n>: <name> (one or more)
|
||||
### Files
|
||||
### Changes
|
||||
### Verification
|
||||
#### Automated
|
||||
- run: ["go", "test", "./internal/foo/..."]
|
||||
#### Manual
|
||||
- <human-testable step>
|
||||
## Testing strategy
|
||||
## Risks and edge cases
|
||||
## Migration
|
||||
## References
|
||||
```
|
||||
|
||||
Validation rules:
|
||||
|
||||
- At least one phase block. Phases numbered from 1, contiguous.
|
||||
- Every phase carries `### Files`, `### Changes`, `### Verification`.
|
||||
- Every phase carries at least one entry under `#### Automated` or
|
||||
`#### Manual`. A phase with neither cannot be verified and is refused.
|
||||
- Automated entries are argv arrays, JSON-parsed from the `run:` line. Not
|
||||
shell strings. See section 4.
|
||||
- `## References` entries cite research ids. An id that does not resolve against
|
||||
the sealed research fails the seal.
|
||||
|
||||
## 2. Research ids
|
||||
|
||||
- `Finding{ID, Claim, Evidence, Confidence}`.
|
||||
- `ID` required, unique within the artifact, matching `^r[0-9]+$` or a stable
|
||||
slug.
|
||||
- `Confidence` limited to `fact|inference|assumption`.
|
||||
- The advertised schema at `agentctx.go:167` becomes true rather than
|
||||
aspirational.
|
||||
- `renderSealed` prints the id with each finding, so a plan can cite
|
||||
`research:r12` and a reader can resolve it.
|
||||
- Plan seal validation resolves every reference. The coordinator holds
|
||||
`ResearchRef`, so the cross-check costs one CAS read.
|
||||
|
||||
## 3. Progress: request, then Orchestra verifies
|
||||
|
||||
The implementer may write exactly one status.
|
||||
|
||||
```json
|
||||
{ "phase": "phase-2", "status": "ready_for_verification" }
|
||||
```
|
||||
|
||||
- Any other status value is refused, and the refusal is delivered to the live
|
||||
session through the F39 path. `verified` is not writable by an agent.
|
||||
- Worker reads that phase's `#### Automated` entries from the accepted plan, not
|
||||
from the request.
|
||||
- Worker runs each argv, in order, in the worktree, capturing exit code and
|
||||
output.
|
||||
- All pass, manual steps exist: phase becomes `awaiting_manual_verification`.
|
||||
- All pass, no manual steps: phase becomes `verified`.
|
||||
- Any fail: phase stays `in_progress`, and the failing command plus its output
|
||||
reaches the implementer.
|
||||
|
||||
Durable record:
|
||||
|
||||
- New event `PlanPhaseVerified{phase, commands, exit_codes, at_sha,
|
||||
evidence_ref}`.
|
||||
- Reduced into a task field `PlanProgress`, so state is derived from events
|
||||
rather than from a worker cache.
|
||||
- Manual sign-off arrives as a human decision, on the surface decisions already
|
||||
use. No new approval mechanism.
|
||||
|
||||
Rendering, in `agentctx`:
|
||||
|
||||
- Plan state sits above continuity and below human decisions.
|
||||
- It names verified phases, the current phase, and any awaiting-manual gate.
|
||||
- The plan document itself renders verbatim. `collapse()` stays for research
|
||||
bullets only.
|
||||
|
||||
## 4. Verification-command allowlist
|
||||
|
||||
The rule, operator's wording:
|
||||
|
||||
```
|
||||
accepted plan command
|
||||
∩ existing quality-gate execution envelope
|
||||
∩ project verification policy
|
||||
= runnable
|
||||
```
|
||||
|
||||
Properties this must hold:
|
||||
|
||||
- No weaker sandbox than the existing quality gate.
|
||||
- No implicit `sh -c`. Commands execute as argv through `exec.CommandContext`,
|
||||
with `Dir` set to the worktree, exactly as the gate sets it.
|
||||
- Shell operators, pipes, and redirections are unavailable by construction,
|
||||
since there is no shell. A project that genuinely needs one declares it in
|
||||
policy, explicitly.
|
||||
- Refusal is observable and delivered to the implementer.
|
||||
- A rejected verification never becomes `verified`.
|
||||
- Project policy, not the plan, determines executable reach.
|
||||
|
||||
Policy shape, on `registry.Project`:
|
||||
|
||||
```json
|
||||
"verification": {
|
||||
"allowed": [
|
||||
["go", "test", "./..."],
|
||||
["go", "test", "./internal/..."],
|
||||
["go", "vet", "./..."],
|
||||
["npm", "test", "--", "*"]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Matcher, argv-aware:
|
||||
|
||||
- Match is positional. `argv[0]` must match exactly.
|
||||
- A literal pattern element matches that element exactly.
|
||||
- `*` matches exactly one element, any value.
|
||||
- A pattern element ending in `/...` matches a path argument under that prefix.
|
||||
- A pattern shorter than the command does not match unless its last element is
|
||||
`*`. No prefix-match by accident.
|
||||
- An empty or absent policy means no plan command is runnable. Absence is a
|
||||
refusal, not a default-allow.
|
||||
|
||||
Refusal text names the command and the project, so the planner learns its real
|
||||
reach. A plan whose commands are all refused fails at seal time, not at
|
||||
verification time. The failure lands on the planner rather than the
|
||||
implementer.
|
||||
|
||||
## 5. Mismatch as a typed request
|
||||
|
||||
```json
|
||||
{
|
||||
"plan_phase": "phase-2",
|
||||
"observed": "...",
|
||||
"contradicts": "...",
|
||||
"evidence": ["..."],
|
||||
"requested_action": "replan | research | human_decision"
|
||||
}
|
||||
```
|
||||
|
||||
- Written to `.orchestra/plan-mismatch.json`. Bounded lines, same validator
|
||||
style as the handoff.
|
||||
- Worker validates and posts. Coordinator records `PlanMismatchRecorded`, then
|
||||
decides the move.
|
||||
- Orchestra performs the reopen. The agent never asks for a backward phase, so
|
||||
`phase-request.json` still refuses one.
|
||||
- The superseded plan moves to a history list on the task. `PlanRef` always
|
||||
names the currently accepted plan, so no ref is ever ambiguous.
|
||||
- A fresh implement session launches against the newly sealed plan. The mismatch
|
||||
is retained as provenance.
|
||||
|
||||
This keeps the phase machine from becoming freely reversible navigation. The
|
||||
edge exists for Orchestra, not for the agent.
|
||||
|
||||
## 6. Tests
|
||||
|
||||
Unit:
|
||||
|
||||
- Plan with every required section validates. One missing section fails, and the
|
||||
error names the section.
|
||||
- Phase with no automated and no manual verification fails.
|
||||
- `run:` line that is not a JSON argv array fails.
|
||||
- Reference to an unknown research id fails, with the id named.
|
||||
- Duplicate research finding id fails. Confidence outside the enum fails.
|
||||
- `renderSealed` contains the plan document byte-for-byte, fences and multi-line
|
||||
blocks included.
|
||||
- Two `Build` calls from the same refs with different handoffs both contain the
|
||||
complete plan.
|
||||
- `status: "verified"` written by an agent is refused, and the refusal reaches
|
||||
the delivery path.
|
||||
- Allowlist matcher: exact match, `*` single-element, `/...` path prefix,
|
||||
shorter-pattern rejection, empty policy rejects everything.
|
||||
- A failed verification leaves the phase unverified and records the exit code.
|
||||
|
||||
## 7. Live proof ladder
|
||||
|
||||
1. Plan seals three detailed phases. Implement launch contains the plan
|
||||
verbatim.
|
||||
2. Phase 1 requests verification. Worker runs the exact plan command. Durable
|
||||
state says phase 1 verified.
|
||||
3. Rotation. Successor receives the complete original plan, phase 1 verified,
|
||||
phase 2 explicitly current.
|
||||
4. Human correction lands above the plan. Plan and state stay subordinate.
|
||||
5. Phase 2 hits a contradiction. Mismatch recorded, no silent implementation,
|
||||
old plan retained, revised plan sealed, fresh launch carries the revised plan
|
||||
in full.
|
||||
|
||||
Step 1 and step 3 are the two that matter for smaller local models. A grep of
|
||||
the rendered `launch.md` either finds the phase-three specification and its
|
||||
verification command, or it does not.
|
||||
|
||||
## Not in scope
|
||||
|
||||
Lifecycle, leases, review, submission, auth, federation, and the burn-in fixes
|
||||
stay untouched. One adjacent change is needed: the Orchestra-only reopen edge in
|
||||
section 5. It is reached through a typed request, not through a new
|
||||
agent-askable transition.
|
||||
Reference in New Issue
Block a user