Files
correx/RETRO.md
T
kami 33baaed903 docs: reconcile BACKLOG→RETRO for static_check stage + critique producer (e46777e)
Per the hygiene rule: the §B-§5 static_check stage seam + emitter and the §B-§6/A3
critique-outcome producer are built and unit-verified, so move them out of the live
"missing" list. Both narrowed to their remaining live-QA-gated *activations* (a sandboxed
production CommandRunner for §B-§5; model-emitted CritiqueFindingsRecordedEvents for §6),
with a dated RETRO entry + commit map. Updated QA-reviewer-static-first (the producing
stage now exists — check 4 reframed from "blocked on unbuilt seam" to an activation step)
and its README index line.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 21:52:59 +00:00

17 KiB
Raw Blame History

CORREX — RETRO (archive of resolved BACKLOG items)

Counterpart to BACKLOG.md (the live outstanding list). Items here are built and unit-verified (Gradle green). Where a live-QA gate applies, that's called out as a follow-up — this sandbox has no local model / SearXNG / GPU / network, so live-QA could not be run here.


2026-06-22 — BACKLOG hygiene reconcile + operator-requested TUI wave (branch feat/backlog-burndown)

Hygiene reconcile. Per BACKLOG.md's own maintenance rule, cut the resolved body bullets that were left ticked-but-in-place after the 2026-06-20 burndown and 2026-06-21 grants work. Sections affected: §A (health probes), §B (static-first infra, CritiqueFinding, architect contradiction-check), §C (A1/A2 gate code), §D (batch fetch-approval, source events, dynamic egress), §E (render matrix, markdown, session list, idea promotion), §G (turnId/probe/narration), §I (.cs symbols, scene validator). Partially-done items were narrowed to their live follow-up rather than deleted: §B5 → "static_check stage emitter only", §B6/§C-A3 → "the CritiqueOutcomeCorrelatedEvent producer only", §C-A1 → "planner-prompt activation only". The full commit map stays in the BACKLOG " RESOLVED" index; detail is in the tables below.

Operator-requested TUI wave (archived here — never BACKLOG items, like the grants work). A run of TUI/UX features added on the branch after the burndown, each compiled + go vet/go test green and rendered via cmd/preview before commit:

Commit What
9143d55 Global input history + stop idle redraws (copy-safe — no redraw churn while selecting text).
85bfddf Slash-command menu in the chat input.
2662156 Transparent modal backdrops (overlays no longer paint an opaque box over the transcript).
ba7ac06 Transcript message-jump (^↑/^↓ to your prev/next message) + OSC52 clipboard copy.
65e5d88 Server: ListFiles/FileList protocol backing the TUI @ picker.
04d7e26 @ file-reference picker in the input.
c616982 Context: inject CLAUDE.md / AGENTS.md as L0 standing context.
54f94a5 Command-palette keybinds + configurable (hideable) status bar.
6a06f2e Inline action rows in the OUTPUT transcript (tool results / approvals / writes / grants as RouterEntry role action, interleaved by arrival).
f14a83c Drop the inline tool-start rows (they doubled up with the result rows).
531910d Transcript free-scroll (PgUp/PgDn, ^u/^d, esc snaps to tail-follow; clamped via outputViewport()/buildTranscriptRows, 2 tests) + help overlay (?) + event-inspector / filter.
db27b34 Page-scroll the ^x diff/preview/command fullscreen viewer (↑↓ line, PgUp/PgDn page, ^u/^d half, g/G ends; scrollDiff() clamp, 2 tests) + advertise it in the modal hint and the ? help overlay. Closes the §E approval-ergonomics re-audit.
d247b19 Bubble Tea v1 → v2 (charm.land/{bubbletea,lipgloss}/v2, Go 1.25). A key-handling shim (key.go: v2 KeyPressMsg → v1-shaped keyMsg at the single Update boundary) keeps ~190 match sites untouched. Other v2 breaks handled: lipgloss.Color is now a func returning color.Color (retyped fields/params); View() returns tea.View (render() builds the string, View() carries AltScreen — alt-screen is a per-frame field now, not a program option); WithWhitespaceStyle replaced WithWhitespace{Background,Foreground}; preview dropped SetColorProfile (v2 = truecolor by default). Enables literal Shift+Enter newline via v2 kitty disambiguation (Ctrl+J/Alt+Enter kept as non-kitty fallback). Live-QA: docs/qa/QA-tui-v2.md.
85af2c6 Real terminal cursor in composer + window title. View.Cursor replaces the frame-animated : a width-1 marker rune (U+E123) is located in the fully-composited frame → blinking CursorBar at (X,Y); static render() resolves it back to so screenshots/goldens are unchanged. Nil in normal mode (hidden, vim-correct), suppressed when a modal is open (which keeps editMode==Insert). animating() no longer ticks in insert mode — the terminal blinks the cursor itself, so an idle insert screen holds still (native text selection survives). View.WindowTitle = active session/model. New cursor_test.go (3) + updated animating-gate test.

These are mostly deterministic render/UX changes (verifiable by go test + cmd/preview). The v2 migration + native cursor are unit-verified the same way, but their behavioral wins (Shift+Enter, the real blinking cursor, no regressions across the new render layer) need a real kitty terminal — that's the live-QA gate in docs/qa/QA-tui-v2.md.

§E approval-ergonomics re-audit — DONE (db27b34). Re-checked the band after it gained the grant scope-picker (A) and inline action rows: the spec still holds — single-key y/n/e for T0T2, mandatory second-key confirm for T3+ (HighTier), navigable queue with an i/n indicator, docked band never modal-stacks. All covered green by approval_test.go. The one gap was the diff viewer scrolling one line at a time; db27b34 adds paging. Item moved out of BACKLOG.


2026-06-22 — reviewer reliability: static_check stage + critique calibration producer (branch feat/backlog-burndown)

Two deterministic role-reliability tracks whose consumer halves already existed but had nothing feeding them. Both built + unit-verified (Gradle green, detekt clean); their activations are model-/sandbox-gated and stay narrowed in BACKLOG.

Commit What Item
e46777e §B-§5 deterministic static_check stage seam + emitter. StaticCheckStageExecutor runs a configured tool (static_tool/static_argv via stage metadata) through the existing StaticAnalysisRunner and emits StaticFindingsRecordedEvent; DefaultSessionOrchestrator.enterStage dispatches any metadata["stage_type"]=="static_check" stage to it instead of the LLM subagent and advances on the unconditional exit edge; TomlWorkflowLoader gained stage_type/static_tool/static_argv fields; role_pipeline.toml carries a static_check stage between implementer and reviewer. No-op until a sandboxed, workspace-scoped CommandRunner is wired + static_argv set (live-QA-gated). Tests: StaticCheckStageExecutorTest (4) + StaticCheckStageTest integration (1). B §5
e46777e §B-§6 / A3 critique-outcome producer. New CritiqueFindingsRecordedEvent (+ CritiqueVerdict) is the producing side — a critic's findings + verdict per iteration, with modelHash. CritiqueOutcomeCorrelator (pure, in the reviewer-loop runtime) decides UPHELD / DISMISSED / INCONCLUSIVE per critic and finding id; a hook in completeWorkflow/failWorkflow correlates recorded findings into CritiqueOutcomeCorrelatedEvents at loop resolution (no-op + idempotent), feeding the existing :core:critique calibration projection. Dormant until the reviewer/plan-critic emit CritiqueFindingsRecordedEvents (model-gated). Tests: CritiqueOutcomeCorrelatorTest (8) + CritiqueCalibrationWiringTest integration (1). B §6 / C-A3

Both follow the same shape as the earlier dormant-activation work: the deterministic seam + the event wiring land and are unit-proven now; the LLM-/sandbox-side activation is the live-QA-gated follow-up. docs/qa/QA-reviewer-static-first.md updated (no longer "producing stage not built").


2026-06-21 — wider grants + revoke (branch feat/backlog-burndown)

Operator-requested (not a prior BACKLOG item): grants that outlive a single session, plus a revoke path. Two commits, each compiled + unit-tested green.

Commit What
c36d41b Cross-session grant scopes (PROJECT/GLOBAL) + revoke. GrantScope.GLOBAL(toolName) added; PROJECT made tool-bound. Engine scopeMatches: GLOBAL matches the bound tool anywhere, PROJECT when the session's projectId (derived from the bound workspace root via ProjectIdentity.of) AND tool match. New reserved GRANT_LEDGER_SESSION_ID stream holds PROJECT/GLOBAL grants; the approval gate unions the ledger's grants with the session's. RevokeGrantApprovalGrantExpiredEvent on the ledger (reducer already drops it); ListGrants/GrantList expose the active standing grants. Server-side T2 grant ceiling removed per operator request — a grant may now authorize any tier (incl. T3/T4); tool-binding is the remaining guard. New GrantScopeMatchingTest (5).
8df0ec7 TUI: scope picker (A) + standing-grants viewer. A (approve-always) opens a session/project/global picker (SESSION default = old behaviour); p/g create wider grants. grants palette command + G shortcut open OverlayGrants listing scope/tool/tiers/path with x/enter to revoke. protocol.go: TypeGrantList+GrantDto, RevokeGrant/ListGrants encoders. Both overlays rendered via cmd/preview (kinds grants, grant-scope).

Why the design: session grants are event-sourced per-session and die with the session; project/global grants must outlive any one session, so they live in a dedicated ledger stream the gate folds in — keeps grants in the audit log (invariant #9) rather than config.

⚠️ Live-QA gate (move out of RETRO once passed): unit tests cover the engine matching, reducer, and ledger fold, but the cross-session behaviour — create a GLOBAL/PROJECT grant in session A, confirm a different session B auto-clears that tool, then revoke and confirm it prompts again — needs a running server + model. Not runnable in this sandbox.


2026-06-20 — backlog burndown (branch feat/backlog-burndown)

Nine tracks, each compiled + unit-tested green before commit.

Commit Track BACKLOG ref
f783eed CritiqueFinding/CritiqueSeverity/CritiqueRole type + CritiqueOutcomeCorrelatedEvent + core/critique calibration projection (state/reducer/projector) B §6 + C-A3
784accb repomap: turnId namespace requires trailing : (no /repo/repo2 collision; L3RepoKnowledgeRetriever filter + ProjectMemoryService write) + WorkspaceStateProbe newline fingerprint G
266bbf0 EventStoreLatencyProbe (wired) + LlamaServerHealthProbe (+ injectable LlamaLivenessClient) + HealthConfig.eventStoreWarnLatencyMs A §4
f715ffa .cs / Godot-Mono type symbols in RepoMapIndexer.SYMBOL_PATTERNS I
0e251d6 SceneValidator — structural .tscn/.tres (header well-formedness, ExtResource/SubResource id resolution, node parent integrity) I
1df7af5 Brief echo-back gate: BriefEchoMismatchEvent + BriefEchoComparator/BriefEchoExtractor + checkBriefEcho orchestrator gate C-A1
1a1b5cc Stage-level plan checkpointing: StageCheckpointPassed/FailedEvent + StageCheckpointReconciler + emitStageCheckpoint (gated on a locked plan) C-A2
eae0a0c Architect contradiction-check (display-only): PossibleContradictionFlaggedEvent + L3-backed ArchitectContradictionChecker B §4
b098d87 Dedicated SourceFetchedEvent / LowQualityExtractionEvent (promoted from ToolExecutionCompletedEvent metadata; additive), emitted from SandboxedToolExecutor D
027ff1f Dynamic per-session egress allowlist: EgressHostsGrantedEvent + EgressAllowlist union helper + EgressAllowlistProjection; NetworkHostRule delegates to the union D
447fc7a Reviewer static-first: StaticFindingsRecordedEvent + StaticAnalysisRunner (injectable CommandRunner; compiler/ktlint/detekt parsers) + excludeStaticFindingsFromReview filter, live-wired into reviewer context assembly B §5
eff8f8d Narration-lane lag: stale pause narrations dropped per-approval-request on resolve / per-session on resume (replay-safe) G
1e6699a tui-go go.mod go 1.261.24.2 (1.26 toolchain unreleased/unfetchable) — unblocks Go build/test on released toolchains E (enabler)
da72ee5 tui-go: markdown rendering for chat turns via glamour (dark, per-width memoized), plain-text fallback; other roles/UI untouched E
1f7a5d9 tui-go session list / resume view: R overlay over GET /sessions, resume via POST /sessions/{id}/resume onto the existing global stream E
2a99e15 tui-go per-event render-matrix golden tests (37 cases) + a coverage guard that parses protocol.go so any new event type without a golden fails E §2
d5afcd3 tui-go approval ergonomics: navigable pending-approval queue (no modal stacking) + y/n/e keys + tier-gated T3+ arm/confirm E §3
641051b Plan-derived diff manifest: PlanStage.writes + PlanDerivedManifest.deriveAllowedWrites/combine, unioned into StageConfig.writeManifest at compile, enforced by the existing containment matcher B §2
ab7e4be Egress allowlist activation: resolveSessionEgressHosts threads the session's EgressAllowlistProjection state into ToolCallAssessmentInput at runPlane2Assessment, so NetworkHostRule now consults the live per-session union (was fed emptySet()) D (activation)
4b0024f Batch source-list fetch-approval: POST /sessions/{id}/approve-sourcesSourceListHosts.extract (java.net.URI, lower-cased, ports stripped, dossier-line tolerant) → one EgressHostsGrantedEvent; live allowlist then auto-clears those web_fetches (no per-URL T2) D
f107ff5 Idea-board → project-profile promotion: IdeaPromotedEvent (board tombstone, like discard) + ProjectProfileWriter (escape-aware TOML serialize/write) + ProjectProfile.withConvention (deduped) + server PromoteIdea handler (loads profile, appends idea text, writes .correx/project.toml); also made SimpleToml's reader unescape \\/\" symmetrically with the writers (fixes pre-existing read/write asymmetry) E
4e08510 Architect contradiction-check activation: ServerModule.start() subscribes to the architect stage's design ArtifactCreatedEvent, resolves decision text (design-schema approach field, capped fallback), runs ArchitectContradictionChecker.check, appends the non-null PossibleContradictionFlaggedEvent. Live-only, never halts. Checker built in Main.kt (gated on project.enabled) and threaded into ServerModule. Replaces the Main.kt TODO(wiring) B §4 (activation)
64a90e7 Llama-probe registration: LlamaServerHealthProbe (266bbf0) wired into the health monitor when a llamacpp provider URL is configured — dedicated CIO client (3s timeout, shutdown-hook close) + HttpLlamaLivenessClient. Gated so a model-less box reports no spurious LLAMA_SERVER DEGRADED. Replaces the Main.kt TODO(wiring) A §4 (activation)

Follow-ups created this pass (refiled into BACKLOG)

  • C-A1 activationplanner.md must emit a brief_echo block and role_pipeline.toml must set briefEcho="true" / briefEchoSource for the gate to fire live (model-dependent → live-QA).
  • C-A3 producer — nothing emits CritiqueOutcomeCorrelatedEvent yet; the calibration projection has no live feed until a reviewer-loop producer records finding outcomes.
  • B §4 wiring DONE (4e08510): ServerModule.start() now subscribes to the architect design artifact and emits the flag. (In-session L3 embedding is NOT needed — the checker filters to PRIOR sessions by design, so it works against prior runs' distilled decisions.)
  • A §4 llama wiring DONE (64a90e7): the probe is registered in the health monitor (gated on a configured llamacpp provider URL) via HttpLlamaLivenessClient. (tokens/sec telemetry still rides liveness-only — the /health endpoint reports reachability; a throughput feed remains future work but the spec's liveness probe is live.)
  • D egress wiring DONE (ab7e4be): session egress state is now threaded into ToolCallAssessmentInput at runPlane2Assessment, so NetworkHostRule consults the live union. Batch fetch-approval DONE (4b0024f): POST /sessions/{id}/approve-sources emits one EgressHostsGrantedEvent for the whole source list.
  • B §5 static_check stage — runner/event/filter complete and the filter is live, but no workflow stage emits StaticFindingsRecordedEvent yet (// TODO(wiring) in StaticAnalysisRunner.kt); needs an event-emitting deterministic stage-type seam.
  • E toolchain — tui-go now builds via auto-downloaded go1.24.2 (GOTOOLCHAIN=auto). The committed directive fix assumes 1.26 was unintended; bump if a specific newer release is actually wanted.

Environment note

  • A ~/.gradle/gradle.properties machine-local override was added on this box (-Xmx768m, parallel=false, kotlin daemon -Xmx640m) because the repo's -Xmx4G OOM-killed the foreground process on a 1.9 GB machine. Not committed — repo defaults intact for higher-RAM machines.