feat: consolidate TraceDecay V2 PR8-PR13 delivery - #421
feat: consolidate TraceDecay V2 PR8-PR13 delivery#421ScriptedAlchemy wants to merge 2508 commits into
Conversation
|
e50f8f5 to
4f5ab66
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 986f25cca6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
5862bd6 to
53502de
Compare
642a33a to
5f2f610
Compare
76dee0f to
0258866
Compare
Exercise fresh and offline acquisition through the packaged gate and preserve actionable lifecycle failure reasons.
Preserve canonical output while returning a nonzero process status so configuration CAS conflicts and unavailable writes can fail shell gates.
`Chart` imported all of ECharts, so one lazy chunk shipped every series type and both renderers: 1,080 KiB raw and 288 KiB Brotli, against plan 11's 200 KiB per-chunk ceiling. The product draws bar and line series on a grid with a tooltip, so register exactly that; the chunk becomes 536 KiB raw and 150 KiB Brotli. ECharts answers an unregistered series with an empty canvas rather than an error, so narrowing the build turns a future mistake into a chart-shaped blank standing in for a measurement. `Chart` now refuses a series type outside the registered set and names it.
Plan 11 states a 250 KiB Brotli initial payload and a 200 KiB per-chunk ceiling, and nothing measured either; the previous bundle guard only rejects a placeholder. check-dashboard-budget.mjs Brotli-compresses the built artifact, so these are transfer sizes rather than a proxy, and it fails on a missing lazy-chunk directory so a non-code-split bundle cannot pass by measuring nothing. Its first run found the ECharts chunk fixed in the previous commit. The 250-element list mount ceiling was only a comment, and a comment does not fail. VirtualList now has assertions, with a nonzero lower bound because a virtualizer that mounted nothing would otherwise satisfy any ceiling. Both gates plus the two accessibility gates are locked into the dashboard workflow contract so they cannot be silently dropped.
`brokered_init` gives itself a 120s budget to "wait out the background open", then calls `call_default_tool_within`, which documents that it deliberately does not retry the warming state so deadline-aware callers receive it as a typed answer. So `tracedecay init` against a freshly started daemon failed immediately with the warming hint instead of waiting, which also broke every `pr11_pr12_runtime_acceptance` fixture at setup. Add a bootstrap-only entry point that retries warming until the caller's deadline, and leave the interactive `tracedecay tool` path unchanged: its callers do want the typed warming state.
Thread and allocator-arena growth, not work, was driving the runtime's memory use. Tokio took its default worker count from core count with an unbounded blocking pool, extraction scaled subprocess workers the same way, and every extraction worker built a full async runtime before doing entirely synchronous work. Clamp async workers to 16 and blocking to 32, clamp extraction workers to 8 and to the file count, and dispatch `ExtractWorker` before Tokio is constructed so a worker never pays for a runtime it does not use. Concurrent database health checks stampeded the same file, so they now queue behind one gate and record queue and execution time. Doctor's project status takes an explicit startup deadline instead of an implicit one, and the owned global control adapter gains CAS coverage for writes during and after a daemon scope. Committed as one snapshot because that is the state proven to build: `cargo dogfood` produced target/release/tracedecay from exactly this tree. That covers the library and binary, not the `#[cfg(test)]` targets also touched here, which remain unbuilt. The two `eprintln!` lines in `main.rs` and `indexing.rs` hand-roll the daemon log format on stderr and fire on every CLI invocation, including hooks. They read as investigation instrumentation rather than shipped output and want removal or routing through the daemon logger.
Plan 11's acceptance requires AST/import-boundary tests that fail when renderer code computes semantics it may only render. The ast-grep install in the CI dashboard job was dead: nothing ever invoked it, and no sgconfig.yml existed. Seven rules under tools/ast-grep/rules cover dashboard/src/viz: server state and wire imports, self-opened transports, ad hoc EventSource across the whole app, storage-persisted adapter layout, locally graded health/severity/readiness, drawing adapters re-ranking by a measured field, and renderer-held route authority. Each is written twice because ast-grep resolves .ts and .tsx as separate languages. Wired as dashboard `boundary:check` and a CI step, with the ast-grep install moved after setup-node so the global bin matches the toolchain that runs the gate. The workflow contract test now pins the step, the script, the rule directory, and every rule id, since a boundary step over an empty rule set would pass every time.
MSW was a devDependency with fixture handlers no Vitest suite consumed,
so every DOM test stubbed transport failures ad hoc through
vi.stubGlobal('fetch'). Plan 11 requires MSW to cover HTTP faults.
Add a setupServer harness beside the fixture handlers and drive three
workspace pages through 500, 404, 401, 403, a connection failure, a
non-JSON body, and a well-formed body the decoder rejects. Each case
asserts the honest state appears and that a plausible fabrication does
not: no invented count, no empty-queue copy for a queue nobody read.
The Codex Stop ingest had no rollout to read, and the project was never committed, so the advisory surface it asserts had no branch or head commit to mount. Seed a rollout whose cwd is this project and a git history, so both the registered project ingest and the advisory cycle run against real inputs instead of an empty workspace.
Moving observation writes onto the store runtime left the crash-harness barrier behind in the old global_db persist path with no callers, so the daemon never stopped at either boundary and every in-flight request completed before the harness could kill it. Put the claim protocol in tracedecay-store, where both boundaries can reach it: the pre-commit wait now blocks inside the rusqlite write executor with its transaction open, and the pre-ack wait blocks in the store adapter that owns the client response. Drop the orphaned copy.
Use canonical lineage event ordering to converge archive projections while rejecting conflicting states owned by the same event.
Memory selectors resolved a registered project but could only be served when that project was already the mounted graph, so a cross-project read could never reach the selected project's durable facts. Resolve the selected ProjectId's project shard read-only through the existing daemon store-runtime registry, denying identities the profile has not enrolled instead of substituting the active project. Path selectors now resolve a registered project that has no recorded store instance, and a selector matching several projects reports ambiguity rather than "not found".
The four-pillar advisory surface required a shared-store publication before it would return anything, but a publication is only recordable for a clean or blocked cycle. Any project whose GitHub, CI, or analyzer pillars are legitimately unavailable therefore terminates as incomplete coverage and the surface reported "unavailable" instead of the canonical result it had just computed. Mint the diagnostics handle from the cycle the owner just ran and return its typed terminal state (termination, provider states, and whether a publication was recorded) alongside the publication-backed diagnostics. Incomplete coverage stays explicit rather than rendering as a clean empty result, cancellation and timeout keep their own problem kinds, and the publication contract is unchanged.
Preserve analyzer and generation authorities across isolated production flows while keeping unavailable context typed and reconnect cleanup explicit.
Resolving a path selector through the project registry dropped the canonical-root ambiguity guard the store-record lookup applied, so a root claimed by two registered projects resolved to whichever one the alias table last named. Report those roots as ambiguous, and phrase every ambiguous selector as unresolved-with-candidates so hosts keep matching the unresolved wording while learning which registrations collided.
Route explicit user-scope reads through durable profile authority and join temporal recovery before searching. Preserve legacy Claude provenance and collapse singleton derived duplicates so replayed observations remain complete.
Summary
This draft PR is the consolidated delivery branch for TraceDecay V2 PR8 through PR13.
The branch also contains the supporting rusqlite runtime cutover, worktree-aware incremental indexing, storage retention/Doctor integration, and direct product tests required by the canonical V2 plans.
Verification
cargo check --all-featurescargo test --all-featurescargo clippy --workspace --all-targets --all-features -- -D warningscargo fmt --all -- --checkCurrent status: implementation is still being consolidated from the shared checkout and CI is red. This PR remains draft until the working tree is committed, broad verification is stable, and the historical conventional-commit blocker is resolved. It must not be merged in its current state.
Safety boundaries
GitHub review ingestion is read-only. Semantic indexing never blocks exact/lexical/graph retrieval and publishes only complete compatible generations. Local coordination logs, private transcript evidence, secrets, and ad hoc artifacts are excluded from commits.