@event4u/agent-config 16.0.0 → 16.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +297 -137
- package/CONTRIBUTING.md +9 -0
- package/README.md +2 -2
- package/dist/agent-src/commands/analyze/inbox.md +26 -0
- package/dist/agent-src/commands/analyze/roadmap-repos.md +27 -0
- package/dist/agent-src/commands/challenge-me/closure.md +178 -0
- package/dist/agent-src/commands/challenge-me.md +9 -2
- package/dist/agent-src/commands/council/default.md +25 -5
- package/dist/agent-src/commands/feature/plan.md +28 -1
- package/dist/agent-src/commands/feature/roadmap.md +28 -1
- package/dist/agent-src/commands/implement-ticket.md +27 -0
- package/dist/agent-src/commands/jira-ticket.md +27 -0
- package/dist/agent-src/commands/pr/create.md +29 -0
- package/dist/agent-src/commands/pr/merge.md +60 -9
- package/dist/agent-src/commands/roadmap/ai-council.md +7 -1
- package/dist/agent-src/commands/roadmap/create.md +74 -27
- package/dist/agent-src/commands/roadmap/materialize.md +27 -0
- package/dist/agent-src/commands/roadmap/process-full.md +123 -18
- package/dist/agent-src/commands/team.md +22 -0
- package/dist/agent-src/contexts/authority/scope-growth-ownership.md +80 -0
- package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +47 -0
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +44 -3
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +15 -15
- package/dist/agent-src/contexts/execution/decision-closure-execution.md +93 -0
- package/dist/agent-src/contexts/execution/fix-loop-ladder.md +108 -0
- package/dist/agent-src/contexts/execution/plan-confidence-gate.md +4 -2
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +75 -6
- package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
- package/dist/agent-src/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
- package/dist/agent-src/guidelines/design-fidelity-routing.md +29 -0
- package/dist/agent-src/rules/autonomous-execution.md +15 -8
- package/dist/agent-src/rules/delegation-policy.md +23 -45
- package/dist/agent-src/rules/design-fidelity.md +32 -37
- package/dist/agent-src/rules/evaluator-independence.md +43 -49
- package/dist/agent-src/rules/test-first.md +41 -0
- package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +3 -3
- package/dist/agent-src/skills/ai-council/SKILL.md +11 -3
- package/dist/agent-src/skills/api-design/data/manifest.json +3 -3
- package/dist/agent-src/skills/database/data/manifest.json +4 -4
- package/dist/agent-src/skills/database/data/query-tuning.csv +3 -3
- package/dist/agent-src/skills/design-review/SKILL.md +50 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +14 -4
- package/dist/agent-src/skills/experiment-loop/SKILL.md +31 -1
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +1 -1
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +42 -3
- package/dist/agent-src/skills/threat-modeling/SKILL.md +9 -4
- package/dist/agent-src/skills/threat-modeling/data/manifest.json +4 -4
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +37 -3
- package/dist/agent-src/templates/agent-settings.md +1 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +188 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -0
- package/dist/cli-delegate/check_update_banner.js +40 -2
- package/dist/cli-delegate/chunk-4E2W63DA.js +335 -0
- package/dist/cli-delegate/chunk-5R7HOLAF.js +99 -0
- package/dist/cli-delegate/{chunk-IVBPRCQO.js → chunk-6KFEC3G7.js} +1 -1
- package/dist/cli-delegate/{chunk-2TAQ2K4V.js → chunk-6KM6ORRY.js} +55 -386
- package/dist/cli-delegate/{chunk-2XY7ILBT.js → chunk-FC75PGJE.js} +42 -2
- package/dist/cli-delegate/{chunk-GYC3VRYN.js → chunk-FXYUYU4N.js} +57 -13
- package/dist/cli-delegate/{chunk-55ACLDUE.js → chunk-GJCBB2UG.js} +168 -10
- package/dist/cli-delegate/{chunk-AK6HODNQ.js → chunk-HDVVGPQW.js} +873 -539
- package/dist/cli-delegate/{chunk-H32DGUJH.js → chunk-P6ZHP5W2.js} +1 -1
- package/dist/cli-delegate/{chunk-57PN4GYJ.js → chunk-RGNIWTEA.js} +1 -1
- package/dist/cli-delegate/chunk-ROYYTEZU.js +39 -0
- package/dist/cli-delegate/{chunk-3FKR64R5.js → chunk-UNCRJBT3.js} +31 -7
- package/dist/cli-delegate/{chunk-2DK2VJWG.js → chunk-WGXTVKCQ.js} +20 -6
- package/dist/cli-delegate/chunk-YDPILCOL.js +152 -0
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +1 -1
- package/dist/cli-delegate/cmd_conformance.js +90 -56
- package/dist/cli-delegate/cmd_doctor.js +7 -5
- package/dist/cli-delegate/cmd_explain.js +2 -2
- package/dist/cli-delegate/cmd_export.js +9 -7
- package/dist/cli-delegate/cmd_fleet.js +4 -2
- package/dist/cli-delegate/cmd_handoff.js +4 -4
- package/dist/cli-delegate/cmd_mcp_available.js +1 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +2 -2
- package/dist/cli-delegate/cmd_preflight.js +4 -2
- package/dist/cli-delegate/cmd_prune.js +10 -8
- package/dist/cli-delegate/cmd_route_audit.js +2 -2
- package/dist/cli-delegate/cmd_route_explain.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +2 -2
- package/dist/cli-delegate/cmd_settings_get.js +28 -2
- package/dist/cli-delegate/cmd_settings_migrate.js +9 -7
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +10 -8
- package/dist/cli-delegate/cmd_uninstall.js +16 -13
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +12 -10
- package/dist/cli-delegate/cmd_versions.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +85 -38
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +4 -4
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +10 -8
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +8 -6
- package/dist/hooks/dispatch.js +1832 -1007
- package/dist/install/claudeRuleRewrite.js +14 -3
- package/dist/install/conflict.js +60 -10
- package/dist/install/conflictTracker.js +218 -0
- package/dist/install/fsPrimitives.js +54 -0
- package/dist/install/install.mjs +2007 -1481
- package/dist/install/manifestFiles.js +259 -0
- package/dist/install/preflight.js +14 -2
- package/dist/install/preserve.js +157 -0
- package/dist/install/recordedOwnership.js +132 -0
- package/dist/install/txlog.js +11 -2
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +398 -39
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +3 -2
- package/dist/scripts/_lib/fs_atomic.js +167 -0
- package/dist/scripts/_lib/installed_tools.js +460 -0
- package/dist/scripts/_lib/lean_projection_mode.js +3 -2
- package/dist/scripts/_lib/settings_renamed_keys.js +78 -0
- package/dist/server/routes/install.js +8 -0
- package/dist/server/routes/wizard.js +9 -3
- package/dist/server/schemas/settings.js +17 -5
- package/dist/shared/missionExecution.js +97 -0
- package/dist/ui/assets/{index-D0jaCRPM.js → index-DH1xc62v.js} +17 -17
- package/dist/ui/index.html +1 -1
- package/docs/MIGRATION.md +103 -0
- package/docs/contracts/settings-classes.md +26 -7
- package/docs/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
- package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
- package/docs/guidelines/design-fidelity-routing.md +29 -0
- package/package.json +1 -1
- package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -0
- package/src/config/agent-settings.template.yml +139 -27
- package/src/config/auto-rule-budget.json +16 -0
- package/src/config/ci-local-parity.yml +18 -5
- package/src/config/continuity-surface.json +21 -0
- package/src/config/gate-coverage.yml +146 -13
- package/src/config/gate-violation-baselines.json +6 -6
- package/src/config/hook-token-budget.json +2 -0
- package/src/config/loop-surfaces.yaml +215 -0
- package/src/config/platform-anchor.json +3 -2
- package/src/config/release-gate-locality.yml +11 -0
- package/src/config/routing-coverage-seed.json +18 -4
- package/src/config/rule-enforcement-baseline.json +0 -1
- package/src/install/claudeRuleRewrite.ts +16 -2
- package/src/install/conflict.ts +65 -9
- package/src/install/conflictTracker.ts +299 -0
- package/src/install/fsPrimitives.ts +54 -0
- package/src/install/manifestFiles.ts +312 -0
- package/src/install/preflight.ts +16 -2
- package/src/install/preserve.ts +205 -0
- package/src/install/recordedOwnership.ts +149 -0
- package/src/install/txlog.ts +11 -2
- package/src/install/types.ts +19 -4
- package/src/scripts/_cli/cmd_conformance.ts +88 -15
- package/src/scripts/_cli/cmd_doctor.ts +4 -3
- package/src/scripts/_cli/cmd_route_explain.ts +9 -2
- package/src/scripts/_cli/cmd_settings_get.ts +44 -0
- package/src/scripts/_cli/doctor_execution.ts +90 -0
- package/src/scripts/_lib/activation_payload.ts +247 -0
- package/src/scripts/_lib/agent_settings.ts +4 -2
- package/src/scripts/_lib/authority_path.ts +102 -0
- package/src/scripts/_lib/cascade_base.ts +94 -0
- package/src/scripts/_lib/changelog_eras.ts +7 -2
- package/src/scripts/_lib/continuation_ladder.ts +149 -2
- package/src/scripts/_lib/council_transport.ts +129 -0
- package/src/scripts/_lib/delivery_ready.ts +112 -0
- package/src/scripts/_lib/forge_protection.ts +267 -0
- package/src/scripts/_lib/hook_platform_keys.ts +27 -0
- package/src/scripts/_lib/json_python_parity.ts +127 -0
- package/src/scripts/_lib/lean_projection_mode.ts +14 -3
- package/src/scripts/_lib/loop_surfaces.ts +382 -0
- package/src/scripts/_lib/mission_record.ts +190 -0
- package/src/scripts/_lib/obligation_frequency.ts +217 -0
- package/src/scripts/_lib/obligations.ts +402 -0
- package/src/scripts/_lib/orchestration_record.ts +11 -20
- package/src/scripts/_lib/release_highlights.ts +199 -10
- package/src/scripts/_lib/release_holds.ts +493 -0
- package/src/scripts/_lib/release_migration_gate.ts +184 -0
- package/src/scripts/_lib/rides_along.ts +102 -0
- package/src/scripts/_lib/settings_renamed_keys.ts +82 -0
- package/src/scripts/_lib/test_delta.ts +166 -0
- package/src/scripts/_lib/test_provenance.ts +171 -0
- package/src/scripts/_lib/typed_op_grant.ts +246 -0
- package/src/scripts/_lib/typed_op_watch.ts +185 -0
- package/src/scripts/ai_council/config.ts +8 -11
- package/src/scripts/ai_council/fallback_config.ts +5 -3
- package/src/scripts/ai_council/ownership_classes.ts +118 -0
- package/src/scripts/ask_block_census.ts +285 -15
- package/src/scripts/check_enforcement_matrix.ts +624 -0
- package/src/scripts/check_gate_reachability.ts +173 -10
- package/src/scripts/check_generator_sync.ts +954 -0
- package/src/scripts/check_preamble_payload_budget.ts +75 -2
- package/src/scripts/check_release_highlights.ts +33 -1
- package/src/scripts/check_release_holds.ts +567 -0
- package/src/scripts/check_rule_projection_integrity.ts +22 -12
- package/src/scripts/check_test_delta.ts +294 -0
- package/src/scripts/check_test_weakening.ts +299 -0
- package/src/scripts/closure_scan.ts +333 -0
- package/src/scripts/compile_hook_manifest.ts +43 -3
- package/src/scripts/council_record_shape.ts +209 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +88 -9
- package/src/scripts/hooks/concern_registry.ts +4 -0
- package/src/scripts/hooks/design_pass_hook.ts +128 -3
- package/src/scripts/hooks/evidence_independence.ts +96 -0
- package/src/scripts/hooks/memory_recall_hook.ts +540 -0
- package/src/scripts/hooks/obligation_settle_hook.ts +182 -0
- package/src/scripts/hooks/rule_inject_hook.ts +49 -1
- package/src/scripts/hooks/run_continuation_hook.ts +17 -20
- package/src/scripts/hooks_doctor.ts +85 -0
- package/src/scripts/hooks_status.ts +19 -0
- package/src/scripts/install.ts +106 -206
- package/src/scripts/janitor.ts +7 -0
- package/src/scripts/lint_decision_classes.ts +464 -0
- package/src/scripts/lint_hook_manifest.ts +11 -0
- package/src/scripts/lint_major_migration_sections.ts +450 -0
- package/src/scripts/lint_plan_risk_register.ts +47 -3
- package/src/scripts/lint_roadmap_blockers.ts +61 -0
- package/src/scripts/lint_roadmap_producers.ts +202 -0
- package/src/scripts/measure_rule_budget.ts +101 -5
- package/src/scripts/new_roadmap.ts +37 -0
- package/src/scripts/orchestration_record.ts +0 -5
- package/src/scripts/release.ts +14 -98
- package/src/scripts/release_drill.ts +267 -1
- package/src/scripts/release_publication.ts +51 -0
- package/src/scripts/report_enforcement_drift.ts +566 -0
- package/src/scripts/report_host_injection_effect.ts +3 -11
- package/src/scripts/report_standing_payload_by_host.ts +26 -152
- package/src/scripts/schemas/agent-settings.schema.json +23 -0
- package/src/scripts/schemas/command.schema.json +4 -0
- package/src/scripts/scope_growth.ts +219 -0
- package/src/scripts/trigger_eval_grandfather.json +0 -1
- package/src/scripts/ui_conformance_probe.ts +622 -0
- package/src/server/schemas/settings.ts +31 -7
- package/src/shared/missionExecution.ts +126 -0
- package/dist/cli-delegate/chunk-523HCFYO.js +0 -90
|
@@ -36,6 +36,12 @@ import * as os from 'node:os';
|
|
|
36
36
|
|
|
37
37
|
import { reportScanned } from './_lib/scan_scope.js';
|
|
38
38
|
import { runSelfTest, type SelfTestCase } from './_lib/gate_self_test.js';
|
|
39
|
+
import {
|
|
40
|
+
INVENTORY_REL,
|
|
41
|
+
inventoryVerdict,
|
|
42
|
+
resetSourceCache,
|
|
43
|
+
type InventoryVerdict,
|
|
44
|
+
} from './_lib/loop_surfaces.js';
|
|
39
45
|
|
|
40
46
|
const REPO_ROOT = process.cwd();
|
|
41
47
|
const TASKFILES_DIR = 'taskfiles';
|
|
@@ -238,6 +244,23 @@ export interface GateVerdict {
|
|
|
238
244
|
unreasoned: string[];
|
|
239
245
|
/** Recorded exemptions that are no longer unreachable — stale rows. */
|
|
240
246
|
stale: string[];
|
|
247
|
+
/**
|
|
248
|
+
* The `_lib-export-reach` axis: a declared loop instrument nothing calls.
|
|
249
|
+
*
|
|
250
|
+
* A second axis in this one script rather than a second gate, because it
|
|
251
|
+
* asks the same question one layer down. The first axis asks whether CI
|
|
252
|
+
* reaches a gate TARGET; this asks whether production code reaches a
|
|
253
|
+
* declared INSTRUMENT. A separate gate would need its own registration,
|
|
254
|
+
* its own coverage row and its own wiring — and would then be the thing
|
|
255
|
+
* this family exists to detect if any of that were missed.
|
|
256
|
+
*
|
|
257
|
+
* Deliberately scoped to the instruments named in `loop-surfaces.yaml`
|
|
258
|
+
* rather than to every `_lib` export. Measured on `loop_guards.ts`, the
|
|
259
|
+
* unscoped version reports nine of fourteen exports dead; a gate whose
|
|
260
|
+
* signal is a minority of its own output gets allowlisted rather than
|
|
261
|
+
* answered.
|
|
262
|
+
*/
|
|
263
|
+
inventory: InventoryVerdict;
|
|
241
264
|
}
|
|
242
265
|
|
|
243
266
|
/**
|
|
@@ -255,25 +278,51 @@ export function gateVerdict(root = REPO_ROOT): GateVerdict {
|
|
|
255
278
|
return {
|
|
256
279
|
unreasoned: r.unreachable.filter((n) => !exempt.has(n)).sort(),
|
|
257
280
|
stale: [...exempt.keys()].filter((n) => !unreachable.has(n)).sort(),
|
|
281
|
+
inventory: inventoryVerdict(root),
|
|
258
282
|
};
|
|
259
283
|
}
|
|
260
284
|
|
|
285
|
+
/** The `_lib-export-reach` half of the verdict, written to stderr. */
|
|
286
|
+
function reportInventory(inv: InventoryVerdict): void {
|
|
287
|
+
for (const f of inv.shape) {
|
|
288
|
+
process.stderr.write(
|
|
289
|
+
`❌ ${INVENTORY_REL}: surface \`${f.id}\` — ${f.detail} (${f.reason}). Every surface ` +
|
|
290
|
+
'carries every field, and a bound resolves to something that exists.\n',
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
for (const f of inv.reach) {
|
|
294
|
+
const fix =
|
|
295
|
+
f.reason === 'dead'
|
|
296
|
+
? 'Give it a production consumer, declare it `status: experimental` with a future ' +
|
|
297
|
+
'`expires:`, or delete it. A built instrument nothing calls is not built.'
|
|
298
|
+
: 'An exemption is a dated deferral, not a label. Decide it, or move the date and ' +
|
|
299
|
+
'say why in `note:`.';
|
|
300
|
+
process.stderr.write(`❌ ${f.id} (${f.file}) — ${f.detail}. ${fix}\n`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
261
304
|
function runGate(root: string): number {
|
|
262
305
|
const v = gateVerdict(root);
|
|
263
306
|
const exempt = readExemptions(root);
|
|
307
|
+
const inv = v.inventory;
|
|
308
|
+
const declared = inv.live.length + inv.exempt.length + inv.reach.length;
|
|
264
309
|
reportScanned({
|
|
265
310
|
gate: 'check_gate_reachability',
|
|
266
|
-
scanned: exempt.size + analyse(root).unreachable.length,
|
|
267
|
-
units: 'exemption row(s) + unreachable target(s)',
|
|
268
|
-
roots: [EXEMPTIONS_REL, ROOT_TASKFILE, TASKFILES_DIR],
|
|
311
|
+
scanned: exempt.size + analyse(root).unreachable.length + declared,
|
|
312
|
+
units: 'exemption row(s) + unreachable target(s) + declared loop instrument(s)',
|
|
313
|
+
roots: [EXEMPTIONS_REL, INVENTORY_REL, ROOT_TASKFILE, TASKFILES_DIR],
|
|
269
314
|
});
|
|
270
|
-
|
|
315
|
+
const inventoryClean = inv.shape.length === 0 && inv.reach.length === 0;
|
|
316
|
+
if (v.unreasoned.length === 0 && v.stale.length === 0 && inventoryClean) {
|
|
271
317
|
process.stdout.write(
|
|
272
318
|
`✅ check_gate_reachability: every unreachable gate target carries a recorded reason ` +
|
|
273
|
-
`(${String(exempt.size)} exempt)
|
|
319
|
+
`(${String(exempt.size)} exempt); every declared loop instrument is called or ` +
|
|
320
|
+
`dated (${String(inv.live.length)} live, ${String(inv.exempt.length)} experimental` +
|
|
321
|
+
`${inv.proseBound.length > 0 ? `, ${String(inv.proseBound.length)} prose-bound surface(s)` : ''}).\n`,
|
|
274
322
|
);
|
|
275
323
|
return 0;
|
|
276
324
|
}
|
|
325
|
+
reportInventory(inv);
|
|
277
326
|
for (const n of v.unreasoned) {
|
|
278
327
|
process.stderr.write(
|
|
279
328
|
`❌ ${n} is gate-shaped, unreachable from \`task ci\` and every workflow, and carries ` +
|
|
@@ -320,6 +369,58 @@ function selfTest(): number {
|
|
|
320
369
|
return v.unreasoned.length === 0 && v.stale.length === 0 ? 0 : 1;
|
|
321
370
|
};
|
|
322
371
|
|
|
372
|
+
/**
|
|
373
|
+
* A throwaway tree for the `_lib-export-reach` axis.
|
|
374
|
+
*
|
|
375
|
+
* `surface` and `instrument` are written verbatim into the inventory, so a
|
|
376
|
+
* case can plant a malformed row without the builder silently repairing
|
|
377
|
+
* it — which is the whole point of a planted failure.
|
|
378
|
+
*/
|
|
379
|
+
const inventoryFixture = (opts: { surface: string; instrument: string; calls: boolean }): number => {
|
|
380
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gr-inv-'));
|
|
381
|
+
roots.push(dir);
|
|
382
|
+
fs.mkdirSync(path.join(dir, 'src', 'config'), { recursive: true });
|
|
383
|
+
fs.mkdirSync(path.join(dir, 'src', 'lib'), { recursive: true });
|
|
384
|
+
fs.writeFileSync(
|
|
385
|
+
path.join(dir, 'src', 'lib', 'thing.ts'),
|
|
386
|
+
[
|
|
387
|
+
'export const CEILING = 3;',
|
|
388
|
+
'export function stalled(): boolean { return false; }',
|
|
389
|
+
'export function helper(): number { return CEILING; }',
|
|
390
|
+
...(opts.calls ? ['export const used = helper();'] : []),
|
|
391
|
+
].join('\n'),
|
|
392
|
+
'utf-8',
|
|
393
|
+
);
|
|
394
|
+
fs.writeFileSync(
|
|
395
|
+
path.join(dir, 'src', 'config', 'loop-surfaces.yaml'),
|
|
396
|
+
`surfaces:\n${opts.surface}\ninstruments:\n${opts.instrument}\n`,
|
|
397
|
+
'utf-8',
|
|
398
|
+
);
|
|
399
|
+
resetSourceCache();
|
|
400
|
+
const v = inventoryVerdict(dir);
|
|
401
|
+
resetSourceCache();
|
|
402
|
+
return v.shape.length === 0 && v.reach.length === 0 ? 0 : 1;
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
const wholeSurface = [
|
|
406
|
+
' s:',
|
|
407
|
+
' kind: code',
|
|
408
|
+
' bound_kind: code',
|
|
409
|
+
' cap: src/lib/thing.ts:CEILING',
|
|
410
|
+
' no_progress: src/lib/thing.ts:stalled',
|
|
411
|
+
' success_stop: a stated stop',
|
|
412
|
+
' checker: a stated checker',
|
|
413
|
+
' human_gate: none',
|
|
414
|
+
' terminal_vocabulary: none',
|
|
415
|
+
' production_consumers: [src/lib/thing.ts]',
|
|
416
|
+
].join('\n');
|
|
417
|
+
// Identical but for the one missing field — so a red can only be the cap.
|
|
418
|
+
const cappedSurface = wholeSurface
|
|
419
|
+
.split('\n')
|
|
420
|
+
.filter((l) => !l.includes('cap:'))
|
|
421
|
+
.join('\n');
|
|
422
|
+
const plainInstrument = [' helper:', ' file: src/lib/thing.ts', ' role: a stated role'].join('\n');
|
|
423
|
+
|
|
323
424
|
const cases: SelfTestCase[] = [
|
|
324
425
|
{
|
|
325
426
|
name: 'a wired gate target → accept',
|
|
@@ -343,9 +444,63 @@ function selfTest(): number {
|
|
|
343
444
|
expect: 'reject',
|
|
344
445
|
run: () => fixture({ target: 'check-x', wired: true, exempt: { 'check-x': 'stale' } }),
|
|
345
446
|
},
|
|
447
|
+
// The `_lib-export-reach` axis. The accept case comes first so a
|
|
448
|
+
// builder that reds on everything is caught before the three planted
|
|
449
|
+
// failures can be read as the axis working.
|
|
450
|
+
{
|
|
451
|
+
name: 'a whole surface and a called instrument → accept',
|
|
452
|
+
expect: 'accept',
|
|
453
|
+
run: () =>
|
|
454
|
+
inventoryFixture({ surface: wholeSurface, instrument: plainInstrument, calls: true }),
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
name: 'a surface with no `cap` → reject',
|
|
458
|
+
expect: 'reject',
|
|
459
|
+
run: () =>
|
|
460
|
+
inventoryFixture({ surface: cappedSurface, instrument: plainInstrument, calls: true }),
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
name: 'an instrument with no consumer → reject',
|
|
464
|
+
expect: 'reject',
|
|
465
|
+
run: () =>
|
|
466
|
+
inventoryFixture({ surface: wholeSurface, instrument: plainInstrument, calls: false }),
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
// The reason `expires:` is a required field rather than a nicety:
|
|
470
|
+
// a declared-inactive instrument with no deadline is the same dead
|
|
471
|
+
// code wearing a label.
|
|
472
|
+
name: 'an exception whose `expires:` has passed → reject',
|
|
473
|
+
expect: 'reject',
|
|
474
|
+
run: () =>
|
|
475
|
+
inventoryFixture({
|
|
476
|
+
surface: wholeSurface,
|
|
477
|
+
instrument: `${plainInstrument}\n status: experimental\n expires: '2020-01-01'`,
|
|
478
|
+
calls: false,
|
|
479
|
+
}),
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
name: 'an `experimental` exception with no `expires:` → reject',
|
|
483
|
+
expect: 'reject',
|
|
484
|
+
run: () =>
|
|
485
|
+
inventoryFixture({
|
|
486
|
+
surface: wholeSurface,
|
|
487
|
+
instrument: `${plainInstrument}\n status: experimental`,
|
|
488
|
+
calls: false,
|
|
489
|
+
}),
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
name: 'an unexpired `experimental` exception on a dead instrument → accept',
|
|
493
|
+
expect: 'accept',
|
|
494
|
+
run: () =>
|
|
495
|
+
inventoryFixture({
|
|
496
|
+
surface: wholeSurface,
|
|
497
|
+
instrument: `${plainInstrument}\n status: experimental\n expires: '2099-01-01'`,
|
|
498
|
+
calls: false,
|
|
499
|
+
}),
|
|
500
|
+
},
|
|
346
501
|
];
|
|
347
502
|
try {
|
|
348
|
-
return runSelfTest({ gate: 'check_gate_reachability', cases, minCases:
|
|
503
|
+
return runSelfTest({ gate: 'check_gate_reachability', cases, minCases: 10, minRejectCases: 6 });
|
|
349
504
|
} finally {
|
|
350
505
|
for (const d of roots) fs.rmSync(d, { recursive: true, force: true });
|
|
351
506
|
}
|
|
@@ -355,18 +510,20 @@ export function main(argv: string[] = process.argv.slice(2), root = REPO_ROOT):
|
|
|
355
510
|
if (argv.includes('--self-test')) return selfTest();
|
|
356
511
|
if (argv.includes('--gate')) return runGate(root);
|
|
357
512
|
const r = analyse(root);
|
|
513
|
+
const inv = inventoryVerdict(root);
|
|
358
514
|
if (argv.includes('--json')) {
|
|
359
|
-
process.stdout.write(`${JSON.stringify(r, null, 2)}\n`);
|
|
515
|
+
process.stdout.write(`${JSON.stringify({ ...r, inventory: inv }, null, 2)}\n`);
|
|
360
516
|
return 0;
|
|
361
517
|
}
|
|
362
518
|
// Emitted on the DEFAULT invocation too, not only under `--gate`: the
|
|
363
519
|
// coverage gate reads a bare run, and a gate that reports what it inspected
|
|
364
520
|
// only in one mode is a gate that reports nothing in the other.
|
|
521
|
+
const declared = inv.live.length + inv.exempt.length + inv.reach.length;
|
|
365
522
|
reportScanned({
|
|
366
523
|
gate: 'check_gate_reachability',
|
|
367
|
-
scanned: readExemptions(root).size + r.unreachable.length,
|
|
368
|
-
units: 'exemption row(s) + unreachable target(s)',
|
|
369
|
-
roots: [EXEMPTIONS_REL, ROOT_TASKFILE, TASKFILES_DIR],
|
|
524
|
+
scanned: readExemptions(root).size + r.unreachable.length + declared,
|
|
525
|
+
units: 'exemption row(s) + unreachable target(s) + declared loop instrument(s)',
|
|
526
|
+
roots: [EXEMPTIONS_REL, INVENTORY_REL, ROOT_TASKFILE, TASKFILES_DIR],
|
|
370
527
|
});
|
|
371
528
|
const total = r.reachable.length + r.scriptInWorkflow.length + r.unreachable.length;
|
|
372
529
|
process.stdout.write(
|
|
@@ -375,6 +532,12 @@ export function main(argv: string[] = process.argv.slice(2), root = REPO_ROOT):
|
|
|
375
532
|
`UNREACHABLE ${String(r.unreachable.length)}\n`,
|
|
376
533
|
);
|
|
377
534
|
for (const n of r.unreachable) process.stdout.write(` · ${n}\n`);
|
|
535
|
+
process.stdout.write(
|
|
536
|
+
`declared loop instruments: ${String(declared)} · live ${String(inv.live.length)} · ` +
|
|
537
|
+
`experimental ${String(inv.exempt.length)} · DEAD ${String(inv.reach.length)} · ` +
|
|
538
|
+
`prose-bound surfaces ${String(inv.proseBound.length)}\n`,
|
|
539
|
+
);
|
|
540
|
+
for (const f of inv.reach) process.stdout.write(` · ${f.id} — ${f.detail}\n`);
|
|
378
541
|
return 0;
|
|
379
542
|
}
|
|
380
543
|
|