Skip to content

simplify(diagnostics): publish compiler status through the project owner - #4545

Open
ScriptedAlchemy wants to merge 5 commits into
masterfrom
simplify/diagnostics-project-compiler-status
Open

ScriptedAlchemy wants to merge 5 commits into
masterfrom
simplify/diagnostics-project-compiler-status

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Fixes #4433. Parent link: none (stack S5 link 1, base master).

Problem

diagnostics_producer.rs copied each producer run into a process-global LAST_RUNS: Mutex<BTreeMap<PathBuf, ..>> with no removal path; availability reads joined it by pathname, so a successor owner at the same path would report its predecessor's run.

Fix

  • New TypeScriptProducerStatusV1 + TypeScriptProducerStatusHandleV1 (immutable Arc snapshot behind a lock). One handle is created per project owner at open, passed to the producer (via TypeScriptProducerStateV1::new) and to the owner's OwnedPrimitiveRuntime (via ProductionPrimitiveOpenRequestV1).
  • typescript_diagnostics_availability and the two diagnostics-absence problem builders read from the owner's handle.
  • Deleted LAST_RUNS, last_runs, last_record, last_producer_run, record_producer_run. Teardown retires the status with the owner; a superseded producer can only publish into its own handle.
  • Reset-required routes (no producer) get a fresh empty handle, i.e. "not run".
  • Per-tsconfig checked/failed/no-compiler/NoTsconfig distinctions are unchanged; findings still come from generation-bound publication only.
  • Not added: an attempted-generation field (Published already carries the generation; nothing reads another).

Verification

  • bazel test //crates/tracedecay-application:unit_test --test_arg=diagnostics_producer: 5 passed, incl. new a_successor_owner_does_not_inherit_the_predecessors_status and a_status_handle_publishes_to_its_owner_only; existing primitives::runtime diagnostics tests pass.
  • bazel build --config=clippy //crates/tracedecay-application/... //crates/tracedecay:all succeeds.

🤖 Generated with Claude Code

The TypeScript producer recorded each run into a process-global,
path-keyed LAST_RUNS map that nothing ever removed, and availability
reads joined it by pathname. A successor owner at the same path could
therefore report its predecessor's run as its own.

Each project owner now creates one TypeScriptProducerStatusHandleV1 at
open. The producer publishes into it and the owner's primitive runtime
reads from it; the global map, last_record, last_producer_run and the
path-only status API are deleted. Teardown retires the status with the
owner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 099ed21

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

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

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Devin Review

));
// One status handle per project owner: the producer publishes into it and
// this owner's diagnostics reads describe it.
let compiler_status = TypeScriptProducerStatusHandleV1::default();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Reopened projects lose compiler status

After cache eviction and reopening, compiler_status reaches the new producer but not the retained primitive runtime. The primitive registrar accepts an existing runtime without replacing its handle, so diagnostics reads report pending despite completed checks.

Learn more

A bounded project-server cache can evict a server without removing its registered primitive runtime. On reopening the same root, project-open creates a new status handle and passes it to the new producer. The primitive registrar silently keeps the existing runtime on AlreadyRegistered, leaving diagnostics reads attached to the old handle. The new producer publishes normally, but its status never reaches those reads.

Example: Open TypeScript project A, then fill the bounded server cache until A is evicted. Reopen A and let its compiler fail. Its new producer records the failure in the new handle, while A's retained primitive runtime still reads the old handle and reports the earlier check or a pending state.

Recommended fix: Reuse the status handle owned by the existing registered primitive runtime when reopening a root, or replace the runtime atomically with the new one before starting the producer. Cover eviction followed by reopening and a changed compiler outcome in a production-path test.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Holding this thread: Autopilot will not pick a compiler-status handle protocol after cache eviction without an operator decision.

Devin's claim is that a bounded server-cache eviction can drop the project server while the primitive runtime stays registered. Reopen then mints a new compiler_status handle for the new producer, but AlreadyRegistered keeps the old runtime, so diagnostics reads stay on the prior handle.

Please choose one:

  1. Reuse the status handle already owned by the retained primitive runtime when reopening the same root.
  2. Replace that runtime atomically with the new handle before the producer starts.
  3. Leave it: treat this as out of this PR, or as the same compiler-supervision/lifetime work already assigned elsewhere (simplify(diagnostics): share daemon compiler admission and bounds #4546 / simplify(typescript): replace the diagnostic owner's handwritten tsconfig interpreter with compiler-owned project evidence #4440).

I will not change registrar ownership or start the producer against a second handle until that call.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

simplify(diagnostics): replace the global last-run map with project-owned compiler status

1 participant