@event4u/agent-config 8.6.0 → 8.7.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 (53) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +29 -0
  3. package/dist/agent-src/skills/skill-writing/SKILL.md +4 -0
  4. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  5. package/dist/discovery/deprecation-report.md +1 -1
  6. package/dist/discovery/discovery-manifest.json +3 -3
  7. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  8. package/dist/discovery/discovery-manifest.summary.md +1 -1
  9. package/dist/discovery/orphan-report.md +1 -1
  10. package/dist/discovery/packs.json +2 -2
  11. package/dist/discovery/trust-report.md +1 -1
  12. package/dist/discovery/workspaces.json +2 -2
  13. package/dist/install/emit_host_rules_cli.js +185 -0
  14. package/dist/install/emit_host_rules_cli.js.map +1 -0
  15. package/dist/install/install.mjs +6 -0
  16. package/dist/install/plan.js +4 -1
  17. package/dist/install/plan.js.map +1 -1
  18. package/dist/install/rule_scope.js +109 -0
  19. package/dist/install/rule_scope.js.map +1 -0
  20. package/dist/install/rule_scope_cli.js +77 -0
  21. package/dist/install/rule_scope_cli.js.map +1 -0
  22. package/dist/install/wizard-plan.js +14 -1
  23. package/dist/install/wizard-plan.js.map +1 -1
  24. package/dist/mcp/registry-manifest.json +1 -1
  25. package/dist/scripts/_lib/agent_settings.js +963 -0
  26. package/dist/scripts/_lib/agent_settings.js.map +1 -0
  27. package/dist/scripts/_lib/agent_src.js +607 -0
  28. package/dist/scripts/_lib/agent_src.js.map +1 -0
  29. package/dist/scripts/_lib/claude_settings_hooks.js +209 -0
  30. package/dist/scripts/_lib/claude_settings_hooks.js.map +1 -0
  31. package/dist/scripts/_lib/model_tier.js +64 -0
  32. package/dist/scripts/_lib/model_tier.js.map +1 -0
  33. package/dist/scripts/_lib/script_output.js +140 -0
  34. package/dist/scripts/_lib/script_output.js.map +1 -0
  35. package/dist/scripts/_lib/user_global_paths.js +297 -0
  36. package/dist/scripts/_lib/user_global_paths.js.map +1 -0
  37. package/dist/scripts/condense.js +2181 -0
  38. package/dist/scripts/condense.js.map +1 -0
  39. package/dist/server/routes/install.js +18 -2
  40. package/dist/server/routes/install.js.map +1 -1
  41. package/dist/server/schemas/settings.js +2 -0
  42. package/dist/server/schemas/settings.js.map +1 -1
  43. package/package.json +1 -1
  44. package/src/config/agent-settings.template.yml +4 -2
  45. package/src/install/emit_host_rules_cli.ts +190 -0
  46. package/src/install/plan.ts +11 -1
  47. package/src/install/rule_scope.ts +120 -0
  48. package/src/install/rule_scope_cli.ts +79 -0
  49. package/src/install/wizard-plan.ts +22 -1
  50. package/src/scripts/check_trigger_eval_presence.ts +171 -0
  51. package/src/scripts/install.sh +118 -4
  52. package/src/scripts/trigger_eval_grandfather.json +226 -0
  53. package/src/server/schemas/settings.ts +6 -0
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Bootstrap shim for the event4u agent-config suite. This plugin ships ONLY the dispatcher hooks plus one install-pointer skill — ALL content (skills, rules, commands) is installed via `npx -y @event4u/agent-config init`, which writes the file projection AND registers the same hooks in ~/.claude/settings.json. DEPRECATED as a content channel; kept so the marketplace listing stays discoverable and existing installs keep working hooks.",
9
- "version": "8.6.0",
9
+ "version": "8.7.0",
10
10
  "keywords": [
11
11
  "agent-config",
12
12
  "skills",
package/CHANGELOG.md CHANGED
@@ -989,6 +989,35 @@ our recommendation order, not its support status.
989
989
  > that forces a new era split (`# Era: 8.2.x`, etc.) — see
990
990
  > [`docs/contracts/CHANGELOG-conventions.md § Era splits`](docs/contracts/CHANGELOG-conventions.md).
991
991
 
992
+ ## [8.7.0](https://github.com/event4u-app/agent-config/compare/8.6.0...8.7.0) (2026-07-08)
993
+
994
+ ### Features
995
+
996
+ * **settings:** validate + surface projection.rule_workspaces/rule_packs ([a27bbf5](https://github.com/event4u-app/agent-config/commit/a27bbf53c7fca206176ed6ddd38b1ec5ee11e357))
997
+ * **install:** consumer Cursor/Windsurf get host-native rule surfaces ([8b68ff5](https://github.com/event4u-app/agent-config/commit/8b68ff58e9c240e41acce1f25faa51bc47f3564b))
998
+ * **install:** consumer rule scoping reaches both install pipelines ([88248e4](https://github.com/event4u-app/agent-config/commit/88248e4d39bd056db133021acc0cc2b0782e78cc))
999
+ * **ci:** trigger-eval presence ratchet with shrink-only grandfather allowlist ([d8f0c0d](https://github.com/event4u-app/agent-config/commit/d8f0c0dd04b3388205becf2cce30c6e0ea09197b))
1000
+
1001
+ ### Bug Fixes
1002
+
1003
+ * **ci:** install repo-root deps in the MCP deploy workflow ([9183c4e](https://github.com/event4u-app/agent-config/commit/9183c4e358e76b344058eb01d7f945f246a44828))
1004
+
1005
+ ### Documentation
1006
+
1007
+ * add frontier quality roadmaps ([bfa9315](https://github.com/event4u-app/agent-config/commit/bfa93157848bf13020a6cb3dcd06381c013fb035))
1008
+ * **skills:** skill-writing names the CI-enforced trigger-eval presence gate ([464722e](https://github.com/event4u-app/agent-config/commit/464722efe83243e3ae480411d59850dac92ca1ac))
1009
+
1010
+ ### Chores
1011
+
1012
+ * **roadmaps:** regenerate progress dashboard ([a8f4178](https://github.com/event4u-app/agent-config/commit/a8f4178a84ef8c66408afe3d5af195ce19ccf5d0))
1013
+ * **gitignore:** ignore Codex CLI interop output (.agents/, .codex/) ([8756d52](https://github.com/event4u-app/agent-config/commit/8756d5226e8760c72d6205e98b9822620d303418))
1014
+ * **dist:** rebuild install bundle after settings-schema extension ([44818d4](https://github.com/event4u-app/agent-config/commit/44818d4c8ad69ec545e99820e3292f0346bb2f20))
1015
+ * **roadmap:** close Phase 1b with pinned consumer-install evidence ([3a2455f](https://github.com/event4u-app/agent-config/commit/3a2455f236279390eb5a8cfe986e6b911493391c))
1016
+ * **condense:** refresh stale hash for commands/upstream-contribute ([c668370](https://github.com/event4u-app/agent-config/commit/c668370663bf7272932c33b5a7874dca4b08a9db))
1017
+ * **roadmaps:** composition-ratchet roadmap executed + archived; adoption roadmap sequenced next ([1bde2ea](https://github.com/event4u-app/agent-config/commit/1bde2ea00478bd1e46c4e9596c8c0cd5962b9ee1))
1018
+
1019
+ Tests: 6949 (+6 since 8.6.0)
1020
+
992
1021
  ## [8.6.0](https://github.com/event4u-app/agent-config/compare/8.5.0...8.6.0) (2026-07-08)
993
1022
 
994
1023
  ### Features
@@ -224,6 +224,10 @@ record it in the commit message (`Eval stub: deferred`). Peer examples
224
224
  for the expected format: `php-coder/evals/triggers.json`,
225
225
  `eloquent/evals/triggers.json`, `skill-writing/evals/triggers.json`.
226
226
 
227
+ Presence CI-enforced for new skills: `check_trigger_eval_presence` fails
228
+ any skill outside shrink-only grandfather allowlist lacking
229
+ `evals/triggers.json` — *skip* defers query quality, never the file.
230
+
227
231
  Rules / commands / guidelines do **not** get eval stubs — only skills
228
232
  route through the top-level catalogue.
229
233
 
@@ -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: "8.6.0"
42
+ agent_config_version: "8.7.0"
43
43
 
44
44
  # --- Project identity ---
45
45
  project:
@@ -1,6 +1,6 @@
1
1
  # Discovery — Deprecation Report
2
2
 
3
- - Generated: `2026-07-08T14:10:55Z`
3
+ - Generated: `2026-07-08T15:01:19Z`
4
4
  - Deprecated artefacts: **0**
5
5
 
6
6
  _None. Tree is clean._
@@ -11982,7 +11982,7 @@
11982
11982
  },
11983
11983
  {
11984
11984
  "category": "skill",
11985
- "checksum": "sha256:ce7bb5aa334783a058f320faf1dfb41aa70140d0a557be29d942ddc08898b239",
11985
+ "checksum": "sha256:87eaa14cd95565d3c642e6e5a3ba1e26ac3b0ee1904e05f92c28ea9512c5dbc6",
11986
11986
  "install": {
11987
11987
  "default": true,
11988
11988
  "removable": false
@@ -12769,7 +12769,7 @@
12769
12769
  "workspaces": []
12770
12770
  }
12771
12771
  ],
12772
- "checksum": "sha256:373d4519debcdb5a39c065b83e496247480fc44a91aeb6f495ba5024f2a7192b",
12772
+ "checksum": "sha256:9902bbcc7fac058b3506979d8233180ef0a52be98f42cec030433ee6781a5cf3",
12773
12773
  "deprecations": [
12774
12774
  {
12775
12775
  "key": "tier",
@@ -12912,7 +12912,7 @@
12912
12912
  "reason": "scaffold template for ticket-bundle tickets (ADR-101); carries no runtime frontmatter — emit-tickets fills it in per ticket"
12913
12913
  }
12914
12914
  ],
12915
- "generated_at": "2026-07-08T14:10:55Z",
12915
+ "generated_at": "2026-07-08T15:01:19Z",
12916
12916
  "packs": [
12917
12917
  {
12918
12918
  "artefact_count": 95,
@@ -1 +1 @@
1
- 01ac916a948ce2e4232ae06f46e3c626f31a3e328c66904dbfd61ef731a13b1c discovery-manifest.json
1
+ 589017598b9d0eab5bfa36b665f3a6d8407ee34a45aa61d913ae9172f71c3ab3 discovery-manifest.json
@@ -1,6 +1,6 @@
1
1
  # Discovery Manifest — Summary
2
2
 
3
- - Generated: `2026-07-08T14:10:55Z`
3
+ - Generated: `2026-07-08T15:01:19Z`
4
4
  - Scanner: `f36b5a348348`
5
5
  - Artefacts: **533**
6
6
  - Unassigned: **0**
@@ -1,6 +1,6 @@
1
1
  # Discovery — Orphan Report
2
2
 
3
- - Generated: `2026-07-08T14:10:55Z`
3
+ - Generated: `2026-07-08T15:01:19Z`
4
4
  - Orphan artefacts: **0**
5
5
 
6
6
  > An orphan is an artefact whose declared pack has no other members.
@@ -1,6 +1,6 @@
1
1
  {
2
- "checksum": "sha256:373d4519debcdb5a39c065b83e496247480fc44a91aeb6f495ba5024f2a7192b",
3
- "generated_at": "2026-07-08T14:10:55Z",
2
+ "checksum": "sha256:9902bbcc7fac058b3506979d8233180ef0a52be98f42cec030433ee6781a5cf3",
3
+ "generated_at": "2026-07-08T15:01:19Z",
4
4
  "packs": [
5
5
  {
6
6
  "always_on": false,
@@ -1,6 +1,6 @@
1
1
  # Discovery — Trust Report
2
2
 
3
- - Generated: `2026-07-08T14:10:55Z`
3
+ - Generated: `2026-07-08T15:01:19Z`
4
4
  - Workspaces tracked: **10**
5
5
  - Human-review-required artefacts: **3**
6
6
 
@@ -1,6 +1,6 @@
1
1
  {
2
- "checksum": "sha256:373d4519debcdb5a39c065b83e496247480fc44a91aeb6f495ba5024f2a7192b",
3
- "generated_at": "2026-07-08T14:10:55Z",
2
+ "checksum": "sha256:9902bbcc7fac058b3506979d8233180ef0a52be98f42cec030433ee6781a5cf3",
3
+ "generated_at": "2026-07-08T15:01:19Z",
4
4
  "scanner_version": "f36b5a348348",
5
5
  "workspaces": [
6
6
  {
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Consumer host-native rule emission
4
+ * (road-to-request-scoped-rule-load Phase 1b Step 3).
5
+ *
6
+ * Before this CLI, consumer Cursor got a symlink farm to raw `.md` (no
7
+ * `.mdc`, no auto-attach globs) and consumer `.windsurfrules` was built by
8
+ * a bash concatenator that STRIPPED all frontmatter — destroying the
9
+ * host-native trigger signal Phase 2 added to the projection path.
10
+ *
11
+ * ## Recorded decision — install-time emission, not dist artifacts
12
+ *
13
+ * Phase 1b Step 3 asked for one recorded choice: pre-built host artifacts
14
+ * in `dist/` vs emission at install time. Decision: INSTALL-TIME EMISSION,
15
+ * re-using the exported condense emitters (`_emit_cursor_mdc`,
16
+ * `_emit_windsurf_rule`, `strip_frontmatter`) verbatim. Rationale:
17
+ * - a new `dist/agent-src/hosts/` tree would cascade through the
18
+ * discovery manifest, artefact checksums, condensation hashes and the
19
+ * always-budget gates for what is derived data;
20
+ * - dist artifacts are scope-agnostic — install-time emission runs AFTER
21
+ * the Phase-1b rule filter, so scoped installs get scoped host files
22
+ * for free;
23
+ * - re-using the exported emitters keeps consumer output byte-identical
24
+ * to the maintainer projection (Pipeline B never drifts from A).
25
+ * The trade-off (node required at install time) matches the rule-scope
26
+ * resolver: no node → install.sh keeps its legacy fallback surfaces.
27
+ *
28
+ * Usage:
29
+ * emit_host_rules_cli.ts --rules-dir <installed rules dir>
30
+ * --project-root <consumer root>
31
+ * --tools cursor,windsurf
32
+ *
33
+ * Exit codes: 0 emitted · 2 usage error · 1 emission failure (caller falls
34
+ * back to the legacy surface).
35
+ */
36
+ import * as fs from 'node:fs';
37
+ import * as path from 'node:path';
38
+ import process from 'node:process';
39
+ import { fileURLToPath, pathToFileURL } from 'node:url';
40
+ import { _emit_cursor_mdc, _emit_windsurf_rule, strip_frontmatter, } from '../scripts/condense.js';
41
+ function _ruleFiles(rulesDir) {
42
+ return fs
43
+ .readdirSync(rulesDir)
44
+ .filter((n) => n.endsWith('.md'))
45
+ .sort()
46
+ .map((n) => path.join(rulesDir, n))
47
+ .filter((p) => {
48
+ try {
49
+ return fs.statSync(p).isFile();
50
+ }
51
+ catch {
52
+ return false;
53
+ }
54
+ });
55
+ }
56
+ /** Remove entries not in `valid` (mirror of condense's `_clean_modern_dir`). */
57
+ function _cleanDir(dir, valid) {
58
+ let entries;
59
+ try {
60
+ entries = fs.readdirSync(dir);
61
+ }
62
+ catch {
63
+ return;
64
+ }
65
+ for (const name of entries) {
66
+ if (name === 'README.md' || valid.has(name)) {
67
+ continue;
68
+ }
69
+ const full = path.join(dir, name);
70
+ try {
71
+ if (fs.lstatSync(full).isDirectory()) {
72
+ fs.rmSync(full, { recursive: true, force: true });
73
+ }
74
+ else {
75
+ fs.unlinkSync(full);
76
+ }
77
+ }
78
+ catch {
79
+ /* best-effort clean */
80
+ }
81
+ }
82
+ }
83
+ export function emitCursor(rulesDir, projectRoot) {
84
+ const targetDir = path.join(projectRoot, '.cursor', 'rules');
85
+ const files = _ruleFiles(rulesDir);
86
+ const valid = new Set();
87
+ for (const src of files) {
88
+ const name = `${path.basename(src, '.md')}.mdc`;
89
+ _emit_cursor_mdc(src, path.join(targetDir, name));
90
+ valid.add(name);
91
+ }
92
+ _cleanDir(targetDir, valid);
93
+ return files.length;
94
+ }
95
+ export function emitWindsurf(rulesDir, projectRoot) {
96
+ const perRuleDir = path.join(projectRoot, '.windsurf', 'rules');
97
+ const files = _ruleFiles(rulesDir);
98
+ const valid = new Set();
99
+ for (const src of files) {
100
+ const name = path.basename(src);
101
+ _emit_windsurf_rule(src, path.join(perRuleDir, name));
102
+ valid.add(name);
103
+ }
104
+ _cleanDir(perRuleDir, valid);
105
+ // Concatenated legacy surface — same format as the projection-path
106
+ // generator (condense.generate_windsurfrules), consumer-sourced header.
107
+ const parts = ['# Auto-generated from .augment/rules/ — do not edit directly\n'];
108
+ for (const src of files) {
109
+ const content = strip_frontmatter(fs.readFileSync(src, 'utf-8'));
110
+ parts.push(`---\n\n${content.trim()}\n`);
111
+ }
112
+ fs.writeFileSync(path.join(projectRoot, '.windsurfrules'), parts.join('\n') + '\n', 'utf-8');
113
+ return files.length;
114
+ }
115
+ export function main(argv = process.argv.slice(2)) {
116
+ let rulesDir = '';
117
+ let projectRoot = '';
118
+ let tools = [];
119
+ for (let i = 0; i < argv.length; i += 1) {
120
+ const arg = argv[i];
121
+ if (arg === '--rules-dir') {
122
+ rulesDir = argv[i + 1] ?? '';
123
+ i += 1;
124
+ }
125
+ else if (arg === '--project-root') {
126
+ projectRoot = argv[i + 1] ?? '';
127
+ i += 1;
128
+ }
129
+ else if (arg === '--tools') {
130
+ tools = (argv[i + 1] ?? '').split(',').filter((t) => t.length > 0);
131
+ i += 1;
132
+ }
133
+ else {
134
+ process.stderr.write(`emit_host_rules_cli: unknown argument: ${arg}\n`);
135
+ return 2;
136
+ }
137
+ }
138
+ if (rulesDir === '' || projectRoot === '' || tools.length === 0) {
139
+ process.stderr.write('usage: emit_host_rules_cli.ts --rules-dir <dir> --project-root <dir> --tools cursor,windsurf\n');
140
+ return 2;
141
+ }
142
+ if (!fs.existsSync(rulesDir)) {
143
+ process.stderr.write(`emit_host_rules_cli: rules dir not found: ${rulesDir}\n`);
144
+ return 1;
145
+ }
146
+ try {
147
+ for (const tool of tools) {
148
+ if (tool === 'cursor') {
149
+ const n = emitCursor(rulesDir, path.resolve(projectRoot));
150
+ process.stdout.write(`cursor: ${n} .mdc rule(s)\n`);
151
+ }
152
+ else if (tool === 'windsurf') {
153
+ const n = emitWindsurf(rulesDir, path.resolve(projectRoot));
154
+ process.stdout.write(`windsurf: ${n} rule(s) + .windsurfrules\n`);
155
+ }
156
+ else {
157
+ process.stderr.write(`emit_host_rules_cli: unknown tool: ${tool}\n`);
158
+ return 2;
159
+ }
160
+ }
161
+ return 0;
162
+ }
163
+ catch (e) {
164
+ process.stderr.write(`emit_host_rules_cli: emission failed: ${e instanceof Error ? e.message : String(e)}\n`);
165
+ return 1;
166
+ }
167
+ }
168
+ function _isCliEntry() {
169
+ if (process.argv[1] === undefined)
170
+ return false;
171
+ const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
172
+ if (import.meta.url === argvUrl)
173
+ return true;
174
+ try {
175
+ return (fs.realpathSync(fileURLToPath(import.meta.url)) ===
176
+ fs.realpathSync(path.resolve(process.argv[1])));
177
+ }
178
+ catch {
179
+ return false;
180
+ }
181
+ }
182
+ if (_isCliEntry()) {
183
+ process.exit(main());
184
+ }
185
+ //# sourceMappingURL=emit_host_rules_cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit_host_rules_cli.js","sourceRoot":"","sources":["../../src/install/emit_host_rules_cli.ts"],"names":[],"mappings":"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"}
@@ -13877,6 +13877,12 @@ var settingsSchema = external_exports.object({
13877
13877
  projection: external_exports.object({
13878
13878
  mode: projectionMode.default("legacy-all").describe(
13879
13879
  "Whether the per-tool projector writes EVERY artefact into the host-tool trees (.claude/ .cursor/ .windsurf/) or only the active profile + packs' artefacts (ADR-040, docs/contracts/capability-packs.md). legacy-all = (default, non-breaking) project the full surface exactly as 5.x did. scoped = project only the active profile's packs unioned with the runtime.active_packs overlay, expanded over the requires graph \u2014 opt in with `agent-config use --profile=<id>`. A failed scoped projection restores the full tree."
13880
+ ),
13881
+ rule_workspaces: external_exports.array(external_exports.string()).default([]).describe(
13882
+ "Workspace scope for the RULE layer only (road-to-request-scoped-rule-load P1/P1b, opt-in). Absent or empty = legacy-all: every rule projects AND installs. Non-empty = only rules whose workspaces frontmatter intersects this list are projected (condense) and installed (install.sh + global wizard payload). Kernel rules always ship; untagged rules fail safe. The default flip to a scoped value is a HUMAN release gate \u2014 do not set this from automation."
13883
+ ),
13884
+ rule_packs: external_exports.array(external_exports.string()).default([]).describe(
13885
+ "Optional second scoping axis for the RULE layer, per pack ids (src/config/discovery/packs.yml). When set, a non-kernel rule also needs a packs frontmatter intersection to ship \u2014 e.g. deselecting frontend-design drops ui-audit-gate + design-fidelity. Same opt-in / human-gate semantics as rule_workspaces."
13880
13886
  )
13881
13887
  }).default({ mode: "legacy-all" }),
13882
13888
  rule_loading_tier: ruleLoadingTier.default("balanced").describe(
@@ -103,7 +103,10 @@ export function buildInstallPlan(inputs) {
103
103
  const filesByTool = {};
104
104
  for (const source of inputs.sources) {
105
105
  const bucket = filesByTool[source.toolId] ?? [];
106
- const files = walkSourceTree(source.srcDir);
106
+ let files = walkSourceTree(source.srcDir);
107
+ if (source.fileFilter !== undefined) {
108
+ files = files.filter(source.fileFilter);
109
+ }
107
110
  for (const srcFile of files) {
108
111
  const rel = relative(source.srcDir, srcFile);
109
112
  const destPath = resolve(source.destDir, rel);
@@ -1 +1 @@
1
- {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/install/plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/install/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8CpD;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACnC,IAAI,CAAC;QACD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACrB,IAAY,EACZ,IAAc,EACd,OAAiC;IAEjC,OAAO;QACH,IAAI;QACJ,IAAI;QACJ,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;KACxD,CAAC;AACN,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACtC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACnB,OAAO,GAAG,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAE,GAAa;IACxC,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACD,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO;IACX,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7B,IAAI,KAAc,CAAC;QACnB,IAAI,CAAC;YACD,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACL,SAAS;QACb,CAAC;QACD,IAAI,KAAK,EAAE,CAAC;YACR,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACxB,CAAC;aAAM,CAAC;YACJ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACL,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAkB;IAC/C,MAAM,WAAW,GAAgC,EAAE,CAAC;IAEpD,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAChD,IAAI,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAClC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5C,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC7C,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAI,CACP,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE;gBAC5B,WAAW,EAAE,MAAM,CAAC,IAAI,KAAK,QAAQ;aACxC,CAAC,CACL,CAAC;YACF,0DAA0D;YAC1D,qDAAqD;YACrD,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG;gBACxB,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAE;gBAC7B,IAAI,EAAE,QAAQ;aACjB,CAAC;QACN,CAAC;QACD,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IACxC,CAAC;IAED,gEAAgE;IAChE,oEAAoE;IACpE,mDAAmD;IACnD,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAClC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,WAAW,CAAC,EAAE,CAAC;YAClC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACpC,CAAC;IACL,CAAC;IAED,OAAO;QACH,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,WAAW;QACX,gBAAgB,EAAE,EAAE;QACpB,MAAM,EAAE,MAAM,CAAC,MAAM;KACxB,CAAC;AACN,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,IAAiB;IACzC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QACpD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACzD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Install-time rule scoping — Pipeline B of consumer-scoped rule projection
3
+ * (road-to-request-scoped-rule-load Phase 1b).
4
+ *
5
+ * The projection filter (`rule_in_scope`, condense.ts) covered only the
6
+ * maintainer projection; the consumer install pipeline shipped rules
7
+ * unfiltered (dead `EXCLUDE_RULES` in install.sh; no exclude at all on the
8
+ * global payload). This module is the ONE scoping surface both install
9
+ * paths consume — it deliberately re-uses `rule_in_scope` so the install
10
+ * semantics can never drift from the projection semantics.
11
+ *
12
+ * ## The `source-of-truth.md` decision (Phase 1b Step 2 — recorded here)
13
+ *
14
+ * Before this module, `install.sh` excluded `source-of-truth.md` from
15
+ * PROJECT installs (hardcoded name) while the GLOBAL payload shipped it —
16
+ * the documented contradiction. Decision: the rule is excluded from BOTH
17
+ * consumer paths, always (even under legacy-all). Rationale: its Iron Law
18
+ * ("NEVER EDIT ANY GENERATED PROJECTION … ALWAYS WORK IN src/") describes
19
+ * THIS repository's build layout; in a consumer project there is no `src/`
20
+ * authoring tree and the installed files ARE the working surface — the rule
21
+ * is not merely useless there, it actively forbids legitimate consumer
22
+ * edits. Shipping it globally was the bug; project installs had it right.
23
+ * The compat list below is the pre-flip carrier of that decision; once the
24
+ * Phase-1 human gate flips consumer defaults to scoped, the rule drops out
25
+ * via its maintainer-only workspace tag and this list can retire.
26
+ */
27
+ import * as fs from 'node:fs';
28
+ import * as path from 'node:path';
29
+ import { rule_in_scope } from '../scripts/condense.js';
30
+ /**
31
+ * Rules excluded from EVERY consumer install path regardless of scope —
32
+ * same treatment on project and global (see module doc for the decision).
33
+ */
34
+ export const COMPAT_ALWAYS_EXCLUDED = ['source-of-truth.md'];
35
+ export const LEGACY_ALL = { workspaces: null, packs: null };
36
+ /** Non-empty string-array extraction; anything else → null (legacy-all). */
37
+ function _list(value) {
38
+ if (Array.isArray(value) && value.length > 0) {
39
+ return value.map((v) => String(v));
40
+ }
41
+ return null;
42
+ }
43
+ /**
44
+ * Extract `projection.rule_workspaces` / `projection.rule_packs` from an
45
+ * already-parsed settings object (same key contract as condense's
46
+ * `_read_projection_list` — absent / empty = legacy-all).
47
+ */
48
+ export function ruleScopeFromSettings(settings) {
49
+ const proj = settings['projection'];
50
+ if (typeof proj !== 'object' || proj === null || Array.isArray(proj)) {
51
+ return LEGACY_ALL;
52
+ }
53
+ const p = proj;
54
+ return {
55
+ workspaces: _list(p['rule_workspaces']),
56
+ packs: _list(p['rule_packs']),
57
+ };
58
+ }
59
+ /**
60
+ * Whether a rule FILE (path into the shipped `dist/agent-src/rules` tree)
61
+ * arrives in a consumer install under `scope`.
62
+ *
63
+ * Delegates the scoping decision to the projection-path predicate
64
+ * (`rule_in_scope` — kernel always ships, untagged axes fail safe) and adds
65
+ * the compat exclusion on top. Non-rule files (non-`.md`) always arrive.
66
+ */
67
+ export function ruleFileArrives(sourcePath, scope) {
68
+ if (!sourcePath.endsWith('.md')) {
69
+ return true;
70
+ }
71
+ const basename = path.basename(sourcePath);
72
+ if (COMPAT_ALWAYS_EXCLUDED.includes(basename)) {
73
+ return false;
74
+ }
75
+ return rule_in_scope(sourcePath, scope.workspaces, scope.packs);
76
+ }
77
+ /**
78
+ * Basenames from `rulesDir` that are EXCLUDED under `scope` — the shape the
79
+ * bash installer consumes (one basename per line via the CLI below).
80
+ */
81
+ export function excludedRuleBasenames(rulesDir, scope) {
82
+ let entries;
83
+ try {
84
+ entries = fs.readdirSync(rulesDir).sort();
85
+ }
86
+ catch {
87
+ return [];
88
+ }
89
+ const out = [];
90
+ for (const name of entries) {
91
+ if (!name.endsWith('.md')) {
92
+ continue;
93
+ }
94
+ const full = path.join(rulesDir, name);
95
+ try {
96
+ if (!fs.statSync(full).isFile()) {
97
+ continue;
98
+ }
99
+ }
100
+ catch {
101
+ continue;
102
+ }
103
+ if (!ruleFileArrives(full, scope)) {
104
+ out.push(name);
105
+ }
106
+ }
107
+ return out;
108
+ }
109
+ //# sourceMappingURL=rule_scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule_scope.js","sourceRoot":"","sources":["../../src/install/rule_scope.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * CLI twin surface of {@link module:install/rule_scope} for the bash
4
+ * installer (road-to-request-scoped-rule-load Phase 1b).
5
+ *
6
+ * Prints one EXCLUDED rule basename per line for the given rules source
7
+ * dir + consumer settings file. `install.sh` consumes this to replace its
8
+ * dead hardcoded `EXCLUDE_RULES` list; on any failure the caller falls back
9
+ * to the static compat exclusion (fail-safe: over-ship, never under-ship).
10
+ *
11
+ * Usage:
12
+ * rule_scope_cli.ts --rules-dir <dist/agent-src/rules> [--settings <file>]
13
+ *
14
+ * Exit codes: 0 ok (list on stdout, possibly empty) · 2 usage error.
15
+ */
16
+ import * as fs from 'node:fs';
17
+ import * as path from 'node:path';
18
+ import process from 'node:process';
19
+ import { fileURLToPath, pathToFileURL } from 'node:url';
20
+ import { load_agent_settings } from '../scripts/_lib/agent_settings.js';
21
+ import { excludedRuleBasenames, ruleScopeFromSettings, LEGACY_ALL } from './rule_scope.js';
22
+ export function main(argv = process.argv.slice(2)) {
23
+ let rulesDir = '';
24
+ let settingsFile = '';
25
+ for (let i = 0; i < argv.length; i += 1) {
26
+ const arg = argv[i];
27
+ if (arg === '--rules-dir') {
28
+ rulesDir = argv[i + 1] ?? '';
29
+ i += 1;
30
+ }
31
+ else if (arg === '--settings') {
32
+ settingsFile = argv[i + 1] ?? '';
33
+ i += 1;
34
+ }
35
+ else {
36
+ process.stderr.write(`rule_scope_cli: unknown argument: ${arg}\n`);
37
+ return 2;
38
+ }
39
+ }
40
+ if (rulesDir === '') {
41
+ process.stderr.write('usage: rule_scope_cli.ts --rules-dir <dir> [--settings <file>]\n');
42
+ return 2;
43
+ }
44
+ let scope = LEGACY_ALL;
45
+ if (settingsFile !== '' && fs.existsSync(settingsFile)) {
46
+ try {
47
+ const settings = load_agent_settings({ project_path: settingsFile });
48
+ scope = ruleScopeFromSettings(settings);
49
+ }
50
+ catch {
51
+ // Unreadable settings → legacy-all (fail-safe: over-ship).
52
+ scope = LEGACY_ALL;
53
+ }
54
+ }
55
+ for (const name of excludedRuleBasenames(path.resolve(rulesDir), scope)) {
56
+ process.stdout.write(`${name}\n`);
57
+ }
58
+ return 0;
59
+ }
60
+ function _isCliEntry() {
61
+ if (process.argv[1] === undefined)
62
+ return false;
63
+ const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
64
+ if (import.meta.url === argvUrl)
65
+ return true;
66
+ try {
67
+ return (fs.realpathSync(fileURLToPath(import.meta.url)) ===
68
+ fs.realpathSync(path.resolve(process.argv[1])));
69
+ }
70
+ catch {
71
+ return false;
72
+ }
73
+ }
74
+ if (_isCliEntry()) {
75
+ process.exit(main());
76
+ }
77
+ //# sourceMappingURL=rule_scope_cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule_scope_cli.js","sourceRoot":"","sources":["../../src/install/rule_scope_cli.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,7 @@
20
20
  import { homedir } from 'node:os';
21
21
  import { isAbsolute, join, resolve } from 'node:path';
22
22
  import { buildInstallPlan } from './plan.js';
23
+ import { ruleFileArrives, LEGACY_ALL } from './rule_scope.js';
23
24
  /**
24
25
  * Per-tool user-scope anchor directory, mirrored 1:1 from
25
26
  * `scripts/install.py:USER_SCOPE_PATHS`. Values may use `~` for the
@@ -157,6 +158,8 @@ export function expandAnchor(anchor, home) {
157
158
  */
158
159
  export function expandWizardSources(inputs) {
159
160
  const { toolIds, packageRoot, home } = inputs;
161
+ const scope = inputs.ruleScope ?? LEGACY_ALL;
162
+ const ruleFilter = (srcFile) => ruleFileArrives(srcFile, scope);
160
163
  const out = [];
161
164
  for (const toolId of toolIds) {
162
165
  const deploy = GLOBAL_DEPLOY_SOURCES[toolId];
@@ -167,7 +170,17 @@ export function expandWizardSources(inputs) {
167
170
  for (const [srcRel, destSub] of deploy) {
168
171
  const srcDir = join(packageRoot, srcRel);
169
172
  const destDir = destSub.length === 0 ? destRoot : join(destRoot, destSub);
170
- out.push({ toolId, srcDir, destDir, kind: 'deployed' });
173
+ // Rule sources get the install-time scoping filter — the same
174
+ // predicate the projection path uses (Phase 1b: Pipeline B may
175
+ // never drift from Pipeline A).
176
+ const isRuleSource = srcRel === 'dist/agent-src/rules';
177
+ out.push({
178
+ toolId,
179
+ srcDir,
180
+ destDir,
181
+ kind: 'deployed',
182
+ ...(isRuleSource ? { fileFilter: ruleFilter } : {}),
183
+ });
171
184
  }
172
185
  }
173
186
  return out;