diff --git a/docs/sprints/2026-07-23.md b/docs/sprints/2026-07-23.md index 6c234291..a52a9dcd 100644 --- a/docs/sprints/2026-07-23.md +++ b/docs/sprints/2026-07-23.md @@ -178,10 +178,28 @@ needs one. stop-at-first-uncertainty), and `analyst_freestyle.md` makes the `dod` artifact the handoff contract — atomic, yes/no-checkable criteria, plus one criterion carrying the named task into the impl plan and one per material failure path. #3 (architect re-plans on better input) fell out for free. -- **#305 stays open.** Store 1 (Observations) shipped (`5df35879` et al) and is real, but Stores 2 - (fix lifecycle) and 3 (plan-shapes + discovery warm-start read path) are unbuilt — and Store 3 is - exactly what Goal 2's exit criterion ("discovery carries accreted knowledge from a prior run") - names. Not closable; carries past this sprint. +- **#305 ✅** (commit `d52a94e5`). The ticket body was stale on two of three stores; traced each + against the tree before touching anything. + - *Store 1* shipped durable (`5df35879`) and was then deliberately **reverted to a memo** + (`12775d56`) — `SqliteObservationStore` was a second unsynchronized SQLite writer holding a fact + the log already carries (`FileWrittenEvent.path` + `postImageHash` + a pure `describe().render()` + over CAS bytes), i.e. an invariant-#1/#8 break. `descriptorMemo` keeps the perf win with none of + the risk. The "extend to the FileReadTool hot path" follow-up died with it: that path keyed on a + workspace-relative path while every consumer looks up the absolute one, so it never hit. + - *Store 2* was already complete in `unconfirmedFixEntries` — the `unconfirmed`/`falsified` states + below hard promotion, matched reactively on the retry's own `classKey`, made genuinely one-shot + by #306. + - *Store 3* was already built, but **deterministically rather than via the embedder**: intent + keyword Jaccard over a fold of (initial intent, locked plan, workflow completion). That beats the + planned embedder version on #8/#9 — pure fold, no environment read, so no recorded-retrieval + event is needed at all. Its one real gap was the consumer gate: `produces execution_plan` only, + so **discovery** — the stage the whole ticket is named after — still started cold. Now gated on + the produced artifact *kind* being a plan-shape consumer (`execution_plan` or `discovery`), with + a discovery-specific framing: the prior run's stage list read as a checklist of surfaces this + task-family touches, to inspect now rather than at stage 6. + - Left deliberately: tool categories in the plan shape (the plan said "stage sequence + tool + categories"). The sequence carries the signal; add the tool list only if a live run shows + discovery missing tooling it should have anticipated. - **#261 blocked by #267, correctly.** Its own body defers it until the simpler pipeline is proven on a clean end-to-end run — which is the #267 acceptance run. Do #267 first.