arkgate 4.6.7 → 4.7.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.
- package/CHANGELOG.md +109 -0
- package/README.md +20 -9
- package/SECURITY.md +1 -1
- package/bin/ark-check-runtime.mjs +13 -1
- package/bin/ark-mcp-runtime.mjs +65 -3
- package/bin/lib/adapter-contract.mjs +17 -36
- package/bin/lib/analysis-engine.mjs +6 -6
- package/bin/lib/ark-run-doctor.mjs +144 -0
- package/bin/lib/ark-run-facts.mjs +472 -0
- package/bin/lib/ark-run-report.mjs +57 -0
- package/bin/lib/ark-run-sensors.mjs +309 -0
- package/bin/lib/config-contract.mjs +86 -11
- package/bin/lib/diagnostic-catalog.mjs +8 -0
- package/bin/lib/doctor-advisories.mjs +45 -8
- package/bin/lib/doctor-human.mjs +10 -0
- package/bin/lib/doctor-plan.mjs +20 -16
- package/bin/lib/extra-merge-teeth.mjs +187 -0
- package/bin/lib/html-report-advisories.mjs +2 -0
- package/bin/lib/html-report-depth.mjs +22 -2
- package/bin/lib/html-report.mjs +16 -0
- package/bin/lib/remediation.mjs +132 -0
- package/bin/lib/resolved-candidate-facts.mjs +67 -2
- package/bin/lib/rules-under-contract.mjs +37 -89
- package/bin/lib/snippet-analysis.mjs +43 -2
- package/bin/lib/status-command.mjs +28 -0
- package/bin/lib/status-manifest.mjs +23 -0
- package/dist/{configTypes-l6XiwiC1.d.ts → configTypes-CgJimx9o.d.ts} +17 -3
- package/dist/eslint/index.cjs +6 -2
- package/dist/eslint/index.d.ts +70 -2
- package/dist/eslint/index.js +6 -2
- package/dist/index.cjs +35 -35
- package/dist/index.d.ts +787 -272
- package/dist/index.js +35 -35
- package/docs/README.md +2 -1
- package/docs/agent-guide.md +21 -15
- package/docs/ai-gates.md +13 -0
- package/docs/configuration.md +24 -11
- package/docs/develop.md +12 -3
- package/docs/diagnostics.md +75 -0
- package/docs/enthusiast/README.md +4 -3
- package/docs/package-surface.md +16 -13
- package/docs/product-voice.md +6 -3
- package/docs/threat-model.md +1 -1
- package/docs/use.md +5 -4
- package/package.json +1 -1
- package/schemas/ark.config.schema.json +41 -2
- package/schemas/ark.resolved-candidate-facts.schema.json +1 -1
- package/schemas/ark.status-manifest.schema.json +47 -0
- package/server.json +2 -2
- package/templates/agent-skills/README.md +1 -1
- package/templates/agent-skills/ark-adopt/SKILL.md +23 -2
- package/templates/agent-skills/ark-place/SKILL.md +26 -2
- package/templates/agent-skills/ark-runtime/SKILL.md +66 -24
- package/templates/skills/ark-adopt.md +23 -2
- package/templates/skills/ark-place.md +26 -2
- package/templates/skills/ark-runtime.md +66 -24
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,115 @@ in the immutable pre-2.0 archive linked below.
|
|
|
5
5
|
|
|
6
6
|
## Unreleased
|
|
7
7
|
|
|
8
|
+
## 4.7.0 — 2026-08-25
|
|
9
|
+
|
|
10
|
+
**Minor** over **4.6.7**. Ships **ArkRun**: an opt-in extra on schema `1.2` for kernel
|
|
11
|
+
usage and complete declarations, plus companion `@arkgate/runtime` DX. Absence is
|
|
12
|
+
silent (Layers / ArkRules verdicts unchanged). In-memory stores remain
|
|
13
|
+
reference-only. **No required config migration.** Does not close Z09 / K01.
|
|
14
|
+
|
|
15
|
+
**Status: prepared** (see `docs/releases/4.7.0.md`). npm `latest` remains **4.6.7**
|
|
16
|
+
until publish.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **`arkRun` extra on `ark.config.json` schema `1.2` (RN02):** optional inline
|
|
21
|
+
`{ mode, compositionRoots, managedLayers, requireDeclarations }`. `1.1` and
|
|
22
|
+
earlier configs migrate in memory; absence is silent (Layers / ArkRules
|
|
23
|
+
verdicts unchanged). Unknown keys, unknown `managedLayers` names, and empty
|
|
24
|
+
`compositionRoots` in `enforced` mode fail closed (`ARKRUN_MISSING_ROOT`).
|
|
25
|
+
Advisory → enforced is a strengthening policy delta; demotion or deletion is
|
|
26
|
+
weakening and needs the existing hash-bound ack. ESLint envelope is RN06
|
|
27
|
+
(landed below); CI extra teeth landed in RN07. Does not close Z09 / K01.
|
|
28
|
+
|
|
29
|
+
- **ArkRun resolver facts on resolved-candidate-facts schema `1.2` (RN03):**
|
|
30
|
+
additive optional `arkRunKernelCalls`, `arkRunManagedNews`, and
|
|
31
|
+
`arkRunCompositionRootHits`. `1.0`/`1.1` payloads stay loadable (empty
|
|
32
|
+
arrays). Syntax evidence only — sensors consume these in RN04. Absence of
|
|
33
|
+
`arkRun` still leaves Layers / ArkRules verdicts unchanged. Does not close
|
|
34
|
+
Z09 / K01.
|
|
35
|
+
|
|
36
|
+
- **ArkRun tier-1 sensors (RN04):** when `arkRun` is present, closed sensors
|
|
37
|
+
emit `ARKRUN_MISSING_ROOT`, `ARKRUN_KERNEL_IN_DOMAIN`, `ARKRUN_DIRECT_NEW`,
|
|
38
|
+
`ARKRUN_UNDECLARED_EMIT`, `ARKRUN_UNDECLARED_HANDLE`, `ARKRUN_UNDECLARED_DEPEND`,
|
|
39
|
+
and `ARKRUN_TRANSPORT_BYPASS`. Advisory findings never flip `valid`; enforced
|
|
40
|
+
blocks. Absence of the extra is still silent on Layers / ArkRules verdicts.
|
|
41
|
+
Optional `arkRunDeclarations` facts stay additive on schema `1.2`. Dual-depth
|
|
42
|
+
catalog nextAction is RN05 (landed below). Does not close Z09 / K01.
|
|
43
|
+
|
|
44
|
+
- **ArkRun diagnostic catalog dual-depth (RN05):** closed `ARKRUN_*` catalog
|
|
45
|
+
entries have dual-depth remediation: casual `enthusiastHint` plus engineer
|
|
46
|
+
`nextAction` (target interpolates the call-site literal or specifier). Adding
|
|
47
|
+
an existing declaration-list string is `mechanical-safe` (`arkrun-declaration-list`)
|
|
48
|
+
only when that literal is already present; other ArkRun findings stay
|
|
49
|
+
`judgment`. Sensors, adapter fallback, and CLI remediation share
|
|
50
|
+
`deterministicNextAction`. Does not close Z09 / K01.
|
|
51
|
+
|
|
52
|
+
- **ArkRun ESLint envelope (RN06):** `arkgate/eslint` recommended config adds
|
|
53
|
+
`ark/no-arkrun-kernel-in-domain`, `ark/no-arkrun-direct-new`, and
|
|
54
|
+
`ark/no-arkrun-transport-bypass`. Same `ARKRUN_*` sensors as ark-check for
|
|
55
|
+
the import / `new` envelope; silent when `arkRun` is absent. Missing-root and
|
|
56
|
+
undeclared-* stay CLI/MCP/preflight. Does not close Z09 / K01.
|
|
57
|
+
|
|
58
|
+
- **ArkRun extra-teeth parity (RN07):** CLI `--strict-merge`, MCP `ark_check` /
|
|
59
|
+
snippet write, PreToolUse hook, atomic preflight, and CI share one ArkRun
|
|
60
|
+
verdict. Enforced extra teeth arm only when the layer plane is classified
|
|
61
|
+
(same ≥50% governed / ≥1 populated-layer floor as ArkRules); advisory and
|
|
62
|
+
absence stay silent on `valid`. Doctor/status `arkRun` section landed in
|
|
63
|
+
RN08 below. Does not close Z09 / K01.
|
|
64
|
+
|
|
65
|
+
- **ArkRun doctor / status / report (RN08):** `ark-check --doctor`, HTML
|
|
66
|
+
`--report`, and `ark status` / MCP `ark_status` expose an `arkRun` section
|
|
67
|
+
that is always `notAScore`. Residual is a finding-id count, never a score or
|
|
68
|
+
LLM verdict. `mergePlanes.arkRun` states whether the extra can fail merge;
|
|
69
|
+
advisory and absence never arm extra teeth. Report parity requires
|
|
70
|
+
`data-advisory="arkRun"`. Does not close Z09 / K01.
|
|
71
|
+
|
|
72
|
+
- **ArkRun companion branding (RN09):** `@arkgate/runtime` README and public
|
|
73
|
+
docs brand the kernel **ArkRun**. `createStrictArkKernel` stays the factory
|
|
74
|
+
(per-instance; no process-wide singleton). Kernel implementation stays out of
|
|
75
|
+
the `arkgate` tarball. Branding is not a production-durability claim. Does not
|
|
76
|
+
close Z09 / K01.
|
|
77
|
+
|
|
78
|
+
- **ArkRun interaction declarations (RN10):** `@arkgate/runtime` `register()`
|
|
79
|
+
accepts `uses` / `reactsTo` / `raises` / `sends` plus optional tooling-only
|
|
80
|
+
`extendedInfo`. `getDependencyInformationPackage()` returns a JSON-serializable
|
|
81
|
+
snapshot of ids, lifetime, and declarations — never factories, live instances,
|
|
82
|
+
or input DTOs. Companion registrations may omit declarations for local
|
|
83
|
+
experiments; enforced `arkRun` on the gate still requires them. Does not close
|
|
84
|
+
Z09 / K01.
|
|
85
|
+
|
|
86
|
+
- **ArkRun transport ports (RN11):** `@arkgate/runtime` `send()` is one call site
|
|
87
|
+
for `local` / `localBlocking` / `broker`. `ephemeral` defaults true (await local
|
|
88
|
+
recording or adapter accept — not a durability claim). Missing broker adapter
|
|
89
|
+
falls back to in-process local delivery, not cloud portability. No cloud SDKs
|
|
90
|
+
ship in the package. Does not close Z09 / K01.
|
|
91
|
+
|
|
92
|
+
- **ArkRun dev inspector (RN12):** `@arkgate/runtime` `startInspector()` /
|
|
93
|
+
`startArkRunInspector()` is opt-in. Default bind is `127.0.0.1`; `NODE_ENV=production`
|
|
94
|
+
vetoes start; public hosts (`0.0.0.0`, `::`) are rejected. HTTP is lazy-loaded.
|
|
95
|
+
`GET /snapshot` and `GET /events` (SSE) serve the information package plus
|
|
96
|
+
transport facts (no factories, no shipped cloud SDKs). Does not close Z09 / K01.
|
|
97
|
+
|
|
98
|
+
- **ArkRun graph slices (RN13):** `@arkgate/runtime` `requestGraph()` slices the
|
|
99
|
+
information package into `process` (raises / reactsTo / sends) or `technical`
|
|
100
|
+
(`uses`) graphs. Optional `nodeIds`, `degreesOfSeparation`, and include/exclude
|
|
101
|
+
query keep a neighborhood. `formatArkRunGraphMermaid()` / `graph.mermaid` is a
|
|
102
|
+
helper string, never a score. Inspector `GET /graph` serves the same slice.
|
|
103
|
+
Does not close Z09 / K01.
|
|
104
|
+
|
|
105
|
+
- **ArkRun skip corpus (RN14):** `tests/fixtures/arkrun-skip-corpus/` is the
|
|
106
|
+
executable proof: Application `new`, same-layer peer import, and homemade
|
|
107
|
+
`EventEmitter` stay green when `arkRun` is absent (Layers / ArkRules match
|
|
108
|
+
schema `1.1`) and fail write path, CLI, MCP, and `--strict-merge` when the
|
|
109
|
+
extra is enforced. Does not close Z09 / K01.
|
|
110
|
+
|
|
111
|
+
- **ArkRun skill-body deepen (RN15):** `/ark-runtime`, `/ark-place`, and
|
|
112
|
+
`/ark-adopt` teach the extra vs companion (advisory adopt, kernel-only
|
|
113
|
+
scaffold, composition-root wiring). Frozen **13** names — no `/ark-run`.
|
|
114
|
+
Skills never enforce; doctor `arkRun` stays `notAScore`. Agent Skills layout
|
|
115
|
+
stays 1:1 with `templates/skills`. Does not close Z09 / K01.
|
|
116
|
+
|
|
8
117
|
## 4.6.7 — 2026-08-24
|
|
9
118
|
|
|
10
119
|
**Patch** over **4.6.6**. Production-hardening: CODEOWNERS, eval/pack honesty, CLI extracts,
|
package/README.md
CHANGED
|
@@ -16,11 +16,11 @@ and makes sure a “green” check means something real.
|
|
|
16
16
|
|
|
17
17
|
</div>
|
|
18
18
|
|
|
19
|
-
> **ArkGate 4.
|
|
19
|
+
> **ArkGate 4.7.0** is prepared on this tree. **4.6.7** remains npm `latest` until publish.
|
|
20
20
|
> A tree is **adopted** only with a required GitHub status running `arkgate-check --strict-merge`,
|
|
21
21
|
> or `.ark/adoption-stance.json` `stance: "advisory-only"`. Doctor is compact (`--doctor --all`
|
|
22
|
-
> for Details). [4.
|
|
23
|
-
> [Docs hub](docs/README.md) · [Product voice](docs/product-voice.md)
|
|
22
|
+
> for Details). [4.7.0 notes](docs/releases/4.7.0.md) · [4.6.7](docs/releases/4.6.7.md) ·
|
|
23
|
+
> [4.6.6](docs/releases/4.6.6.md) · [Docs hub](docs/README.md) · [Product voice](docs/product-voice.md)
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
@@ -78,11 +78,12 @@ A machine-readable architecture file (`ark.config.json`) plus enforcement:
|
|
|
78
78
|
|-------|----------------|--------|
|
|
79
79
|
| **Layers** (always) | Who may import whom — imports, placement, purity, isolation | `ark.config.json` layers + rules |
|
|
80
80
|
| **ArkRules** (opt-in; structure rules inside a layer) | Habits *inside* a layer — structure sensors + domain invariants as data | `arkRules` → `arkrules/<Layer>.json` |
|
|
81
|
+
| **ArkRun** (opt-in extra) | Kernel usage + complete declarations | `arkRun` on schema `1.2` |
|
|
81
82
|
|
|
82
|
-
Absence of ArkRules changes no inter-layer verdict. Label residual **`[Layer]`** vs **`[ArkRules]`**.
|
|
83
|
-
Details: [configuration](docs/configuration.md
|
|
83
|
+
Absence of ArkRules or ArkRun changes no inter-layer verdict. Label residual **`[Layer]`** vs **`[ArkRules]`**.
|
|
84
|
+
Details: [configuration](docs/configuration.md) · [use path](docs/use.md).
|
|
84
85
|
|
|
85
|
-
**Not** a web framework, ORM, or job runner. Optional
|
|
86
|
+
**Not** a web framework, ORM, or job runner. Optional **ArkRun** extra and companion kernel (`@arkgate/runtime`) are separate and not required for the gate. In-memory stores are not production durability.
|
|
86
87
|
|
|
87
88
|
**Name note:** npm package `arkgate` — not affiliated with the separate Archgate CLI project.
|
|
88
89
|
|
|
@@ -192,9 +193,18 @@ More: [docs/develop.md](docs/develop.md) · skills install: [docs/agent-guide.md
|
|
|
192
193
|
|
|
193
194
|
---
|
|
194
195
|
|
|
195
|
-
## Optional
|
|
196
|
+
## Optional ArkRun kernel
|
|
196
197
|
|
|
197
|
-
Gates need **no** app runtime. The experimental `@arkgate/runtime`
|
|
198
|
+
Gates need **no** app runtime. The experimental **ArkRun** companion (`@arkgate/runtime`) is separate
|
|
199
|
+
and is not a production-readiness claim. `createStrictArkKernel` is the factory: each call creates
|
|
200
|
+
an isolated instance (no process-wide singleton). Managed components declare `uses` / `reactsTo` /
|
|
201
|
+
`raises` / `sends`; `getDependencyInformationPackage()` is a JSON snapshot and never leaks factories.
|
|
202
|
+
`requestGraph()` slices that snapshot into process or technical graphs (`nodeIds`,
|
|
203
|
+
`degreesOfSeparation`, include/exclude query) with a Mermaid helper. `send()` is local /
|
|
204
|
+
localBlocking / broker (broker falls back to in-process local; `ephemeral`
|
|
205
|
+
defaults true; no cloud SDKs in the package). Opt-in `startInspector()` binds `127.0.0.1`,
|
|
206
|
+
refuses `NODE_ENV=production`, and lazy-loads HTTP for JSON snapshots, SSE, and `/graph`. The kernel is
|
|
207
|
+
not bundled in the `arkgate` tarball.
|
|
198
208
|
|
|
199
209
|
### Durability stance
|
|
200
210
|
|
|
@@ -217,7 +227,8 @@ for real systems. Details: [docs/production-hardening.md](docs/production-harden
|
|
|
217
227
|
| Config · package surface · TS | [configuration](docs/configuration.md) · [package-surface](docs/package-surface.md) · [typescript-support](docs/typescript-support.md) |
|
|
218
228
|
| Brownfield | [docs/brownfield-adoption.md](docs/brownfield-adoption.md) |
|
|
219
229
|
| Security | [SECURITY.md](SECURITY.md) |
|
|
220
|
-
| Current
|
|
230
|
+
| Current tree (4.7.0 prepared) | [docs/releases/4.7.0.md](docs/releases/4.7.0.md) · [CHANGELOG](CHANGELOG.md) |
|
|
231
|
+
| Current published (4.6.7 on npm `latest`) | [docs/releases/4.6.7.md](docs/releases/4.6.7.md) |
|
|
221
232
|
| Prior published (4.6.6) | [docs/releases/4.6.6.md](docs/releases/4.6.6.md) |
|
|
222
233
|
| Prior published (4.6.5) | [docs/releases/4.6.5.md](docs/releases/4.6.5.md) |
|
|
223
234
|
| Prior published (4.6.3) | [docs/releases/4.6.3.md](docs/releases/4.6.3.md) |
|
package/SECURITY.md
CHANGED
|
@@ -18,7 +18,7 @@ Preferred path: use GitHub's private vulnerability reporting for this repository
|
|
|
18
18
|
- reproduction steps
|
|
19
19
|
- expected impact
|
|
20
20
|
- whether the issue affects `arkgate-check` / `ark-check`, `arkgate-mcp` / `ark-mcp`,
|
|
21
|
-
generated agent gates, the GitHub Action, or the optional
|
|
21
|
+
generated agent gates, the GitHub Action, or the optional ArkRun kernel
|
|
22
22
|
|
|
23
23
|
If private vulnerability reporting is unavailable, open a minimal public issue asking for
|
|
24
24
|
a private security contact without including exploit details.
|
|
@@ -1471,6 +1471,7 @@ async function main() {
|
|
|
1471
1471
|
score: fitness.score,
|
|
1472
1472
|
mode: fitness.mode,
|
|
1473
1473
|
improvementCompass: reportCompass,
|
|
1474
|
+
arkRun: designDepth?.arkRun ?? null,
|
|
1474
1475
|
}),
|
|
1475
1476
|
leftoverDesignWork: designDepth?.designFitness?.designWeak === true,
|
|
1476
1477
|
};
|
|
@@ -1493,7 +1494,17 @@ async function main() {
|
|
|
1493
1494
|
adoption: adoptionForReport,
|
|
1494
1495
|
designDepth,
|
|
1495
1496
|
advisories: {
|
|
1496
|
-
...computeDoctorAdvisories(
|
|
1497
|
+
...computeDoctorAdvisories(
|
|
1498
|
+
root,
|
|
1499
|
+
config,
|
|
1500
|
+
coverage,
|
|
1501
|
+
rules,
|
|
1502
|
+
files,
|
|
1503
|
+
ts,
|
|
1504
|
+
parseHealth,
|
|
1505
|
+
undefined,
|
|
1506
|
+
activeViolations
|
|
1507
|
+
),
|
|
1497
1508
|
// Doctor parity: always emit improvement compass when doctor would (reportParity).
|
|
1498
1509
|
...(designDepth?.improvementCompass
|
|
1499
1510
|
? { improvementCompass: designDepth.improvementCompass }
|
|
@@ -1502,6 +1513,7 @@ async function main() {
|
|
|
1502
1513
|
...(designDepth?.deepModuleCoach
|
|
1503
1514
|
? { deepModuleCoach: designDepth.deepModuleCoach }
|
|
1504
1515
|
: {}),
|
|
1516
|
+
...(designDepth?.arkRun ? { arkRun: designDepth.arkRun } : {}),
|
|
1505
1517
|
},
|
|
1506
1518
|
};
|
|
1507
1519
|
const html = args.beginner
|
package/bin/ark-mcp-runtime.mjs
CHANGED
|
@@ -308,6 +308,42 @@ function hookEnforcement(root, host, operation, completePatch = false) {
|
|
|
308
308
|
}).enforcementLadder;
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
+
function extraMergeTeethClassification(root, config) {
|
|
312
|
+
const files = collectGovernedFiles(root, config);
|
|
313
|
+
const layers = config.layers ?? [];
|
|
314
|
+
let classified = 0;
|
|
315
|
+
const populated = new Set();
|
|
316
|
+
for (const abs of files) {
|
|
317
|
+
const layer = layerForFile(root, abs, layers);
|
|
318
|
+
if (layer) {
|
|
319
|
+
classified += 1;
|
|
320
|
+
populated.add(layer);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
governedPercent: files.length > 0 ? Math.round((classified / files.length) * 100) : 0,
|
|
325
|
+
populatedLayerCount: populated.size,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function arkRunSnippetContext({ root, config, filePath, layer, relFile, classification }) {
|
|
330
|
+
const extra = config?.arkRun;
|
|
331
|
+
if (!extra) return { layer, filePath };
|
|
332
|
+
const relative =
|
|
333
|
+
relFile ||
|
|
334
|
+
(typeof filePath === 'string'
|
|
335
|
+
? path.relative(root, path.resolve(root, filePath)).split(path.sep).join('/')
|
|
336
|
+
: undefined);
|
|
337
|
+
return {
|
|
338
|
+
layer,
|
|
339
|
+
filePath,
|
|
340
|
+
relFile: relative,
|
|
341
|
+
arkRun: extra,
|
|
342
|
+
layers: config.layers ?? [],
|
|
343
|
+
classification: classification ?? extraMergeTeethClassification(root, config),
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
311
347
|
function designDeltaViolations(delta) {
|
|
312
348
|
return (delta?.changes ?? []).map((change) => ({
|
|
313
349
|
ruleId: 'DESIGN_SMELL_REGRESSION',
|
|
@@ -565,7 +601,18 @@ function runHookPayload(payload, gate, config, args, ts, attemptContext, output
|
|
|
565
601
|
|
|
566
602
|
const layer = inferLayer(filePath, config, args.root);
|
|
567
603
|
const validateOnce = (src) =>
|
|
568
|
-
validateSnippetAnalysis({
|
|
604
|
+
validateSnippetAnalysis({
|
|
605
|
+
gate,
|
|
606
|
+
ts,
|
|
607
|
+
source: src,
|
|
608
|
+
context: arkRunSnippetContext({
|
|
609
|
+
root: args.root,
|
|
610
|
+
config,
|
|
611
|
+
filePath,
|
|
612
|
+
layer,
|
|
613
|
+
relFile: normalizedRel,
|
|
614
|
+
}),
|
|
615
|
+
});
|
|
569
616
|
// W1: one validation pass (+ optional autoPatch). Original write still blocked when
|
|
570
617
|
// invalid; hosts must apply autoPatch explicitly (never silent write).
|
|
571
618
|
const result = ts
|
|
@@ -2136,7 +2183,17 @@ export async function runArkMcp({ hookInput } = {}) {
|
|
|
2136
2183
|
const filePath = params.arguments.filePath;
|
|
2137
2184
|
const layer = params.arguments.layer ?? inferLayer(filePath, config, args.root);
|
|
2138
2185
|
const validateOnce = (src) =>
|
|
2139
|
-
validateSnippetAnalysis({
|
|
2186
|
+
validateSnippetAnalysis({
|
|
2187
|
+
gate,
|
|
2188
|
+
ts,
|
|
2189
|
+
source: src,
|
|
2190
|
+
context: arkRunSnippetContext({
|
|
2191
|
+
root: args.root,
|
|
2192
|
+
config,
|
|
2193
|
+
filePath,
|
|
2194
|
+
layer,
|
|
2195
|
+
}),
|
|
2196
|
+
});
|
|
2140
2197
|
// W1: attempt mechanical-safe single-file autoPatch (import type), re-validate or discard.
|
|
2141
2198
|
const result = validateWithAutoPatch({
|
|
2142
2199
|
source,
|
|
@@ -2429,7 +2486,12 @@ export async function runArkMcp({ hookInput } = {}) {
|
|
|
2429
2486
|
gate,
|
|
2430
2487
|
ts,
|
|
2431
2488
|
source: src,
|
|
2432
|
-
context: {
|
|
2489
|
+
context: arkRunSnippetContext({
|
|
2490
|
+
root: args.root,
|
|
2491
|
+
config,
|
|
2492
|
+
filePath: placement.filePath,
|
|
2493
|
+
layer,
|
|
2494
|
+
}),
|
|
2433
2495
|
});
|
|
2434
2496
|
const result = composePrepareWrite({
|
|
2435
2497
|
source,
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Pure CLI helper (bin/lib/adapter-contract.mjs). Zero Node I/O.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { deterministicNextAction } from './remediation.mjs';
|
|
12
12
|
/** Versioned public result contract shared by every ArkGate enforcement adapter. */
|
|
13
13
|
/**
|
|
14
14
|
* 1.5 adds stable finding refs on every factory-emitted diagnostic (ACS06):
|
|
@@ -77,41 +77,22 @@ export function adapterDocsCodePath(ruleId) {
|
|
|
77
77
|
return `${ADAPTER_DIAGNOSTIC_DOCS_RELATIVE_PATH}#${ruleId}`;
|
|
78
78
|
}
|
|
79
79
|
function nextActionForDiagnostic(ruleId, evidence, violation) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
if (ruleId === 'CAPABILITY_VIOLATION') {
|
|
97
|
-
return `Define a ${text(violation.capability) ?? 'capability'} port in ${evidence.fromLayer ?? 'the walled layer'}, bind the implementation outside it, test at the public interface, then preflight again.`;
|
|
98
|
-
}
|
|
99
|
-
if (ruleId === 'CIRCULAR_DEPENDENCY') {
|
|
100
|
-
return 'Extract the shared dependency into a third module, test at the public interface, then preflight again.';
|
|
101
|
-
}
|
|
102
|
-
if (ruleId === 'RAW_EVENT_PUBLISH')
|
|
103
|
-
return 'Publish through a registered intent creator, then run Ark again.';
|
|
104
|
-
if (ruleId === 'PUBLISH_MISSING_SOURCE')
|
|
105
|
-
return 'Add metadata.source to the publish call, then run Ark again.';
|
|
106
|
-
if (ruleId === 'ARKRULE_STRUCTURE' ||
|
|
107
|
-
ruleId === 'ARKRULE_INVARIANT' ||
|
|
108
|
-
ruleId === 'INVARIANT_UNCOVERED' ||
|
|
109
|
-
ruleId.startsWith('ARKRULE_')) {
|
|
110
|
-
const source = evidence.arkruleSource ?? 'arkrules/<Layer>.json';
|
|
111
|
-
const id = evidence.arkruleId ?? 'the ArkRule';
|
|
112
|
-
return `Fix the structure or invariant for ${id} (declared in ${source}), then preflight again. Do not demote the rule without a hash-bound policy acknowledgement.`;
|
|
113
|
-
}
|
|
114
|
-
return `Resolve ${ruleId} without weakening ark.config.json, then run Ark again.`;
|
|
80
|
+
return deterministicNextAction({
|
|
81
|
+
ruleId,
|
|
82
|
+
target: text(evidence.target) ?? text(violation.target) ?? undefined,
|
|
83
|
+
fromLayer: text(evidence.fromLayer) ?? undefined,
|
|
84
|
+
toLayer: text(evidence.toLayer) ?? undefined,
|
|
85
|
+
typeOnly: evidence.typeOnly === true,
|
|
86
|
+
targetTypeOnlyExports: evidence.targetTypeOnlyExports === true,
|
|
87
|
+
namedBindingsTypeOnly: evidence.namedBindingsTypeOnly === true,
|
|
88
|
+
portProofEligible: evidence.portProofEligible === true,
|
|
89
|
+
peerIsolation: evidence.peerIsolation === true,
|
|
90
|
+
sourcePureTypeModule: evidence.sourcePureTypeModule === true,
|
|
91
|
+
edgeKind: text(evidence.edgeKind) ?? undefined,
|
|
92
|
+
capability: text(evidence.capability) ?? text(violation.capability) ?? undefined,
|
|
93
|
+
arkruleId: text(evidence.arkruleId) ?? undefined,
|
|
94
|
+
arkruleSource: text(evidence.arkruleSource) ?? undefined,
|
|
95
|
+
});
|
|
115
96
|
}
|
|
116
97
|
export function toAdapterDiagnostic(violation, fallbackSeverity = 'error',
|
|
117
98
|
/**
|