arkgate 3.7.0 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGELOG.md +76 -1145
  2. package/README.md +59 -19
  3. package/bin/ark-check-runtime.mjs +1598 -0
  4. package/bin/ark-check.mjs +32 -1565
  5. package/bin/ark-mcp-runtime.mjs +1976 -0
  6. package/bin/ark-mcp.mjs +84 -1495
  7. package/bin/ark-shared.mjs +34 -38
  8. package/bin/ark.mjs +33 -66
  9. package/bin/lib/adapter-contract.mjs +161 -9
  10. package/bin/lib/agent-gates.mjs +1 -0
  11. package/bin/lib/analysis-completeness.mjs +28 -0
  12. package/bin/lib/analysis-engine.mjs +8 -8
  13. package/bin/lib/analysis-policy.mjs +27 -0
  14. package/bin/lib/architecture-scan.mjs +70 -357
  15. package/bin/lib/auto-patch.mjs +76 -8
  16. package/bin/lib/ci-and-commands.mjs +1 -1
  17. package/bin/lib/codex-home.mjs +43 -16
  18. package/bin/lib/design-delta.mjs +4 -0
  19. package/bin/lib/doctor-advisories.mjs +4 -3
  20. package/bin/lib/doctor-plan.mjs +40 -41
  21. package/bin/lib/enforcement-state.mjs +2 -0
  22. package/bin/lib/github-enforcement.mjs +443 -0
  23. package/bin/lib/hook-templates.mjs +12 -148
  24. package/bin/lib/html-report-advisories.mjs +1 -1
  25. package/bin/lib/html-report-depth.mjs +9 -0
  26. package/bin/lib/html-report.mjs +5 -5
  27. package/bin/lib/install-migrate.mjs +83 -79
  28. package/bin/lib/managed-upgrade.mjs +622 -0
  29. package/bin/lib/mcp-adoption.mjs +3 -1
  30. package/bin/lib/parse-health.mjs +6 -5
  31. package/bin/lib/port-proof.mjs +2 -2
  32. package/bin/lib/prepare-change.mjs +68 -38
  33. package/bin/lib/prepare-write.mjs +7 -1
  34. package/bin/lib/resident-doctor-client.mjs +55 -0
  35. package/bin/lib/resident-hook.mjs +247 -0
  36. package/bin/lib/resolved-candidate-facts.mjs +1160 -0
  37. package/bin/lib/scan-files.mjs +19 -6
  38. package/bin/lib/snippet-analysis.mjs +119 -0
  39. package/bin/lib/source-policy.mjs +24 -0
  40. package/bin/lib/typescript-host.mjs +15 -18
  41. package/bin/lib/unavailable-analysis.mjs +76 -0
  42. package/bin/lib/upgrade-command.mjs +115 -0
  43. package/bin/lib/weakest-link.mjs +21 -179
  44. package/bin/lib/write-path-capabilities.mjs +167 -16
  45. package/bin/lib/write-path-detect.mjs +3 -2
  46. package/dist/eslint/index.cjs +3 -3
  47. package/dist/eslint/index.d.ts +3 -0
  48. package/dist/eslint/index.js +3 -3
  49. package/dist/index.cjs +7 -7
  50. package/dist/index.d.ts +1073 -141
  51. package/dist/index.js +7 -7
  52. package/docs/agent-guide.md +103 -59
  53. package/docs/ai-gates.md +97 -16
  54. package/docs/demos/01-write-gate-self-correction.md +2 -2
  55. package/docs/enthusiast/README.md +10 -10
  56. package/docs/enthusiast/how-to-gallery-starter.md +2 -2
  57. package/docs/enthusiast/reference-commands.md +18 -1
  58. package/docs/enthusiast/tutorial-first-project.md +2 -2
  59. package/docs/package-surface.md +98 -12
  60. package/docs/typescript-support.md +109 -37
  61. package/package.json +32 -4
  62. package/schemas/ark.analysis-result.schema.json +159 -2
  63. package/schemas/ark.design-delta.schema.json +1 -0
  64. package/schemas/ark.enforcement-state.schema.json +84 -0
  65. package/schemas/ark.resolved-candidate-facts.schema.json +1 -0
  66. package/server.json +2 -2
  67. package/templates/skills/ark-explore.md +5 -5
  68. package/templates/skills/ark-fix.md +1 -1
  69. package/templates/skills/ark-runtime.md +15 -8
  70. package/templates/skills/ark-upgrade.md +122 -182
  71. package/bin/lib/ai-velocity.mjs +0 -293
  72. package/bin/lib/graph-cycles.mjs +0 -6
  73. package/bin/lib/safety-diagnostics.mjs +0 -284
  74. package/bin/lib/ts-resolve.mjs +0 -228
  75. package/dist/configTypes-DAPvBqK6.d.cts +0 -61
  76. package/dist/eslint/index.d.cts +0 -146
  77. package/dist/index.d.cts +0 -986
@@ -17,46 +17,127 @@ hardening guide remains repository-hosted rather than duplicated in the gate tar
17
17
  | Surface | How you use it | Stability notes |
18
18
  |---------|----------------|-----------------|
19
19
  | **CLI** | `arkgate` / `arkgate-check` (aliases `ark` / `ark-check`) | Flags and human text may improve; **JSON output shapes** for `--json` (check, doctor, plan, coverage, recommend) are stable within a major. Additive fields OK; removals/renames are major. |
20
+ | **Programmatic gate API** | `import { analyzeProject, loadContract, createAICodeGate, ... } from 'arkgate'` | The root export is the static gate/config/analysis contract listed below. It intentionally contains no runtime-kernel implementation. |
20
21
  | **Doctor design fitness (P02+)** | `ark-check --doctor --json` → `doctor.designFitness`, `doctor.designSmells[]` | Additive. Stable smell `id`s: `io-under-application`, `handler-in-persistence`, `god-module`, `domain-logic-in-ui`, `facade-sql-in-routes`, `mixed-pattern-cluster`, `soft-contract`. Y02 extends `handler-in-persistence` to static ES imports/re-exports of framework HTTP surfaces (`next/server`), `defineRoute` calls, and existing handler bodies inside Persistence-role layers or specific persistence paths; `require()` and dynamic `import()` are outside this narrow advisory, and a generic `Infrastructure` role alone is not Persistence. Persistence candidates are filtered and sorted before the bounded content scan so large application prefixes cannot hide the advisory. The detector inspects the first 800 sorted Persistence candidates; later candidates are uninspected, so absence of this advisory is not whole-tree proof above that envelope. Each smell has `evidence[]`, `fix`, technical `message`, and plain-language **`outcome`** (Q02). Does **not** fail the gate by itself. |
21
22
  | **Post-green path (Q01)** | `doctor.postGreenPath`, `doctor.primaryNextAction`, `doctor.healthyFinishedForbidden` | Additive when `designFitness.designWeak`. Single Shape door (`id: clarify-for-ai`): explore shape-focus → dual-plan B → autopilot only with OK. Never empty plan A = healthy finished. |
22
23
  | **Golden pattern (Q03)** | Optional `.ark/golden-pattern.json`; doctor JSON `doctor.goldenPattern`; MCP `ark_place` / `ark_prepare_write` → `goldenPattern` | Additive, **advisory for NEW code only**. Required fields: `name`, `norm`; optional `newCodeHome`, `examplePath`, `schemaVersion`. **Absent is normal** (no claim). Never ENFORCE; never clears design-weak. Malformed → `invalid: true`, not silent guidance. |
23
24
  | **Plan pattern B (P03+)** | `ark-check --plan --json` → `plan.patternBets[]`, `plan.goal.designWeak` | Additive. Each bet: `id`, `smellId`, `pilot`, `evidence`, `successSignal`, `killSwitch`, **`neverMechanicalSafe: true`**, `class: "judgment"`. **Never** auto-applied by loop/autoPatch; not a `remediationKind` mechanical-safe. `goal.met` remains edge honesty only. |
24
25
  | **Pilot loop (Q04)** | `plan.pilotLoop` / `doctor.pilotLoop` | Additive. When design-weak: `active`, `oneAtATime`, `neverMechanicalSafe`, **`nextPilot`** extraction-card fields (`pilotTarget`, `smellId`, `move`, `successSignal`, `killSwitch`, `doNot[]`). **One pilot → re-doctor**; never multi-pilot batch; never mechanical-safe. |
25
- | **AI-velocity eval (Q05)** | `npm run eval:ai-velocity` → `eval/ai-velocity-report.json` | Fixture-measured (no live LLM). Same feature scenario on design-weak vs golden-path arms; metric **`placementTurns`** (agent-equivalent). Golden must be strictly better. Method string lives next to the number. Does not weaken the gate. |
26
+ | **AI-velocity eval (Q05)** | Repository-only evidence: `npm run eval:ai-velocity` → `eval/ai-velocity-report.json` | Fixture-measured (no live LLM). Same feature scenario on design-weak vs golden-path arms; metric **`placementTurns`** (agent-equivalent). Golden must be strictly better. Method string lives next to the number. Does not weaken the gate. |
26
27
  | **Contract health (W01)** | `ark-check --doctor --json` → `doctor.contractHealth`; optional `.ark/contract-smell-acks.json` | Additive, **advisory only** — meta-lint of the contract itself (layer-name heuristics; imprecision costs a warning line, never a verdict); never changes the verdict, `designFitness`, or `patternBets`. Stable smell ids: `contract-bidirectional-allow`, `contract-peripheral-depends-core`, `contract-lateral-adapter-allow`, `contract-dead-rule`; each smell has `severity`, `evidence[]` (sorted, honest `…(+N more)` truncation), `fix`, `message`, plain-language `outcome`, and `acknowledgedEdges` (acks applied to that id). **X03/X06**: the lateral smell does not fire on an adapter reaching its **own family's infra base** — the target reads `<Family><InfraWords…>` (**every** remaining target token an infra word: `Infra(structure)`/`Base`/`Core`/`Shared`/`Common`/`Kernel`/`Platform`/`Foundation`) and the source carries the family token **anywhere** in its name (X06, field: `HoursPersistenceAdapters -> PersistenceInfrastructure` — mid-name families). `PaymentsCoreAdapters` is still a sibling; cross-family edges, non-infra siblings, and the reverse (base → member) still fire. Acknowledgments live in the bounded sidecar (`{ acks: [{ id, edge, reason, reviewBy? }] }`, ≤64 KB / ≤200 entries; bidirectional edges order-insensitive, exact two segments); `contractHealth.acknowledged` counts **applied** acks only (stale acks count 0). **X02 ack lifecycle**: optional `reviewBy` (`YYYY-MM-DD`, strict round-trip validation — `2026-02-30` is malformed) — past the date the ack **stops applying** and the smell returns with `(ack expired …)` annotated evidence; among dated entries a fresh re-ack wins over a dead one, but once ANY dated ack exists for an edge the dated entries govern — a leftover undated duplicate cannot resurrect an expired exception. `detectContractSmells` defaults `today` to the real clock (pass `null` to disable expiry); `analyzeContractSmells` stays pure (clock injected). `contractHealth.ackLifecycle` reports `{ undated, malformed, expiredCount, expired[], staleCount, stale[] (lists capped at 12) }`; undated acks apply (backward compatible) but surface in doctor, report, and the fossilization note even when every smell is suppressed. **X05**: an ack matching **no detected edge** (orphaned by a fixed contract or quieted heuristic, unknown id, or typo'd edge) is `stale` — it suppresses nothing and doctor/report list the exact entries to fix or delete, even at zero visible smells. Malformed `reviewBy` never applies (fail-loud, like a sloppy edge); non-string `reviewBy` → whole file `invalid`. **Absent is normal**; malformed file or edge grammar → ignored + `ackFile.invalid` where applicable, never silent suppression. |
27
- | **Effect capabilities (U03/Y08)** | Analysis API `collectCapabilityUses(ts, sourceFile)` + Domain vocabulary (`CAPABILITY_IDS`, `capabilityForModuleSpecifier`, `capabilityForAmbientName`, `forbiddenGlobalForModuleSpecifier`, `lowerForbiddenGlobal`); pure-engine `ir.capabilityUses` | Additive within IR `1.0`. Seven **closed** ids: `network`, `filesystem`, `clock`, `randomness`, `environment`, `process`, `persistence` (ADR 0009). Direct evidence only — transitive inference never detects. The symbol-aware collector covers ambient globals (shadowing/type-only/globalThis-alias precision from the S05/C04 machinery) plus imports; the compiler-free IR engine carries **import-based** uses only (exact module or subpath match, never substring; textual `import type`/`export type` erasure — ANY braced named-binding list stays a value import there; template-literal bodies are skipped entirely (specifiers inside `${…}` are the symbol path's job); `require(…)` counts as capability evidence but never creates a graph edge on the pure path). **U04 walls are opt-in:** per-layer `capabilities: { deny: [...] }` or the dual-depth sugar `pure: true` (denies all seven); absence changes no verdict. `CAPABILITY_VIOLATION` is judgment-class (never mechanical-safe) with a port-injection `nextAction`; D7 dedup — evidence already owned by the layer's `forbiddenGlobals` reports only `FORBIDDEN_GLOBAL`. Y08 adds one deliberately narrow import dual: `forbiddenGlobals: ["process"]` owns exact value imports of `process` and `node:process`, but not subpaths or `child_process`; statement-level `import type` / `export type` remains erased on every path (the existing pure-IR all-named limitation above is unchanged). Atomic preflight blocks denied capabilities and that exact dual across a complete multi-file candidate (import-based on the pure path; other ambient evidence adds on the symbol-aware CLI/hook path). T01 policy-delta classifies the surface on **coverage atoms** (`ambient:<entry>` prefix-expanded, narrow `import-exact:<specifier>` duals, and `import:<capability>` for a complete wall): any lost atom is weakening (`fetch`→`XMLHttpRequest`, `Date`→`Date.now`, wall→fg all weaken; finding path `$.layers[name].capabilities`); fg → equivalent-or-stronger wall never needs an acknowledgment; unlowerable custom globals keep raw key comparison. |
28
+ | **Effect capabilities (U03/Y08)** | Public root API: `analyzeProject(...).ir.capabilityUses`; the CLI/hook adapters add symbol-aware ambient evidence internally | Additive within IR `1.0`. Seven **closed** ids: `network`, `filesystem`, `clock`, `randomness`, `environment`, `process`, `persistence` (ADR 0009). `collectCapabilityUses` and the Domain vocabulary are internal implementation exports, **not** exports from `arkgate`; the related public low-level helper is `collectForbiddenCapabilityUses`. Direct evidence only — transitive inference never detects. The symbol-aware adapter path covers ambient globals (shadowing/type-only/globalThis-alias precision from the S05/C04 machinery) plus imports; the compiler-free IR engine carries **import-based** uses only (exact module or subpath match, never substring; textual `import type`/`export type` erasure — ANY braced named-binding list stays a value import there; template-literal bodies are skipped entirely (specifiers inside `${…}` are the symbol path's job); `require(…)` counts as capability evidence but never creates a graph edge on the pure path). **U04 walls are opt-in:** per-layer `capabilities: { deny: [...] }` or the dual-depth sugar `pure: true` (denies all seven); absence changes no verdict. `CAPABILITY_VIOLATION` is judgment-class (never mechanical-safe) with a port-injection `nextAction`; D7 dedup — evidence already owned by the layer's `forbiddenGlobals` reports only `FORBIDDEN_GLOBAL`. Y08 adds one deliberately narrow import dual: `forbiddenGlobals: ["process"]` owns exact value imports of `process` and `node:process`, but not subpaths or `child_process`; statement-level `import type` / `export type` remains erased on every path (the existing pure-IR all-named limitation above is unchanged). Atomic preflight blocks denied capabilities and that exact dual across a complete multi-file candidate (import-based on the pure path; other ambient evidence adds on the symbol-aware CLI/hook path). T01 policy-delta classifies the surface on **coverage atoms** (`ambient:<entry>` prefix-expanded, narrow `import-exact:<specifier>` duals, and `import:<capability>` for a complete wall): any lost atom is weakening (`fetch`→`XMLHttpRequest`, `Date`→`Date.now`, wall→fg all weaken; finding path `$.layers[name].capabilities`); fg → equivalent-or-stronger wall never needs an acknowledgment; unlowerable custom globals keep raw key comparison. |
28
29
  | **Ambient state (U05)** | `ark-check --doctor --json` → `doctor.ambientState`; optional `.ark/ambient-state-acks.json` | Additive, **advisory only and opt-in**: only layers declared `pure: true` are scanned; the MVP shape is module-scope `let`/`var`. Findings carry `file`/`line`/`name`/`kind` (sorted, capped with honest `truncated` count). Acknowledgments live in the bounded sidecar (`{ acks: [{ file, name, reason }] }`, ≤64 KB / ≤200 entries); `acknowledged` counts applied acks; malformed file suppresses nothing. When TypeScript is unavailable the sensor reports `available: false` instead of guessing. **No strict mode exists** — A5: strictness requires a completed corpus and an explicit later decision. |
29
- | **Parse health (Y03)** | `ark-check --doctor --json` → `doctor.parseHealth`; report section `data-advisory="parseHealth"` | Additive, **advisory only**. The existing architecture AST contributes only `parseDiagnosticCount` per governed file (cache schema v9, bound to the TypeScript parser version; no raw diagnostics, second parse, or `tsc`). JSON reports `scannedFiles`, `affectedFiles`, `diagnosticCount`, deterministic top-12 `{ file, diagnosticCount }` entries, and honest `truncated`/`overflow`; missing/unsafe counts or unavailable scan evidence produce `available: false`, never a clean claim or a non-JSON-safe number. Parse health never changes the verdict, `ok`, violations, `designFitness`, or `patternBets`. |
30
+ | **Parse health + analysis completeness (Y03/Z02)** | `ark-check --doctor --json` → `doctor.parseHealth` + `doctor.completeness`; check JSON → `completeness`; report section `data-advisory="parseHealth"` | The resolved candidate facts contribute only `parseDiagnosticCount` per governed file (no raw diagnostics, second parser pass, or `tsc`). Z04's correctness path ignores legacy v9 caches and parses the complete candidate on every invocation; Z07 owns any future identity-keyed warm snapshot. Doctor remains diagnostic: parse health adds no architecture violation and does not change `designFitness` or `patternBets`. Verdict surfaces consume the evidence fail-closed: affected governed files mean `partial`, plan `goal.met: false`, normal JSON `valid:false`/`ok:false`, and strict merge exit `1`; the non-strict process exit remains advisory for compatibility. No usable host means `unavailable`, plan false, and CLI exit `2`. JSON reports `scannedFiles`, `affectedFiles`, `diagnosticCount`, deterministic top-12 `{ file, diagnosticCount }` entries, and honest `truncated`/`overflow`; missing/unsafe evidence never becomes a clean claim. |
30
31
  | **Physical cohesion + reshape pilot (X04/Y01)** | `ark-check --doctor --json` → `doctor.physicalCohesion` (`reshapePilot`, `reshapeDecisions`); optional `.ark/reshape-decisions.json`; report section `data-advisory="physicalCohesion"` | Additive, **advisory only** — `notAScore`; never feeds the verdict, `designFitness`, or `patternBets`. Signal is **concentration, not volume**: concept clusters per anchor directory (deterministic path/name tokenization; framework filenames like `route.ts` take the topmost meaningful path segment — ADR 0010 D2). Fixed corpus-calibrated thresholds (`maxCluster ≥ 40` OR ≥2 anchors ≥ 20, ADR 0010 D3); findings ranked and capped (top 5, honest `truncated`). Anchors under `app/`/`pages/` are `fixedByConvention` and never move (D7). `reshapePilot` is **proposed, never applied** (`neverMechanicalSafe`): one Q04-style pilot card at a time targeting the smallest convention-free anchor, with `moveSample`/`movesTotal`, `successSignal`, `killSwitch`, `doNot[]`; real moves run only through the write gate + atomic preflight via `/ark-loop`; merges are `/ark-architect` judgment cards, never a codemod (D6). **Y01 verdict memory:** bounded sidecar `{ schemaVersion?: "1", decisions: [{ concept, anchors, verdict: "accepted"|"deferred"|"rejected", reason, reviewBy? }] }` (≤64 KiB / ≤200 unique targets). Identity is concept + complete sorted anchor set, never counts/change-map evidence. Current rejected/deferred records suppress pilot pressure only; accepted keeps the existing path. Expired/malformed/stale/invalid records suppress nothing; lifecycle and decisions render in doctor/report. Explicit only — golden-pattern prose never infers a verdict. |
31
32
  | **Capability walls, every adapter (U04+U06)** | CLI scan, pure IR engine, atomic preflight, `ark-mcp --hook` / MCP gate (`capabilityWalls`), ESLint `ark/no-denied-capabilities` | The same opt-in deny set enforces across every surface: hook/MCP and CLI cover ambient + import evidence (symbol-aware); the pure engine, preflight, and ESLint cover the import dimension (documented envelope). Dual depth everywhere: plain port hint (`FIX_HINTS`/`suggestion`) + stable JSON (`ruleId`, `capability`, `fixClass: inject-port`, deterministic `nextAction`). |
32
- | **Hook-path budgets (U06)** | `npm run bench:hook-path`; `eval/performance/hook-budgets.v1.json`; CI job "Hook-path end-to-end budgets" | Measures the COMPLETE pre-tool paths as fresh child processes (hook cold/warm, doctor cold) at 1k/10k. D5 method locked: ceilings are Linux-baseline p95 + fixed headroom, set once per cycle, never ratcheted; scenarios without a recorded baseline stay in RECORDING mode and cannot fail CI. |
33
+ | **Hook-path budgets (U06)** | Repository-only evidence: `npm run bench:hook-path`; `eval/performance/hook-budgets.v1.json`; CI job "Hook-path end-to-end budgets" | Measures the COMPLETE pre-tool paths as fresh child processes (hook cold/warm, doctor cold) at 1k/10k. D5 method locked: ceilings are Linux-baseline p95 + fixed headroom, set once per cycle, never ratcheted; scenarios without a recorded baseline stay in RECORDING mode and cannot fail CI. |
33
34
  | **Governance weight (W02)** | `ark-check --doctor --json` → `doctor.contractHealth.governanceWeight` | Additive, **advisory only** — raw facts (`declaredLayers`, `populatedLayers`, `governedFiles`, `rules`, `deniedEdges`, `allowedEdges`, `filesPerLayer`, `rulesPerLayer`) plus a fixed comparative band `weight: heavy | typical | light | unknown` and its fixed `note`. Fixed deterministic thresholds: **heavy** = fewer than 25 governed files per declared layer AND (6+ layers OR 4+ well-formed rules per layer); **light** = at most 2 layers over 150+ governed files; **unknown** = no layers or no governed files; everything else is **typical** (banding uses raw ratios; the reported ratios are rounded for display). `notAScore: true` is explicit: never a composite score, ranking, or gate input; the heavy note asks to justify NEW layers/rules and never suggests deleting working ones. Human doctor prints a line only for `heavy`/`light`. |
34
35
  | **Report parity (X01)** | `ark-check --report` → advisory sections (`data-advisory="contractHealth\|ambientState\|parseHealth"`, nested `governanceWeight`) + layer wall badges | The report is a rendering of doctor truth. **Standing rule:** every doctor advisory ships with its report section — enforced by the `reportParity` guard, which enumerates the doctor's advisory keys and fails on any missing section. |
35
36
  | **MCP tools** | `arkgate-mcp` / `ark://…` resources | Tool names and primary argument shapes are stable within a major. |
36
37
  | **`ark.config.json`** | Layer globs, rules, include/exclude, forbiddenGlobals, intent prefixes, `peerIsolation`, `dynamicImportAllowlist`, `safety` thresholds | Versioned by `schemaVersion`; unknown fields fail closed and migrations preserve the previous supported major. |
37
38
  | **Policy transition analysis (T01, 3.1.0)** | `analyzePolicyDelta(...)`; MCP `ark_policy_delta`; CLI `--policy-base` / `--policy-base-ref` / `--policy-ack`; check JSON `policyDelta` | Additive schema `1.0`. Classifications and finding ids are deterministic. Weakening/judgment requires an acknowledgement bound to both policy hashes and the exact blocking finding set. |
38
39
  | **Atomic change preflight (T02, 3.1.0)** | `preflightChange(...)`; CLI `ark preflight --changes <file> --json`; MCP `ark_prepare_change` | Additive schema `1.0`. One complete governed production-source `{path,content}` / `{path,delete:true}` batch; read-only; returns operation, content/tree/policy/compiler fingerprints and stable graph findings. MCP availability alone is advisory. |
39
- | **Architecture change map (T03, 3.1.0)** | `arkgate/schema/change-map`; CLI `ark preflight --change-map <file>`; MCP `ark_prepare_change.changeMap` | Optional strict schema `1.0`. Canonical planned paths + operations + resolved Ark layers + dependencies between planned files. Preflight returns `changeMapHash`; absence is normal and adds no project file. Structural intent only, never behavioral completion. |
40
+ | **Architecture change map (T03, 3.1.0)** | `arkgate/schema/change-map` or `arkgate/schema/ark.change-map.schema.json`; CLI `ark preflight --change-map <file>`; MCP `ark_prepare_change.changeMap` | Optional strict schema `1.0`. Canonical planned paths + operations + resolved Ark layers + dependencies between planned files. Preflight returns `changeMapHash`; absence is normal and adds no project file. Structural intent only, never behavioral completion. |
40
41
  | **Structural convergence (T04, 3.1.0)** | `analyzeArchitectureConvergence(...)`; map-enabled `preflightChange(...)`; existing CLI/MCP preflight adapters | Additive `convergence` result with stable `satisfied`, `missing`, `contradictory`, and `unplanned` findings. Uses the supplied/current project tree as base and the explicit complete change set as candidate; no implicit Git or LLM input. `readOnly: true`; `behavioralCompletion: "not-evaluated"`. Structural mismatch makes preflight invalid. |
41
42
  | **Enforcement ladder + fixed journey (T05, 3.1.0)** | `doctor.writePath.enforcementLadder`; hook repair `enforcement`; `npm run eval:change-integrity` | Additive schema `1.0` separates supported/installed/active/bypassable state and evidence. Hard is operation-scoped only for a supported covered hook; MCP is advisory; required CI status stays unverified locally. Fixed no-context fixture proves CLI/MCP/hook/final parity, one casual denial, acceptance behavior, and strict Ark. |
42
- | **`arkgate/schema/analysis-result`** | Public CLI/MCP/hook diagnostic envelope (`schemaVersion`, `valid`, `diagnostics`) | Schema `1.1` adds optional `nextAction`; the `1.0` fixture and consumer-owned TypeScript diagnostics remain valid. |
43
+ | **Enforcement state (Z06/Z10)** | `doctor.writePath.enforcementState`; schema/type | Schema `1.1`: runtime observation, operation coverage, and operation-scoped `hard`. Only fresh covered active-host evidence permits `hard:true`; unverified assets and MCP remain non-hard. |
44
+ | **Design delta (Z10)** | `--fail-on-new-smells --base-ref <ref>`; hook/MCP; schema/types | Schema `1.0`: identities, touched paths, stable evidence/verdict. Missing base fails closed; only new/worsened `domain-logic-in-ui` blocks; global doctor smells stay advisory. |
45
+ | **`arkgate/schema/analysis-result`** or **`arkgate/schema/ark.analysis-result.schema.json`** | Public CLI/MCP/hook diagnostic envelope (`schemaVersion`, `mode`, `valid`, `completeness`, `completenessReasons`, `diagnostics`, resolved identities) | Schema `1.3` distinguishes `resolved-candidate-facts` from `lexical-compatibility`; partial/unavailable analysis is always non-green, and resolved complete/partial results require policy/resolver/facts/tree identities. `1.2` added completeness and remains accepted alongside consumer-owned 1.0/1.1 values. |
46
+ | **`arkgate/schema/resolved-candidate-facts`** or **`arkgate/schema/ark.resolved-candidate-facts.schema.json`** | Versioned parity-capable input for `analyzeResolvedProject` / `preflightResolvedChange` | Schema `1.0` is serializable and deterministic. Tooling owns filesystem/compiler resolution; Domain/Kernel validate and evaluate supplied facts without importing those effects. Facts name resolver/compiler inputs, governed files, dependency evidence, completeness reasons, and candidate tree/facts hashes. |
43
47
  | **Config JSON Schema** | `arkgate/schema` or `arkgate/schema/ark.config.schema.json` | Stable package resource subpaths for editor completion and contract tooling. |
44
48
  | **Agent skills** | `/ark-*` templates installed by `--install-agent-gates` | Skill *names* and “default flow” are stable; internal skill prose may evolve (e.g. When/not when, explore Shape dual-plan seed, extraction cards, day-zero origin order). |
45
49
  | **ESLint subpath** | `arkgate/eslint` | Config-driven layer/import rules; loads consumer `ark.config.json`. |
46
50
  | **GitHub Action** | `pedroknigge/arkgate` (see `action.yml`) | The `uses:` tag/SHA selects the checker source; `version` remains an optional exact npm compatibility override. |
51
+ | **Package metadata** | `arkgate/package.json` | Stable resource subpath for tooling that needs the installed manifest. |
52
+
53
+ ### Corrective distribution status and strict boundary
54
+
55
+ `arkgate@3.8.0` includes the non-deduplicable TS6 host, completeness schema, and resolved
56
+ candidate-facts parity path above. It installs `typescript-ark-host` at
57
+ exact `npm:typescript@6.0.3`, prefers a usable project compiler API, and fails closed on `partial`
58
+ or `unavailable` analysis. Its packed compatibility gate is scoped to Node 18/20/22/24,
59
+ npm/pnpm/Yarn, and project TypeScript 5.9.3/6.0.3/7.0.2. All 36 packed cells passed on source
60
+ `228dd893` in CI run `29655190747`. Yarn uses strict PnP for the JS compilers and its
61
+ `node-modules` linker for native TS7; the report names that mode.
62
+
63
+ Z04 closes the separate current-source parity claim under the supplied-facts boundary selected in
64
+ [ADR 0011](adr/0011-resolved-candidate-facts-boundary.md). Complete candidates—including aliases,
65
+ workspace/project packages, symlinks, creates, updates, and deletes—are resolved once into
66
+ versioned facts and evaluated by one pure Kernel/generated-bundle verdict. CLI, MCP, complete-patch
67
+ hook, programmatic resolved APIs, and final check preserve the same evidence identities; ESLint
68
+ claims parity only for its documented on-disk static-relative envelope. Retained lexical APIs and
69
+ single-snippet adapters report `lexical-compatibility`, `partial`, and non-green instead of
70
+ borrowing the resolved claim.
71
+
72
+ Strict CI remains the final authority because it is the merge boundary, not because another
73
+ semantic engine is expected there. No early adapter result is permission to suppress that gate.
47
74
 
48
75
  Gates need **no application code imports**. Most projects only use the CLI + MCP + config.
49
76
 
77
+ ## Programmatic root API
78
+
79
+ `src/gate.ts` is the canonical source for `import ... from 'arkgate'`. Its public runtime values
80
+ are grouped below.
81
+
82
+ | Group | Exported runtime values |
83
+ |-------|-------------------------|
84
+ | Metadata and adapter diagnostics | `version`, `ARK_ANALYSIS_RESULT_SCHEMA_VERSION`, `ARK_ANALYSIS_RESULT_SCHEMA`, `createAdapterResult`, `toAdapterDiagnostic` |
85
+ | AI snippet gate | `createAICodeGate` |
86
+ | Profiles and config factories | `createArchitectureProfile`, `createArchitectureProfileFromArkConfig`, `createElevenLayerArkConfig`, `elevenLayerProfile` |
87
+ | Analysis and preflight | `loadContract`, `analyzeResolvedProject`, `preflightResolvedChange`, lexical-compatibility `analyzeProject` / `analyzeChange` / `preflightChange`, `analyzePolicyDelta`, `analyzeArchitectureConvergence`, `explainViolation`, `evaluateArchitectureGraph`, `collectAnalysisConfigWarnings`, `detectArchitectureCycles`, `collectForbiddenCapabilityUses`, `extractSemanticDependencies` |
88
+ | Policy delta | `POLICY_DELTA_SCHEMA_VERSION`, `classifyArkPolicyDelta`, `policyDeltaAcknowledgementMatches` |
89
+ | Design delta contract | `ARK_DESIGN_DELTA_SCHEMA_VERSION` |
90
+ | Analysis IR + resolved facts | `ANALYSIS_IR_SCHEMA_VERSION`, `RESOLVED_CANDIDATE_FACTS_SCHEMA_VERSION`, `RESOLVED_CANDIDATE_FACTS_SCHEMA`, `createResolvedCandidateFacts`, `loadResolvedCandidateFacts`, `resolvedFactsEvidenceRequirementsHash`, `deterministicHash`, `stableSerialize` |
91
+ | Config contract | `ARK_CONFIG_SCHEMA`, `ARK_CONFIG_SCHEMA_VERSION`, `loadArkConfigContract`, `parseArkConfigJson` |
92
+
93
+ The type-only root exports are also semver-supported:
94
+
95
+ - Adapter diagnostics: `AdapterDiagnostic`, `AdapterResult`, `AdapterSeverity`,
96
+ `AdapterViolationInput`, `AdapterCompletenessReason`, `AnalysisCompleteness`, `AnalysisMode`.
97
+ - Resolved facts: `ResolvedCandidateFacts`, `ResolvedCandidateFactsInput`, and their
98
+ dependency/file/evidence component types.
99
+ - AI snippet gate: `AICodeGate`, `AICodeGateResult`, `AICodeGateViolation`,
100
+ `AICodeGateContext`, `AICodeGateOptions`, `AIGateExtension`.
101
+ - Profiles and config factories: `ArchitectureLayer`, `ArchitectureLayerConfig`,
102
+ `ArchitectureProfile`, `ArchitectureRule`, `ArkCheckConfig`,
103
+ `CreateArchitectureProfileFromArkConfigOptions`, `CreateArchitectureProfileOptions`,
104
+ `CreateElevenLayerArkConfigOptions`.
105
+ - Analysis and preflight: `AnalysisContract`, `ArchitectureChangeMap`,
106
+ `ArchitectureChangeMapContract`, `ArchitectureChangeMapDependency`,
107
+ `ArchitectureChangeMapFile`, `ArchitectureChangeOperation`,
108
+ `AnalyzeArchitectureConvergenceInput`, `ArchitectureActualChange`,
109
+ `ArchitectureConvergenceClassification`, `ArchitectureConvergenceFinding`,
110
+ `ArchitectureConvergenceResult`, `ArchitectureDependency`, `AnalyzeProjectInput`,
111
+ `AnalyzeResolvedProjectInput`, `PreflightResolvedChangeInput`, `AnalyzeChangeInput`,
112
+ `AnalysisResult`, `ResolvedAnalysisFile`, `ResolvedAnalysisIr`, `ResolvedAnalysisResult`,
113
+ `ResolvedChangePreflightResult`, `ResolvedSafetyReport`, `PreparedChangeFile`, `ChangePreflightResult`,
114
+ `AnalyzePolicyDeltaInput`, `PolicyDeltaAnalysis`, `ArchitectureEngineViolation`,
115
+ `ArchitectureEngineEdge`, `EvaluateArchitectureGraphInput`, `ArchitectureEngineResult`,
116
+ `CollectAnalysisConfigWarningsInput`, `ForbiddenCapabilityUse`, `SemanticDependency`,
117
+ `SemanticDependencyKind`.
118
+ - Policy delta: `PolicyDelta`, `PolicyDeltaAcknowledgement`, `PolicyDeltaClassification`,
119
+ `PolicyDeltaFinding`.
120
+ - Design delta: `ArkDesignDeltaResult`, `ArkDesignDeltaIdentity`, `ArkDesignDeltaChange`,
121
+ `ArkDesignDeltaEvidence`, `ArkDesignSmellId`, `ArkDesignDeltaVerdict`.
122
+ - Analysis IR: `AnalysisFileInput`, `AnalysisFileChange`, `AnalysisCompilerOptions`,
123
+ `AnalysisFile`, `AnalysisImportEdge`, `AnalysisCapabilityUse`, `AnalysisEvidence`,
124
+ `AnalysisViolation`, `AnalysisIr`.
125
+ - Config contract: `ArkConfig`, `ArkConfigLoadResult`.
126
+
127
+ Runtime-kernel factories, `CAPABILITY_IDS`, `collectCapabilityUses`, and Domain capability mapping
128
+ helpers are deliberately absent from this root. Use `@arkgate/runtime` for the experimental
129
+ runtime, and `analyzeProject(...).ir.capabilityUses` for public capability evidence.
130
+
50
131
  ---
51
132
 
52
133
  ## Experimental opt-in surfaces
53
134
 
54
- These APIs are shipped for evaluation and compatibility, but they are **not production-ready
135
+ These APIs are implemented for evaluation and compatibility, but they are **not production-ready
55
136
  product claims**. Static architecture enforcement does not depend on them.
56
137
 
57
138
  | Surface | Import path | Notes |
58
139
  |---------|-------------|--------|
59
- | **Runtime kernel** | **`@arkgate/runtime`** | Separate 0.x package, published under the `experimental` tag. Event bus, intents, policies, sagas, event buffer, projections, and strict helpers. Built-in stores are **InMemory reference only**. |
140
+ | **Runtime kernel** | **`@arkgate/runtime`** | Separate 0.x source package configured for the `experimental` tag. It is not currently present in the npm registry, and the root `publish-npm.yml` workflow does not publish it automatically. Event bus, intents, policies, sagas, event buffer, projections, and strict helpers. Built-in stores are **InMemory reference only**. |
60
141
  | **Runtime migration shim** | `arkgate/runtime` | Deprecated forwarder to `@arkgate/runtime`; contains no implementation and is removed in ArkGate 4. |
61
142
  | **NestJS adapter** | `@arkgate/runtime/nestjs` | Experimental optional peer `@nestjs/common`; the deprecated `arkgate/nestjs` path forwards here. |
62
143
 
@@ -72,7 +153,12 @@ import { createStrictArkKernel, createStrictArkKernelFromConfig } from '@arkgate
72
153
  import { ArkModule, InjectArk } from '@arkgate/runtime/nestjs';
73
154
  ```
74
155
 
75
- See [production-hardening.md](./production-hardening.md) for requirements an eventual
156
+ These imports describe the intended package boundary. Before an npm evaluation, verify that a
157
+ separate publication exists with `npm view @arkgate/runtime dist-tags --json`. Until it does,
158
+ build `packages/runtime` in an ArkGate source checkout and install that local folder; do not treat
159
+ the deprecated root forwarding shims as an embedded runtime.
160
+
161
+ See [production-hardening.md](https://github.com/pedroknigge/arkgate/blob/main/docs/production-hardening.md) for requirements an eventual
76
162
  production deployment would need to satisfy; it is not a readiness certification.
77
163
 
78
164
  ---
@@ -100,6 +186,6 @@ production deployment would need to satisfy; it is not a readiness certification
100
186
 
101
187
  ## Release notes (maintainers)
102
188
 
103
- Ship notes for a version live under [releases/](./releases/) (latest:
104
- [3.7.0.md](./releases/3.7.0.md)).
105
- Publish path: signed annotated tag → GitHub Release → `publish-npm.yml` (see [CONTRIBUTING.md](../CONTRIBUTING.md)).
189
+ Ship notes for a version live under [releases/](https://github.com/pedroknigge/arkgate/tree/main/docs/releases) (latest:
190
+ [3.8.0.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/3.8.0.md)).
191
+ Publish path: signed annotated tag → GitHub Release → `publish-npm.yml` (see [CONTRIBUTING.md](https://github.com/pedroknigge/arkgate/blob/main/CONTRIBUTING.md)).
@@ -1,4 +1,4 @@
1
- # TypeScript support (5.x · 6.x · 7.x)
1
+ # TypeScript support (5.x / 6.x / 7.x)
2
2
 
3
3
  ArkGate’s architecture gate (`arkgate-check` / `ark-mcp`) needs a **JavaScript API**
4
4
  TypeScript package that exposes:
@@ -6,6 +6,7 @@ TypeScript package that exposes:
6
6
  - `ts.sys` (at least `fileExists`)
7
7
  - `createSourceFile` (AST)
8
8
  - `resolveModuleName` (module graph)
9
+ - `isInTypeQuery` (runtime-reference classification)
9
10
 
10
11
  It does **not** require the Go-native `tsc` binary for the gate. Type-checking
11
12
  semantics of your app still come from **your** project `typescript` + `tsconfig`.
@@ -14,11 +15,22 @@ semantics of your app still come from **your** project `typescript` + `tsconfig`
14
15
 
15
16
  | Range | Status |
16
17
  |-------|--------|
17
- | **TypeScript 5.x** | Fully supported (primary CI) |
18
- | **TypeScript 6.x** | Supported (bridge release before 7) |
19
- | **TypeScript 7.x** | Supported as **project** compiler; gate loads project TS when API-compatible, otherwise **falls back** to a JS-API TypeScript |
18
+ | **TypeScript 5.x** | Supported; packed compatibility cell uses **5.9.3** |
19
+ | **TypeScript 6.x** | Supported; packed compatibility cell uses **6.0.3** |
20
+ | **TypeScript 7.x** | Supported through the project's own compiler plus ArkGate's physically distinct TypeScript 6 analysis host; packed compatibility cell uses **7.0.2** |
20
21
 
21
- Optional peer (documentational):
22
+ These current-source claims passed the complete 36-cell packed matrix on source `228dd893` in
23
+ [CI run 29655190747](https://github.com/pedroknigge/arkgate/actions/runs/29655190747).
24
+ Published 3.7.0 remains outside this corrected support claim.
25
+
26
+ > **Distribution boundary:** published `arkgate@3.7.0` predates this correction. Its compatible
27
+ > analysis dependency can deduplicate to a TS7 version-only export, and its unavailable
28
+ > `--plan --json` result can incorrectly report `goal.met: true`. The current source candidate for
29
+ > the next corrective release fixes both defects with a non-deduplicable host and explicit analysis
30
+ > completeness. Do not attribute that fix to 3.7.0; upgrade once the corrective version is
31
+ > published.
32
+
33
+ Supported consumer range (also declared as an optional peer for compatibility):
22
34
 
23
35
  ```json
24
36
  "peerDependencies": {
@@ -26,24 +38,63 @@ Optional peer (documentational):
26
38
  }
27
39
  ```
28
40
 
29
- ArkGate does not hard-require `typescript` as a runtime dependency of the package
30
- itself; the CLI resolves it from the **project** first, then from the environment.
41
+ The current source line installs one exact production fallback under a different package identity:
42
+
43
+ ```json
44
+ "dependencies": {
45
+ "typescript-ark-host": "npm:typescript@6.0.3"
46
+ }
47
+ ```
48
+
49
+ The CLI still resolves the consumer project's **own** `typescript` first so a usable project API
50
+ and its module-resolution semantics win. If that export is missing or version-only, ArkGate loads
51
+ `typescript-ark-host`. Because the dependency key is distinct from `typescript`, npm, pnpm, and
52
+ Yarn cannot satisfy it by reusing the project's TS7 package. It also does not replace the project's
53
+ `tsc`; builds and type checks continue to run the compiler selected by the consumer lockfile.
31
54
 
32
55
  ## How loading works
33
56
 
34
- 1. Prefer `require('typescript')` from the **project** root (when it has `sys` + AST + resolve).
35
- 2. If missing or **not API-compatible** (TS 7.0 version-only export, or incomplete host), fall back to **ArkGate’s own** `typescript` dependency (JS-API 5.x nested under the package), then bare `import('typescript')`.
36
- 3. If nothing usable is found:
37
- - `--plan` still prints **coverage honesty** (no import graph)
38
- - full check exits non-zero with an install hint
57
+ 1. Prefer `require('typescript')` from the **project** root when it has `sys` + AST + resolve.
58
+ 2. If the project export is missing or **not API-compatible** (for example, the TS 7.0
59
+ version-only export), load `typescript-ark-host` at exact `npm:typescript@6.0.3` from ArkGate's
60
+ install tree.
61
+ 3. If neither host is usable, analysis is `unavailable`: plan has `goal.met: false`, normal JSON
62
+ has `valid: false` and `ok: false` with `ANALYSIS_HOST_UNAVAILABLE`, and the CLI exits `2`.
63
+ 4. If the selected host reports parse diagnostics in governed files, analysis is `partial`:
64
+ `--plan --json` has `goal.met: false`, normal JSON has `valid: false` / `ok: false`, and
65
+ `--strict-merge` exits `1`. The non-strict command preserves its legacy advisory exit code;
66
+ doctor also remains diagnostic while exposing the same completeness and parse-health evidence.
39
67
 
40
68
  Debug which TypeScript was used:
41
69
 
42
70
  ```bash
43
71
  ARK_DEBUG_TS=1 npx arkgate-check --plan
44
- # → [ark-check] TypeScript 5.9.x via arkgate (fallback)
72
+ # project TS 5/6 → [ark-check] TypeScript 5.9.3 via project
73
+ # project TS 7 → [ark-check] TypeScript 6.0.3 via arkgate-fallback (fallback)
45
74
  ```
46
75
 
76
+ ## Analysis identity and completeness (schema 1.3)
77
+
78
+ Every current CLI/MCP/hook diagnostic envelope carries required `mode`, `completeness`, and
79
+ structured `completenessReasons`:
80
+
81
+ | Value | Meaning | Can plan/check be green? |
82
+ |-------|---------|--------------------------|
83
+ | `complete` | Every governed file was analyzed with a usable host and no parse diagnostics | Yes, if the normal contract verdict is also clean |
84
+ | `partial` | A host ran, but governed syntax could not be fully parsed | No in JSON/plan; strict merge fails. The non-strict process exit remains advisory for compatibility |
85
+ | `unavailable` | No API-compatible host could produce architecture evidence | No; CLI exits `2` |
86
+
87
+ Schema 1.3 also distinguishes `resolved-candidate-facts` from `lexical-compatibility`.
88
+ Resolved complete/partial results carry `policyHash`, `resolverIdentity`, `factsHash`, and
89
+ `candidateTreeHash`, so adapters can prove they evaluated the same input. Single-file lexical
90
+ surfaces cannot prove module resolution and therefore report `partial`, `valid:false`, plus
91
+ `lexicalValid` where useful. Both the exported union and JSON Schema prohibit `valid:true` for
92
+ partial/unavailable analysis. The public TypeScript `AdapterResult` union still accepts
93
+ consumer-owned 1.0/1.1/1.2 values. For source compatibility, the low-level
94
+ `createAdapterResult({ valid, ... })` factory still treats omitted completeness as complete; that
95
+ legacy construction is not evidence of resolved adapter parity, and shipped adapters pass mode,
96
+ completeness, reasons, and identities explicitly.
97
+
47
98
  ## TypeScript 7 notes
48
99
 
49
100
  TypeScript 7 is the **native (Go) compiler** generation. Important for tools like ArkGate:
@@ -51,7 +102,10 @@ TypeScript 7 is the **native (Go) compiler** generation. Important for tools lik
51
102
  - **`require('typescript')` on 7.0.x** exports only `{ version, versionMajorMinor }` — not `sys`, `createSourceFile`, or `resolveModuleName`.
52
103
  - Unstable programmatic surfaces live under `typescript/unstable/*` (sync/async API, AST). They are **not** the classic TS 5/6 host ArkGate uses today.
53
104
  - Stable **programmatic JS API** maturity continues over the 7.x line (Microsoft: full story into **7.1+**).
54
- - When the project’s TypeScript is not API-compatible, ArkGate loads its **bundled JS-API dependency** (`typescript@^5.9`, nested under the package) so the host write path and CI check keep working while you try TS 7 as the project compiler.
105
+ - When the project’s TypeScript is not API-compatible, the current source line loads the exact,
106
+ separately named `typescript-ark-host` dependency. Published 3.7.0 does not yet have that fix.
107
+ - TypeScript 7 syntax that TypeScript 6.0.3 cannot parse is reported as `partial`, never clean.
108
+ ArkGate fails closed until its analysis host can parse every governed file.
55
109
  - Your **tsconfig** must follow TS 6/7 defaults (see below) or `tsc` / resolve can fail independently of ArkGate.
56
110
 
57
111
  ### tsconfig defaults that surprise teams (TS 6 → 7)
@@ -87,47 +141,62 @@ Example consumer-friendly skeleton (also used in `tests/fixtures/ts-consumer`):
87
141
  }
88
142
  ```
89
143
 
90
- ## Side-by-side TypeScript 6 + 7 (tooling)
144
+ ## Project compiler remains project-owned
91
145
 
92
- If you need **tsc 7** for builds and a **JS API 6** for tools that still expect classic exports:
146
+ Do not downgrade, alias, or replace the project's `typescript` dependency for ArkGate. A TS7
147
+ project keeps TS7 for `tsc`, editor semantics, and its lockfile; `typescript-ark-host` is an
148
+ internal analysis dependency. If a repository intentionally runs multiple `tsc` versions for its
149
+ own migration, keep that setup separate from ArkGate's host resolution.
93
150
 
94
- ```json
95
- {
96
- "devDependencies": {
97
- "typescript": "npm:@typescript/typescript6@^6.0.0",
98
- "typescript-7": "npm:typescript@^7.0.0"
99
- }
100
- }
101
- ```
151
+ Declare the project compiler directly whenever you invoke `tsc`. If a consumer has no direct
152
+ `typescript` dependency, a package manager may expose the fallback alias's binary because it is the
153
+ only compiler in the install; that binary is not ArkGate's promise for project type checking. A
154
+ direct project `typescript` dependency wins in the packed npm, pnpm, and Yarn cells.
102
155
 
103
- - `npx tsc6` TypeScript 6 CLI (from the alias package)
104
- - `npx typescript-7` / install path — TypeScript 7 CLI as needed
156
+ ## Yarn PnP and the native TS7 compiler
105
157
 
106
- ArkGate will prefer the project’s `typescript` package; keep that entry **API-compatible** (5/6, or 7 once `sys` is present). See Microsoft’s TS 7 RC blog for dual-install details.
158
+ The supported Yarn 4.17.1 matrix names its linker mode explicitly:
159
+
160
+ - TypeScript 5.9/6.0 cells use **strict PnP** with no root `node_modules`.
161
+ - TypeScript 7.0 cells use Yarn's **`node-modules` linker**, so the native compiler resolves normal
162
+ package imports without an internal-path or unplugged-package bridge.
163
+
164
+ Yarn supports PnP for JS TypeScript releases by applying a compatibility patch to TypeScript's
165
+ resolver. The native TS7 compiler does not execute that JavaScript patch. ArkGate therefore does
166
+ not claim strict-PnP type-checking support for the TS7 cell; use Yarn's `node-modules` linker or
167
+ remain on the JS compiler for that workflow. ArkGate's CLI/MCP analysis-host fallback is a separate
168
+ concern and never changes the compiler selected by the project. See Yarn's
169
+ [PnP explanation](https://yarnpkg.com/getting-started/qa#why-is-typescript-patched-even-if-i-dont-use-plugnplay)
170
+ and Microsoft's [TS7 native release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/).
107
171
 
108
172
  ## CI matrix (this repo)
109
173
 
110
- GitHub Actions job `ts-compat` installs TypeScript **5.9.x**, **6.0.x**, and **7.0.x** into a temp copy of `tests/fixtures/ts-consumer` and runs:
174
+ The release compatibility workflow packs the candidate first, then tests clean consumers across:
111
175
 
112
- ```bash
113
- node bin/ark-check.mjs --root <fixture> --plan --json --no-cache
114
- ```
176
+ - Node **18 / 20 / 22 / 24**;
177
+ - **npm / pnpm / Yarn**;
178
+ - project TypeScript **5.9.3 / 6.0.3 / 7.0.2**.
115
179
 
116
- Locally:
180
+ That is 36 installed-artifact cells. Each cell verifies that the project's `tsc` stays on the
181
+ requested project compiler and that ArkGate resolves its fallback as exact 6.0.3 when the project
182
+ API is unusable. Reports record `installMode` so the Yarn TS7 linker boundary cannot disappear
183
+ behind a green job. All 36 cells passed on source `228dd893` in CI run `29655190747`. Locally, the
184
+ repository entry point is:
117
185
 
118
186
  ```bash
119
- node scripts/ts-compat-matrix.mjs 5.9.3
120
- node scripts/ts-compat-matrix.mjs 6.0.3
121
- node scripts/ts-compat-matrix.mjs 7.0.2
187
+ npm run test:ts-compat
122
188
  ```
123
189
 
124
190
  ## What “compatible” means for ArkGate
125
191
 
126
192
  | Goal | Status |
127
193
  |------|--------|
128
- | Gate does not crash on project TS 7 | Yes (fallback if API incomplete) |
194
+ | Packed gate runs beside project TS 7 | Yes in current source; verified across the complete packed matrix. Published 3.7.0 predates the distinct host |
129
195
  | Plan/check work with project TS 5/6 | Yes |
130
196
  | Plan/check work when project has TS 7 + usable `sys` | Yes (uses project) |
197
+ | Project `tsc` remains the selected project version | Yes; the analysis alias does not replace it |
198
+ | TS7-only syntax outside the TS6 parser envelope reports clean | No; completeness becomes `partial` and strict merge fails |
199
+ | Missing analysis host can satisfy a plan | No; completeness is `unavailable`, goal is false, exit is `2` |
131
200
  | Gate uses native Go typechecker API exclusively | Not required; future if 7.1+ exposes a stable Node API we adopt |
132
201
  | User tsconfigs with removed options still “just work” | User must migrate tsconfig (TS6/7); Ark reports resolve/parse failures clearly |
133
202
 
@@ -175,4 +244,7 @@ When Microsoft ships a stable Node API for native TypeScript 7.1+:
175
244
  2. Keep the multi-version matrix green.
176
245
  3. Optionally prefer project TS 7 for resolution without fallback.
177
246
 
178
- Until then, **fallback + matrix** is the compatibility story so teams can try TS 7 today without breaking the architecture gate.
247
+ Until then, the exact TypeScript 6 analysis alias is the compatibility bridge. Any `partial` or
248
+ `unavailable` result is a hard stop for accepting the analysis, not permission to trust a
249
+ clean-looking subset. Automation must read `valid`/`ok` or use `--strict-merge`; the legacy
250
+ non-strict process exit is not the completeness authority.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkgate",
3
- "version": "3.7.0",
3
+ "version": "3.8.0",
4
4
  "description": "ArkGate — architecture co-pilot for AI TypeScript (write gate, CI gate, plan/loop)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -28,6 +28,12 @@
28
28
  "./schema/ark.analysis-result.schema.json": "./schemas/ark.analysis-result.schema.json",
29
29
  "./schema/change-map": "./schemas/ark.change-map.schema.json",
30
30
  "./schema/ark.change-map.schema.json": "./schemas/ark.change-map.schema.json",
31
+ "./schema/resolved-candidate-facts": "./schemas/ark.resolved-candidate-facts.schema.json",
32
+ "./schema/ark.resolved-candidate-facts.schema.json": "./schemas/ark.resolved-candidate-facts.schema.json",
33
+ "./schema/enforcement-state": "./schemas/ark.enforcement-state.schema.json",
34
+ "./schema/ark.enforcement-state.schema.json": "./schemas/ark.enforcement-state.schema.json",
35
+ "./schema/design-delta": "./schemas/ark.design-delta.schema.json",
36
+ "./schema/ark.design-delta.schema.json": "./schemas/ark.design-delta.schema.json",
31
37
  "./nestjs": {
32
38
  "types": "./compat/nestjs.d.ts",
33
39
  "import": "./compat/nestjs.js",
@@ -47,9 +53,18 @@
47
53
  "files": [
48
54
  "bin",
49
55
  "bin/lib",
56
+ "!bin/lib/design-delta.source.mjs",
57
+ "!bin/lib/enforcement-state.source.mjs",
58
+ "!bin/lib/hook-templates.source.mjs",
59
+ "!bin/lib/ai-velocity.mjs",
60
+ "!bin/lib/graph-cycles.mjs",
61
+ "!bin/lib/safety-diagnostics.mjs",
62
+ "!bin/lib/ts-resolve.mjs",
50
63
  "compat",
51
64
  "dist",
65
+ "!dist/**/*.d.cts",
52
66
  "schemas",
67
+ "!schemas/*.source.json",
53
68
  "docs/agent-guide.md",
54
69
  "docs/enthusiast",
55
70
  "docs/demos/01-write-gate-self-correction.md",
@@ -82,7 +97,7 @@
82
97
  "test:fuzz": "npm run build && ARK_FUZZ_CAMPAIGN=pr vitest run tests/fuzz",
83
98
  "test:fuzz:extended": "npm run build && ARK_FUZZ_CAMPAIGN=extended vitest run tests/fuzz",
84
99
  "test:confidence": "npm run test:coverage && npm run test:mutation",
85
- "test:adapter-parity": "vitest run tests/unit/adapters/adapterParity.test.ts tests/unit/eslint/parity.test.ts",
100
+ "test:adapter-parity": "vitest run tests/unit/adapters/adapterParity.test.ts tests/unit/adapters/z04ResolvedAdapterParity.test.ts tests/unit/eslint/parity.test.ts",
86
101
  "test:onboarding-matrix": "for shard in library/small library/medium library/large api/small api/medium api/large frontend/small frontend/medium frontend/large monorepo/small monorepo/medium monorepo/large; do O04_SHARD=$shard npm run test:onboarding-matrix:shard; done",
87
102
  "test:onboarding-matrix:shard": "vitest run tests/unit/static-check/o04OnboardingMatrix.test.ts",
88
103
  "test:gate-only": "vitest run tests/unit/static-check/arkCheck.test.ts tests/unit/mcp/arkMcp.test.ts tests/unit/eslint",
@@ -95,11 +110,20 @@
95
110
  "check:layer-match": "node scripts/generate-layer-match.mjs --check",
96
111
  "generate:cli-pure": "node scripts/generate-cli-pure.mjs",
97
112
  "check:cli-pure": "node scripts/generate-cli-pure.mjs --check",
113
+ "generate:packaged-tooling": "node scripts/generate-packaged-tooling.mjs",
114
+ "check:packaged-tooling": "node scripts/generate-packaged-tooling.mjs --check",
98
115
  "generate:analysis-engine": "node scripts/generate-analysis-engine.mjs",
99
116
  "check:analysis-engine": "node scripts/generate-analysis-engine.mjs --check",
117
+ "generate:z08-prompts": "node scripts/generate-z08-task-prompts.mjs",
118
+ "check:z08-prompts": "node scripts/generate-z08-task-prompts.mjs --check",
119
+ "prepare:z08-sources": "node eval/causal/prepare-sources.mjs",
120
+ "generate:z08-manifest": "node eval/causal/generate-manifest.mjs",
121
+ "attest:z08-mutation": "node eval/causal/attest-mutation.mjs",
122
+ "eval:z08-causal": "node eval/causal/run.mjs",
123
+ "test:z08:harness": "vitest run tests/unit/eval/causalContract.test.ts tests/unit/eval/causalAnalysis.test.ts tests/unit/eval/causalRunner.test.ts tests/unit/eval/causalGrader.test.ts tests/unit/eval/z08TaskMaterialize.test.ts",
100
124
  "check:gallery-starters": "node scripts/check-gallery-starters.mjs",
101
125
  "generate:gallery-starters": "node scripts/check-gallery-starters.mjs --write",
102
- "test:ts-compat": "node scripts/ts-compat-matrix.mjs 5.9.3 && node scripts/ts-compat-matrix.mjs 6.0.3 && node scripts/ts-compat-matrix.mjs 7.0.2",
126
+ "test:ts-compat": "node scripts/ts-compat-matrix.mjs",
103
127
  "eval:agent": "node eval/run.mjs",
104
128
  "eval:corpus": "node eval/validate-corpus.mjs",
105
129
  "eval:comparative": "node eval/comparative-run.mjs",
@@ -111,6 +135,8 @@
111
135
  "test:adoption-harness": "vitest run tests/unit/eval/adoptionHarness.test.ts",
112
136
  "bench:scale": "node scripts/ark-scale-bench.mjs",
113
137
  "test:scale-bench": "npm run build && vitest run tests/unit/scripts/arkScaleBench.test.ts",
138
+ "test:z07:pr": "node scripts/z07-feedback-run.mjs --mode pr",
139
+ "test:z07:nonmutation": "node scripts/z07-feedback-run.mjs --mode full",
114
140
  "check:module-budgets": "node scripts/check-module-budgets.mjs",
115
141
  "check:package-files": "node scripts/verify-package-files.mjs",
116
142
  "check:release-artifacts": "node scripts/verify-release-artifacts.mjs",
@@ -122,7 +148,7 @@
122
148
  "bench:hook-path": "node scripts/hook-path-bench.mjs"
123
149
  },
124
150
  "dependencies": {
125
- "typescript": ">=5.0.0 <8"
151
+ "typescript-ark-host": "npm:typescript@6.0.3"
126
152
  },
127
153
  "peerDependencies": {
128
154
  "@arkgate/runtime": ">=0.1.0-experimental.0 <1",
@@ -152,10 +178,12 @@
152
178
  "@stryker-mutator/vitest-runner": "^9.6.1",
153
179
  "@types/node": "^20.14.0",
154
180
  "@vitest/coverage-v8": "^3.2.6",
181
+ "esbuild": "0.28.1",
155
182
  "fast-check": "^4.9.0",
156
183
  "reflect-metadata": "^0.2.2",
157
184
  "rxjs": "^7.8.2",
158
185
  "tsup": "^8.1.0",
186
+ "typescript": "5.9.3",
159
187
  "vitest": "^3.2.6"
160
188
  },
161
189
  "engines": {