arkgate 4.8.24 → 4.8.25
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 +85 -0
- package/README.md +2 -2
- package/bin/ark-check-runtime.mjs +17 -14
- package/bin/ark-layer-match.mjs +115 -13
- package/bin/ark-mcp-runtime.mjs +36 -31
- package/bin/ark-shared.mjs +4 -23
- package/bin/lib/adoption-stance.mjs +2 -2
- package/bin/lib/adr-path.mjs +3 -3
- package/bin/lib/agent-gates.mjs +0 -61
- package/bin/lib/agent-homes.mjs +12 -21
- package/bin/lib/agent-projection-command.mjs +4 -4
- package/bin/lib/ambient-state.mjs +9 -30
- package/bin/lib/analysis-engine.mjs +14 -14
- package/bin/lib/architecture-scan.mjs +11 -9
- package/bin/lib/ark-order-doctor.mjs +3 -28
- package/bin/lib/ark-order-facts.mjs +6 -99
- package/bin/lib/ark-order-types.mjs +1 -2
- package/bin/lib/ark-run-doctor.mjs +3 -28
- package/bin/lib/ark-run-facts.mjs +30 -40
- package/bin/lib/ark-run-sensors.mjs +1 -1
- package/bin/lib/arkrule-file-hints.mjs +2 -47
- package/bin/lib/arkrules-contract.mjs +124 -133
- package/bin/lib/arkrules-sensors.mjs +7 -5
- package/bin/lib/check-args.mjs +63 -1
- package/bin/lib/ci-and-commands.mjs +8 -72
- package/bin/lib/ci-merge-boundary.mjs +1 -1
- package/bin/lib/class-source-scan.mjs +5 -5
- package/bin/lib/clone-detection.mjs +474 -0
- package/bin/lib/codex-home.mjs +1 -1
- package/bin/lib/config-contract-slices.mjs +44 -6
- package/bin/lib/config-contract.mjs +40 -117
- package/bin/lib/config-extras.mjs +16 -22
- package/bin/lib/contract-smells.mjs +33 -15
- package/bin/lib/core-ratchet.mjs +0 -2
- package/bin/lib/dashboard-cli.mjs +2 -2
- package/bin/lib/deep-module-coach.mjs +2 -4
- package/bin/lib/deploy-path.mjs +13 -38
- package/bin/lib/design-smells.mjs +2 -2
- package/bin/lib/diagnostic-catalog.mjs +8 -1
- package/bin/lib/doctor-advisories.mjs +55 -9
- package/bin/lib/doctor-green-cite.mjs +1 -1
- package/bin/lib/doctor-human.mjs +1 -1
- package/bin/lib/doctor-next-actions.mjs +2 -2
- package/bin/lib/doctor-plan.mjs +4 -6
- package/bin/lib/duplication-io.mjs +572 -0
- package/bin/lib/effective-contract-load.mjs +181 -44
- package/bin/lib/entry-points-io.mjs +424 -0
- package/bin/lib/extra-merge-teeth.mjs +36 -0
- package/bin/lib/field-install.mjs +38 -14
- package/bin/lib/first-run-help.mjs +7 -3
- package/bin/lib/flat-parent-importers.mjs +5 -3
- package/bin/lib/gate-files.mjs +30 -89
- package/bin/lib/github-enforcement.mjs +165 -28
- package/bin/lib/golden-pattern.mjs +1 -1
- package/bin/lib/hook-templates.mjs +16 -16
- package/bin/lib/html-report-advisories.mjs +4 -0
- package/bin/lib/html-report-depth.mjs +2 -2
- package/bin/lib/html-report.mjs +2 -2
- package/bin/lib/import-graph-projection.mjs +112 -0
- package/bin/lib/improvement-compass-doctor.mjs +1 -24
- package/bin/lib/invariant-coverage-io.mjs +4 -3
- package/bin/lib/invariant-coverage.mjs +26 -0
- package/bin/lib/invariant-probe-cli.mjs +347 -0
- package/bin/lib/invariant-probe-io.mjs +165 -0
- package/bin/lib/invariant-probe-runner.mjs +268 -0
- package/bin/lib/invariant-probe-sites.mjs +174 -0
- package/bin/lib/invariant-probe-workspace.mjs +183 -0
- package/bin/lib/invariant-probe.mjs +461 -0
- package/bin/lib/invariant-tests-path.mjs +16 -22
- package/bin/lib/literal-path-drift.mjs +4 -2
- package/bin/lib/managed-upgrade.mjs +2 -8
- package/bin/lib/mcp-adoption.mjs +4 -5
- package/bin/lib/mcp-hook-payload.mjs +4 -4
- package/bin/lib/orphan-modules-io.mjs +458 -0
- package/bin/lib/orphan-modules.mjs +251 -0
- package/bin/lib/outside-importers.mjs +197 -0
- package/bin/lib/package-manager.mjs +3 -3
- package/bin/lib/parse-health.mjs +1 -1
- package/bin/lib/persistence-write-hint.mjs +33 -8
- package/bin/lib/pin-dependent-gates.mjs +2 -2
- package/bin/lib/policy-delta-io.mjs +55 -8
- package/bin/lib/post-green-path.mjs +1 -1
- package/bin/lib/prepare-change.mjs +3 -9
- package/bin/lib/prepare-write.mjs +1 -2
- package/bin/lib/presets.mjs +56 -68
- package/bin/lib/product-copy.mjs +1 -6
- package/bin/lib/project-root.mjs +31 -62
- package/bin/lib/resolved-candidate-facts.mjs +90 -62
- package/bin/lib/rules-under-contract.mjs +72 -8
- package/bin/lib/scan-files.mjs +4 -4
- package/bin/lib/schema-validation.mjs +130 -0
- package/bin/lib/sensor-promote-cli.mjs +2 -11
- package/bin/lib/sensor-promote-io.mjs +33 -22
- package/bin/lib/sensor-promotion.mjs +1 -1
- package/bin/lib/skill-catalog-apply.mjs +1 -1
- package/bin/lib/skill-install.mjs +42 -38
- package/bin/lib/snippet-analysis.mjs +1 -1
- package/bin/lib/start-install-recovery.mjs +1 -1
- package/bin/lib/start-preview.mjs +1 -1
- package/bin/lib/states-transitions-presence.mjs +3 -3
- package/bin/lib/status-command.mjs +2 -18
- package/bin/lib/status-manifest.mjs +18 -26
- package/bin/lib/status-transition-catalog.mjs +0 -6
- package/bin/lib/suggestions.mjs +3 -3
- package/bin/lib/team-parliament-io.mjs +3 -17
- package/bin/lib/team-parliament.mjs +15 -9
- package/bin/lib/upgrade-behavior-changes.mjs +2 -2
- package/bin/lib/upgrade-command.mjs +2 -24
- package/bin/lib/upgrade-outcome.mjs +1 -1
- package/bin/lib/upstream-report.mjs +21 -10
- package/bin/lib/violations.mjs +10 -9
- package/bin/lib/weakest-link.mjs +13 -0
- package/bin/lib/write-path-capabilities.mjs +2 -2
- package/dist/chunk-AHACEKSV.js +16 -0
- package/dist/chunk-UN5EH4QV.cjs +16 -0
- package/dist/{configTypes-BJbaeoj4.d.cts → configTypes-GPvvdleM.d.cts} +12 -1
- package/dist/{configTypes-BJbaeoj4.d.ts → configTypes-GPvvdleM.d.ts} +12 -1
- package/dist/eslint/index.cjs +11 -11
- package/dist/eslint/index.d.cts +10 -1
- package/dist/eslint/index.d.ts +10 -1
- package/dist/eslint/index.js +11 -11
- package/dist/index.cjs +34 -34
- package/dist/index.d.cts +587 -515
- package/dist/index.d.ts +587 -515
- package/dist/index.js +34 -34
- package/dist/nestjs/index.cjs +1 -1
- package/dist/nestjs/index.d.cts +1 -1
- package/dist/nestjs/index.d.ts +1 -1
- package/dist/nestjs/index.js +1 -1
- package/dist/order/index.cjs +1 -1
- package/dist/order/index.js +1 -1
- package/dist/runtime/index.cjs +12 -12
- package/dist/runtime/index.d.cts +174 -136
- package/dist/runtime/index.d.ts +174 -136
- package/dist/runtime/index.js +12 -12
- package/dist/{types-DRinG-vT.d.cts → types-CnauMQQL.d.cts} +33 -25
- package/dist/{types-DRinG-vT.d.ts → types-CnauMQQL.d.ts} +33 -25
- package/docs/README.md +2 -1
- package/docs/agent-guide.md +134 -2
- package/docs/ai-gates.md +15 -1
- package/docs/configuration.md +40 -11
- package/docs/diagnostics.md +118 -2
- package/docs/package-surface.md +4 -1
- package/docs/product-voice.md +7 -1
- package/package.json +11 -2
- package/schemas/ark.config.schema.json +31 -3
- package/schemas/ark.invariant-probe.schema.json +368 -0
- package/server.json +2 -2
- package/templates/agent-skills/README.md +1 -1
- package/templates/agent-skills/ark-adopt/SKILL.md +1 -0
- package/templates/agent-skills/ark-contract/SKILL.md +17 -0
- package/templates/agent-skills/ark-coverage/SKILL.md +2 -0
- package/templates/agent-skills/ark-explore/SKILL.md +7 -0
- package/templates/agent-skills/ark-fix/SKILL.md +20 -0
- package/templates/agent-skills/ark-place/SKILL.md +8 -0
- package/templates/skills/ark-adopt.md +1 -0
- package/templates/skills/ark-contract.md +17 -0
- package/templates/skills/ark-coverage.md +2 -0
- package/templates/skills/ark-explore.md +7 -0
- package/templates/skills/ark-fix.md +20 -0
- package/templates/skills/ark-place.md +8 -0
- package/bin/lib/ark-order-error.mjs +0 -18
- package/bin/lib/ark-order-invariants.mjs +0 -388
- package/bin/lib/stable-hash.mjs +0 -90
- package/dist/chunk-MBXCFLO4.js +0 -16
- package/dist/chunk-RNQHRDCQ.cjs +0 -16
|
@@ -175,10 +175,19 @@ type ArkConfigChildSlices = {
|
|
|
175
175
|
* `to` is the universe id plus one child segment.
|
|
176
176
|
*/
|
|
177
177
|
sliceAliases?: ArkConfigSliceAlias[];
|
|
178
|
+
/**
|
|
179
|
+
* Filename at each child slice root. `<Layer>` is the only token.
|
|
180
|
+
* Example: `arkrules.<Layer>.json`.
|
|
181
|
+
*/
|
|
182
|
+
arkRulesFile?: string;
|
|
178
183
|
};
|
|
179
184
|
type ArkConfigSliceAlias = {
|
|
180
185
|
from: string;
|
|
181
186
|
to: string;
|
|
187
|
+
/** True: the path stays. It is not an owed move and does not clear other honesty debt. */
|
|
188
|
+
pinned?: boolean;
|
|
189
|
+
/** Doctor label, such as `framework-route`. A label alone does not pin. */
|
|
190
|
+
reason?: string;
|
|
182
191
|
};
|
|
183
192
|
type ArkConfigCrossSliceEdge = {
|
|
184
193
|
from: string;
|
|
@@ -213,7 +222,9 @@ type ArkConfigCoverage = {
|
|
|
213
222
|
* ADR 0012 — optional map of layer name → project-relative ArkRules file path.
|
|
214
223
|
* Absence changes no inter-layer verdict.
|
|
215
224
|
*/
|
|
216
|
-
|
|
225
|
+
/** One path, or several paths merged into that layer's catalog. */
|
|
226
|
+
type ArkConfigArkRulesRef = string | string[];
|
|
227
|
+
type ArkConfigArkRulesRefs = Record<string, ArkConfigArkRulesRef>;
|
|
217
228
|
/** ADR 0020 — advisory never adds merge teeth; enforced is the extra's merge plane. */
|
|
218
229
|
type ArkConfigArkRunMode = 'advisory' | 'enforced';
|
|
219
230
|
/**
|
|
@@ -1624,6 +1635,24 @@ type ArkRunRegisterOptions<T = unknown> = {
|
|
|
1624
1635
|
};
|
|
1625
1636
|
type ArkRunRegistrationHandle = ArkRunInformationPackageComponent;
|
|
1626
1637
|
|
|
1638
|
+
type ArkRunInspectorListenSource = {
|
|
1639
|
+
getInspectorSnapshot(bind: ArkRunInspectorBind): ArkRunInspectorSnapshot;
|
|
1640
|
+
requestGraph(query?: ArkRunGraphQuery): ArkRunGraph;
|
|
1641
|
+
/** OD04: pending/failed outbox summaries (EventBufferStore.list). */
|
|
1642
|
+
listInspectorOutbox?(): Promise<ArkRunInspectorOutboxMonitor>;
|
|
1643
|
+
/** OD04: workflow/saga summaries (WorkflowEngine.list). */
|
|
1644
|
+
listInspectorWorkflows?(): Promise<ArkRunInspectorWorkflowsMonitor>;
|
|
1645
|
+
/** Duck-typed kernel ports when explicit list* helpers are absent. */
|
|
1646
|
+
outbox?: {
|
|
1647
|
+
list(status?: 'pending' | 'dispatched' | 'failed'): Promise<unknown[]>;
|
|
1648
|
+
};
|
|
1649
|
+
eventBuffer?: {
|
|
1650
|
+
list(status?: 'pending' | 'dispatched' | 'failed'): Promise<unknown[]>;
|
|
1651
|
+
};
|
|
1652
|
+
workflowEngine?: {
|
|
1653
|
+
list(workflowName?: string): Promise<unknown[]>;
|
|
1654
|
+
};
|
|
1655
|
+
};
|
|
1627
1656
|
type ArkRunInspectorHandle = {
|
|
1628
1657
|
host: string;
|
|
1629
1658
|
port: number;
|
|
@@ -1636,11 +1665,6 @@ type ArkRunInspectorHandle = {
|
|
|
1636
1665
|
close(): Promise<void>;
|
|
1637
1666
|
};
|
|
1638
1667
|
|
|
1639
|
-
/**
|
|
1640
|
-
* Opt-in ArkRun inspector. HTTP is dynamically imported so constructing a
|
|
1641
|
-
* kernel does not bind a port or load `node:http`.
|
|
1642
|
-
*/
|
|
1643
|
-
|
|
1644
1668
|
type StartArkRunInspectorOptions = {
|
|
1645
1669
|
host?: string;
|
|
1646
1670
|
port?: number;
|
|
@@ -1648,24 +1672,8 @@ type StartArkRunInspectorOptions = {
|
|
|
1648
1672
|
nodeEnv?: string;
|
|
1649
1673
|
sseIntervalMs?: number;
|
|
1650
1674
|
};
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
requestGraph(query?: ArkRunGraphQuery): ArkRunGraph;
|
|
1654
|
-
/** OD04: pending/failed outbox summaries (EventBufferStore.list). */
|
|
1655
|
-
listInspectorOutbox?(): Promise<ArkRunInspectorOutboxMonitor>;
|
|
1656
|
-
/** OD04: workflow/saga summaries (WorkflowEngine.list). */
|
|
1657
|
-
listInspectorWorkflows?(): Promise<ArkRunInspectorWorkflowsMonitor>;
|
|
1658
|
-
/** Duck-typed kernel ports when explicit list* helpers are absent. */
|
|
1659
|
-
outbox?: {
|
|
1660
|
-
list(status?: 'pending' | 'dispatched' | 'failed'): Promise<unknown[]>;
|
|
1661
|
-
};
|
|
1662
|
-
eventBuffer?: {
|
|
1663
|
-
list(status?: 'pending' | 'dispatched' | 'failed'): Promise<unknown[]>;
|
|
1664
|
-
};
|
|
1665
|
-
workflowEngine?: {
|
|
1666
|
-
list(workflowName?: string): Promise<unknown[]>;
|
|
1667
|
-
};
|
|
1668
|
-
};
|
|
1675
|
+
/** What the inspector reads: snapshot, graph, and optional outbox / workflow monitors. */
|
|
1676
|
+
type ArkRunInspectorSource = ArkRunInspectorListenSource;
|
|
1669
1677
|
declare function startArkRunInspector(source: ArkRunInspectorSource, options?: StartArkRunInspectorOptions): Promise<ArkRunInspectorHandle>;
|
|
1670
1678
|
|
|
1671
1679
|
/**
|
|
@@ -1789,4 +1797,4 @@ interface CreateArkKernelFromConfigOptions extends Omit<CreateArkKernelOptions,
|
|
|
1789
1797
|
}
|
|
1790
1798
|
type ArkKernelConfig = ArkCheckConfig;
|
|
1791
1799
|
|
|
1792
|
-
export { type
|
|
1800
|
+
export { type TraceRecord as $, type ArkKernel as A, type EventBus as B, type CreateArkKernelOptions as C, type DependencyGraph as D, type EventContractRegistry as E, type CreateObservabilityReporterOptions as F, type GraphEdge as G, PolicyEngine as H, IntentRegistry as I, type ArkManifest as J, type WorkflowSnapshot as K, type SagaDefinition as L, type MetadataRegistry as M, type CreateWorkflowEngineOptions as N, type ObservabilityReporter as O, type ProjectionRegistry as P, type SagaInstance as Q, type ReadModelStore as R, type SagaContext as S, type WorkflowEngine as T, type ArkConfig as U, type ArkConfigLoadResult as V, type WorkflowStore as W, type DependencyInformationPackage as X, type ArkKernelConfig as Y, type CreateArkKernelFromConfigOptions as Z, type TraceRecordType as _, type AuditStore as a, type ArkRunInspectorSource as a$, type OutboxStatus as a0, type OutboxRecord as a1, type ObservabilityDriftReport as a2, ARK_RUN_COMPONENT_LIFETIMES as a3, ARK_RUN_EPHEMERAL_DEFAULT as a4, ARK_RUN_GRAPH_DEFAULT_SLICE as a5, ARK_RUN_GRAPH_NODE_KINDS as a6, ARK_RUN_GRAPH_PROCESS_EDGE_KINDS as a7, ARK_RUN_GRAPH_SCHEMA_VERSION as a8, ARK_RUN_GRAPH_SLICES as a9, type ArkRunDeliveredVia as aA, type ArkRunExtendedInfo as aB, type ArkRunGraph as aC, type ArkRunGraphEdge as aD, type ArkRunGraphEdgeKind as aE, type ArkRunGraphMatch as aF, type ArkRunGraphMatchInput as aG, type ArkRunGraphNode as aH, type ArkRunGraphNodeKind as aI, type ArkRunGraphProcessEdgeKind as aJ, type ArkRunGraphQuery as aK, type ArkRunGraphResolvedQuery as aL, type ArkRunGraphSlice as aM, type ArkRunGraphTechnicalEdgeKind as aN, type ArkRunInformationPackageComponent as aO, type ArkRunInspectorBind as aP, ArkRunInspectorBindError as aQ, type ArkRunInspectorBindInput as aR, type ArkRunInspectorHandle as aS, type ArkRunInspectorHardening as aT, type ArkRunInspectorHardeningDurability as aU, type ArkRunInspectorMonitorBuildOptions as aV, type ArkRunInspectorOutboxMonitor as aW, type ArkRunInspectorOutboxRecordSummary as aX, ArkRunInspectorProductionError as aY, type ArkRunInspectorSnapshot as aZ, type ArkRunInspectorSnapshotInput as a_, ARK_RUN_GRAPH_TECHNICAL_EDGE_KINDS as aa, ARK_RUN_INFORMATION_PACKAGE_SCHEMA_VERSION as ab, ARK_RUN_INSPECTOR_DEFAULT_HOST as ac, ARK_RUN_INSPECTOR_DEFAULT_PORT as ad, ARK_RUN_INSPECTOR_EVENTS_PATH as ae, ARK_RUN_INSPECTOR_GRAPH_PATH as af, ARK_RUN_INSPECTOR_MONITOR_SAMPLE_LIMIT as ag, ARK_RUN_INSPECTOR_OUTBOX_PATH as ah, ARK_RUN_INSPECTOR_SCHEMA_VERSION as ai, ARK_RUN_INSPECTOR_SNAPSHOT_PATH as aj, ARK_RUN_INSPECTOR_SSE_EVENT as ak, ARK_RUN_INSPECTOR_TRANSPORT_FALLBACK as al, ARK_RUN_INSPECTOR_WORKFLOWS_PATH as am, ARK_RUN_TRANSPORT_KINDS as an, type ArchitectureLayer as ao, type ArchitectureLayerConfig as ap, type ArchitectureRule as aq, type ArkManifestArchitecture as ar, type ArkManifestData as as, type ArkManifestEntityLink as at, type ArkManifestGraph as au, type ArkManifestIntent as av, type ArkManifestPolicy as aw, type ArkManifestProjection as ax, type ArkRunBrokerAdapter as ay, type ArkRunComponentLifetime as az, type AuditRecord as b, formatArkRunInspectorSseEvent as b$, type ArkRunInspectorStoreDurability as b0, type ArkRunInspectorStoreDurabilityKind as b1, type ArkRunInspectorStoreRole as b2, type ArkRunInspectorTransportFacts as b3, type ArkRunInspectorWorkflowSummary as b4, type ArkRunInspectorWorkflowsMonitor as b5, type ArkRunPublisher as b6, type ArkRunRegisterOptions as b7, type ArkRunRegistrationHandle as b8, type ArkRunSendOptions as b9, type OutboxStore as bA, type PolicyEvaluationResult as bB, type ProjectionCheckpoint as bC, type ProjectionDefinition as bD, type PublishedEventRecord as bE, type RetryPolicy as bF, type SagaStatus as bG, type SagaStep as bH, type StartArkRunInspectorOptions as bI, type TraceSink as bJ, type Unsubscribe as bK, type WorkflowDefinition as bL, type WorkflowStatus as bM, type WorkflowStep as bN, appendDecisionTape as bO, arkRunGraphQueryFromSearchParams as bP, arkRunInspectorUrl as bQ, buildArkRunInspectorHardening as bR, buildArkRunInspectorOutboxMonitor as bS, buildArkRunInspectorSnapshot as bT, buildArkRunInspectorWorkflowsMonitor as bU, buildDependencyInformationPackage as bV, classifyArkRunInspectorStoreDurability as bW, closeArkRunGraphQuery as bX, closedArkRunEphemeral as bY, closedArkRunTransportKind as bZ, formatArkRunGraphMermaid as b_, type ArkRunSendPlan as ba, type ArkRunSendPlanInput as bb, type ArkRunSendResult as bc, type ArkRunTransportKind as bd, type AuditRecordInput as be, type AuditRecordType as bf, type CorrelationId as bg, type EntityMeta as bh, type EventContractIssue as bi, type EventHandler as bj, type EventInterceptionInfo as bk, type EventInterceptor as bl, type EventInterceptorContext as bm, type EventMetadata as bn, type EventPayloadPatch as bo, type EventPayloadSchema as bp, type EventPublisher as bq, type EventSchemaField as br, type EventSchemaFieldType as bs, type FieldMeta as bt, type GraphNode as bu, type IntentRelationshipKind as bv, InvalidArkRunGraphQueryError as bw, InvalidArkRunSendOptionError as bx, type ObservabilityFlow as by, type ObservedLayerFlowMode as bz, type AuditQuery as c, isArkRunInspectorLoopbackHost as c0, isArkRunInspectorProductionEnv as c1, requestArkRunGraph as c2, resolveArkRunInspectorBind as c3, resolveArkRunSendPlan as c4, startArkRunInspector as c5, unavailableArkRunInspectorOutboxMonitor as c6, unavailableArkRunInspectorWorkflowsMonitor as c7, type CreateAuditTrailOptions as d, type AuditTrail as e, type CreateArchitectureProfileOptions as f, type ArchitectureProfile as g, type ArkCheckConfig as h, type CreateArchitectureProfileFromArkConfigOptions as i, type CreateElevenLayerArkConfigOptions as j, type EventContract as k, type DomainEvent as l, type EventContractValidationResult as m, type IntentName as n, type DefineIntentOptions as o, type IntentCreator as p, type CreateProjectionRegistryOptions as q, type PolicyViolation as r, type PolicySeverity as s, type PolicyEnforcementMode as t, type Policy as u, type IntentRelationship as v, type EventBufferStore as w, type EventBufferRecord as x, type EventBufferStatus as y, type EventBusOptions as z };
|
|
@@ -175,10 +175,19 @@ type ArkConfigChildSlices = {
|
|
|
175
175
|
* `to` is the universe id plus one child segment.
|
|
176
176
|
*/
|
|
177
177
|
sliceAliases?: ArkConfigSliceAlias[];
|
|
178
|
+
/**
|
|
179
|
+
* Filename at each child slice root. `<Layer>` is the only token.
|
|
180
|
+
* Example: `arkrules.<Layer>.json`.
|
|
181
|
+
*/
|
|
182
|
+
arkRulesFile?: string;
|
|
178
183
|
};
|
|
179
184
|
type ArkConfigSliceAlias = {
|
|
180
185
|
from: string;
|
|
181
186
|
to: string;
|
|
187
|
+
/** True: the path stays. It is not an owed move and does not clear other honesty debt. */
|
|
188
|
+
pinned?: boolean;
|
|
189
|
+
/** Doctor label, such as `framework-route`. A label alone does not pin. */
|
|
190
|
+
reason?: string;
|
|
182
191
|
};
|
|
183
192
|
type ArkConfigCrossSliceEdge = {
|
|
184
193
|
from: string;
|
|
@@ -213,7 +222,9 @@ type ArkConfigCoverage = {
|
|
|
213
222
|
* ADR 0012 — optional map of layer name → project-relative ArkRules file path.
|
|
214
223
|
* Absence changes no inter-layer verdict.
|
|
215
224
|
*/
|
|
216
|
-
|
|
225
|
+
/** One path, or several paths merged into that layer's catalog. */
|
|
226
|
+
type ArkConfigArkRulesRef = string | string[];
|
|
227
|
+
type ArkConfigArkRulesRefs = Record<string, ArkConfigArkRulesRef>;
|
|
217
228
|
/** ADR 0020 — advisory never adds merge teeth; enforced is the extra's merge plane. */
|
|
218
229
|
type ArkConfigArkRunMode = 'advisory' | 'enforced';
|
|
219
230
|
/**
|
|
@@ -1624,6 +1635,24 @@ type ArkRunRegisterOptions<T = unknown> = {
|
|
|
1624
1635
|
};
|
|
1625
1636
|
type ArkRunRegistrationHandle = ArkRunInformationPackageComponent;
|
|
1626
1637
|
|
|
1638
|
+
type ArkRunInspectorListenSource = {
|
|
1639
|
+
getInspectorSnapshot(bind: ArkRunInspectorBind): ArkRunInspectorSnapshot;
|
|
1640
|
+
requestGraph(query?: ArkRunGraphQuery): ArkRunGraph;
|
|
1641
|
+
/** OD04: pending/failed outbox summaries (EventBufferStore.list). */
|
|
1642
|
+
listInspectorOutbox?(): Promise<ArkRunInspectorOutboxMonitor>;
|
|
1643
|
+
/** OD04: workflow/saga summaries (WorkflowEngine.list). */
|
|
1644
|
+
listInspectorWorkflows?(): Promise<ArkRunInspectorWorkflowsMonitor>;
|
|
1645
|
+
/** Duck-typed kernel ports when explicit list* helpers are absent. */
|
|
1646
|
+
outbox?: {
|
|
1647
|
+
list(status?: 'pending' | 'dispatched' | 'failed'): Promise<unknown[]>;
|
|
1648
|
+
};
|
|
1649
|
+
eventBuffer?: {
|
|
1650
|
+
list(status?: 'pending' | 'dispatched' | 'failed'): Promise<unknown[]>;
|
|
1651
|
+
};
|
|
1652
|
+
workflowEngine?: {
|
|
1653
|
+
list(workflowName?: string): Promise<unknown[]>;
|
|
1654
|
+
};
|
|
1655
|
+
};
|
|
1627
1656
|
type ArkRunInspectorHandle = {
|
|
1628
1657
|
host: string;
|
|
1629
1658
|
port: number;
|
|
@@ -1636,11 +1665,6 @@ type ArkRunInspectorHandle = {
|
|
|
1636
1665
|
close(): Promise<void>;
|
|
1637
1666
|
};
|
|
1638
1667
|
|
|
1639
|
-
/**
|
|
1640
|
-
* Opt-in ArkRun inspector. HTTP is dynamically imported so constructing a
|
|
1641
|
-
* kernel does not bind a port or load `node:http`.
|
|
1642
|
-
*/
|
|
1643
|
-
|
|
1644
1668
|
type StartArkRunInspectorOptions = {
|
|
1645
1669
|
host?: string;
|
|
1646
1670
|
port?: number;
|
|
@@ -1648,24 +1672,8 @@ type StartArkRunInspectorOptions = {
|
|
|
1648
1672
|
nodeEnv?: string;
|
|
1649
1673
|
sseIntervalMs?: number;
|
|
1650
1674
|
};
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
requestGraph(query?: ArkRunGraphQuery): ArkRunGraph;
|
|
1654
|
-
/** OD04: pending/failed outbox summaries (EventBufferStore.list). */
|
|
1655
|
-
listInspectorOutbox?(): Promise<ArkRunInspectorOutboxMonitor>;
|
|
1656
|
-
/** OD04: workflow/saga summaries (WorkflowEngine.list). */
|
|
1657
|
-
listInspectorWorkflows?(): Promise<ArkRunInspectorWorkflowsMonitor>;
|
|
1658
|
-
/** Duck-typed kernel ports when explicit list* helpers are absent. */
|
|
1659
|
-
outbox?: {
|
|
1660
|
-
list(status?: 'pending' | 'dispatched' | 'failed'): Promise<unknown[]>;
|
|
1661
|
-
};
|
|
1662
|
-
eventBuffer?: {
|
|
1663
|
-
list(status?: 'pending' | 'dispatched' | 'failed'): Promise<unknown[]>;
|
|
1664
|
-
};
|
|
1665
|
-
workflowEngine?: {
|
|
1666
|
-
list(workflowName?: string): Promise<unknown[]>;
|
|
1667
|
-
};
|
|
1668
|
-
};
|
|
1675
|
+
/** What the inspector reads: snapshot, graph, and optional outbox / workflow monitors. */
|
|
1676
|
+
type ArkRunInspectorSource = ArkRunInspectorListenSource;
|
|
1669
1677
|
declare function startArkRunInspector(source: ArkRunInspectorSource, options?: StartArkRunInspectorOptions): Promise<ArkRunInspectorHandle>;
|
|
1670
1678
|
|
|
1671
1679
|
/**
|
|
@@ -1789,4 +1797,4 @@ interface CreateArkKernelFromConfigOptions extends Omit<CreateArkKernelOptions,
|
|
|
1789
1797
|
}
|
|
1790
1798
|
type ArkKernelConfig = ArkCheckConfig;
|
|
1791
1799
|
|
|
1792
|
-
export { type
|
|
1800
|
+
export { type TraceRecord as $, type ArkKernel as A, type EventBus as B, type CreateArkKernelOptions as C, type DependencyGraph as D, type EventContractRegistry as E, type CreateObservabilityReporterOptions as F, type GraphEdge as G, PolicyEngine as H, IntentRegistry as I, type ArkManifest as J, type WorkflowSnapshot as K, type SagaDefinition as L, type MetadataRegistry as M, type CreateWorkflowEngineOptions as N, type ObservabilityReporter as O, type ProjectionRegistry as P, type SagaInstance as Q, type ReadModelStore as R, type SagaContext as S, type WorkflowEngine as T, type ArkConfig as U, type ArkConfigLoadResult as V, type WorkflowStore as W, type DependencyInformationPackage as X, type ArkKernelConfig as Y, type CreateArkKernelFromConfigOptions as Z, type TraceRecordType as _, type AuditStore as a, type ArkRunInspectorSource as a$, type OutboxStatus as a0, type OutboxRecord as a1, type ObservabilityDriftReport as a2, ARK_RUN_COMPONENT_LIFETIMES as a3, ARK_RUN_EPHEMERAL_DEFAULT as a4, ARK_RUN_GRAPH_DEFAULT_SLICE as a5, ARK_RUN_GRAPH_NODE_KINDS as a6, ARK_RUN_GRAPH_PROCESS_EDGE_KINDS as a7, ARK_RUN_GRAPH_SCHEMA_VERSION as a8, ARK_RUN_GRAPH_SLICES as a9, type ArkRunDeliveredVia as aA, type ArkRunExtendedInfo as aB, type ArkRunGraph as aC, type ArkRunGraphEdge as aD, type ArkRunGraphEdgeKind as aE, type ArkRunGraphMatch as aF, type ArkRunGraphMatchInput as aG, type ArkRunGraphNode as aH, type ArkRunGraphNodeKind as aI, type ArkRunGraphProcessEdgeKind as aJ, type ArkRunGraphQuery as aK, type ArkRunGraphResolvedQuery as aL, type ArkRunGraphSlice as aM, type ArkRunGraphTechnicalEdgeKind as aN, type ArkRunInformationPackageComponent as aO, type ArkRunInspectorBind as aP, ArkRunInspectorBindError as aQ, type ArkRunInspectorBindInput as aR, type ArkRunInspectorHandle as aS, type ArkRunInspectorHardening as aT, type ArkRunInspectorHardeningDurability as aU, type ArkRunInspectorMonitorBuildOptions as aV, type ArkRunInspectorOutboxMonitor as aW, type ArkRunInspectorOutboxRecordSummary as aX, ArkRunInspectorProductionError as aY, type ArkRunInspectorSnapshot as aZ, type ArkRunInspectorSnapshotInput as a_, ARK_RUN_GRAPH_TECHNICAL_EDGE_KINDS as aa, ARK_RUN_INFORMATION_PACKAGE_SCHEMA_VERSION as ab, ARK_RUN_INSPECTOR_DEFAULT_HOST as ac, ARK_RUN_INSPECTOR_DEFAULT_PORT as ad, ARK_RUN_INSPECTOR_EVENTS_PATH as ae, ARK_RUN_INSPECTOR_GRAPH_PATH as af, ARK_RUN_INSPECTOR_MONITOR_SAMPLE_LIMIT as ag, ARK_RUN_INSPECTOR_OUTBOX_PATH as ah, ARK_RUN_INSPECTOR_SCHEMA_VERSION as ai, ARK_RUN_INSPECTOR_SNAPSHOT_PATH as aj, ARK_RUN_INSPECTOR_SSE_EVENT as ak, ARK_RUN_INSPECTOR_TRANSPORT_FALLBACK as al, ARK_RUN_INSPECTOR_WORKFLOWS_PATH as am, ARK_RUN_TRANSPORT_KINDS as an, type ArchitectureLayer as ao, type ArchitectureLayerConfig as ap, type ArchitectureRule as aq, type ArkManifestArchitecture as ar, type ArkManifestData as as, type ArkManifestEntityLink as at, type ArkManifestGraph as au, type ArkManifestIntent as av, type ArkManifestPolicy as aw, type ArkManifestProjection as ax, type ArkRunBrokerAdapter as ay, type ArkRunComponentLifetime as az, type AuditRecord as b, formatArkRunInspectorSseEvent as b$, type ArkRunInspectorStoreDurability as b0, type ArkRunInspectorStoreDurabilityKind as b1, type ArkRunInspectorStoreRole as b2, type ArkRunInspectorTransportFacts as b3, type ArkRunInspectorWorkflowSummary as b4, type ArkRunInspectorWorkflowsMonitor as b5, type ArkRunPublisher as b6, type ArkRunRegisterOptions as b7, type ArkRunRegistrationHandle as b8, type ArkRunSendOptions as b9, type OutboxStore as bA, type PolicyEvaluationResult as bB, type ProjectionCheckpoint as bC, type ProjectionDefinition as bD, type PublishedEventRecord as bE, type RetryPolicy as bF, type SagaStatus as bG, type SagaStep as bH, type StartArkRunInspectorOptions as bI, type TraceSink as bJ, type Unsubscribe as bK, type WorkflowDefinition as bL, type WorkflowStatus as bM, type WorkflowStep as bN, appendDecisionTape as bO, arkRunGraphQueryFromSearchParams as bP, arkRunInspectorUrl as bQ, buildArkRunInspectorHardening as bR, buildArkRunInspectorOutboxMonitor as bS, buildArkRunInspectorSnapshot as bT, buildArkRunInspectorWorkflowsMonitor as bU, buildDependencyInformationPackage as bV, classifyArkRunInspectorStoreDurability as bW, closeArkRunGraphQuery as bX, closedArkRunEphemeral as bY, closedArkRunTransportKind as bZ, formatArkRunGraphMermaid as b_, type ArkRunSendPlan as ba, type ArkRunSendPlanInput as bb, type ArkRunSendResult as bc, type ArkRunTransportKind as bd, type AuditRecordInput as be, type AuditRecordType as bf, type CorrelationId as bg, type EntityMeta as bh, type EventContractIssue as bi, type EventHandler as bj, type EventInterceptionInfo as bk, type EventInterceptor as bl, type EventInterceptorContext as bm, type EventMetadata as bn, type EventPayloadPatch as bo, type EventPayloadSchema as bp, type EventPublisher as bq, type EventSchemaField as br, type EventSchemaFieldType as bs, type FieldMeta as bt, type GraphNode as bu, type IntentRelationshipKind as bv, InvalidArkRunGraphQueryError as bw, InvalidArkRunSendOptionError as bx, type ObservabilityFlow as by, type ObservedLayerFlowMode as bz, type AuditQuery as c, isArkRunInspectorLoopbackHost as c0, isArkRunInspectorProductionEnv as c1, requestArkRunGraph as c2, resolveArkRunInspectorBind as c3, resolveArkRunSendPlan as c4, startArkRunInspector as c5, unavailableArkRunInspectorOutboxMonitor as c6, unavailableArkRunInspectorWorkflowsMonitor as c7, type CreateAuditTrailOptions as d, type AuditTrail as e, type CreateArchitectureProfileOptions as f, type ArchitectureProfile as g, type ArkCheckConfig as h, type CreateArchitectureProfileFromArkConfigOptions as i, type CreateElevenLayerArkConfigOptions as j, type EventContract as k, type DomainEvent as l, type EventContractValidationResult as m, type IntentName as n, type DefineIntentOptions as o, type IntentCreator as p, type CreateProjectionRegistryOptions as q, type PolicyViolation as r, type PolicySeverity as s, type PolicyEnforcementMode as t, type Policy as u, type IntentRelationship as v, type EventBufferStore as w, type EventBufferRecord as x, type EventBufferStatus as y, type EventBusOptions as z };
|
package/docs/README.md
CHANGED
|
@@ -73,7 +73,8 @@ These are **not** the day-to-day product path. They stay in the repo for evidenc
|
|
|
73
73
|
| Field adoption kit (scaffolding, not closed) | [field/](field/) |
|
|
74
74
|
| Runtime hardening (experimental) | [production-hardening.md](production-hardening.md) |
|
|
75
75
|
|
|
76
|
-
Current release: [CHANGELOG](../CHANGELOG.md) (`arkgate@4.8.
|
|
76
|
+
Current release: [CHANGELOG](../CHANGELOG.md) (`arkgate@4.8.25`; confirm npm with `npm view arkgate@4.8.25 version`; does not close `K01`).
|
|
77
|
+
Prior published: [CHANGELOG](../CHANGELOG.md) (`arkgate@4.8.24`).
|
|
77
78
|
Prior published: [CHANGELOG](../CHANGELOG.md) (`arkgate@4.8.23`).
|
|
78
79
|
Prior published: [CHANGELOG](../CHANGELOG.md) (`arkgate@4.8.22`).
|
|
79
80
|
Prior published: [CHANGELOG](../CHANGELOG.md) (`arkgate@4.8.21`).
|
package/docs/agent-guide.md
CHANGED
|
@@ -41,7 +41,7 @@ the project API is unusable. See the distribution and completeness boundary in
|
|
|
41
41
|
ark start → ark start --apply → ark-check --doctor
|
|
42
42
|
day to day: compact router / MCP place + validate + check
|
|
43
43
|
guided work: install skill pack → /ark-autopilot
|
|
44
|
-
optional: arkRules map + arkrules/*.json (intra-layer; starts advisory)
|
|
44
|
+
optional: arkRules map (one path or a list) + arkrules/*.json, or childSlices.arkRulesFile at a slice root (intra-layer; starts advisory)
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
`arkgate-check --doctor` shows what's wrong and what to do first. From **4.0.0**, doctor may
|
|
@@ -621,6 +621,9 @@ block a promotion, and the surface names which one fired:
|
|
|
621
621
|
- **`no-coverage-evidence`** — an invariant whose evidence does not support
|
|
622
622
|
promotion. The text is `canPromoteInvariant`'s own, so this surface can never
|
|
623
623
|
promise a promotion the gate then refuses.
|
|
624
|
+
- **`probe-survived`** — the committed invariant probe shows the covering tests
|
|
625
|
+
still pass with the rule broken, or never call it. Same judge; named apart
|
|
626
|
+
because the fix is a stronger test. See [Probe an invariant](#probe-an-invariant).
|
|
624
627
|
|
|
625
628
|
It needs no TypeScript and runs no analysis: the contract, the ArkRules
|
|
626
629
|
documents it points at, and the coverage evidence walk (a filesystem walk plus a
|
|
@@ -675,6 +678,63 @@ than a targeted text edit. Exit 0 for a preview or a successful write, 1 for an
|
|
|
675
678
|
unknown rule id or a refused write, 2 for bad arguments or ArkRules references
|
|
676
679
|
that will not load.
|
|
677
680
|
|
|
681
|
+
### Probe an invariant
|
|
682
|
+
|
|
683
|
+
A test title that names an invariant counts as coverage. That proves the test
|
|
684
|
+
exists, not that it would fail if the rule broke. The probe checks that, on
|
|
685
|
+
request:
|
|
686
|
+
|
|
687
|
+
```bash
|
|
688
|
+
npx arkgate-check --probe-invariants # every invariant with a coverage.symbol
|
|
689
|
+
npx arkgate-check --probe-invariants=INV-REFUND-WINDOW
|
|
690
|
+
npx arkgate-check --probe-invariants --write # save .ark/invariant-probe.json
|
|
691
|
+
npx arkgate-check --probe-invariants --runner vitest # only when the runner is unclear
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
```text
|
|
695
|
+
INV-REFUND-WINDOW: the tests still pass when the guard is negated (src/domain/refunds/refundPolicy.ts:14).
|
|
696
|
+
The test names the rule but does not pin it. Next: add a case that fails when the rule is broken, then re-run with --write.
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
For each invariant with a `coverage.symbol`, it copies the project to a
|
|
700
|
+
temporary folder, then runs only the covering tests (titles that name the id,
|
|
701
|
+
and tests that import the symbol's file), with your own runner (vitest, jest or
|
|
702
|
+
`node --test`):
|
|
703
|
+
|
|
704
|
+
1. unchanged — they must pass;
|
|
705
|
+
2. with the file throwing on load — a test must fail, or the copy is not the one
|
|
706
|
+
the tests load (`inconclusive`);
|
|
707
|
+
3. with the symbol throwing when called — a test must fail, or the tests never
|
|
708
|
+
call it (`not-reached`);
|
|
709
|
+
4. with at most three small changes inside the symbol (negate a guard, drop a
|
|
710
|
+
`throw`, flip or shift a comparison, shift a constant) — each must make a test
|
|
711
|
+
fail, or the change went unnoticed (`survived`).
|
|
712
|
+
|
|
713
|
+
Every row reads `killed`, `survived`, `not-reached`, `inconclusive` or
|
|
714
|
+
`unprobeable` (no symbol, a type or interface, no covering test — a declaration
|
|
715
|
+
is not a test). It is not a score.
|
|
716
|
+
|
|
717
|
+
**Your files are never changed.** Every change happens in the copy, which is
|
|
718
|
+
removed when the run ends, including on Ctrl-C. `--write` adds only
|
|
719
|
+
`.ark/invariant-probe.json`. Exit 0 when nothing survived or went unreached,
|
|
720
|
+
1 when something did, 2 when it could not run (`reasonCode` in the JSON).
|
|
721
|
+
|
|
722
|
+
**What the result can do.** Only refuse. When the committed file has a fresh
|
|
723
|
+
`survived` or `not-reached` row, `--promote` and the policy delta refuse to
|
|
724
|
+
promote that invariant to `enforced` (blocker `probe-survived`). Fresh means
|
|
725
|
+
the symbol file, every covering test and the invariant are unchanged since the
|
|
726
|
+
run; anything else is stale and changes nothing, like `killed`, `inconclusive`
|
|
727
|
+
or no file at all. Status and `--rules-inventory` show the state per invariant
|
|
728
|
+
(`INVARIANT_PROBE_SURVIVED` when it refuses). CI sees the refusal only if you
|
|
729
|
+
commit the file.
|
|
730
|
+
|
|
731
|
+
**Trust.** Running the probe runs your tests, exactly like `npm test`; you start
|
|
732
|
+
it, nothing else does. It never runs from the write hook, MCP, ESLint, the
|
|
733
|
+
GitHub Action or `--strict-merge`, and refuses to combine with them. The runner
|
|
734
|
+
gets a short list of environment variables (no tokens, proxies pointed at a
|
|
735
|
+
dead port, `HOME` and the temp folder inside the copy). That is best effort,
|
|
736
|
+
not a sandbox.
|
|
737
|
+
|
|
678
738
|
### Literal path drift after a rename (`--path-drift`)
|
|
679
739
|
|
|
680
740
|
A repo path written inside a **string, a comment or a docstring** is invisible to
|
|
@@ -747,6 +807,78 @@ TS/TSX gate the type-aware passes use, because a comment is not code and the
|
|
|
747
807
|
class was first found in a `.css` file. Generated files are skipped, and every
|
|
748
808
|
file the walk refuses is counted by reason in the output.
|
|
749
809
|
|
|
810
|
+
### Files nothing imports
|
|
811
|
+
|
|
812
|
+
A rewrite often lands next to the old file, and the old one stays. Nothing
|
|
813
|
+
imports it. Status reads that from the import edges the check already resolved,
|
|
814
|
+
so it costs no second analysis and never changes the check.
|
|
815
|
+
|
|
816
|
+
```bash
|
|
817
|
+
npx arkgate-check --doctor # one dim count line at most
|
|
818
|
+
npx arkgate-check --doctor --all # the list, plus exports nothing imports by name
|
|
819
|
+
npx arkgate-check --doctor --json # doctor.orphanModules
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
```text
|
|
823
|
+
Nothing imports src/lib/legacy-pricing.ts, and no entry point covers it.
|
|
824
|
+
Next: Delete it through the write gate, or add it to .ark/entry-points.json if a framework loads it.
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
A file is listed only when no governed file, no test, no project script and no
|
|
828
|
+
known entry point imports it. Entry points come from `package.json` (`main`,
|
|
829
|
+
`exports`, `bin`, scripts — built `dist/` paths map back to source), CI workflow
|
|
830
|
+
run steps, framework conventions (Next routes and `middleware`, Vite
|
|
831
|
+
`index.html`, Nest `main`, Vercel `api/`, Storybook stories), the arkRun /
|
|
832
|
+
arkOrder roots in `ark.config.json`, config and setup files, ambient declaration
|
|
833
|
+
files, and `.ark/entry-points.json`. A file only tests import is counted, not
|
|
834
|
+
listed.
|
|
835
|
+
|
|
836
|
+
When a dynamic import, `import.meta.glob`, `new URL(…, import.meta.url)`, a
|
|
837
|
+
quoted path, or an import that did not resolve could still reach a file, the
|
|
838
|
+
item says so (`maybe-dynamic`, `maybe-unresolved`) and the section is
|
|
839
|
+
`partial`. Read those before deleting. A framework or loader ArkGate does not
|
|
840
|
+
know goes in the sidecar, with a reason and an optional review date:
|
|
841
|
+
|
|
842
|
+
```json
|
|
843
|
+
{
|
|
844
|
+
"schemaVersion": "1",
|
|
845
|
+
"entryPoints": [
|
|
846
|
+
{ "glob": "src/plugins/**", "reason": "loaded by name from the plugin manifest", "reviewBy": "2027-01-01" }
|
|
847
|
+
]
|
|
848
|
+
}
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
Delete one file at a time through the write gate (`/ark-fix`), then run status
|
|
852
|
+
again. Never delete a `maybe-*` item without reading what may load it.
|
|
853
|
+
|
|
854
|
+
### Copies across a wall
|
|
855
|
+
|
|
856
|
+
A slice wall denies the import. The cheapest way around it is to copy the code,
|
|
857
|
+
and a copy is not an import, so the check cannot see it. Status details can.
|
|
858
|
+
|
|
859
|
+
```bash
|
|
860
|
+
npx arkgate-check --doctor --all # the list, with a place the shared code could live
|
|
861
|
+
npx arkgate-check --doctor --all --json # doctor.crossWallDuplication
|
|
862
|
+
```
|
|
863
|
+
|
|
864
|
+
```text
|
|
865
|
+
This code is copied between src/features/billing and src/features/invoices (34 of 35 names match).
|
|
866
|
+
The wall stops the import, not the copy. Next: move it to src/shared/ with /ark-place.
|
|
867
|
+
```
|
|
868
|
+
|
|
869
|
+
A copy is listed only when its two files sit on two sides of a wall the check
|
|
870
|
+
would enforce — two slices, two child slices of one universe — or in two
|
|
871
|
+
layers. Copies inside one slice are counted, never listed: the slice may
|
|
872
|
+
import its own code. The suggested home comes from your config: the declared
|
|
873
|
+
`sharedRoots`, the universe common folder (`childSlices.commonFolders`), or the
|
|
874
|
+
lower layer both sides may import. When none fits, it says `/ark-place`.
|
|
875
|
+
|
|
876
|
+
Compact status never runs this; its JSON says `not-run` and names the command.
|
|
877
|
+
Tests, `.d.ts`, generated files and files over 256 KB are never read for it. The
|
|
878
|
+
thresholds are fixed (at least 50 tokens and 5 lines, and most names matching);
|
|
879
|
+
there is no config key. Move one copy at a time through the write gate
|
|
880
|
+
(`/ark-fix`), import it from both sides, then run status again.
|
|
881
|
+
|
|
750
882
|
### Presets
|
|
751
883
|
|
|
752
884
|
- `hexagonal` / `layered` / `feature-sliced` / `monorepo` / **`ui-surface`** (UI/Vite/Remotion-style) / **`vertical-slice`** (features/* + peerIsolation) / **`ddd-bounded-contexts`** (contexts/*/domain|application|infra + shared kernel)
|
|
@@ -1421,7 +1553,7 @@ The server exposes these thirteen tools. Every tool accepts the additive
|
|
|
1421
1553
|
| `ark_manifest` | No non-project args: return the machine-readable architecture contract with an authoritative binding after the identity handshake. |
|
|
1422
1554
|
| `validate_code` | `{ source, layer?, filePath? }`: single-file lexical check (layer plane plus the enforced ArkRun / ArkRules structure / ArkOrder sensors CI runs on that file); infer the layer from `filePath` when possible. Always partial: `valid:false` / `isError:true` until complete-candidate preflight — read `lexicalValid` for the one-file verdict. Not a hook; hard blocking is `arkgate-mcp --hook`. |
|
|
1423
1555
|
| `ark_check` | `{ strict?, baseline? }`: run the full project architecture check. `verdict` separates `identity`, `completeness`, `graph`, `coverage`, `gates`, and `overallOk`; no individual green fact substitutes for the combined verdict. |
|
|
1424
|
-
| `ark_policy_delta` | `{ baseConfig, candidateConfig?, baseArkRuleFiles?, candidateArkRuleFiles?, acknowledgement? }`: classify a complete contract transition, ArkRules included; never edits the contract. `baseArkRuleFiles` (`{ "<path from baseConfig.arkRules>": <file JSON> }`) is required when `baseConfig` maps `arkRules`. Weakening / new layer / new allow edge needs `adrPath` on the acknowledgement. |
|
|
1556
|
+
| `ark_policy_delta` | `{ baseConfig, candidateConfig?, baseArkRuleFiles?, candidateArkRuleFiles?, acknowledgement? }`: classify a complete contract transition, ArkRules included; never edits the contract. `baseArkRuleFiles` (`{ "<path from baseConfig.arkRules>": <file JSON> }`) is required when `baseConfig` maps `arkRules`. Include each `childSlices.arkRulesFile` path in that map when the wall discovers one. Weakening / new layer / new allow edge needs `adrPath` on the acknowledgement. |
|
|
1425
1557
|
| `ark_coverage` | No args: report per-layer counts, every unclassified file, unmatched layers, and missing rule edges. |
|
|
1426
1558
|
| `ark_place` | `{ filePath, description? }`: resolve the governed home for `filePath` (fail-closed without it; never invents a path) and return its import/global constraints. |
|
|
1427
1559
|
| `ark_prepare_write` | `{ source, filePath, description?, layer? }`: compose placement and snippet validation, with hashes and a mechanical-safe patch when available. `filePath` is required (fail-closed). Partial like `validate_code`: read `lexicalValid`. |
|
package/docs/ai-gates.md
CHANGED
|
@@ -941,13 +941,27 @@ but stays advisory.
|
|
|
941
941
|
**command**. The hard merge boundary is making that job a **required GitHub status context** —
|
|
942
942
|
not “workflow file present.”
|
|
943
943
|
|
|
944
|
+
**Skipped jobs and `needs:`:** GitHub reports a skipped job as a status that satisfies branch
|
|
945
|
+
protection. Doctor therefore counts an Ark job as fail-closed only when nothing can skip it on
|
|
946
|
+
purpose:
|
|
947
|
+
|
|
948
|
+
| Ark job shape | Workflow evidence | Required-status verdict (`ARK_DOCTOR_GITHUB=1`) |
|
|
949
|
+
|---------------|-------------------|--------------------------------------------------|
|
|
950
|
+
| No `if:`, or `if: true` / `always()` | fail-closed | required when its context is required |
|
|
951
|
+
| `needs:` jobs with no conditional `if:` anywhere up the chain | fail-closed (it only skips when a needed job fails) | required only when every needed job is also required; otherwise `unverified` plus gap `enforcement-ark-check-upstream-not-required` |
|
|
952
|
+
| Job-level `if:` on a profile output (or any other condition), or a conditional job in its `needs:` chain | not fail-closed (the skip reports success) | not counted |
|
|
953
|
+
| `continue-on-error: true` on the job or the Ark step | not fail-closed | not counted |
|
|
954
|
+
|
|
955
|
+
A required check bound to the GitHub Actions app counts. A check bound to another app stays
|
|
956
|
+
`unverified`. Doctor queries branch protection only with `ARK_DOCTOR_GITHUB=1` and a working `gh`.
|
|
957
|
+
|
|
944
958
|
Or use the repository's composite Action at a pinned release or commit. Pin the tag (or commit
|
|
945
959
|
SHA) that matches the `arkgate` version in your `package.json` and write hook. The Action runs the
|
|
946
960
|
checker from the ref you pin, so an older ref runs an older checker, and that checker rejects newer
|
|
947
961
|
config keys (for example `schemaVersion` 1.3, `childSlices`, `sliceIdentity`) with exit 2:
|
|
948
962
|
|
|
949
963
|
```yaml
|
|
950
|
-
- uses: pedroknigge/arkgate@v4.8.
|
|
964
|
+
- uses: pedroknigge/arkgate@v4.8.25 # same version as the arkgate devDependency
|
|
951
965
|
with:
|
|
952
966
|
root: .
|
|
953
967
|
config: ark.config.json
|
package/docs/configuration.md
CHANGED
|
@@ -132,12 +132,24 @@ Top-level fields:
|
|
|
132
132
|
`enforced`. Declaring nothing stays silent unless any invariant is already enforced — then
|
|
133
133
|
missing roots fail closed (`INVARIANT_COVERAGE_ROOTS_MISSING`), because otherwise coverage can
|
|
134
134
|
certify a test the project never declared a runner root for.
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
`
|
|
140
|
-
|
|
135
|
+
|
|
136
|
+
ArkGate never executes tests — except the opt-in `arkgate-check --probe-invariants`, which
|
|
137
|
+
you run yourself: it breaks an invariant's `coverage.symbol` on purpose in a temporary copy
|
|
138
|
+
and runs only its covering tests with your own runner. Its committed result
|
|
139
|
+
(`.ark/invariant-probe.json`) can only **refuse** a promotion, never grant one, and it is
|
|
140
|
+
never part of a check or the merge gate. No config key. See
|
|
141
|
+
[Probe an invariant](agent-guide.md#probe-an-invariant).
|
|
142
|
+
- **`arkRules`** (optional, schema `1.1+`) — map of layer name → one project-relative path, or a
|
|
143
|
+
list of paths merged into that layer's catalog (`"DomainModel": "arkrules/DomainModel.json"`
|
|
144
|
+
or `"DomainModel": ["arkrules/DomainModel.json", "arkrules/DomainModel.shared.json"]`). A
|
|
145
|
+
string keeps today's behaviour. Keys must match a declared layer. The same effective id in
|
|
146
|
+
two files is `ARKRULE_DUPLICATE_ID` and config load fails closed. Missing or invalid
|
|
147
|
+
referenced files **fail closed**. A `arkrules/*.json` file the map does not reference, and a
|
|
148
|
+
slice file named `arkrules.<Layer>.json` beside governed code that discovery did not read,
|
|
149
|
+
is advisory drift: `ARKRULE_FILE_UNREFERENCED` in check `warnings`,
|
|
150
|
+
`rulesUnderContract.unreferencedFiles` in doctor, and `arkRulesCatalog.unreferencedFiles` in
|
|
151
|
+
MCP `ark_manifest`. It never fails the check. Doctor `rulesUnderContract.bySlice` lists the
|
|
152
|
+
rules a child slice contributed. `ark_place` shows those ids as `sliceRules` next to the layer.
|
|
141
153
|
- **`arkRun`** (optional, schema `1.2+`) — inline ArkRun extra (`mode`, `kernelRoots`
|
|
142
154
|
(`compositionRoots` alias), `managedLayers`, `requireDeclarations`). Absence is silent. Unknown keys fail closed.
|
|
143
155
|
`managedLayers` must name existing `layers[].name` values. Empty `compositionRoots` in
|
|
@@ -290,6 +302,8 @@ Rule fields:
|
|
|
290
302
|
when both paths classify. Applies to **any** declared `from`→`to` pair, not only self-edges.
|
|
291
303
|
Missing paths, empty slice folders, or unclassifiable slices **fail closed** (deny — cannot
|
|
292
304
|
prove same-slice).
|
|
305
|
+
The wall denies imports; status details (`--doctor --all`) list code copied across it
|
|
306
|
+
(`doctor.crossWallDuplication`, advisory, no config key).
|
|
293
307
|
- `sliceFolders` is a bare name or a starred prefix. A bare name (`features`) stays an
|
|
294
308
|
unanchored one-segment match: `src/lib/features/projects/rfi/x.ts` with `["features"]` is
|
|
295
309
|
`features/projects`. The next segment is never a filename, so
|
|
@@ -429,9 +443,23 @@ Rule fields:
|
|
|
429
443
|
universe is `CROSS_PARENT_SLICE` and an import into another child of the same
|
|
430
444
|
universe is `CROSS_SIBLING_SLICE`. Same-child imports and imports into that
|
|
431
445
|
universe's common folders follow the existing child wall. Doctor lists every
|
|
432
|
-
alias as an owed move: the source glob, the target slice, the destination
|
|
433
|
-
folder, and the files. The section says
|
|
434
|
-
|
|
446
|
+
unpinned alias as an owed move: the source glob, the target slice, the destination
|
|
447
|
+
folder, and the files. The section says those files are not finished.
|
|
448
|
+
`"pinned": true` lists the alias under pinned instead. `reason` (for example
|
|
449
|
+
`"framework-route"`) is the label doctor prints. A reason alone does not pin.
|
|
450
|
+
A pinned route is not `slice-alias-debt` and does not clear any other honesty
|
|
451
|
+
reason, so `productHonesty.finished` stays false while real debt remains.
|
|
452
|
+
`childSlices.arkRulesFile` is a filename at each child root the wall already
|
|
453
|
+
resolved (`"arkrules.<Layer>.json"`). `<Layer>` is the only token. The file is
|
|
454
|
+
law: it enters `policyHash`, and a path added or removed is one
|
|
455
|
+
`arkrules-ref-added` or `arkrules-ref-removed`. The effective id is
|
|
456
|
+
`<childId>#<localId>`. Omitting `appliesTo` scopes the rule to the slice
|
|
457
|
+
directory. An explicit `appliesTo` outside that directory is
|
|
458
|
+
`ARKRULE_SCOPE_ESCAPES_SLICE` and config load fails closed. A filename
|
|
459
|
+
`arkrules.<Layer>.json` is a law path for mixed-law classification. An older
|
|
460
|
+
build rejects the array form, `arkRulesFile`, `pinned`, and `reason` at config
|
|
461
|
+
load. Aliases
|
|
462
|
+
are debt while any unpinned alias remains. `productHonesty.finished` stays false while that debt, or any other honesty reason, remains.
|
|
435
463
|
Adding aliases is a strengthening policy delta (unclassified files come under
|
|
436
464
|
the walls). Removing them is weakening (those files leave the walls) and needs
|
|
437
465
|
the same hash-bound acknowledgement as any other weakening. Additions and
|
|
@@ -653,7 +681,7 @@ Each `arkrules/<Layer>.json` may declare:
|
|
|
653
681
|
|
|
654
682
|
| Section | Purpose | Modes | What it really enforces |
|
|
655
683
|
|---------|---------|--------|-------------------------|
|
|
656
|
-
| `structure[]` | Closed sensor ids (e.g. `orchestration-only`, `thin-adapter`, `writes-via-aggregate`, `aggregate-private-state`, `always-valid-factory`, `domain-event-on-mutation`, `no-anemic-model`) | `advisory` (default) or `enforced` | **Heuristics of module shape** — not proof that logic was extracted to Domain. `writes-via-aggregate` is driver
|
|
684
|
+
| `structure[]` | Closed sensor ids (e.g. `orchestration-only`, `thin-adapter`, `writes-via-aggregate`, `aggregate-private-state`, `always-valid-factory`, `domain-event-on-mutation`, `no-anemic-model`) | `advisory` (default) or `enforced` | **Heuristics of module shape** — not proof that logic was extracted to Domain. `writes-via-aggregate` is a driver import plus a write token, or a SQL write head inside a tagged template, in the declaring layer (ADR 0032). Tier-2 sensors (`no-anemic-model`) stay advisory-only (cannot promote to enforced). Class shapes come from a tokenizer that skips strings, comments, template literals and regex literals; a class it cannot walk to its end is reported as `shape analysed until character N` (an error under an enforced sensor), never passed in silence. |
|
|
657
685
|
| `invariants[]` | Stable ids + description + `coverage` (`test` / `symbol`) + optional `appliesTo` globs | `advisory` or `enforced` | **Named policy + evidence.** `coverage.symbol` means a declaration of that identifier in a non-test file (witness path `symbolEvidenceFile`, project-relative; additive `shape`: `function`, `class`, `const`, `method`, `type`, `interface`, or `enum`). A `Class.member` symbol (e.g. `Order.ensureInvariants`) requires a member with that name inside the body of `class Class`, a `const Class = class { … }` expression, a `namespace Class { … }` (function or const), or a top-level key of a `const Class = { … }` object literal; a member of another container, a nested object key, a free function, or a file that only mentions the class name does not count. The search is not restricted to the invariant's layer. `coverage.test: false` without a `coverage.symbol` declares no evidence: it is advisory-only (an enforced invariant with that shape reports `INVARIANT_UNCOVERED` and fails strict; the rest of the catalog still evaluates) and cannot be promoted. Imports and test calls do not count. A `describe` / `it` / `test` / `context` title may also name the invariant id. A comment, string, or other bare mention does not. Does **not** execute tests or business logic and does **not** replace behavior/property tests. Doctor and `--rules-inventory` print the witness path and discard counts on green runs too. A declaration match is not “the tests pass.” |
|
|
658
686
|
|
|
659
687
|
**Reporting:** diagnostics carry `evidence.arkruleId` + `evidence.arkruleSource`. Label residual
|
|
@@ -817,7 +845,8 @@ MCP clients can call `ark_policy_delta` with the previous `baseConfig`, an optio
|
|
|
817
845
|
contract (the current project contract is the default), and the same optional acknowledgement.
|
|
818
846
|
When `baseConfig` maps `arkRules`, pass the base catalog as data in `baseArkRuleFiles`
|
|
819
847
|
(`{ "<path from baseConfig.arkRules>": <ArkRules file JSON> }`); without it the call is refused
|
|
820
|
-
instead of returning a config-only verdict.
|
|
848
|
+
instead of returning a config-only verdict. When `childSlices.arkRulesFile` is set, include each
|
|
849
|
+
discovered slice file in that same map, keyed by its project-relative path. The candidate catalog is read from disk when the
|
|
821
850
|
candidate is omitted or maps the same `arkRules` files as the project contract (after the loader's
|
|
822
851
|
normalisation, so the project `ark.config.json` passed verbatim counts); otherwise pass
|
|
823
852
|
`candidateArkRuleFiles` in the same shape.
|