arkgate 3.6.1 → 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 (83) hide show
  1. package/CHANGELOG.md +122 -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-layer-match.mjs +2 -1
  6. package/bin/ark-mcp-runtime.mjs +1976 -0
  7. package/bin/ark-mcp.mjs +84 -1495
  8. package/bin/ark-shared.mjs +34 -38
  9. package/bin/ark.mjs +33 -66
  10. package/bin/lib/adapter-contract.mjs +161 -9
  11. package/bin/lib/agent-gates.mjs +1 -0
  12. package/bin/lib/analysis-completeness.mjs +28 -0
  13. package/bin/lib/analysis-engine.mjs +8 -8
  14. package/bin/lib/analysis-policy.mjs +27 -0
  15. package/bin/lib/architecture-scan.mjs +70 -304
  16. package/bin/lib/auto-patch.mjs +76 -8
  17. package/bin/lib/ci-and-commands.mjs +1 -1
  18. package/bin/lib/codex-home.mjs +43 -16
  19. package/bin/lib/design-delta.mjs +4 -0
  20. package/bin/lib/design-smells.mjs +67 -14
  21. package/bin/lib/doctor-advisories.mjs +23 -7
  22. package/bin/lib/doctor-plan.mjs +44 -47
  23. package/bin/lib/enforcement-state.mjs +2 -0
  24. package/bin/lib/github-enforcement.mjs +443 -0
  25. package/bin/lib/hook-templates.mjs +12 -148
  26. package/bin/lib/html-report-advisories.mjs +59 -0
  27. package/bin/lib/html-report-depth.mjs +9 -0
  28. package/bin/lib/html-report.mjs +5 -5
  29. package/bin/lib/install-migrate.mjs +83 -79
  30. package/bin/lib/managed-upgrade.mjs +622 -0
  31. package/bin/lib/mcp-adoption.mjs +3 -1
  32. package/bin/lib/parse-health.mjs +75 -0
  33. package/bin/lib/port-proof.mjs +2 -2
  34. package/bin/lib/prepare-change.mjs +68 -38
  35. package/bin/lib/prepare-write.mjs +7 -1
  36. package/bin/lib/reshape-decisions.mjs +284 -0
  37. package/bin/lib/resident-doctor-client.mjs +55 -0
  38. package/bin/lib/resident-hook.mjs +247 -0
  39. package/bin/lib/resolved-candidate-facts.mjs +1160 -0
  40. package/bin/lib/scan-files.mjs +19 -6
  41. package/bin/lib/snippet-analysis.mjs +119 -0
  42. package/bin/lib/source-policy.mjs +24 -0
  43. package/bin/lib/typescript-host.mjs +15 -18
  44. package/bin/lib/unavailable-analysis.mjs +76 -0
  45. package/bin/lib/upgrade-command.mjs +115 -0
  46. package/bin/lib/weakest-link.mjs +21 -179
  47. package/bin/lib/write-path-capabilities.mjs +167 -16
  48. package/bin/lib/write-path-detect.mjs +3 -2
  49. package/dist/eslint/index.cjs +3 -3
  50. package/dist/eslint/index.d.ts +3 -0
  51. package/dist/eslint/index.js +3 -3
  52. package/dist/index.cjs +7 -7
  53. package/dist/index.d.ts +1073 -141
  54. package/dist/index.js +7 -7
  55. package/docs/agent-guide.md +127 -52
  56. package/docs/ai-gates.md +100 -18
  57. package/docs/configuration.md +6 -0
  58. package/docs/demos/01-write-gate-self-correction.md +2 -2
  59. package/docs/enthusiast/README.md +10 -10
  60. package/docs/enthusiast/how-to-gallery-starter.md +2 -2
  61. package/docs/enthusiast/reference-commands.md +18 -1
  62. package/docs/enthusiast/tutorial-first-project.md +2 -2
  63. package/docs/package-surface.md +101 -14
  64. package/docs/typescript-support.md +118 -37
  65. package/package.json +33 -4
  66. package/schemas/ark.analysis-result.schema.json +159 -2
  67. package/schemas/ark.design-delta.schema.json +1 -0
  68. package/schemas/ark.enforcement-state.schema.json +84 -0
  69. package/schemas/ark.resolved-candidate-facts.schema.json +1 -0
  70. package/server.json +2 -2
  71. package/templates/skills/ark-autopilot.md +12 -0
  72. package/templates/skills/ark-explore.md +12 -5
  73. package/templates/skills/ark-fix.md +12 -2
  74. package/templates/skills/ark-loop.md +14 -1
  75. package/templates/skills/ark-runtime.md +15 -8
  76. package/templates/skills/ark-upgrade.md +122 -182
  77. package/bin/lib/ai-velocity.mjs +0 -293
  78. package/bin/lib/graph-cycles.mjs +0 -6
  79. package/bin/lib/safety-diagnostics.mjs +0 -284
  80. package/bin/lib/ts-resolve.mjs +0 -227
  81. package/dist/configTypes-DAPvBqK6.d.cts +0 -61
  82. package/dist/eslint/index.d.cts +0 -146
  83. package/dist/index.d.cts +0 -986
@@ -1,21 +1,155 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://unpkg.com/arkgate@2/schemas/ark.analysis-result.schema.json",
3
+ "$id": "https://unpkg.com/arkgate@3/schemas/ark.analysis-result.schema.json",
4
4
  "title": "ArkGate analysis result",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": [
8
8
  "schemaVersion",
9
+ "mode",
9
10
  "valid",
11
+ "completeness",
12
+ "completenessReasons",
10
13
  "diagnostics"
11
14
  ],
15
+ "allOf": [
16
+ {
17
+ "if": {
18
+ "properties": {
19
+ "completeness": {
20
+ "enum": [
21
+ "partial",
22
+ "unavailable"
23
+ ]
24
+ }
25
+ },
26
+ "required": [
27
+ "completeness"
28
+ ]
29
+ },
30
+ "then": {
31
+ "properties": {
32
+ "valid": {
33
+ "const": false
34
+ }
35
+ }
36
+ }
37
+ },
38
+ {
39
+ "if": {
40
+ "properties": {
41
+ "mode": {
42
+ "const": "resolved-candidate-facts"
43
+ },
44
+ "completeness": {
45
+ "enum": [
46
+ "complete",
47
+ "partial"
48
+ ]
49
+ }
50
+ },
51
+ "required": [
52
+ "mode",
53
+ "completeness"
54
+ ]
55
+ },
56
+ "then": {
57
+ "required": [
58
+ "policyHash",
59
+ "resolverIdentity",
60
+ "factsHash",
61
+ "candidateTreeHash"
62
+ ]
63
+ }
64
+ },
65
+ {
66
+ "if": {
67
+ "properties": {
68
+ "completeness": {
69
+ "const": "complete"
70
+ }
71
+ },
72
+ "required": [
73
+ "completeness"
74
+ ]
75
+ },
76
+ "then": {
77
+ "properties": {
78
+ "completenessReasons": {
79
+ "maxItems": 0
80
+ }
81
+ }
82
+ },
83
+ "else": {
84
+ "properties": {
85
+ "completenessReasons": {
86
+ "minItems": 1
87
+ }
88
+ }
89
+ }
90
+ }
91
+ ],
12
92
  "properties": {
13
93
  "schemaVersion": {
14
- "const": "1.1"
94
+ "const": "1.3"
95
+ },
96
+ "mode": {
97
+ "enum": [
98
+ "lexical-compatibility",
99
+ "resolved-candidate-facts"
100
+ ]
15
101
  },
16
102
  "valid": {
17
103
  "type": "boolean"
18
104
  },
105
+ "completeness": {
106
+ "enum": [
107
+ "complete",
108
+ "partial",
109
+ "unavailable"
110
+ ]
111
+ },
112
+ "completenessReasons": {
113
+ "type": "array",
114
+ "items": {
115
+ "type": "object",
116
+ "additionalProperties": false,
117
+ "required": [
118
+ "code",
119
+ "message"
120
+ ],
121
+ "properties": {
122
+ "code": {
123
+ "type": "string",
124
+ "minLength": 1
125
+ },
126
+ "message": {
127
+ "type": "string",
128
+ "minLength": 1
129
+ },
130
+ "file": {
131
+ "type": "string",
132
+ "minLength": 1
133
+ }
134
+ }
135
+ }
136
+ },
137
+ "policyHash": {
138
+ "type": "string",
139
+ "minLength": 1
140
+ },
141
+ "resolverIdentity": {
142
+ "type": "string",
143
+ "minLength": 1
144
+ },
145
+ "factsHash": {
146
+ "type": "string",
147
+ "minLength": 1
148
+ },
149
+ "candidateTreeHash": {
150
+ "type": "string",
151
+ "minLength": 1
152
+ },
19
153
  "diagnostics": {
20
154
  "type": "array",
21
155
  "items": {
@@ -81,6 +215,29 @@
81
215
  },
82
216
  "typeOnly": {
83
217
  "type": "boolean"
218
+ },
219
+ "targetTypeOnlyExports": {
220
+ "type": "boolean"
221
+ },
222
+ "sourcePureTypeModule": {
223
+ "type": "boolean"
224
+ },
225
+ "namedBindingsTypeOnly": {
226
+ "type": "boolean"
227
+ },
228
+ "portProofEligible": {
229
+ "type": "boolean"
230
+ },
231
+ "peerIsolation": {
232
+ "type": "boolean"
233
+ },
234
+ "capability": {
235
+ "type": "string",
236
+ "minLength": 1
237
+ },
238
+ "edgeKind": {
239
+ "type": "string",
240
+ "minLength": 1
84
241
  }
85
242
  }
86
243
  },
@@ -0,0 +1 @@
1
+ {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://unpkg.com/arkgate@3/schemas/ark.design-delta.schema.json","title":"ArkGate design delta","type":"object","additionalProperties":false,"required":["schemaVersion","mode","complete","valid","base","candidate","supportedSmellIds","touchedPaths","changes","baseFindingCount","candidateFindingCount","historicalResidualCount"],"properties":{"schemaVersion":{"const":"1.0"},"mode":{"enum":["git-base","write-candidate"]},"complete":{"type":"boolean"},"valid":{"type":"boolean"},"base":{"$ref":"#/$defs/identity"},"candidate":{"$ref":"#/$defs/identity"},"supportedSmellIds":{"type":"array","items":{"const":"domain-logic-in-ui"},"minItems":1,"uniqueItems":true},"touchedPaths":{"type":"array","items":{"type":"string","minLength":1},"uniqueItems":true},"changes":{"type":"array","items":{"$ref":"#/$defs/change"}},"baseFindingCount":{"type":"integer","minimum":0},"candidateFindingCount":{"type":"integer","minimum":0},"historicalResidualCount":{"type":"integer","minimum":0},"error":{"type":"string","minLength":1}},"$defs":{"identity":{"type":"object","additionalProperties":false,"required":["kind","value"],"properties":{"kind":{"enum":["git-tree","candidate-tree"]},"value":{"type":"string","minLength":1},"commit":{"type":"string","minLength":1}}},"evidence":{"type":"object","additionalProperties":false,"required":["kind","path","magnitude"],"properties":{"kind":{"type":"string","minLength":1},"path":{"type":"string","minLength":1},"line":{"type":"integer","minimum":1},"symbol":{"type":"string","minLength":1},"detail":{"type":"string","minLength":1},"magnitude":{"type":"number","minimum":0}}},"finding":{"type":"object","required":["smellId","fingerprint","identity","evidence","repairHint"],"properties":{"smellId":{"enum":["io-under-application","handler-in-persistence","god-module","domain-logic-in-ui","facade-sql-in-routes","mixed-pattern-cluster","soft-contract"]},"fingerprint":{"type":"string","pattern":"^sha256:[a-f0-9]{64}$"},"identity":{"type":"string","minLength":1},"evidence":{"$ref":"#/$defs/evidence"},"repairHint":{"type":"string","minLength":1}}},"change":{"type":"object","unevaluatedProperties":false,"allOf":[{"$ref":"#/$defs/finding"},{"type":"object","required":["classification","baseMagnitude","candidateMagnitude"],"properties":{"classification":{"enum":["new","worsened"]},"baseMagnitude":{"type":"number","minimum":0},"candidateMagnitude":{"type":"number","minimum":0}}}]}}}
@@ -0,0 +1,84 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://unpkg.com/arkgate@3/schemas/ark.enforcement-state.schema.json",
4
+ "title": "ArkGate enforcement state",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "activeHost",
10
+ "localWrite",
11
+ "advisoryMcp",
12
+ "ciMerge"
13
+ ],
14
+ "properties": {
15
+ "schemaVersion": { "const": "1.1" },
16
+ "activeHost": {
17
+ "enum": ["claude", "grok", "cursor", "codex", "unknown"]
18
+ },
19
+ "localWrite": { "$ref": "#/$defs/boundary" },
20
+ "advisoryMcp": { "$ref": "#/$defs/boundary" },
21
+ "ciMerge": { "$ref": "#/$defs/boundary" }
22
+ },
23
+ "$defs": {
24
+ "verification": {
25
+ "anyOf": [{ "type": "boolean" }, { "const": "unverified" }]
26
+ },
27
+ "evidence": {
28
+ "type": "object",
29
+ "additionalProperties": false,
30
+ "required": ["field", "source", "value"],
31
+ "properties": {
32
+ "field": {
33
+ "enum": ["configured", "installed", "active", "runtimeObserved", "operationCoverage", "bypassable", "required", "hard"]
34
+ },
35
+ "source": { "type": "string", "minLength": 1 },
36
+ "value": { "$ref": "#/$defs/verification" }
37
+ },
38
+ "allOf": [
39
+ {
40
+ "if": {
41
+ "properties": { "field": { "enum": ["configured", "installed", "runtimeObserved", "hard"] } },
42
+ "required": ["field"]
43
+ },
44
+ "then": { "properties": { "value": { "type": "boolean" } } }
45
+ }
46
+ ]
47
+ },
48
+ "boundary": {
49
+ "type": "object",
50
+ "additionalProperties": false,
51
+ "required": [
52
+ "supported",
53
+ "analyzed",
54
+ "configured",
55
+ "installed",
56
+ "active",
57
+ "runtimeObserved",
58
+ "operation",
59
+ "operationCoverage",
60
+ "bypassable",
61
+ "required",
62
+ "hard",
63
+ "evidence"
64
+ ],
65
+ "properties": {
66
+ "supported": { "type": "boolean" },
67
+ "analyzed": { "type": "boolean" },
68
+ "configured": { "type": "boolean" },
69
+ "installed": { "type": "boolean" },
70
+ "active": { "$ref": "#/$defs/verification" },
71
+ "runtimeObserved": { "type": "boolean" },
72
+ "operation": { "type": ["string", "null"] },
73
+ "operationCoverage": { "$ref": "#/$defs/verification" },
74
+ "bypassable": { "$ref": "#/$defs/verification" },
75
+ "required": { "$ref": "#/$defs/verification" },
76
+ "hard": { "type": "boolean" },
77
+ "evidence": {
78
+ "type": "array",
79
+ "items": { "$ref": "#/$defs/evidence" }
80
+ }
81
+ }
82
+ }
83
+ }
84
+ }
@@ -0,0 +1 @@
1
+ {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://unpkg.com/arkgate@3/schemas/ark.resolved-candidate-facts.schema.json","title":"ArkGate resolved candidate facts","type":"object","additionalProperties":false,"required":["schemaVersion","completeness","completenessReasons","resolverIdentity","compilerIdentity","compilerOptionsHash","tsconfigHash","candidateTreeHash","evidenceRequirementsHash","files","dependencies","capabilityUses","ambientUses","publishCalls","intentReferences","safetyUses","factsHash"],"properties":{"schemaVersion":{"const":"1.0"},"completeness":{"enum":["complete","partial","unavailable"]},"completenessReasons":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["code","message"],"properties":{"code":{"type":"string","minLength":1},"message":{"type":"string","minLength":1},"file":{"type":"string","minLength":1,"pattern":"^(?!/)(?![A-Za-z]:/)(?!.*\\\\)(?!.*//)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*[\\u0000-\\u001f\\u007f])(?!.*\\/$).+$"}}}},"resolverIdentity":{"type":"string","minLength":1},"compilerIdentity":{"type":"string","minLength":1},"compilerOptionsHash":{"type":"string","minLength":1},"tsconfigHash":{"type":"string","minLength":1},"candidateTreeHash":{"type":"string","minLength":1},"evidenceRequirementsHash":{"type":"string","minLength":1},"projectPackageName":{"type":"string","minLength":1},"files":{"type":"array","uniqueItems":true,"items":{"type":"object","additionalProperties":false,"required":["path","contentHash","parseStatus","parseDiagnosticCount","exportsOnlyTypes","typeOnlyExportNames","hasTopLevelSideEffects"],"properties":{"path":{"type":"string","minLength":1,"pattern":"^(?!/)(?![A-Za-z]:/)(?!.*\\\\)(?!.*//)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*[\\u0000-\\u001f\\u007f])(?!.*\\/$).+$"},"contentHash":{"type":"string","minLength":1},"parseStatus":{"enum":["parsed","invalid"]},"parseDiagnosticCount":{"type":"integer","minimum":0},"exportsOnlyTypes":{"type":"boolean"},"typeOnlyExportNames":{"type":"array","items":{"type":"string","minLength":1}},"hasTopLevelSideEffects":{"type":"boolean"}},"allOf":[{"if":{"properties":{"parseStatus":{"const":"parsed"}}},"then":{"properties":{"parseDiagnosticCount":{"const":0}}}},{"if":{"properties":{"parseStatus":{"const":"invalid"}}},"then":{"properties":{"parseDiagnosticCount":{"minimum":1}}}}]}},"dependencies":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["from","kind","typeOnly","line","resolution"],"properties":{"from":{"type":"string","minLength":1,"pattern":"^(?!/)(?![A-Za-z]:/)(?!.*\\\\)(?!.*//)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*[\\u0000-\\u001f\\u007f])(?!.*\\/$).+$"},"specifier":{"type":"string","minLength":1},"kind":{"enum":["import","export","dynamic-import","require"]},"typeOnly":{"type":"boolean"},"line":{"type":"integer","minimum":1},"resolution":{"enum":["resolved-project","resolved-external","unresolved","dynamic"]},"target":{"type":"string","minLength":1,"pattern":"^(?!/)(?![A-Za-z]:/)(?!.*\\\\)(?!.*//)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*[\\u0000-\\u001f\\u007f])(?!.*\\/$).+$"},"namedBindings":{"type":"array","items":{"type":"string","minLength":1}},"targetTypeOnlyExports":{"type":"boolean"},"sourcePureTypeModule":{"type":"boolean"},"namedBindingsTypeOnly":{"type":"boolean"},"portProofEligible":{"type":"boolean"}},"allOf":[{"if":{"properties":{"resolution":{"const":"resolved-project"}}},"then":{"required":["target"]},"else":{"not":{"required":["target"]}}},{"if":{"properties":{"resolution":{"const":"dynamic"}}},"else":{"required":["specifier"]}}]}},"capabilityUses":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["file","line","symbol","capability","source"],"properties":{"file":{"type":"string","minLength":1,"pattern":"^(?!/)(?![A-Za-z]:/)(?!.*\\\\)(?!.*//)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*[\\u0000-\\u001f\\u007f])(?!.*\\/$).+$"},"line":{"type":"integer","minimum":1},"symbol":{"type":"string","minLength":1},"capability":{"enum":["network","filesystem","clock","randomness","environment","process","persistence"]},"source":{"enum":["ambient-global","import-based"]}}}},"ambientUses":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["file","line","symbol"],"properties":{"file":{"type":"string","minLength":1,"pattern":"^(?!/)(?![A-Za-z]:/)(?!.*\\\\)(?!.*//)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*[\\u0000-\\u001f\\u007f])(?!.*\\/$).+$"},"line":{"type":"integer","minimum":1},"symbol":{"type":"string","minLength":1}}}},"publishCalls":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["file","line","objectHasIntent","arkPublishCandidate","hasSource"],"properties":{"file":{"type":"string","minLength":1,"pattern":"^(?!/)(?![A-Za-z]:/)(?!.*\\\\)(?!.*//)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*[\\u0000-\\u001f\\u007f])(?!.*\\/$).+$"},"line":{"type":"integer","minimum":1},"rawIntentName":{"type":"string","minLength":1},"objectHasIntent":{"type":"boolean"},"arkPublishCandidate":{"type":"boolean"},"hasSource":{"type":"boolean"},"sourceIntent":{"type":"string","minLength":1}}}},"intentReferences":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["file","line","intent"],"properties":{"file":{"type":"string","minLength":1,"pattern":"^(?!/)(?![A-Za-z]:/)(?!.*\\\\)(?!.*//)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*[\\u0000-\\u001f\\u007f])(?!.*\\/$).+$"},"line":{"type":"integer","minimum":1},"intent":{"type":"string","minLength":1}}}},"safetyUses":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["file","line","kind"],"properties":{"file":{"type":"string","minLength":1,"pattern":"^(?!/)(?![A-Za-z]:/)(?!.*\\\\)(?!.*//)(?!.*(?:^|/)\\.{1,2}(?:/|$))(?!.*[\\u0000-\\u001f\\u007f])(?!.*\\/$).+$"},"line":{"type":"integer","minimum":1},"kind":{"enum":["ts-suppression","any-cast","dynamic-import","dynamic-require","in-memory-store"]},"symbol":{"type":"string","minLength":1}},"allOf":[{"if":{"properties":{"kind":{"const":"in-memory-store"}}},"then":{"required":["symbol"]},"else":{"not":{"required":["symbol"]}}}]}},"factsHash":{"type":"string","minLength":1}},"allOf":[{"if":{"properties":{"completeness":{"const":"complete"}}},"then":{"properties":{"completenessReasons":{"maxItems":0},"files":{"items":{"properties":{"parseStatus":{"const":"parsed"}}}}}}},{"if":{"properties":{"completeness":{"enum":["partial","unavailable"]}}},"then":{"properties":{"completenessReasons":{"minItems":1}}}}]}
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.6.1",
9
+ "version": "3.8.0",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "arkgate",
14
- "version": "3.6.1",
14
+ "version": "3.8.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”.
@@ -60,7 +60,7 @@ say so in one line and hand off `stop`.
60
60
  |------|------|-------------|
61
61
  | **Recon (default)** | map / residual / “what next?” / bare `/ark-explore` | Headline → map → ranked table → **Top 3** → residue → Completion |
62
62
  | **Dual-plan seed** | user asks for a **plan**, mejora, roadmap, “Ark + patrón”, **or** spaghetti signals fire (§G) | Same recon **plus** **§ Dual-plan seed** (A + B). **Cap 3–5 B bets.** |
63
- | **Shape-focus** | plan A already empty / ENFORCE, user wants **pattern** depth only | Abbreviated map + **mandatory** concurrent-patterns table + B bets only (A = “goal.met / empty”) |
63
+ | **Shape-focus** | plan A already empty / ENFORCE, `plan.completeness` is `complete`, user wants **pattern** depth only | Abbreviated map + **mandatory** concurrent-patterns table + B bets only (A = “goal.met / empty”) |
64
64
 
65
65
  **Auto-upgrade:** if §G spaghetti signals fire, you **must** use dual-plan seed or shape-focus
66
66
  — never end on recon-only with “layers are clean.”
@@ -75,7 +75,7 @@ say so in one line and hand off `stop`.
75
75
 
76
76
  | Section | Content |
77
77
  |---------|---------|
78
- | **A. Remediation** | From `--plan` — usually empty when ENFORCE; one line if so |
78
+ | **A. Remediation** | From `--plan` — usually empty when ENFORCE; one line if so. Empty counts only when `plan.completeness === "complete"` |
79
79
  | **B. Pattern / evolution** | **3–5** bets max; each: evidence · así te lo re-soluciono · **success signal** · next skill · **pilot** · **kill-switch** if new layer/big move |
80
80
  | **Phase ladder** | Name which of Align / Stabilize / **Shape** the repo is in (§G) |
81
81
 
@@ -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:** require `plan.completeness === "complete"` before accepting `goal.met`. If `doctor.parseHealth.affectedFiles > 0`, open and name those paths; never describe them as clean or successfully inspected. Doctor alone does not change the gate verdict, but check/plan completeness is `partial`, plan goal is false, and strict merge fails.
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?).
@@ -195,7 +202,7 @@ Prefer bets the user can run next (`command` / skill), not vague “improve DX
195
202
  ### G. Spaghetti / design-depth ladder (non-deterministic path — mandatory when signals fire)
196
203
 
197
204
  **Signals (any one → dual-plan seed or shape-focus):**
198
- - Plan A empty / `goal.met` **and** you still see design-weak / concurrent patterns / god modules.
205
+ - Plan A empty / `goal.met` with `completeness: complete` **and** you still see design-weak / concurrent patterns / god modules.
199
206
  - Brownfield with mixed layouts (flat services + “hex” folders + feature dumps).
200
207
  - Semantic false-green (path-correct, design-wrong).
201
208
  - User words: spaghetti, monstruo, legacy, “está enforce pero horrible”, pattern, refactor shape.
@@ -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/route bodies under repo/db globs |
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 |
@@ -268,7 +275,7 @@ Kinds: `risk` | `false-green` | `debt` | `opportunity` | `shape` | `manifiesto`
268
275
  On false-green dominant: **STOP — do not continue this skill as complete.** **STOP — false-green: invoke /ark-adopt or /ark-contract before claiming ENFORCE.** Do not claim goal.met / ENFORCE from type-only cleanup while doctor reports `contract-false-green-io-under-application`.
269
276
  On concentrated edge dominant: **STOP — do not continue this skill as complete.** **STOP — concentrated edge: invoke /ark-contract with source evidence** (do not freeze a wrong contract or grind N freezes).
270
277
  7. **Dual-plan seed** — required in dual-plan seed / shape-focus (and when §G auto-upgrades); A + B cap 3–5; extraction cards for I/O bets.
271
- 8. **Deterministic residue** — plan steps, violations, doctor top action. Point to `/ark-loop` / `/ark-fix` **only when A steps exist**; never pretend loop is the architecture story when goal is already met.
278
+ 8. **Deterministic residue** — plan completeness, steps, violations, doctor top action. Point to `/ark-loop` / `/ark-fix` **only when A steps exist**; never call a `partial`/`unavailable` plan met, and never pretend loop is the architecture story when a complete goal is already met.
272
279
 
273
280
  Optional: **Diff vs naive sensor-only read** (what reading the tree changed).
274
281
 
@@ -18,7 +18,7 @@ the two files on the violation edge.
18
18
  | Judgment design for a known violation | Contract wrong / false-green → STOP to `/ark-contract` / `/ark-adopt` |
19
19
 
20
20
  When the fix is really a **Shape** extraction (I/O out of routes, god module split), write an
21
- **extraction card** before editing — same template as [brownfield-adoption.md](../../docs/brownfield-adoption.md)
21
+ **extraction card** before editing — same template as `docs/brownfield-adoption.md`
22
22
  §6 and explore §G. Fixed fields (never mechanical-safe, never silent B apply):
23
23
 
24
24
  ```text
@@ -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 the card: `pilotTarget`, `moveSample`/`movesTotal`, `successSignal`, `killSwitch`, `doNot[]`.
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
 
@@ -8,11 +8,12 @@ description: Evaluate the experimental Ark runtime kernel against hand-rolled ev
8
8
  The runtime kernel is currently **experimental** and is not required for ArkGate enforcement or
9
9
  presented as production-ready. Use this skill only when the user explicitly wants to evaluate it.
10
10
 
11
- `arkgate` ships the experimental runtime kernel
11
+ The separate `@arkgate/runtime` source package contains the experimental runtime kernel
12
12
  (`createArkKernel`) with an event bus, event contracts, outbox, audit trail,
13
13
  policy engine, workflow/saga coordination, projections, observability hooks,
14
- and NestJS adapters. This skill migrates hand-rolled versions of those to the
15
- kernel, one feature at a time.
14
+ and NestJS adapters. The stable `arkgate` package is the architecture gate; it does not bundle
15
+ the runtime implementation. This skill migrates hand-rolled versions of those to the kernel,
16
+ one feature at a time.
16
17
 
17
18
  ## Dual engine (mandatory)
18
19
 
@@ -41,20 +42,25 @@ the same files or weaken the gate.
41
42
  - saga/workflow orchestration (multi-step processes with compensation)
42
43
  - read-model/projection builders
43
44
  - policy/authorization checks scattered across use cases
44
- Also check whether `@nestjs/common` is present → the `arkgate/nestjs`
45
+ Also check whether `@nestjs/common` is present → the `@arkgate/runtime/nestjs`
45
46
  adapters apply.
46
47
  2. **Pick ONE target** — the smallest, most self-contained candidate (fewest
47
48
  call sites). Migrating everything at once is how adoptions die. List the
48
49
  rest as follow-ups in the report.
49
- 3. **Migrate** — import from `arkgate/runtime` (preferred experimental subpath) or
50
- `arkgate/nestjs`, and read the package's `docs/agent-guide.md`
51
- (in `node_modules/arkgate/docs/`) for the runtime API before
50
+ 3. **Resolve availability** — run `npm view @arkgate/runtime dist-tags --json`. If an
51
+ `experimental` tag exists, install that exact companion. Otherwise continue only from an
52
+ ArkGate source checkout: run `npm run build:runtime` at its root and install its local
53
+ `packages/runtime` folder into the target. Outside a source checkout, stop and report that the
54
+ runtime is unavailable; never fall back to the deprecated root shims as if they contained it.
55
+ 4. **Migrate** — import from `@arkgate/runtime` or `@arkgate/runtime/nestjs`, and read the
56
+ [runtime package guide](https://github.com/pedroknigge/arkgate/blob/main/packages/runtime/README.md)
57
+ plus the [experimental surface policy](https://github.com/pedroknigge/arkgate/blob/main/docs/package-surface.md#experimental-opt-in-surfaces) before
52
58
  writing code. Wire the kernel at the composition root; keep the domain
53
59
  ignorant of it (handlers/ports, not kernel imports inside domain code —
54
60
  the architecture check enforces this; Claude/Grok hooks can block it earlier). Note: the kernel bounds in-memory
55
61
  history by default (`maxHistorySize` 1000); mention this if the hand-rolled
56
62
  version retained everything.
57
- 4. **Delete the hand-rolled version** once call sites are moved — the point is
63
+ 5. **Delete the hand-rolled version** once call sites are moved — the point is
58
64
  less code, not a second parallel system. Deleting code is a destructive move:
59
65
  confirm with the user before removing the old implementation, and never delete
60
66
  something the inventory only *suspects* is dead (a misclassified load-bearing
@@ -63,6 +69,7 @@ the same files or weaken the gate.
63
69
  ## Critical handoffs
64
70
 
65
71
  - No static gates yet: **STOP — do not continue this skill as complete.** Run `/ark-architect` or `/ark-adopt` first.
72
+ - Runtime companion unavailable from npm and no ArkGate source checkout: **STOP** and report the distribution boundary.
66
73
  - Inventory finds nothing: stop; do not introduce kernel speculatively.
67
74
 
68
75
  ## Operating rules