arkgate 4.8.11 → 4.8.13
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 +43 -2
- package/README.md +22 -32
- package/bin/ark-check-runtime.mjs +2 -0
- package/bin/lib/analysis-engine.mjs +4 -4
- package/bin/lib/ark-order-doctor.mjs +154 -0
- package/bin/lib/ark-order-report.mjs +64 -0
- package/bin/lib/ark-order-sensors.mjs +1 -1
- package/bin/lib/diagnostic-catalog.mjs +2 -2
- package/bin/lib/doctor-advisories.mjs +91 -18
- package/bin/lib/doctor-human.mjs +2 -10
- package/bin/lib/doctor-plan.mjs +4 -3
- package/bin/lib/extra-merge-teeth.mjs +32 -4
- package/bin/lib/html-report-advisories.mjs +2 -0
- package/bin/lib/html-report-depth.mjs +8 -18
- package/bin/lib/html-report.mjs +16 -0
- package/bin/lib/remediation.mjs +5 -5
- package/bin/lib/rules-under-contract.mjs +14 -0
- package/bin/lib/start-preview.mjs +1 -0
- package/bin/lib/status-command.mjs +28 -0
- package/bin/lib/status-manifest.mjs +23 -0
- package/bin/lib/violations.mjs +10 -1
- package/dist/{diagnosticCatalog-DiflIock.d.ts → diagnosticCatalog-DA565Lja.d.ts} +1 -1
- package/dist/eslint/index.cjs +4 -4
- package/dist/eslint/index.js +4 -4
- package/dist/index.cjs +31 -31
- package/dist/index.d.ts +71 -3
- package/dist/index.js +31 -31
- package/dist/nestjs/index.cjs +1 -1
- package/dist/nestjs/index.js +1 -1
- package/dist/runtime/index.cjs +15 -15
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +15 -15
- package/docs/README.md +4 -3
- package/docs/agent-guide.md +2 -1
- package/docs/arkorder.md +28 -10
- package/docs/package-surface.md +2 -1
- package/docs/product-voice.md +9 -8
- package/docs/use.md +1 -1
- package/package.json +1 -1
- package/schemas/ark.status-manifest.schema.json +47 -0
- package/server.json +2 -2
package/bin/lib/remediation.mjs
CHANGED
|
@@ -239,15 +239,15 @@ export function deterministicNextAction(violation) {
|
|
|
239
239
|
case 'ARKORDER_KERNEL_IN_DOMAIN':
|
|
240
240
|
return 'Move the arkgate/order import out of the Domain-role layer into a plane root or adapter, then preflight again. Never mechanical-safe.';
|
|
241
241
|
case 'ARKORDER_GENERIC_UPDATE':
|
|
242
|
-
return '
|
|
242
|
+
return 'Don\'t use a generic update. First freeze with release(). Later, propose the change, then apply it.';
|
|
243
243
|
case 'ARKORDER_TOO_MANY_PARAMS':
|
|
244
244
|
return 'Cut ξ to the slow keys that actually slave the rest, then preflight again. Never mechanical-safe.';
|
|
245
245
|
case 'ARKORDER_INGEST_WRITES_XI':
|
|
246
246
|
return 'Keep ingest results as absorb/escalate_up/hold only. Change ξ with proposeRelease then apply(ProposeResult). Never mechanical-safe.';
|
|
247
247
|
case 'ARKORDER_XI_FIELD_WRITE':
|
|
248
248
|
return typeof violation.target === 'string' && violation.target.length > 0
|
|
249
|
-
? `
|
|
250
|
-
: '
|
|
249
|
+
? `Don't write ${violation.target} from a use-case. Take the event in, or change that choice through the valve (proposeRelease then apply), not a generic update.`
|
|
250
|
+
: "Don't write a named product choice from a use-case. Take the event in, or change that choice through the valve (proposeRelease then apply), not a generic update.";
|
|
251
251
|
case 'ARKORDER_UNVALVED_RELEASE':
|
|
252
252
|
return 'Change ξ with proposeRelease then apply(ProposeResult). release() is only the first freeze. Never mechanical-safe.';
|
|
253
253
|
default:
|
|
@@ -528,7 +528,7 @@ export function enrichViolationWithFixClass(violation) {
|
|
|
528
528
|
enriched.effort = 'medium';
|
|
529
529
|
enriched.enthusiastHint =
|
|
530
530
|
violation.ruleId === 'ARKORDER_GENERIC_UPDATE'
|
|
531
|
-
? '
|
|
531
|
+
? 'Don\'t PATCH the billing plan. First freeze with release(), or propose the change then apply it.'
|
|
532
532
|
: violation.ruleId === 'ARKORDER_KERNEL_IN_DOMAIN'
|
|
533
533
|
? 'Domain stays plane-free. Import arkgate/order only from a listed plane root.'
|
|
534
534
|
: violation.ruleId === 'ARKORDER_TOO_MANY_PARAMS'
|
|
@@ -536,7 +536,7 @@ export function enrichViolationWithFixClass(violation) {
|
|
|
536
536
|
: violation.ruleId === 'ARKORDER_INGEST_WRITES_XI'
|
|
537
537
|
? 'ingest can absorb or escalate. It never writes a new house.'
|
|
538
538
|
: violation.ruleId === 'ARKORDER_XI_FIELD_WRITE'
|
|
539
|
-
? 'Name the
|
|
539
|
+
? 'Name the few big choices in arkOrder.xiKeys. Invoices and seats still flow; changing the plan goes through the valve, not a generic update.'
|
|
540
540
|
: violation.ruleId === 'ARKORDER_INFORMATION_BUDGET'
|
|
541
541
|
? 'A scale may not observe a denied kind. Cut it from the projector or from cannotObserve.'
|
|
542
542
|
: violation.ruleId === 'ARKORDER_XI_TTL'
|
|
@@ -62,6 +62,18 @@ function arkRunMergeInput(config, residualCount = 0) {
|
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
function arkOrderMergeInput(config, residualCount = 0) {
|
|
66
|
+
const extra = config?.arkOrder;
|
|
67
|
+
if (!extra || typeof extra !== 'object') {
|
|
68
|
+
return { present: false, mode: null, residualCount: 0 };
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
present: true,
|
|
72
|
+
mode: extra.mode === 'enforced' || extra.mode === 'advisory' ? extra.mode : null,
|
|
73
|
+
residualCount: Number(residualCount) || 0,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
65
77
|
export function summarizeRulesUnderContract(root, config, facts, classification) {
|
|
66
78
|
if (!config?.arkRules || Object.keys(config.arkRules).length === 0) {
|
|
67
79
|
return {
|
|
@@ -74,6 +86,7 @@ export function summarizeRulesUnderContract(root, config, facts, classification)
|
|
|
74
86
|
classification,
|
|
75
87
|
arkRules: { active: false },
|
|
76
88
|
arkRun: arkRunMergeInput(config),
|
|
89
|
+
arkOrder: arkOrderMergeInput(config),
|
|
77
90
|
}),
|
|
78
91
|
notAScore: true,
|
|
79
92
|
note: 'No arkRules map — intra-layer ArkRules are opt-in.',
|
|
@@ -187,6 +200,7 @@ export function summarizeRulesUnderContract(root, config, facts, classification)
|
|
|
187
200
|
uncovered: uncoveredInvariants,
|
|
188
201
|
},
|
|
189
202
|
arkRun: arkRunMergeInput(config),
|
|
203
|
+
arkOrder: arkOrderMergeInput(config),
|
|
190
204
|
});
|
|
191
205
|
|
|
192
206
|
return {
|
|
@@ -162,6 +162,7 @@ export function renderStartPreview(preview, options = {}) {
|
|
|
162
162
|
if (!applying) {
|
|
163
163
|
console.log('Setup: install package + host gates (see --json).');
|
|
164
164
|
console.log('Preview does not write. Apply installs CI.');
|
|
165
|
+
console.log('Optional extras stay off. This start is layers only — they stop bad imports.');
|
|
165
166
|
}
|
|
166
167
|
if (preview.runtimeActivation) {
|
|
167
168
|
console.log('Host: Codex is configured but not verified yet. Restart the host, then confirm this project.');
|
|
@@ -26,6 +26,7 @@ import { readBaseline } from './violations.mjs';
|
|
|
26
26
|
import { reportsDir, readJsonSafe } from './html-report.mjs';
|
|
27
27
|
import { summarizeRulesUnderContract } from './rules-under-contract.mjs';
|
|
28
28
|
import { projectStatusArkRun } from './ark-run-doctor.mjs';
|
|
29
|
+
import { projectStatusArkOrder } from './ark-order-doctor.mjs';
|
|
29
30
|
import { collectVsBaseFacts, discoverTeamBaseRef } from './team-parliament-io.mjs';
|
|
30
31
|
import { classifyAdopted, readAdoptionStance } from './adoption-stance.mjs';
|
|
31
32
|
|
|
@@ -354,6 +355,19 @@ export function collectStatusFacts(options = {}) {
|
|
|
354
355
|
return projectStatusArkRun({ present: true, mode, extraMergeTeeth, residual });
|
|
355
356
|
})();
|
|
356
357
|
|
|
358
|
+
const arkOrder = (() => {
|
|
359
|
+
const extra = config?.arkOrder;
|
|
360
|
+
if (!extra || typeof extra !== 'object') {
|
|
361
|
+
return projectStatusArkOrder({ present: false, residual: 0 });
|
|
362
|
+
}
|
|
363
|
+
const snap = latest?.arkOrder && typeof latest.arkOrder === 'object' ? latest.arkOrder : null;
|
|
364
|
+
const mode = extra.mode === 'enforced' || extra.mode === 'advisory' ? extra.mode : null;
|
|
365
|
+
const extraMergeTeeth =
|
|
366
|
+
snap && typeof snap.extraMergeTeeth === 'boolean' ? snap.extraMergeTeeth === true : false;
|
|
367
|
+
const residual = typeof snap?.residual === 'number' ? snap.residual : null;
|
|
368
|
+
return projectStatusArkOrder({ present: true, mode, extraMergeTeeth, residual });
|
|
369
|
+
})();
|
|
370
|
+
|
|
357
371
|
// DF02 — always project compass with honesty mode (never invent green residual).
|
|
358
372
|
// Prefer explicit override (tests/MCP inject doctor-facts); else report snapshot.
|
|
359
373
|
let improvementCompass = null;
|
|
@@ -403,6 +417,7 @@ export function collectStatusFacts(options = {}) {
|
|
|
403
417
|
latest?.designFitness?.designWeak === true ||
|
|
404
418
|
latest?.doctor?.designFitness?.designWeak === true,
|
|
405
419
|
arkRun: options.arkRun ?? arkRun,
|
|
420
|
+
arkOrder: options.arkOrder ?? arkOrder,
|
|
406
421
|
adopted:
|
|
407
422
|
options.adopted ??
|
|
408
423
|
classifyAdopted({
|
|
@@ -534,6 +549,19 @@ export function runStatusCommand(args = {}) {
|
|
|
534
549
|
' · not a score'
|
|
535
550
|
);
|
|
536
551
|
}
|
|
552
|
+
const arkOrderLine = manifest.arkOrder;
|
|
553
|
+
if (arkOrderLine && arkOrderLine.notAScore === true) {
|
|
554
|
+
const residual =
|
|
555
|
+
arkOrderLine.residual == null ? 'unknown' : String(arkOrderLine.residual);
|
|
556
|
+
write(
|
|
557
|
+
` arkOrder: ${arkOrderLine.present ? arkOrderLine.mode || 'on' : 'absent'}` +
|
|
558
|
+
` · residual=${residual}` +
|
|
559
|
+
(arkOrderLine.present
|
|
560
|
+
? ` · extraMergeTeeth=${arkOrderLine.extraMergeTeeth === true}`
|
|
561
|
+
: '') +
|
|
562
|
+
' · not a score'
|
|
563
|
+
);
|
|
564
|
+
}
|
|
537
565
|
write(` next: [${manifest.nextAction.id}] ${manifest.nextAction.summary}`);
|
|
538
566
|
}
|
|
539
567
|
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { projectStatusArkRun } from './ark-run-doctor.mjs';
|
|
12
|
+
import { projectStatusArkOrder } from './ark-order-doctor.mjs';
|
|
12
13
|
export const ARK_STATUS_MANIFEST_SCHEMA_VERSION = '1.0';
|
|
13
14
|
export const ARK_STATUS_MANIFEST_SCHEMA_URL = 'https://unpkg.com/arkgate@4/schemas/ark.status-manifest.schema.json';
|
|
14
15
|
/**
|
|
@@ -249,6 +250,12 @@ export function resolveStatusNextAction(facts, binding, activation, lastCheck, r
|
|
|
249
250
|
summary: 'ArkRun residual remains — wire kernel usage or declarations through arkgate/runtime. Not a score.',
|
|
250
251
|
};
|
|
251
252
|
}
|
|
253
|
+
if (facts.arkOrder?.present === true && (facts.arkOrder.residual ?? 0) > 0) {
|
|
254
|
+
return {
|
|
255
|
+
id: 'review-arkorder-residual',
|
|
256
|
+
summary: 'ArkOrder leftover remains — change that product choice through the valve (proposeRelease then apply), not a generic update. Not a score.',
|
|
257
|
+
};
|
|
258
|
+
}
|
|
252
259
|
if (facts.adopted === 'required-merge' || facts.adopted === 'advisory-only-acked') {
|
|
253
260
|
return {
|
|
254
261
|
id: 'stay-enforced',
|
|
@@ -336,6 +343,9 @@ export function buildStatusManifest(facts) {
|
|
|
336
343
|
if (facts.arkRun && typeof facts.arkRun === 'object') {
|
|
337
344
|
status.arkRun = projectStatusArkRun(facts.arkRun);
|
|
338
345
|
}
|
|
346
|
+
if (facts.arkOrder && typeof facts.arkOrder === 'object') {
|
|
347
|
+
status.arkOrder = projectStatusArkOrder(facts.arkOrder);
|
|
348
|
+
}
|
|
339
349
|
return status;
|
|
340
350
|
}
|
|
341
351
|
const STATUS_COMPASS_MODE_SET = new Set(STATUS_COMPASS_MODES);
|
|
@@ -628,5 +638,18 @@ export const ARK_STATUS_MANIFEST_SCHEMA = {
|
|
|
628
638
|
residual: { anyOf: [{ type: 'integer', minimum: 0 }, { type: 'null' }] },
|
|
629
639
|
},
|
|
630
640
|
},
|
|
641
|
+
arkOrder: {
|
|
642
|
+
type: 'object',
|
|
643
|
+
description: 'ArkOrder extra residual (notAScore). present/mode from config; residual is a finding-id count (null = unknown, not green). extraMergeTeeth is honesty, never a score.',
|
|
644
|
+
additionalProperties: false,
|
|
645
|
+
required: ['notAScore', 'present', 'mode', 'extraMergeTeeth', 'residual'],
|
|
646
|
+
properties: {
|
|
647
|
+
notAScore: { const: true },
|
|
648
|
+
present: { type: 'boolean' },
|
|
649
|
+
mode: { anyOf: [{ enum: ['advisory', 'enforced'] }, { type: 'null' }] },
|
|
650
|
+
extraMergeTeeth: { type: 'boolean' },
|
|
651
|
+
residual: { anyOf: [{ type: 'integer', minimum: 0 }, { type: 'null' }] },
|
|
652
|
+
},
|
|
653
|
+
},
|
|
631
654
|
},
|
|
632
655
|
};
|
package/bin/lib/violations.mjs
CHANGED
|
@@ -59,9 +59,18 @@ export const FIX_HINTS = {
|
|
|
59
59
|
'Break the cycle: extract the shared code into a module both sides import, invert one edge behind a port/interface, or merge the files if they are really one unit.',
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
+
/** Extra-plane label so a slow-key deny reads as clearly as a bad import. */
|
|
63
|
+
export function violationPlaneLabel(ruleId) {
|
|
64
|
+
if (typeof ruleId !== 'string') return '';
|
|
65
|
+
if (ruleId.startsWith('ARKORDER_')) return '[ArkOrder] ';
|
|
66
|
+
if (ruleId.startsWith('ARKRUN_')) return '[ArkRun] ';
|
|
67
|
+
return '';
|
|
68
|
+
}
|
|
69
|
+
|
|
62
70
|
export function printViolation(violation) {
|
|
63
71
|
const location = `${violation.file}:${violation.line}`;
|
|
64
|
-
|
|
72
|
+
const plane = violationPlaneLabel(violation.ruleId);
|
|
73
|
+
console.error(`${color.red('✖')} ${color.bold(`${plane}${violation.ruleId}`)} ${location}`);
|
|
65
74
|
if (violation.fromLayer && violation.toLayer) {
|
|
66
75
|
const target = violation.target ? ` ${color.dim(`(${violation.target})`)}` : '';
|
|
67
76
|
console.error(` ${violation.fromLayer} → ${violation.toLayer}${target}`);
|
|
@@ -392,7 +392,7 @@ declare function createAdapterResult(input: {
|
|
|
392
392
|
}): CurrentAdapterResult;
|
|
393
393
|
|
|
394
394
|
/** ArkGate library version — single source of truth. */
|
|
395
|
-
declare const version = "4.8.
|
|
395
|
+
declare const version = "4.8.13";
|
|
396
396
|
|
|
397
397
|
/**
|
|
398
398
|
* AI Code Gate (basic).
|