Skip to content

Whole-tree typecheck advisory carrier: ResolveTypecheckGate::DiagnosticsCollector (north-star #5760/#5772) - #5826

Closed
gunbai-bot[bot] wants to merge 4 commits into
mainfrom
fix/whole-tree-diagnostics-collector
Closed

gunbai-bot[bot] wants to merge 4 commits into
mainfrom
fix/whole-tree-diagnostics-collector

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Jun 25, 2026 •

Copy link
Copy Markdown
Contributor

What

The sole carrier authority for the north-star whole-tree typecheck work (driving down the ~779 orphan-module diagnostics #5760 parse-resilience unmasked). Builds the collect-and-continue gate + its first advisory consumer. Advisory only, non-blocking — promotion to a blocking gate is the operator's call once the count is driven to ~0 (DESIGN §5/§6; do not flip a floor gate from closure-scope to whole-tree-scope unilaterally).

Per the anti-fork pin: this PR is the single home for the WholeTreeCtx/whole_tree_resolved_ctx signature change; sunny-fox's #5774 drops its own carrier changes and consumes DiagnosticsCollector after this merges.

Carrier (cli_run.rs)

  • ResolveTypecheckGate::DiagnosticsCollector — no diagnostic is blocking; the full resolve/typecheck diagnostic set is returned (collect-and-continue), vs Strict (fail-closed) and DiscoveryCorpusAdvisory.
  • resolved_graph_from_sources returns diagnostics as a 3rd tuple element; WholeTreeCtx carries a resolve_diagnostics field; whole_tree_resolved_ctx takes the gate as a parameter (was hardcoded Strict). Existing 3-arg callers (the wiring-liveness whole-tree bin + its enum test) pass Strict — behavior preserved.

Consumer (whole_tree_typecheck_advisory.rs)

Thin advisory bin: resolves every module under the source roots in one pass under DiagnosticsCollector, prints one TSV line per diagnostic (module_name<TAB>file<TAB>message) for downstream classification, always exits 0. This is what makes resolve_diagnostics live (read by execution, not just typechecked).

Discriminating test (green by execution)

whole_tree_diagnostics_collector_test.rs over a 2-module fixture (one clean, one with a dangling call):

  • Strict fails closed; DiagnosticsCollector resolves both modules and surfaces the diagnostic naming wtd.broken + the missing symbol — the gate delta proven, not asserted.
  • a clean-only subtree collects zero diagnostics (no-fabrication control). Flip the dangling call to a real one and both gates go green — the red-witness control.

Corrected measurement: 179 → 8 (de-fabricated exclude)

The earlier "179 diagnostics / 22 modules" count was 96% a measurement artifact of the advisory bin's own default exclude, not corpus state. The default was a blanket ["test/fixture/"] — a path substring match that drops the top-level shared fixtures real test modules import (derivable_coercion_task_id, rung_3_4_common, rung_5_6_common, task_manager_demo, …). Excluding an imported module manufactures a phantom unresolved-import in every importer plus its cascade — the derivable_coercion=49, find_witness=29, nat_semiring rung clusters were all this.

This PR narrows the default to scanner/lens fixture INPUT subdirectories only (read by path, not importable: layering_scan/, transport_script_scan/, realization_vocab_scan/, medium_structure_scan/, extdeps_external_authority/, floor_skip/, program_assembly/) via a single-authority helper default_advisory_fixture_excludes. The corrected whole-tree count is 8 diagnostics / 6 modules.

The narrowing is justified by principle, not hand-tuned to a number, and pinned closed so it cannot silently re-broaden: the new test default_advisory_fixture_excludes_are_scanner_only asserts no entry is the blanket root, every entry is a test/fixture/<dir>/ subdir, imported shared fixtures are NOT excluded, and scanner inputs ARE (DESIGN §5 — a fabricating exclude is a fail-open measurement; pin it closed).

The remaining 8 are not corpus rot: a single root no field 'Env'/'Which' on type 'shell' — modules call shell.Env.Get / shell.Which.Check, and extdeps.shell does define service shell.Env + service shell.Which (shipped tools that resolve in-closure). This is a genuine whole-tree resolver service-member gap (QN-collision / service-resolution family), addressed in a separate follow-up PR (stage0 resolver, skew-prone — deliberately not folded here).

CI note

The only CI red expected is the inherited floor pair, which clears on #5821 (merged). This PR also folds a one-line fix for an inherited fleet-red (#5777 left a dead duplicate let extdeps_root that reds clippy --all-targets -- -D warnings on every .rs PR) so this PR's clippy gate is a true green signal — separate labeled commit.

🤖 Generated with Claude Code

briansrls and others added 2 commits June 25, 2026 21:12
…icsCollector + advisory reporter (north-star #5760/#5772)

Adds the collect-and-continue carrier the advisory whole-tree typecheck gate
needs, and its first consumer — advisory only, non-blocking. Promotion to a
blocking gate stays the operator's call once the count is driven to ~0
(DESIGN §5/§6).

Carrier (cli_run.rs):
- ResolveTypecheckGate::DiagnosticsCollector — no diagnostic is blocking; the
  full resolve/typecheck diagnostic set is returned (collect-and-continue),
  vs Strict (fail-closed) and DiscoveryCorpusAdvisory.
- resolved_graph_from_sources returns the diagnostics as a 3rd tuple element;
  WholeTreeCtx carries a resolve_diagnostics field; whole_tree_resolved_ctx
  takes the gate as a parameter (was hardcoded Strict). Existing 3-arg callers
  (the wiring-liveness whole-tree bin + its enum test) pass Strict — behavior
  preserved.

Consumer (whole_tree_typecheck_advisory.rs):
- thin advisory bin: resolves every module under the source roots in one pass
  under DiagnosticsCollector and prints one TSV line per diagnostic
  (module_name<TAB>file<TAB>message) for downstream classification. Always
  exits 0. This is what makes resolve_diagnostics LIVE (read by execution).

Discriminating test (whole_tree_diagnostics_collector_test.rs, green by
execution): over a 2-module fixture (one clean, one with a dangling call),
Strict fails closed while DiagnosticsCollector resolves both modules and
surfaces the diagnostic naming wtd.broken + the missing symbol; a clean-only
subtree collects ZERO diagnostics (no fabrication control).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ml_markup_smoke_test

#5777 left an exact duplicate binding (line 13 immediately shadowed by an
identical line 15, used at the .arg() call). `cargo clippy --all-targets
-- -D warnings` (the CI rust gate) reds on the shadowed dead binding, so every
.rs PR inherits the red. One-line dead-code removal; unrelated to the carrier
but folded here so this PR's clippy gate is a true green signal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Jun 26, 2026
…sCollector

Drop the §3 carrier fork before marking #5774 merge-eligible:
- Remove WholeLivenessCorpus arm from resolved_graph_from_sources match
- Remove wiring_liveness_whole_tree binary from Cargo.toml
  (source already deleted by prior auto-commit; Cargo decl was orphaned)
- Restore ensure_wiring_liveness_whole_tree_built in host_prelude.dag
  (transport.dag imports it; reverted accidentally by gate-flip strip)

Everything else from the gate-flip is already stripped in the prior
WIP commit (e62b64b): enum variant, typecheck_gate param, ci_spec/
ci_gates/ci_floor_plan gate enrollments, wiring_liveness_gate.dag,
wiring_liveness_whole_tree.rs binary source.

The wiring gate-flip re-lands as a follow-up stacked on #5826, which
carries DiagnosticsCollector — the single carrier authority.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
briansrls and others added 2 commits June 25, 2026 21:30
…bdirs only (179→8)

The advisory bin's default exclude was a blanket `["test/fixture/"]`, a path
substring match that dropped the top-level SHARED fixtures real test modules
`import` (derivable_coercion_task_id, rung_3_4_common, rung_5_6_common,
task_manager_demo, …). Excluding an imported module fabricates a phantom
unresolved-import in every importer plus its cascade — ~171 of the 179 reported
diagnostics were this measurement artifact, not corpus state.

Narrow the default to scanner/lens fixture INPUT subdirectories only (read by
path, not importable: layering_scan/, transport_script_scan/,
realization_vocab_scan/, medium_structure_scan/, extdeps_external_authority/,
floor_skip/, program_assembly/) via a single-authority helper
`default_advisory_fixture_excludes`, wired into the advisory bin. The corrected
whole-tree count is 8 diagnostics / 6 modules; the 8 are a real whole-tree
resolver service-member gap (shell.Env / shell.Which), addressed separately.

The narrowing is justified by PRINCIPLE, not hand-tuned to a number, and pinned
so it cannot silently re-broaden: `default_advisory_fixture_excludes_are_scanner_only`
asserts no entry is the blanket root, every entry is a `test/fixture/<dir>/`
subdir, imported shared fixtures are NOT excluded, and scanner inputs ARE
(DESIGN §5 — a fabricating exclude is a fail-open measurement; pin it closed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

CI red @ d531b63 is infra-OOM, not a carrier regression — no fix to push.

Both failing jobs (ci, rust_tests) die at the same point with the same signature:

sccache: Compiler killed by signal 9
error: could not compile `v1-compiler` (lib)  (exit status: 254)

That is rustc itself SIGKILL'd while compiling v1-compiler lib — at CARGO_BUILD_JOBS=1, on the BUILD step, before any test or witness runs. There is no FAIL [batch N] marker and no error[...] compile diagnostic — the discriminators of a real red. The carrier diff is 3 small files (advisory-exclude helper + bin wiring + a pin test); it compiles clean and passes fmt + clippy (-D warnings) + the 3 carrier tests locally. Host memory pressure is OOM-killing the rustc process, which is the host-converge tentpole tracked at the fleet level, not anything in this PR.

Action: HOLD the frozen HEAD (d531b63). No re-push, no re-run — re-running just re-rolls the same OOM dice. This clears when the host-converge cap applies. Already approved (claude, zero findings); the remaining gates are a 2nd distinct provider + host-converge, both operator-owned.

— sent from smart-wolf-187

@briansrls briansrls closed this Jun 26, 2026
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.

1 participant