1b58bc325e
This branch's uncommitted WIP, committed together (entangled at file level). Distinct pieces of work: Freestyle QA fixes (this session): - FileEditTool: pre-validate replace anchor in validateRequest — reject a missing/ambiguous target BEFORE the approval gate, mirroring read/write's file-not-found / read-before-write pre-checks. Shared not-found/ambiguous messages between validate and execute so they can't drift. - PlanGrounder: add `scanned` flag; when no RepoMapComputedEvent was recorded, repoMapPaths is "unknown" not "empty workspace" — skip scope grounding (which proves a path ABSENT) so real paths (apps/server/**) aren't falsely rejected. Build-manifest check still runs. - FreestyleDriver: wire scanned=(repoMap!=null); on plan rejection emit a session-terminal WorkflowFailedEvent so a rejected run reads FAILED, not the COMPLETED-lie (last verdict was the planning-phase WorkflowCompleted). - ServerModule: resolve project-memory workspace root from the session's bound workspace (sessionWorkspaceRoot) instead of boot-static pm.repoRoot(), fixing the workspace-binding divergence (correx vs empty scratch dir). Retire tracked in Vikunja #266. - LaunchRegistrationRaceTest: join registered jobs before asserting launchCount — computeIfAbsent returns the Job immediately but the fire-and-forget launch body lagged awaitAll (the 49-vs-50 flake). ACR concept-compiler experiment (pre-existing WIP on this branch): - ExecutionPlanCompiler/Model/PlanLinter, #264 needs-seam (sessionArtifacts), LSP diagnostics subsystem (LspDiagnosticEvents/Runner/Lsp4j), BootWorkspace, config surface, workflow prompts/schemas, orchestrator advance-don't-rerun. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
151 lines
8.9 KiB
Markdown
151 lines
8.9 KiB
Markdown
# Correx — Catch-up for a ~2-month-old memory
|
||
|
||
**If your last memory of Correx is the epic-13/epic-14 era (mid-May 2026), read this.**
|
||
|
||
Back then the project was a *skeleton*: epics 0–14 had landed the module structure
|
||
(events → sessions → transitions → validation → approvals → artifacts → context →
|
||
tools → inference → kernel → infra → interfaces → router). It compiled and replayed,
|
||
but the orchestration loop was thin and mostly unproven against real model runs.
|
||
|
||
Two months and ~250 feature commits later, the architecture is the *same* (all 9 Hard
|
||
Invariants still hold; the event log is still the only source of truth), but nearly the
|
||
entire *behavioral* layer — how a session actually drives a model through real work —
|
||
was built and hardened by live QA. This document groups the major additions. It is a
|
||
map, not a changelog; the dated files in `docs/plans/` are the real changelog.
|
||
|
||
Work is no longer tracked as "epics." It's tracked as **plans** (`docs/plans/`) and a
|
||
**Vikunja backlog** (project_id 4).
|
||
|
||
---
|
||
|
||
## The single biggest correction: the TUI is now Go
|
||
|
||
The Kotlin TUI (Mosaic, then tamboui) was **retired**. The interactive terminal UI is
|
||
now a **Go / Bubble Tea** app at `apps/tui-go` — a WS client of the server. `apps/cli`
|
||
(Clikt, Kotlin) and `apps/server` (Ktor) are the only Gradle app modules; the old
|
||
`apps/desktop` / `apps/worker` stubs were deleted. If you remember tamboui, forget it.
|
||
|
||
## New whole subsystems (did not meaningfully exist at epic-14)
|
||
|
||
**Native task tracking (`core:tasks`).** A dependency-aware work graph: `task_decompose`
|
||
splits a goal into a DEPENDS_ON graph in one approval; tasks have claim gates
|
||
(dependency-hard-gate, cite-before-claim, duplicate-title guard), per-task history,
|
||
markdown export, a full REST surface, a `correx task` CLI, a TUI task board with
|
||
readiness, and **git-driven status** (a commit mention → IN_PROGRESS, a closing keyword
|
||
→ DONE, idempotent). The execution loop is now *tasked* — it replaced the old linear
|
||
role_pipeline.
|
||
|
||
**Plane-2 tool-call intent validation (`core:toolintent`).** An anti-hallucination /
|
||
safety layer that assesses every tool call *before* it runs and records
|
||
`ToolCallAssessedEvent`: path-containment, read-before-write, reference-must-exist,
|
||
write-scope adherence, stale-write, exec-interpreter and network-host rules, and a
|
||
per-session egress allowlist. This is the layer that stops an agent citing files it
|
||
never read or writing outside its declared scope.
|
||
|
||
**Compression pipeline (`infrastructure:compression`).** A staged, replay-safe context
|
||
compressor: level policy → fact sheet + strict allocation → tier summarizer → token
|
||
pruning + embedding relevance + ToMe merge → static-doc pruning (CLAUDE.md/AGENTS.md).
|
||
Distinct from the required/optional *bucket* rework in `core:context`.
|
||
|
||
**Staged verification & review gates.** Stage output passes a gate ladder instead of
|
||
being trusted: build gate, plan-compile gate, contract/execution gate, and a
|
||
semantic-review gate (`core:critique`, with structured `CritiqueFinding` + per-model
|
||
calibration). Per-gate retry budgets with progress-aware charging and hybrid salvage;
|
||
static-first reviewer framing; capability-gap reflection; brief echo-back gate.
|
||
|
||
**Research workflow.** `WebSearchTool` (local SearXNG), `WebFetchTool` (bounded fetch),
|
||
deterministic HTML→markdown extraction, a research workflow graph, batch source-fetch
|
||
approval, and dedicated `SourceFetched` / `LowQualityExtraction` events. On by default.
|
||
|
||
**Cross-session repo memory (L3 + repo-map + project profile).** `RepoMapIndexer`
|
||
(symbols for Kotlin, GDScript, C#/Godot-Mono, markdown headings), `RepoKnowledgeRetriever`
|
||
with recency fallback, L3 ANN retrieval (`in_memory` or `turbovec` sidecar) recorded as
|
||
environment observations, `ProjectMemoryService`/`Distiller`, and `ProjectProfile`
|
||
(per-repo standing context at `.correx/project.toml`) injected as L0. Note: this is
|
||
*repo-scoped* memory — the "cross-session memory" anti-feature (conversational recall)
|
||
is still deliberately out.
|
||
|
||
**Git run-branch transport (the "Gitea transport") — SHIPPED.** The server owns a Git
|
||
checkout; each run pushes to a run branch (`GitRunBranchTransport`, `RunBranchPushedEvent`);
|
||
`GitTaskSync`/`GitCommandCommitReader` drive task status from commits. "gitea" is just
|
||
the configured remote name; the transport is plain Git.
|
||
|
||
**Observability & replay tooling (Epic 15, largely shipped).** Event-stream inspector
|
||
(`correx events`, `/sessions/{id}/events`), session replay + determinism digest,
|
||
causation-graph DOT export, metrics as a replayable projection (`correx stats`),
|
||
event-sourced health checks (EventStore latency, llama-server liveness, disk watermark,
|
||
ROCm/VRAM probe), and correlation-structured MDC logging.
|
||
|
||
**Model lifecycle management (`[[models]]`).** Correx spawns/owns the llama-server
|
||
process: per-stage model selection, manual swap + pin, resource telemetry, VRAM gauge.
|
||
(The autonomous *residency scheduler* is still unbuilt — see below.)
|
||
|
||
**Workspace scoping & undo.** `WorkspaceResolver` trust pipeline + `allowed_workspace_roots`,
|
||
per-session workspace-scoped tools/policy, client→server workspace handshake, crash-safe
|
||
atomic file writes with pre/post-image captured to CAS (`FileWrittenEvent`), and a
|
||
`FileMutationReverser` undo primitive (server endpoint + CLI). Agents can also READ
|
||
outside `workspace_root` via an operator approval prompt (writes stay jailed).
|
||
|
||
**Approvals & grants.** Cross-session grant scopes (PROJECT/GLOBAL) + revoke,
|
||
grant-aware approval engine, risk rationale surfaced to the operator; approval gates now
|
||
block indefinitely instead of auto-rejecting on timeout, and steering actually affects
|
||
the run.
|
||
|
||
**Router interaction layer.** Beyond CHAT+STEERING: grounded system prompts, triage
|
||
directive (no bare refusals), structured **workflow proposals** from triage, a
|
||
**clarification-question loop** (analyst asks, operator answers, producer-exit rehydrate
|
||
on reconnect), **rubber-duck idea board** (capture/feed/promote to project profile), and
|
||
grounded **narration** (pinned narration model, latency/token metrics surfaced).
|
||
|
||
**Freestyle / execution-plan engine.** Two-phase planning→execution driver,
|
||
`ExecutionPlanCompiler` + `ExecutionPlanLockedEvent`, post-plan operator approval gate,
|
||
freestyle graph re-routing (deterministic override), soft-lock steering preemption,
|
||
plan grounding + positive-pattern mining + a stage-prompt audition rig.
|
||
|
||
**Decision journal (`core:journal`).** Decision-journal projection injected into stage
|
||
context, salience-aware compaction (`JournalCompactionService`, CAS-rendered).
|
||
|
||
**Personalization (`core:config`).** `OperatorProfile` + `ProfileLoader` bound at start
|
||
and surfaced into L0; propose-only `ProfileAdaptationService`.
|
||
|
||
**Native MCP host.** The server mounts external stdio MCP servers as first-class Correx
|
||
tools (inherit tier / receipt / replay). `codebase-memory-mcp` is installed and granted
|
||
per code-intel stage.
|
||
|
||
**Recovery loop.** Failed write-less stages route to recovery instead of futile retry;
|
||
tier-2 intent-holder arbiter; remaining-delta pinning; failure-ticket routing +
|
||
review-gate RECOVER + return-to-sender; structured package-404 recovery evidence;
|
||
stage-global repeated-failure loop breaker.
|
||
|
||
**Godot / game-dev support.** GDScript + C#/Godot-Mono symbol extraction in the repo
|
||
map, and a structural `.tscn`/`.tres` scene validator.
|
||
|
||
## Refactors & hardening you'll notice
|
||
|
||
- `DefaultSessionOrchestrator` god-class decomposed into per-concern extensions;
|
||
`DomainEventMapper`'s god-`when` split per-domain. Detekt baseline ratcheted 120 → 90.
|
||
- Persistence hardened: sequences assigned atomically inside INSERT, reads serialized
|
||
with the append transaction, slow WS clients no longer stall the kernel.
|
||
- Tool results bounded + framed, full output spilled to CAS with a `tool_output`
|
||
retrieval tool; `glob`/`grep` search tools; web_fetch SSRF fix; interruptible shell
|
||
timeouts with process-tree kill; shell allowlist validates every command position.
|
||
- Config: orchestration loop/threshold/budget constants moved to `[orchestration]`;
|
||
operator-tunable sampling knobs (top_k/min_p/repeat_penalty) per stage.
|
||
|
||
## Still planned / deliberately NOT built (don't assume these exist)
|
||
|
||
- Full **remote always-on / thin-client** deployment topology. Its Git *transport*
|
||
shipped (above); the hosting topology itself is not yet stood up.
|
||
- Full router **context isolation** (persistent conversation history, session-scoped
|
||
boundaries). CHAT+STEERING works; the isolation layer is deferred.
|
||
- Autonomous GPU **residency scheduling** (lifecycle *is* built; idle-eviction policy
|
||
is not).
|
||
- Still explicitly out: parallel agent execution, conversational cross-session memory,
|
||
three-critic ensemble, fine-tuning, streaming inference.
|
||
|
||
## Where to look now
|
||
|
||
- `CLAUDE.md` — current session guide, Module Map, invariants.
|
||
- `docs/plans/` — the real changelog of intent since epic-14 (dated files).
|
||
- Vikunja project 4 — live backlog. `scripts/ctx.py <query>` — ranked file/symbol lookup.
|