arkgate 3.6.0 → 3.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 +69 -0
- package/README.md +4 -5
- package/bin/ark-check.mjs +3 -3
- package/bin/ark-layer-match.mjs +2 -1
- package/bin/ark.mjs +2 -2
- package/bin/lib/agent-gates.mjs +2 -0
- package/bin/lib/analysis-engine.mjs +6 -6
- package/bin/lib/architecture-scan.mjs +66 -13
- package/bin/lib/ci-and-commands.mjs +5 -8
- package/bin/lib/codex-home.mjs +21 -6
- package/bin/lib/design-smells.mjs +67 -14
- package/bin/lib/doctor-advisories.mjs +20 -5
- package/bin/lib/doctor-plan.mjs +5 -7
- package/bin/lib/gate-files.mjs +1 -1
- package/bin/lib/hook-templates.mjs +21 -1
- package/bin/lib/html-report-advisories.mjs +59 -0
- package/bin/lib/install-migrate.mjs +26 -11
- package/bin/lib/mcp-adoption.mjs +21 -4
- package/bin/lib/parse-health.mjs +74 -0
- package/bin/lib/reshape-decisions.mjs +284 -0
- package/bin/lib/ts-resolve.mjs +3 -2
- package/bin/lib/write-path-capabilities.mjs +6 -0
- package/dist/eslint/index.cjs +2 -2
- package/dist/eslint/index.js +2 -2
- package/dist/index.cjs +7 -7
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -6
- package/docs/agent-guide.md +34 -3
- package/docs/ai-gates.md +21 -18
- package/docs/configuration.md +6 -0
- package/docs/enthusiast/how-to-agent-gates.md +1 -1
- package/docs/package-surface.md +6 -5
- package/docs/typescript-support.md +9 -0
- package/package.json +2 -1
- package/server.json +2 -2
- package/templates/skills/ark-autopilot.md +12 -0
- package/templates/skills/ark-explore.md +8 -1
- package/templates/skills/ark-fix.md +11 -1
- package/templates/skills/ark-loop.md +14 -1
|
@@ -153,6 +153,15 @@ parameters, and imports shadow ambient names; aliases such as `const Clock = Dat
|
|
|
153
153
|
module paths then uses the nearest tsconfig/jsconfig compiler options, including path aliases,
|
|
154
154
|
project-local packages, workspaces, and symlinked workspace entries.
|
|
155
155
|
|
|
156
|
+
`forbiddenGlobals: ["process"]` also owns the exact runtime module spellings `process` and
|
|
157
|
+
`node:process`. They report `FORBIDDEN_GLOBAL` with import-form evidence across the CLI, pure IR,
|
|
158
|
+
atomic preflight, MCP/AICodeGate, and ESLint. This is an exact dual, not a process-capability wall:
|
|
159
|
+
`node:process/subpath`, `child_process`, and `node:child_process` do not match. `import type` and
|
|
160
|
+
`export type` declarations are erased and do not produce this finding on any path. The
|
|
161
|
+
symbol-aware CLI/hook/AICodeGate path and ESLint also recognize all-type named lists; the
|
|
162
|
+
compiler-free pure IR retains its documented conservative treatment of those lists as value
|
|
163
|
+
imports.
|
|
164
|
+
|
|
156
165
|
ArkGate intentionally does not claim soundness for runtime-generated module names, `eval`, custom
|
|
157
166
|
loader functions, proxy-based globals, dynamically computed property keys, or aliases mutated
|
|
158
167
|
after declaration. Those constructs must remain absent from governed pure layers or be handled by
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arkgate",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.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",
|
|
@@ -106,6 +106,7 @@
|
|
|
106
106
|
"eval:loop-cost": "node eval/loop-cost-run.mjs",
|
|
107
107
|
"eval:ai-velocity": "node eval/ai-velocity-run.mjs",
|
|
108
108
|
"eval:change-integrity": "node eval/change-integrity-run.mjs",
|
|
109
|
+
"eval:mechanical-edit-hygiene": "node eval/mechanical-edit-hygiene-run.mjs",
|
|
109
110
|
"eval:adoption": "node eval/adoption-run.mjs",
|
|
110
111
|
"test:adoption-harness": "vitest run tests/unit/eval/adoptionHarness.test.ts",
|
|
111
112
|
"bench:scale": "node scripts/ark-scale-bench.mjs",
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/pedroknigge/arkgate",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "3.
|
|
9
|
+
"version": "3.7.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "arkgate",
|
|
14
|
-
"version": "3.
|
|
14
|
+
"version": "3.7.0",
|
|
15
15
|
"runtimeHint": "npx",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
@@ -54,6 +54,11 @@ decision-grade explore pass **and** without opening violating files.
|
|
|
54
54
|
7. **Q04 pilot loop for B:** when design-weak, take **`pilotLoop.nextPilot`** (one extraction card)
|
|
55
55
|
→ apply **only** that pilot with user OK → **re-doctor**. Never multi-pilot batch B; residual
|
|
56
56
|
outside the pilot may remain and must not be called “healthy finished.”
|
|
57
|
+
8. **Y01 reshape verdicts:** read `doctor.physicalCohesion.reshapeDecisions` before acting on
|
|
58
|
+
mirror facts. Outcome first: a current rejected/deferred verdict means “intentional/deferred
|
|
59
|
+
layout — no pilot”; never reconstruct that dead card from `findings`. When the user accepts,
|
|
60
|
+
defers, or rejects a live card, persist its exact `decisionTarget` with a non-empty reason and
|
|
61
|
+
optional `reviewBy` in `.ark/reshape-decisions.json`; never infer a verdict from golden prose.
|
|
57
62
|
|
|
58
63
|
|
|
59
64
|
## Subagent fan-out (optional, host-dependent)
|
|
@@ -147,6 +152,13 @@ repo so the next agent session continues the same pilot — still never auto-app
|
|
|
147
152
|
populated cores are `optional: true`, run `ark-check --ratchet-cores` then `--doctor`.
|
|
148
153
|
Never ratchet while active violations remain or false-green gap is open.
|
|
149
154
|
|
|
155
|
+
## Mechanical-edit hygiene (Y04 — outcome gate)
|
|
156
|
+
|
|
157
|
+
- Header injection must **merge into the existing doc comment**; the kept result has one `/**`, not stacked headers.
|
|
158
|
+
- Route completion or movement must **preserve the original typed `defineRoute<…>(opts, handler)` call**; reconstruct that call instead of extracting untyped opts/handler constants that drop generics or contextual typing.
|
|
159
|
+
- A convention-only `*-data.ts` stub is not a fix: move the real code or **leave the placeholder file uncreated**; never write `import "server-only"; export {}` as an empty naming token.
|
|
160
|
+
- Keep the edit only when the **previously clean file stays typecheck-clean**. Otherwise roll it back and treat the change as judgment.
|
|
161
|
+
|
|
150
162
|
## Never
|
|
151
163
|
|
|
152
164
|
- Disable rules, broaden allows, or baseline **new** debt to “finish”.
|
|
@@ -123,6 +123,7 @@ Useful split: **core product tree** | **field path** (`examples/`, starters) | *
|
|
|
123
123
|
6. **§G spaghetti / design-depth** when signals fire (or always on brownfield).
|
|
124
124
|
7. Ranked rows that **change a decision**; each bet has a **success signal** (not a file count).
|
|
125
125
|
8. Hard lines: never weaken the contract; never invent mechanical-safe kinds; never claim ENFORCE from type-only cleanup while false-green doctor ids are active.
|
|
126
|
+
9. **Parse honesty:** if `doctor.parseHealth.affectedFiles > 0`, open and name those paths; never describe them as clean or successfully inspected. The advisory does not change the gate verdict.
|
|
126
127
|
|
|
127
128
|
## Reconnaissance pass (do all that apply)
|
|
128
129
|
|
|
@@ -150,6 +151,12 @@ Useful split: **core product tree** | **field path** (`examples/`, starters) | *
|
|
|
150
151
|
|
|
151
152
|
Mark the **golden** pattern to copy. Do not only list layer file counts.
|
|
152
153
|
|
|
154
|
+
When `doctor.physicalCohesion` includes `reshapeDecisions`, treat current rejected/deferred
|
|
155
|
+
targets as explicit adopter decisions, not residual to re-fight. Keep their mirror facts in the
|
|
156
|
+
map. When the user accepts, defers, or rejects a live `reshapePilot.nextPilot`, record the card's
|
|
157
|
+
exact `decisionTarget` with a reason (and optional `reviewBy`) in
|
|
158
|
+
`.ark/reshape-decisions.json`. Never infer or suppress from free-form golden-pattern prose.
|
|
159
|
+
|
|
153
160
|
### C. Coupling & debt (measure, don’t guess)
|
|
154
161
|
Prefer evidence over aesthetics:
|
|
155
162
|
- **Fan-in / importers** of hot modules (who imports the suspect file?).
|
|
@@ -215,7 +222,7 @@ ENFORCE without Shape progress is **`ENFORCE · design-weak`** — say that out
|
|
|
215
222
|
| Smell id (label) | How you detect it in source |
|
|
216
223
|
|------------------|-----------------------------|
|
|
217
224
|
| `io-under-application` | I/O clients under Application; empty Domain/Persistence (also doctor when present) |
|
|
218
|
-
| `handler-in-persistence` | HTTP
|
|
225
|
+
| `handler-in-persistence` | Static framework HTTP imports, `defineRoute` calls, or route bodies under Persistence-role repo/db globs (first 800 sorted candidates; no advisory is not whole-tree proof above that bound) |
|
|
219
226
|
| `god-module` | High fan-in + wide export surface + mixed concerns |
|
|
220
227
|
| `domain-logic-in-ui` | `can*` / `calculate*` / policy constants in hooks/pages |
|
|
221
228
|
| `mixed-pattern-cluster` | Same feature area uses ≥2 incompatible layouts |
|
|
@@ -105,12 +105,22 @@ If the “fix” is really a missing business intent or Domain home for a rule:
|
|
|
105
105
|
- Prefer mechanical-safe kinds when the plan tags them; otherwise design judgment carefully.
|
|
106
106
|
- Code only — no DB migrations unless user asked.
|
|
107
107
|
|
|
108
|
+
## Mechanical-edit hygiene (Y04 — outcome gate)
|
|
109
|
+
|
|
110
|
+
- Header injection must **merge into the existing doc comment**; the kept result has one `/**`, not stacked headers.
|
|
111
|
+
- Route completion or movement must **preserve the original typed `defineRoute<…>(opts, handler)` call**; reconstruct that call instead of extracting untyped opts/handler constants that drop generics or contextual typing.
|
|
112
|
+
- A convention-only `*-data.ts` stub is not a fix: move the real code or **leave the placeholder file uncreated**; never write `import "server-only"; export {}` as an empty naming token.
|
|
113
|
+
- Keep the edit only when the **previously clean file stays typecheck-clean**. Otherwise roll it back and treat the change as judgment.
|
|
114
|
+
|
|
108
115
|
## Reshape findings (X04 — never mechanical)
|
|
109
116
|
|
|
110
117
|
If `doctor.physicalCohesion` fires while you fix: do **not** fold reshape moves into your fix
|
|
111
118
|
batch. Physical moves run only through `/ark-loop`'s one-pilot loop; merge decisions only as
|
|
112
119
|
`/ark-architect` merge cards. A cohesion finding is context for your fix, never a license to
|
|
113
|
-
reorganize.
|
|
120
|
+
reorganize. Respect `physicalCohesion.reshapeDecisions`: never revive a current rejected/deferred
|
|
121
|
+
target from the still-visible facts. If the user makes a verdict while reviewing the finding,
|
|
122
|
+
record its exact `decisionTarget` + reason in `.ark/reshape-decisions.json`; never infer one from
|
|
123
|
+
golden-pattern prose.
|
|
114
124
|
|
|
115
125
|
## Done
|
|
116
126
|
|
|
@@ -82,12 +82,21 @@ feature dirs, plan clusters), you **may** dispatch **subagents**:
|
|
|
82
82
|
|
|
83
83
|
Never auto: free value uses of imports, multi-import files, dynamic import/require, forbidden globals, cycles, port-proof inject, multi-file adapter scaffolding without proof.
|
|
84
84
|
|
|
85
|
+
## Mechanical-edit hygiene (Y04 — outcome gate)
|
|
86
|
+
|
|
87
|
+
- Header injection must **merge into the existing doc comment**; the kept result has one `/**`, not stacked headers.
|
|
88
|
+
- Route completion or movement must **preserve the original typed `defineRoute<…>(opts, handler)` call**; reconstruct that call instead of extracting untyped opts/handler constants that drop generics or contextual typing.
|
|
89
|
+
- A convention-only `*-data.ts` stub is not a fix: move the real code or **leave the placeholder file uncreated**; never write `import "server-only"; export {}` as an empty naming token.
|
|
90
|
+
- Keep the edit only when the **previously clean file stays typecheck-clean**. Otherwise roll it back and treat the change as judgment.
|
|
91
|
+
|
|
85
92
|
## Reshape pilots (X04 — physical cohesion, advisory)
|
|
86
93
|
|
|
87
94
|
When `ark-check --doctor --json` carries `doctor.physicalCohesion.reshapePilot.nextPilot`,
|
|
88
95
|
you may run **that one pilot** — never more:
|
|
89
96
|
|
|
90
|
-
1. Read
|
|
97
|
+
1. Read `physicalCohesion.reshapeDecisions` first. A current rejected/deferred target has no live
|
|
98
|
+
card: respect the explicit record and do not reconstruct it from raw facts. Read a live card's
|
|
99
|
+
`pilotTarget`, `decisionTarget`, `moveSample`/`movesTotal`, `successSignal`, `killSwitch`, `doNot[]`.
|
|
91
100
|
2. Moves are **proposed only** — enumerate the full move set for the pilot anchor, express it as
|
|
92
101
|
an architecture change map, and validate through the atomic preflight (`ark_prepare_change` /
|
|
93
102
|
the write gate) **before** any file moves. A move the preflight rejects is a finding, not a
|
|
@@ -97,6 +106,10 @@ you may run **that one pilot** — never more:
|
|
|
97
106
|
4. After the move set: full gate re-run + re-doctor. Success = the concept's cluster count drops
|
|
98
107
|
and the verdict stays green; otherwise use the kill switch (revert the move set, nothing else).
|
|
99
108
|
5. Re-doctor decides whether a next card exists. One pilot per loop iteration, always.
|
|
109
|
+
6. If the user accepts, defers, or rejects the target, persist that explicit verdict in
|
|
110
|
+
`.ark/reshape-decisions.json` using the card's exact `decisionTarget`, a reason, and optional
|
|
111
|
+
`reviewBy`. `accepted` keeps this execution path; `deferred`/`rejected` stop repeat pressure.
|
|
112
|
+
Never infer a decision from `.ark/golden-pattern.json` prose.
|
|
100
113
|
|
|
101
114
|
## Steps
|
|
102
115
|
|