@event4u/agent-config 10.3.0 → 10.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +78 -0
  3. package/README.md +1 -1
  4. package/dist/agent-src/commands/analyze.md +2 -1
  5. package/dist/agent-src/commands/design-system/capture.md +44 -0
  6. package/dist/agent-src/commands/design-system/generate.md +53 -0
  7. package/dist/agent-src/commands/design-system/import.md +63 -0
  8. package/dist/agent-src/commands/design-system.md +66 -0
  9. package/dist/agent-src/skills/design-system-capture/SKILL.md +9 -0
  10. package/dist/agent-src/skills/design-system-capture/references/design-system-json.md +70 -0
  11. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  12. package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.ts +4 -1
  13. package/dist/cli-delegate/chunk-RLN73PR5.js +157 -0
  14. package/dist/cli-delegate/{chunk-I5EAFRII.js → chunk-ZPSXJTLI.js} +2 -154
  15. package/dist/cli-delegate/cmd_conformance.js +671 -213
  16. package/dist/cli-delegate/cmd_handoff.js +8 -6
  17. package/dist/cli-delegate/cmd_session_recycle.js +5 -3
  18. package/dist/discovery/deprecation-report.md +1 -1
  19. package/dist/discovery/discovery-manifest.json +116 -11
  20. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  21. package/dist/discovery/discovery-manifest.summary.md +3 -3
  22. package/dist/discovery/dormancy-report.md +1 -1
  23. package/dist/discovery/orphan-report.md +1 -1
  24. package/dist/discovery/packs.json +9 -5
  25. package/dist/discovery/trust-report.md +2 -2
  26. package/dist/discovery/workspaces.json +8 -4
  27. package/dist/hooks/dispatch.js +940 -387
  28. package/dist/mcp/registry-manifest.json +2 -2
  29. package/dist/mcp/server.json +2 -2
  30. package/dist/mcp/server.mjs +1102 -592
  31. package/package.json +1 -1
  32. package/src/agent-src/templates/scripts/work_engine/directives/ui/design.ts +4 -1
  33. package/src/config/gate-coverage.yml +23 -2
  34. package/src/config/gate-violation-baselines.json +2 -2
  35. package/src/scripts/_lib/design_system_import.ts +987 -0
  36. package/src/scripts/design_system_import.ts +264 -0
  37. package/src/scripts/hook_manifest.yaml +71 -2
  38. package/src/scripts/hooks/concern_registry.ts +4 -0
  39. package/src/scripts/hooks/dispatch_hook.ts +10 -0
  40. package/src/scripts/hooks/host_semantics.ts +2 -0
  41. package/src/scripts/hooks/spawn_guard_shadow_hook.ts +212 -0
  42. package/src/scripts/hooks/subagent_ledger_hook.ts +723 -0
  43. package/src/scripts/hooks/turn_end_gate_hook.ts +39 -2
  44. package/src/scripts/lint_hook_manifest.ts +2 -0
  45. package/src/scripts/lint_rule_skill_pack_reach.ts +194 -13
  46. package/tests/fixtures/hooks/subagent_start.json +7 -0
  47. package/tests/fixtures/hooks/subagent_stop.json +8 -0
@@ -2,6 +2,9 @@ import { createRequire as __acCreateRequire } from 'node:module'; const require
2
2
  import {
3
3
  readHookStdin
4
4
  } from "./chunk-MMJL4TIX.js";
5
+ import {
6
+ validateAssumption
7
+ } from "./chunk-ZPSXJTLI.js";
5
8
  import {
6
9
  ArgparseExit,
7
10
  STATUS_SYMBOLS,
@@ -59,12 +62,12 @@ import {
59
62
 
60
63
  // src/scripts/_cli/cmd_conformance.ts
61
64
  var YAML = __toESM(require_dist(), 1);
62
- import * as fs14 from "node:fs";
65
+ import * as fs15 from "node:fs";
63
66
  import * as os7 from "node:os";
64
- import * as path14 from "node:path";
67
+ import * as path15 from "node:path";
65
68
  import process6 from "node:process";
66
69
  import { spawnSync as spawnSync2 } from "node:child_process";
67
- import { fileURLToPath as fileURLToPath14, pathToFileURL as pathToFileURL14 } from "node:url";
70
+ import { fileURLToPath as fileURLToPath15, pathToFileURL as pathToFileURL15 } from "node:url";
68
71
 
69
72
  // src/install/txlog.ts
70
73
  import { createReadStream, createWriteStream, existsSync, readFileSync, renameSync, statSync, unlinkSync } from "node:fs";
@@ -125,18 +128,18 @@ function routeTargetPathsPosix(target) {
125
128
  }
126
129
 
127
130
  // src/scripts/report_conformance_funnel.ts
128
- import * as fs13 from "node:fs";
131
+ import * as fs14 from "node:fs";
129
132
  import * as os6 from "node:os";
130
- import * as path13 from "node:path";
133
+ import * as path14 from "node:path";
131
134
  import process5 from "node:process";
132
- import { fileURLToPath as fileURLToPath13, pathToFileURL as pathToFileURL13 } from "node:url";
135
+ import { fileURLToPath as fileURLToPath14, pathToFileURL as pathToFileURL14 } from "node:url";
133
136
 
134
137
  // src/scripts/conformance_scan.ts
135
- import { createHash as createHash3 } from "node:crypto";
136
- import fs9 from "node:fs";
138
+ import { createHash as createHash4 } from "node:crypto";
139
+ import fs10 from "node:fs";
137
140
  import os2 from "node:os";
138
- import path9 from "node:path";
139
- import { fileURLToPath as fileURLToPath9, pathToFileURL as pathToFileURL9 } from "node:url";
141
+ import path10 from "node:path";
142
+ import { fileURLToPath as fileURLToPath10, pathToFileURL as pathToFileURL10 } from "node:url";
140
143
 
141
144
  // src/scripts/_lib/transcript_entry.ts
142
145
  function _isObject(v) {
@@ -1339,10 +1342,10 @@ if (isCliEntry) {
1339
1342
  }
1340
1343
 
1341
1344
  // src/scripts/hooks/turn_end_gate_hook.ts
1342
- import * as crypto2 from "node:crypto";
1343
- import * as fs6 from "node:fs";
1344
- import * as path6 from "node:path";
1345
- import { fileURLToPath as fileURLToPath6, pathToFileURL as pathToFileURL6 } from "node:url";
1345
+ import * as crypto3 from "node:crypto";
1346
+ import * as fs7 from "node:fs";
1347
+ import * as path7 from "node:path";
1348
+ import { fileURLToPath as fileURLToPath7, pathToFileURL as pathToFileURL7 } from "node:url";
1346
1349
 
1347
1350
  // src/scripts/hooks/end_review_nudge_hook.ts
1348
1351
  import { spawnSync } from "node:child_process";
@@ -1710,9 +1713,456 @@ if (_isCliEntry5()) {
1710
1713
  process.exit(main5());
1711
1714
  }
1712
1715
 
1716
+ // src/scripts/hooks/subagent_ledger_hook.ts
1717
+ import * as crypto2 from "node:crypto";
1718
+ import * as fs6 from "node:fs";
1719
+ import * as path6 from "node:path";
1720
+ import { fileURLToPath as fileURLToPath6, pathToFileURL as pathToFileURL6 } from "node:url";
1721
+
1722
+ // src/scripts/_lib/subagent_response.ts
1723
+ var MAX_SUMMARY_CHARS = 2e3;
1724
+ var MAX_RESPONSE_LINE_CHARS = 240;
1725
+ var MAX_RESPONSE_ENTRIES = 40;
1726
+ var MAX_ARTIFACT_REF_CHARS = 200;
1727
+ var MAX_ENVELOPE_CHARS = 12e3;
1728
+ var CONFIDENCE = /* @__PURE__ */ new Set(["low", "medium", "high"]);
1729
+ function validateResponse(input) {
1730
+ const errors = [];
1731
+ if (input === null || typeof input !== "object") {
1732
+ return { valid: false, errors: ["response is not an object"] };
1733
+ }
1734
+ const r = input;
1735
+ if (typeof r.summary !== "string") errors.push("summary missing or not a string");
1736
+ if (typeof r.handoff !== "string") errors.push("handoff missing or not a string");
1737
+ if (!CONFIDENCE.has(r.confidence)) errors.push(`confidence must be low|medium|high (got ${String(r.confidence)})`);
1738
+ if (!Array.isArray(r.findings)) errors.push("findings missing or not an array");
1739
+ if (!Array.isArray(r.risks)) errors.push("risks missing or not an array");
1740
+ if (Array.isArray(r.findings)) {
1741
+ for (const [i, f] of r.findings.entries()) {
1742
+ if (!f || typeof f.title !== "string") errors.push(`finding[${i}] missing title`);
1743
+ const refs = f?.evidence_refs;
1744
+ if (refs && refs.some((x) => typeof x !== "string" || x.includes("\n"))) {
1745
+ errors.push(`finding[${i}] evidence_refs must be ref tokens, not bodies`);
1746
+ }
1747
+ }
1748
+ }
1749
+ if (r.assumptions !== void 0) {
1750
+ if (!Array.isArray(r.assumptions)) {
1751
+ errors.push("assumptions must be an array of {statement, basis, epistemic_state}");
1752
+ } else {
1753
+ for (const [i, a] of r.assumptions.entries()) {
1754
+ errors.push(...validateAssumption(a, `assumptions[${i}]`));
1755
+ }
1756
+ }
1757
+ }
1758
+ if (typeof r.summary === "string" && r.summary.length > MAX_SUMMARY_CHARS) {
1759
+ errors.push(`summary is ${r.summary.length} chars (max ${MAX_SUMMARY_CHARS}) \u2014 the envelope carries a bounded summary; the full result belongs on disk (artifact_paths)`);
1760
+ }
1761
+ if (typeof r.handoff === "string" && r.handoff.length > MAX_RESPONSE_LINE_CHARS) {
1762
+ errors.push(`handoff is ${r.handoff.length} chars (max ${MAX_RESPONSE_LINE_CHARS})`);
1763
+ }
1764
+ for (const [key, arr] of [
1765
+ ["findings", r.findings],
1766
+ ["risks", r.risks],
1767
+ ["artifact_paths", r.artifact_paths]
1768
+ ]) {
1769
+ if (Array.isArray(arr) && arr.length > MAX_RESPONSE_ENTRIES) {
1770
+ errors.push(`${key} carries ${arr.length} entries (max ${MAX_RESPONSE_ENTRIES}) \u2014 an envelope is a handoff, not a transcript`);
1771
+ }
1772
+ }
1773
+ if (Array.isArray(r.risks)) {
1774
+ for (const [i, risk] of r.risks.entries()) {
1775
+ if (typeof risk === "string" && risk.length > MAX_RESPONSE_LINE_CHARS) {
1776
+ errors.push(`risks[${i}] is ${risk.length} chars (max ${MAX_RESPONSE_LINE_CHARS})`);
1777
+ }
1778
+ }
1779
+ }
1780
+ if (Array.isArray(r.findings)) {
1781
+ for (const [i, f] of r.findings.entries()) {
1782
+ if (f && typeof f.title === "string" && f.title.length > MAX_RESPONSE_LINE_CHARS) {
1783
+ errors.push(`finding[${i}] title is ${f.title.length} chars (max ${MAX_RESPONSE_LINE_CHARS})`);
1784
+ }
1785
+ }
1786
+ }
1787
+ if (r.artifact_paths !== void 0) {
1788
+ if (!Array.isArray(r.artifact_paths)) {
1789
+ errors.push("artifact_paths must be an array of path ref tokens");
1790
+ } else {
1791
+ for (const [i, p] of r.artifact_paths.entries()) {
1792
+ if (typeof p !== "string" || p.includes("\n") || p.length > MAX_ARTIFACT_REF_CHARS) {
1793
+ errors.push(`artifact_paths[${i}] must be a single-line path ref \u2264 ${MAX_ARTIFACT_REF_CHARS} chars`);
1794
+ }
1795
+ }
1796
+ }
1797
+ }
1798
+ try {
1799
+ const serialized = JSON.stringify(input);
1800
+ if (serialized.length > MAX_ENVELOPE_CHARS) {
1801
+ errors.push(`envelope serializes to ${serialized.length} chars (max ${MAX_ENVELOPE_CHARS}) \u2014 move content to disk and reference it via artifact_paths`);
1802
+ }
1803
+ } catch {
1804
+ errors.push("envelope is not JSON-serializable");
1805
+ }
1806
+ return { valid: errors.length === 0, errors };
1807
+ }
1808
+
1809
+ // src/scripts/hooks/subagent_ledger_hook.ts
1810
+ var EXIT_ALLOW4 = 0;
1811
+ function isObject2(v) {
1812
+ return typeof v === "object" && v !== null && !Array.isArray(v);
1813
+ }
1814
+ var LEDGER_DIR = path6.join("agents", "runtime", "state", "subagent-ledger");
1815
+ var OPEN_SUBDIR = "open";
1816
+ var OPEN_RECORD_TTL_MS = 24 * 60 * 60 * 1e3;
1817
+ function refFor(agentId) {
1818
+ return crypto2.createHash("sha256").update(agentId, "utf8").digest("hex").slice(0, 12);
1819
+ }
1820
+ function unwrapPayload(envelope) {
1821
+ const inner = envelope["payload"];
1822
+ return isObject2(inner) ? inner : envelope;
1823
+ }
1824
+ function str2(payload, ...keys) {
1825
+ for (const k of keys) {
1826
+ const v = payload[k];
1827
+ if (typeof v === "string" && v) return v;
1828
+ }
1829
+ return null;
1830
+ }
1831
+ function extractParentId(payload, ownId) {
1832
+ const explicit = str2(payload, "parent_agent_id", "parentAgentId");
1833
+ if (explicit) return explicit;
1834
+ const session = payload["session"];
1835
+ if (isObject2(session)) {
1836
+ const sessionAgent = str2(session, "agent_id", "agentId");
1837
+ if (sessionAgent && sessionAgent !== ownId) return sessionAgent;
1838
+ }
1839
+ return null;
1840
+ }
1841
+ function classifyEnvelope(message) {
1842
+ if (message === null || !message.trim()) return { verdict: "absent", error_count: 0 };
1843
+ const candidates = _jsonObjectCandidates(message);
1844
+ if (candidates.length === 0) return { verdict: "absent", error_count: 0 };
1845
+ let best = null;
1846
+ for (const candidate of candidates) {
1847
+ const result = validateResponse(candidate);
1848
+ if (result.valid) return { verdict: "ok", error_count: 0 };
1849
+ if (best === null) best = { verdict: "fail", error_count: result.errors.length };
1850
+ }
1851
+ return best ?? { verdict: "absent", error_count: 0 };
1852
+ }
1853
+ function _jsonObjectCandidates(message) {
1854
+ const texts = [];
1855
+ for (const match of message.matchAll(/^[ \t]*```[ \t]*(?:json)?[ \t]*\r?\n([\s\S]*?)^[ \t]*```/gm)) {
1856
+ if (match[1]) texts.push(match[1]);
1857
+ }
1858
+ let depth = 0;
1859
+ let start = -1;
1860
+ let inString = false;
1861
+ let escaped = false;
1862
+ for (let i = 0; i < message.length; i++) {
1863
+ const ch = message[i];
1864
+ if (inString) {
1865
+ if (escaped) escaped = false;
1866
+ else if (ch === "\\") escaped = true;
1867
+ else if (ch === '"') inString = false;
1868
+ continue;
1869
+ }
1870
+ if (ch === '"') inString = true;
1871
+ else if (ch === "{") {
1872
+ if (depth === 0) start = i;
1873
+ depth++;
1874
+ } else if (ch === "}") {
1875
+ if (depth > 0) {
1876
+ depth--;
1877
+ if (depth === 0 && start !== -1) {
1878
+ texts.push(message.slice(start, i + 1));
1879
+ start = -1;
1880
+ }
1881
+ }
1882
+ }
1883
+ }
1884
+ const out = [];
1885
+ for (const text of texts) {
1886
+ try {
1887
+ const parsed = JSON.parse(text.trim());
1888
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) out.push(parsed);
1889
+ } catch {
1890
+ }
1891
+ }
1892
+ return out;
1893
+ }
1894
+ function openDir(root) {
1895
+ return path6.join(root, LEDGER_DIR, OPEN_SUBDIR);
1896
+ }
1897
+ function openFile(root, ref) {
1898
+ return path6.join(openDir(root), `${ref}.json`);
1899
+ }
1900
+ var DEPTH_BASES = /* @__PURE__ */ new Set(["observed", "asserted-parent", "assumed-root"]);
1901
+ function _asOpenRecord(value, expectedRef) {
1902
+ if (!isObject2(value)) return null;
1903
+ const ref = value["ref"];
1904
+ if (typeof ref !== "string" || ref !== expectedRef) return null;
1905
+ if (typeof value["started_at"] !== "string") return null;
1906
+ if (typeof value["depth"] !== "number" || !Number.isFinite(value["depth"])) return null;
1907
+ if (typeof value["depth_basis"] !== "string" || !DEPTH_BASES.has(value["depth_basis"])) return null;
1908
+ const agentType = value["agent_type"];
1909
+ const parentRef = value["parent_ref"];
1910
+ const sessionId = value["session_id"];
1911
+ return {
1912
+ ref,
1913
+ agent_type: typeof agentType === "string" ? agentType : null,
1914
+ started_at: value["started_at"],
1915
+ parent_ref: typeof parentRef === "string" ? parentRef : null,
1916
+ depth: value["depth"],
1917
+ depth_basis: value["depth_basis"],
1918
+ session_id: typeof sessionId === "string" ? sessionId : null
1919
+ };
1920
+ }
1921
+ function readOpenRecords(root) {
1922
+ const out = /* @__PURE__ */ new Map();
1923
+ let names;
1924
+ try {
1925
+ names = fs6.readdirSync(openDir(root));
1926
+ } catch {
1927
+ return out;
1928
+ }
1929
+ for (const name of names) {
1930
+ if (!name.endsWith(".json")) continue;
1931
+ const expectedRef = name.slice(0, -".json".length);
1932
+ try {
1933
+ const raw = fs6.readFileSync(path6.join(openDir(root), name), "utf8");
1934
+ const rec = _asOpenRecord(JSON.parse(raw), expectedRef);
1935
+ if (rec) out.set(rec.ref, rec);
1936
+ } catch {
1937
+ }
1938
+ }
1939
+ return out;
1940
+ }
1941
+ function resolveDepth(parentRef, open) {
1942
+ if (parentRef === null) return { depth: 1, depth_basis: "assumed-root" };
1943
+ const parent = open.get(parentRef);
1944
+ if (!parent) return { depth: 2, depth_basis: "asserted-parent" };
1945
+ return { depth: parent.depth + 1, depth_basis: "observed" };
1946
+ }
1947
+ function ledgerFileFor(root, ts) {
1948
+ return path6.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
1949
+ }
1950
+ function appendLedgerLine(root, ts, line) {
1951
+ if (is_replay_mode()) return;
1952
+ const file = ledgerFileFor(root, ts);
1953
+ fs6.mkdirSync(path6.dirname(file), { recursive: true });
1954
+ fs6.appendFileSync(file, `${JSON.stringify(line)}
1955
+ `, "utf8");
1956
+ }
1957
+ var WALL_CLOCK_ARMS_MS = [
1958
+ { label: "5m", ms: 5 * 60 * 1e3 },
1959
+ { label: "15m", ms: 15 * 60 * 1e3 },
1960
+ { label: "30m", ms: 30 * 60 * 1e3 },
1961
+ { label: "2h", ms: 2 * 60 * 60 * 1e3 }
1962
+ ];
1963
+ function armsExceeded(elapsedMs) {
1964
+ if (elapsedMs === null || !Number.isFinite(elapsedMs)) return [];
1965
+ return WALL_CLOCK_ARMS_MS.filter((a) => elapsedMs >= a.ms).map((a) => a.label);
1966
+ }
1967
+ function openRecordStats(root, nowMs = Date.now()) {
1968
+ const ledgerPresent = fs6.existsSync(path6.join(root, LEDGER_DIR));
1969
+ const open = readOpenRecords(root);
1970
+ let maxDepth = 0;
1971
+ let counted = 0;
1972
+ let stale = 0;
1973
+ for (const rec of open.values()) {
1974
+ const started = Date.parse(rec.started_at);
1975
+ const isStale = Number.isFinite(started) && nowMs - started >= OPEN_RECORD_TTL_MS;
1976
+ if (isStale) {
1977
+ stale++;
1978
+ continue;
1979
+ }
1980
+ counted++;
1981
+ if (rec.depth > maxDepth) maxDepth = rec.depth;
1982
+ }
1983
+ return {
1984
+ open_count: counted,
1985
+ max_depth: maxDepth,
1986
+ stale_excluded: stale,
1987
+ ledger_present: ledgerPresent
1988
+ };
1989
+ }
1990
+ function writeOpenRecord(root, rec) {
1991
+ atomic_write_json(openFile(root, rec.ref), rec);
1992
+ }
1993
+ function removeOpenRecord(root, ref) {
1994
+ if (is_replay_mode()) return;
1995
+ try {
1996
+ fs6.unlinkSync(openFile(root, ref));
1997
+ } catch {
1998
+ }
1999
+ }
2000
+ function countOpen(root) {
2001
+ try {
2002
+ return fs6.readdirSync(openDir(root)).filter((n) => n.endsWith(".json")).length;
2003
+ } catch {
2004
+ return 0;
2005
+ }
2006
+ }
2007
+ function reapStaleOpenRecords(root, nowIso) {
2008
+ const now = Date.parse(nowIso);
2009
+ if (!Number.isFinite(now)) return 0;
2010
+ let reaped = 0;
2011
+ for (const rec of readOpenRecords(root).values()) {
2012
+ const started = Date.parse(rec.started_at);
2013
+ if (!Number.isFinite(started) || now - started < OPEN_RECORD_TTL_MS) continue;
2014
+ removeOpenRecord(root, rec.ref);
2015
+ reaped++;
2016
+ appendLedgerLine(root, nowIso, {
2017
+ event: "subagent_reaped",
2018
+ ts: nowIso,
2019
+ ref: rec.ref,
2020
+ agent_type: rec.agent_type,
2021
+ depth: rec.depth,
2022
+ depth_basis: rec.depth_basis,
2023
+ // R2 round 2, finding 5: the arm list is NOT repeated here. A reap
2024
+ // fires only past OPEN_RECORD_TTL_MS (24 h), which exceeds every
2025
+ // arm (largest: 2 h), so `stop_loss_arms_exceeded` would be a
2026
+ // constant on this line — a field that cannot vary answers no
2027
+ // question. `age_ms` carries strictly more information and is what
2028
+ // a reader should aggregate over.
2029
+ age_ms: now - started,
2030
+ reason: "open record exceeded OPEN_RECORD_TTL_MS without a stop"
2031
+ });
2032
+ }
2033
+ return reaped;
2034
+ }
2035
+ function appendUnidentified(root, event, nowIso, payload) {
2036
+ appendLedgerLine(root, nowIso, {
2037
+ event,
2038
+ ts: nowIso,
2039
+ ref: null,
2040
+ unidentified: true,
2041
+ // The agent TYPE is an id-shaped enum and may still be present; it is
2042
+ // the only thing salvageable from a payload with no id.
2043
+ agent_type: str2(payload, "agent_type", "agentType", "subagent_type", "subagentType"),
2044
+ reason: "payload carried no agent id \u2014 nothing to correlate start with stop"
2045
+ });
2046
+ }
2047
+ function handleStart(root, payload, nowIso, sessionId) {
2048
+ const agentId = str2(payload, "agent_id", "agentId");
2049
+ if (agentId === null) {
2050
+ appendUnidentified(root, "subagent_start", nowIso, payload);
2051
+ return;
2052
+ }
2053
+ const ref = refFor(agentId);
2054
+ const parentId = extractParentId(payload, agentId);
2055
+ const parentRef = parentId ? refFor(parentId) : null;
2056
+ const { depth, depth_basis } = resolveDepth(parentRef, readOpenRecords(root));
2057
+ const rec = {
2058
+ ref,
2059
+ agent_type: str2(payload, "agent_type", "agentType", "subagent_type", "subagentType"),
2060
+ started_at: nowIso,
2061
+ parent_ref: parentRef,
2062
+ depth,
2063
+ depth_basis,
2064
+ session_id: sessionId
2065
+ };
2066
+ writeOpenRecord(root, rec);
2067
+ appendLedgerLine(root, nowIso, {
2068
+ event: "subagent_start",
2069
+ ts: nowIso,
2070
+ ref,
2071
+ agent_type: rec.agent_type,
2072
+ parent_ref: parentRef,
2073
+ depth,
2074
+ depth_basis,
2075
+ concurrent_open: countOpen(root)
2076
+ });
2077
+ }
2078
+ function handleStop(root, payload, nowIso) {
2079
+ const agentId = str2(payload, "agent_id", "agentId");
2080
+ if (agentId === null) {
2081
+ appendUnidentified(root, "subagent_stop", nowIso, payload);
2082
+ return;
2083
+ }
2084
+ const ref = refFor(agentId);
2085
+ const rec = readOpenRecords(root).get(ref) ?? null;
2086
+ let durationMs = null;
2087
+ if (rec) {
2088
+ const started = Date.parse(rec.started_at);
2089
+ if (Number.isFinite(started)) durationMs = Math.max(0, Date.parse(nowIso) - started);
2090
+ }
2091
+ const parse2 = classifyEnvelope(str2(payload, "last_assistant_message", "lastAssistantMessage"));
2092
+ removeOpenRecord(root, ref);
2093
+ appendLedgerLine(root, nowIso, {
2094
+ event: "subagent_stop",
2095
+ ts: nowIso,
2096
+ ref,
2097
+ agent_type: rec?.agent_type ?? str2(payload, "agent_type", "agentType", "subagent_type", "subagentType"),
2098
+ depth: rec?.depth ?? null,
2099
+ depth_basis: rec?.depth_basis ?? null,
2100
+ // `null` = the matching start was never seen. That is a finding about
2101
+ // the instrument's own coverage and is recorded as such, not as 0.
2102
+ duration_ms: durationMs,
2103
+ // Phase 3 Step 3, shadow: which wall-clock arms this dispatch would
2104
+ // have tripped. Recorded, never acted on.
2105
+ stop_loss_arms_exceeded: armsExceeded(durationMs),
2106
+ start_seen: rec !== null,
2107
+ envelope_parse: parse2.verdict,
2108
+ envelope_error_count: parse2.error_count,
2109
+ concurrent_open: countOpen(root)
2110
+ });
2111
+ }
2112
+ function processEnvelope(envelope, consumerRoot) {
2113
+ try {
2114
+ if (!isObject2(envelope)) return EXIT_ALLOW4;
2115
+ const event = envelope["event"];
2116
+ if (event !== "subagent_start" && event !== "subagent_stop") return EXIT_ALLOW4;
2117
+ const payload = unwrapPayload(envelope);
2118
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
2119
+ const sessionId = str2(payload, "session_id", "sessionId") ?? str2(envelope, "session_id", "sessionId");
2120
+ reapStaleOpenRecords(consumerRoot, nowIso);
2121
+ if (event === "subagent_start") handleStart(consumerRoot, payload, nowIso, sessionId);
2122
+ else handleStop(consumerRoot, payload, nowIso);
2123
+ } catch {
2124
+ return EXIT_ALLOW4;
2125
+ }
2126
+ return EXIT_ALLOW4;
2127
+ }
2128
+ function resolveConsumerRoot(envelope) {
2129
+ if (isObject2(envelope)) {
2130
+ const pr = str2(envelope, "workspace_root", "project_root");
2131
+ if (pr) return pr;
2132
+ const payload = unwrapPayload(envelope);
2133
+ const cwd = str2(payload, "cwd");
2134
+ if (cwd) return cwd;
2135
+ }
2136
+ return process.cwd();
2137
+ }
2138
+ function main6() {
2139
+ const raw = readHookStdin();
2140
+ let envelope = {};
2141
+ try {
2142
+ envelope = raw.trim() ? JSON.parse(raw) : {};
2143
+ } catch {
2144
+ return EXIT_ALLOW4;
2145
+ }
2146
+ return processEnvelope(envelope, resolveConsumerRoot(envelope));
2147
+ }
2148
+ function _isCliEntry6() {
2149
+ if (true) {
2150
+ return false;
2151
+ }
2152
+ if (process.argv[1] === void 0) return false;
2153
+ const argvUrl = pathToFileURL6(path6.resolve(process.argv[1])).href;
2154
+ if (import.meta.url === argvUrl) return true;
2155
+ try {
2156
+ return fs6.realpathSync(fileURLToPath6(import.meta.url)) === fs6.realpathSync(path6.resolve(process.argv[1]));
2157
+ } catch {
2158
+ return false;
2159
+ }
2160
+ }
2161
+ if (_isCliEntry6()) process.exit(main6());
2162
+
1713
2163
  // src/scripts/hooks/turn_end_gate_hook.ts
1714
2164
  var EXIT_BLOCK2 = 1;
1715
- var EXIT_ALLOW4 = 0;
2165
+ var EXIT_ALLOW5 = 0;
1716
2166
  var TRANSCRIPT_READ_MAX_BYTES = 8 * 1024 * 1024;
1717
2167
  function stripFencedBlocks(text) {
1718
2168
  const out = [];
@@ -1816,7 +2266,7 @@ function detectPromissory(reply) {
1816
2266
  }
1817
2267
  function readCiSettled(workspaceRoot) {
1818
2268
  try {
1819
- const raw = fs6.readFileSync(path6.join(workspaceRoot, STATE_FILE3), "utf-8");
2269
+ const raw = fs7.readFileSync(path7.join(workspaceRoot, STATE_FILE3), "utf-8");
1820
2270
  const decoded = JSON.parse(raw);
1821
2271
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
1822
2272
  const ci = decoded["ci_last"];
@@ -1850,7 +2300,7 @@ function detectCompletionClaim(reply, ci) {
1850
2300
  }
1851
2301
  function readLanguagePin(workspaceRoot) {
1852
2302
  try {
1853
- const raw = fs6.readFileSync(path6.join(workspaceRoot, STATE_FILE), "utf-8");
2303
+ const raw = fs7.readFileSync(path7.join(workspaceRoot, STATE_FILE), "utf-8");
1854
2304
  const decoded = JSON.parse(raw);
1855
2305
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
1856
2306
  const lang = decoded["language"];
@@ -1899,17 +2349,17 @@ function detectUnverifiedEdit(toolCalls) {
1899
2349
  };
1900
2350
  }
1901
2351
  function stateDir(workspaceRoot) {
1902
- return path6.join(workspaceRoot, "agents", "runtime", "state", "turn-end-gate");
2352
+ return path7.join(workspaceRoot, "agents", "runtime", "state", "turn-end-gate");
1903
2353
  }
1904
2354
  function sessionStateFile2(workspaceRoot, sessionKey) {
1905
- return path6.join(stateDir(workspaceRoot), `${sessionKey}.json`);
2355
+ return path7.join(stateDir(workspaceRoot), `${sessionKey}.json`);
1906
2356
  }
1907
2357
  function deriveSessionKey2(sessionId) {
1908
- return crypto2.createHash("sha256").update(sessionId).digest("hex").slice(0, 32);
2358
+ return crypto3.createHash("sha256").update(sessionId).digest("hex").slice(0, 32);
1909
2359
  }
1910
2360
  function alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal) {
1911
2361
  try {
1912
- const raw = fs6.readFileSync(sessionStateFile2(workspaceRoot, sessionKey), "utf-8");
2362
+ const raw = fs7.readFileSync(sessionStateFile2(workspaceRoot, sessionKey), "utf-8");
1913
2363
  const decoded = JSON.parse(raw);
1914
2364
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
1915
2365
  return decoded["refused_turn"] === turnOrdinal;
@@ -1934,10 +2384,10 @@ function readTranscriptTail(transcriptPath, opts = {}) {
1934
2384
  if (!transcriptPath || !isSafeTranscriptPath(transcriptPath, opts)) return empty;
1935
2385
  let lines;
1936
2386
  try {
1937
- if (opts.maxBytes !== void 0 && fs6.statSync(transcriptPath).size > opts.maxBytes) {
2387
+ if (opts.maxBytes !== void 0 && fs7.statSync(transcriptPath).size > opts.maxBytes) {
1938
2388
  return empty;
1939
2389
  }
1940
- lines = fs6.readFileSync(transcriptPath, "utf-8").split("\n");
2390
+ lines = fs7.readFileSync(transcriptPath, "utf-8").split("\n");
1941
2391
  } catch {
1942
2392
  return empty;
1943
2393
  }
@@ -2010,33 +2460,41 @@ function _messageText(content) {
2010
2460
  }
2011
2461
  return parts.length > 0 ? parts.join("\n") : null;
2012
2462
  }
2013
- function str2(v) {
2463
+ function str3(v) {
2014
2464
  return typeof v === "string" ? v : "";
2015
2465
  }
2016
- function main6() {
2466
+ function main7() {
2017
2467
  let envelope;
2018
2468
  let payload;
2019
2469
  try {
2020
2470
  [envelope, payload] = unwrap(readHookStdin(), "claude");
2021
2471
  } catch {
2022
- return EXIT_ALLOW4;
2472
+ return EXIT_ALLOW5;
2473
+ }
2474
+ if (payload["stop_hook_active"] === true) return EXIT_ALLOW5;
2475
+ const workspaceRoot = str3(envelope["workspace_root"]) || process.cwd();
2476
+ let dispatchOpen = false;
2477
+ try {
2478
+ dispatchOpen = openRecordStats(workspaceRoot).open_count > 0;
2479
+ } catch {
2023
2480
  }
2024
- if (payload["stop_hook_active"] === true) return EXIT_ALLOW4;
2025
- const workspaceRoot = str2(envelope["workspace_root"]) || process.cwd();
2026
- const transcriptPath = str2(
2481
+ const transcriptPath = str3(
2027
2482
  payload["transcript_path"] ?? payload["transcriptPath"]
2028
2483
  );
2029
2484
  const { lastAssistant, turnOrdinal, toolCalls } = readTranscriptTail(transcriptPath, {
2030
2485
  maxBytes: TRANSCRIPT_READ_MAX_BYTES
2031
2486
  });
2032
- if (!lastAssistant) return EXIT_ALLOW4;
2487
+ if (!lastAssistant) return EXIT_ALLOW5;
2033
2488
  const sessionKey = deriveSessionKey2(
2034
- str2(envelope["session_id"]) || "unknown-session"
2489
+ str3(envelope["session_id"]) || "unknown-session"
2035
2490
  );
2036
- if (alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal)) return EXIT_ALLOW4;
2491
+ if (alreadyRefusedTurn(workspaceRoot, sessionKey, turnOrdinal)) return EXIT_ALLOW5;
2037
2492
  const findings = [];
2038
2493
  for (const f of [
2039
- detectPromissory(lastAssistant),
2494
+ // A and D are the completion-adjacent pair a pending dispatch excuses
2495
+ // (Phase 3 Step 2, narrowed by R2 round 2 finding 2). B and C are not
2496
+ // excused by anything about a dispatch and run unchanged.
2497
+ dispatchOpen ? null : detectPromissory(lastAssistant),
2040
2498
  detectLanguage(lastAssistant, readLanguagePin(workspaceRoot)),
2041
2499
  detectUnverifiedEdit(toolCalls),
2042
2500
  // Round 7 § Phase 1 — detector D, in the same unconditional list as the
@@ -2046,11 +2504,11 @@ function main6() {
2046
2504
  // gating is where the comment above says gating belongs — inside the
2047
2505
  // detector: no CI observed, or a settled read, or no completion claim
2048
2506
  // ⇒ no finding.
2049
- detectCompletionClaim(lastAssistant, readCiSettled(workspaceRoot))
2507
+ dispatchOpen ? null : detectCompletionClaim(lastAssistant, readCiSettled(workspaceRoot))
2050
2508
  ]) {
2051
2509
  if (f) findings.push(f);
2052
2510
  }
2053
- if (findings.length === 0) return EXIT_ALLOW4;
2511
+ if (findings.length === 0) return EXIT_ALLOW5;
2054
2512
  markRefusedTurn(workspaceRoot, sessionKey, turnOrdinal, findings[0].detector);
2055
2513
  const lines = findings.map(
2056
2514
  (f) => ` \xB7 ${f.detector}: ${f.reason}
@@ -2065,37 +2523,37 @@ ${lines.join("\n")}
2065
2523
  );
2066
2524
  return EXIT_BLOCK2;
2067
2525
  }
2068
- function _isCliEntry6() {
2526
+ function _isCliEntry7() {
2069
2527
  if (true) {
2070
2528
  return false;
2071
2529
  }
2072
2530
  if (process.argv[1] === void 0) {
2073
2531
  return false;
2074
2532
  }
2075
- const argvUrl = pathToFileURL6(path6.resolve(process.argv[1])).href;
2533
+ const argvUrl = pathToFileURL7(path7.resolve(process.argv[1])).href;
2076
2534
  if (import.meta.url === argvUrl) {
2077
2535
  return true;
2078
2536
  }
2079
2537
  try {
2080
- const here = fs6.realpathSync(fileURLToPath6(import.meta.url));
2081
- const argv = fs6.realpathSync(path6.resolve(process.argv[1]));
2538
+ const here = fs7.realpathSync(fileURLToPath7(import.meta.url));
2539
+ const argv = fs7.realpathSync(path7.resolve(process.argv[1]));
2082
2540
  return here === argv;
2083
2541
  } catch {
2084
2542
  return false;
2085
2543
  }
2086
2544
  }
2087
- if (_isCliEntry6()) {
2088
- process.exit(main6());
2545
+ if (_isCliEntry7()) {
2546
+ process.exit(main7());
2089
2547
  }
2090
2548
 
2091
2549
  // src/scripts/hooks/evidence_independence.ts
2092
- import crypto3 from "node:crypto";
2093
- import fs7 from "node:fs";
2094
- import path7 from "node:path";
2095
- import { fileURLToPath as fileURLToPath7, pathToFileURL as pathToFileURL7 } from "node:url";
2096
- var EXIT_ALLOW5 = 0;
2550
+ import crypto4 from "node:crypto";
2551
+ import fs8 from "node:fs";
2552
+ import path8 from "node:path";
2553
+ import { fileURLToPath as fileURLToPath8, pathToFileURL as pathToFileURL8 } from "node:url";
2554
+ var EXIT_ALLOW6 = 0;
2097
2555
  var EXIT_BLOCK3 = 1;
2098
- var STATE_FILE4 = path7.join("agents", "state", "evidence-dispatch.json");
2556
+ var STATE_FILE4 = path8.join("agents", "state", "evidence-dispatch.json");
2099
2557
  function _isObject6(v) {
2100
2558
  return typeof v === "object" && v !== null && !Array.isArray(v);
2101
2559
  }
@@ -2163,8 +2621,8 @@ function extractDispatch(envelope) {
2163
2621
  }
2164
2622
  function _ledgerStamp(consumer_root) {
2165
2623
  try {
2166
- const raw = fs7.readFileSync(
2167
- path7.join(consumer_root, "agents", "state", "git-authorization.json"),
2624
+ const raw = fs8.readFileSync(
2625
+ path8.join(consumer_root, "agents", "state", "git-authorization.json"),
2168
2626
  "utf8"
2169
2627
  );
2170
2628
  const d = JSON.parse(raw);
@@ -2175,7 +2633,7 @@ function _ledgerStamp(consumer_root) {
2175
2633
  }
2176
2634
  function _load(target) {
2177
2635
  try {
2178
- const decoded = JSON.parse(fs7.readFileSync(target, "utf8"));
2636
+ const decoded = JSON.parse(fs8.readFileSync(target, "utf8"));
2179
2637
  if (_isObject6(decoded) && Array.isArray(decoded["evaluations"])) {
2180
2638
  return decoded;
2181
2639
  }
@@ -2186,7 +2644,7 @@ function _load(target) {
2186
2644
  var WARN_TEXT = "First evaluation dispatch this turn. Two shapes fabricated a binding honest-null in the audited sessions \u2014 check your prompt for both before it goes out: (1) a verdict pre-loaded into the prompt, and (2) a scope narrowed to files you chose. A review you commissioned on your own work is admissible as gate evidence only when the prompt is recorded alongside the verdict.";
2187
2645
  function decide2(tool, prompt, priorEvaluations) {
2188
2646
  if (!isDispatchTool(tool) || !isEvaluationPrompt(prompt)) {
2189
- return { exit: EXIT_ALLOW5, stdout: "", stderr: "", evaluations: priorEvaluations };
2647
+ return { exit: EXIT_ALLOW6, stdout: "", stderr: "", evaluations: priorEvaluations };
2190
2648
  }
2191
2649
  const preloaded = preloadedVerdict(prompt);
2192
2650
  if (preloaded !== null) {
@@ -2199,11 +2657,11 @@ function decide2(tool, prompt, priorEvaluations) {
2199
2657
  };
2200
2658
  }
2201
2659
  if (!isSelfScoped(prompt)) {
2202
- return { exit: EXIT_ALLOW5, stdout: "", stderr: "", evaluations: priorEvaluations };
2660
+ return { exit: EXIT_ALLOW6, stdout: "", stderr: "", evaluations: priorEvaluations };
2203
2661
  }
2204
2662
  if (priorEvaluations >= 1) {
2205
2663
  return {
2206
- exit: EXIT_ALLOW5,
2664
+ exit: EXIT_ALLOW6,
2207
2665
  stdout: `${JSON.stringify({
2208
2666
  decision: "warn",
2209
2667
  reason: `Second evaluation dispatch of your own work in this turn. If both passes judge the SAME subject, that is verdict shopping \u2014 commissioning another with a different prompt or scope selects the answer instead of measuring it. Report what the first pass returned, then re-plan. If this is an implementation fan-out rather than a second review, carry on: this check reads prose and cannot tell the two apart with certainty.`
@@ -2214,7 +2672,7 @@ function decide2(tool, prompt, priorEvaluations) {
2214
2672
  };
2215
2673
  }
2216
2674
  return {
2217
- exit: EXIT_ALLOW5,
2675
+ exit: EXIT_ALLOW6,
2218
2676
  stdout: `${JSON.stringify({ decision: "warn", reason: WARN_TEXT })}
2219
2677
  `,
2220
2678
  stderr: "",
@@ -2230,10 +2688,10 @@ function run5(stdin_text, options) {
2230
2688
  envelope = decoded;
2231
2689
  }
2232
2690
  } catch {
2233
- return EXIT_ALLOW5;
2691
+ return EXIT_ALLOW6;
2234
2692
  }
2235
2693
  }
2236
- const target = path7.join(options.consumer_root, STATE_FILE4);
2694
+ const target = path8.join(options.consumer_root, STATE_FILE4);
2237
2695
  const state = _load(target);
2238
2696
  const session_id = typeof envelope["session_id"] === "string" ? envelope["session_id"] : "";
2239
2697
  const turnMarker = `${session_id}:${_ledgerStamp(options.consumer_root)}`;
@@ -2247,7 +2705,7 @@ function run5(stdin_text, options) {
2247
2705
  if (decision.evaluations > state.evaluations.length) {
2248
2706
  state.evaluations.push({
2249
2707
  at: (/* @__PURE__ */ new Date()).toISOString(),
2250
- digest: crypto3.createHash("sha256").update(prompt).digest("hex").slice(0, 16),
2708
+ digest: crypto4.createHash("sha256").update(prompt).digest("hex").slice(0, 16),
2251
2709
  prompt_chars: prompt.length
2252
2710
  });
2253
2711
  try {
@@ -2263,7 +2721,7 @@ function run5(stdin_text, options) {
2263
2721
  }
2264
2722
  return decision.exit;
2265
2723
  }
2266
- function main7(argv) {
2724
+ function main8(argv) {
2267
2725
  const args = argv ?? process.argv.slice(2);
2268
2726
  let consumer_root = process.cwd();
2269
2727
  for (let i = 0; i < args.length; i += 1) {
@@ -2277,33 +2735,33 @@ function main7(argv) {
2277
2735
  }
2278
2736
  return run5(readHookStdin(), { consumer_root });
2279
2737
  }
2280
- function _isCliEntry7() {
2738
+ function _isCliEntry8() {
2281
2739
  if (true) {
2282
2740
  return false;
2283
2741
  }
2284
2742
  if (process.argv[1] === void 0) {
2285
2743
  return false;
2286
2744
  }
2287
- const argvUrl = pathToFileURL7(path7.resolve(process.argv[1])).href;
2745
+ const argvUrl = pathToFileURL8(path8.resolve(process.argv[1])).href;
2288
2746
  if (import.meta.url === argvUrl) {
2289
2747
  return true;
2290
2748
  }
2291
2749
  try {
2292
- const here = fs7.realpathSync(fileURLToPath7(import.meta.url));
2293
- const argv = fs7.realpathSync(path7.resolve(process.argv[1]));
2750
+ const here = fs8.realpathSync(fileURLToPath8(import.meta.url));
2751
+ const argv = fs8.realpathSync(path8.resolve(process.argv[1]));
2294
2752
  return here === argv;
2295
2753
  } catch {
2296
2754
  return false;
2297
2755
  }
2298
2756
  }
2299
- if (_isCliEntry7()) {
2300
- process.exit(main7());
2757
+ if (_isCliEntry8()) {
2758
+ process.exit(main8());
2301
2759
  }
2302
2760
 
2303
2761
  // src/scripts/hooks/delegation_nudge_hook.ts
2304
- import fs8 from "node:fs";
2305
- import path8 from "node:path";
2306
- import { fileURLToPath as fileURLToPath8, pathToFileURL as pathToFileURL8 } from "node:url";
2762
+ import fs9 from "node:fs";
2763
+ import path9 from "node:path";
2764
+ import { fileURLToPath as fileURLToPath9, pathToFileURL as pathToFileURL9 } from "node:url";
2307
2765
 
2308
2766
  // src/scripts/_lib/host_capability.ts
2309
2767
  import process2 from "node:process";
@@ -2630,7 +3088,7 @@ function resolveSubagentRouting(inp) {
2630
3088
  }
2631
3089
 
2632
3090
  // src/scripts/hooks/delegation_nudge_hook.ts
2633
- var EXIT_ALLOW6 = 0;
3091
+ var EXIT_ALLOW7 = 0;
2634
3092
  var EXIT_WARN3 = 2;
2635
3093
  function _isObject7(v) {
2636
3094
  return typeof v === "object" && v !== null && !Array.isArray(v);
@@ -2791,34 +3249,34 @@ function _workspaceRoot(envelope) {
2791
3249
  }
2792
3250
  return process.cwd();
2793
3251
  }
2794
- function main8() {
3252
+ function main9() {
2795
3253
  let envelope = {};
2796
3254
  try {
2797
3255
  const raw = readHookStdin();
2798
3256
  envelope = raw.trim() ? JSON.parse(raw) : {};
2799
3257
  } catch {
2800
- return EXIT_ALLOW6;
3258
+ return EXIT_ALLOW7;
2801
3259
  }
2802
3260
  const env = _isObject7(envelope) ? envelope : {};
2803
3261
  const event = env["event"];
2804
3262
  const slot = typeof event === "string" && event !== "" ? event : "user_prompt_submit";
2805
3263
  if (slot !== "user_prompt_submit") {
2806
- return EXIT_ALLOW6;
3264
+ return EXIT_ALLOW7;
2807
3265
  }
2808
3266
  const payload = _isObject7(env["payload"]) ? env["payload"] : env;
2809
3267
  const prompt = _extractPrompt2(payload);
2810
3268
  if (!prompt) {
2811
- return EXIT_ALLOW6;
3269
+ return EXIT_ALLOW7;
2812
3270
  }
2813
3271
  if (isSyntheticPrompt(prompt)) {
2814
- return EXIT_ALLOW6;
3272
+ return EXIT_ALLOW7;
2815
3273
  }
2816
3274
  const root = _workspaceRoot(env);
2817
3275
  const platform = env["platform"];
2818
3276
  const hostId = typeof platform === "string" && platform ? platform : null;
2819
3277
  const result = classifyPrompt(prompt, root, hostId);
2820
3278
  if (!result) {
2821
- return EXIT_ALLOW6;
3279
+ return EXIT_ALLOW7;
2822
3280
  }
2823
3281
  process.stdout.write(
2824
3282
  `${JSON.stringify({
@@ -2830,31 +3288,31 @@ function main8() {
2830
3288
  );
2831
3289
  return EXIT_WARN3;
2832
3290
  }
2833
- function _isCliEntry8() {
3291
+ function _isCliEntry9() {
2834
3292
  if (true) {
2835
3293
  return false;
2836
3294
  }
2837
3295
  if (process.argv[1] === void 0) {
2838
3296
  return false;
2839
3297
  }
2840
- const argvUrl = pathToFileURL8(path8.resolve(process.argv[1])).href;
3298
+ const argvUrl = pathToFileURL9(path9.resolve(process.argv[1])).href;
2841
3299
  if (import.meta.url === argvUrl) {
2842
3300
  return true;
2843
3301
  }
2844
3302
  try {
2845
- const here = fs8.realpathSync(fileURLToPath8(import.meta.url));
2846
- const argv = fs8.realpathSync(path8.resolve(process.argv[1]));
3303
+ const here = fs9.realpathSync(fileURLToPath9(import.meta.url));
3304
+ const argv = fs9.realpathSync(path9.resolve(process.argv[1]));
2847
3305
  return here === argv;
2848
3306
  } catch {
2849
3307
  return false;
2850
3308
  }
2851
3309
  }
2852
- if (_isCliEntry8()) {
2853
- process.exit(main8());
3310
+ if (_isCliEntry9()) {
3311
+ process.exit(main9());
2854
3312
  }
2855
3313
 
2856
3314
  // src/scripts/conformance_scan.ts
2857
- var REPO_ROOT = path9.resolve(path9.dirname(fileURLToPath9(import.meta.url)), "..", "..");
3315
+ var REPO_ROOT = path10.resolve(path10.dirname(fileURLToPath10(import.meta.url)), "..", "..");
2858
3316
  var OBSERVED_BAND = { low: 9.1, high: 39.2 };
2859
3317
  var BAND_MIN_TURNS = 1978;
2860
3318
  var CARRIER_CHANGES = [
@@ -3204,7 +3662,7 @@ function scanSession(sessionId, lines) {
3204
3662
  closeWindow();
3205
3663
  return report;
3206
3664
  }
3207
- var DEFAULT_RATE_SERIES = path9.join(
3665
+ var DEFAULT_RATE_SERIES = path10.join(
3208
3666
  REPO_ROOT,
3209
3667
  "agents",
3210
3668
  "runtime",
@@ -3213,7 +3671,7 @@ var DEFAULT_RATE_SERIES = path9.join(
3213
3671
  );
3214
3672
  function defaultStore(projectDir) {
3215
3673
  const slug = projectStoreSlug(projectDir);
3216
- return path9.join(process.env["HOME"] ?? "", ".claude", "projects", slug);
3674
+ return path10.join(process.env["HOME"] ?? "", ".claude", "projects", slug);
3217
3675
  }
3218
3676
  function _tokens(chars) {
3219
3677
  return Math.round(chars / 4);
@@ -3224,13 +3682,13 @@ function measureDelivered(projectRulesDir, globalRulesDir) {
3224
3682
  return {
3225
3683
  project: {
3226
3684
  dir: projectRulesDir,
3227
- present: fs9.existsSync(projectRulesDir),
3685
+ present: fs10.existsSync(projectRulesDir),
3228
3686
  files: p.files,
3229
3687
  tokens: _tokens(p.chars)
3230
3688
  },
3231
3689
  global: {
3232
3690
  dir: globalRulesDir,
3233
- present: fs9.existsSync(globalRulesDir),
3691
+ present: fs10.existsSync(globalRulesDir),
3234
3692
  files: g.files,
3235
3693
  tokens: _tokens(g.chars)
3236
3694
  },
@@ -3238,13 +3696,13 @@ function measureDelivered(projectRulesDir, globalRulesDir) {
3238
3696
  };
3239
3697
  }
3240
3698
  function storeKey(store) {
3241
- return createHash3("sha256").update(path9.resolve(store)).digest("hex").slice(0, 12);
3699
+ return createHash4("sha256").update(path10.resolve(store)).digest("hex").slice(0, 12);
3242
3700
  }
3243
3701
  function scanStore(store, limit) {
3244
- const files = fs9.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ f, m: fs9.statSync(path9.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.f);
3702
+ const files = fs10.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ f, m: fs10.statSync(path10.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.f);
3245
3703
  const per_session = [];
3246
3704
  for (const f of files) {
3247
- const lines = fs9.readFileSync(path9.join(store, f), "utf8").split("\n");
3705
+ const lines = fs10.readFileSync(path10.join(store, f), "utf8").split("\n");
3248
3706
  const r = scanSession(f.replace(/\.jsonl$/, "").slice(0, 8), lines);
3249
3707
  if (r.assistant_turns > 0) {
3250
3708
  per_session.push(r);
@@ -3272,10 +3730,10 @@ function scanStore(store, limit) {
3272
3730
  const task_completeness_rate_pct = completeness_windows === 0 ? 0 : Number((100 * task_completeness / completeness_windows).toFixed(1));
3273
3731
  const era = spansCarrierChange(per_session.map((s) => s.first_at));
3274
3732
  const delivered = measureDelivered(
3275
- path9.join(REPO_ROOT, ".claude", "rules"),
3276
- path9.join(process.env["HOME"] ?? os2.homedir(), ".claude", "rules")
3733
+ path10.join(REPO_ROOT, ".claude", "rules"),
3734
+ path10.join(process.env["HOME"] ?? os2.homedir(), ".claude", "rules")
3277
3735
  );
3278
- const ownStore = path9.resolve(store) === path9.resolve(defaultStore(REPO_ROOT));
3736
+ const ownStore = path10.resolve(store) === path10.resolve(defaultStore(REPO_ROOT));
3279
3737
  return {
3280
3738
  scanned_at: (/* @__PURE__ */ new Date()).toISOString(),
3281
3739
  store,
@@ -3305,8 +3763,8 @@ function scanStore(store, limit) {
3305
3763
  };
3306
3764
  }
3307
3765
  function recordRate(file, scanned_at, rate) {
3308
- fs9.mkdirSync(path9.dirname(file), { recursive: true });
3309
- fs9.appendFileSync(file, `${JSON.stringify({ measured_at: scanned_at, ...rate })}
3766
+ fs10.mkdirSync(path10.dirname(file), { recursive: true });
3767
+ fs10.appendFileSync(file, `${JSON.stringify({ measured_at: scanned_at, ...rate })}
3310
3768
  `, "utf8");
3311
3769
  }
3312
3770
  function render(report) {
@@ -3405,7 +3863,7 @@ function render(report) {
3405
3863
  lines.push(" checkbox batching \u2014 measured NOWHERE. ~5 low-severity findings.");
3406
3864
  return lines.join("\n");
3407
3865
  }
3408
- function main9(argv) {
3866
+ function main10(argv) {
3409
3867
  const args = argv ?? process.argv.slice(2);
3410
3868
  let store = null;
3411
3869
  let limit = 30;
@@ -3437,14 +3895,14 @@ function main9(argv) {
3437
3895
  return 2;
3438
3896
  }
3439
3897
  const resolved = store ?? defaultStore(process.cwd());
3440
- if (!fs9.existsSync(resolved)) {
3898
+ if (!fs10.existsSync(resolved)) {
3441
3899
  process.stderr.write(`conformance:behavior: no transcript store at ${resolved}
3442
3900
  `);
3443
3901
  return 1;
3444
3902
  }
3445
3903
  const report = scanStore(resolved, Number.isFinite(limit) && limit > 0 ? limit : 30);
3446
3904
  if (out) {
3447
- fs9.writeFileSync(out, `${JSON.stringify(report, null, 2)}
3905
+ fs10.writeFileSync(out, `${JSON.stringify(report, null, 2)}
3448
3906
  `, "utf8");
3449
3907
  }
3450
3908
  if (record) {
@@ -3452,7 +3910,7 @@ function main9(argv) {
3452
3910
  }
3453
3911
  if (why !== null) {
3454
3912
  const id = why;
3455
- fs9.writeSync(
3913
+ fs10.writeSync(
3456
3914
  1,
3457
3915
  json ? `${JSON.stringify(
3458
3916
  {
@@ -3472,48 +3930,48 @@ function main9(argv) {
3472
3930
  );
3473
3931
  return 0;
3474
3932
  }
3475
- fs9.writeSync(1, json ? `${JSON.stringify(report, null, 2)}
3933
+ fs10.writeSync(1, json ? `${JSON.stringify(report, null, 2)}
3476
3934
  ` : `${render(report)}
3477
3935
  `);
3478
3936
  return 0;
3479
3937
  }
3480
- function _isCliEntry9() {
3938
+ function _isCliEntry10() {
3481
3939
  if (true) {
3482
3940
  return false;
3483
3941
  }
3484
3942
  if (process.argv[1] === void 0) {
3485
3943
  return false;
3486
3944
  }
3487
- const argvUrl = pathToFileURL9(path9.resolve(process.argv[1])).href;
3945
+ const argvUrl = pathToFileURL10(path10.resolve(process.argv[1])).href;
3488
3946
  if (import.meta.url === argvUrl) {
3489
3947
  return true;
3490
3948
  }
3491
3949
  try {
3492
- const here = fs9.realpathSync(fileURLToPath9(import.meta.url));
3493
- const argv = fs9.realpathSync(path9.resolve(process.argv[1]));
3950
+ const here = fs10.realpathSync(fileURLToPath10(import.meta.url));
3951
+ const argv = fs10.realpathSync(path10.resolve(process.argv[1]));
3494
3952
  return here === argv;
3495
3953
  } catch {
3496
3954
  return false;
3497
3955
  }
3498
3956
  }
3499
- if (_isCliEntry9()) {
3500
- process.exit(main9());
3957
+ if (_isCliEntry10()) {
3958
+ process.exit(main10());
3501
3959
  }
3502
3960
 
3503
3961
  // src/scripts/report_carrier_divergence.ts
3504
- import * as fs10 from "node:fs";
3962
+ import * as fs11 from "node:fs";
3505
3963
  import * as os3 from "node:os";
3506
- import * as path10 from "node:path";
3964
+ import * as path11 from "node:path";
3507
3965
  import process3 from "node:process";
3508
- import { fileURLToPath as fileURLToPath10, pathToFileURL as pathToFileURL10 } from "node:url";
3509
- var _HERE = fileURLToPath10(import.meta.url);
3510
- var REPO_ROOT2 = path10.resolve(path10.dirname(_HERE), "..", "..");
3511
- var PROJECT_RULES = path10.join(".claude", "rules");
3512
- var PROJECTION_SOURCE = path10.join("dist", "agent-src", "rules");
3513
- var GLOBAL_RULES = path10.join(".claude", "rules");
3966
+ import { fileURLToPath as fileURLToPath11, pathToFileURL as pathToFileURL11 } from "node:url";
3967
+ var _HERE = fileURLToPath11(import.meta.url);
3968
+ var REPO_ROOT2 = path11.resolve(path11.dirname(_HERE), "..", "..");
3969
+ var PROJECT_RULES = path11.join(".claude", "rules");
3970
+ var PROJECTION_SOURCE = path11.join("dist", "agent-src", "rules");
3971
+ var GLOBAL_RULES = path11.join(".claude", "rules");
3514
3972
  function _listRules(dir) {
3515
3973
  try {
3516
- return fs10.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
3974
+ return fs11.readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
3517
3975
  } catch {
3518
3976
  return [];
3519
3977
  }
@@ -3521,7 +3979,7 @@ function _listRules(dir) {
3521
3979
  function _ruleType(file) {
3522
3980
  let text;
3523
3981
  try {
3524
- text = fs10.readFileSync(file, "utf-8");
3982
+ text = fs11.readFileSync(file, "utf-8");
3525
3983
  } catch {
3526
3984
  return "";
3527
3985
  }
@@ -3532,8 +3990,8 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
3532
3990
  const out = {
3533
3991
  projectDir,
3534
3992
  globalDir,
3535
- globalPresent: fs10.existsSync(globalDir),
3536
- projectPresent: fs10.existsSync(projectDir),
3993
+ globalPresent: fs11.existsSync(globalDir),
3994
+ projectPresent: fs11.existsSync(projectDir),
3537
3995
  shared: 0,
3538
3996
  identical: [],
3539
3997
  provenanceOnly: [],
@@ -3556,7 +4014,7 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
3556
4014
  }
3557
4015
  if (!inP && inG) {
3558
4016
  out.globalOnly.push(rule);
3559
- if (sourceDir !== void 0 && _ruleType(path10.join(sourceDir, rule)) === "manual") {
4017
+ if (sourceDir !== void 0 && _ruleType(path11.join(sourceDir, rule)) === "manual") {
3560
4018
  out.manualOnlyGlobal.push(rule);
3561
4019
  }
3562
4020
  continue;
@@ -3566,8 +4024,8 @@ function compareCarriers(projectDir, globalDir, sourceDir) {
3566
4024
  let projectCopy;
3567
4025
  let globalCopy;
3568
4026
  try {
3569
- projectCopy = fs10.readFileSync(path10.join(projectDir, rule));
3570
- globalCopy = fs10.readFileSync(path10.join(globalDir, rule));
4027
+ projectCopy = fs11.readFileSync(path11.join(projectDir, rule));
4028
+ globalCopy = fs11.readFileSync(path11.join(globalDir, rule));
3571
4029
  verdict = comparePair(projectCopy, globalCopy);
3572
4030
  } catch {
3573
4031
  out.shared -= 1;
@@ -3712,11 +4170,11 @@ function render2(d) {
3712
4170
  }
3713
4171
  return lines.join("\n");
3714
4172
  }
3715
- function main10(argv) {
4173
+ function main11(argv) {
3716
4174
  const args = argv ?? process3.argv.slice(2);
3717
- let projectDir = path10.join(REPO_ROOT2, PROJECT_RULES);
3718
- let globalDir = path10.join(os3.homedir(), GLOBAL_RULES);
3719
- let sourceDir = path10.join(REPO_ROOT2, PROJECTION_SOURCE);
4175
+ let projectDir = path11.join(REPO_ROOT2, PROJECT_RULES);
4176
+ let globalDir = path11.join(os3.homedir(), GLOBAL_RULES);
4177
+ let sourceDir = path11.join(REPO_ROOT2, PROJECTION_SOURCE);
3720
4178
  const value = (i) => {
3721
4179
  const v = args[i + 1];
3722
4180
  return v === void 0 || v.startsWith("-") ? null : v;
@@ -3730,7 +4188,7 @@ function main10(argv) {
3730
4188
  `);
3731
4189
  return 1;
3732
4190
  }
3733
- const resolved = path10.resolve(v);
4191
+ const resolved = path11.resolve(v);
3734
4192
  if (a === "--project") projectDir = resolved;
3735
4193
  else if (a === "--global") globalDir = resolved;
3736
4194
  else sourceDir = resolved;
@@ -3750,44 +4208,44 @@ function main10(argv) {
3750
4208
  `);
3751
4209
  return 0;
3752
4210
  }
3753
- function _isCliEntry10() {
4211
+ function _isCliEntry11() {
3754
4212
  if (process3.argv[1] === void 0) return false;
3755
- if (import.meta.url === pathToFileURL10(path10.resolve(process3.argv[1])).href) return true;
4213
+ if (import.meta.url === pathToFileURL11(path11.resolve(process3.argv[1])).href) return true;
3756
4214
  try {
3757
- return fs10.realpathSync(_HERE) === fs10.realpathSync(path10.resolve(process3.argv[1]));
4215
+ return fs11.realpathSync(_HERE) === fs11.realpathSync(path11.resolve(process3.argv[1]));
3758
4216
  } catch {
3759
4217
  return false;
3760
4218
  }
3761
4219
  }
3762
- if (_isCliEntry10()) {
3763
- process3.exit(main10());
4220
+ if (_isCliEntry11()) {
4221
+ process3.exit(main11());
3764
4222
  }
3765
4223
 
3766
4224
  // src/scripts/report_skill_activation.ts
3767
- import * as fs11 from "node:fs";
4225
+ import * as fs12 from "node:fs";
3768
4226
  import * as os4 from "node:os";
3769
- import * as path11 from "node:path";
3770
- import { fileURLToPath as fileURLToPath11, pathToFileURL as pathToFileURL11 } from "node:url";
3771
- var _HERE2 = fileURLToPath11(import.meta.url);
3772
- var REPO_ROOT3 = path11.resolve(path11.dirname(_HERE2), "..", "..");
4227
+ import * as path12 from "node:path";
4228
+ import { fileURLToPath as fileURLToPath12, pathToFileURL as pathToFileURL12 } from "node:url";
4229
+ var _HERE2 = fileURLToPath12(import.meta.url);
4230
+ var REPO_ROOT3 = path12.resolve(path12.dirname(_HERE2), "..", "..");
3773
4231
  var SKILLS_ROOT = "src/skills";
3774
4232
  var TRIGGER_KEYS = ["triggers:", "trigger_description:", "file_pattern:", "path_prefix:"];
3775
4233
  var DETERMINISTIC_RE = /^\s*(?:[-*]\s*)?(?:\*\*)?(MUST|NEVER|ALWAYS)\b/m;
3776
4234
  function censusSkills(root) {
3777
4235
  const out = { total: 0, withTriggerKey: [], withDeterministicObligation: [] };
3778
- if (!fs11.existsSync(root)) {
4236
+ if (!fs12.existsSync(root)) {
3779
4237
  return out;
3780
4238
  }
3781
- for (const entry of fs11.readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
4239
+ for (const entry of fs12.readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
3782
4240
  if (!entry.isDirectory()) {
3783
4241
  continue;
3784
4242
  }
3785
- const file = path11.join(root, entry.name, "SKILL.md");
3786
- if (!fs11.existsSync(file)) {
4243
+ const file = path12.join(root, entry.name, "SKILL.md");
4244
+ if (!fs12.existsSync(file)) {
3787
4245
  continue;
3788
4246
  }
3789
4247
  out.total += 1;
3790
- const text = fs11.readFileSync(file, "utf8");
4248
+ const text = fs12.readFileSync(file, "utf8");
3791
4249
  const fmEnd = text.startsWith("---") ? text.indexOf("\n---", 3) : -1;
3792
4250
  const fm = fmEnd === -1 ? "" : text.slice(0, fmEnd);
3793
4251
  if (TRIGGER_KEYS.some((k) => new RegExp(`^${k}`, "m").test(fm))) {
@@ -3801,17 +4259,17 @@ function censusSkills(root) {
3801
4259
  return out;
3802
4260
  }
3803
4261
  function defaultStore2(cwd) {
3804
- return path11.join(os4.homedir(), ".claude", "projects", projectStoreSlug(cwd));
4262
+ return path12.join(os4.homedir(), ".claude", "projects", projectStoreSlug(cwd));
3805
4263
  }
3806
4264
  function measureUsage(store, limit) {
3807
4265
  const rep = { store, sessions: 0, assistantTurns: 0, invocations: 0, bySkill: {} };
3808
- if (!fs11.existsSync(store)) {
4266
+ if (!fs12.existsSync(store)) {
3809
4267
  return rep;
3810
4268
  }
3811
- const files = fs11.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => path11.join(store, f)).sort((a, b) => fs11.statSync(b).mtimeMs - fs11.statSync(a).mtimeMs).slice(0, limit);
4269
+ const files = fs12.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => path12.join(store, f)).sort((a, b) => fs12.statSync(b).mtimeMs - fs12.statSync(a).mtimeMs).slice(0, limit);
3812
4270
  rep.sessions = files.length;
3813
4271
  for (const file of files) {
3814
- for (const line of fs11.readFileSync(file, "utf8").split("\n")) {
4272
+ for (const line of fs12.readFileSync(file, "utf8").split("\n")) {
3815
4273
  if (!line.trim()) {
3816
4274
  continue;
3817
4275
  }
@@ -3874,7 +4332,7 @@ function render3(census, usage) {
3874
4332
  }
3875
4333
  totalInv += u.invocations;
3876
4334
  lines.push(
3877
- ` ${path11.basename(u.store).slice(-38).padEnd(38)} sessions=${String(u.sessions).padStart(3)} asst=${String(u.assistantTurns).padStart(6)} Skill calls=${String(u.invocations).padStart(3)}`
4335
+ ` ${path12.basename(u.store).slice(-38).padEnd(38)} sessions=${String(u.sessions).padStart(3)} asst=${String(u.assistantTurns).padStart(6)} Skill calls=${String(u.invocations).padStart(3)}`
3878
4336
  );
3879
4337
  }
3880
4338
  lines.push("");
@@ -3899,7 +4357,7 @@ function render3(census, usage) {
3899
4357
  lines.push(" catalogue once per session, then count descriptions against bare names.");
3900
4358
  return lines.join("\n");
3901
4359
  }
3902
- function main11(argv) {
4360
+ function main12(argv) {
3903
4361
  let limit = 30;
3904
4362
  const stores = [];
3905
4363
  for (let i = 0; i < argv.length; i += 1) {
@@ -3922,24 +4380,24 @@ function main11(argv) {
3922
4380
  if (stores.length === 0) {
3923
4381
  stores.push(defaultStore2(REPO_ROOT3));
3924
4382
  }
3925
- const census = censusSkills(path11.join(REPO_ROOT3, SKILLS_ROOT));
4383
+ const census = censusSkills(path12.join(REPO_ROOT3, SKILLS_ROOT));
3926
4384
  const usage = stores.map((s) => measureUsage(s, limit));
3927
4385
  process.stdout.write(`${render3(census, usage)}
3928
4386
  `);
3929
4387
  return 0;
3930
4388
  }
3931
- if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL11(path11.resolve(process.argv[1])).href) {
3932
- process.exit(main11(process.argv.slice(2)));
4389
+ if (process.argv[1] !== void 0 && import.meta.url === pathToFileURL12(path12.resolve(process.argv[1])).href) {
4390
+ process.exit(main12(process.argv.slice(2)));
3933
4391
  }
3934
4392
 
3935
4393
  // src/scripts/report_skill_obligation_violations.ts
3936
- import * as fs12 from "node:fs";
4394
+ import * as fs13 from "node:fs";
3937
4395
  import * as os5 from "node:os";
3938
- import * as path12 from "node:path";
4396
+ import * as path13 from "node:path";
3939
4397
  import process4 from "node:process";
3940
- import { fileURLToPath as fileURLToPath12, pathToFileURL as pathToFileURL12 } from "node:url";
3941
- var _HERE3 = fileURLToPath12(import.meta.url);
3942
- var REPO_ROOT4 = path12.resolve(path12.dirname(_HERE3), "..", "..");
4398
+ import { fileURLToPath as fileURLToPath13, pathToFileURL as pathToFileURL13 } from "node:url";
4399
+ var _HERE3 = fileURLToPath13(import.meta.url);
4400
+ var REPO_ROOT4 = path13.resolve(path13.dirname(_HERE3), "..", "..");
3943
4401
  var OBLIGATION_LINE_RE = new RegExp(`${DETERMINISTIC_RE.source}.*`, "gm");
3944
4402
  var PATH_RE = /`([A-Za-z0-9_./-]*\/[A-Za-z0-9_.-]+\.[a-z]{2,6})`/g;
3945
4403
  var CMD_RE = /`([a-z][a-z0-9-]*(?: [a-z][a-z0-9:._-]*){1,3})`/g;
@@ -3977,7 +4435,7 @@ function _artefacts(line) {
3977
4435
  return out;
3978
4436
  }
3979
4437
  function extractObligations(repoRoot) {
3980
- const skillsRoot = path12.join(repoRoot, SKILLS_ROOT);
4438
+ const skillsRoot = path13.join(repoRoot, SKILLS_ROOT);
3981
4439
  const census = censusSkills(skillsRoot);
3982
4440
  const out = {
3983
4441
  skills: census.withDeterministicObligation,
@@ -3991,7 +4449,7 @@ function extractObligations(repoRoot) {
3991
4449
  for (const skill of census.withDeterministicObligation) {
3992
4450
  let text;
3993
4451
  try {
3994
- text = fs12.readFileSync(path12.join(skillsRoot, skill, "SKILL.md"), "utf-8");
4452
+ text = fs13.readFileSync(path13.join(skillsRoot, skill, "SKILL.md"), "utf-8");
3995
4453
  } catch {
3996
4454
  continue;
3997
4455
  }
@@ -4107,7 +4565,7 @@ function scanSessionForViolations(session, lines, forbidden, parsed) {
4107
4565
  return flags;
4108
4566
  }
4109
4567
  function defaultStore3(cwd) {
4110
- return path12.join(os5.homedir(), ".claude", "projects", projectStoreSlug(cwd));
4568
+ return path13.join(os5.homedir(), ".claude", "projects", projectStoreSlug(cwd));
4111
4569
  }
4112
4570
  function scanStore2(repoRoot, store, limit) {
4113
4571
  const census = extractObligations(repoRoot);
@@ -4120,14 +4578,14 @@ function scanStore2(repoRoot, store, limit) {
4120
4578
  };
4121
4579
  let files;
4122
4580
  try {
4123
- files = fs12.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ p: path12.join(store, f), m: fs12.statSync(path12.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.p);
4581
+ files = fs13.readdirSync(store).filter((f) => f.endsWith(".jsonl")).map((f) => ({ p: path13.join(store, f), m: fs13.statSync(path13.join(store, f)).mtimeMs })).sort((a, b) => b.m - a.m).slice(0, limit).map((x) => x.p);
4124
4582
  } catch {
4125
4583
  return report;
4126
4584
  }
4127
4585
  report.sessions = files.length;
4128
4586
  for (const file of files) {
4129
- const lines = fs12.readFileSync(file, "utf-8").split("\n");
4130
- const id = path12.basename(file).replace(/\.jsonl$/, "").slice(0, 8);
4587
+ const lines = fs13.readFileSync(file, "utf-8").split("\n");
4588
+ const id = path13.basename(file).replace(/\.jsonl$/, "").slice(0, 8);
4131
4589
  const entries = _parseSession(lines);
4132
4590
  if (loadedSkillsFrom(entries).size > 0) report.sessionsWithASkill += 1;
4133
4591
  report.flags.push(...scanSessionForViolations(id, lines, census.forbidden, entries));
@@ -4197,7 +4655,7 @@ function render4(r) {
4197
4655
  lines.push(" ships as detection-only, and this one says so.");
4198
4656
  return lines.join("\n");
4199
4657
  }
4200
- function main12(argv) {
4658
+ function main13(argv) {
4201
4659
  const args = argv ?? process4.argv.slice(2);
4202
4660
  let limit = 30;
4203
4661
  let json = false;
@@ -4250,35 +4708,35 @@ function main12(argv) {
4250
4708
  }
4251
4709
  return 0;
4252
4710
  }
4253
- function _isCliEntry11() {
4711
+ function _isCliEntry12() {
4254
4712
  if (process4.argv[1] === void 0) return false;
4255
- if (import.meta.url === pathToFileURL12(path12.resolve(process4.argv[1])).href) return true;
4713
+ if (import.meta.url === pathToFileURL13(path13.resolve(process4.argv[1])).href) return true;
4256
4714
  try {
4257
- return fs12.realpathSync(_HERE3) === fs12.realpathSync(path12.resolve(process4.argv[1]));
4715
+ return fs13.realpathSync(_HERE3) === fs13.realpathSync(path13.resolve(process4.argv[1]));
4258
4716
  } catch {
4259
4717
  return false;
4260
4718
  }
4261
4719
  }
4262
- if (_isCliEntry11()) {
4263
- process4.exit(main12());
4720
+ if (_isCliEntry12()) {
4721
+ process4.exit(main13());
4264
4722
  }
4265
4723
 
4266
4724
  // src/scripts/report_conformance_funnel.ts
4267
- var _HERE4 = fileURLToPath13(import.meta.url);
4268
- var REPO_ROOT5 = path13.resolve(path13.dirname(_HERE4), "..", "..");
4725
+ var _HERE4 = fileURLToPath14(import.meta.url);
4726
+ var REPO_ROOT5 = path14.resolve(path14.dirname(_HERE4), "..", "..");
4269
4727
  function buildFunnel(opts = {}) {
4270
4728
  const repoRoot = opts.repoRoot ?? REPO_ROOT5;
4271
- const projectRulesDir = opts.projectRulesDir ?? path13.join(repoRoot, PROJECT_RULES);
4272
- const globalRulesDir = opts.globalRulesDir ?? path13.join(os6.homedir(), GLOBAL_RULES);
4273
- const sourceDir = opts.sourceDir ?? path13.join(repoRoot, PROJECTION_SOURCE);
4729
+ const projectRulesDir = opts.projectRulesDir ?? path14.join(repoRoot, PROJECT_RULES);
4730
+ const globalRulesDir = opts.globalRulesDir ?? path14.join(os6.homedir(), GLOBAL_RULES);
4731
+ const sourceDir = opts.sourceDir ?? path14.join(repoRoot, PROJECTION_SOURCE);
4274
4732
  const store = opts.store ?? defaultStore(repoRoot);
4275
4733
  const limit = opts.limit ?? 30;
4276
4734
  return {
4277
4735
  delivered: measureDelivered(projectRulesDir, globalRulesDir),
4278
4736
  divergence: compareCarriers(projectRulesDir, globalRulesDir, sourceDir),
4279
- skills: censusSkills(path13.join(repoRoot, SKILLS_ROOT)),
4737
+ skills: censusSkills(path14.join(repoRoot, SKILLS_ROOT)),
4280
4738
  usage: measureUsage(store, limit),
4281
- storePresent: fs13.existsSync(store),
4739
+ storePresent: fs14.existsSync(store),
4282
4740
  sk2: scanStore2(repoRoot, store, limit)
4283
4741
  };
4284
4742
  }
@@ -4403,7 +4861,7 @@ function render5(r) {
4403
4861
  lines.push("workflow without a measured false-positive rate first (locked policy).");
4404
4862
  return lines.join("\n");
4405
4863
  }
4406
- function main13(argv) {
4864
+ function main14(argv) {
4407
4865
  const args = argv ?? process5.argv.slice(2);
4408
4866
  const opts = {};
4409
4867
  const value = (i) => {
@@ -4419,7 +4877,7 @@ function main13(argv) {
4419
4877
  `);
4420
4878
  return 1;
4421
4879
  }
4422
- const resolved = path13.resolve(v);
4880
+ const resolved = path14.resolve(v);
4423
4881
  if (a === "--store") opts.store = resolved;
4424
4882
  else if (a === "--project") opts.projectRulesDir = resolved;
4425
4883
  else if (a === "--global") opts.globalRulesDir = resolved;
@@ -4449,21 +4907,21 @@ function main13(argv) {
4449
4907
  `);
4450
4908
  return 0;
4451
4909
  }
4452
- function _isCliEntry12() {
4910
+ function _isCliEntry13() {
4453
4911
  if (process5.argv[1] === void 0) return false;
4454
- if (import.meta.url === pathToFileURL13(path13.resolve(process5.argv[1])).href) return true;
4912
+ if (import.meta.url === pathToFileURL14(path14.resolve(process5.argv[1])).href) return true;
4455
4913
  try {
4456
- return fs13.realpathSync(_HERE4) === fs13.realpathSync(path13.resolve(process5.argv[1]));
4914
+ return fs14.realpathSync(_HERE4) === fs14.realpathSync(path14.resolve(process5.argv[1]));
4457
4915
  } catch {
4458
4916
  return false;
4459
4917
  }
4460
4918
  }
4461
- if (_isCliEntry12()) {
4462
- process5.exit(main13());
4919
+ if (_isCliEntry13()) {
4920
+ process5.exit(main14());
4463
4921
  }
4464
4922
 
4465
4923
  // src/scripts/_cli/cmd_conformance.ts
4466
- var _HERE5 = fileURLToPath14(import.meta.url);
4924
+ var _HERE5 = fileURLToPath15(import.meta.url);
4467
4925
  var PACKAGE_ROOT = resolvePackageRoot(import.meta.url);
4468
4926
  var CONFORMANCE_CHECK_IDS = [
4469
4927
  "txlog-clean",
@@ -4486,17 +4944,17 @@ function conformanceLogPath() {
4486
4944
  if (override && override.trim().length > 0) {
4487
4945
  return override;
4488
4946
  }
4489
- return path14.join(os7.homedir(), ".event4u", "agent-config", "conformance-log.jsonl");
4947
+ return path15.join(os7.homedir(), ".event4u", "agent-config", "conformance-log.jsonl");
4490
4948
  }
4491
4949
  function installLogPath() {
4492
4950
  const override = process6.env["AGENT_CONFIG_INSTALL_LOG"];
4493
4951
  if (override && override.trim().length > 0) {
4494
4952
  return override;
4495
4953
  }
4496
- return path14.join(os7.homedir(), ".event4u", "agent-config", "install-log.jsonl");
4954
+ return path15.join(os7.homedir(), ".event4u", "agent-config", "install-log.jsonl");
4497
4955
  }
4498
4956
  function _check_txlog_clean(logPath = installLogPath()) {
4499
- if (!fs14.existsSync(logPath)) {
4957
+ if (!fs15.existsSync(logPath)) {
4500
4958
  return {
4501
4959
  id: "txlog-clean",
4502
4960
  status: "ok",
@@ -4530,11 +4988,11 @@ function _check_txlog_clean(logPath = installLogPath()) {
4530
4988
  };
4531
4989
  }
4532
4990
  function routeTargetPaths(target) {
4533
- return routeTargetPathsPosix(target).map((rel) => path14.join(...rel.split("/")));
4991
+ return routeTargetPathsPosix(target).map((rel) => path15.join(...rel.split("/")));
4534
4992
  }
4535
4993
  function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
4536
- const routerPath = path14.join(packageRoot, "dist", "router.json");
4537
- if (!fs14.existsSync(routerPath)) {
4994
+ const routerPath = path15.join(packageRoot, "dist", "router.json");
4995
+ if (!fs15.existsSync(routerPath)) {
4538
4996
  return {
4539
4997
  id: "router-pointers",
4540
4998
  status: "fail",
@@ -4544,7 +5002,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
4544
5002
  }
4545
5003
  let router;
4546
5004
  try {
4547
- router = JSON.parse(fs14.readFileSync(routerPath, "utf8"));
5005
+ router = JSON.parse(fs15.readFileSync(routerPath, "utf8"));
4548
5006
  } catch (exc) {
4549
5007
  return {
4550
5008
  id: "router-pointers",
@@ -4553,13 +5011,13 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
4553
5011
  remedy: "reinstall the package \u2014 dist/router.json is corrupt"
4554
5012
  };
4555
5013
  }
4556
- const rulesDir = path14.join(packageRoot, "dist", "agent-src", "rules");
5014
+ const rulesDir = path15.join(packageRoot, "dist", "agent-src", "rules");
4557
5015
  const broken = [];
4558
5016
  let ids = 0;
4559
5017
  let targets = 0;
4560
5018
  for (const kernelId of router["kernel"] ?? []) {
4561
5019
  ids += 1;
4562
- if (!fs14.existsSync(path14.join(rulesDir, `${kernelId}.md`))) {
5020
+ if (!fs15.existsSync(path15.join(rulesDir, `${kernelId}.md`))) {
4563
5021
  broken.push(`kernel:${kernelId} \u2192 rules/${kernelId}.md missing`);
4564
5022
  }
4565
5023
  }
@@ -4567,7 +5025,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
4567
5025
  for (const entry of router[tier] ?? []) {
4568
5026
  const ruleId = String(entry["id"] ?? "");
4569
5027
  ids += 1;
4570
- if (!fs14.existsSync(path14.join(rulesDir, `${ruleId}.md`))) {
5028
+ if (!fs15.existsSync(path15.join(rulesDir, `${ruleId}.md`))) {
4571
5029
  broken.push(`${tier}:${ruleId} \u2192 rules/${ruleId}.md missing`);
4572
5030
  }
4573
5031
  for (const target of entry["routes_to"] ?? []) {
@@ -4577,7 +5035,7 @@ function _check_router_pointers(packageRoot = PACKAGE_ROOT) {
4577
5035
  broken.push(`${ruleId} \u2192 unparseable routes_to ${JSON.stringify(target)}`);
4578
5036
  continue;
4579
5037
  }
4580
- if (!candidates.some((rel) => fs14.existsSync(path14.join(packageRoot, rel)))) {
5038
+ if (!candidates.some((rel) => fs15.existsSync(path15.join(packageRoot, rel)))) {
4581
5039
  broken.push(`${ruleId} \u2192 ${target} (${candidates[0]} missing)`);
4582
5040
  }
4583
5041
  }
@@ -4609,9 +5067,9 @@ function detectSmokePlatform(projectRoot) {
4609
5067
  return "claude";
4610
5068
  }
4611
5069
  function dispatcherRunner(packageRoot) {
4612
- const localTsx = path14.join(packageRoot, "node_modules", ".bin", "tsx");
4613
- const script = path14.join(packageRoot, "src", "scripts", "hooks", "dispatch_hook.ts");
4614
- if (fs14.existsSync(localTsx)) {
5070
+ const localTsx = path15.join(packageRoot, "node_modules", ".bin", "tsx");
5071
+ const script = path15.join(packageRoot, "src", "scripts", "hooks", "dispatch_hook.ts");
5072
+ if (fs15.existsSync(localTsx)) {
4615
5073
  return [localTsx, script];
4616
5074
  }
4617
5075
  return ["npx", "tsx", script];
@@ -4661,12 +5119,12 @@ function _check_hook_dispatcher(projectRoot, packageRoot = PACKAGE_ROOT, opts =
4661
5119
  };
4662
5120
  }
4663
5121
  function readSettingsMode(projectRoot) {
4664
- const settingsPath = path14.join(projectRoot, ".agent-settings.yml");
4665
- if (!fs14.existsSync(settingsPath)) {
5122
+ const settingsPath = path15.join(projectRoot, ".agent-settings.yml");
5123
+ if (!fs15.existsSync(settingsPath)) {
4666
5124
  return "eager-all";
4667
5125
  }
4668
5126
  try {
4669
- const parsed = YAML.parse(fs14.readFileSync(settingsPath, "utf8"));
5127
+ const parsed = YAML.parse(fs15.readFileSync(settingsPath, "utf8"));
4670
5128
  const lean = parsed?.["lean_projection"] ?? null;
4671
5129
  const mode = lean?.["mode"];
4672
5130
  return typeof mode === "string" && mode.length > 0 ? mode : "eager-all";
@@ -4677,7 +5135,7 @@ function readSettingsMode(projectRoot) {
4677
5135
  function kernelIdsFromRouter(packageRoot) {
4678
5136
  try {
4679
5137
  const router = JSON.parse(
4680
- fs14.readFileSync(path14.join(packageRoot, "dist", "router.json"), "utf8")
5138
+ fs15.readFileSync(path15.join(packageRoot, "dist", "router.json"), "utf8")
4681
5139
  );
4682
5140
  return new Set((router["kernel"] ?? []).map(String));
4683
5141
  } catch {
@@ -4694,8 +5152,8 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
4694
5152
  remedy: "set lean_projection.mode to 'eager-all' or 'thin' in .agent-settings.yml"
4695
5153
  };
4696
5154
  }
4697
- const rulesDir = projectedRulesDir ?? path14.join(projectRoot, ".augment", "rules");
4698
- if (!fs14.existsSync(rulesDir)) {
5155
+ const rulesDir = projectedRulesDir ?? path15.join(projectRoot, ".augment", "rules");
5156
+ if (!fs15.existsSync(rulesDir)) {
4699
5157
  return {
4700
5158
  id: "lean-projection",
4701
5159
  status: "skipped",
@@ -4704,7 +5162,7 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
4704
5162
  };
4705
5163
  }
4706
5164
  const kernel = kernelIdsFromRouter(packageRoot);
4707
- const files = fs14.readdirSync(rulesDir).filter((f) => f.endsWith(".md") && f !== "INDEX.md").sort();
5165
+ const files = fs15.readdirSync(rulesDir).filter((f) => f.endsWith(".md") && f !== "INDEX.md").sort();
4708
5166
  const nonKernel = files.filter((f) => !kernel.has(f.replace(/\.md$/, "")));
4709
5167
  if (nonKernel.length === 0) {
4710
5168
  return {
@@ -4718,7 +5176,7 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
4718
5176
  for (const f of nonKernel) {
4719
5177
  let text = "";
4720
5178
  try {
4721
- text = fs14.readFileSync(path14.join(rulesDir, f), "utf8");
5179
+ text = fs15.readFileSync(path15.join(rulesDir, f), "utf8");
4722
5180
  } catch {
4723
5181
  continue;
4724
5182
  }
@@ -4749,8 +5207,8 @@ function _check_lean_projection(projectRoot, packageRoot = PACKAGE_ROOT, project
4749
5207
  function _check_host_manifest(projectRoot) {
4750
5208
  const detected = Object.entries(detectToolPresence(projectRoot)).filter(([, v]) => v === true).map(([k]) => k);
4751
5209
  const detectedNote = detected.length > 0 ? `detected surfaces: ${detected.join(", ")}` : "no surfaces detected";
4752
- const settingsPath = path14.join(projectRoot, ".agent-settings.yml");
4753
- if (!fs14.existsSync(settingsPath)) {
5210
+ const settingsPath = path15.join(projectRoot, ".agent-settings.yml");
5211
+ if (!fs15.existsSync(settingsPath)) {
4754
5212
  return {
4755
5213
  id: "host-manifest",
4756
5214
  status: "ok",
@@ -4760,7 +5218,7 @@ function _check_host_manifest(projectRoot) {
4760
5218
  }
4761
5219
  let parsed = null;
4762
5220
  try {
4763
- parsed = YAML.parse(fs14.readFileSync(settingsPath, "utf8"));
5221
+ parsed = YAML.parse(fs15.readFileSync(settingsPath, "utf8"));
4764
5222
  } catch (exc) {
4765
5223
  return {
4766
5224
  id: "host-manifest",
@@ -4859,7 +5317,7 @@ function _parse(argv) {
4859
5317
  }
4860
5318
  return opts;
4861
5319
  }
4862
- function main14(argv = null) {
5320
+ function main15(argv = null) {
4863
5321
  const opts = _parse(argv !== null ? Array.from(argv) : process6.argv.slice(2));
4864
5322
  if (opts.funnel) {
4865
5323
  print(render5(buildFunnel()));
@@ -4930,25 +5388,25 @@ function main14(argv = null) {
4930
5388
  }
4931
5389
  return failed ? 1 : 0;
4932
5390
  }
4933
- function _isCliEntry13() {
5391
+ function _isCliEntry14() {
4934
5392
  if (process6.argv[1] === void 0) {
4935
5393
  return false;
4936
5394
  }
4937
- const argvUrl = pathToFileURL14(path14.resolve(process6.argv[1])).href;
5395
+ const argvUrl = pathToFileURL15(path15.resolve(process6.argv[1])).href;
4938
5396
  if (import.meta.url === argvUrl) {
4939
5397
  return true;
4940
5398
  }
4941
5399
  try {
4942
- const here = fs14.realpathSync(fileURLToPath14(import.meta.url));
4943
- const argv = fs14.realpathSync(path14.resolve(process6.argv[1]));
5400
+ const here = fs15.realpathSync(fileURLToPath15(import.meta.url));
5401
+ const argv = fs15.realpathSync(path15.resolve(process6.argv[1]));
4944
5402
  return here === argv;
4945
5403
  } catch {
4946
5404
  return false;
4947
5405
  }
4948
5406
  }
4949
- if (_isCliEntry13() || process6.argv[1] === _HERE5) {
5407
+ if (_isCliEntry14() || process6.argv[1] === _HERE5) {
4950
5408
  try {
4951
- process6.exitCode = main14(process6.argv.slice(2));
5409
+ process6.exitCode = main15(process6.argv.slice(2));
4952
5410
  } catch (e) {
4953
5411
  if (e instanceof ArgparseExit) {
4954
5412
  process6.exitCode = e.code;
@@ -4971,7 +5429,7 @@ export {
4971
5429
  conformanceLogPath,
4972
5430
  detectSmokePlatform,
4973
5431
  installLogPath,
4974
- main14 as main,
5432
+ main15 as main,
4975
5433
  routeTargetPaths,
4976
5434
  runConformanceChecks
4977
5435
  };