@event4u/agent-config 7.0.0 → 7.0.2

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.
@@ -0,0 +1,126 @@
1
+ # Changelog Archive — pre-7.0.0
2
+
3
+ > Frozen snapshot of `event4u/agent-config` changelog entries
4
+ > released before `7.0.0`, split out of the main
5
+ > [`CHANGELOG.md`](../../CHANGELOG.md) by `scripts/release.py`
6
+ > once the active era's body crossed the drift cap enforced by
7
+ > `tests/test_changelog_eras.py`.
8
+ >
9
+ > **Read-only.** New entries land in `CHANGELOG.md`. Entries
10
+ > here are not amended — git tags remain the canonical source
11
+ > for what shipped.
12
+ >
13
+ > Entry shape follows
14
+ > [`../contracts/CHANGELOG-conventions.md`](../contracts/CHANGELOG-conventions.md).
15
+
16
+ ## [6.1.0](https://github.com/event4u-app/agent-config/compare/6.0.0...6.1.0) (2026-06-14)
17
+
18
+ ### Features
19
+
20
+ * **rules:** Iron Law — never drop inherited/shared-branch commits without asking ([e03dc18](https://github.com/event4u-app/agent-config/commit/e03dc18300a2ef032d508062be032267a1f1f844))
21
+ * **workspace:** plain-language host-decision explainability + employee-mode gate (6.0.0 P5) ([f485476](https://github.com/event4u-app/agent-config/commit/f485476050d3d7660aa3aaeacc54438e5eee44a9))
22
+ * **governance:** workspace boundary contract + import-edge drift linter (6.0.0 P4) ([943eb29](https://github.com/event4u-app/agent-config/commit/943eb29747eb3dca0988317e2a526cd38d12f06c))
23
+ * **install:** preview-only dry-run for the upgrade-cleanup reaper (6.0.0 P2) ([4caa802](https://github.com/event4u-app/agent-config/commit/4caa802b1fd1bbf1beda71e5ad553000e7b7f2bf))
24
+ * **create-pr:** run the PR-gate archival sweep before opening the PR ([bdd645b](https://github.com/event4u-app/agent-config/commit/bdd645b3bcc7443c00df653d8f53982417d0ca3e))
25
+ * **roadmaps:** deterministic PR-gate archival sweep ([10643ca](https://github.com/event4u-app/agent-config/commit/10643ca9f5ff56ff02f376531e5c8c07998aa08d))
26
+ * **memory:** remove agent-memory Layer 2; file-first memory only ([c8903c6](https://github.com/event4u-app/agent-config/commit/c8903c6f3a5502434b29c1b55535a9ebc3c55ac4))
27
+ * **bench:** v2 pilot run + honest-null report; spawn stratified follow-up (Phase 4-6) ([5b7f7bd](https://github.com/event4u-app/agent-config/commit/5b7f7bd1112462f83ca42ef6509f4871cdba7ebe))
28
+ * **bench:** v2 dual-axis scorer + runner + paired stats (Phase 2-3) ([ae25ee2](https://github.com/event4u-app/agent-config/commit/ae25ee2c7a8b0fe6325a0c886911a8c48c7546d5))
29
+ * **bench:** v2 discipline-axis corpus + fixtures (Phase 0-1) ([1371dd0](https://github.com/event4u-app/agent-config/commit/1371dd05096c38c7f28f0c4a55b1daf2bb230500))
30
+ * **bench:** wrapper-lift A/B benchmark — model-pin, budget-cap, error-aware ([a09238a](https://github.com/event4u-app/agent-config/commit/a09238ad0455baaf6f68016a195ad54725acd3a3))
31
+ * **reasoning:** add model-agnostic Reasoning Discipline Protocol (RDP) ([b4b5bec](https://github.com/event4u-app/agent-config/commit/b4b5bec18f58630add4e7802c9e32b46b88f3084))
32
+ * **security:** Phase 3 consumer audit + runtime injection hook + review skill ([23efe50](https://github.com/event4u-app/agent-config/commit/23efe5001104c1fd7056f7b2216fc4583f7f29f3))
33
+ * **security:** Phase 2 injection-aware authoring rules ([eb41da9](https://github.com/event4u-app/agent-config/commit/eb41da9c7a1e3140d1efad760bd06e0bd53cb513))
34
+ * **security:** Phase 1 self-audit corpus linters + containment convention ([f678aba](https://github.com/event4u-app/agent-config/commit/f678abab7b521f389e16abb837594b3d23a38d5f))
35
+ * **ai-council:** resolve config user-global-first ([9177b52](https://github.com/event4u-app/agent-config/commit/9177b52a99842b3adffc21b325b39610ef520c6d))
36
+ * **ci:** guard against re-introducing external-source references ([88d35d9](https://github.com/event4u-app/agent-config/commit/88d35d913f5afec7db33f5817229b366cac7256f))
37
+ * **doctor:** add read-only stale-orphans health check ([48e6118](https://github.com/event4u-app/agent-config/commit/48e6118eab2e39fbfa1884a9f6defb1c8719a2ba))
38
+ * **packs:** split meta into capability-scoped packs ([b363839](https://github.com/event4u-app/agent-config/commit/b3638393a6c67ecaac41ae19df89b2ed0b03154b))
39
+ * **commands:** add first-class visibility frontmatter field ([db4d88d](https://github.com/event4u-app/agent-config/commit/db4d88dcf41629f27973624d6476f935be32e2c9))
40
+
41
+ ### Bug Fixes
42
+
43
+ * **refs:** mark the RDP-contract acceptance criterion as a forward-ref ([c7cee96](https://github.com/event4u-app/agent-config/commit/c7cee966495a5c96932c9f2b71ab72aae517623f))
44
+ * **memory:** mine-session description ≤200 chars + command-count floor ([f368e06](https://github.com/event4u-app/agent-config/commit/f368e0667980e3f3a03233e8152fd23daaa8bc5d))
45
+ * **bench:** lint-bench-ab validates the v2 docs/benchmark.md sections ([41d552b](https://github.com/event4u-app/agent-config/commit/41d552bd3a162577be3a898fca9123cce87b38b9))
46
+ * **server:** mirror reasoning.* in settings schema (template parity + diff) ([5f77256](https://github.com/event4u-app/agent-config/commit/5f77256da1ecbfa03f3aa1261f23ec940991c2bc))
47
+ * **reasoning:** skill-lint senior sections + valid rule tier (2b) ([7f3e278](https://github.com/event4u-app/agent-config/commit/7f3e2789ab483b6938a39aac303f1fbe2f35792e))
48
+ * **security:** refresh threat-model command effective-hash ([5505b57](https://github.com/event4u-app/agent-config/commit/5505b57fa6e4e4bf02e2891f49a30e6dc9128da1))
49
+ * **security:** tighten security-sensitive-stop — clear long_rule lint regression ([d528126](https://github.com/event4u-app/agent-config/commit/d528126120bf51335267bdde66793343ec376c87))
50
+ * **security:** list agent-security-review + security-audit-config in marketplace.json ([f432a62](https://github.com/event4u-app/agent-config/commit/f432a62d42fab5fc6707b166e869ca8cc2d5d866))
51
+ * **security:** CI — portability reword + settings-schema parity for injection_scan ([fa78a58](https://github.com/event4u-app/agent-config/commit/fa78a589101fd41984d85496666f2fd618e49a1f))
52
+ * **cli:** preflight dependency guard with an actionable message ([ce58c76](https://github.com/event4u-app/agent-config/commit/ce58c7683541a3bc22852186a9764be127f87e4b))
53
+ * **repo:** untrack stray node_modules symlink, ignore symlink form ([67cc9e6](https://github.com/event4u-app/agent-config/commit/67cc9e61deb241aa23e9affaa5adc1fd92d99f14))
54
+ * **refs:** exempt gitignored agents/.harvest-local in check_references ([0d0b170](https://github.com/event4u-app/agent-config/commit/0d0b1702c27c06e96d486211f639148f7ed0628e))
55
+ * **refs:** mark gitignored harvest-local ref in security-pillar roadmap ([3abf215](https://github.com/event4u-app/agent-config/commit/3abf215692cf49ac190248c0007668b5a7b1e1f0))
56
+ * **ci:** guard against empty (0-byte) roadmap files ([5115865](https://github.com/event4u-app/agent-config/commit/511586591171735437bba8cdb106094628a3d611))
57
+ * **roadmaps:** restore competitive-borrow v6 work, drop empty reaping stub ([9fceeb7](https://github.com/event4u-app/agent-config/commit/9fceeb7fc9585965f44e25543a9699d0ff8ee519))
58
+ * **ai-council:** align user-global config path with the setup wizard ([54de5a8](https://github.com/event4u-app/agent-config/commit/54de5a853c271311d79b2b436dd3fa58fa25eb69))
59
+ * **rule:** drop non-portable task-invocations from source-confidentiality backstop ([57e6f7f](https://github.com/event4u-app/agent-config/commit/57e6f7fe5199cc5192ead2a1468ad7d04dd5d5bc))
60
+ * **install:** always-run tag sweep so reaping catches pre-inventory orphans ([91e5418](https://github.com/event4u-app/agent-config/commit/91e541852c30899cb84dd2070f705dfe7947d350))
61
+ * **discovery:** register visibility + new capability packs in schema/vocab ([1fcc72b](https://github.com/event4u-app/agent-config/commit/1fcc72b08fbd13f85c01d3df7fbc98790395ac91))
62
+
63
+ ### Documentation
64
+
65
+ * **domain-watch:** capture deferred heavyweight tracks in one watch-note (6.0.0 P6) ([e212e1f](https://github.com/event4u-app/agent-config/commit/e212e1fcebed5d61c63d0719deb485787aca6fde))
66
+ * **changelog:** add 6.0.0 release overview + breaking-changes section (6.0.0 P3) ([fdb4b63](https://github.com/event4u-app/agent-config/commit/fdb4b63cd495489341215430ae12a9866cb8503b))
67
+ * fix stale source-of-truth paths and drop above-fold jargon (6.0.0 P1) ([9ee9870](https://github.com/event4u-app/agent-config/commit/9ee98708e1fdcf612848b393aace48b33a548e99))
68
+ * **roadmaps:** add capability-discoverability follow-up from fable-feedback-3 ([a658c2f](https://github.com/event4u-app/agent-config/commit/a658c2f9c338182d1db2db503ab8ce6aa9c1f42f))
69
+ * **model-recommendation:** add orchestrator→subagent model-routing guidance ([669f83d](https://github.com/event4u-app/agent-config/commit/669f83de5b2e6de590d87f7a093eb098bcf8a086))
70
+ * **roadmaps:** add RDP discoverability roadmap ([c65e1b2](https://github.com/event4u-app/agent-config/commit/c65e1b2648af8bfd2a39a6c6dc74124cfc67101b))
71
+ * **roadmaps:** revise discipline-axis pilot for weak-host-first methodology ([9ccb816](https://github.com/event4u-app/agent-config/commit/9ccb816b1fe449cb537567696487c09a4ea2ee8e))
72
+ * **rules:** replace Merge-gated with PR-gate in roadmap-progress-sync ([c140687](https://github.com/event4u-app/agent-config/commit/c1406876e880babd70a178bb958af89f31c49eec))
73
+ * **roadmaps:** memory-layer-cleanup removal + consolidation plans ([254758f](https://github.com/event4u-app/agent-config/commit/254758f1a24d7898b5828a3396d20b7498370d08))
74
+ * **roadmap:** check-refs:skip discipline-axis bench (external repo citations) ([13c5fdb](https://github.com/event4u-app/agent-config/commit/13c5fdb04016c40488140f59688e9db88eee0d9d))
75
+ * **roadmaps:** agent-memory removal + memory-pipeline consolidation plans ([6fbf6a6](https://github.com/event4u-app/agent-config/commit/6fbf6a6d33571839f8c85b276a8728ff62c606c7))
76
+ * **roadmaps:** 3-condition value bench (v1) + discipline-axis bench (v2) ([f5a89c6](https://github.com/event4u-app/agent-config/commit/f5a89c69e60c345dbb655f3b0dab294d2b56669a))
77
+ * **roadmaps:** RDP eval+promotion follow-up; archive frontier-reasoning parent ([417223b](https://github.com/event4u-app/agent-config/commit/417223bce4a4d04404512cfa804ad872dd11324c))
78
+ * **roadmap:** security pillar — supply-chain integrity + injection-aware authoring ([c15ef6a](https://github.com/event4u-app/agent-config/commit/c15ef6adc17226513660b324b7960dc80125bbf3))
79
+ * **roadmap:** fill in road-to-6.0.0-final-readiness ([46ba5a0](https://github.com/event4u-app/agent-config/commit/46ba5a002fb300afbce43e56b92a945bd0957dec))
80
+ * **roadmap:** add image/brand/typography + greenfield-scaffold roadmaps ([f615452](https://github.com/event4u-app/agent-config/commit/f6154528a7b1ba34fb5543c91ac2c905999d2e8c))
81
+ * **ai-council:** repoint config references to the user-global path ([1307f80](https://github.com/event4u-app/agent-config/commit/1307f804b2c1cc4a2b9a3d2ad1b829f2a7108619))
82
+ * **ai-council:** document user-global config location (ADR-093) ([c501e55](https://github.com/event4u-app/agent-config/commit/c501e557fdb94d7214555a3b53042a275b2dc923))
83
+ * **roadmap:** competitive-borrow plan (source-anonymous) ([9e3c692](https://github.com/event4u-app/agent-config/commit/9e3c692745170ad62b0f67d40afa8aad751e34dd))
84
+ * **roadmap:** close metadata-leanness, spawn tier-removal follow-up ([93d5361](https://github.com/event4u-app/agent-config/commit/93d5361d05d5ddef944d4931c6260e69464d8270))
85
+ * **adr:** ADR-092 defer command tier-alias removal (forcing-function) ([71d2630](https://github.com/event4u-app/agent-config/commit/71d26300d14c9b894dfef19ed6a6b3c996f5895f))
86
+ * **roadmap:** metadata & command-surface leanness plan + evidence ([b31d106](https://github.com/event4u-app/agent-config/commit/b31d1061f5816eb3a8aadd4bd154e76ee00d089a))
87
+ * **roadmap:** archive completed reaping-orphans fix plan ([c1ed447](https://github.com/event4u-app/agent-config/commit/c1ed4478f14c634c5fde5dbed224f72ae2c6eedb))
88
+ * record evidence-gated decisions, archive residuals roadmap ([3657e12](https://github.com/event4u-app/agent-config/commit/3657e12fbcacb4740b4d1d84309d7dea28cd3c58))
89
+
90
+ ### Refactoring
91
+
92
+ * **ai-council:** relocate config out of the repo to user-global ([17fb14a](https://github.com/event4u-app/agent-config/commit/17fb14a03736cb14f2f56861f194e5bfc00e80b9))
93
+ * **commands:** fold fix:pr-bot/developer-comments into fix:pr-comments ([4c1c1c8](https://github.com/event4u-app/agent-config/commit/4c1c1c8795d422e1ba8d5ae77409f43f3b8fb2e5))
94
+
95
+ ### Tests
96
+
97
+ * lower command-surface floor to 148 after fix:pr-* fold ([2b5e9ef](https://github.com/event4u-app/agent-config/commit/2b5e9ef7f6a8160aac6d2d26bb2876d7d8ed1427))
98
+ * **install:** lock the reaping-gap class against regression ([d7ca6d0](https://github.com/event4u-app/agent-config/commit/d7ca6d0f967672d02d0b367fcfa408f6d675a220))
99
+
100
+ ### CI
101
+
102
+ * **skill-lint:** also enforce rule tiers + guard the CI wiring ([6cde280](https://github.com/event4u-app/agent-config/commit/6cde2809c5ace248807236dee9634a590955795d))
103
+ * **skill-lint:** run lint-command-tiers on every PR ([2e123c6](https://github.com/event4u-app/agent-config/commit/2e123c696a6bf2047cbc4473a9555c51b8f33da8))
104
+
105
+ ### Chores
106
+
107
+ * **roadmaps:** complete + archive road-to-6.0.0-final-readiness (6.0.0) ([652294a](https://github.com/event4u-app/agent-config/commit/652294ad01ad48a2875ebd75953b82d06c350e56))
108
+ * **roadmaps:** archive completed memory-layer-cleanup roadmaps ([9380482](https://github.com/event4u-app/agent-config/commit/9380482cf512c73f0783ff7a2270793d5dca8b95))
109
+ * **memory:** regenerate pack manifest for shortened mine-session description ([14cec0e](https://github.com/event4u-app/agent-config/commit/14cec0ed0c6de254639e3727d7ad1f3a3147902e))
110
+ * **memory:** regenerate projections, catalogs, and dashboard ([78cc1a1](https://github.com/event4u-app/agent-config/commit/78cc1a1180f6eced4c60e0c408da1103d0621ab0))
111
+ * **roadmaps:** regenerate progress dashboard ([d0d2757](https://github.com/event4u-app/agent-config/commit/d0d2757e93026fab6f995732a130f126371e7978))
112
+ * **security:** archive road-to-security-pillar (Phases 1-3 shipped) ([ad5f552](https://github.com/event4u-app/agent-config/commit/ad5f55204bae429b960db40976c3dc40ea759f97))
113
+ * **security:** bump command-count messaging 148→149 (new /security-audit-config) ([5f5b79a](https://github.com/event4u-app/agent-config/commit/5f5b79a1d741b1565cfbc0aaf8c74aa43165fd0b))
114
+ * **security:** regenerate dist, router, counts, pack manifests ([84ff0fc](https://github.com/event4u-app/agent-config/commit/84ff0fcd1216fbbd05a3a340148f681b95c2d4a8))
115
+ * add uncomitted roadmaps ([699c2c5](https://github.com/event4u-app/agent-config/commit/699c2c5e8a70453a46b9c70e68ba621f96a5f64c))
116
+ * **condense:** reconcile stale condensation hashes ([d9ac27e](https://github.com/event4u-app/agent-config/commit/d9ac27e232cc60dba941f75632dde9a5bbd2c4db))
117
+ * add uncomitted roadmaps ([28ff06c](https://github.com/event4u-app/agent-config/commit/28ff06ce3741db46a5d39e1bc0a2a698d3a94c1f))
118
+ * **rules:** track anonymized harvest roadmaps; harden source-confidentiality ([bc77fb9](https://github.com/event4u-app/agent-config/commit/bc77fb93476c8045cd227f94ad09b0f1f3cebbdd))
119
+ * sync stale condensation for work / agents-init / agents-optimize ([0f816ca](https://github.com/event4u-app/agent-config/commit/0f816cae017824af718cd750457bfc1476252927))
120
+ * sync command-count messaging to 148 after fix:pr-* removal ([94097ce](https://github.com/event4u-app/agent-config/commit/94097ce0bee1739d2f54688705b1aaf78a73cee4))
121
+ * sync stale condensation hashes for unchanged command files ([a32da9a](https://github.com/event4u-app/agent-config/commit/a32da9a5c4199d1148549f63bf7c0012496cd2b6))
122
+ * remove external-source references from the tracked tree ([3248611](https://github.com/event4u-app/agent-config/commit/3248611a8ae2e7d0574ba8e121f85077faae9f69))
123
+ * **commands:** backfill visibility + re-tag pack across command sources ([d08f5b6](https://github.com/event4u-app/agent-config/commit/d08f5b6550735db22f4f855f155d2fd91a8dc047))
124
+ * **changelog:** split era 5.9.x → pre-6.0.0 ([c442750](https://github.com/event4u-app/agent-config/commit/c44275053c07352402e162d6accbe67f6d380010))
125
+
126
+ Tests: 6068
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event4u/agent-config",
3
- "version": "7.0.0",
3
+ "version": "7.0.2",
4
4
  "description": "Universal AI Agent OS — audited skills, governance rules, commands, and templates for AI coding tools (Claude Code, Cursor, Windsurf, Copilot).",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -126,6 +126,64 @@ export function current_era_body_size(lines: readonly string[] | null = null): n
126
126
  return next_era_line - current_idx - 1;
127
127
  }
128
128
 
129
+ /**
130
+ * Lines in the current era body EXCLUDING the newest (topmost) released
131
+ * version section.
132
+ *
133
+ * The drift cap bounds *accumulated prior* releases in the current era — the
134
+ * mechanism by which "growth forces an era split" (see
135
+ * `docs/contracts/CHANGELOG-conventions.md § Era splits`). The newest released
136
+ * section is exempt: a single release is allowed to be arbitrarily large and
137
+ * instead forces the split on the **next** bump, once it has become a prior
138
+ * entry. Without this exemption a single large catch-up release — e.g. a
139
+ * 376-commit bump whose `## [x.y.z]` section alone exceeds the cap — trips the
140
+ * gate with no era split that could ever bring it under, which is the exact
141
+ * failure this function fixes.
142
+ *
143
+ * Returns the same count as {@link current_era_body_size} when the era holds no
144
+ * released section yet (nothing to exempt).
145
+ */
146
+ export function current_era_accumulated_body_size(lines: readonly string[] | null = null): number {
147
+ const all = lines ?? read_changelog_lines();
148
+ const spans = era_spans(all);
149
+ const current_idx = current_era_index(spans);
150
+ if (current_idx === null) {
151
+ return 0;
152
+ }
153
+ let next_era_line = all.length;
154
+ for (const span of spans) {
155
+ if (span.line_index > current_idx) {
156
+ next_era_line = span.line_index;
157
+ break;
158
+ }
159
+ }
160
+ const total = next_era_line - current_idx - 1;
161
+ if (total <= 0) {
162
+ return total;
163
+ }
164
+ // Topmost (newest) version heading in the era body.
165
+ let first = -1;
166
+ for (let i = current_idx + 1; i < next_era_line; i++) {
167
+ if (VERSION_HEADING_RE.test(all[i]!)) {
168
+ first = i;
169
+ break;
170
+ }
171
+ }
172
+ if (first === -1) {
173
+ return total; // no released section yet → nothing to exempt
174
+ }
175
+ // The next version heading marks where accumulated prior releases begin.
176
+ let next_ver = next_era_line;
177
+ for (let i = first + 1; i < next_era_line; i++) {
178
+ if (VERSION_HEADING_RE.test(all[i]!)) {
179
+ next_ver = i;
180
+ break;
181
+ }
182
+ }
183
+ const newest_section = next_ver - first;
184
+ return Math.max(0, total - newest_section);
185
+ }
186
+
129
187
  /** Parse `M.N.x` into `[M, N]`; return null for archived labels. */
130
188
  export function parse_era_label(label: string): [number, number] | null {
131
189
  const m = ERA_LABEL_RE.exec(label.trim());
@@ -429,23 +429,58 @@ function tuple_lt(a: [number, number, number], b: [number, number, number]): boo
429
429
  return false;
430
430
  }
431
431
 
432
- /** Read `version` from the package's own `package.json`. */
433
- export function current_package_version(repo_root?: string | null): string {
434
- let root = repo_root ?? null;
435
- if (root === null) {
436
- // __file__ = src/scripts/_lib/installed_lock.ts → repo root is three
437
- // levels up (_lib → scripts → src → root), i.e. parents[3] in Python.
438
- const here = path.dirname(fileURLToPath(import.meta.url));
439
- root = path.resolve(here, "..", "..", "..");
440
- }
432
+ /** Read a string `version` from `<dir>/package.json`, or null if absent/malformed. */
433
+ function _read_package_version(dir: string): string | null {
441
434
  try {
442
- const data = JSON.parse(fs.readFileSync(path.join(root, "package.json"), { encoding: "utf-8" }));
435
+ const data = JSON.parse(fs.readFileSync(path.join(dir, "package.json"), { encoding: "utf-8" }));
443
436
  const version = (data as { version?: unknown }).version;
444
437
  if (typeof version === "string" && version.trim()) {
445
438
  return version.trim();
446
439
  }
447
440
  } catch {
448
- // Missing / unreadable / malformed package.json → fall through.
441
+ // Missing / unreadable / malformed package.json → null.
442
+ }
443
+ return null;
444
+ }
445
+
446
+ /**
447
+ * Walk upward from `start_dir` to the nearest `package.json` carrying a string
448
+ * `version`. Layout-independent: works in the source tree
449
+ * (`src/scripts/_lib/`), a per-file `dist/`, AND the esbuild single-file bundle
450
+ * (`dist/cli/agent-config.js`) where this module's runtime location differs
451
+ * from its source path. Returns null at the filesystem root.
452
+ */
453
+ export function _find_package_version_upward(start_dir: string): string | null {
454
+ let dir = start_dir;
455
+ for (;;) {
456
+ const found = _read_package_version(dir);
457
+ if (found !== null) {
458
+ return found;
459
+ }
460
+ const parent = path.dirname(dir);
461
+ if (parent === dir) {
462
+ return null; // reached the filesystem root
463
+ }
464
+ dir = parent;
465
+ }
466
+ }
467
+
468
+ /**
469
+ * Read `version` from the package's own `package.json`.
470
+ *
471
+ * With no `repo_root`, the version is resolved by walking **upward** from this
472
+ * module's runtime directory to the nearest `package.json`. A previous fixed
473
+ * `parents[3]` hop assumed the source layout (`src/scripts/_lib/`); in the
474
+ * shipped esbuild bundle the module runs from `dist/cli/`, so three hops
475
+ * overshot the package root → `package.json` not found → `"0.0.0"` → a
476
+ * spurious "downgrade" refusal on `agent-config global` (lockfile recorded a
477
+ * real version, current package read as `0.0.0`). The upward walk is correct
478
+ * in both layouts.
479
+ */
480
+ export function current_package_version(repo_root?: string | null): string {
481
+ if (repo_root != null) {
482
+ return _read_package_version(repo_root) ?? "0.0.0";
449
483
  }
450
- return "0.0.0";
484
+ const here = path.dirname(fileURLToPath(import.meta.url));
485
+ return _find_package_version_upward(here) ?? "0.0.0";
451
486
  }
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * RDP gate-time classification validation (road-to-rdp-frontier-polish Phase 1).
4
+ *
5
+ * The council's blocker on "keep-scoped" (2026-06-22): scoping the orchestrator
6
+ * to interdependent-multi-step work via agent self-assessment is only honest if
7
+ * the agent can classify a task AT GATE TIME — from the prompt alone, before
8
+ * doing the work. This script measures exactly that: the standard host classifies
9
+ * each labelled corpus prompt as multi-step vs single-turn, scored against the
10
+ * ground-truth `mechanism` label. High accuracy → the self-assessment gate is a
11
+ * real control, not vibes. Low accuracy → keep-scoped is not implementable.
12
+ *
13
+ * Direct Messages API via fetch (no SDK dep), reuses the key gate + cost
14
+ * estimate from skill_trigger_eval.ts. Dry-run by default; --confirm to spend
15
+ * (+ RDP_EVAL_ALLOW_NONTTY=1 on a non-tty caller that has confirmed cost).
16
+ *
17
+ * Usage: ./scripts-run src/scripts/rdp_gate_classify --corpus <file> --confirm
18
+ */
19
+ import * as fs from 'node:fs';
20
+ import { estimate_cost, load_anthropic_key } from './skill_trigger_eval.js';
21
+
22
+ /** stdout helper — the lint config forbids `console.log` (allows warn/error). */
23
+ const emit = (s: string): void => {
24
+ process.stdout.write(`${s}\n`);
25
+ };
26
+
27
+ const ANTHROPIC_URL = 'https://api.anthropic.com/v1/messages';
28
+ const ANTHROPIC_VERSION = '2023-06-01';
29
+
30
+ const GATE_SYSTEM = `You are an agent deciding, at the START of a task (before doing any work), whether
31
+ to engage a heavyweight multi-step reasoning orchestrator. You see ONLY the task
32
+ prompt. Classify the task into exactly one bucket using the rdp-gate criterion:
33
+
34
+ - "multi-step": interdependent multi-step work where the ordering and handoffs
35
+ between steps matter (e.g. schema → API → job → UI; a migration with stages; a
36
+ cross-cutting refactor). The orchestrator helps here.
37
+ - "single-turn": a single analytical or lookup question, a naming/explain/yes-no
38
+ ask, or a one-shot edit — work that does NOT decompose into ordered
39
+ interdependent steps. The orchestrator over-processes here.
40
+
41
+ Respond with STRICT JSON only: {"bucket":"multi-step"|"single-turn","confidence":"high"|"medium"|"low"}`;
42
+
43
+ interface Slot {
44
+ n: string;
45
+ slug: string;
46
+ mechanism?: string;
47
+ band: string;
48
+ prompt: string;
49
+ }
50
+
51
+ async function classify(apiKey: string, model: string, prompt: string): Promise<{ bucket: string; confidence: string } | null> {
52
+ const resp = await fetch(ANTHROPIC_URL, {
53
+ method: 'POST',
54
+ headers: {
55
+ 'x-api-key': apiKey,
56
+ 'anthropic-version': ANTHROPIC_VERSION,
57
+ 'content-type': 'application/json',
58
+ },
59
+ body: JSON.stringify({
60
+ model,
61
+ max_tokens: 60,
62
+ system: GATE_SYSTEM,
63
+ messages: [{ role: 'user', content: `Task prompt:\n${prompt}` }],
64
+ }),
65
+ });
66
+ if (!resp.ok) throw new Error(`API ${resp.status}: ${(await resp.text()).slice(0, 300)}`);
67
+ const data = (await resp.json()) as {
68
+ content?: Array<{ type?: string; text?: string }>;
69
+ usage?: { input_tokens?: number; output_tokens?: number };
70
+ };
71
+ const text = (data.content ?? []).filter((b) => b.type === 'text').map((b) => b.text ?? '').join('');
72
+ const m = text.match(/\{[\s\S]*\}/);
73
+ if (!m) return null;
74
+ try {
75
+ return JSON.parse(m[0]) as { bucket: string; confidence: string };
76
+ } catch {
77
+ return null;
78
+ }
79
+ }
80
+
81
+ function expectedBucket(mechanism: string | undefined): string {
82
+ return mechanism === 'multi-stage' ? 'multi-step' : 'single-turn';
83
+ }
84
+
85
+ async function main(): Promise<number> {
86
+ const argv = process.argv.slice(2);
87
+ const args: Record<string, string | boolean> = {};
88
+ for (let i = 0; i < argv.length; i++) {
89
+ const t = argv[i];
90
+ if (t === undefined) continue;
91
+ if (t === '--confirm') args.confirm = true;
92
+ else if (t.startsWith('--')) {
93
+ const next = argv[i + 1];
94
+ if (next && !next.startsWith('--')) { args[t.slice(2)] = next; i++; } else args[t.slice(2)] = true;
95
+ }
96
+ }
97
+ const corpusPath = (args.corpus as string) ?? '';
98
+ const model = (args.model as string) ?? 'claude-haiku-4-5-20251001';
99
+ if (!corpusPath) throw new Error('--corpus <file> required');
100
+ const slots = (JSON.parse(fs.readFileSync(corpusPath, 'utf-8')) as { slots: Slot[] }).slots;
101
+
102
+ const est = slots.reduce((p) => p + estimate_cost(model, 250, 60), 0);
103
+ emit(`rdp-gate-classify · ${slots.length} prompts · ${model} · ~$${est.toFixed(4)}`);
104
+ if (!args.confirm) {
105
+ emit('DRY-RUN — no spend. Re-run with --confirm.');
106
+ return 0;
107
+ }
108
+ if (!process.stdin.isTTY && process.env.RDP_EVAL_ALLOW_NONTTY !== '1') {
109
+ throw new Error('Non-tty: set RDP_EVAL_ALLOW_NONTTY=1 only after confirming cost.');
110
+ }
111
+ const apiKey = load_anthropic_key();
112
+ let correct = 0;
113
+ const rows: Array<Record<string, unknown>> = [];
114
+ for (const s of slots) {
115
+ const r = await classify(apiKey, model, s.prompt);
116
+ const exp = expectedBucket(s.mechanism);
117
+ const got = r?.bucket ?? 'parse-error';
118
+ const ok = got === exp;
119
+ if (ok) correct++;
120
+ console.error(` ${s.n} ${s.slug}: expected ${exp} · got ${got} (${r?.confidence ?? '-'}) ${ok ? 'OK' : 'MISS'}`);
121
+ rows.push({ slot: s.n, slug: s.slug, expected: exp, got, confidence: r?.confidence ?? null, ok });
122
+ }
123
+ const acc = Math.round((correct / slots.length) * 1000) / 10;
124
+ const out = (args.results as string) ?? '/tmp/rdp-gate-classify.json';
125
+ fs.writeFileSync(out, JSON.stringify({ model, n: slots.length, correct, accuracy_pct: acc, rows }, null, 2), 'utf-8');
126
+ emit(`\nGATE-TIME CLASSIFICATION ACCURACY: ${correct}/${slots.length} = ${acc}% (model ${model})`);
127
+ emit(`Results: ${out}`);
128
+ return 0;
129
+ }
130
+
131
+ main().then((c) => process.exit(c), (e) => { console.error(e instanceof Error ? e.message : String(e)); process.exit(1); });