Skip to content

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

Draft
ScriptedAlchemy wants to merge 3404 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 3404 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: ebe2706

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>
`stock_host_registration_evidence` was an 18-arm `match` building
near-identical `HostRegistrationEvidenceV1` rows per host. Replace it with
one `const HOST_REGISTRATIONS: &[HostRegistrationDescriptor]` table (host,
route, evidence_ref, starts_analyzer) written through a small local
`macro_rules!`, and implement the function as a filter over the table that
projects each row's state from the canonical capability matrix via
`HostRegistrationRouteV1::capability()`, which stays the only route ->
capability mapping.

Output is byte-identical for every host: 57 rows across 18 hosts, CLI row
first (consumers index `routes[0]`). The pre-change rows were captured
from the `match` into `fixtures/stock_host_registration_evidence.json`
and a test asserts every host's projected rows equal that fixture. The
completeness test now iterates the table and every `HostKindV1` variant.

Closes #1089
The freshness witness reduced every source candidate to (path, len,
mtime) and treated an equal signature as proof that the retained
generation was source-current. A same-length rewrite whose mtime was
preserved (rsync -a, cp --preserve, touch -d, restore tools) therefore
never reconciled and the stale generation served indefinitely, on the
live ladder, across restart, and for explicitly admitted ignored sources.

The stat signature is now a negative cache only. Unequal metadata still
skips straight to reconcile without reading a byte. Equal metadata is
followed by re-deriving each candidate's canonical content digest through
the same bounded read + sanitize + digest path capture uses and comparing
it against the generation's own sealed file manifest
(SanitizedCodeSnapshotV1::files). The fence, the query ladder, restart
admission, the retained text path, and the empty-serving seat all consult
that manifest; the on-disk witness format is unchanged and keeps naming
the generation whose manifest is the authority.

A tracked file whose raw bytes disagree with a clean-tree generation may
still be exactly HEAD's blob once git's clean filters (core.autocrlf, eol,
ident, drivers) are applied, so disputed tracked files are re-checked
through the repository's filter pipeline before they disprove currency;
untracked and admitted sources have no blob to be sealed from.

Closes #1071.
The scheduler and registry docs still called the freshness ladder a stat
signature proof. Name the two layers as they now behave: the stat sweep
as the negative cache and the sealed file digests as the currency proof.
`kiro_hooks_capture_prompt_boundary_and_type_post_tool_use_unsupported`
expects the Kiro `userPromptSubmit` callback to spool its PromptBoundary
envelope when no daemon answers. ee3b8a8 (merged through a919de7) made the
Codex and Kiro prompt callbacks answer `{}` and exit 0 without dispatching when
the profile has no installed identity record, and the enrollment fixture only
pinned the repository identity and published the hook binding — it never
installed the profile, so the hook stayed quiet and nothing reached the spool.

An enrolled project always belongs to an installed profile in production, so
`enroll_native_capture_project` now installs the identity through the canonical
`profile_identity::load_or_create` authority before creating the project store.

`cargo test -p tracedecay-cli --test core_cli_suite -- tool_daemon_test::kiro_hooks_capture_prompt_boundary_and_type_post_tool_use_unsupported --exact`
→ 1 passed.
With the `hotpath` feature every `#[hotpath::measure]` async fn lays out as
13 nested layout_of frames (the fn future, `measure_async[_future]`, the
`InstrumentedFuture`/caller-scope wrapper and the body block, each behind
`MaybeUninit`/`ManuallyDrop`/`MaybeDangling`) instead of 4, so the registered
schema admission chain overflowed rustc's 128-deep query limit wherever a
concrete admission future was laid out: `attach_registered_inner`'s boxed
block in tracedecay-store-runtime (the `--all-features` CLI build), and the
`HostAdmissionTestRuntimeV1` / `RegisteredGlobalDbTestRuntime` harness roots
in the tracedecay-global-db, -session-temporal-store and -session-memory lib
tests.

The expanding child was the same in all four crates (full query stack via
`-Ztreat-err-as-bug`): `admit_and_attach_with_operation_task_owner` ->
`converge_attached_registered_schema` -> `converge_registered_schema_on` ->
`ensure_authority_invariants` -> `authority_invariant_step` ->
`validate_projection_authority_chunk` -> `validate_projection_authority_suffix_pages`
-> `verify_native_source_supersession` -> `resolve_output_projection` ->
`message_projection` -> `derive_projection_with_alias` ->
`derive_projection_with_alias_from_generation` ->
`durable_projection_disposition` -> engine query. The sibling admission
path through `ensure_attached_registered_schema` ->
`classify_registered_schema_admission` ->
`require_admissible_session_temporal_schema` -> contract validation ->
`read_table_metadata` sat between 105 and 112 frames on its own.

The three phase owners now run their state machine behind `Box::pin` so the
admission futures embed only a pointer and rustc lays each phase out as its
own root: `ensure_authority_invariants` (the resumable audit),
`classify_registered_schema_admission` (read-only authority classification)
and `install_registered_schema_stages` (the admission transaction). Signatures,
measure labels, error mapping and ordering are unchanged; the deepest chain in
the global-db lib test drops from >128 to at most 104 frames.

Closes #1068.
`lsp_disconnect_expiry_settles_unacknowledged_outbound_as_dropped` ran its
whole body under `start_paused = true` so it could advance past
`LSP_SESSION_TTL_MS`. Its final step drains the delivery settlement recorder,
whose durable writes go through the SQLite writer. b501f51 moved that writer
from `spawn_blocking` — which inhibits tokio's paused-clock auto-advance while
in flight — to awaiting an `async_channel` acknowledgement from the writer
thread. The paused runtime no longer sees any pending work while the write is
outstanding, auto-advances straight to the recorder's shutdown timer, and the
drain reports `delivery_settlement_recorder_shutdown_deadline` although the
write completes moments later.

Pause the clock only around the TTL advance and resume it before the drain, so
the settlement runs against real time like every other LSP delivery test.

`cargo test -p tracedecay --lib --features test-helpers -- daemon::invocation_tests::lsp_tests::lsp_disconnect_expiry_settles_unacknowledged_outbound_as_dropped --exact`
→ 1 passed.
`the_hook_runtime_handle_answers_through_root_adapters` (914bde7) compared
the resolved `StoreLayout::project_root` against the canonicalized temp root
while handing the runtime the raw `tempdir()` path. The layout keeps the
caller's spelling of the root, so on macOS — where temp roots live behind the
`/var` -> `/private/var` symlink — the assertion compared two spellings of one
directory and failed. Linux temp roots are already canonical, which is why the
Linux run stayed green.

Canonicalize the fixture root before use, the way the other daemon fixtures
already do (617949c, 0664edf), and compare against that same path.
`write_hook_output` retains a delivery receipt before answering the host, and
its spool writer lock is shared with the daemon's replay consumer. The a919de7
merge resolution switched that open from a non-waiting `open` to
`open_until(started + synchronous budget)`, anchoring the lock wait at the hook
process's start. The synchronous budget is 100 ms; several response hooks
legitimately spend longer than that before they reach the write — the Kiro
prompt callback runs a bounded transcript catch-up (1.5 s budget) and the
Codex PostCompact callback awaits the daemon's compaction journey. For them the
deadline was already expired on arrival, so `lock_until` refused even an
uncontended lock, `write_hook_output` returned false before writing stdout, and
the hook exited 1 with no output for the host.

Anchor the bounded wait at the write itself: one synchronous budget to acquire
the shared lock, whatever the body cost. The `started` parameter no longer has
a reader, so drop it and the bindings that only fed it.

Fixes `codex_compaction::codex_post_compact_hook_commits_app_server_summary_through_daemon_effect`
(deterministic: the compaction always outlasts the budget) and the
`hook-kiro-prompt-submit exited with Some(1)` attempt of
`hook_replay_test::replayed_provider_hooks_record_attributed_rows_and_bridge_to_analytics_events`
(timing-dependent on the same deadline).
ffa01d3 routed the capture-only native callbacks (and Claude's retired
`preToolUse`) through `record_native_capture_invoked`, so every hook the host
fires records one attributed `hook_invoked` row whatever its capture outcome —
14 of the 27 native commands had been firing silently. The a919de7 merge
took `hook_replay_test` from the other lane (ee3b8a8), whose
`emits_timing_rows` still expected zero rows from those callbacks, while
production kept ffa01d3's recorder; the replay then found the Claude
`preToolUse` row production now writes and failed.

Restate the test to ffa01d3's contract: exactly one row per replay, and
every one of them bridged into `analytics_events`.

`cargo test -p tracedecay --features test-helpers --test hooks_lsp_suite -- hook_replay_test::replayed_provider_hooks_record_attributed_rows_and_bridge_to_analytics_events --exact`
→ 1 passed (with the receipt-wait fix).
9bc7ded (#899) made a selector-bound `fact_store get` report the scope of
the project whose store actually answered instead of the calling session's
admitted project. 2f17bc8 (merged through a919de7) carried an older local
copy of `get_selected_project_fact` that asserts the admitted project id on
`scope.project_id`, so the acceptance journey failed with project B's id where
it expected project A's.

Assert the selected project's id, keeping the `assert_ne!` so the restatement
is only satisfied by a genuinely restated scope.

`cargo test -p tracedecay --features test-helpers --test runtime_acceptance_suite -- grafeo_restart_acceptance::memory_relation_graph_survives_physical_daemon_restart_and_isolates_profile_and_projects --exact`
→ 1 passed.
`native_stream_projection_replaces_retained_effects_and_rebuilds_without_duplicates`
(2f17bc8, merged through a919de7) seeds a projection alias row named
`retained.cline.message`. The global database authority audit has always
admitted only `consolidated/<lineage>/<unaliased message id>` aliases
(`validate_alias_binding`), and it runs on every open; after the native source
transition transfers that alias to the successor and the test reopens the
profile runtime, the audit refused the fixture with "projection alias is not
an eligible consolidation output binding".

Seed an alias production could have produced — `consolidated/retained/`
over the canonical fixture's `record.projection-cline.0` — and assert on it.

`cargo test -p tracedecay --features test-helpers --test session_suite -- observation_projection::source_transition::native_stream_projection_replaces_retained_effects_and_rebuilds_without_duplicates --exact`
→ 1 passed.
069ca84 (#890/#892) cut the bundled skills down to domain guidance and
deferred tool schemas to the live catalog. It also dropped every mention of the
mutating tool families, so `registered_tools_are_referenced_by_the_plugin_bundle`
found 61 registered tools — Work, Workflow, Context Scout control,
configuration mutation, source edits, fact writes, session refresh, native
integration, worktree removal — that no skill, rule, command, or agent in the
Cursor bundle points an agent at, which is the silent-tool-family state that
guard exists to catch.

Name each tool once, inline where its skill already describes the operation
(`managing-work`, `managing-workflows`, `editing-safely`, `project-memory`,
`reviewing-changes`, `discovering-tracedecay`, `managing-session-context`).
Names are routing hints, not the argument catalogs #892 removed; the bodies
still defer arguments to the live schemas.

`generated_skill_mirrors_session_context_retrieval_contract` is restated to
the same split: the repository skill and the Hermes skill must both route to
the retrieval operations and preserve the wire fields (`next_cursor`,
`coverage`, `anchors`, `needs_synthesis`), while argument defaults and worked
guidance (`provider=all`, `temporal_mode=…`, `begin`/`status`/`cancel`, …)
stay a requirement of the Hermes template, which is the full manual its host
installs and which 069ca84 did not touch.

`cargo test -p tracedecay --lib --features test-helpers -- mcp::tools::plugin_conformance_tests::registered_tools_are_referenced_by_the_plugin_bundle mcp::tools::plugin_conformance_tests::plugin_tool_mentions_resolve_to_registered_tools mcp::tools::plugin_conformance_tests::readme_mcp_allowlist_matches_read_only_tools --exact`
→ 3 passed.
`cargo test -p tracedecay --features test-helpers --test hermes_suite -- lcm_bridge::generated_skill_mirrors_session_context_retrieval_contract --exact`
→ 1 passed.
The serving-readiness test asserted that a source hint makes the query
ladder report a required reconcile. After e92e602 the ladder judges
movement from source truth only, because the hint already posted its own
pass and a query that re-reported it escalated the targeted hint pass
into an observed-change rescan. The production invariant the test
guards is that the seated proof is refused until that pass revalidates
it, which the fence still enforces through the epoch; assert both halves
explicitly.

The semantic availability journey read only the first page of a
truncated tracedecay_search answer; reassemble the handle through
offset / next_offset / has_more exactly as the CLI and the bootstrap
harness do.
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

CI red-suite triage (run 34168826002) — landed at 04da312 (fable/ci-red-suite, 10 commits) plus 5c1623f.

All 11 non-lane-owned failures are green with --exact, enclosing suites pass, and clippy -D warnings is clean on the touched crates. Two production regressions from the d2868ead9..e20241d86 reconcile merges are fixed at their owning boundary:

  1. write_hook_output anchored its receipt-spool lock deadline at hook start (a919de7 merge resolution), so any response hook whose body outlasted the 100 ms synchronous budget — Codex PostCompact, Kiro prompt-submit — exited 1 with no stdout; it now bounds the wait from the write (95095d9).
  2. freshness_probe_requires_reconcile (2f17bc8) treated a hint-advanced cancellation epoch as source movement, letting a racing query escalate a targeted hint pass into an overflow rescan; it judges from Git metadata / the source witness again (e92e602). The seated-proof fence still refuses a hinted seat through the epoch; 5c1623f asserts both halves in serving_readiness_tests.

The remainder were tests that lost their contract in the merge — Refused vs Offline census (2f17bc8), selected-project evidence scope (#899 / 9bc7ded), one analytics row per native callback (ffa01d3) — plus fixture defects (audit-refused alias shape, missing profile identity after ee3b8a8, macOS /private root, paused clock vs the b501f51 writer thread) and the #892 skill refactor having dropped all 61 mutating tool names from the bundle (restored as inline names, no argument catalogs; the Hermes marker test split accordingly).

Excluded: the two store-runtime publication tests (fixed under #1066) and published_text_artifact_with_stale_search_revision_is_rebuilt (fixed in f528683). Observed once as a load flake, not fixed: graph_off_overflow_preserves_text_owner_progress_without_full_decode (TRY 1 fail / TRY 2 pass under nextest). Fixture-gated FastEmbed journeys that CI cannot see are red and tracked in #1097.

`InvocationConnectionLease` settled every drop with one boolean: a
successful request returned its stream to idle, and any other outcome
discarded the stream *and* cleared the whole idle pool. One reset socket
therefore forced every concurrent caller to reconnect and re-handshake
even when the daemon behind the pool had not changed.

Replace the boolean with an explicit `LeaseDisposition`:

- `Return` — the request settled on this stream; it goes back to idle.
- `DiscardOne` — the default. Write/read/protocol failures, cancellation,
  timeouts, indeterminate effects and unacknowledged deliveries retire
  only their own stream. Possibly desynchronized sockets still never
  return to idle.
- `InvalidatePool` — only on evidence the daemon generation changed: the
  daemon refused this client's handshake (revision or credential
  rotation), or the authority liveness probe reports the record that
  named this endpoint is no longer current (restart). Production
  connections discovered through the authority record always carry that
  probe, so a real restart still drains the pool on the first failure.

Two hotpath gauges (`…pool.discarded_total`, `…pool.invalidated_total`)
make reconnect storms attributable to one or the other.

The former `transport_failure_purges_other_idle_connections_before_reconnect`
test asserted the old over-invalidation without any authority evidence; it
now models a restart with a rotated authority record. New tests prove a
request-local failure leaves the other idle stream reusable (and reused
without a new accept), and that a handshake refusal drains the pool.

Closes #1041.
`QuiescedDaemonLifecycle`'s `Drop` ran `let _ = self.restore();`. When
maintenance code unwound before an explicit `finish*`, a failed fallback
restore vanished: the managed daemon could be left stopped with nothing
naming it. The same fallback also re-ran a restore whose failure an
explicit `finish*` had already returned to its caller, silently spending
a second readiness window on the same failure.

Replace the `restored: bool` with a `RestoreSettlement`:

- `Owed` — restore not yet successful; `Drop` is the fallback.
- `Complete` — set only after a restore actually succeeds, or when the
  caller explicitly waives it (`finish_without_restore`).
- `FailureReturned` — an explicit finish attempted the restore and
  returned the typed error; `Drop` neither retries nor re-reports it.

`Drop` now attempts the restore only while `Owed` and, if it fails, emits
one `tracing::error!` carrying the captured prior state, the expected
daemon version, whether the exclusive lease was still owned, and the
typed restore error. It never panics, so an in-flight unwind is not
turned into an abort. Explicit `finish`, `finish_with_state`,
`finish_after_update` and the combined operation+restore paths keep
returning their errors directly.

Tests capture the crate's `tracing` output: an unwind after quiesce with
a failing systemd `start` attempts the restore exactly once and logs one
structured error with those fields; an explicit `finish` that fails
returns the error, attempts no second restore, and logs nothing; a
completed finish leaves `Drop` silent.

Closes #1042.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment