feat(schema): close prose-and-shape drift gate; regenerate from Rust#380
Merged
Conversation
BartWaardenburg
added a commit
that referenced
this pull request
May 16, 2026
…/ SvelteKit Two issues caught by parallel review on PR #380: 1. BLOCK: CoverageSetupFramework variants NestJs / SvelteKit landed as `nest_js` / `svelte_kit` in the regenerated schema (and downstream TS contracts). The runtime emits `nestjs` / `sveltekit` (per crates/cli/src/coverage/mod.rs:106-108 and crates/cli/src/explain.rs:958), so the schema rejected every real NestJS / SvelteKit setup output under ajv strict validation. The Rust enum had `rename_all = "snake_case"` without explicit per-variant renames for NestJs / SvelteKit; NextJs had a per-variant rename that worked correctly, masking the gap. Root cause was twofold: - `CoverageSetupFramework` (and its sibling helper enums) are NOT in `derived_definition_names()`, so `merge_with_committed` treats them as transitively-referenced helpers handled by the second loop. - That second loop carried a `if definitions.contains_key(name) { continue; }` guard that silently preserved the committed schema's stale helper definitions on every regen. Any change to a serde rename / schemars attribute on a helper was invisible until the helper was deleted by hand from `docs/output-schema.json`. Fix: invert the guard so derived helpers always overwrite the committed entry, with the `derived_definition_names()` in-scope set skipped because those are processed by the first loop with augmentation. After Phase 8 every helper in `docs/output-schema.json` is a derived artifact, so the "preserve hand-authored helpers" rationale no longer applies. Added `#[serde(rename = "nestjs")]` to `NestJs` and `#[serde(rename = "sveltekit")]` to `SvelteKit` to match the wire and the established `NextJs` pattern. 2. LOW: stale comments in `crates/cli/src/bin/schema_emit.rs`. The `finding_definition_names()` docstring still said "requiredness is decided by the committed schema and the augmentation is non-opinionated", but the augmentation now unconditionally pushes `actions` into required. The `committed_definitions_match_derived_property_keys` test still described `actions_meta` as injected via post-pass on `serde_json::Value` rather than modeled on the typed envelope, but Phase 8 typed it as `Option<HealthActionsMeta>` on `HealthReport`. Both rewritten to reflect current behaviour. Verified: - Strict drift gate still passes (7 schema tests). - `cargo test --workspace --all-targets` green. - `cargo clippy --workspace --all-targets -- -D warnings` clean. - `pnpm run check:codegen` clean (TS contracts regenerated). - `CoverageSetupFramework` definition now emits `nextjs` / `nestjs` / `nuxt` / `sveltekit` / `astro` / `remix` / `vite` / `plain_node` / `unknown`, matching the runtime and `_meta.enums`.
BartWaardenburg
added a commit
that referenced
this pull request
May 16, 2026
…/ SvelteKit Two issues caught by parallel review on PR #380: 1. BLOCK: CoverageSetupFramework variants NestJs / SvelteKit landed as `nest_js` / `svelte_kit` in the regenerated schema (and downstream TS contracts). The runtime emits `nestjs` / `sveltekit` (per crates/cli/src/coverage/mod.rs:106-108 and crates/cli/src/explain.rs:958), so the schema rejected every real NestJS / SvelteKit setup output under ajv strict validation. The Rust enum had `rename_all = "snake_case"` without explicit per-variant renames for NestJs / SvelteKit; NextJs had a per-variant rename that worked correctly, masking the gap. Root cause was twofold: - `CoverageSetupFramework` (and its sibling helper enums) are NOT in `derived_definition_names()`, so `merge_with_committed` treats them as transitively-referenced helpers handled by the second loop. - That second loop carried a `if definitions.contains_key(name) { continue; }` guard that silently preserved the committed schema's stale helper definitions on every regen. Any change to a serde rename / schemars attribute on a helper was invisible until the helper was deleted by hand from `docs/output-schema.json`. Fix: invert the guard so derived helpers always overwrite the committed entry, with the `derived_definition_names()` in-scope set skipped because those are processed by the first loop with augmentation. After Phase 8 every helper in `docs/output-schema.json` is a derived artifact, so the "preserve hand-authored helpers" rationale no longer applies. Added `#[serde(rename = "nestjs")]` to `NestJs` and `#[serde(rename = "sveltekit")]` to `SvelteKit` to match the wire and the established `NextJs` pattern. 2. LOW: stale comments in `crates/cli/src/bin/schema_emit.rs`. The `finding_definition_names()` docstring still said "requiredness is decided by the committed schema and the augmentation is non-opinionated", but the augmentation now unconditionally pushes `actions` into required. The `committed_definitions_match_derived_property_keys` test still described `actions_meta` as injected via post-pass on `serde_json::Value` rather than modeled on the typed envelope, but Phase 8 typed it as `Option<HealthActionsMeta>` on `HealthReport`. Both rewritten to reflect current behaviour. Verified: - Strict drift gate still passes (7 schema tests). - `cargo test --workspace --all-targets` green. - `cargo clippy --workspace --all-targets -- -D warnings` clean. - `pnpm run check:codegen` clean (TS contracts regenerated). - `CoverageSetupFramework` definition now emits `nextjs` / `nestjs` / `nuxt` / `sveltekit` / `astro` / `remix` / `vite` / `plain_node` / `unknown`, matching the runtime and `_meta.enums`.
ea06c88 to
a82e072
Compare
This was referenced May 16, 2026
BartWaardenburg
added a commit
that referenced
this pull request
May 16, 2026
…/ SvelteKit Two issues caught by parallel review on PR #380: 1. BLOCK: CoverageSetupFramework variants NestJs / SvelteKit landed as `nest_js` / `svelte_kit` in the regenerated schema (and downstream TS contracts). The runtime emits `nestjs` / `sveltekit` (per crates/cli/src/coverage/mod.rs:106-108 and crates/cli/src/explain.rs:958), so the schema rejected every real NestJS / SvelteKit setup output under ajv strict validation. The Rust enum had `rename_all = "snake_case"` without explicit per-variant renames for NestJs / SvelteKit; NextJs had a per-variant rename that worked correctly, masking the gap. Root cause was twofold: - `CoverageSetupFramework` (and its sibling helper enums) are NOT in `derived_definition_names()`, so `merge_with_committed` treats them as transitively-referenced helpers handled by the second loop. - That second loop carried a `if definitions.contains_key(name) { continue; }` guard that silently preserved the committed schema's stale helper definitions on every regen. Any change to a serde rename / schemars attribute on a helper was invisible until the helper was deleted by hand from `docs/output-schema.json`. Fix: invert the guard so derived helpers always overwrite the committed entry, with the `derived_definition_names()` in-scope set skipped because those are processed by the first loop with augmentation. After Phase 8 every helper in `docs/output-schema.json` is a derived artifact, so the "preserve hand-authored helpers" rationale no longer applies. Added `#[serde(rename = "nestjs")]` to `NestJs` and `#[serde(rename = "sveltekit")]` to `SvelteKit` to match the wire and the established `NextJs` pattern. 2. LOW: stale comments in `crates/cli/src/bin/schema_emit.rs`. The `finding_definition_names()` docstring still said "requiredness is decided by the committed schema and the augmentation is non-opinionated", but the augmentation now unconditionally pushes `actions` into required. The `committed_definitions_match_derived_property_keys` test still described `actions_meta` as injected via post-pass on `serde_json::Value` rather than modeled on the typed envelope, but Phase 8 typed it as `Option<HealthActionsMeta>` on `HealthReport`. Both rewritten to reflect current behaviour. Verified: - Strict drift gate still passes (7 schema tests). - `cargo test --workspace --all-targets` green. - `cargo clippy --workspace --all-targets -- -D warnings` clean. - `pnpm run check:codegen` clean (TS contracts regenerated). - `CoverageSetupFramework` definition now emits `nextjs` / `nestjs` / `nuxt` / `sveltekit` / `astro` / `remix` / `vite` / `plain_node` / `unknown`, matching the runtime and `_meta.enums`.
a82e072 to
edc8933
Compare
BartWaardenburg
added a commit
that referenced
this pull request
May 16, 2026
…/ SvelteKit Two issues caught by parallel review on PR #380: 1. BLOCK: CoverageSetupFramework variants NestJs / SvelteKit landed as `nest_js` / `svelte_kit` in the regenerated schema (and downstream TS contracts). The runtime emits `nestjs` / `sveltekit` (per crates/cli/src/coverage/mod.rs:106-108 and crates/cli/src/explain.rs:958), so the schema rejected every real NestJS / SvelteKit setup output under ajv strict validation. The Rust enum had `rename_all = "snake_case"` without explicit per-variant renames for NestJs / SvelteKit; NextJs had a per-variant rename that worked correctly, masking the gap. Root cause was twofold: - `CoverageSetupFramework` (and its sibling helper enums) are NOT in `derived_definition_names()`, so `merge_with_committed` treats them as transitively-referenced helpers handled by the second loop. - That second loop carried a `if definitions.contains_key(name) { continue; }` guard that silently preserved the committed schema's stale helper definitions on every regen. Any change to a serde rename / schemars attribute on a helper was invisible until the helper was deleted by hand from `docs/output-schema.json`. Fix: invert the guard so derived helpers always overwrite the committed entry, with the `derived_definition_names()` in-scope set skipped because those are processed by the first loop with augmentation. After Phase 8 every helper in `docs/output-schema.json` is a derived artifact, so the "preserve hand-authored helpers" rationale no longer applies. Added `#[serde(rename = "nestjs")]` to `NestJs` and `#[serde(rename = "sveltekit")]` to `SvelteKit` to match the wire and the established `NextJs` pattern. 2. LOW: stale comments in `crates/cli/src/bin/schema_emit.rs`. The `finding_definition_names()` docstring still said "requiredness is decided by the committed schema and the augmentation is non-opinionated", but the augmentation now unconditionally pushes `actions` into required. The `committed_definitions_match_derived_property_keys` test still described `actions_meta` as injected via post-pass on `serde_json::Value` rather than modeled on the typed envelope, but Phase 8 typed it as `Option<HealthActionsMeta>` on `HealthReport`. Both rewritten to reflect current behaviour. Verified: - Strict drift gate still passes (7 schema tests). - `cargo test --workspace --all-targets` green. - `cargo clippy --workspace --all-targets -- -D warnings` clean. - `pnpm run check:codegen` clean (TS contracts regenerated). - `CoverageSetupFramework` definition now emits `nextjs` / `nestjs` / `nuxt` / `sveltekit` / `astro` / `remix` / `vite` / `plain_node` / `unknown`, matching the runtime and `_meta.enums`.
edc8933 to
8648df6
Compare
BartWaardenburg
added a commit
that referenced
this pull request
May 16, 2026
…/ SvelteKit Two issues caught by parallel review on PR #380: 1. BLOCK: CoverageSetupFramework variants NestJs / SvelteKit landed as `nest_js` / `svelte_kit` in the regenerated schema (and downstream TS contracts). The runtime emits `nestjs` / `sveltekit` (per crates/cli/src/coverage/mod.rs:106-108 and crates/cli/src/explain.rs:958), so the schema rejected every real NestJS / SvelteKit setup output under ajv strict validation. The Rust enum had `rename_all = "snake_case"` without explicit per-variant renames for NestJs / SvelteKit; NextJs had a per-variant rename that worked correctly, masking the gap. Root cause was twofold: - `CoverageSetupFramework` (and its sibling helper enums) are NOT in `derived_definition_names()`, so `merge_with_committed` treats them as transitively-referenced helpers handled by the second loop. - That second loop carried a `if definitions.contains_key(name) { continue; }` guard that silently preserved the committed schema's stale helper definitions on every regen. Any change to a serde rename / schemars attribute on a helper was invisible until the helper was deleted by hand from `docs/output-schema.json`. Fix: invert the guard so derived helpers always overwrite the committed entry, with the `derived_definition_names()` in-scope set skipped because those are processed by the first loop with augmentation. After Phase 8 every helper in `docs/output-schema.json` is a derived artifact, so the "preserve hand-authored helpers" rationale no longer applies. Added `#[serde(rename = "nestjs")]` to `NestJs` and `#[serde(rename = "sveltekit")]` to `SvelteKit` to match the wire and the established `NextJs` pattern. 2. LOW: stale comments in `crates/cli/src/bin/schema_emit.rs`. The `finding_definition_names()` docstring still said "requiredness is decided by the committed schema and the augmentation is non-opinionated", but the augmentation now unconditionally pushes `actions` into required. The `committed_definitions_match_derived_property_keys` test still described `actions_meta` as injected via post-pass on `serde_json::Value` rather than modeled on the typed envelope, but Phase 8 typed it as `Option<HealthActionsMeta>` on `HealthReport`. Both rewritten to reflect current behaviour. Verified: - Strict drift gate still passes (7 schema tests). - `cargo test --workspace --all-targets` green. - `cargo clippy --workspace --all-targets -- -D warnings` clean. - `pnpm run check:codegen` clean (TS contracts regenerated). - `CoverageSetupFramework` definition now emits `nextjs` / `nestjs` / `nuxt` / `sveltekit` / `astro` / `remix` / `vite` / `plain_node` / `unknown`, matching the runtime and `_meta.enums`.
8648df6 to
766addf
Compare
Phase 8 of issue #338. The strict structural drift gate is no longer `#[ignore]`d: every type in `derived_definition_names()` is regenerated from Rust, with descriptions sourced from `///` doc comments and per-envelope titles from `#[schemars(title = "...")]`. Editing the committed schema by hand on any in-scope definition now fails the default `cargo test` invocation. What landed: - Strict gate flipped on at `crates/cli/src/bin/schema_emit.rs::drift_tests::committed_definitions_match_derived_structurally`. - Augmentation fix: `augment_finding_definition` now pushes "actions" into the per-finding `required` array, matching the wire (which always emits the array, possibly empty). - Production `normalize_schema` mirrors the test-side strip: drops schemars cosmetic output (`default`, `examples`, `format`, `minimum`/`maximum`/`exclusive*`) and collapses single-arm `allOf` ref wrappers so the regenerated document stays clean. - Each envelope in `crates/cli/src/output_envelope.rs` carries `#[schemars(title = "fallow <command> --format json")]` so the Mintlify docs renderer keeps its section headings. - `HealthActionsMeta` is a typed struct under `crates/cli/src/health_types/` flowing through `HealthReport.actions_meta` and `HealthGroup.actions_meta`. The previous "actions_meta" AUGMENTATION_KEYS escape hatch is retired; the runtime still injects the breadcrumb post-pass on the `serde_json::Value` tree because the suppression context lives inside the report builder, but the schema now documents the field. - The latent invalid `CoverageSetupOutput.package_manager` shape in the committed schema (`type: "string", enum: [null, ...]`, rejected by ajv strict) is replaced by the proper `anyOf: [{$ref}, {type: null}]` form via the regen. - `docs/output-schema.json` is regenerated from Rust as the source of truth. - `CONTRIBUTING.md` updated to reflect the closed escape hatch. - VS Code + npm typed contract files (`output-contract.d.ts`) regenerated via `pnpm run codegen:types`. What stays hand-maintained: - Top-level metadata (`$schema`, `title`, `description`, `oneOf`), preserved verbatim by `merge_with_committed`. - Two non-strict drift tests (`committed_property_refs_match_derived_property_refs` covering $ref-target drift, plus `committed_definitions_match_derived_property_keys` covering property-key + required drift). They complement the strict gate rather than duplicating it.
…/ SvelteKit Two issues caught by parallel review on PR #380: 1. BLOCK: CoverageSetupFramework variants NestJs / SvelteKit landed as `nest_js` / `svelte_kit` in the regenerated schema (and downstream TS contracts). The runtime emits `nestjs` / `sveltekit` (per crates/cli/src/coverage/mod.rs:106-108 and crates/cli/src/explain.rs:958), so the schema rejected every real NestJS / SvelteKit setup output under ajv strict validation. The Rust enum had `rename_all = "snake_case"` without explicit per-variant renames for NestJs / SvelteKit; NextJs had a per-variant rename that worked correctly, masking the gap. Root cause was twofold: - `CoverageSetupFramework` (and its sibling helper enums) are NOT in `derived_definition_names()`, so `merge_with_committed` treats them as transitively-referenced helpers handled by the second loop. - That second loop carried a `if definitions.contains_key(name) { continue; }` guard that silently preserved the committed schema's stale helper definitions on every regen. Any change to a serde rename / schemars attribute on a helper was invisible until the helper was deleted by hand from `docs/output-schema.json`. Fix: invert the guard so derived helpers always overwrite the committed entry, with the `derived_definition_names()` in-scope set skipped because those are processed by the first loop with augmentation. After Phase 8 every helper in `docs/output-schema.json` is a derived artifact, so the "preserve hand-authored helpers" rationale no longer applies. Added `#[serde(rename = "nestjs")]` to `NestJs` and `#[serde(rename = "sveltekit")]` to `SvelteKit` to match the wire and the established `NextJs` pattern. 2. LOW: stale comments in `crates/cli/src/bin/schema_emit.rs`. The `finding_definition_names()` docstring still said "requiredness is decided by the committed schema and the augmentation is non-opinionated", but the augmentation now unconditionally pushes `actions` into required. The `committed_definitions_match_derived_property_keys` test still described `actions_meta` as injected via post-pass on `serde_json::Value` rather than modeled on the typed envelope, but Phase 8 typed it as `Option<HealthActionsMeta>` on `HealthReport`. Both rewritten to reflect current behaviour. Verified: - Strict drift gate still passes (7 schema tests). - `cargo test --workspace --all-targets` green. - `cargo clippy --workspace --all-targets -- -D warnings` clean. - `pnpm run check:codegen` clean (TS contracts regenerated). - `CoverageSetupFramework` definition now emits `nextjs` / `nestjs` / `nuxt` / `sveltekit` / `astro` / `remix` / `vite` / `plain_node` / `unknown`, matching the runtime and `_meta.enums`.
The Phase 8 merge-logic fix (commit c9c4df0) made `merge_with_committed` always overwrite transitive helpers from the derived schema, which fixed the NestJs / SvelteKit rename gap but also revealed that two helper fields had richer prose in the previously-committed schema than in their Rust `///` doc comments. Affected: - `DuplicationStats.clone_groups`: lost "Matches `clone_groups[].length` post `minOccurrences` filtering; the count of groups hidden by the filter is exposed in `clone_groups_below_min_occurrences`." - `DuplicationStats.clone_instances`: lost "Matches the sum of `clone_groups[].locations[].length` post `minOccurrences` filtering." Both prose blocks describe the relationship between the count fields and the `minOccurrences` filter (the same one that gates the new `clone_groups_below_min_occurrences` field). Without them, JSON consumers reading the schema lose the context that the count fields reflect POST-filter totals, not raw corpus totals. Restored by enriching the `///` doc comments in `crates/core/src/duplicates/types.rs` to match the prior committed schema text. The regen now emits the full prose; tests + clippy + fmt clean. The Phase 8 regen surfaced ~130 other prose regressions on in-scope types (HealthScore.grade lost the score-banding, HealthFinding.severity lost the threshold defaults, etc.). They are pre-existing in `ed07ef6c` (the Phase 8 commit) and tracked as a follow-up.
The original Phase 8 regen (commit `ed07ef6c`) replaced the
previously-published schema's hand-authored descriptions with the
matching Rust `///` doc comments, which were systematically terser. The
loss surfaced once `merge_with_committed` started overwriting transitive
helpers (commit `c9c4df08`); 141 field and top-level descriptions across
42 definitions read materially less than the version on `origin/main`:
- `HealthScore.grade`: lost the score banding (`A: score >= 85, B:
70-84, C: 55-69, D: 40-54, F: below 40`)
- `HealthScore.score`: lost the reproducibility note (`100 -
sum(penalties) == score`)
- `HealthFinding.severity`: lost the threshold defaults (`cognitive
25/40, cyclomatic 30/50`)
- `HealthFindingAction.type`: lost the multi-action / action-selection
prose explaining when each action variant fires
- `AuditOutput.attribution`: lost the `audit.gate` interaction note
- `CheckOutput.unused_catalog_entries`: lost the catalog-spec prose
- `RuntimeCoverageReport`: lost descriptions on 10 / 13 fields
- `HealthScorePenalties`: lost descriptions on 10 / 11 fields
- `RuntimeCoverageSummary`: lost descriptions on 10 / 12 fields
- ... plus 130+ more terser fields
Restored by enriching the `///` doc comments in the source structs to
match the previously-published prose verbatim, then regenerating
`docs/output-schema.json` plus the npm + VS Code typed contracts. The
augmented `schema_version` description on `RuntimeCoverageReport` (which
lives in `schema_emit.rs::augment_runtime_coverage_report` rather than
on a typed field) was also re-extended.
Files touched:
- `crates/types/src/envelope.rs`, `crates/types/src/output_health.rs`,
`crates/types/src/results.rs`
- `crates/core/src/duplicates/types.rs`
- `crates/cli/src/health_types/{mod,scores,coverage,trends,vital_signs,
targets,runtime_coverage,grouped}.rs`
- `crates/cli/src/output_envelope.rs`
- `crates/cli/src/bin/schema_emit.rs` (augmented schema_version
description text)
- `docs/output-schema.json`, `editors/vscode/src/generated/
output-contract.d.ts`, `npm/fallow/types/output-contract.d.ts`
(regenerated)
After this commit, the OLD `origin/main` schema and the regenerated
schema agree on prose: zero field descriptions differ by more than 30
characters, and the structural alignment from commits `ed07ef6c`,
`c9c4df08`, `f9ccdca4` stays in place.
Verified:
- `cargo test --workspace --all-targets` green.
- `cargo clippy --workspace --all-targets -- -D warnings` clean.
- `cargo fmt --all -- --check` clean.
- `pnpm run check:codegen` clean.
- Programmatic comparison of every field description vs `origin/main`
shows zero remaining > 30-char regressions.
Phase 8 of issue #338 closed the prose-and-shape escape hatch, flipped the strict structural drift gate out of `#[ignore]`, fixed the augmentation to add `actions` to `required`, modeled `actions_meta` as a typed `Option<HealthActionsMeta>`, taught the production normalizer to strip schemars cosmetic output, preserved envelope titles via `#[schemars(title)]`, fixed the merge-logic gap that silently froze transitive helpers across regens (which surfaced a `nest_js` / `svelte_kit` rename mismatch on `CoverageSetupFramework`), corrected the latent `package_manager` invalid-enum shape, and restored 141 prose descriptions across 42 definitions that the initial regen had reduced to terser `///` text. Adds a second bullet under `[Unreleased] / Internal` covering Phase 8's work as a follow-up to the existing Phase 5 envelope-derive entry. Both bullets reference #338. The first bullet describes what Phase 5 shipped (the migration path); the second describes what Phase 8 shipped (closing the gate + the cleanup it forced). Refs #338.
The Phase 8 stack rebased onto Phase 5's tip (which absorbed v2.75.0 from main) needs one more schema + TS contract regeneration so the committed artifacts reflect the merged Rust source. Refs #338.
766addf to
2f6666e
Compare
The prose-restoration commit pulled `<name>`, `<hash>`, `<anonymous>`, `<template>` literally into `///` doc comments, which rustdoc strict mode parses as unclosed HTML tags. The Documentation CI job runs with `RUSTDOCFLAGS=-D warnings`, so the warnings became errors. Wrap each placeholder in backticks so the markdown renderer treats the text as inline code instead of an HTML opening tag. The schema-emit binary regenerates descriptions verbatim from the `///` text, so the JSON-schema output and TypeScript contracts regenerate automatically. Five sites: - `crates/types/src/results.rs:93` — `<name>` in `UnresolvedCatalogReference.catalog:<name>` doc - `crates/cli/src/health_types/runtime_coverage.rs:319` — `<hash>` in `RuntimeCoverageFinding.id` doc - `crates/cli/src/health_types/scores.rs:208-209` — `<anonymous>` and `<template>` in `HealthFinding.name` doc - `crates/cli/src/health_types/scores.rs:402` — `<anonymous>` in `LargeFunctionEntry.name` doc Refs #338.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 8 of issue #338. The strict structural drift gate is no longer
#[ignore]d: every type inderived_definition_names()is regenerated from Rust, with descriptions sourced from///doc comments and per-envelope titles from#[schemars(title = "...")]. Editing the committed schema by hand on any in-scope definition now fails the defaultcargo testinvocation.Base branch is
feat/issue-338-phase5-envelopes(stacked PR). Phase 5 (10 commits deriving envelope structs from Rust) is the prerequisite; this PR's diff is only the 1 commit closing the gate on top. Merge Phase 5 first, then rebase this onto main.What landed
crates/cli/src/bin/schema_emit.rs::drift_tests::committed_definitions_match_derived_structurally.augment_finding_definitionnow pushes"actions"into the per-findingrequiredarray, matching the wire (which always emits the array, possibly empty).normalize_schemamirrors the test-side strip: drops schemars cosmetic output (default,examples,format,minimum/maximum/exclusive*) and collapses single-armallOfref wrappers so the regenerated document stays clean.crates/cli/src/output_envelope.rscarries#[schemars(title = "fallow <command> --format json")]so the Mintlify docs renderer keeps its section headings.HealthActionsMetais a typed struct undercrates/cli/src/health_types/flowing throughHealthReport.actions_metaandHealthGroup.actions_meta. The previousactions_metaAUGMENTATION_KEYSescape hatch is retired; the runtime still injects the breadcrumb post-pass on theserde_json::Valuetree because the suppression context lives inside the report builder, but the schema now documents the field.CoverageSetupOutput.package_managershape in the committed schema (type: "string", enum: [null, ...], rejected by ajv strict) is replaced by the properanyOf: [{$ref}, {type: null}]form via the regen.docs/output-schema.jsonregenerated from Rust as the source of truth.CONTRIBUTING.mdupdated to reflect the closed escape hatch.output-contract.d.ts) regenerated viapnpm run codegen:types.What stays hand-maintained
$schema,title,description,oneOf), preserved verbatim bymerge_with_committed.committed_property_refs_match_derived_property_refscovering$ref-target drift, pluscommitted_definitions_match_derived_property_keyscovering property-key + required drift). They complement the strict gate rather than duplicating it.Wire compatibility
SCHEMA_VERSIONstays at 6. The wire shape is unchanged:actions_metaalready appeared on the wire via post-pass injection,actionsalready appeared as an array on every finding, and the four flaggedOption<T>fields (ReviewReconcileOutput.target,CoverageSetupOutput.package_manager,.dockerfile_snippet,.config_written) already emitted asnullrather than absent. Phase 8 only changes the schema document's encoding (inlined enums become$refs to registered definitions, descriptions flow from///); JSON instances validate identically against both forms.Test plan
cargo test --workspace --all-targets(all 7 schema drift tests including the previously-#[ignore]d strict gate)cargo clippy --workspace --all-targets -- -D warningscargo fmt --all -- --checkpnpm run check:codegen(TypeScript contracts in lock-step with regenerated schema)bash action/tests/run.sh(200 jq tests)bash ci/tests/run.sh(205 jq tests)Refs #338.