@event4u/agent-config 15.0.0 → 16.0.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 (78) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +142 -348
  5. package/dist/agent-src/commands/roadmap/create.md +3 -2
  6. package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +50 -0
  7. package/dist/agent-src/rules/user-interaction.md +31 -30
  8. package/dist/agent-src/skills/error-handling-patterns/SKILL.md +9 -0
  9. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  10. package/dist/cli-delegate/{chunk-HZ52BRGG.js → chunk-H32DGUJH.js} +14 -89
  11. package/dist/cli-delegate/chunk-NUHLI2RX.js +80 -0
  12. package/dist/cli-delegate/{chunk-TYSY33MD.js → chunk-QJWAUMJW.js} +12 -2
  13. package/dist/cli-delegate/{chunk-2KKXJW25.js → chunk-S3VFXMTM.js} +1 -1
  14. package/dist/cli-delegate/cmd_conformance.js +831 -272
  15. package/dist/cli-delegate/cmd_explain.js +4 -2
  16. package/dist/cli-delegate/cmd_handoff.js +2 -2
  17. package/dist/cli-delegate/cmd_packs_active.js +2 -1
  18. package/dist/cli-delegate/cmd_session_recycle.js +2 -2
  19. package/dist/cli-delegate/cmd_settings_set.js +13 -0
  20. package/dist/discovery/deprecation-report.md +1 -1
  21. package/dist/discovery/discovery-manifest.json +5 -5
  22. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  23. package/dist/discovery/discovery-manifest.summary.md +1 -1
  24. package/dist/discovery/dormancy-report.md +1 -1
  25. package/dist/discovery/orphan-report.md +1 -1
  26. package/dist/discovery/packs.json +2 -2
  27. package/dist/discovery/trust-report.md +1 -1
  28. package/dist/discovery/workspaces.json +2 -2
  29. package/dist/hooks/dispatch.js +1274 -571
  30. package/dist/install/install.mjs +1 -0
  31. package/dist/mcp/registry-manifest.json +2 -2
  32. package/dist/mcp/server.json +2 -2
  33. package/dist/mcp/server.mjs +1218 -632
  34. package/dist/scripts/_lib/installed_lock.js +1 -1
  35. package/dist/server/io/yamlIO.js +50 -0
  36. package/package.json +1 -1
  37. package/src/config/continuity-surface.json +7 -0
  38. package/src/config/gate-violation-baselines.json +3 -3
  39. package/src/config/host-injection-effect.json +1 -1
  40. package/src/config/preamble-payload-budget.json +12 -7
  41. package/src/config/preamble-payload-exceptions.json +28 -0
  42. package/src/scripts/_dispatch.bash +3 -1
  43. package/src/scripts/_lib/base_ref_payload.ts +315 -0
  44. package/src/scripts/_lib/dropped_decision.ts +142 -0
  45. package/src/scripts/_lib/installed_lock.ts +1 -1
  46. package/src/scripts/_lib/measured_payload_ceiling.ts +424 -0
  47. package/src/scripts/_lib/payload_catalogue_completeness.ts +211 -0
  48. package/src/scripts/_lib/release_findings_ingest.ts +324 -0
  49. package/src/scripts/_lib/release_tag_dispatch.ts +63 -0
  50. package/src/scripts/_lib/review_baseline.ts +254 -0
  51. package/src/scripts/_lib/review_skipped_record.ts +61 -1
  52. package/src/scripts/_lib/standing_bound_ratchet.ts +216 -103
  53. package/src/scripts/_lib/turn_end_refusals.ts +51 -4
  54. package/src/scripts/check_beta_review_markers.ts +35 -4
  55. package/src/scripts/check_finding_dispositions.ts +167 -16
  56. package/src/scripts/check_held_object_arrivals.ts +381 -0
  57. package/src/scripts/check_preamble_payload_budget.ts +399 -122
  58. package/src/scripts/check_release_published.ts +1 -1
  59. package/src/scripts/check_reply_consistency.ts +86 -17
  60. package/src/scripts/hook_manifest.json +1 -1
  61. package/src/scripts/hook_manifest.yaml +39 -3
  62. package/src/scripts/hooks/block_kernel_rule_writes.ts +12 -2
  63. package/src/scripts/hooks/concern_registry.ts +2 -0
  64. package/src/scripts/hooks/end_review_nudge_hook.ts +101 -21
  65. package/src/scripts/hooks/review_baseline_hook.ts +130 -0
  66. package/src/scripts/hooks/turn_end_gate_hook.ts +232 -14
  67. package/src/scripts/hooks_doctor.ts +4 -1
  68. package/src/scripts/install.ts +1 -1
  69. package/src/scripts/interruption_report.ts +8 -2
  70. package/src/scripts/janitor.ts +8 -1
  71. package/src/scripts/measure_turn_end_gate.ts +302 -5
  72. package/src/scripts/release.ts +52 -64
  73. package/src/scripts/release_drill.ts +193 -14
  74. package/src/scripts/release_env.ts +1 -1
  75. package/src/scripts/release_publication.ts +1 -1
  76. package/src/scripts/report_held_object_arrivals.ts +456 -0
  77. package/src/scripts/sync_agent_settings.ts +140 -18
  78. package/src/server/io/yamlIO.ts +48 -0
@@ -272,8 +272,9 @@ Ask (in the user's language) exactly one numbered-options question:
272
272
 
273
273
  > How should this roadmap be executed later?
274
274
  >
275
- > 1. Fully autonomous — one run-start contract confirmation, then no
276
- > interruptions except the safety floors
275
+ > 1. Fully autonomous — one run-start contract confirmation, then the
276
+ > only halts are the safety floors, a quality-red, and a step that
277
+ > reveals out-of-roadmap work
277
278
  > 2. Checkpoint at phase boundaries — compact status + continue prompt
278
279
  > per phase
279
280
  > 3. Interactive — every gate fires as today
@@ -202,3 +202,53 @@ After completing a batch of actions, provide a summary table:
202
202
  | 2 | `test.php` | Updated assertion |
203
203
  | 3 | `config.php` | Skipped (intentional) |
204
204
  ```
205
+
206
+ ## The trigger is a decision, not a format — the measurement behind it
207
+
208
+ Migrated out of `user-interaction.md` on 2026-09-11 to pay for Iron Law 3
209
+ under the per-spawn preamble budget. The obligation stays in the rule; this
210
+ is the evidence for it.
211
+
212
+ Measured (30-session conformance audit, 2026-08-06): **every** malformed ask
213
+ was a one-line parenthetical or a trailing free-text offer — a German
214
+ "say the word if I should take the three lines along", an English "shall I
215
+ implement it this way?" — while the same sessions formatted their **large**
216
+ asks perfectly. So the rule is being read as *if numbered options, then a
217
+ recommendation line*. It is the other way round, and an ask that feels too
218
+ small for a block is exactly the one that escapes the format.
219
+
220
+ Three further caught shapes: a contentless filler option; an inline
221
+ "(recommended)" tag **beside** the recommendation line (the dual source
222
+ Iron Law 1 forbids); an option set answerable only as `1,3,4`.
223
+
224
+ **No gate ships for this.** `check_reply_consistency` can read a draft on
225
+ stdin, but it inspects *numbered-option blocks* — and every measured failure
226
+ had no block by construction, so it scans exactly the surface that did not
227
+ fail. `conformance:behavior` deliberately does not score ask-shape, so an
228
+ unmoved rate is a finding rather than a silence.
229
+
230
+ ## Iron Law 3 — why laws 1 and 2 do not reach across a turn boundary
231
+
232
+ Iron Laws 1 and 2 are discharged by the shape of the reply that carries the
233
+ block. Neither survives a turn boundary, which is the gap Iron Law 3 closes:
234
+ a second assistant execution with no user message between it and the ask is
235
+ not a new conversation, and from the user's side a thread that ends without
236
+ the question ended without the question.
237
+
238
+ **The measured failure.** A turn put three numbered options and a
239
+ recommendation line to the user. A `stop` concern then produced a second
240
+ assistant execution with no intervening user message, and that second reply
241
+ handled the concern while demoting the open question to a subordinate clause.
242
+ The four rules that could have caught it did not, each for a stated reason:
243
+ Iron Law 1 inspects a reply that HAS an options block, `check_reply_consistency`
244
+ receives a draft rather than a transcript, `active-remediation` governs
245
+ findings rather than issued decisions, and `no-cheap-questions` guards the
246
+ opposite direction.
247
+
248
+ **Carrier, stated honestly.** The deterministic half is the
249
+ `pending-decision` detector in `src/scripts/hooks/turn_end_gate_hook.ts` —
250
+ it refuses a turn-end when an earlier reply in the same user turn carried a
251
+ block and the closing reply carries none. It sees one user turn on one host,
252
+ so everything outside that is model-carried, exactly like Iron Law 2's own
253
+ "no gate ships for this" note. `check_reply_consistency` reads a single draft
254
+ and holds no cross-turn state; it cannot see this law at all.
@@ -19,9 +19,10 @@ obligation_frequency: "per-turn"
19
19
 
20
20
  # User Interaction
21
21
 
22
- Two Iron Laws govern every reply that contains numbered options.
23
- They override conversation momentum, brevity, and the urge to defer
24
- to the user. **Missing a recommendation is a rule violation, not a slip.**
22
+ Three Iron Laws govern a decision put to the user — two on the reply that
23
+ carries it, one on what happens if the agent runs again before the answer.
24
+ They override conversation momentum, brevity, and the urge to defer to the
25
+ user. **Missing a recommendation is a rule violation, not a slip.**
25
26
 
26
27
  ## Iron Law 1 — Single-Source Recommendation
27
28
 
@@ -43,14 +44,28 @@ EVERY REPLY WITH NUMBERED OPTIONS RUNS THE SELF-CHECK. NO EXCEPTIONS.
43
44
  SKIPPING IT IS A RULE VIOLATION, NOT A SLIP.
44
45
  ```
45
46
 
46
- Mechanical backstop:
47
+ Mechanical backstop for Iron Laws 1 and 2 (non-zero exit on either), a safety
48
+ net under the self-scan rather than a replacement for it:
47
49
  `./scripts-run src/scripts/check_reply_consistency --stdin < draft.md`
48
- (non-zero exit on any rule below). Self-scan is the primary gate;
49
- the script is the deterministic safety net.
50
+ It takes a DRAFT, so it cannot see Iron Law 3, which is about a transcript.
51
+
52
+ ## Iron Law 3 — A Decision Outlives the Turn
53
+
54
+ ```
55
+ A DECISION HANDED TO THE USER STAYS LIVE UNTIL THE USER ANSWERS IT.
56
+ THE AGENT RUNS AGAIN WITHOUT AN ANSWER — HOOK CONTINUATION, NOTIFICATION,
57
+ WAKE, RETRY — AND THE BLOCK PLUS ITS RECOMMENDATION LINE ARE RE-PRESENTED
58
+ IN THE SAME FORM. A SUBORDINATE CLAUSE IS NOT A RE-PRESENTATION.
59
+ A HOOK'S CONCERN MAY BE ADDED TO A PENDING DECISION, NEVER REPLACE ONE.
60
+ ONLY THE USER CLOSES IT — BY ANSWERING, OR BY MAKING IT MOOT.
61
+ ```
62
+
63
+ Carrier: the `pending-decision` detector on `turn-end-gate`, one user turn on
64
+ one host; the rest is model-carried. Mechanics carries the measured failure.
50
65
 
51
66
  ## Question pacing — one decision point per turn
52
67
 
53
- [`ask-when-uncertain`](ask-when-uncertain.md)'s Iron Law is canonical: **one question per turn**. What counts as "one question" is **one decision point** — a single numbered-options block is ONE question even when its options span multiple dimensions (a depth-and-framework matrix answered with a single number is one decision). Multiple separate asks in one reply, or a block whose answer would need a structured reply (`1a, 2b`), violate the kernel rule's self-check.
68
+ [`ask-when-uncertain`](ask-when-uncertain.md)'s Iron Law is canonical: **one question per turn**. What counts as "one question" is **one decision point** — one numbered-options block is ONE question even when its options span several dimensions, provided a single number answers it. Multiple separate asks in one reply, or a block needing a structured reply (`1a, 2b`), violate the kernel rule's self-check.
54
69
 
55
70
  If in doubt, split into serial turns — never a long batched prompt.
56
71
 
@@ -62,33 +77,19 @@ NOT ON THE PRESENCE OF A NUMBERED LIST.
62
77
  A TRAILING FREE-TEXT OFFER IS AN ASK. A BARE YES/NO IS AN ASK.
63
78
  ```
64
79
 
65
- Measured (30-session conformance audit, 2026-08-06): **every** malformed ask was
66
- a one-line parenthetical or a trailing free-text offer — *"sag Bescheid, wenn
67
- ich die drei Zeilen mitnehmen soll"*, *"Soll ich das so umsetzen?"* — while the
68
- same sessions formatted their **large** asks perfectly. So the rule is being
69
- read as *if numbered options, then a recommendation line*. It is the other way
70
- round, and an ask that feels too small for a block is exactly the one that
71
- escapes the format. Three further caught shapes: a contentless filler option; an
72
- inline `(Empfohlen)` tag **beside** the recommendation line (the dual source
73
- Iron Law 1 forbids); an option set answerable only as `1,3,4`.
74
-
75
- **No gate ships for this.** `check_reply_consistency` can read a draft on stdin,
76
- but it inspects *numbered-option blocks* — and every measured failure had no
77
- block by construction, so it scans exactly the surface that did not fail. `conformance:behavior` deliberately does not score ask-shape,
78
- so an unmoved rate is a finding rather than a silence.
80
+ Measured (30-session audit, 2026-08-06): **every** malformed ask was a one-line
81
+ parenthetical or a trailing offer, while the same sessions formatted their
82
+ **large** asks perfectly — the ask that feels too small for a block is the one
83
+ that escapes the format. **No gate ships for this**: the backstop inspects
84
+ numbered-option blocks, and every measured failure had none. Detail: mechanics.
79
85
 
80
86
  ## Mechanics — rationale, failure modes, format details, examples
81
87
 
82
- The "why take a position", position-agnostic clause, format
83
- specification (neutral block + bolded recommendation line + caveat),
84
- no-trailing-open-question rule, "what does NOT count" catalog, full
85
- five-step pre-send self-check, named failure-mode catalog (end-of-turn
86
- menu, trailing-question hedge, no-preference hedge, multi-block reply,
87
- …), slip-handling protocol, numbered-options rules, format examples,
88
- progress indicators, and summary-table patterns all live in
88
+ The rule above is the obligation surface. Everything you look up rather than
89
+ obey — why to take a position, the format spec, the five-step self-check, the
90
+ named failure-mode catalog, slip handling, examples, progress indicators and
91
+ summary patterns — is in
89
92
  [`contexts/communication/rules-auto/user-interaction-mechanics.md`](../contexts/communication/rules-auto/user-interaction-mechanics.md).
90
- The rule above is the obligation surface; the mechanics file is the
91
- lookup material.
92
93
 
93
94
  When the user pastes large tool output, logs, JSON, or API responses,
94
95
  keep the reply narrow: extract only the relevant fields with targeted
@@ -79,6 +79,15 @@ Every produced error must carry: `code` (stable string), `message` (human-readab
79
79
 
80
80
  Forbidden: secrets, raw SQL, full stack traces in user-facing surfaces, internal class names leaked through API boundaries.
81
81
 
82
+ **"User-facing" means PRODUCTION, and the missing half of that sentence cost a real failure.** Read without the qualifier — as it stood until 2026-09-11 — this clause forbids the developer's own diagnostics in their own dev environment, which is the opposite of what it is for. The measured consequence, reported by the maintainer: a feature whose detail view crashed on open and showed a blank region, so neither the developer nor the agent could see *what* was missing, and the failure had to be reconstructed by hand.
83
+
84
+ | Environment | What a failed render or request shows |
85
+ |---|---|
86
+ | local / dev / preview | the **full** diagnostic, visibly: what was expected, what arrived, which field or endpoint, the stack. A toast, an error overlay, an inline panel — anything the developer cannot miss. Silence here is the defect. |
87
+ | production | the sanitized payload above, plus a correlation id the developer can look up. Never the stack. |
88
+
89
+ **A blank page is never an acceptable failure mode in dev.** If a component cannot render because data is missing or a contract changed, it says so on screen in dev and degrades to a stated empty/error state in production — never to nothing. That is the same obligation the four completeness rows in [`ai-code-blindspots`](../ai-code-blindspots/SKILL.md) put on the render surface, stated here for the error path that reaches it.
90
+
82
91
  ### Step 5 — Define the boundary
83
92
 
84
93
  Exactly **one** layer translates internal errors to the egress format (HTTP status + body, queue requeue policy, CLI exit code). Anywhere else doing this duplication is the bug.
@@ -39,7 +39,7 @@ schema_version: 1
39
39
  # CI guard: a release bump of `package.json` must update this value
40
40
  # in lockstep — see scripts/check_template_pin_drift.ts (road-to-
41
41
  # portable-runtime-and-update-check P3.3).
42
- agent_config_version: "15.0.0"
42
+ agent_config_version: "16.0.0"
43
43
 
44
44
  # --- Project identity ---
45
45
  project:
@@ -1,90 +1,16 @@
1
1
  import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
2
+ import {
3
+ artefact_roots
4
+ } from "./chunk-NUHLI2RX.js";
2
5
  import {
3
6
  DEFAULT_PROJECT_FILE,
4
7
  logger
5
8
  } from "./chunk-2XY7ILBT.js";
6
9
 
7
10
  // src/scripts/config/profiles.ts
8
- import * as fs2 from "node:fs";
9
- import { createRequire } from "node:module";
10
- import * as path3 from "node:path";
11
-
12
- // src/scripts/_lib/agent_src.ts
13
11
  import * as fs from "node:fs";
14
- import * as path2 from "node:path";
15
- import { fileURLToPath } from "node:url";
16
-
17
- // src/scripts/_lib/guidelines_lane.ts
12
+ import { createRequire } from "node:module";
18
13
  import * as path from "node:path";
19
- var GUIDELINES_SOURCE_REL = path.join("docs", "guidelines");
20
-
21
- // src/scripts/_lib/agent_src.ts
22
- var _HERE = path2.dirname(fileURLToPath(import.meta.url));
23
- var _DEFAULT_ROOT = path2.resolve(_HERE, "..", "..", "..");
24
- function _deriveRoots(root) {
25
- const packages = path2.join(root, "packages");
26
- const src = path2.join(root, "src");
27
- return {
28
- ROOT: root,
29
- LEGACY_SRC: path2.join(root, ".agent-src.uncondensed"),
30
- PACKAGES: packages,
31
- PACKAGE_CORE: path2.join(packages, "core"),
32
- SRC: src,
33
- SRC_SKILLS: path2.join(src, "skills"),
34
- SRC_RULES: path2.join(src, "rules"),
35
- SRC_AGENT: path2.join(src, "agent-src"),
36
- SRC_DOMAINS: path2.join(src, "domains")
37
- };
38
- }
39
- var _roots = _deriveRoots(_DEFAULT_ROOT);
40
- function _isDir(p) {
41
- try {
42
- return fs.statSync(p).isDirectory();
43
- } catch {
44
- return false;
45
- }
46
- }
47
- function _exists(p) {
48
- try {
49
- fs.statSync(p);
50
- return true;
51
- } catch {
52
- return false;
53
- }
54
- }
55
- function _iterdirSorted(p) {
56
- let names;
57
- try {
58
- names = fs.readdirSync(p);
59
- } catch {
60
- return [];
61
- }
62
- names.sort();
63
- return names.map((name) => path2.join(p, name));
64
- }
65
- function artefact_roots() {
66
- const roots = [];
67
- if (_exists(_roots.LEGACY_SRC)) {
68
- roots.push(_roots.LEGACY_SRC);
69
- }
70
- if (_exists(_roots.PACKAGES)) {
71
- for (const pkg of _iterdirSorted(_roots.PACKAGES)) {
72
- const sub = path2.join(pkg, ".agent-src.uncondensed");
73
- if (_isDir(sub)) {
74
- roots.push(sub);
75
- }
76
- }
77
- }
78
- if (_isDir(_roots.SRC_AGENT)) {
79
- roots.push(_roots.SRC_AGENT);
80
- }
81
- if (_isDir(_roots.SRC_SKILLS) || _isDir(_roots.SRC_RULES)) {
82
- roots.push(_roots.SRC);
83
- }
84
- return roots;
85
- }
86
-
87
- // src/scripts/config/profiles.ts
88
14
  var _require = createRequire(import.meta.url);
89
15
  var PROFILE_ID_ENV = "AGENT_CONFIG_PROFILE_ID";
90
16
  var DEFAULT_PROFILE_ID = "developer";
@@ -135,7 +61,7 @@ function _load_yaml(p) {
135
61
  }
136
62
  let text;
137
63
  try {
138
- text = fs2.readFileSync(p, "utf-8");
64
+ text = fs.readFileSync(p, "utf-8");
139
65
  } catch (exc) {
140
66
  logger.warning("profile read failed for %s: %s", p, String(exc));
141
67
  return {};
@@ -153,8 +79,8 @@ function _load_yaml(p) {
153
79
  return _isPlainDict(data) ? data : {};
154
80
  }
155
81
  function profile_file(project_root, profile_id) {
156
- const legacy = path3.join(project_root, PROFILES_DIRNAME, `${profile_id}.yml`);
157
- if (_exists2(legacy)) {
82
+ const legacy = path.join(project_root, PROFILES_DIRNAME, `${profile_id}.yml`);
83
+ if (_exists(legacy)) {
158
84
  return legacy;
159
85
  }
160
86
  let roots;
@@ -164,8 +90,8 @@ function profile_file(project_root, profile_id) {
164
90
  return legacy;
165
91
  }
166
92
  for (const root of roots) {
167
- const candidate = path3.join(root, "profiles", `${profile_id}.yml`);
168
- if (_exists2(candidate)) {
93
+ const candidate = path.join(root, "profiles", `${profile_id}.yml`);
94
+ if (_exists(candidate)) {
169
95
  return candidate;
170
96
  }
171
97
  }
@@ -217,14 +143,14 @@ function _pick_id(pack_profile_id, user_settings, runtime_id) {
217
143
  }
218
144
  function resolve_profile(params) {
219
145
  const settings = params.user_settings ?? {};
220
- const settings_file = path3.join(params.project_root, DEFAULT_PROJECT_FILE);
146
+ const settings_file = path.join(params.project_root, DEFAULT_PROJECT_FILE);
221
147
  const [profile_id, source] = _pick_id(
222
148
  params.pack_profile_id ?? null,
223
149
  settings,
224
150
  params.runtime_id ?? null
225
151
  );
226
152
  if (profile_id === null) {
227
- if (_exists2(settings_file)) {
153
+ if (_exists(settings_file)) {
228
154
  return new ResolvedProfile({
229
155
  id: DEFAULT_PROFILE_ID,
230
156
  source: SOURCE_MISSING,
@@ -238,16 +164,16 @@ function resolve_profile(params) {
238
164
  );
239
165
  }
240
166
  const yaml_path = profile_file(params.project_root, profile_id);
241
- if (!_exists2(yaml_path)) {
167
+ if (!_exists(yaml_path)) {
242
168
  throw new ProfileError(
243
169
  `profile.id=${_repr(profile_id)} (${source}) but ${yaml_path} not found`
244
170
  );
245
171
  }
246
172
  return _build_resolved(profile_id, _load_yaml(yaml_path), { source });
247
173
  }
248
- function _exists2(p) {
174
+ function _exists(p) {
249
175
  try {
250
- fs2.statSync(p);
176
+ fs.statSync(p);
251
177
  return true;
252
178
  } catch {
253
179
  return false;
@@ -267,7 +193,6 @@ function _repr(s) {
267
193
  }
268
194
 
269
195
  export {
270
- artefact_roots,
271
196
  PROFILE_ID_ENV,
272
197
  SOURCE_MISSING,
273
198
  ProfileError,
@@ -0,0 +1,80 @@
1
+ import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
2
+
3
+ // src/scripts/_lib/agent_src.ts
4
+ import * as fs from "node:fs";
5
+ import * as path2 from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ // src/scripts/_lib/guidelines_lane.ts
9
+ import * as path from "node:path";
10
+ var GUIDELINES_SOURCE_REL = path.join("docs", "guidelines");
11
+
12
+ // src/scripts/_lib/agent_src.ts
13
+ var _HERE = path2.dirname(fileURLToPath(import.meta.url));
14
+ var _DEFAULT_ROOT = path2.resolve(_HERE, "..", "..", "..");
15
+ function _deriveRoots(root) {
16
+ const packages = path2.join(root, "packages");
17
+ const src = path2.join(root, "src");
18
+ return {
19
+ ROOT: root,
20
+ LEGACY_SRC: path2.join(root, ".agent-src.uncondensed"),
21
+ PACKAGES: packages,
22
+ PACKAGE_CORE: path2.join(packages, "core"),
23
+ SRC: src,
24
+ SRC_SKILLS: path2.join(src, "skills"),
25
+ SRC_RULES: path2.join(src, "rules"),
26
+ SRC_AGENT: path2.join(src, "agent-src"),
27
+ SRC_DOMAINS: path2.join(src, "domains")
28
+ };
29
+ }
30
+ var _roots = _deriveRoots(_DEFAULT_ROOT);
31
+ function _isDir(p) {
32
+ try {
33
+ return fs.statSync(p).isDirectory();
34
+ } catch {
35
+ return false;
36
+ }
37
+ }
38
+ function _exists(p) {
39
+ try {
40
+ fs.statSync(p);
41
+ return true;
42
+ } catch {
43
+ return false;
44
+ }
45
+ }
46
+ function _iterdirSorted(p) {
47
+ let names;
48
+ try {
49
+ names = fs.readdirSync(p);
50
+ } catch {
51
+ return [];
52
+ }
53
+ names.sort();
54
+ return names.map((name) => path2.join(p, name));
55
+ }
56
+ function artefact_roots() {
57
+ const roots = [];
58
+ if (_exists(_roots.LEGACY_SRC)) {
59
+ roots.push(_roots.LEGACY_SRC);
60
+ }
61
+ if (_exists(_roots.PACKAGES)) {
62
+ for (const pkg of _iterdirSorted(_roots.PACKAGES)) {
63
+ const sub = path2.join(pkg, ".agent-src.uncondensed");
64
+ if (_isDir(sub)) {
65
+ roots.push(sub);
66
+ }
67
+ }
68
+ }
69
+ if (_isDir(_roots.SRC_AGENT)) {
70
+ roots.push(_roots.SRC_AGENT);
71
+ }
72
+ if (_isDir(_roots.SRC_SKILLS) || _isDir(_roots.SRC_RULES)) {
73
+ roots.push(_roots.SRC);
74
+ }
75
+ return roots;
76
+ }
77
+
78
+ export {
79
+ artefact_roots
80
+ };
@@ -891,7 +891,9 @@ var DETECTOR_IDS = [
891
891
  "promissory",
892
892
  "language",
893
893
  "verification",
894
- "completion"
894
+ "completion",
895
+ "pending-decision",
896
+ "untested"
895
897
  ];
896
898
  var REFUSAL_STATE_REL = path2.join("agents", "runtime", "state", "turn-end-gate");
897
899
  function refusalStateDir(workspaceRoot) {
@@ -916,7 +918,9 @@ function readSessionCounts(workspaceRoot, sessionId) {
916
918
  }
917
919
  }
918
920
  function emptyCounts() {
919
- return { promissory: 0, language: 0, verification: 0, completion: 0 };
921
+ const out = {};
922
+ for (const id of DETECTOR_IDS) out[id] = 0;
923
+ return out;
920
924
  }
921
925
  function isDetector(v) {
922
926
  return typeof v === "string" && DETECTOR_IDS.includes(v);
@@ -942,6 +946,9 @@ function parseRecord(raw) {
942
946
  if (typeof o["agent_config_version"] === "string") {
943
947
  rec.agent_config_version = o["agent_config_version"];
944
948
  }
949
+ if (typeof o["refused_prompt_id"] === "string") {
950
+ rec.refused_prompt_id = o["refused_prompt_id"];
951
+ }
945
952
  const counts = o["counts"];
946
953
  if (typeof counts === "object" && counts !== null && !Array.isArray(counts)) {
947
954
  const parsed = {};
@@ -985,6 +992,9 @@ function foldRefusal(prev, input) {
985
992
  else if (prev?.agent_config_version !== void 0) {
986
993
  rec.agent_config_version = prev.agent_config_version;
987
994
  }
995
+ if (input.promptId !== void 0 && input.promptId !== "") {
996
+ rec.refused_prompt_id = input.promptId;
997
+ }
988
998
  return rec;
989
999
  }
990
1000
  function readInstallBoundary() {
@@ -3,7 +3,7 @@ import {
3
3
  pruneAgedRefusalState,
4
4
  readSessionCounts,
5
5
  statePathFor
6
- } from "./chunk-TYSY33MD.js";
6
+ } from "./chunk-QJWAUMJW.js";
7
7
  import {
8
8
  readHookStdin
9
9
  } from "./chunk-F7DQWYR5.js";