/* Canonical remediation catalog mapping ruleId to structured remediation patterns. Consumed by diagnosticsResult() for auto-population and by remediation.hint.validate for coverage checking (RFC-1027). Does not own the Diagnostic schema — that lives in werkstatt-engine schemas. Does not aggregate remediation hints into KernelExecutionReport — that is the engine's job. ADR-0105: remediation entries for the DIST-LEAK-01..05 rule family (serialization-leak guard). RFC-1201: remediation entry for PARITY-MD-CONSTRUCT-COUNT (inline-construct parity). RFC-1209: remediation entries for the RB-01..06 resource-budget rule family. RFC-1209: site resource budgets and public transparency surface (RFC-1209) RFC-1210: closed-loop signal ingest to bounded missions (RFC-1210) RFC-1027, RFC-1185, warpgogol-m000196 */ export interface RemediationPattern { ruleId: string; action: string; template?: string; docRef?: string; targetFiles?: string[]; } const REMEDIATION_ENTRIES: RemediationPattern[] = [ { ruleId: "SEO-RUNTIME.CANONICAL-MISMATCH", action: "Ensure the canonical URL in the rendered HTML matches the production domain without language prefix for the default locale.", docRef: "docs/authoring/site-composition.md", targetFiles: ["src/layouts/**/*.astro"], }, { ruleId: "WORKSPACE.SURFACE.VALIDATE", action: "Fix surface validation errors by checking the surface block declarations against the schema.", docRef: "docs/authoring/site-composition.md", }, { ruleId: "TEST.SIGNAL.POLICY.VALIDATE", action: "Align test signal declarations with the policy schema — check signal name, severity, and evidence path.", docRef: "docs/agents/domain.md", }, { ruleId: "PUBLIC.ICONS.VALIDATE", action: "Replace invalid icon references with valid SurfaceLabels entries or remove the icon field.", docRef: "docs/authoring/site-composition.md", }, { ruleId: "PARITY-SECTION-COUNT", action: "Add or remove sections so the locale overlay matches the base locale section count.", docRef: "docs/authoring/preventive-measures-parity-and-templates.md", }, { ruleId: "PARITY-MD-CONSTRUCT-COUNT", action: "Align inline markdown constructs (code spans, links, images, footnote references) between the localized block and its counterpart locale, or record an intentional difference via translation.parity.suppress.", docRef: "docs/authoring/preventive-measures-parity-and-templates.md", }, { ruleId: "GEN-FILES-01", action: "Regenerate generated files by running the owning kernel command, then commit the updated output.", docRef: "docs/authoring/generated-files-and-templates.md", }, { ruleId: "RAUT-01", action: "Fix the remediation block in system-state.yaml to match the autonomy schema (autonomy: off|bounded, signalSources: string[]).", docRef: "docs/rfcs/rfc-1210-closed-loop-runtime-remediation-channel-from-telemetry-signals-to-bounded-missions.md", }, { ruleId: "RAUT-02", action: "Repair the remediationClasses catalog — every autoFixable entry must name a registered fixCommand; the catalog is closed, fix the entry or drop autoFixable.", docRef: "docs/rfcs/rfc-1210-closed-loop-runtime-remediation-channel-from-telemetry-signals-to-bounded-missions.md", }, { ruleId: "RAUT-03", action: "Declare at least one signalSources invoker in system-state.yaml for bounded autonomy, or set remediation.autonomy: off.", docRef: "docs/rfcs/rfc-1210-closed-loop-runtime-remediation-channel-from-telemetry-signals-to-bounded-missions.md", }, { ruleId: "DEPS-GEN-01", action: "Run pnpm exec werkstatt run deps.peer.check to regenerate the peer dependency manifest.", docRef: "docs/authoring/generated-files-and-templates.md", }, { ruleId: "AGC-01", action: "Fix the agent gate configuration — ensure the gate metadata matches the declared gate catalog.", docRef: "docs/agents/domain.md", }, { ruleId: "WORKPIECE-IMPORTS-01", action: "Resolve the broken import in the workpiece — check the module path and ensure the package is installed.", }, { ruleId: "SNAP-01", action: "Regenerate the behavior snapshot by running pnpm exec werkstatt run behavior.snapshot.generate.", }, { ruleId: "CREG-04", action: "Fix the content regression — review the content diff and update the review.yaml before closing the mission.", docRef: "docs/authoring/site-composition.md", }, { ruleId: "CREG-03", action: "Fix the content regression — ensure all locale overlays are consistent with the base content.", docRef: "docs/authoring/preventive-measures-parity-and-templates.md", }, { ruleId: "CREG-01", action: "Fix the content regression — the base content was changed without a review.yaml. Run content.regression.review.generate.", docRef: "docs/authoring/site-composition.md", }, { ruleId: "BRK-04", action: "Fix the bordbuch entry — ensure the hash chain is intact and the entry is properly signed.", }, { ruleId: "PROPS-01", action: "Fix the content props schema violation — check the frontmatter against the schema declaration.", }, { ruleId: "MAINTENANCE.DEBT.BASELINE.VALIDATE", action: "Regenerate the maintenance debt baseline by running pnpm exec werkstatt run maintenance.debt.baseline.generate.", }, { ruleId: "HDR-04", action: "Fix the header configuration — ensure the header block matches the surface schema.", docRef: "docs/authoring/site-composition.md", }, { ruleId: "HDR-02", action: "Fix the header navigation — ensure all nav items have valid href and label.", docRef: "docs/authoring/site-composition.md", }, { ruleId: "HDR-01", action: "Fix the header structure — ensure the header block is declared in the surface composition.", docRef: "docs/authoring/site-composition.md", }, { ruleId: "GEN-EDIT-01", action: "Do not hand-edit generated files. Modify the source template and regenerate.", docRef: "docs/authoring/generated-files-and-templates.md", }, { ruleId: "DEPS-PEER-01", action: "Add the missing peer dependency to the package.json or remove the import that requires it.", }, { ruleId: "CW-EVID-01", action: "Fix the changelog evidence — ensure the evidence file exists and is referenced correctly.", }, { ruleId: "CMD-MAN-03", action: "Regenerate the command manifest by running pnpm exec werkstatt run command.manifest.generate.", }, { ruleId: "CI-LOCAL-05", action: "Fix the CI configuration — ensure the local CI workflow matches the pipeline definitions.", }, { ruleId: "AGS-05", action: "Fix the agent gate search configuration — ensure the search manifest is generated and accessible.", docRef: "docs/agents/domain.md", }, { ruleId: "AGS-02", action: "Fix the agent gate search schema — ensure the search chunk text is within the max length.", docRef: "docs/agents/domain.md", }, { ruleId: "AGO-01", action: "Fix the agent gate output — ensure the gate output matches the declared schema.", docRef: "docs/agents/domain.md", }, { ruleId: "AGK-03", action: "Fix the agent gate key — ensure the gate key is unique and matches the declared catalog.", docRef: "docs/agents/domain.md", }, { ruleId: "WS-WRITE-02", action: "Fix the workspace write — ensure the write intent is declared and the path is within the workspace root.", }, { ruleId: "SUPPRESS-VAL-04", action: "Fix the suppression validation — ensure the suppression rule matches the declared schema.", docRef: "docs/authoring/guide-suppression-matching.md", }, { ruleId: "ENV-CONTRACT-02", action: "Fix the environment contract — ensure the env variable is declared in .env.example and matches the contract.", }, { ruleId: "ENV-CONTRACT-04", action: "Fix the environment contract — ensure the env variable type matches the declared schema.", }, { ruleId: "ENV-CONTRACT-05", action: "Fix the environment contract — ensure the env variable is documented in the .env.example file.", }, { ruleId: "DEPLOY-SCRIPTS-03", action: "Fix the deploy script — ensure the script is executable and matches the deployment pipeline.", }, { ruleId: "FLEET-05", action: "Fix the fleet configuration — ensure the fleet entry matches the declared schema.", }, { ruleId: "TYPO-NUM-01", action: "Replace English number format (1,234.56) with German format (1.234,56) in German text.", docRef: "docs/rfcs/rfc-1070-extend-typography-validate-with-tier-2-locale-rules-for-numbers-abbreviations-and-apostrophes.md", targetFiles: ["src/content/**/*.md"], }, { ruleId: "TYPO-NUM-02", action: "Replace dot-thousands format (1.234,56) with Ukrainian format using NNBSP (1\u202F234,56) in Ukrainian text.", docRef: "docs/rfcs/rfc-1070-extend-typography-validate-with-tier-2-locale-rules-for-numbers-abbreviations-and-apostrophes.md", targetFiles: ["src/content/**/*.md"], }, { ruleId: "TYPO-NUM-03", action: "Replace regular space thousands separator with NNBSP (U+202F) in Ukrainian numbers.", docRef: "docs/rfcs/rfc-1070-extend-typography-validate-with-tier-2-locale-rules-for-numbers-abbreviations-and-apostrophes.md", targetFiles: ["src/content/**/*.md"], }, { ruleId: "TYPO-ABBR-01", action: "Add the required trailing period to the abbreviation (e.g. Nr → Nr., usw → usw.).", docRef: "docs/rfcs/rfc-1070-extend-typography-validate-with-tier-2-locale-rules-for-numbers-abbreviations-and-apostrophes.md", targetFiles: ["src/content/**/*.md"], }, { ruleId: "TYPO-ABBR-02", action: "Add the required internal space in German multi-part abbreviations (e.g. z.B. → z. B., u.a. → u. a.).", docRef: "docs/rfcs/rfc-1070-extend-typography-validate-with-tier-2-locale-rules-for-numbers-abbreviations-and-apostrophes.md", targetFiles: ["src/content/**/*.md"], }, { ruleId: "TYPO-APOS-01", action: "Replace curly apostrophe (U+2019) with straight apostrophe (') in Ukrainian text.", docRef: "docs/rfcs/rfc-1070-extend-typography-validate-with-tier-2-locale-rules-for-numbers-abbreviations-and-apostrophes.md", targetFiles: ["src/content/**/*.md"], }, { ruleId: "TYPO-APOS-02", action: "Replace modifier letter apostrophe (U+02BC) with straight apostrophe (') in Ukrainian text.", docRef: "docs/rfcs/rfc-1070-extend-typography-validate-with-tier-2-locale-rules-for-numbers-abbreviations-and-apostrophes.md", targetFiles: ["src/content/**/*.md"], }, { ruleId: "TYPO-UNICODE-01", action: "Remove zero-width characters (U+200B, U+200C, U+200D, U+FEFF) from the source text.", docRef: "docs/rfcs/rfc-1071-extend-typography-validate-with-tier-3-advisory-rules-for-unicode-hygiene-link-text-and-sentence-length.md", targetFiles: ["src/content/**/*.md"], }, { ruleId: "TYPO-UNICODE-02", action: "Remove soft hyphen (U+00AD) from the source text — it is invisible in most editors but affects rendering.", docRef: "docs/rfcs/rfc-1071-extend-typography-validate-with-tier-3-advisory-rules-for-unicode-hygiene-link-text-and-sentence-length.md", targetFiles: ["src/content/**/*.md"], }, { ruleId: "TYPO-LINK-01", action: "Replace bare URL link text with descriptive link text (e.g. [Learn more](url) instead of [https://example.com](url)).", docRef: "docs/rfcs/rfc-1071-extend-typography-validate-with-tier-3-advisory-rules-for-unicode-hygiene-link-text-and-sentence-length.md", targetFiles: ["src/content/**/*.md"], }, { ruleId: "TYPO-LINK-02", action: "Replace generic link text (click here, hier klicken, тут, here, hier) with a descriptive phrase that indicates the link target.", docRef: "docs/rfcs/rfc-1071-extend-typography-validate-with-tier-3-advisory-rules-for-unicode-hygiene-link-text-and-sentence-length.md", targetFiles: ["src/content/**/*.md"], }, { ruleId: "TYPO-SENT-01", action: "Split the long sentence (more than 40 words) into shorter sentences for readability.", docRef: "docs/rfcs/rfc-1071-extend-typography-validate-with-tier-3-advisory-rules-for-unicode-hygiene-link-text-and-sentence-length.md", targetFiles: ["src/content/**/*.md"], }, { ruleId: "SHARED-CONTEXT-COLLISION-UNDECLARED", action: "Declare `inherit: ` on the consuming block to subscribe to the source block's authored props, or `inherit: false` to opt out of the collision group. Run `shared.context.migrate` inside a mission to materialize edges automatically.", docRef: "docs/authoring/site-composition.md", targetFiles: ["src/content/pages/**/*.md"], }, { ruleId: "SHARED-CONTEXT-INHERIT-TARGET-MISSING", action: "Point `inherit` at a pageId declared in system.md pages[] whose same-language entry has a block with the same id+type — or remove the edge.", docRef: "docs/authoring/site-composition.md", targetFiles: ["src/content/pages/**/*.md"], }, { ruleId: "SHARED-CONTEXT-INHERIT-SELF", action: "Remove the `inherit` edge — a block cannot inherit from its own page; authored props already apply.", docRef: "docs/authoring/site-composition.md", targetFiles: ["src/content/pages/**/*.md"], }, { ruleId: "SHARED-CONTEXT-INHERIT-LANG-MISSING", action: "Create the named page's content entry for this language, or remove the inherit edge from this language's file — otherwise default-language props would silently leak into the translated page.", docRef: "docs/authoring/site-composition.md", targetFiles: ["src/content/pages/**/*.md"], }, { ruleId: "SHARED-CONTEXT-REQUIRED-PAGE-MISSING", action: "Add the pageId to system.md pages[] and create its content entry, or remove it from sharedContext.requiredPageIds.", docRef: "docs/authoring/site-composition.md", targetFiles: ["src/content/system.md", "src/content/pages/**/*.md"], }, { ruleId: "DIST-LEAK-01", action: "A non-serializable runtime value reached a string position in rendered output — check deep-walk helpers for plain-object guards (non-plain objects like Date must pass through).", docRef: "docs/adrs/adr-0105-deep-walks-preserve-non-plain-objects-and-dist-is-scanned-for-serialization-leaks.md", }, { ruleId: "DIST-LEAK-02", action: "An unparseable or corrupted date reached the page — normalize date-bearing values via toIsoDateString (Date → toISOString) before they reach components.", docRef: "docs/adrs/adr-0105-deep-walks-preserve-non-plain-objects-and-dist-is-scanned-for-serialization-leaks.md", }, { ruleId: "DIST-LEAK-03", action: "An attribute received undefined/null/NaN — guard the prop source and omit the attribute instead of serializing the sentinel.", docRef: "docs/adrs/adr-0105-deep-walks-preserve-non-plain-objects-and-dist-is-scanned-for-serialization-leaks.md", }, { ruleId: "DIST-LEAK-04", action: "A text node rendered a bare undefined/null/NaN — coerce or suppress the value before render.", docRef: "docs/adrs/adr-0105-deep-walks-preserve-non-plain-objects-and-dist-is-scanned-for-serialization-leaks.md", }, { ruleId: "DIST-LEAK-05", action: "A dist file could not be read and was skipped by the scan — fix permissions/encoding; a skipped file escapes a fail-closed guard.", }, { ruleId: "RB-01", action: "Route exceeds the pageWeightKb budget — shrink media/markup on the route or declare a routeOverrides entry for it in src/content/system.md.", docRef: "docs/rfcs/rfc-1209-site-resource-budgets-and-public-energy-transparency-surface.md", targetFiles: ["src/content/system.md"], }, { ruleId: "RB-02", action: "Route exceeds the maxJsKb budget — remove or slim scripts (including inline