@event4u/agent-config 14.17.0 → 14.19.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 +207 -77
- package/README.md +72 -150
- package/dist/agent-src/README.md +1 -1
- package/dist/agent-src/commands/agent-handoff.md +2 -2
- package/dist/agent-src/commands/pr/merge.md +35 -44
- package/dist/agent-src/commands/review/changes.md +19 -19
- package/dist/agent-src/commands/review.md +2 -2
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +30 -3
- package/dist/agent-src/rules/autonomous-execution.md +1 -1
- package/dist/agent-src/rules/git-history-discipline.md +2 -2
- package/dist/agent-src/rules/guidelines.md +1 -1
- package/dist/agent-src/rules/session-canary.md +2 -2
- package/dist/agent-src/rules/token-efficiency.md +1 -1
- package/dist/agent-src/skills/accessibility-auditor/SKILL.md +2 -0
- package/dist/agent-src/skills/adversarial-review/SKILL.md +0 -8
- package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +27 -1
- package/dist/agent-src/skills/canvas-design/SKILL.md +1 -1
- package/dist/agent-src/skills/code-intelligence/SKILL.md +60 -12
- package/dist/agent-src/skills/complexity-first-planning/SKILL.md +27 -0
- package/dist/agent-src/skills/design-intelligence/SKILL.md +1 -1
- package/dist/agent-src/skills/design-intelligence/data/app-interface.csv +1 -1
- package/dist/agent-src/skills/design-intelligence/data/motion.csv +17 -17
- package/dist/agent-src/skills/design-intelligence/data/ux-guidelines.csv +2 -2
- package/dist/agent-src/skills/design-intelligence/references/context-and-registers.md +17 -0
- package/dist/agent-src/skills/design-intelligence/references/design-rules-checklist.md +4 -4
- package/dist/agent-src/skills/design-review/SKILL.md +3 -1
- package/dist/agent-src/skills/design-variations/SKILL.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +1 -1
- package/dist/agent-src/skills/fe-design/SKILL.md +32 -5
- package/dist/agent-src/skills/fe-design/references/craft-floor.md +7 -0
- package/dist/agent-src/skills/fe-design/references/design-patterns.md +47 -2
- package/dist/agent-src/skills/feature-planning/SKILL.md +34 -0
- package/dist/agent-src/skills/git-workflow/SKILL.md +37 -12
- package/dist/agent-src/skills/git-workflow/references/push-closes-its-loop.md +176 -0
- package/dist/agent-src/skills/laravel-mail/SKILL.md +44 -0
- package/dist/agent-src/skills/laravel-scheduling/SKILL.md +3 -1
- package/dist/agent-src/skills/project-analyzer/SKILL.md +0 -6
- package/dist/agent-src/skills/react-native-setup/SKILL.md +3 -3
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/sequential-thinking/SKILL.md +18 -8
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +40 -0
- package/dist/agent-src/skills/ui-apply-generic/SKILL.md +1 -1
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +1 -1
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +29 -2
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +53 -8
- package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli/commands/recordTriggerEval.js +2 -2
- package/dist/cli/main.js +1 -1
- package/dist/cli-delegate/{chunk-AKJGUQNO.js → chunk-GZTMRYCN.js} +405 -341
- package/dist/cli-delegate/{chunk-7RXIKF62.js → chunk-IDHUQIXP.js} +283 -132
- package/dist/cli-delegate/cmd_adr_effective.js +318 -81
- package/dist/cli-delegate/cmd_conformance.js +749 -669
- package/dist/cli-delegate/cmd_doctor.js +1 -1
- package/dist/cli-delegate/cmd_export.js +1 -1
- package/dist/cli-delegate/cmd_handoff.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +1 -1
- package/dist/cli-delegate/cmd_route_audit.js +1 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +1 -1
- package/dist/cli-delegate/cmd_uninstall.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +39 -38
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +2764 -2439
- package/dist/install/install.mjs +588 -527
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1381 -1138
- package/dist/scripts/_lib/model_tier.js +1 -1
- package/dist/shared/settingsConsent.js +1 -1
- package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/docs/guidelines/design-antipatterns.md +87 -64
- package/package.json +1 -1
- package/src/agent-src/README.md +1 -1
- package/src/config/ci-local-parity.yml +6 -0
- package/src/config/conformance-claim-baseline.json +9 -0
- package/src/config/gate-coverage.yml +170 -0
- package/src/config/gate-violation-baselines.json +4 -4
- package/src/config/release-gate-locality.yml +141 -0
- package/src/scripts/_cli/cmd_doctor.ts +2 -2
- package/src/scripts/_cli/cmd_handoff.ts +1 -1
- package/src/scripts/_cli/cmd_update.ts +1 -1
- package/src/scripts/_cli/cmd_versions.ts +1 -1
- package/src/scripts/_lib/adr_frontmatter.ts +44 -0
- package/src/scripts/_lib/consequence_objects.ts +152 -0
- package/src/scripts/_lib/exec_evidence.ts +7 -0
- package/src/scripts/_lib/global_deploy_inventory.ts +2 -2
- package/src/scripts/_lib/host_permission_checks.ts +251 -0
- package/src/scripts/_lib/model_tier.ts +1 -1
- package/src/scripts/_lib/obligation_frequency.ts +2 -2
- package/src/scripts/_lib/release_highlights.ts +265 -1
- package/src/scripts/_lib/release_material.ts +129 -0
- package/src/scripts/_lib/repeated_run.ts +77 -0
- package/src/scripts/_lib/runtime_journal.ts +26 -3
- package/src/scripts/_lib/runtime_wiring_checks.ts +12 -1
- package/src/scripts/_lib/session_register.ts +11 -6
- package/src/scripts/_lib/sqlite_schema.ts +22 -0
- package/src/scripts/_lib/surface.ts +86 -0
- package/src/scripts/_lib/tamper_vocabulary.ts +242 -0
- package/src/scripts/_lib/ui_authority.ts +116 -0
- package/src/scripts/_lib/unified_diff.ts +121 -0
- package/src/scripts/adr/regenerate_index.ts +54 -1
- package/src/scripts/adr_cite_check.ts +71 -15
- package/src/scripts/ai_council/clients.ts +1 -1
- package/src/scripts/autonomy_friction_corpus.ts +229 -0
- package/src/scripts/build_proof.ts +15 -2
- package/src/scripts/check_beta_review_markers.ts +141 -17
- package/src/scripts/check_enforcement_coverage.ts +1 -1
- package/src/scripts/check_enforcement_denominator.ts +121 -11
- package/src/scripts/check_finding_dispositions.ts +239 -6
- package/src/scripts/check_gate_coverage.ts +96 -0
- package/src/scripts/check_installed_hooks_fresh.ts +381 -0
- package/src/scripts/check_release_highlights.ts +99 -14
- package/src/scripts/check_skill_activation_claim.ts +179 -0
- package/src/scripts/check_suppression_hygiene.ts +11 -0
- package/src/scripts/check_trigger_evals.ts +1 -1
- package/src/scripts/code_graph/build.ts +230 -33
- package/src/scripts/code_graph/extract.ts +168 -33
- package/src/scripts/code_graph/types.ts +37 -2
- package/src/scripts/code_graph/validate.ts +12 -1
- package/src/scripts/conformance_scan.ts +45 -4
- package/src/scripts/detect_silent_catch.ts +403 -0
- package/src/scripts/detect_verification_tampering.ts +538 -0
- package/src/scripts/explain_run.ts +1 -1
- package/src/scripts/generate_capability_matrix.ts +1 -1
- package/src/scripts/git_authorization_hook.ts +228 -18
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +47 -30
- package/src/scripts/hooks/augment-dispatcher.sh +1 -1
- package/src/scripts/hooks/block_no_verify.ts +3 -3
- package/src/scripts/hooks/category_a.ts +291 -0
- package/src/scripts/hooks/cline-dispatcher.sh +1 -1
- package/src/scripts/hooks/concern_registry.ts +2 -2
- package/src/scripts/hooks/cursor-dispatcher.sh +11 -5
- package/src/scripts/hooks/dispatch_hook.ts +17 -22
- package/src/scripts/hooks/evidence_independence.ts +21 -2
- package/src/scripts/hooks/{block_unauthorized_git.ts → git_command_classifier.ts} +175 -364
- package/src/scripts/hooks/host_lowering.ts +215 -0
- package/src/scripts/hooks/host_lowering.yaml +185 -0
- package/src/scripts/hooks/host_semantics.ts +105 -37
- package/src/scripts/hooks/journal_record_hook.ts +10 -0
- package/src/scripts/hooks/permission_gate.ts +117 -0
- package/src/scripts/hooks/push_settle_hook.ts +250 -0
- package/src/scripts/hooks/ship_diff_volume_hook.ts +1 -1
- package/src/scripts/hooks_status.ts +12 -10
- package/src/scripts/install-hooks.sh +134 -1
- package/src/scripts/install.ts +53 -82
- package/src/scripts/install_anthropic_key.sh +2 -2
- package/src/scripts/language_mirror_hook.ts +27 -5
- package/src/scripts/lint_design_antipattern_parity.ts +80 -0
- package/src/scripts/lint_evidence_artifacts.ts +45 -1
- package/src/scripts/lint_hook_manifest.ts +87 -3
- package/src/scripts/lint_motion_authority_drift.ts +731 -0
- package/src/scripts/lint_readme_size.ts +158 -12
- package/src/scripts/lint_reasoning_fixtures.ts +216 -0
- package/src/scripts/lint_skill_trigger_contradiction.ts +161 -0
- package/src/scripts/measure_sibling_naming.ts +150 -0
- package/src/scripts/redact_hook_capture.ts +1 -1
- package/src/scripts/release.ts +31 -143
- package/src/scripts/release_drill.ts +71 -1
- package/src/scripts/release_publication.ts +243 -3
- package/src/scripts/release_verify.ts +220 -0
- package/src/scripts/report_skill_activation.ts +319 -7
- package/src/scripts/schemas/review-findings.schema.json +6 -1
- package/src/scripts/schemas/skill.schema.json +12 -2
- package/src/scripts/self_review_gate.ts +10 -1
- package/src/scripts/session_canary_hook.ts +1 -1
- package/src/scripts/session_register_hook.ts +4 -3
- package/src/scripts/trigger_eval_grandfather.json +5 -1
- package/src/scripts/validate_agent_settings.ts +1 -1
- package/src/shared/settingsConsent.ts +1 -1
|
@@ -6,16 +6,16 @@ import {
|
|
|
6
6
|
import "./chunk-J55WI3RR.js";
|
|
7
7
|
|
|
8
8
|
// src/scripts/_cli/cmd_adr_effective.ts
|
|
9
|
-
import * as
|
|
10
|
-
import * as
|
|
11
|
-
import
|
|
12
|
-
import { fileURLToPath as
|
|
9
|
+
import * as fs3 from "node:fs";
|
|
10
|
+
import * as path4 from "node:path";
|
|
11
|
+
import process5 from "node:process";
|
|
12
|
+
import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
13
13
|
|
|
14
14
|
// src/scripts/adr_cite_check.ts
|
|
15
|
-
import * as
|
|
15
|
+
import * as fs2 from "node:fs";
|
|
16
16
|
import * as os from "node:os";
|
|
17
|
-
import * as
|
|
18
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
17
|
+
import * as path3 from "node:path";
|
|
18
|
+
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
|
|
19
19
|
|
|
20
20
|
// src/scripts/_lib/adr_frontmatter.ts
|
|
21
21
|
var FOLD_MARKERS = /* @__PURE__ */ new Set([">", ">-", ">+", "|", "|-", "|+"]);
|
|
@@ -218,9 +218,234 @@ function isLowEvidenceAccepted(fm) {
|
|
|
218
218
|
const evidence = evidenceOf(fm);
|
|
219
219
|
return evidence?.strength === "E0" || evidence?.strength === "E1";
|
|
220
220
|
}
|
|
221
|
+
var DATED_TRIGGER_RE = /^\s*(?:expir(?:y|es)\b\s*[:—-]?\s*)?(\d{4})-(\d{2})-(\d{2})(?!\d)/iu;
|
|
222
|
+
var DATED_TRIGGER_PROBE = /^\s*(?:expir(?:y|es)\b|\d{4}-\d{1,2}-\d{1,2}\b)/iu;
|
|
223
|
+
function iso_day(d) {
|
|
224
|
+
return d.toISOString().slice(0, 10);
|
|
225
|
+
}
|
|
226
|
+
function dated_trigger_day(trigger) {
|
|
227
|
+
const m = DATED_TRIGGER_RE.exec(trigger);
|
|
228
|
+
if (m === null) return null;
|
|
229
|
+
const [y, mo, d] = [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
230
|
+
const at = new Date(Date.UTC(y, mo - 1, d));
|
|
231
|
+
if (at.getUTCFullYear() !== y || at.getUTCMonth() !== mo - 1 || at.getUTCDate() !== d) {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
return iso_day(at);
|
|
235
|
+
}
|
|
221
236
|
|
|
222
|
-
// src/scripts/_lib/
|
|
237
|
+
// src/scripts/_lib/as_of.ts
|
|
238
|
+
import { spawnSync } from "node:child_process";
|
|
239
|
+
import * as fs from "node:fs";
|
|
240
|
+
import * as path from "node:path";
|
|
223
241
|
import process2 from "node:process";
|
|
242
|
+
import { fileURLToPath } from "node:url";
|
|
243
|
+
var AsOfPinError = class extends Error {
|
|
244
|
+
};
|
|
245
|
+
var REPO_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
|
|
246
|
+
function readArgvPin(argv) {
|
|
247
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
248
|
+
const arg = argv[i] ?? "";
|
|
249
|
+
if (arg === "--as-of") return argv[i + 1] ?? "";
|
|
250
|
+
if (arg.startsWith("--as-of=")) return arg.slice("--as-of=".length);
|
|
251
|
+
}
|
|
252
|
+
return void 0;
|
|
253
|
+
}
|
|
254
|
+
function parsePin(raw, source) {
|
|
255
|
+
const trimmed = raw.trim();
|
|
256
|
+
const ms = Date.parse(trimmed);
|
|
257
|
+
if (trimmed === "" || Number.isNaN(ms)) {
|
|
258
|
+
throw new AsOfPinError(
|
|
259
|
+
`${source} is not a parseable date: ${JSON.stringify(raw)}. Pass an ISO-8601 instant, e.g. 2026-08-23T00:00:00Z.`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
return new Date(ms);
|
|
263
|
+
}
|
|
264
|
+
function inCi(env) {
|
|
265
|
+
const raw = (env.CI ?? "").trim().toLowerCase();
|
|
266
|
+
return raw !== "" && raw !== "0" && raw !== "false";
|
|
267
|
+
}
|
|
268
|
+
function headCommitDate(cwd = REPO_ROOT) {
|
|
269
|
+
const res = spawnSync("git", ["log", "-1", "--format=%cI", "HEAD"], {
|
|
270
|
+
cwd,
|
|
271
|
+
encoding: "utf-8"
|
|
272
|
+
});
|
|
273
|
+
if (res.status !== 0) return null;
|
|
274
|
+
const iso = (res.stdout ?? "").trim();
|
|
275
|
+
if (iso === "") return null;
|
|
276
|
+
const ms = Date.parse(iso);
|
|
277
|
+
return Number.isNaN(ms) ? null : new Date(ms);
|
|
278
|
+
}
|
|
279
|
+
function resolveAsOf(sources = {}) {
|
|
280
|
+
const argv = sources.argv ?? process2.argv.slice(2);
|
|
281
|
+
const env = sources.env ?? process2.env;
|
|
282
|
+
const argvPin = readArgvPin(argv);
|
|
283
|
+
if (argvPin !== void 0) {
|
|
284
|
+
return { at: parsePin(argvPin, "--as-of"), rung: "argv", reproducible: true };
|
|
285
|
+
}
|
|
286
|
+
const envPin = env.AC_AS_OF;
|
|
287
|
+
if (envPin !== void 0 && envPin.trim() !== "") {
|
|
288
|
+
return { at: parsePin(envPin, "AC_AS_OF"), rung: "env", reproducible: true };
|
|
289
|
+
}
|
|
290
|
+
if (inCi(env)) {
|
|
291
|
+
const commit = (sources.commitDate ?? headCommitDate)();
|
|
292
|
+
if (commit !== null) {
|
|
293
|
+
return { at: commit, rung: "commit", reproducible: true };
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
const warn = sources.warn ?? ((line) => process2.stderr.write(line));
|
|
297
|
+
const at = (sources.wallClock ?? (() => /* @__PURE__ */ new Date()))();
|
|
298
|
+
warn(
|
|
299
|
+
`\u26A0\uFE0F as-of: unpinned run \u2014 using the wall clock (${at.toISOString()}); this verdict is not reproducible. Pass --as-of <iso> or set AC_AS_OF to pin it.
|
|
300
|
+
`
|
|
301
|
+
);
|
|
302
|
+
return { at, rung: "wall-clock", reproducible: false };
|
|
303
|
+
}
|
|
304
|
+
var cached = null;
|
|
305
|
+
function asOfResolution() {
|
|
306
|
+
cached ??= resolveAsOf();
|
|
307
|
+
return cached;
|
|
308
|
+
}
|
|
309
|
+
function asOf() {
|
|
310
|
+
return new Date(asOfResolution().at.getTime());
|
|
311
|
+
}
|
|
312
|
+
function tsxBin() {
|
|
313
|
+
return path.join(
|
|
314
|
+
REPO_ROOT,
|
|
315
|
+
"node_modules",
|
|
316
|
+
".bin",
|
|
317
|
+
process2.platform === "win32" ? "tsx.cmd" : "tsx"
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
function runSelf(args, env) {
|
|
321
|
+
const res = spawnSync(tsxBin(), [fileURLToPath(import.meta.url), ...args], {
|
|
322
|
+
cwd: REPO_ROOT,
|
|
323
|
+
encoding: "utf-8",
|
|
324
|
+
env
|
|
325
|
+
});
|
|
326
|
+
return {
|
|
327
|
+
status: res.status ?? 1,
|
|
328
|
+
stdout: res.stdout ?? "",
|
|
329
|
+
stderr: res.stderr ?? ""
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
function bareEnv() {
|
|
333
|
+
const env = { ...process2.env };
|
|
334
|
+
delete env.AC_AS_OF;
|
|
335
|
+
delete env.CI;
|
|
336
|
+
delete env.GITHUB_ACTIONS;
|
|
337
|
+
return env;
|
|
338
|
+
}
|
|
339
|
+
function selfTest(write) {
|
|
340
|
+
const commit = headCommitDate();
|
|
341
|
+
let failed = 0;
|
|
342
|
+
let checks = 0;
|
|
343
|
+
const expect = (name, ok, detail) => {
|
|
344
|
+
checks += 1;
|
|
345
|
+
if (ok) {
|
|
346
|
+
write(`\u2705 ${name}
|
|
347
|
+
`);
|
|
348
|
+
} else {
|
|
349
|
+
write(`\u274C ${name}: ${detail}
|
|
350
|
+
`);
|
|
351
|
+
failed += 1;
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
const argvRun = runSelf(["--print", "--as-of", "2026-01-02T03:04:05Z"], bareEnv());
|
|
355
|
+
expect(
|
|
356
|
+
"rung 1 (argv) \u2014 an explicit --as-of wins",
|
|
357
|
+
argvRun.status === 0 && argvRun.stdout.includes("rung=argv") && argvRun.stdout.includes("at=2026-01-02T03:04:05.000Z"),
|
|
358
|
+
`exit ${String(argvRun.status)}, stdout ${JSON.stringify(argvRun.stdout)}`
|
|
359
|
+
);
|
|
360
|
+
const precedence = runSelf(["--print", "--as-of=2026-01-02T03:04:05Z"], {
|
|
361
|
+
...bareEnv(),
|
|
362
|
+
AC_AS_OF: "2020-01-01T00:00:00Z"
|
|
363
|
+
});
|
|
364
|
+
expect(
|
|
365
|
+
"rung 1 precedence \u2014 --as-of= overrides AC_AS_OF",
|
|
366
|
+
precedence.status === 0 && precedence.stdout.includes("rung=argv") && precedence.stdout.includes("at=2026-01-02T03:04:05.000Z"),
|
|
367
|
+
`exit ${String(precedence.status)}, stdout ${JSON.stringify(precedence.stdout)}`
|
|
368
|
+
);
|
|
369
|
+
const envRun = runSelf(["--print"], { ...bareEnv(), AC_AS_OF: "2025-06-07T08:09:10Z" });
|
|
370
|
+
expect(
|
|
371
|
+
"rung 2 (env) \u2014 AC_AS_OF answers when argv is silent",
|
|
372
|
+
envRun.status === 0 && envRun.stdout.includes("rung=env") && envRun.stdout.includes("at=2025-06-07T08:09:10.000Z"),
|
|
373
|
+
`exit ${String(envRun.status)}, stdout ${JSON.stringify(envRun.stdout)}`
|
|
374
|
+
);
|
|
375
|
+
const ciRun = runSelf(["--print"], { ...bareEnv(), CI: "true" });
|
|
376
|
+
expect(
|
|
377
|
+
"rung 3 (commit) \u2014 CI pins to the tree under test",
|
|
378
|
+
ciRun.status === 0 && ciRun.stdout.includes("rung=commit") && commit !== null && ciRun.stdout.includes(`at=${commit.toISOString()}`),
|
|
379
|
+
`exit ${String(ciRun.status)}, stdout ${JSON.stringify(ciRun.stdout)}, HEAD date ${commit === null ? "UNAVAILABLE" : commit.toISOString()}`
|
|
380
|
+
);
|
|
381
|
+
const wallRun = runSelf(["--print"], bareEnv());
|
|
382
|
+
expect(
|
|
383
|
+
"rung 4 (wall-clock) \u2014 unpinned runs resolve and WARN once",
|
|
384
|
+
wallRun.status === 0 && wallRun.stdout.includes("rung=wall-clock") && wallRun.stdout.includes("reproducible=false") && wallRun.stderr.includes("not reproducible"),
|
|
385
|
+
`exit ${String(wallRun.status)}, stdout ${JSON.stringify(wallRun.stdout)}, stderr ${JSON.stringify(wallRun.stderr)}`
|
|
386
|
+
);
|
|
387
|
+
const badArgv = runSelf(["--print", "--as-of", "not-a-date"], bareEnv());
|
|
388
|
+
expect(
|
|
389
|
+
"malformed --as-of is rejected, not downgraded",
|
|
390
|
+
badArgv.status !== 0 && badArgv.stderr.includes("not a parseable date"),
|
|
391
|
+
`exit ${String(badArgv.status)}, stderr ${JSON.stringify(badArgv.stderr)}`
|
|
392
|
+
);
|
|
393
|
+
const badEnv = runSelf(["--print"], { ...bareEnv(), AC_AS_OF: "2026-13-45" });
|
|
394
|
+
expect(
|
|
395
|
+
"malformed AC_AS_OF is rejected, not downgraded",
|
|
396
|
+
badEnv.status !== 0 && badEnv.stderr.includes("not a parseable date"),
|
|
397
|
+
`exit ${String(badEnv.status)}, stderr ${JSON.stringify(badEnv.stderr)}`
|
|
398
|
+
);
|
|
399
|
+
const FLOOR = 7;
|
|
400
|
+
if (checks < FLOOR) {
|
|
401
|
+
write(
|
|
402
|
+
`\u274C as_of --self-test: ${String(checks)} case(s) is below the declared floor of ${String(FLOOR)}.
|
|
403
|
+
`
|
|
404
|
+
);
|
|
405
|
+
return 1;
|
|
406
|
+
}
|
|
407
|
+
write(
|
|
408
|
+
`
|
|
409
|
+
as_of --self-test: ${String(checks - failed)}/${String(checks)} case(s) behaved (floor ${String(FLOOR)})
|
|
410
|
+
`
|
|
411
|
+
);
|
|
412
|
+
return failed > 0 ? 1 : 0;
|
|
413
|
+
}
|
|
414
|
+
function main(argv) {
|
|
415
|
+
if (argv.includes("--self-test")) {
|
|
416
|
+
return selfTest((chunk) => process2.stdout.write(chunk));
|
|
417
|
+
}
|
|
418
|
+
let res;
|
|
419
|
+
try {
|
|
420
|
+
res = resolveAsOf({ argv });
|
|
421
|
+
} catch (e) {
|
|
422
|
+
if (e instanceof AsOfPinError) {
|
|
423
|
+
process2.stderr.write(`\u274C as-of: ${e.message}
|
|
424
|
+
`);
|
|
425
|
+
return 2;
|
|
426
|
+
}
|
|
427
|
+
throw e;
|
|
428
|
+
}
|
|
429
|
+
process2.stdout.write(
|
|
430
|
+
`rung=${res.rung} at=${res.at.toISOString()} reproducible=${String(res.reproducible)}
|
|
431
|
+
`
|
|
432
|
+
);
|
|
433
|
+
return 0;
|
|
434
|
+
}
|
|
435
|
+
function isCliEntry() {
|
|
436
|
+
if (process2.argv[1] === void 0) return false;
|
|
437
|
+
try {
|
|
438
|
+
return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process2.argv[1]));
|
|
439
|
+
} catch {
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (isCliEntry()) {
|
|
444
|
+
process2.exit(main(process2.argv.slice(2)));
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// src/scripts/_lib/gate_ledger.ts
|
|
448
|
+
import process3 from "node:process";
|
|
224
449
|
var SKIP_REASON_MESSAGE = {
|
|
225
450
|
excluded_directory: "the target sits under a directory this gate deliberately does not walk",
|
|
226
451
|
size_limit: "the target exceeds the size ceiling this gate reads within",
|
|
@@ -368,7 +593,7 @@ var GateLedger = class {
|
|
|
368
593
|
*
|
|
369
594
|
* @throws {UnaccountedTargetsError} via {@link finalize}.
|
|
370
595
|
*/
|
|
371
|
-
report(write =
|
|
596
|
+
report(write = process3.stdout.write.bind(process3.stdout)) {
|
|
372
597
|
const tally = this.finalize();
|
|
373
598
|
const checked = tally.completed + tally.failed;
|
|
374
599
|
const parts = [
|
|
@@ -389,27 +614,27 @@ var GateLedger = class {
|
|
|
389
614
|
};
|
|
390
615
|
|
|
391
616
|
// src/scripts/_lib/gate_self_test.ts
|
|
392
|
-
import { spawnSync } from "node:child_process";
|
|
393
|
-
import * as
|
|
394
|
-
import
|
|
617
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
618
|
+
import * as path2 from "node:path";
|
|
619
|
+
import process4 from "node:process";
|
|
395
620
|
function runGateCli(repoRoot, scriptRelPath, args, cwd) {
|
|
396
|
-
const tsx =
|
|
621
|
+
const tsx = path2.join(
|
|
397
622
|
repoRoot,
|
|
398
623
|
"node_modules",
|
|
399
624
|
".bin",
|
|
400
|
-
|
|
625
|
+
process4.platform === "win32" ? "tsx.cmd" : "tsx"
|
|
401
626
|
);
|
|
402
|
-
const res =
|
|
627
|
+
const res = spawnSync2(tsx, [path2.join(repoRoot, scriptRelPath), ...args], {
|
|
403
628
|
cwd,
|
|
404
629
|
encoding: "utf-8",
|
|
405
630
|
maxBuffer: 64 * 1024 * 1024,
|
|
406
631
|
// The child must not recurse into its own self-test.
|
|
407
|
-
env: { ...
|
|
632
|
+
env: { ...process4.env, GATE_SELF_TEST_CHILD: "1" }
|
|
408
633
|
});
|
|
409
634
|
return res.status ?? 1;
|
|
410
635
|
}
|
|
411
636
|
function runSelfTest(opts) {
|
|
412
|
-
const write = opts.write ??
|
|
637
|
+
const write = opts.write ?? process4.stdout.write.bind(process4.stdout);
|
|
413
638
|
const minReject = opts.minRejectCases ?? 1;
|
|
414
639
|
const rejectCases = opts.cases.filter((c) => c.expect === "reject").length;
|
|
415
640
|
if (opts.cases.length < opts.minCases || rejectCases < minReject) {
|
|
@@ -451,10 +676,10 @@ ${opts.gate} --self-test: ${String(opts.cases.length - failed)}/${String(opts.ca
|
|
|
451
676
|
}
|
|
452
677
|
|
|
453
678
|
// src/scripts/adr_cite_check.ts
|
|
454
|
-
var _HERE =
|
|
455
|
-
var
|
|
679
|
+
var _HERE = path3.dirname(fileURLToPath2(import.meta.url));
|
|
680
|
+
var REPO_ROOT2 = path3.resolve(_HERE, "..", "..");
|
|
456
681
|
function scan_root() {
|
|
457
|
-
return process.env["ADR_CITE_CHECK_ROOT"] ??
|
|
682
|
+
return process.env["ADR_CITE_CHECK_ROOT"] ?? REPO_ROOT2;
|
|
458
683
|
}
|
|
459
684
|
var ADR_DIRS = ["docs/decisions", "docs/adrs"];
|
|
460
685
|
var SURFACES_NOT_SCANNED = [
|
|
@@ -486,36 +711,36 @@ function normalise_ref(ref) {
|
|
|
486
711
|
return { id: `ADR-${m[1].padStart(3, "0")}`, area: null, num: String(Number(m[1])) };
|
|
487
712
|
}
|
|
488
713
|
function walk_md(dir) {
|
|
489
|
-
if (!
|
|
714
|
+
if (!fs2.existsSync(dir)) return [];
|
|
490
715
|
const out = [];
|
|
491
|
-
for (const entry of
|
|
492
|
-
const full =
|
|
716
|
+
for (const entry of fs2.readdirSync(dir, { withFileTypes: true })) {
|
|
717
|
+
const full = path3.join(dir, entry.name);
|
|
493
718
|
if (entry.isDirectory()) out.push(...walk_md(full));
|
|
494
719
|
else if (entry.name.endsWith(".md") && entry.name !== "INDEX.md") out.push(full);
|
|
495
720
|
}
|
|
496
721
|
return out.sort();
|
|
497
722
|
}
|
|
498
|
-
function adr_files(repo_root =
|
|
499
|
-
return ADR_DIRS.flatMap((d) => walk_md(
|
|
723
|
+
function adr_files(repo_root = REPO_ROOT2) {
|
|
724
|
+
return ADR_DIRS.flatMap((d) => walk_md(path3.join(repo_root, d)));
|
|
500
725
|
}
|
|
501
726
|
var CITATION_ROOTS = ["src/rules", "src/skills", "src/domains", "docs"];
|
|
502
727
|
var CITATION_FILE_EXTS = /* @__PURE__ */ new Set([".md", ".ts", ".yml", ".yaml"]);
|
|
503
728
|
var CITATION_RE = /ADR-(?:[a-z][a-z0-9]*-\d{1,4}|\d{1,4})(?![0-9A-Za-z])/g;
|
|
504
729
|
function walk_citable(dir) {
|
|
505
|
-
if (!
|
|
730
|
+
if (!fs2.existsSync(dir)) return [];
|
|
506
731
|
const out = [];
|
|
507
|
-
for (const entry of
|
|
508
|
-
const full =
|
|
732
|
+
for (const entry of fs2.readdirSync(dir, { withFileTypes: true })) {
|
|
733
|
+
const full = path3.join(dir, entry.name);
|
|
509
734
|
if (entry.isDirectory()) out.push(...walk_citable(full));
|
|
510
|
-
else if (CITATION_FILE_EXTS.has(
|
|
735
|
+
else if (CITATION_FILE_EXTS.has(path3.extname(entry.name))) out.push(full);
|
|
511
736
|
}
|
|
512
737
|
return out.sort();
|
|
513
738
|
}
|
|
514
|
-
function cited_refs(repo_root =
|
|
739
|
+
function cited_refs(repo_root = REPO_ROOT2) {
|
|
515
740
|
const found = /* @__PURE__ */ new Set();
|
|
516
741
|
for (const root of CITATION_ROOTS) {
|
|
517
|
-
for (const file of walk_citable(
|
|
518
|
-
for (const m of
|
|
742
|
+
for (const file of walk_citable(path3.join(repo_root, root))) {
|
|
743
|
+
for (const m of fs2.readFileSync(file, "utf-8").matchAll(CITATION_RE)) {
|
|
519
744
|
found.add(m[0]);
|
|
520
745
|
}
|
|
521
746
|
}
|
|
@@ -535,7 +760,7 @@ function unresolved_basis_refs(basis, repo_root) {
|
|
|
535
760
|
const missing = [];
|
|
536
761
|
for (const ref of basis) {
|
|
537
762
|
if (basis_ref_kind(ref) !== "path") continue;
|
|
538
|
-
if (!
|
|
763
|
+
if (!fs2.existsSync(path3.join(repo_root, basis_ref_path(ref)))) missing.push(ref);
|
|
539
764
|
}
|
|
540
765
|
return missing;
|
|
541
766
|
}
|
|
@@ -557,10 +782,13 @@ function amendment_blocks(body) {
|
|
|
557
782
|
}
|
|
558
783
|
return found;
|
|
559
784
|
}
|
|
560
|
-
function trigger_state(fm) {
|
|
785
|
+
function trigger_state(fm, asOfDate) {
|
|
561
786
|
const t = (fm["review_trigger"] ?? "").trim();
|
|
562
787
|
if (t === "") return "none";
|
|
563
788
|
if (t.toLowerCase() === "unclassified") return "none";
|
|
789
|
+
const day = dated_trigger_day(t);
|
|
790
|
+
if (day !== null) return iso_day(asOfDate ?? asOf()) >= day ? "fired" : "not-fired";
|
|
791
|
+
if (DATED_TRIGGER_PROBE.test(t)) return "dated-unparsed";
|
|
564
792
|
return "indeterminate";
|
|
565
793
|
}
|
|
566
794
|
function verdict_for(r) {
|
|
@@ -582,12 +810,21 @@ function verdict_for(r) {
|
|
|
582
810
|
if (r.trigger_state === "none") {
|
|
583
811
|
return "LIVE, NO REOPEN CONDITION \u2014 the ADR records no `review_trigger`, so nothing would ever reopen it on its own. Treat that as a defect in the ADR, not as strength of the lock.";
|
|
584
812
|
}
|
|
813
|
+
if (r.trigger_state === "fired") {
|
|
814
|
+
return "LIVE, TRIGGER FIRED \u2014 the reopen condition is a date and that date has passed. The record still binds until someone acts on it, and citing it without naming the fired trigger presents a lapsed review as a current one.";
|
|
815
|
+
}
|
|
816
|
+
if (r.trigger_state === "not-fired") {
|
|
817
|
+
return "LIVE, TRIGGER NOT YET FIRED \u2014 the reopen condition is a date still in the future. This is the one state in which a trigger genuinely adds nothing to the citation, and it stops being true on a known day.";
|
|
818
|
+
}
|
|
819
|
+
if (r.trigger_state === "dated-unparsed") {
|
|
820
|
+
return 'LIVE, DATED TRIGGER UNREADABLE \u2014 the reopen condition announces a date this tool could not parse. That is a defect in the record or in the parser, not a verdict: fix the trigger to open with `Expiry YYYY-MM-DD` rather than reading this as "unknown".';
|
|
821
|
+
}
|
|
585
822
|
return "LIVE, TRIGGER INDETERMINATE \u2014 the reopen condition is semantic and this tool cannot decide it. Not an unqualified lock: evaluate the condition against the current tree and route the result.";
|
|
586
823
|
}
|
|
587
|
-
function cite_check(refs, repo_root =
|
|
824
|
+
function cite_check(refs, repo_root = REPO_ROOT2) {
|
|
588
825
|
const files = adr_files(repo_root);
|
|
589
826
|
const contents = /* @__PURE__ */ new Map();
|
|
590
|
-
for (const f of files) contents.set(f,
|
|
827
|
+
for (const f of files) contents.set(f, fs2.readFileSync(f, "utf-8"));
|
|
591
828
|
return refs.map((ref) => {
|
|
592
829
|
const parsed = normalise_ref(ref);
|
|
593
830
|
if (parsed === null) {
|
|
@@ -629,11 +866,11 @@ function cite_check(refs, repo_root = REPO_ROOT) {
|
|
|
629
866
|
const bodyStart = text.indexOf("\n---\n", 4);
|
|
630
867
|
const body = bodyStart === -1 ? text : text.slice(bodyStart + 5);
|
|
631
868
|
const cited = area === null ? new RegExp(`ADR-0*${num}\\b`, "i") : new RegExp(`ADR-${area}-0*${Number(num)}\\b`, "i");
|
|
632
|
-
const referenced_by = files.filter((f) => f !== match && cited.test(contents.get(f) ?? "")).map((f) =>
|
|
869
|
+
const referenced_by = files.filter((f) => f !== match && cited.test(contents.get(f) ?? "")).map((f) => path3.relative(repo_root, f));
|
|
633
870
|
const partial = {
|
|
634
871
|
ref: id,
|
|
635
872
|
resolved: true,
|
|
636
|
-
file:
|
|
873
|
+
file: path3.relative(repo_root, match),
|
|
637
874
|
...fm["status"] !== void 0 ? { status: fm["status"] } : {},
|
|
638
875
|
...fm["date"] !== void 0 ? { date: fm["date"] } : {},
|
|
639
876
|
...fm["decision"] !== void 0 ? { decision: fm["decision"] } : {},
|
|
@@ -713,15 +950,15 @@ ${r.ref}${r.file !== void 0 ? ` \xB7 ${r.file}` : ""}`);
|
|
|
713
950
|
}
|
|
714
951
|
return lines.join("\n");
|
|
715
952
|
}
|
|
716
|
-
function
|
|
717
|
-
const tmp =
|
|
953
|
+
function selfTest2() {
|
|
954
|
+
const tmp = fs2.mkdtempSync(path3.join(os.tmpdir(), "acc-"));
|
|
718
955
|
const mk = (adr, citation) => {
|
|
719
|
-
const root =
|
|
720
|
-
|
|
721
|
-
|
|
956
|
+
const root = fs2.mkdtempSync(path3.join(tmp, "root-"));
|
|
957
|
+
fs2.mkdirSync(path3.join(root, "docs", "decisions"), { recursive: true });
|
|
958
|
+
fs2.mkdirSync(path3.join(root, "src", "rules"), { recursive: true });
|
|
722
959
|
if (adr !== null) {
|
|
723
|
-
|
|
724
|
-
|
|
960
|
+
fs2.writeFileSync(
|
|
961
|
+
path3.join(root, "docs", "decisions", `ADR-${adr}-probe.md`),
|
|
725
962
|
`---
|
|
726
963
|
status: accepted
|
|
727
964
|
date: 2026-08-21
|
|
@@ -733,8 +970,8 @@ decision: probe
|
|
|
733
970
|
"utf-8"
|
|
734
971
|
);
|
|
735
972
|
}
|
|
736
|
-
|
|
737
|
-
|
|
973
|
+
fs2.writeFileSync(
|
|
974
|
+
path3.join(root, "src", "rules", "probe.md"),
|
|
738
975
|
citation === null ? "# Probe\n\nNo decision is named here.\n" : `# Probe
|
|
739
976
|
|
|
740
977
|
See ${citation}.
|
|
@@ -746,7 +983,7 @@ See ${citation}.
|
|
|
746
983
|
const run = (root) => {
|
|
747
984
|
process.env["ADR_CITE_CHECK_ROOT"] = root;
|
|
748
985
|
try {
|
|
749
|
-
return runGateCli(
|
|
986
|
+
return runGateCli(REPO_ROOT2, "src/scripts/adr_cite_check.ts", ["--cited"], REPO_ROOT2);
|
|
750
987
|
} finally {
|
|
751
988
|
delete process.env["ADR_CITE_CHECK_ROOT"];
|
|
752
989
|
}
|
|
@@ -775,18 +1012,18 @@ See ${citation}.
|
|
|
775
1012
|
]
|
|
776
1013
|
});
|
|
777
1014
|
} finally {
|
|
778
|
-
|
|
1015
|
+
fs2.rmSync(tmp, { recursive: true, force: true });
|
|
779
1016
|
}
|
|
780
1017
|
}
|
|
781
|
-
var TRIGGER_VERDICTS = ["fired", "not-fired", "indeterminate"];
|
|
782
|
-
function corpus_survey(repo_root =
|
|
1018
|
+
var TRIGGER_VERDICTS = ["fired", "not-fired", "indeterminate", "dated-unparsed"];
|
|
1019
|
+
function corpus_survey(repo_root = REPO_ROOT2) {
|
|
783
1020
|
const files = adr_files(repo_root);
|
|
784
1021
|
const cited_outside = /* @__PURE__ */ new Set();
|
|
785
1022
|
for (const root of CITATION_ROOTS) {
|
|
786
|
-
for (const file of walk_citable(
|
|
787
|
-
const rel =
|
|
788
|
-
if (rel.startsWith(
|
|
789
|
-
for (const m of
|
|
1023
|
+
for (const file of walk_citable(path3.join(repo_root, root))) {
|
|
1024
|
+
const rel = path3.relative(repo_root, file);
|
|
1025
|
+
if (rel.startsWith(path3.join("docs", "decisions"))) continue;
|
|
1026
|
+
for (const m of fs2.readFileSync(file, "utf-8").matchAll(CITATION_RE)) {
|
|
790
1027
|
const parsed = normalise_ref(m[0]);
|
|
791
1028
|
if (parsed !== null) cited_outside.add(parsed.id);
|
|
792
1029
|
}
|
|
@@ -794,15 +1031,15 @@ function corpus_survey(repo_root = REPO_ROOT) {
|
|
|
794
1031
|
}
|
|
795
1032
|
const rows = [];
|
|
796
1033
|
for (const f of files) {
|
|
797
|
-
const text =
|
|
1034
|
+
const text = fs2.readFileSync(f, "utf-8");
|
|
798
1035
|
const fm = parse_frontmatter(text) ?? {};
|
|
799
|
-
const base =
|
|
800
|
-
const parsedSelf = normalise_ref(
|
|
1036
|
+
const base = path3.basename(f);
|
|
1037
|
+
const parsedSelf = normalise_ref(path3.relative(repo_root, f));
|
|
801
1038
|
const num = parsedSelf?.id ?? base;
|
|
802
1039
|
const raw_trigger = (fm["review_trigger"] ?? "").trim();
|
|
803
1040
|
rows.push({
|
|
804
1041
|
ref: num,
|
|
805
|
-
file:
|
|
1042
|
+
file: path3.relative(repo_root, f),
|
|
806
1043
|
status: (fm["status"] ?? "(none)").trim(),
|
|
807
1044
|
successor: (fm["superseded_by"] ?? "\u2014").trim() || "\u2014",
|
|
808
1045
|
has_trigger: raw_trigger !== "" && raw_trigger.toLowerCase() !== "unclassified",
|
|
@@ -863,9 +1100,9 @@ function render_corpus(rows, sum) {
|
|
|
863
1100
|
out.push(" Reports only. This command decides nothing and gates nothing.");
|
|
864
1101
|
return out.join("\n") + "\n";
|
|
865
1102
|
}
|
|
866
|
-
function
|
|
1103
|
+
function main2(argv) {
|
|
867
1104
|
const as_json = argv.includes("--json");
|
|
868
|
-
if (argv.includes("--self-test")) return
|
|
1105
|
+
if (argv.includes("--self-test")) return selfTest2();
|
|
869
1106
|
const corpus_mode = argv.includes("--cited");
|
|
870
1107
|
const survey_mode = argv.includes("--all");
|
|
871
1108
|
if (survey_mode) {
|
|
@@ -958,22 +1195,22 @@ function main(argv) {
|
|
|
958
1195
|
}
|
|
959
1196
|
if (process.argv[1] !== void 0) {
|
|
960
1197
|
try {
|
|
961
|
-
const here =
|
|
962
|
-
const argv1 =
|
|
1198
|
+
const here = fs2.realpathSync(fileURLToPath2(import.meta.url));
|
|
1199
|
+
const argv1 = fs2.realpathSync(path3.resolve(process.argv[1]));
|
|
963
1200
|
if (here === argv1) {
|
|
964
|
-
process.exitCode =
|
|
1201
|
+
process.exitCode = main2(process.argv.slice(2));
|
|
965
1202
|
}
|
|
966
1203
|
} catch {
|
|
967
|
-
const argvUrl = pathToFileURL(
|
|
1204
|
+
const argvUrl = pathToFileURL(path3.resolve(process.argv[1])).href;
|
|
968
1205
|
if (import.meta.url === argvUrl) {
|
|
969
|
-
process.exitCode =
|
|
1206
|
+
process.exitCode = main2(process.argv.slice(2));
|
|
970
1207
|
}
|
|
971
1208
|
}
|
|
972
1209
|
}
|
|
973
1210
|
|
|
974
1211
|
// src/scripts/_cli/cmd_adr_effective.ts
|
|
975
|
-
var _HERE2 =
|
|
976
|
-
var
|
|
1212
|
+
var _HERE2 = path4.dirname(fileURLToPath3(import.meta.url));
|
|
1213
|
+
var REPO_ROOT3 = path4.resolve(_HERE2, "..", "..", "..");
|
|
977
1214
|
var ASSERTIVE_SECTIONS = ["decision", "consequences", "amendment"];
|
|
978
1215
|
var RETIRES_RE = /^>?\s*retires:\s*(.+)$/i;
|
|
979
1216
|
var CLAUSE_MARKER_RE = /\*\*\((?:Superseded|Narrowed|Reopened) by ([^—)]+?)\s*(?:—[^)]*)?\)\*\*/;
|
|
@@ -1099,7 +1336,7 @@ function resolveAdrFile(ref, repoRoot) {
|
|
|
1099
1336
|
const match = area === null ? files.find((f) => new RegExp(`(^|/)ADR-0*${num}[-.]`, "i").test(f)) : files.find((f) => new RegExp(`/docs/adrs/${area}/0*${String(Number(num))}-`, "i").test(f));
|
|
1100
1337
|
return match ?? null;
|
|
1101
1338
|
}
|
|
1102
|
-
function effectiveState(ref, repoRoot =
|
|
1339
|
+
function effectiveState(ref, repoRoot = REPO_ROOT3) {
|
|
1103
1340
|
const parsed = normalise_ref(ref);
|
|
1104
1341
|
const id = parsed?.id ?? ref;
|
|
1105
1342
|
const match = resolveAdrFile(ref, repoRoot);
|
|
@@ -1115,7 +1352,7 @@ function effectiveState(ref, repoRoot = REPO_ROOT2) {
|
|
|
1115
1352
|
effective_decision: []
|
|
1116
1353
|
};
|
|
1117
1354
|
}
|
|
1118
|
-
const text =
|
|
1355
|
+
const text = fs3.readFileSync(match, "utf-8");
|
|
1119
1356
|
const scalars = parse_frontmatter(text) ?? {};
|
|
1120
1357
|
const structured = readAdrFrontmatter(text);
|
|
1121
1358
|
const provenance = structured === null ? null : provenanceOf(structured);
|
|
@@ -1130,7 +1367,7 @@ function effectiveState(ref, repoRoot = REPO_ROOT2) {
|
|
|
1130
1367
|
return {
|
|
1131
1368
|
ref: id,
|
|
1132
1369
|
resolved: true,
|
|
1133
|
-
file:
|
|
1370
|
+
file: path4.relative(repoRoot, match),
|
|
1134
1371
|
...scalars["status"] !== void 0 ? { status: scalars["status"] } : {},
|
|
1135
1372
|
...scalars["date"] !== void 0 ? { date: scalars["date"] } : {},
|
|
1136
1373
|
...scalars["decision"] !== void 0 ? { decision: scalars["decision"] } : {},
|
|
@@ -1216,39 +1453,39 @@ function parseArgv(argv) {
|
|
|
1216
1453
|
return { ok: false, message: "usage: agent-config adr:effective <ADR-NNN> [ADR-NNN \u2026] [--json]" };
|
|
1217
1454
|
return { ok: true, refs, json };
|
|
1218
1455
|
}
|
|
1219
|
-
function
|
|
1456
|
+
function main3(argv = process5.argv.slice(2)) {
|
|
1220
1457
|
const parsed = parseArgv(argv);
|
|
1221
1458
|
if (!parsed.ok) {
|
|
1222
|
-
|
|
1459
|
+
process5.stderr.write(`${parsed.message ?? "usage error"}
|
|
1223
1460
|
`);
|
|
1224
1461
|
return 2;
|
|
1225
1462
|
}
|
|
1226
1463
|
const states = (parsed.refs ?? []).map((ref) => effectiveState(ref));
|
|
1227
1464
|
if (parsed.json === true) {
|
|
1228
|
-
|
|
1465
|
+
process5.stdout.write(`${JSON.stringify(states, null, 2)}
|
|
1229
1466
|
`);
|
|
1230
1467
|
} else {
|
|
1231
1468
|
for (const state of states) {
|
|
1232
|
-
for (const line of render2(state))
|
|
1469
|
+
for (const line of render2(state)) process5.stdout.write(`${line}
|
|
1233
1470
|
`);
|
|
1234
|
-
|
|
1471
|
+
process5.stdout.write("\n");
|
|
1235
1472
|
}
|
|
1236
1473
|
}
|
|
1237
1474
|
const bad = states.filter((s) => !s.resolved || s.contradictions.length > 0);
|
|
1238
1475
|
return bad.length > 0 ? 1 : 0;
|
|
1239
1476
|
}
|
|
1240
1477
|
function _isCliEntry() {
|
|
1241
|
-
if (
|
|
1242
|
-
const argvUrl = pathToFileURL2(
|
|
1478
|
+
if (process5.argv[1] === void 0) return false;
|
|
1479
|
+
const argvUrl = pathToFileURL2(path4.resolve(process5.argv[1])).href;
|
|
1243
1480
|
if (import.meta.url === argvUrl) return true;
|
|
1244
1481
|
try {
|
|
1245
|
-
return
|
|
1482
|
+
return fs3.realpathSync(fileURLToPath3(import.meta.url)) === fs3.realpathSync(path4.resolve(process5.argv[1]));
|
|
1246
1483
|
} catch {
|
|
1247
1484
|
return false;
|
|
1248
1485
|
}
|
|
1249
1486
|
}
|
|
1250
1487
|
if (_isCliEntry()) {
|
|
1251
|
-
|
|
1488
|
+
process5.exitCode = main3();
|
|
1252
1489
|
}
|
|
1253
1490
|
export {
|
|
1254
1491
|
ASSERTIVE_SECTIONS,
|
|
@@ -1256,7 +1493,7 @@ export {
|
|
|
1256
1493
|
clauseFindings,
|
|
1257
1494
|
decisionSection,
|
|
1258
1495
|
effectiveState,
|
|
1259
|
-
|
|
1496
|
+
main3 as main,
|
|
1260
1497
|
parseArgv,
|
|
1261
1498
|
render2 as render,
|
|
1262
1499
|
resolveAdrFile,
|