@event4u/agent-config 9.17.0 → 9.18.1

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 (131) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +122 -171
  3. package/dist/agent-src/commands/challenge-me/vision.md +5 -0
  4. package/dist/agent-src/commands/evals/rule-compliance-audit.json +46 -0
  5. package/dist/agent-src/commands/feature/plan.md +20 -0
  6. package/dist/agent-src/commands/feature/roadmap.md +19 -0
  7. package/dist/agent-src/commands/pr/create.md +29 -0
  8. package/dist/agent-src/commands/roadmap/create.md +29 -0
  9. package/dist/agent-src/commands/rule-compliance-audit.md +28 -5
  10. package/dist/agent-src/contexts/execution/plan-confidence-gate.md +133 -0
  11. package/dist/agent-src/rules/active-remediation.md +2 -0
  12. package/dist/agent-src/rules/architecture.md +2 -0
  13. package/dist/agent-src/rules/augment-edit-discipline.md +2 -0
  14. package/dist/agent-src/rules/brand-consistency.md +10 -62
  15. package/dist/agent-src/rules/brand-source-of-truth.md +62 -11
  16. package/dist/agent-src/rules/broken-access-control.md +4 -0
  17. package/dist/agent-src/rules/cli-output-handling.md +5 -0
  18. package/dist/agent-src/rules/code-comment-discipline.md +3 -0
  19. package/dist/agent-src/rules/commit-conventions.md +2 -0
  20. package/dist/agent-src/rules/cross-source-consistency.md +3 -0
  21. package/dist/agent-src/rules/design-fidelity.md +2 -0
  22. package/dist/agent-src/rules/doc-screenshot-hygiene.md +2 -0
  23. package/dist/agent-src/rules/docker-commands.md +4 -0
  24. package/dist/agent-src/rules/domain-adoption-policy.md +2 -0
  25. package/dist/agent-src/rules/domain-safety-disclaimer.md +5 -2
  26. package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
  27. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +9 -0
  28. package/dist/agent-src/rules/image-likeness-and-rights.md +4 -0
  29. package/dist/agent-src/rules/improve-before-implement.md +4 -0
  30. package/dist/agent-src/rules/laravel-routing.md +4 -0
  31. package/dist/agent-src/rules/legal-safety-floor.md +3 -0
  32. package/dist/agent-src/rules/lethal-trifecta-guard.md +3 -0
  33. package/dist/agent-src/rules/media-governance-routing.md +5 -0
  34. package/dist/agent-src/rules/minimal-safe-diff.md +2 -0
  35. package/dist/agent-src/rules/no-roadmap-references.md +2 -0
  36. package/dist/agent-src/rules/notes-first-reasoning.md +2 -0
  37. package/dist/agent-src/rules/php-coding.md +2 -0
  38. package/dist/agent-src/rules/prefer-enums-over-literals.md +3 -0
  39. package/dist/agent-src/rules/provider-lifecycle-discipline.md +5 -0
  40. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +2 -0
  41. package/dist/agent-src/rules/roadmap-progress-sync.md +2 -0
  42. package/dist/agent-src/rules/rule-type-governance.md +2 -0
  43. package/dist/agent-src/rules/scale-discipline.md +3 -0
  44. package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
  45. package/dist/agent-src/rules/security-sensitive-stop.md +9 -2
  46. package/dist/agent-src/rules/senior-engineering-discipline.md +6 -0
  47. package/dist/agent-src/rules/skill-quality.md +2 -0
  48. package/dist/agent-src/rules/source-confidentiality.md +4 -0
  49. package/dist/agent-src/rules/source-discovery-gate.md +3 -0
  50. package/dist/agent-src/rules/source-of-truth.md +2 -0
  51. package/dist/agent-src/rules/strategy-safety-floor.md +2 -0
  52. package/dist/agent-src/rules/think-before-action.md +5 -0
  53. package/dist/agent-src/rules/ui-audit-gate.md +2 -0
  54. package/dist/agent-src/skills/design-intelligence/SKILL.md +6 -180
  55. package/dist/agent-src/skills/design-intelligence/references/context-and-registers.md +100 -0
  56. package/dist/agent-src/skills/design-intelligence/references/integration-mapping.md +91 -0
  57. package/dist/agent-src/skills/design-review/SKILL.md +4 -141
  58. package/dist/agent-src/skills/design-review/references/review-communication.md +92 -0
  59. package/dist/agent-src/skills/design-review/references/verification-automation.md +61 -0
  60. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +8 -27
  61. package/dist/agent-src/skills/existing-ui-audit/references/anti-slop-cross-reference.md +31 -0
  62. package/dist/agent-src/skills/fe-design/SKILL.md +4 -289
  63. package/dist/agent-src/skills/fe-design/references/design-patterns.md +227 -0
  64. package/dist/agent-src/skills/fe-design/references/design-read-and-memory.md +75 -0
  65. package/dist/agent-src/skills/roadmap-management/SKILL.md +10 -0
  66. package/dist/agent-src/skills/roadmap-writing/SKILL.md +12 -1
  67. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  68. package/dist/agent-src/templates/roadmaps.md +12 -0
  69. package/dist/agent-src/templates/scripts/work_engine/directives/ui/_fix_lane.ts +52 -0
  70. package/dist/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +8 -0
  71. package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.ts +6 -0
  72. package/dist/agent-src/templates/scripts/work_engine/intent/classify.ts +56 -4
  73. package/dist/cli/registry.js +2 -0
  74. package/dist/cli/registry.js.map +1 -1
  75. package/dist/cli-delegate/chunk-AIIUU73N.js +2040 -0
  76. package/dist/cli-delegate/{chunk-IMSXPRVH.js → chunk-ELMFOQPW.js} +11 -0
  77. package/dist/cli-delegate/chunk-LF2KKJ4Q.js +183 -0
  78. package/dist/cli-delegate/cmd_explain.js +36 -36
  79. package/dist/cli-delegate/cmd_export.js +1 -1
  80. package/dist/cli-delegate/cmd_handoff.js +203 -2228
  81. package/dist/cli-delegate/cmd_prune.js +1 -1
  82. package/dist/cli-delegate/cmd_route_audit.js +249 -0
  83. package/dist/cli-delegate/cmd_route_explain.js +285 -0
  84. package/dist/cli-delegate/cmd_settings_migrate.js +1 -1
  85. package/dist/cli-delegate/cmd_sync.js +1 -1
  86. package/dist/cli-delegate/cmd_uninstall.js +1 -1
  87. package/dist/cli-delegate/cmd_validate.js +1 -1
  88. package/dist/discovery/deprecation-report.md +1 -1
  89. package/dist/discovery/discovery-manifest.json +57 -57
  90. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  91. package/dist/discovery/discovery-manifest.summary.md +1 -1
  92. package/dist/discovery/orphan-report.md +1 -1
  93. package/dist/discovery/packs.json +2 -2
  94. package/dist/discovery/trust-report.md +1 -1
  95. package/dist/discovery/workspaces.json +2 -2
  96. package/dist/install/install.mjs +11 -0
  97. package/dist/mcp/registry-manifest.json +1 -1
  98. package/dist/mcp/server.json +2 -2
  99. package/dist/router.json +1 -1
  100. package/dist/server/schemas/settings.js +12 -0
  101. package/dist/server/schemas/settings.js.map +1 -1
  102. package/package.json +1 -1
  103. package/src/agent-src/templates/scripts/work_engine/directives/ui/_fix_lane.ts +52 -0
  104. package/src/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +8 -0
  105. package/src/agent-src/templates/scripts/work_engine/directives/ui/design.ts +6 -0
  106. package/src/agent-src/templates/scripts/work_engine/intent/classify.ts +56 -4
  107. package/src/config/agent-settings.template.yml +46 -0
  108. package/src/config/evaluator-budgets.json +3 -3
  109. package/src/config/gate-coverage.yml +44 -0
  110. package/src/scripts/_cli/cmd_explain.ts +41 -36
  111. package/src/scripts/_cli/cmd_route_audit.ts +290 -0
  112. package/src/scripts/_cli/cmd_route_explain.ts +269 -0
  113. package/src/scripts/_dispatch.bash +23 -0
  114. package/src/scripts/_lib/git_env.ts +40 -0
  115. package/src/scripts/_lib/md_table.ts +27 -0
  116. package/src/scripts/_lib/planning_settings.ts +43 -0
  117. package/src/scripts/_lib/release_highlights.ts +279 -0
  118. package/src/scripts/_lib/router_match.ts +301 -0
  119. package/src/scripts/annotate_r1_outcomes.ts +258 -0
  120. package/src/scripts/check_completion_review.ts +1322 -0
  121. package/src/scripts/check_release_highlights.ts +60 -152
  122. package/src/scripts/compile_router.ts +20 -3
  123. package/src/scripts/dispatch_r2_reviewer.ts +969 -0
  124. package/src/scripts/eval_ui_triviality.ts +156 -0
  125. package/src/scripts/lint_abstraction_thresholds.ts +3 -1
  126. package/src/scripts/lint_plan_risk_register.ts +931 -0
  127. package/src/scripts/lint_trigger_collisions.ts +257 -0
  128. package/src/scripts/release.ts +47 -13
  129. package/src/scripts/router_telemetry.ts +16 -290
  130. package/src/scripts/schemas/rule.schema.json +10 -0
  131. package/src/server/schemas/settings.ts +18 -0
@@ -0,0 +1,258 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Gate R1 outcome annotation helper (quarterly cadence — see
4
+ * docs/contracts/plan-review-gates.md § 7).
5
+ *
6
+ * Walks the `## Risk Register` sections of ARCHIVED roadmaps
7
+ * (agents/roadmaps/archive/*.md), and for every register row that has no
8
+ * recorded outcome yet, prompts the operator:
9
+ *
10
+ * helped — the mitigation prevented the risk (or materially reduced it)
11
+ * fired — the risk fired despite (or without) the mitigation
12
+ * unknown — cannot be judged (yet)
13
+ *
14
+ * Each answer appends one `r1_mitigation_outcome` event to the tracked
15
+ * metrics JSONL (agents/evidence/metrics/gate-metrics.jsonl) — ids +
16
+ * counters only, PII-free by construction. Already-annotated rows
17
+ * (same file + rank in the JSONL) are skipped, so re-runs are idempotent.
18
+ *
19
+ * Not a gate: no `scanned:` line, no gate-coverage entry. Exit 0 on
20
+ * completion (including nothing-to-annotate), 2 on internal error.
21
+ *
22
+ * Usage:
23
+ * ./scripts-run src/scripts/annotate_r1_outcomes # interactive
24
+ * ./scripts-run src/scripts/annotate_r1_outcomes --list # show pending only
25
+ */
26
+
27
+ import * as fs from 'node:fs';
28
+ import * as path from 'node:path';
29
+ import * as readline from 'node:readline';
30
+ import { fileURLToPath, pathToFileURL } from 'node:url';
31
+
32
+ import { splitMarkdownRow } from './_lib/md_table.js';
33
+
34
+ const ARCHIVE_DIR = 'agents/roadmaps/archive';
35
+ const METRICS_FILE = 'agents/evidence/metrics/gate-metrics.jsonl';
36
+ const OUTCOMES = new Set(['helped', 'fired', 'unknown']);
37
+
38
+ interface RegisterRow {
39
+ file: string;
40
+ rank: number;
41
+ item: string;
42
+ mitigation: string;
43
+ }
44
+
45
+ /** § 1.2 register columns: Rank | Item | Risk type | Description | Mitigation | Anchored under. */
46
+ const REGISTER_CELLS = 6;
47
+ const ITEM_CELL = 1;
48
+ const MITIGATION_CELL = 4;
49
+
50
+ export function extractRegisterRows(file: string, content: string): RegisterRow[] {
51
+ const rows: RegisterRow[] = [];
52
+ const lines = content.split(/\r?\n/);
53
+ let inRegister = false;
54
+ for (const line of lines) {
55
+ if (/^##\s+Risk Register\s*$/.test(line)) {
56
+ inRegister = true;
57
+ continue;
58
+ }
59
+ if (inRegister && /^##\s+/.test(line)) break;
60
+ if (!inRegister) continue;
61
+ if (!line.trim().startsWith('|')) continue;
62
+ // Escape-aware split, shared with both validators: a per-column
63
+ // `[^|]*` regex mis-aligns on a `\|` inside a cell — the shape the
64
+ // contract's own §1.2 example uses (`product \| implementation`) —
65
+ // and then records the Description as the mitigation.
66
+ const cells = splitMarkdownRow(line);
67
+ if (cells.length < REGISTER_CELLS) continue;
68
+ const rank = cells[0] ?? '';
69
+ if (!/^\d+$/.test(rank)) continue; // header / separator / prose row
70
+ rows.push({
71
+ file,
72
+ rank: Number(rank),
73
+ item: (cells[ITEM_CELL] ?? '').trim(),
74
+ mitigation: (cells[MITIGATION_CELL] ?? '').trim(),
75
+ });
76
+ }
77
+ return rows;
78
+ }
79
+
80
+ export function annotatedKeys(metricsText: string): Set<string> {
81
+ const keys = new Set<string>();
82
+ for (const line of metricsText.split('\n')) {
83
+ if (line.trim() === '') continue;
84
+ try {
85
+ const ev = JSON.parse(line) as { event?: string; file?: string; rank?: number };
86
+ if (ev.event === 'r1_mitigation_outcome' && ev.file !== undefined && ev.rank !== undefined) {
87
+ keys.add(`${ev.file}#${String(ev.rank)}`);
88
+ }
89
+ } catch {
90
+ // tolerate foreign lines — the JSONL is append-only and shared
91
+ }
92
+ }
93
+ return keys;
94
+ }
95
+
96
+ /**
97
+ * Ask one question. Resolves `null` on EOF instead of hanging or throwing:
98
+ * `rl.question`'s callback never fires once the stream ends, so a piped or
99
+ * scheduled invocation would otherwise block forever — and an interface that is
100
+ * ALREADY closed (the input ran out between two prompts) throws
101
+ * `ERR_USE_AFTER_CLOSE` from `question`, which is the same end-of-input state
102
+ * and must end the pass just as cleanly.
103
+ */
104
+ function ask(rl: readline.Interface, q: string): Promise<string | null> {
105
+ return new Promise((resolve) => {
106
+ if ((rl as { closed?: boolean }).closed === true) {
107
+ resolve(null);
108
+ return;
109
+ }
110
+ let settled = false;
111
+ const onClose = (): void => {
112
+ if (!settled) {
113
+ settled = true;
114
+ resolve(null);
115
+ }
116
+ };
117
+ rl.once('close', onClose);
118
+ try {
119
+ rl.question(q, (answer) => {
120
+ settled = true;
121
+ rl.removeListener('close', onClose);
122
+ resolve(answer);
123
+ });
124
+ } catch {
125
+ rl.removeListener('close', onClose);
126
+ if (!settled) {
127
+ settled = true;
128
+ resolve(null);
129
+ }
130
+ }
131
+ });
132
+ }
133
+
134
+ export interface AnnotateIo {
135
+ /**
136
+ * readline input; defaults to `process.stdin`.
137
+ *
138
+ * Injected by the tests to drive the EOF path deterministically — a
139
+ * caller-supplied stream is a deliberate non-TTY answer channel, so the
140
+ * TTY refusal below applies to `process.stdin` only.
141
+ */
142
+ input?: NodeJS.ReadableStream;
143
+ }
144
+
145
+ export async function main(argv?: readonly string[], io: AnnotateIo = {}): Promise<number> {
146
+ const args = argv ?? process.argv.slice(2);
147
+ const listOnly = args.includes('--list');
148
+
149
+ if (!fs.existsSync(ARCHIVE_DIR)) {
150
+ process.stdout.write(`No archive directory at ${ARCHIVE_DIR} — nothing to annotate.\n`);
151
+ return 0;
152
+ }
153
+
154
+ const files = fs
155
+ .readdirSync(ARCHIVE_DIR)
156
+ .filter((f) => f.endsWith('.md'))
157
+ .map((f) => path.join(ARCHIVE_DIR, f));
158
+
159
+ const metricsText = fs.existsSync(METRICS_FILE) ? fs.readFileSync(METRICS_FILE, 'utf8') : '';
160
+ const done = annotatedKeys(metricsText);
161
+
162
+ const pending: RegisterRow[] = [];
163
+ for (const f of files) {
164
+ const rows = extractRegisterRows(f, fs.readFileSync(f, 'utf8'));
165
+ for (const r of rows) {
166
+ if (!done.has(`${r.file}#${String(r.rank)}`)) pending.push(r);
167
+ }
168
+ }
169
+
170
+ if (pending.length === 0) {
171
+ process.stdout.write('✅ No un-annotated Risk-Register rows in archived roadmaps.\n');
172
+ return 0;
173
+ }
174
+
175
+ process.stdout.write(`${String(pending.length)} un-annotated mitigation(s) in archived roadmaps:\n`);
176
+ if (listOnly) {
177
+ for (const r of pending) {
178
+ process.stdout.write(` ${r.file} #${String(r.rank)} — ${r.item}\n`);
179
+ }
180
+ return 0;
181
+ }
182
+
183
+ // Interactive-only by construction: the annotation pass is a human quarterly
184
+ // cadence, so a non-TTY invocation is refused up front with the read-only
185
+ // alternative rather than left to block on a prompt nobody can answer.
186
+ if (io.input === undefined && process.stdin.isTTY !== true) {
187
+ process.stderr.write(
188
+ '❌ annotate_r1_outcomes needs an interactive terminal (stdin is not a TTY).\n' +
189
+ ' Use --list for the read-only pending inventory.\n',
190
+ );
191
+ return 2;
192
+ }
193
+
194
+ const rl = readline.createInterface({ input: io.input ?? process.stdin, output: process.stdout });
195
+ try {
196
+ for (const r of pending) {
197
+ process.stdout.write(`\n${r.file} #${String(r.rank)}\n risk: ${r.item}\n mitigation: ${r.mitigation}\n`);
198
+ let answer = '';
199
+ let eof = false;
200
+ while (!OUTCOMES.has(answer)) {
201
+ const raw = await ask(rl, ' outcome [helped/fired/unknown, s=skip]: ');
202
+ if (raw === null) {
203
+ eof = true;
204
+ break;
205
+ }
206
+ answer = raw.trim().toLowerCase();
207
+ if (answer === 's' || answer === 'skip') break;
208
+ }
209
+ if (eof) {
210
+ process.stdout.write('\n⚠️ stdin closed — ending the annotation pass early.\n');
211
+ break;
212
+ }
213
+ if (!OUTCOMES.has(answer)) continue;
214
+ const event = {
215
+ event: 'r1_mitigation_outcome',
216
+ date: new Date().toISOString().slice(0, 10),
217
+ file: r.file,
218
+ rank: r.rank,
219
+ outcome: answer,
220
+ };
221
+ // The metrics dir need not exist yet (a repo whose first recorded
222
+ // event is this one). Creating it here rather than letting
223
+ // `appendFileSync` throw matters because the throw would land AFTER
224
+ // the operator answered — an ENOENT crash that discards answers a
225
+ // human just typed. `recursive: true` is a no-op once it exists.
226
+ fs.mkdirSync(path.dirname(METRICS_FILE), { recursive: true });
227
+ fs.appendFileSync(METRICS_FILE, `${JSON.stringify(event)}\n`);
228
+ }
229
+ } finally {
230
+ rl.close();
231
+ }
232
+ process.stdout.write('\n✅ Annotation pass complete.\n');
233
+ return 0;
234
+ }
235
+
236
+ const _HERE = fileURLToPath(import.meta.url);
237
+ function _isCliEntry(): boolean {
238
+ if (process.argv[1] === undefined) return false;
239
+ const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
240
+ if (import.meta.url === argvUrl) return true;
241
+ try {
242
+ const here = fs.realpathSync(fileURLToPath(import.meta.url));
243
+ const argv1 = fs.realpathSync(path.resolve(process.argv[1]));
244
+ return here === argv1;
245
+ } catch {
246
+ return false;
247
+ }
248
+ }
249
+
250
+ if (_isCliEntry() || process.argv[1] === _HERE) {
251
+ main()
252
+ .then((code) => process.exit(code))
253
+ .catch((exc: unknown) => {
254
+ const msg = exc instanceof Error ? exc.message : String(exc);
255
+ process.stderr.write(`❌ Internal error: ${msg}\n`);
256
+ process.exit(2);
257
+ });
258
+ }