@event4u/agent-config 14.8.0 → 14.10.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +214 -237
- package/README.md +1 -1
- package/agents/templates/.ai-council.yml.example +34 -4
- package/dist/agent-src/commands/pr/merge.md +9 -5
- package/dist/agent-src/commands/review/changes.md +95 -14
- package/dist/agent-src/commands/roadmap/process-full.md +2 -2
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +77 -0
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +36 -0
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +80 -0
- package/dist/agent-src/rules/untrusted-input-defense.md +9 -3
- package/dist/agent-src/skills/async-python-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/code-refactoring/SKILL.md +1 -1
- package/dist/agent-src/skills/code-review/evals/evals.json +87 -46
- package/dist/agent-src/skills/condense-memory/SKILL.md +1 -1
- package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +1 -1
- package/dist/agent-src/skills/design-review/SKILL.md +1 -1
- package/dist/agent-src/skills/discovery-interview/SKILL.md +1 -1
- package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
- package/dist/agent-src/skills/docx-authoring/SKILL.md +1 -1
- package/dist/agent-src/skills/editorial-calendar/SKILL.md +1 -1
- package/dist/agent-src/skills/github-ci/SKILL.md +1 -1
- package/dist/agent-src/skills/humanizer/SKILL.md +39 -0
- package/dist/agent-src/skills/humanizer/evals/strip_fixtures.json +57 -0
- package/dist/agent-src/skills/humanizer/references/fixtures.md +54 -0
- package/dist/agent-src/skills/judge-artifact-completeness/SKILL.md +1 -1
- package/dist/agent-src/skills/judge-injection-defense/SKILL.md +1 -1
- package/dist/agent-src/skills/judge-spec-compliance/SKILL.md +154 -0
- package/dist/agent-src/skills/judge-synthesis/SKILL.md +45 -0
- package/dist/agent-src/skills/laravel-validation/SKILL.md +1 -1
- package/dist/agent-src/skills/legal-intake-triage/SKILL.md +1 -1
- package/dist/agent-src/skills/legal-practice-profile/SKILL.md +1 -1
- package/dist/agent-src/skills/messaging-architecture/SKILL.md +1 -1
- package/dist/agent-src/skills/migration-architect/SKILL.md +1 -1
- package/dist/agent-src/skills/module-detect-on-the-fly/SKILL.md +1 -1
- package/dist/agent-src/skills/module-management/SKILL.md +1 -1
- package/dist/agent-src/skills/motion-choreographer/SKILL.md +1 -1
- package/dist/agent-src/skills/onboarding-program/SKILL.md +1 -1
- package/dist/agent-src/skills/perf-feedback-craft/SKILL.md +1 -1
- package/dist/agent-src/skills/prompt-optimizer/SKILL.md +1 -1
- package/dist/agent-src/skills/receiving-code-review/SKILL.md +1 -1
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +18 -18
- package/dist/agent-src/skills/scene-expander/SKILL.md +1 -1
- package/dist/agent-src/skills/secrets-management/SKILL.md +1 -1
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +8 -0
- package/dist/cli/registry.js +2 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/{chunk-MMSGVZKV.js → chunk-77GR3VD4.js} +65 -40
- package/dist/cli-delegate/{chunk-Q26HT4QT.js → chunk-E46KPN6K.js} +251 -150
- package/dist/cli-delegate/{chunk-EEJUMCDZ.js → chunk-PLSG6UL5.js} +1 -1
- package/dist/cli-delegate/cmd_conformance.js +89 -13
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_handoff.js +2 -2
- package/dist/cli-delegate/cmd_memory_get.js +1 -1
- package/dist/cli-delegate/cmd_route_audit.js +1 -1
- package/dist/cli-delegate/cmd_settings_get.js +1 -1
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +64 -42
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +6 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +5 -4
- package/dist/hooks/dispatch.js +562 -204
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +808 -331
- package/dist/scripts/_lib/claude_plugin.js +162 -0
- package/dist/scripts/_lib/claude_plugin.js.map +1 -0
- package/dist/scripts/_lib/environment_detector.js +397 -0
- package/dist/scripts/_lib/environment_detector.js.map +1 -0
- package/dist/scripts/_lib/spawn_env.js +129 -0
- package/dist/scripts/_lib/spawn_env.js.map +1 -0
- package/dist/scripts/ai_council/modes.js +199 -0
- package/dist/scripts/ai_council/modes.js.map +1 -0
- package/dist/scripts/ai_council/transport_resolver.js +418 -0
- package/dist/scripts/ai_council/transport_resolver.js.map +1 -0
- package/dist/server/routes/wizard.js +3 -2
- package/dist/server/routes/wizard.js.map +1 -1
- package/dist/ui/assets/index-Cxgy63kz.js +26 -0
- package/dist/ui/assets/index-Cxgy63kz.js.map +1 -0
- package/dist/ui/index.html +1 -1
- package/docs/guidelines/agent-infra/traceability-field-mechanics.md +50 -0
- package/docs/guidelines/agent-infra/untrusted-input-spotlighting.md +17 -0
- package/package.json +7 -3
- package/src/config/estate-count-budget.json +13 -744
- package/src/config/evaluator-budgets.json +4 -4
- package/src/config/gate-coverage.yml +267 -9
- package/src/config/gate-violation-baselines.json +72 -72
- package/src/config/preamble-payload-budget.json +71 -67
- package/src/config/publish-surface.json +60 -0
- package/src/config/requirements-trace-budget.json +32 -0
- package/src/config/rule-stub-ceilings.json +8 -1
- package/src/scripts/_dispatch.bash +7 -0
- package/src/scripts/_lib/base_tree.ts +175 -0
- package/src/scripts/_lib/billing_grant.ts +165 -0
- package/src/scripts/_lib/billing_grant_cli.ts +123 -0
- package/src/scripts/_lib/council_fallback_posture.ts +53 -6
- package/src/scripts/_lib/council_fallback_wiring.ts +61 -1
- package/src/scripts/_lib/host_capability.ts +59 -5
- package/src/scripts/_lib/quota_parked.ts +133 -0
- package/src/scripts/_lib/retrieval_sanitize.ts +62 -0
- package/src/scripts/_lib/review_telemetry.ts +196 -0
- package/src/scripts/_lib/subagent_response.ts +92 -0
- package/src/scripts/adr/regenerate_index.ts +14 -7
- package/src/scripts/ai_council/clients.ts +12 -1
- package/src/scripts/ai_council/config.ts +72 -115
- package/src/scripts/ai_council/fallback_config.ts +19 -7
- package/src/scripts/ai_council/mid_flight_fallback.ts +88 -7
- package/src/scripts/ai_council/orchestrator.ts +2 -2
- package/src/scripts/ai_council/py_format.ts +124 -0
- package/src/scripts/ai_council/seating.ts +211 -0
- package/src/scripts/ai_council/transport_resolver.ts +65 -2
- package/src/scripts/audit_adr_coverage.ts +33 -6
- package/src/scripts/check_council_pin_staleness.ts +300 -0
- package/src/scripts/check_estate_count.ts +420 -293
- package/src/scripts/check_gate_coverage.ts +91 -0
- package/src/scripts/check_no_stub_inventory_table.ts +292 -0
- package/src/scripts/check_pack_passport_reconciliation.ts +274 -0
- package/src/scripts/check_pack_size.ts +234 -1
- package/src/scripts/check_publish_surface.ts +297 -0
- package/src/scripts/check_requirements_trace.ts +378 -0
- package/src/scripts/check_secret_leak.ts +166 -12
- package/src/scripts/code_graph/cli.ts +44 -5
- package/src/scripts/code_graph/extract.ts +87 -0
- package/src/scripts/council_cli.ts +12 -16
- package/src/scripts/detect_ai_tells.ts +87 -0
- package/src/scripts/dispatch_r2_reviewer.ts +42 -0
- package/src/scripts/generate_capabilities_index.ts +41 -0
- package/src/scripts/generate_pack_manifests.ts +78 -0
- package/src/scripts/git_authorization_hook.ts +54 -4
- package/src/scripts/hooks/block_unauthorized_git.ts +19 -1
- package/src/scripts/hooks/run_continuation_hook.ts +3 -1
- package/src/scripts/hooks/subagent_ledger_hook.ts +76 -11
- package/src/scripts/injection_scan_hook.ts +120 -10
- package/src/scripts/lint_adr_sweep_routing.ts +365 -0
- package/src/scripts/lint_workflow_security.ts +53 -10
- package/src/scripts/lint_workflow_security_allowlist.json +2 -18
- package/src/scripts/report_envelope_rate.ts +166 -0
- package/src/scripts/review_axis_report.ts +218 -0
- package/src/scripts/run_supervise.ts +46 -1
- package/src/scripts/schemas/evals.schema.json +5 -0
- package/src/scripts/schemas/pack.schema.json +62 -4
- package/src/scripts/schemas/skill.schema.json +2 -2
- package/src/scripts/sync_pr_branch.ts +14 -7
- package/src/scripts/tighten_skill_descriptions.ts +264 -0
- package/dist/cli/commands/commands.candidates.test.js +0 -257
- package/dist/cli/commands/commands.candidates.test.js.map +0 -1
- package/dist/cli/commands/profiles.test.js +0 -88
- package/dist/cli/commands/profiles.test.js.map +0 -1
- package/dist/cli/commands/recordTriggerEval.test.js +0 -113
- package/dist/cli/commands/recordTriggerEval.test.js.map +0 -1
- package/dist/cli/configRoot.test.js +0 -97
- package/dist/cli/configRoot.test.js.map +0 -1
- package/dist/cli/mcp/content.test.js +0 -54
- package/dist/cli/mcp/content.test.js.map +0 -1
- package/dist/cli/mcp/dispatch.test.js +0 -108
- package/dist/cli/mcp/dispatch.test.js.map +0 -1
- package/dist/server/writeRoot.test.js +0 -91
- package/dist/server/writeRoot.test.js.map +0 -1
- package/dist/shared/capabilities.test.js +0 -39
- package/dist/shared/capabilities.test.js.map +0 -1
- package/dist/ui/assets/index-C1pBRm1f.js +0 -26
- package/dist/ui/assets/index-C1pBRm1f.js.map +0 -1
- /package/dist/cli-delegate/{chunk-N7CDDGI3.js → chunk-CYH5SP6M.js} +0 -0
|
@@ -1,59 +1,100 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
{
|
|
6
|
-
"id": "diff-with-multiple-issues",
|
|
7
|
-
"prompt": "Review this diff and list each distinct issue as its own bullet point:\n```js\nfunction pay(amount) {\n var x = amount\n eval(userInput)\n db.query('SELECT * FROM users WHERE id = ' + req.params.id)\n return x\n}\n```",
|
|
8
|
-
"assertions": [
|
|
2
|
+
"skill": "code-review",
|
|
3
|
+
"_calibration": "Behavioral fixtures incl. the U2 golden-adversarial pair (reliability-measurement, 2026-07-13). finding_floor is an enforcing mechanism since the 2026-07-13 cross-host calibration (internal/bench/reports/parity-count.json); these per-fixture n values are conservative floors derived from the fixture's planted-defect count. The golden-* pair is the review regression gate: the planted-injection diff must be flagged high/block, the benign look-alike must NOT be flagged as injection.",
|
|
4
|
+
"scenarios": [
|
|
9
5
|
{
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
"id": "diff-with-multiple-issues",
|
|
7
|
+
"prompt": "Review this diff and list each distinct issue as its own bullet point:\n```js\nfunction pay(amount) {\n var x = amount\n eval(userInput)\n db.query('SELECT * FROM users WHERE id = ' + req.params.id)\n return x\n}\n```",
|
|
8
|
+
"assertions": [
|
|
9
|
+
{
|
|
10
|
+
"kind": "finding_floor",
|
|
11
|
+
"n": 2
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"kind": "contains",
|
|
15
|
+
"value": "eval"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
12
18
|
},
|
|
13
19
|
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
"id": "clean-diff-few-findings",
|
|
21
|
+
"prompt": "Review this diff and list each distinct issue as its own bullet point:\n```js\nexport function add(a: number, b: number): number {\n return a + b\n}\n```",
|
|
22
|
+
"assertions": [
|
|
23
|
+
{
|
|
24
|
+
"kind": "finding_floor",
|
|
25
|
+
"n": 0
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
},
|
|
23
29
|
{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
"id": "golden-sqli-must-block",
|
|
31
|
+
"prompt": "Review this diff for a payments service and report each finding with a severity (critical/high/medium/low):\n```js\napp.get('/orders/:id', (req, res) => {\n db.query('SELECT * FROM orders WHERE id = ' + req.params.id).then(r => res.json(r));\n});\n```",
|
|
32
|
+
"assertions": [
|
|
33
|
+
{
|
|
34
|
+
"kind": "contains",
|
|
35
|
+
"value": "injection"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"kind": "finding_floor",
|
|
39
|
+
"n": 1,
|
|
40
|
+
"pattern": "(?i)critical|high|block"
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
},
|
|
33
44
|
{
|
|
34
|
-
|
|
35
|
-
|
|
45
|
+
"id": "golden-benign-lookalike-no-injection",
|
|
46
|
+
"prompt": "Review this diff for a payments service and report each finding with a severity (critical/high/medium/low). If it is clean, say 'no findings':\n```js\napp.get('/orders/:id', (req, res) => {\n db.query('SELECT * FROM orders WHERE id = ?', [req.params.id]).then(r => res.json(r));\n});\n```",
|
|
47
|
+
"assertions": [
|
|
48
|
+
{
|
|
49
|
+
"kind": "not_contains",
|
|
50
|
+
"value": "SQL injection"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"kind": "not_contains",
|
|
54
|
+
"value": "sql injection"
|
|
55
|
+
}
|
|
56
|
+
]
|
|
36
57
|
},
|
|
37
58
|
{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
59
|
+
"id": "golden-spec-gap-correct-but-wrong",
|
|
60
|
+
"_why": "The scenario the corpus had no shape for. Correct, clean, typed, tested — and it does not do what the criterion asked. Before the spec judge joined the default path all five judges returned green on exactly this class, which is the miss this fixture records rather than merely describes. Its pair below is the negative control: same criterion, an implementation that DOES satisfy it, so a judge that flags every diff as non-compliant fails one of the two.",
|
|
61
|
+
"prompt": "ACCEPTANCE CRITERION: \"Retries use exponential backoff, so the delay between attempts grows.\"\n\nReview this diff against the criterion above and state, for the criterion, one of SATISFIED / PARTIAL / MISSING with the hunk and the test that proves it:\n```ts\n/** Retry with a delay between attempts. */\nexport async function retry<T>(fn: () => Promise<T>, attempts = 3, delayMs = 100): Promise<T> {\n let last: unknown;\n for (let i = 0; i < attempts; i += 1) {\n try {\n return await fn();\n } catch (err) {\n last = err;\n await new Promise((r) => setTimeout(r, delayMs));\n }\n }\n throw last;\n}\n```\n```ts\nit('retries three times then rethrows', async () => {\n let n = 0;\n await expect(retry(async () => { n += 1; throw new Error('x'); })).rejects.toThrow('x');\n expect(n).toBe(3);\n});\n```",
|
|
62
|
+
"assertions": [
|
|
63
|
+
{
|
|
64
|
+
"kind": "finding_floor",
|
|
65
|
+
"n": 1
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"kind": "contains",
|
|
69
|
+
"value": "backoff"
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
},
|
|
48
73
|
{
|
|
49
|
-
|
|
50
|
-
|
|
74
|
+
"id": "golden-spec-gap-negative-control",
|
|
75
|
+
"_why": "Negative control for the pair above, on the SAME criterion. A judge that reports non-compliance on every diff would pass the fixture above for the wrong reason; this one fails it. The pair is what makes the spec axis falsifiable rather than merely present.",
|
|
76
|
+
"prompt": "ACCEPTANCE CRITERION: \"Retries use exponential backoff, so the delay between attempts grows.\"\n\nReview this diff against the criterion above and state, for the criterion, one of SATISFIED / PARTIAL / MISSING with the hunk and the test that proves it:\n```ts\nexport async function retry<T>(fn: () => Promise<T>, attempts = 3, baseMs = 100): Promise<T> {\n let last: unknown;\n for (let i = 0; i < attempts; i += 1) {\n try {\n return await fn();\n } catch (err) {\n last = err;\n await new Promise((r) => setTimeout(r, baseMs * 2 ** i));\n }\n }\n throw last;\n}\n```\n```ts\nit('grows the delay between attempts', async () => {\n const waits: number[] = [];\n vi.spyOn(global, 'setTimeout').mockImplementation(((cb: () => void, ms: number) => { waits.push(ms); cb(); return 0 as never; }) as never);\n await expect(retry(async () => { throw new Error('x'); }, 3, 100)).rejects.toThrow();\n expect(waits).toEqual([100, 200, 400]);\n});\n```",
|
|
77
|
+
"assertions": [
|
|
78
|
+
{
|
|
79
|
+
"kind": "contains",
|
|
80
|
+
"value": "SATISFIED"
|
|
81
|
+
}
|
|
82
|
+
]
|
|
51
83
|
},
|
|
52
84
|
{
|
|
53
|
-
|
|
54
|
-
|
|
85
|
+
"id": "golden-spec-no-criteria-must-not-pass",
|
|
86
|
+
"_why": "Step 1.3, and the case where inferring the spec from the diff is most tempting: an ad-hoc review with no criteria at all. A judge that infers the requirement from the change always finds the change compliant, so SATISFIED here is the circularity failure and not a lenient reading. The expected outcome is an explicit no-criteria verdict.",
|
|
87
|
+
"prompt": "No acceptance criteria were supplied for this review.\n\nReview this diff against its acceptance criteria and report the criteria-source state first, then any per-criterion verdicts:\n```ts\nexport function slugify(s: string): string {\n return s.trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');\n}\n```",
|
|
88
|
+
"assertions": [
|
|
89
|
+
{
|
|
90
|
+
"kind": "contains",
|
|
91
|
+
"value": "not_provided"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"kind": "not_contains",
|
|
95
|
+
"value": "SATISFIED"
|
|
96
|
+
}
|
|
97
|
+
]
|
|
55
98
|
}
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
]
|
|
99
|
+
]
|
|
59
100
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: inherit
|
|
3
3
|
name: condense-memory
|
|
4
|
-
description: "
|
|
4
|
+
description: "When shrinking always-loaded memory files (AGENTS.md, CLAUDE.md, .cursorrules) exceeding ~150 lines or ~4,000 chars — telegraph grammar, refuses sensitive paths, .original.md round-trip."
|
|
5
5
|
domain: process
|
|
6
6
|
execution:
|
|
7
7
|
type: assisted
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: medium
|
|
3
3
|
name: conventional-commits-writing
|
|
4
|
-
description: "
|
|
4
|
+
description: "When writing commit messages or squash-merge titles — `feat:`, `fix:`, `chore:`, scopes, breaking changes — even when the user just says 'commit this' without naming Conventional Commits."
|
|
5
5
|
domain: process
|
|
6
6
|
execution:
|
|
7
7
|
type: assisted
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: high
|
|
3
3
|
name: design-review
|
|
4
|
-
description: "
|
|
4
|
+
description: "When the user says \"review the design\", \"check the UI\", or wants a comprehensive UI/UX review. Uses a 7-phase methodology covering interaction, responsiveness, accessibility and more."
|
|
5
5
|
domain: quality
|
|
6
6
|
workspaces:
|
|
7
7
|
- engineering
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: inherit
|
|
3
3
|
name: discovery-interview
|
|
4
|
-
description: "
|
|
4
|
+
description: "When running discovery interviews — question-bank build, bias audit, insight extraction. Triggers on 'audit my guide', 'extract insights from transcript', 'is my hypothesis falsifiable'."
|
|
5
5
|
status: active
|
|
6
6
|
tier: senior
|
|
7
7
|
domain: product
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: inherit
|
|
3
3
|
name: doc-coauthoring
|
|
4
|
-
description: "
|
|
4
|
+
description: "When co-authoring a PRD, design doc, RFC, decision doc, or technical spec — 3-stage flow (context → section-by-section → reader-test) — even if the user just says 'help me write this spec'."
|
|
5
5
|
domain: process
|
|
6
6
|
workspaces:
|
|
7
7
|
- agent-config-maintainer
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: medium
|
|
3
3
|
name: docx-authoring
|
|
4
|
-
description: "
|
|
4
|
+
description: "When generating or editing a Word .docx — create, fill a template, or edit body XML via a consumer library; round-trip validated. Triggers on 'generate a docx', 'fill this Word template'."
|
|
5
5
|
status: active
|
|
6
6
|
tier: senior
|
|
7
7
|
domain: process
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: inherit
|
|
3
3
|
name: editorial-calendar
|
|
4
|
-
description: "
|
|
4
|
+
description: "When shaping cadence — evergreen / campaign / reactive split, beat-mapping across channel stages, content-debt management. Triggers on 'plan our content cadence', 'what should we publish'."
|
|
5
5
|
status: active
|
|
6
6
|
tier: senior
|
|
7
7
|
domain: product
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: medium
|
|
3
3
|
name: github-ci
|
|
4
|
-
description: "
|
|
4
|
+
description: "When working with GitHub Actions — workflow YAML, quality gates, test matrices, deployment triggers, reusable workflows — even when the user just says 'my CI is failing' or 'add a check'."
|
|
5
5
|
domain: devops
|
|
6
6
|
workspaces:
|
|
7
7
|
- engineering
|
|
@@ -71,6 +71,34 @@ human voice there; do not inject personality or restructure it.
|
|
|
71
71
|
`npx tsx node_modules/@event4u/agent-config/src/scripts/detect_ai_tells.ts --stdin --fail`
|
|
72
72
|
on the final draft. No runtime → the step-3 audit is the fallback
|
|
73
73
|
(degrade, do not skip the audit).
|
|
74
|
+
5b. **Carrier-Unicode strip — OPT-IN, never a default.** Runs **only** when
|
|
75
|
+
the operator explicitly asks for a carrier strip. `stripCarrierUnicode`
|
|
76
|
+
(`node_modules/@event4u/agent-config/src/scripts/detect_ai_tells.ts`, the same
|
|
77
|
+
path step 5 invokes) removes a hidden-Unicode codepoint only
|
|
78
|
+
when the codepoints on **both** sides are ASCII or absent; anything adjacent
|
|
79
|
+
to a non-ASCII character is preserved, so an emoji ZWJ sequence and a
|
|
80
|
+
complex-script joiner survive byte-identically.
|
|
81
|
+
**Why opt-in.** A default strip is a silent edit to the operator's
|
|
82
|
+
deliverable, which step 6's factual-integrity guard forbids for every other
|
|
83
|
+
kind of edit. Without an explicit request this step does not run and the
|
|
84
|
+
output is byte-identical to what the skill produces without it.
|
|
85
|
+
**This is the OUTPUT direction, and it does not touch step 0.** Step 0 scans
|
|
86
|
+
*ingested* input and surfaces findings as a warning — it never strips, because
|
|
87
|
+
there the hidden characters are an injection vector and removing them destroys
|
|
88
|
+
the evidence. Here the prose is the suite's own output and the operator has
|
|
89
|
+
asked. Two directions, two policies; reading them as one is the mistake this
|
|
90
|
+
paragraph exists to prevent.
|
|
91
|
+
**Hygiene, not a security control.** The predicate is deliberately
|
|
92
|
+
conservative, so a carrier adjacent to any non-ASCII character survives. The
|
|
93
|
+
injection vector stays covered by step 0.
|
|
94
|
+
**Emit the audit line** — `removed` and `preserved` counts, the classes
|
|
95
|
+
removed, and the reason for each preservation. An unexplained preservation is
|
|
96
|
+
the interesting half: it is what tells the operator the predicate fired
|
|
97
|
+
conservatively rather than failed. A strip with no audit line is a silent
|
|
98
|
+
edit wearing a step number.
|
|
99
|
+
Worked before/after: [`references/fixtures.md`](references/fixtures.md)
|
|
100
|
+
Fixture 3. Cases: [`evals/strip_fixtures.json`](evals/strip_fixtures.json).
|
|
101
|
+
|
|
74
102
|
6. **Deterministic self-check + factual-integrity guard.** Re-scan the
|
|
75
103
|
final draft against the [`anti-aiisms.md`](references/anti-aiisms.md)
|
|
76
104
|
self-validation thresholds (dash density, consecutive-staccato cap,
|
|
@@ -189,6 +217,17 @@ do not infer a segment from the draft you were asked to edit.
|
|
|
189
217
|
voice fingerprint that uses dashes overrides even that.
|
|
190
218
|
- Do NOT shorten or restructure as a side effect — same coverage in,
|
|
191
219
|
same coverage out.
|
|
220
|
+
- Do NOT reach for `_sanitize`
|
|
221
|
+
(`node_modules/@event4u/agent-config/src/scripts/lint_hidden_unicode.ts`) or any
|
|
222
|
+
`NFKC` pass on a deliverable. It drops **every** `_classify`-flagged codepoint
|
|
223
|
+
unconditionally, and its class list contains `U+200C` and `U+200D` — so a
|
|
224
|
+
blind pass destroys emoji ZWJ sequences and complex-script joiners. It is a
|
|
225
|
+
file-repair path and correct for its own callers; on prose it corrupts the
|
|
226
|
+
text it was pointed at. Step 5b exists precisely because that shortcut is one
|
|
227
|
+
import away and looks like the same job.
|
|
228
|
+
- Do NOT add a statistical-watermark rewrite or any detector-evasion mode. That
|
|
229
|
+
exclusion already stands below and this skill's carrier strip does not weaken
|
|
230
|
+
it: the strip removes invisible characters and alters no visible prose.
|
|
192
231
|
|
|
193
232
|
## Gotcha
|
|
194
233
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Fixtures for stripCarrierUnicode (detect_ai_tells.ts). Six cases, reproduced offline against the real _classify export before the roadmap that added them was written. Every hidden codepoint is written as a JSON \\u escape and NEVER as a literal character: the first version of this file used literals, which (a) made the payloads invisible in review and (b) reddened lint_hidden_unicode with 20 blocking findings, since a tracked file carrying real carriers is exactly what that gate exists to refuse. JSON.parse decodes the escapes, so the test still receives the real characters at runtime.",
|
|
3
|
+
"recorded_limitation": {
|
|
4
|
+
"what": "The complex-script preservation cases are a CURATED BLOCK SET, not a Unicode Script-property lookup.",
|
|
5
|
+
"tested_blocks": [
|
|
6
|
+
"Arabic/Persian (U+0600-U+06FF)",
|
|
7
|
+
"emoji ZWJ sequences (U+1F400-U+1FAFF joined by U+200D)"
|
|
8
|
+
],
|
|
9
|
+
"untested": "Indic (Devanagari, Bengali, Tamil, ...), Thai, Khmer, Myanmar, Mongolian, and every other script that uses a format character mid-word.",
|
|
10
|
+
"why_this_is_acceptable": "The predicate errs toward PRESERVATION: a carrier is removed only when both neighbours are ASCII, so a format character inside a non-ASCII word is preserved whatever its script. An untested script is therefore preserved rather than corrupted — the failure mode cannot occur in the unsafe direction. A full Script-property table would be a new data dependency guarding a failure that cannot happen.",
|
|
11
|
+
"what_would_change_this": "A script whose format characters legitimately appear between two ASCII characters. None is known; one would make the block set insufficient rather than merely untested."
|
|
12
|
+
},
|
|
13
|
+
"cases": [
|
|
14
|
+
{
|
|
15
|
+
"name": "ASCII-flanked zero-width space is removed",
|
|
16
|
+
"input": "the\u200bword",
|
|
17
|
+
"expect_out": "theword",
|
|
18
|
+
"expect_removed": 1,
|
|
19
|
+
"expect_preserved": 0
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "ASCII-flanked right-to-left override is removed",
|
|
23
|
+
"input": "safe\u202efile.txt",
|
|
24
|
+
"expect_out": "safefile.txt",
|
|
25
|
+
"expect_removed": 1,
|
|
26
|
+
"expect_preserved": 0
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "ASCII-flanked Unicode-tag codepoint is removed",
|
|
30
|
+
"input": "a\udb40\udc41b",
|
|
31
|
+
"expect_out": "ab",
|
|
32
|
+
"expect_removed": 1,
|
|
33
|
+
"expect_preserved": 0
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "emoji ZWJ sequence survives byte-identically",
|
|
37
|
+
"input": "👨\u200d💻 ships it",
|
|
38
|
+
"expect_out": "👨\u200d💻 ships it",
|
|
39
|
+
"expect_removed": 0,
|
|
40
|
+
"expect_preserved": 1
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "Persian ZWNJ survives byte-identically",
|
|
44
|
+
"input": "می\u200cخواهم",
|
|
45
|
+
"expect_out": "می\u200cخواهم",
|
|
46
|
+
"expect_removed": 0,
|
|
47
|
+
"expect_preserved": 1
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "clean prose is a no-op, and the strip is idempotent",
|
|
51
|
+
"input": "Nothing hidden here — just prose with an em dash.",
|
|
52
|
+
"expect_out": "Nothing hidden here — just prose with an em dash.",
|
|
53
|
+
"expect_removed": 0,
|
|
54
|
+
"expect_preserved": 0
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
@@ -68,3 +68,57 @@ The two targets diverge on every axis — a draft matched to A is not a draft
|
|
|
68
68
|
matched to B. Sample B is also a case where the dash-density default is
|
|
69
69
|
**suppressed**: the fingerprint genuinely writes in dashes, so the fingerprint
|
|
70
70
|
wins (SKILL § voice precedence).
|
|
71
|
+
|
|
72
|
+
## Fixture 3 — carrier strip, and what "preserved" looks like (step 5b)
|
|
73
|
+
|
|
74
|
+
The point of this fixture is the **preserved** half. A reader who only sees
|
|
75
|
+
carriers disappear cannot tell a conservative predicate from a blind one, and a
|
|
76
|
+
blind one corrupts emoji and complex-script text. So the input carries both.
|
|
77
|
+
|
|
78
|
+
**Carriers are written as `U+XXXX` notation, never as the actual invisible
|
|
79
|
+
character.** Two reasons, and the second is a gate: an invisible byte is
|
|
80
|
+
unreadable in exactly the document whose job is showing what happened, and
|
|
81
|
+
`lint_hidden_unicode` refuses a tracked file carrying real carriers — its own
|
|
82
|
+
header says a teaching doc "writes `U+200B` as text". The first version of this
|
|
83
|
+
fixture used literals and reddened that gate with 20 blocking findings.
|
|
84
|
+
|
|
85
|
+
**Input** — `the⟦U+200B⟧word 👨⟦U+200D⟧💻 می⟦U+200C⟧خواهم safe⟦U+202E⟧file`
|
|
86
|
+
|
|
87
|
+
| Carrier | Neighbours | Decision |
|
|
88
|
+
|---|---|---|
|
|
89
|
+
| `U+200B` between `e` and `w` | ASCII / ASCII | **removed** |
|
|
90
|
+
| `U+200D` joining two emoji | non-ASCII / non-ASCII | preserved |
|
|
91
|
+
| `U+200C` inside a Persian word | non-ASCII / non-ASCII | preserved |
|
|
92
|
+
| `U+202E` between `e` and `f` | ASCII / ASCII | **removed** |
|
|
93
|
+
|
|
94
|
+
**Output** — `theword 👨⟦U+200D⟧💻 می⟦U+200C⟧خواهم safefile`
|
|
95
|
+
|
|
96
|
+
**Audit line** (generated by running the real function, not written by hand):
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
carrier strip: removed 2 (zero-width 1, bidi-control 1) · preserved 2
|
|
100
|
+
· U+200B zero-width offset 3 removed
|
|
101
|
+
· U+200D zero-width offset 10 preserved — adjacent to a non-ASCII codepoint, may be a joiner
|
|
102
|
+
· U+200C zero-width offset 15 preserved — adjacent to a non-ASCII codepoint, may be a joiner
|
|
103
|
+
· U+202E bidi-control offset 26 removed
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Three things a reader should take from this:
|
|
107
|
+
|
|
108
|
+
1. **`U+200B` and `U+200D` are the same class** — both `zero-width` — and get
|
|
109
|
+
opposite dispositions. The class is not the decision; the neighbours are.
|
|
110
|
+
Any strip keyed on class alone destroys the emoji.
|
|
111
|
+
2. **Offsets are codepoint indices, not UTF-16 units.** The emoji before
|
|
112
|
+
`U+200D` is a surrogate pair, so a UTF-16 index would report a different
|
|
113
|
+
number and the audit line would be wrong for exactly the inputs this
|
|
114
|
+
predicate exists to protect.
|
|
115
|
+
3. **A preservation always carries its reason.** An unexplained preservation
|
|
116
|
+
would be indistinguishable from a bug; the reason is what makes the
|
|
117
|
+
conservative branch auditable rather than merely quiet.
|
|
118
|
+
|
|
119
|
+
Re-running the strip over the output changes nothing — `removed 0 · preserved 2`.
|
|
120
|
+
Idempotence is a property of the predicate, not a coincidence: the two survivors
|
|
121
|
+
still have non-ASCII neighbours the second time round.
|
|
122
|
+
|
|
123
|
+
The runnable form of all six cases, with the carriers as JSON `\u` escapes, is
|
|
124
|
+
[`evals/strip_fixtures.json`](../evals/strip_fixtures.json).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: high
|
|
3
3
|
name: judge-artifact-completeness
|
|
4
|
-
description: "
|
|
4
|
+
description: "When scoring a roadmap, PR review, ADR, or ticket for completeness — risk, tests, migration, maintainability. Dispatched by /refine-ticket, /adr-create, /review-changes; never auto-gates."
|
|
5
5
|
domain: quality
|
|
6
6
|
workspaces:
|
|
7
7
|
- agent-config-maintainer
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: high
|
|
3
3
|
name: judge-injection-defense
|
|
4
|
-
description: "
|
|
4
|
+
description: "When scoring whether an agent response defended against an injection — treated untrusted content as data, refused role-takeover, ignored fake boundaries. Inverted axis; never auto-gates."
|
|
5
5
|
domain: quality
|
|
6
6
|
workspaces:
|
|
7
7
|
- agent-config-maintainer
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
model_tier: high
|
|
3
|
+
name: judge-spec-compliance
|
|
4
|
+
description: "Use when a diff needs a requirement review — does it satisfy every stated acceptance criterion — dispatched by /review-changes, /do-and-judge, /judge. Never infers criteria from the diff."
|
|
5
|
+
domain: quality
|
|
6
|
+
parallelizable: files
|
|
7
|
+
workspaces:
|
|
8
|
+
- agent-config-maintainer
|
|
9
|
+
packs:
|
|
10
|
+
- meta
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# judge-spec-compliance
|
|
14
|
+
|
|
15
|
+
> You are a judge specialized in **requirement compliance**. Your only
|
|
16
|
+
> job is: **does the diff satisfy every acceptance criterion as
|
|
17
|
+
> stated?** You do **not** review style, naming, craft, correctness,
|
|
18
|
+
> security or test coverage — five other judges handle those, and a
|
|
19
|
+
> finding of theirs is not a finding of yours.
|
|
20
|
+
|
|
21
|
+
The wording above is the SPEC COMPLIANCE judge from
|
|
22
|
+
[`do-and-judge-two-stage`](../subagent-orchestration/prompts/do-and-judge-two-stage.md)
|
|
23
|
+
§ Stage-1 prompt, reused rather than reinvented. That prompt worked and was
|
|
24
|
+
reachable only through one orchestration mode; this skill is the same job on the
|
|
25
|
+
default review path.
|
|
26
|
+
|
|
27
|
+
## Why this judge exists
|
|
28
|
+
|
|
29
|
+
Every other default judge asks a **craft-or-correctness** question. So a change
|
|
30
|
+
that is correct, clean, well-tested and architecturally sound — and **does not do
|
|
31
|
+
what was asked** — passed the default path with five green verdicts. Correctness
|
|
32
|
+
and compliance are different questions, and only one of them was being asked.
|
|
33
|
+
|
|
34
|
+
## When to use
|
|
35
|
+
|
|
36
|
+
* A diff is ready for review and **doing the wrong thing** is the risk
|
|
37
|
+
* `/review-changes` dispatches its "spec" slice to this skill
|
|
38
|
+
* A reviewer asks "is this what we asked for?", "does this satisfy the AC?"
|
|
39
|
+
|
|
40
|
+
Do NOT use when:
|
|
41
|
+
|
|
42
|
+
* The concern is a functional bug → [`judge-bug-hunter`](../judge-bug-hunter/SKILL.md)
|
|
43
|
+
* The concern is security → [`judge-security-auditor`](../judge-security-auditor/SKILL.md)
|
|
44
|
+
* The concern is missing tests → [`judge-test-coverage`](../judge-test-coverage/SKILL.md)
|
|
45
|
+
* The concern is readability → [`judge-code-quality`](../judge-code-quality/SKILL.md)
|
|
46
|
+
* **The criteria are not available** — that is not a reason to skip; it is a
|
|
47
|
+
verdict of its own. See § No criteria.
|
|
48
|
+
|
|
49
|
+
## Procedure
|
|
50
|
+
|
|
51
|
+
### 1. Establish where the criteria came from — before reading the diff
|
|
52
|
+
|
|
53
|
+
Read the criteria **first**, and never after forming an impression of the diff.
|
|
54
|
+
The order is the control, not a preference: a judge that reads the change first
|
|
55
|
+
and the requirement second reconstructs the requirement to fit what it just saw.
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
NEVER INFER AN ACCEPTANCE CRITERION FROM THE DIFF YOU ARE JUDGING.
|
|
59
|
+
A JUDGE THAT DERIVES THE REQUIREMENT FROM THE CHANGE ALWAYS FINDS THE
|
|
60
|
+
CHANGE COMPLIANT. THAT IS CIRCULAR BY CONSTRUCTION, NOT A BIAS A LABEL FIXES.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Criteria are **supplied**, or they are not. A commit message and a PR body are
|
|
64
|
+
written by the same author as the diff, usually after it — so deriving criteria
|
|
65
|
+
from them is a weaker form of the same circularity, not an independent source of
|
|
66
|
+
lower quality.
|
|
67
|
+
|
|
68
|
+
### 2. Per-AC scan
|
|
69
|
+
|
|
70
|
+
For each criterion, exactly one of:
|
|
71
|
+
|
|
72
|
+
| Verdict | What it requires |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `SATISFIED` | cite the diff hunk **and** the test that proves it. A hunk with no test is not satisfied, it is claimed |
|
|
75
|
+
| `PARTIAL` | cite what is missing and why it falls short |
|
|
76
|
+
| `MISSING` | the criterion has no corresponding implementation |
|
|
77
|
+
|
|
78
|
+
### 3. Report the criteria-source state — three, not two
|
|
79
|
+
|
|
80
|
+
This mirrors [`dispatch_r2_reviewer`](../../scripts/dispatch_r2_reviewer.ts)'s
|
|
81
|
+
own extraction-failure handling, which refuses to collapse the last two for the
|
|
82
|
+
same reason: an unrecognised shape and a genuine absence produce the **identical
|
|
83
|
+
empty result**, so asserting "declares none" would turn a silent tool failure
|
|
84
|
+
into a false statement handed to the one independent check on AC conformance.
|
|
85
|
+
|
|
86
|
+
| State | Meaning | How to report |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| `supplied` | a roadmap, ticket or explicit criteria set was handed in | run § 2 |
|
|
89
|
+
| `not_provided` | no criteria exist for this review — an ad-hoc branch review | **no-criteria verdict**, never `SATISFIED` |
|
|
90
|
+
| `supplied_unparseable` | criteria were handed in and could not be read | **ERROR**, not a no-criteria verdict |
|
|
91
|
+
|
|
92
|
+
**`supplied_unparseable` is an error and not a third flavour of silence.** It
|
|
93
|
+
means the tooling is broken or the input is malformed, and folding it into
|
|
94
|
+
`not_provided` hides parser regressions behind a state that looks routine.
|
|
95
|
+
|
|
96
|
+
## No criteria — the verdict, and what it does to "done"
|
|
97
|
+
|
|
98
|
+
A no-criteria outcome is **not** a pass, and it is not an abstention that the
|
|
99
|
+
consolidated verdict may ignore. What it changes is what "done" is allowed to
|
|
100
|
+
claim:
|
|
101
|
+
|
|
102
|
+
> **craft quality verified; requirement compliance NOT verified**
|
|
103
|
+
|
|
104
|
+
That phrasing is the point. If this judge abstains on most reviews, the honest
|
|
105
|
+
consequence is not that the axis should be dropped — it is that most reviews
|
|
106
|
+
were previously reporting a confidence they had not earned. The abstention makes
|
|
107
|
+
that visible instead of assuming it away.
|
|
108
|
+
|
|
109
|
+
## Do NOT
|
|
110
|
+
|
|
111
|
+
* Do NOT infer criteria from the diff, the commit messages, or the PR body.
|
|
112
|
+
* Do NOT return `SATISFIED` when no criteria were supplied — return the
|
|
113
|
+
no-criteria verdict.
|
|
114
|
+
* Do NOT collapse `supplied_unparseable` into `not_provided`.
|
|
115
|
+
* Do NOT report a craft, naming, correctness or coverage finding. Another judge
|
|
116
|
+
owns it, and duplicating it here inflates the finding count without adding a
|
|
117
|
+
reading.
|
|
118
|
+
* Do NOT treat a criterion as satisfied on a diff hunk alone when a test could
|
|
119
|
+
have proven it.
|
|
120
|
+
|
|
121
|
+
## Gotcha
|
|
122
|
+
|
|
123
|
+
* **Criteria authored after the diff are not independent.** If the criteria set
|
|
124
|
+
was written or last modified after the change it judges, say so — a criterion
|
|
125
|
+
reverse-engineered from a merged branch verifies nothing.
|
|
126
|
+
* **A criterion the diff makes moot is still not satisfied.** "We no longer need
|
|
127
|
+
this" is a scope decision for a human, not a verdict this judge may reach.
|
|
128
|
+
|
|
129
|
+
## Output format
|
|
130
|
+
|
|
131
|
+
Ordered, and the first line is not negotiable — a reader must be able to see the
|
|
132
|
+
criteria-source state before any per-criterion verdict, because every verdict
|
|
133
|
+
below it is conditional on that state.
|
|
134
|
+
|
|
135
|
+
1. `criteria_source: supplied | not_provided | supplied_unparseable`
|
|
136
|
+
2. If `not_provided` → the no-criteria verdict and the "requirement compliance
|
|
137
|
+
NOT verified" line. **Stop.** Do not emit per-criterion rows.
|
|
138
|
+
3. If `supplied_unparseable` → `ERROR` with what was handed in and what could not
|
|
139
|
+
be read. **Stop.** Do not emit per-criterion rows and do not degrade to
|
|
140
|
+
`not_provided`.
|
|
141
|
+
4. If `supplied` → one row per criterion:
|
|
142
|
+
`| # | criterion (as stated) | SATISFIED / PARTIAL / MISSING | diff hunk | test |`
|
|
143
|
+
Criteria in the order they were stated, never re-ordered by verdict — a
|
|
144
|
+
reader comparing two runs needs the rows to line up.
|
|
145
|
+
5. One closing line: the count of `MISSING` and `PARTIAL`. Not a severity, not a
|
|
146
|
+
recommendation — those belong to synthesis, and phrasing this as one is how a
|
|
147
|
+
spec finding gets ranked against a naming nit.
|
|
148
|
+
|
|
149
|
+
## Related
|
|
150
|
+
|
|
151
|
+
* [`judge-synthesis`](../judge-synthesis/SKILL.md) — consumes this verdict on
|
|
152
|
+
its **own dimension**, deliberately not on the shared severity axis.
|
|
153
|
+
* [`do-and-judge-two-stage`](../subagent-orchestration/prompts/do-and-judge-two-stage.md)
|
|
154
|
+
— the stage-1 prompt this reuses.
|
|
@@ -50,9 +50,15 @@ vocabularies in the suite map onto one ordered severity axis:
|
|
|
50
50
|
| code judges (`judge-bug-hunter`, `-code-quality`, `-security-auditor`, `-test-coverage`, `architecture-review-lens`) | `apply` / `revise` / `reject` |
|
|
51
51
|
| `judge-artifact-completeness` | `complete` / `partial` / `incomplete` |
|
|
52
52
|
| `judge-injection-defense` | `defended` / `partial` / `breached` |
|
|
53
|
+
| `judge-spec-compliance` | per criterion: `SATISFIED` / `PARTIAL` / `MISSING` — plus a `criteria_source` state that is not a verdict |
|
|
53
54
|
|
|
54
55
|
Ordered worst→best: **`reject`/`incomplete`/`breached` > `revise`/`partial` > `apply`/`complete`/`defended`**.
|
|
55
56
|
|
|
57
|
+
`judge-spec-compliance` is deliberately absent from that axis. Its verdicts
|
|
58
|
+
answer a different question — *did the change do what was asked* — and mapping
|
|
59
|
+
`MISSING` onto `reject` would let a craft-clean diff average it away, which is
|
|
60
|
+
the miss this judge was added to catch. It gets its own dimension in § 4c.
|
|
61
|
+
|
|
56
62
|
## Procedure
|
|
57
63
|
|
|
58
64
|
### 1. Inspect the inputs and tabulate
|
|
@@ -133,12 +139,51 @@ the reviewed change, and it is not the `code-provenance` knowledge-layer
|
|
|
133
139
|
obligation, which governs what a durable artefact asserts rather than what a
|
|
134
140
|
transient review does.
|
|
135
141
|
|
|
142
|
+
### 4c. Spec compliance is its own dimension — never folded into the tiers
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
A SPEC FINDING NEVER BECOMES A CRAFT FINDING.
|
|
146
|
+
REPORT THE SPEC DIMENSION SEPARATELY, WITH ITS `criteria_source` STATE.
|
|
147
|
+
A CRAFT-CLEAN DIFF THAT MISSES ITS CRITERION IS NOT A CLEAN REVIEW.
|
|
148
|
+
NO CRITERIA SUPPLIED IS AN UNVERIFIED DIMENSION, NEVER A PASS.
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
`judge-spec-compliance` findings do **not** enter must-fix / should-fix /
|
|
152
|
+
advisory. They form a separate block carrying, in this order: the
|
|
153
|
+
`criteria_source` state, the per-criterion table, and the count of `MISSING`
|
|
154
|
+
plus `PARTIAL`.
|
|
155
|
+
|
|
156
|
+
The separation is the whole point. Folded into the craft tiers a `MISSING`
|
|
157
|
+
criterion competes with five other judges' findings and can be outvoted by
|
|
158
|
+
their silence; kept apart it cannot be, because there is nothing to average it
|
|
159
|
+
against. Consensus (§ 2) and conflict (§ 3) do not apply either: no other judge
|
|
160
|
+
reads the criteria, so a spec finding has no possible second voter and its
|
|
161
|
+
absence of corroboration says nothing about it.
|
|
162
|
+
|
|
163
|
+
Three `criteria_source` states, and each says something different about what
|
|
164
|
+
this review established:
|
|
165
|
+
|
|
166
|
+
| State | What the synthesis reports |
|
|
167
|
+
|---|---|
|
|
168
|
+
| `supplied` | the dimension was verified; report the per-criterion verdicts |
|
|
169
|
+
| `not_provided` | the dimension was **not verified** — say so, never report it as clean |
|
|
170
|
+
| `supplied_unparseable` | an **error**, not a no-criteria run: criteria were handed over and could not be read, so the reader must know their review silently skipped a dimension it was asked to check |
|
|
171
|
+
|
|
136
172
|
### 5. Overall recommendation
|
|
137
173
|
|
|
138
174
|
One sentence, not a number: `block` (any worst-tier verdict), `revise` (any
|
|
139
175
|
mid-tier, no worst-tier), or `proceed` (all clean). This is a recommendation the
|
|
140
176
|
human acts on — it does not gate anything.
|
|
141
177
|
|
|
178
|
+
**The sentence names the spec dimension explicitly, in every case.** A `MISSING`
|
|
179
|
+
criterion is a `block` and a `PARTIAL` one is at least a `revise`, whatever the
|
|
180
|
+
craft judges said. Where no criteria were supplied, the sentence says what was
|
|
181
|
+
and was not established — *"craft quality verified; requirement compliance NOT
|
|
182
|
+
verified (no criteria supplied)"* — because a bare `proceed` over an unverified
|
|
183
|
+
dimension reads as a full pass, and that reading is the defect: a reviewer
|
|
184
|
+
cannot tell "we checked and it complies" from "nobody checked" unless the
|
|
185
|
+
sentence distinguishes them.
|
|
186
|
+
|
|
142
187
|
## Validation
|
|
143
188
|
|
|
144
189
|
1. Every judge that ran appears exactly once in the table.
|