Skip to content

feat: TraceDecay V2 delivery (PR8–PR13) + daemon performance, memory, and reliability overhaul - #707

Draft
ScriptedAlchemy wants to merge 3666 commits into
masterfrom
codex/tracedecay-total-redesign-plan-reopened
Draft

feat: TraceDecay V2 delivery (PR8–PR13) + daemon performance, memory, and reliability overhaul#707
ScriptedAlchemy wants to merge 3666 commits into
masterfrom
codex/tracedecay-total-redesign-plan-reopened

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Replacement review for #421 after its accidental merge was reverted from master in 52a9aab. This commit has the exact tree of #421 head d4c67d4. Do not merge until explicitly authorized.

Issues this PR fixes

Refs #753 (source-identity + restart journey tests landed on branch at eae9328; keep draft until full product journey/CI)
Refs #792 (journey acceptance pending)
Refs #837 (journey acceptance pending)
Refs #838 (journey acceptance pending)
Refs #855 (journey acceptance pending)
Fixes #862
Fixes #861
Fixes #810
Fixes #845
Fixes #856
Fixes #853
Fixes #799
Fixes #836
Fixes #830

Partially addressed here, tracked to completion on their own issues: #852, #800, #863, #843, #842, #848.

🤖 Generated with Claude Code

#887 dead-surface deletion inventory

  • Deleted 2,479 lines across 93 files (31 insertions), including uncategorized test ports, obsolete schema/registry helpers, dead graph/LSP/session/storage APIs, and stale dead-code suppressions.
  • build_state compatibility wrapper was deleted; the live get_gc_meta suppression was removed. clean_c_comment / clean_c_doc_comment are retained because feat: TraceDecay V2 delivery (PR8–PR13) + daemon performance, memory, and reliability overhaul #707 now has production callers in C, C++, GLSL, Go, and Objective-C extractors.
  • Remaining suppressions are limited to schema-derive carriers, feature-gated cross-binary test helpers, and platform/lifetime ownership roles with explicit comments; no future/follow-up suppression remains.
  • Verification: cargo check --workspace --all-targets; cargo clippy --workspace --all-targets -- -D warnings; both pass on the integrated branch.

#888/#890/#891/#892 workflow cleanup

  • Agent-suite inventory: 18 files / 134 tests -> 17 files / 122 tests; duplicate Claude inventories and prose/tool-name gates were deleted in favor of canonical schema, installer, and live CLI authorities.
  • Bundled skills: 18 skills / 1,953 body lines -> 17 skills / 449 body lines; reference/script material 502 -> 89 lines. The mandatory using-tracedecay bootstrap was deleted, detailed mechanics moved to live tool help, and unique safety/domain rules remain narrowly routed.
  • Managed skills now author routing descriptions and positive/neighbor/negative validation explicitly, support no_skill_needed, and keep only actual host size/syntax limits.
  • Kiro/Claude persisted steering migrated from prose headings to ownership sentinels with update/uninstall compatibility for shipped markers.
  • Eval harness carries endpoint profiles hermetically (env+model only, mode 0400), strips commands from skill-free arms, supports repeated parallel pools, and emits routing/outcome/efficiency/over-trigger metrics. Current-profile validation: 20/20 runs successful, both control/treatment isolated, positive/negative scenarios parsed and graded, zero 429s.

@changeset-bot

changeset-bot Bot commented Aug 24, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9ca6759

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

Post-reopen correction pushed in a23f86a: source-neutral background reconcile no longer advances the scheduler epoch and cancel in-flight text activation; mounted hook overflow uses the explicit invalidating path. Evidence: RED reproduced 0/1, GREEN 1/1 for ordinary_background_reconcile_does_not_supersede_in_flight_text_work; cargo check --lib --locked passed.

@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

if [[ -n "${{ steps.target-runtime.outputs.runtime_library }}" ]]; then
companion_args+=(
--companion
"${{ steps.target-runtime.outputs.runtime_library }}=${{ steps.target-runtime.outputs.runtime_entry_name }}"

P1 Badge Install the bundled Linux runtime beside the binary

For Linux targets, this archive now contains libonnxruntime.so.1, and the verification step succeeds only while that companion remains beside the $ORIGIN-linked executable. However, install.sh lines 80-84 extracts the archive and copies only tracedecay into the install directory before deleting the temporary directory. On systems without a compatible system ONNX Runtime, binaries installed through the advertised script will therefore fail in the dynamic loader even for --version; install the companion library beside the executable or use a layout whose runtime search path matches the installed location.


{
"type": "json",
"path": "server.json",
"jsonpath": "$.version"

P1 Badge Advance the SDK version in release PRs

The new npm publication job derives its version from the packed sdks/typescript/package.json, but this release-please list updates only the root manifest, CLI manifest, and server.json; the SDK manifest and lockfile remain fixed at 0.1.0. Starting with the release after 0.1.0, the job will either fail its different-integrity check for @tracedecay/sdk@0.1.0 or no-op for identical bytes, so no SDK version corresponding to the new stable release is published.


const overview = useQuery({
queryKey: ['delivery', 'overview'],
queryFn: () => fetchEnvelope('/api/delivery/overview', DeliveryOverviewV1Schema),

P1 Badge Scope Delivery queries to the selected project

When the scope bar selects a project other than the active project, this query keeps the same cache key and continues fetching the unprefixed active-project route. The dashboard already provides scopeKey and scopedUrl, and the backend mounts /api/projects/{id}/delivery/overview; without using them here, the page labels the selected project while showing another project's Git, CI, and release data, and switching scopes does not trigger a refetch.


let digest = RegistrationDigest {
project_id: project_id.to_string(),
canonical_root: registration_root.to_path_buf(),
git_common_dir: git_common_dir.clone(),
tracked_branches,

P1 Badge Include Git remote identity in the registration digest

When origin changes via git remote set-url without touching branch metadata or store artifacts, this digest remains identical, so the cache returns at lines 130-131 before git_remote_url is recomputed at line 147. The registry consequently retains the old remote and its alias, causing remote-based cross-project resolution to reject the new identity or continue resolving the stale one until an unrelated artifact changes; include the normalized remote in the digest.

AGENTS.md reference: AGENTS.md:L159-L161


private sendCurrentDiagnostics(): void {
const uris = vscode.languages.getDiagnostics().map(([uri]) => uri);
this.sendChangedDiagnostics(uris);

P2 Badge Batch startup diagnostics instead of dropping the tail

At activation or language-client restart, getDiagnostics() can return more than 32 document URIs, but this passes the entire list to limitAdmittedNativeDiagnosticDocuments, which permanently slices it to the first 32. Documents after that boundary are never synchronized unless they later emit a diagnostic-change or open event, leaving TraceDecay's native diagnostic state incomplete indefinitely for larger workspaces; split the startup list into bounded batches instead.

ℹ️ 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".

ScriptedAlchemy added a commit that referenced this pull request Aug 24, 2026
fix(clippy): clear the workspace clippy failures on #707
ScriptedAlchemy added a commit that referenced this pull request Aug 25, 2026
Removing the re-export shims left their module doc comments orphaned in
`context` and `graph`. The rest are pre-existing lints that only fire under
`--all-features`, which compiles the `test-transport` support surface as
non-test code:

- the registered-test-server constructor gets the file's existing explicit
  `expect_used` allow, since `lib.rs` denies it only outside `cfg(test)`;
- `http_application_registry` is read by the `cfg(test)` capacity journey and
  only reads as dead under `test-transport` alone, so the allow is gated to
  `not(test)` rather than renamed to a discard;
- the hotpath cadence helpers keep `#[inline(always)]` with an explicit allow,
  preserving the author's intent instead of silently downgrading it.

The `daemon_suite` restart wait is now the original helper recovered from the
PR #707 head rather than a reconstruction: it additionally proves the runtime
readiness receipt authorizes the exact configuration the SDK selected.
ScriptedAlchemy added a commit that referenced this pull request Aug 26, 2026
ScriptedAlchemy added a commit that referenced this pull request Aug 26, 2026
The relocation fix that anchored this test above the package allocated a
`PathBuf` only to hand out a reference, which `-D warnings` rejects as
`unnecessary_to_owned` and which failed the Clippy gate on #707.

`validate_requested_workload` takes `&Path`, and `CARGO_MANIFEST_DIR` is a
literal, so `Path::new` yields a `&'static Path` with no allocation and no
temporary to borrow from.
ScriptedAlchemy added a commit that referenced this pull request Aug 26, 2026
…707-20260826-a1

perf(index): integrate post-#721 catch-up delta into #707
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

#733 landed Clippy-red. Helper branch (not merged, shared checkout untouched):

cursor/707-clippy-after-733 @ latest HEAD of this PR (186880e550)

Clears the #733 Clippy denials:

  • nest Unbound | Unavailable or-patterns
  • collapse nested hint/witness and session-drain ifs
  • box SessionGraphAttachmentStateV1::Attached so the enum is not 808B

Adopt when you want:

git fetch origin cursor/707-clippy-after-733
git merge --ff-only origin/cursor/707-clippy-after-733

I will not land this on #707.

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

Clippy helper is now on the Codex worktrees (still not landed on this PR head):

  • relocate /fast/projects/tracedecay/.codex-worktrees/root-package-relocation @ 806b8c74ef (cherry-pick of 3293045f53)
  • post-721 /tmp/tracedecay-integrate-post721-707-a1 @ 127ab57fae (ff to 186880e550 then same cherry-pick)

Same change as cursor/707-clippy-after-733. I will not push/merge this onto #707.

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

Isolated post-#721 verification (worktree /tmp/tracedecay-integrate-post721-707-a1, CARGO_TARGET_DIR=/tmp/td-post721-isolated-target):

Green (non-vacuous) on merge 3b1baaee82 / later 127ab57fae:

  • tracedecay-graph-db --lib 87
  • tracedecay-runtime-core --lib 677
  • tracedecay-usecases --lib 837 (+1 ignored)
  • tracedecay-code-index --lib 177 (+1 ignored)
  • sealed_publication_tests 3, daemon::scheduler 33, session_runtime 1, sealed_projection_deadline_tests 1
  • late-bind native_declared_topology_projection 12

Not green

  • --all-features cannot compile tracedecay-rusqlite-runtime (admission.rs:120): hotpath::mutex! vs std::sync::Mutex because graph-db enables hotpath/hotpath without tracedecay-rusqlite-runtime/hotpath.
  • daemon::tests::scheduler 11 passed / 11 failed. Failures are scheduler_config::*: ensure_worker_planprofile code-index worker plan was not installed during daemon bootstrap (plus one writer-gate timeout and one missing scheduler key). Production bootstrap.rs still calls install_profile_worker_plan; the test daemon path does not.

Clippy helper remains on this tree at 127ab57fae / relocate 806b8c74ef. Not pushed to this PR head.

ScriptedAlchemy added a commit that referenced this pull request Aug 27, 2026
Ports the missing pieces of commit b1e41b712 ("fix(build): land the
batching commit's missing consumers") onto #707: HookCompletedReadinessDistributions
moved into tracedecay-agent-hosts with pub(crate) fields, so
input_rows_processed, input_rows_dropped_at_cap, and events_considered
are no longer reachable outside the crate. Adds the three public
accessors.

source_event and input_rows_received (also added by the source commit)
are not ported: nothing on this branch reads them through an accessor
today - the root-crate benchmark still compares via
serde_json::to_value(&readiness_distributions)["field"], which does
not need them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@cursor
cursor Bot changed the base branch from master to cursor/vendor-split-707-d6ed August 27, 2026 05:09
cursor Bot pushed a commit that referenced this pull request Aug 27, 2026
Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
@cursor
cursor Bot force-pushed the cursor/vendor-split-707-d6ed branch from 5d8f2a1 to c7fcf3f Compare August 27, 2026 05:52
ScriptedAlchemy added a commit that referenced this pull request Aug 27, 2026
…d6ed

chore(vendor): stacked vendor-only PR for #707 — generated vendor churn, land first
@ScriptedAlchemy
ScriptedAlchemy deleted the branch master August 27, 2026 06:24
@ScriptedAlchemy
ScriptedAlchemy changed the base branch from cursor/vendor-split-707-d6ed to master August 27, 2026 06:24
cursor Bot pushed a commit that referenced this pull request Aug 27, 2026
…rules

Co-authored-by: Zack Jackson <ScriptedAlchemy@users.noreply.github.com>
ScriptedAlchemy and others added 23 commits September 9, 2026 03:23
…plan-reopened' into fable/root-lib-tests

# Conflicts:
#	crates/tracedecay/src/lib.rs
…plan-reopened' into codex/tracedecay-total-redesign-plan-reopened
`02cd8b31f` derived `ApplicationSurfaceOperation::from_tool_name` from
the transport spelling alone, so `tracedecay tool diagnostics_read`
stopped resolving: `diagnostics_read` is the operation's canonical
identity, but its CLI/MCP binding is spelled `diagnostics`, and the
schema lookup then searched for an unadvertised
`tracedecay_diagnostics_read` definition and failed with `unknown tool`.

Resolve `tracedecay tool` names through the catalog's two spellings —
the CLI binding name and the canonical identity — then select the one
advertised MCP definition and the shipped request adapter by the
operation's transport spelling, so per-key flags, `--help`, and `--args`
behave identically whichever name the operator typed. The MCP transport
keeps its spelling-only contract.
`628006360` retired the in-process analysis owner for
`tracedecay_diagnostics`; the tool now dispatches to the application
surface, which reports typed transport unavailability instead of
awaiting the verified graph query. The absent-query-port probe still
listed it and expected the graph refusal.
`02cd8b31f` derived the parity set from every current dashboard
binding, sweeping in `native_integration_status`, whose read serves the
dashboard alone by design and has no HTTP handler to agree with. Derive
the set from dashboard bindings whose capability HTTP also serves, and
assert the diagnostics read stays in it.
`run_native_capture` measured its single synchronous budget from hook
start and spent it on both bounded lock waits: spool admission and the
delivery-receipt writer. The analytics row, enrolled-layout lookup, and
decode that precede admission consumed it on a loaded runner, so
`lock_until` refused an uncontended lock and the hook exited 1 after
answering `{}` — the `hook-cursor-stop exited with Some(1)` failure of
`hook_replay_test`. `95095d932` fixed the same anchoring for the
response hooks' output write; give each capture-path wait one budget
measured from its own attempt.
…lan-reopened

# Conflicts:
#	crates/tracedecay-contracts/src/doctor/adapters.rs
…an-1073-1088

refactor(runtime): replace project facade traits
…plan-reopened' into codex/tracedecay-total-redesign-plan-reopened
02cd8b3 made every application tool advertise its canonical schemars
request body verbatim. The default-profile tools/list grew from 573,502
to 737,884 bytes and tripped the 640 KiB regression tripwire: the three
CAS-gated configuration writes alone added ~75 KiB by re-embedding the
complete ConfigurationValueV1 / ProtectedChange unions (86 `$defs`
each), and 153 tools now carried a `$schema` marker, a root `title`
(the Rust type name), and rustdoc rationale paragraphs in every
description.

Every canonical body now passes through `mcp_input_schema` before it is
advertised: `$schema`, the root `title`, and the paragraphs after each
description's summary are dropped (validation semantics unchanged; SDK
generation reads the Rust type path, not the title). configuration_set,
configuration_batch, and configuration_protected_preview bound their
value unions to the canonical discriminator tags plus read-first
guidance, since the required `expected_revision` comes from a read that
already shows the typed value; HTTP and SDK keep the full schema. The
per-tool `format` description is shortened.

Measured default-profile payload: 737,884 -> 626,799 bytes, 4% under
the unchanged ceiling. The canonical-projection tests compare against
the same projection instead of the raw body.
Stock Hermes ranks deferred tools with BM25 over the tool name,
description, and parameter names. def5bc9 tripled the
tracedecay_search description without saying what the tool is, so its
length normalisation dropped the tool from first to fifth for the query
"semantic code search"; 02cd8b3 then re-derived the callable code tool
descriptions ("… code symbol search …", "… phrase search …"), which
pushed it to seventh and out of Hermes' five-result default. The
description now opens with what the tool does — semantic code search
over the code graph, fusing semantic and lexical routes with a lexical
fallback — and keeps the freshness, lexical_anchors, and prefer_symbol
guidance in fewer words. tracedecay_search ranks first again
(BM25 9.19 vs 7.60 for the runner-up) and scripts/hermes_stock_check.py
passes against the pinned upstream ref.
Feature gates (run 34309279328): the transcript_ingest bench's
run_provider_bench overflows rustc's query depth under
--features hotpath,hotpath-mcp; boxing the ingest pass future keeps its
layout out of the loop body.

Clippy on 3e9c635: map_or_else for the kill/reap messages, a heap
buffer for the 64 KiB pipe-echo helper, and a lint-free byte count in the
drain test.
pr_context folds each changed config file into one config_summary entry
that is returned but never analyzed as a seed, so seed_symbols_analyzed
is legitimately below symbol_page.returned whenever the PR touches
config (run 34309279328: 193 seeds + 6 summaries = 199). The strict
validator demanded equality; this branch was never reached before the
context phase started passing. It now requires every returned entry to
be a seed or a config summary, exactly.
observation_authority_reset_recovers_the_retained_temporal_authority
failed deterministically (CI runs 34296614024 and 34303181887, and
locally) at its `observed_converging` assertion: the describe it polled
after reopening the reset store never answered the converging refusal,
so the loop broke on evidence at the first read.

The transient is still there and still typed. Since 40c7841 the CLI
(`call_tool_with_project_open_retry`, behind the `tracedecay tool` path
every probe in this journey uses) honours a completed tool result's
`problem.retry: after_delay` and re-sends the request until the tool
deadline can no longer hold the delay. The converging refusal is exactly
that state: `RetainedSurfaceExecutionErrorV1::unavailable` renders as an
authority-class unavailable, pre-admission, after-delay, 250 ms, so
`tracedecay tool tracedecay_lcm_describe` now rides out the whole
convergence and hands back the converged answer. Measured on the
24-rollout fixture: the first describe after reopen took 30-42 s and
returned evidence at generation 2, while a doctor read 0.7-0.8 s after
reopen reported partial / stale / historical_convergence.

Requiring the journey to catch the refusal through a client whose
contract is to wait it out is a stale expectation, not a regression:
MCP clients still receive the typed state, and the CLI still surfaces it
once its deadline is exhausted. Restate the journey around what it can
assert without racing the worker. The first doctor read after reopen
(evidence, which the CLI never re-sends) must be the typed converging
state or already current, and current only with generations rebuilt.
Describe is read as the converged answer and must serve the session's
preserved LCM content unchanged. The rebuilt authority must re-record
the swept corpus and provider coverage. No fixture growth, no sleeps, no
deadline changes.
Both run_with_timeout harnesses polled try_wait without reading stdout or
stderr, so a child blocked on a full pipe could never exit and was killed
as a hang. branch_list_reads_profile_sharded_branch_meta hit this at 90 s
with the daemon's answer already written (~300 stderr lines under
machine-wide pipe pressure). Each pipe is now drained on its own thread
from spawn and joined when the child exits.
Master-bound pull requests kept their runs to completion so each landed
tip would get a verdict. In practice GitHub holds one pending run per
concurrency group: while the aed0b8d run spent 100+ min on the macOS
job, three later heads were queued and cancelled by each other without
ever scheduling a job, and the surviving head would have been judged
~100 min late. Cancelling the superseded run gives the current head the
earliest verdict, which is the only one anyone can act on.
The macOS job built `--workspace --bins --tests` in 80.2 min and ran the
suite in 19.9 min on the 3-vCPU runner (run 34303181887; run 34309279328
built for 74.9 min and was cancelled in its tests at 85 min), landing
~80 min after every other lane: it was the critical path of every pull
request run. rust-cache carries dependency artifacts only, so that build
is the workspace crates plus ld64 linking ~130 test binaries, every run.

macOS now runs the Linux partitions in four groups, one `macos-14` job
each, and `Test macOS` folds their verdicts and junit reports as
`Test Linux` does. A group runs each partition in turn against one
target directory with the selection `linux-test-partitions.py` resolves
for the Linux job (`build-args`, then nextest under the `ci` policy with
`--no-tests=fail`), so `root-sessions` and `root-journeys`, which share
one feature resolution, compile the chain beneath the root crate once.

Grouping, from the warm Arm partitions of run 34309279328 (compile +
tests, minutes): root-lib 14.7 + 7.5 alone, its root chain, library test
target and 1675 tests being the floor no split lowers; root-sessions
15.3 + 3.1 with root-journeys, which adds 2.7 + 2.7 on the shared
resolution; runtime 15.6 + 2.4 with core-storage 10.4 + 1.9;
core-contracts 13.9 + 0.6 with root-dashboard-api 12.7 + 0.8. Every
pairing that puts a second partition beside a root group is heavier than
the heaviest of these, and none of the other four shares a resolution,
so no other grouping saves compile. Expected wall: 28/31/40/38 min at
the 3-vCPU floor (compile x4/3), 38/43/57/56 at the 2x the one macOS
measurement showed (the chain beneath the root crate: 19.0 min on macOS
against 9.3 on Arm). The budgets take the 2x plus the 8 min
cold-dependency allowance and 25 % headroom the Linux budgets carry,
60/65/85/80, and the manifest records the arithmetic beside each group;
the first hosted run replaces them with measured time plus headroom.

The manifest is the one authority: every partition names its
`macos_group`, `check` proves every partition names a listed group and
every group runs a partition (beside the exactly-one-partition proof for
test targets), and `MACOS_GROUP_CAP` keeps a run to four of the
account's five concurrent macOS jobs so another run can start.
`scope-gate` derives the macOS matrix from it as it does the Linux one.
…plan-reopened' into codex/tracedecay-total-redesign-plan-reopened
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment