@event4u/agent-config 9.1.0 → 9.3.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 +38 -234
- package/README.md +1 -1
- package/dist/agent-src/commands/fix/route.md +49 -0
- package/dist/agent-src/commands/fix.md +4 -2
- package/dist/agent-src/commands/implement-ticket.md +2 -0
- package/dist/agent-src/commands/review/changes.md +22 -0
- package/dist/agent-src/commands/tdd/green.md +32 -0
- package/dist/agent-src/commands/tdd/red.md +33 -0
- package/dist/agent-src/commands/tdd/refactor.md +31 -0
- package/dist/agent-src/commands/tdd.md +50 -0
- package/dist/agent-src/contexts/communication/rules-auto/guidelines-mechanics.md +1 -0
- package/dist/agent-src/contexts/execution/subagent-modes-detail.md +41 -6
- package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +81 -2
- package/dist/agent-src/contexts/execution/verify-budget.md +15 -0
- package/dist/agent-src/rules/architecture.md +7 -0
- package/dist/agent-src/rules/cross-source-consistency.md +92 -0
- package/dist/agent-src/rules/delegation-policy.md +1 -1
- package/dist/agent-src/skills/estimate-ticket/SKILL.md +2 -0
- package/dist/agent-src/skills/fe-design/SKILL.md +1 -0
- package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
- package/dist/agent-src/skills/judge-code-quality/SKILL.md +1 -0
- package/dist/agent-src/skills/persona-improvement/SKILL.md +81 -0
- package/dist/agent-src/skills/po-discovery/SKILL.md +2 -0
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +10 -0
- package/dist/agent-src/skills/refine-ticket/SKILL.md +7 -0
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +14 -0
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +38 -28
- package/dist/agent-src/skills/subagent-orchestration/evals/evals.json +18 -0
- package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +3 -2
- package/dist/agent-src/skills/subagent-orchestration/prompts/adversarial-verification-council.md +79 -0
- package/dist/agent-src/skills/subagent-orchestration/schemas/adversarial-findings.json +56 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +205 -29
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +5 -5
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +19 -11
- package/dist/discovery/trust-report.md +4 -4
- package/dist/discovery/workspaces.json +16 -8
- package/dist/install/install.mjs +9 -0
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/router.json +1 -1
- package/dist/server/schemas/settings.js +5 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/CLAIMS.md +10 -3
- package/docs/architecture.md +4 -4
- package/docs/archive/CHANGELOG-pre-9.2.0.md +276 -0
- package/docs/benchmark.md +24 -0
- package/docs/command-flows.md +9 -3
- package/docs/contracts/command-clusters.md +2 -1
- package/docs/decisions/ADR-122-adversarial-verification-council.md +136 -0
- package/docs/decisions/INDEX.md +1 -0
- package/docs/design/adversarial-council-eval.md +106 -0
- package/docs/development.md +10 -1
- package/docs/featured-skills.md +2 -2
- package/docs/getting-started-by-role.md +1 -1
- package/docs/getting-started.md +1 -1
- package/docs/governance-advantage.md +1 -1
- package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +109 -0
- package/docs/guidelines/component-oriented-and-oop-development.md +181 -0
- package/docs/proof.md +7 -7
- package/package.json +3 -2
- package/src/config/agent-settings.template.yml +42 -0
- package/src/scripts/_lib/adversarial_council_gate.test.ts +112 -0
- package/src/scripts/_lib/adversarial_council_gate.ts +98 -0
- package/src/scripts/_lib/adversarial_reconcile.test.ts +197 -0
- package/src/scripts/_lib/adversarial_reconcile.ts +187 -0
- package/src/scripts/_lib/verify_budget.ts +4 -1
- package/src/scripts/ai_council/prompts.ts +7 -0
- package/src/scripts/hook_manifest.yaml +17 -6
- package/src/scripts/install-hooks.sh +32 -17
- package/src/scripts/pr_url_reminder_hook.ts +177 -0
- package/src/scripts/schemas/agent-settings.schema.json +11 -0
- package/src/server/schemas/settings.ts +9 -0
|
@@ -145,6 +145,17 @@ concerns:
|
|
|
145
145
|
script: src/scripts/team_review_gate_hook.ts
|
|
146
146
|
args: []
|
|
147
147
|
fail_closed: false
|
|
148
|
+
# Reply-shape backstop for the direct-answers rule (reply-close): a PR
|
|
149
|
+
# created THIS turn must end the reply as the literal last raw URL. This
|
|
150
|
+
# PostToolUse hook fires right after a PR *create* (gh pr create, or a
|
|
151
|
+
# github create-pull-request tool) that produced a `…/pull/<n>` URL, and
|
|
152
|
+
# WARNS in context (exit 2) so the reminder lands before the reply closes.
|
|
153
|
+
# Never blocks; unconditional (reinforces an always-on rule, fires only on
|
|
154
|
+
# the rare create event, so no settings gate). fail_closed: false.
|
|
155
|
+
pr-url-reminder:
|
|
156
|
+
script: src/scripts/pr_url_reminder_hook.ts
|
|
157
|
+
args: []
|
|
158
|
+
fail_closed: false
|
|
148
159
|
|
|
149
160
|
platforms:
|
|
150
161
|
augment:
|
|
@@ -152,7 +163,7 @@ platforms:
|
|
|
152
163
|
session_end: [chat-history]
|
|
153
164
|
stop: [chat-history, hot-context, verify-before-complete]
|
|
154
165
|
pre_tool_use: [block-no-verify, rtk-wrap, design-slop]
|
|
155
|
-
post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan]
|
|
166
|
+
post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder]
|
|
156
167
|
|
|
157
168
|
claude:
|
|
158
169
|
session_start: [chat-history, hot-context, first-run-gate, onboarding-gate, verify-before-complete, minimal-safe-diff, profile-staleness, wrapper-freshness, surface-probe]
|
|
@@ -160,7 +171,7 @@ platforms:
|
|
|
160
171
|
stop: [chat-history, hot-context, verify-before-complete, team-review-gate]
|
|
161
172
|
user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff]
|
|
162
173
|
pre_tool_use: [block-no-verify, rtk-wrap, design-slop]
|
|
163
|
-
post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan]
|
|
174
|
+
post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder]
|
|
164
175
|
|
|
165
176
|
# Cowork — the Claude desktop app's local-agent-mode runtime, built
|
|
166
177
|
# on top of the Claude Code CLI. Same lifecycle vocabulary, same
|
|
@@ -182,7 +193,7 @@ platforms:
|
|
|
182
193
|
stop: [chat-history, hot-context, verify-before-complete]
|
|
183
194
|
user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff]
|
|
184
195
|
pre_tool_use: [block-no-verify, rtk-wrap, design-slop]
|
|
185
|
-
post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan]
|
|
196
|
+
post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder]
|
|
186
197
|
|
|
187
198
|
# Phase 7.5 — Cursor. `.cursor/hooks.json` (project) is read by the
|
|
188
199
|
# IDE and CLI; `~/.cursor/hooks.json` (user) is opt-in via
|
|
@@ -196,7 +207,7 @@ platforms:
|
|
|
196
207
|
session_end: [chat-history]
|
|
197
208
|
stop: [chat-history, hot-context, verify-before-complete]
|
|
198
209
|
user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff]
|
|
199
|
-
post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan]
|
|
210
|
+
post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder]
|
|
200
211
|
|
|
201
212
|
# Phase 7.6 — Cline. Hooks live under `.clinerules/hooks/<HookName>`
|
|
202
213
|
# (project, no file extension, must be executable per Cline docs) or
|
|
@@ -211,7 +222,7 @@ platforms:
|
|
|
211
222
|
session_end: [chat-history]
|
|
212
223
|
stop: [chat-history, hot-context, verify-before-complete]
|
|
213
224
|
user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff]
|
|
214
|
-
post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan]
|
|
225
|
+
post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder]
|
|
215
226
|
|
|
216
227
|
# Phase 7.7 — Windsurf (Cascade). Hooks live at `.windsurf/hooks.json`
|
|
217
228
|
# (project) or `~/.codeium/windsurf/hooks.json` (user). Cascade has
|
|
@@ -245,7 +256,7 @@ platforms:
|
|
|
245
256
|
session_end: [chat-history]
|
|
246
257
|
stop: [chat-history, hot-context, verify-before-complete]
|
|
247
258
|
user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff]
|
|
248
|
-
post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan]
|
|
259
|
+
post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder]
|
|
249
260
|
|
|
250
261
|
# Phase 7.9 — Copilot has no hook surface. Concerns route through
|
|
251
262
|
# rule-only fallback; the dispatcher silently no-ops on --platform copilot.
|
|
@@ -8,32 +8,47 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
8
8
|
# This installer lives at src/scripts/install-hooks.sh, so the repo root
|
|
9
9
|
# (which owns .git/) is two levels up.
|
|
10
10
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
11
|
-
|
|
11
|
+
# Resolve the SHARED hooks dir via git so this also works from a linked worktree
|
|
12
|
+
# (where $PROJECT_ROOT/.git is a file, not a dir, and a literal .git/hooks path
|
|
13
|
+
# would break under `set -e`). --git-common-dir points at the main .git even from
|
|
14
|
+
# a worktree; fall back to the literal path only outside a git repo.
|
|
15
|
+
if COMMON_GIT_DIR="$(git -C "$PROJECT_ROOT" rev-parse --git-common-dir 2>/dev/null)"; then
|
|
16
|
+
case "$COMMON_GIT_DIR" in /*) : ;; *) COMMON_GIT_DIR="$PROJECT_ROOT/$COMMON_GIT_DIR" ;; esac
|
|
17
|
+
HOOKS_DIR="$COMMON_GIT_DIR/hooks"
|
|
18
|
+
else
|
|
19
|
+
HOOKS_DIR="$PROJECT_ROOT/.git/hooks"
|
|
20
|
+
fi
|
|
12
21
|
|
|
13
22
|
mkdir -p "$HOOKS_DIR"
|
|
14
23
|
|
|
15
24
|
cat > "$HOOKS_DIR/pre-push" << 'EOF'
|
|
16
25
|
#!/usr/bin/env bash
|
|
17
|
-
# Pre-push hook:
|
|
18
|
-
#
|
|
26
|
+
# Pre-push hook: mirror the CI "Sync + Generate Tools Consistency" gate LOCALLY
|
|
27
|
+
# so derived-output drift is caught BEFORE push, not in remote CI.
|
|
19
28
|
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
29
|
+
# History: the remote "Consistency" check failed in a large share of PRs because
|
|
30
|
+
# the old hook only verified dist sync + the COMMAND count — it missed
|
|
31
|
+
# guideline/skill/rule count drift and the generate-tools / router / corpus
|
|
32
|
+
# outputs (e.g. a new guideline bumping the count in README + docs/architecture).
|
|
33
|
+
# `task consistency` is the EXACT CI mirror (sync-check + sync-check-hashes +
|
|
34
|
+
# sync + generate-tools + compile-router + compile-corpus + `git diff --quiet`),
|
|
35
|
+
# so any derived-output drift blocks the push here. Runtime ~15-40s (it
|
|
36
|
+
# regenerates the tool trees) — cheaper than a red CI run and a fixup re-push.
|
|
24
37
|
|
|
25
38
|
fail=0
|
|
26
39
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
echo "
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
if ! command -v task >/dev/null 2>&1; then
|
|
41
|
+
echo "⚠️ 'task' (go-task) not found — cannot run the consistency gate locally."
|
|
42
|
+
echo " Install it (https://taskfile.dev) so pre-push can mirror the CI check;"
|
|
43
|
+
echo " skipping the consistency check for this push."
|
|
44
|
+
else
|
|
45
|
+
echo "🔍 Consistency — mirroring the CI 'Sync + Generate Tools Consistency' gate..."
|
|
46
|
+
if ! task consistency; then
|
|
47
|
+
echo "❌ Derived outputs drifted (counts / dist / generated tool trees / router / corpus)."
|
|
48
|
+
echo " 'task consistency' just regenerated them into your working tree —"
|
|
49
|
+
echo " review + 'git add' the changes (or run 'task consistency-fix'), commit, then re-push."
|
|
50
|
+
fail=1
|
|
51
|
+
fi
|
|
37
52
|
fi
|
|
38
53
|
|
|
39
54
|
echo "🔍 Checking for leftover conflict markers / unmerged paths..."
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* PostToolUse PR-URL reminder — reply-shape backstop for `direct-answers`.
|
|
4
|
+
*
|
|
5
|
+
* The `direct-answers` rule (reply-close) requires: a PR created THIS turn puts
|
|
6
|
+
* its raw URL as the **literal last line** of the reply. That is a behavioural
|
|
7
|
+
* rule with no deterministic backstop, so it can be silently missed — the URL
|
|
8
|
+
* ends up inline mid-reply instead of last. This hook fires right after a
|
|
9
|
+
* PR-creating tool call, extracts the created PR URL from the tool output, and
|
|
10
|
+
* WARNS in context (exit 2) so the reminder lands exactly when the PR is born,
|
|
11
|
+
* before the reply closes.
|
|
12
|
+
*
|
|
13
|
+
* Fires ONLY on an actual PR *create*:
|
|
14
|
+
* - a shell command matching `gh pr create`, OR
|
|
15
|
+
* - a GitHub tool whose name means "create a pull request"
|
|
16
|
+
* (e.g. create_pull_request / createPullRequest / pulls.create),
|
|
17
|
+
* AND only when the tool output actually contains a `…/pull/<n>` URL — so a
|
|
18
|
+
* failed / dry-run create (no URL) does not nag, and `gh pr view/checks/list/
|
|
19
|
+
* comment` (which also print PR URLs) never fire it.
|
|
20
|
+
*
|
|
21
|
+
* Warn only — never blocks (fail_closed: false). Unconditional: it reinforces
|
|
22
|
+
* an always-on rule and only fires on the rare PR-create event, so it carries
|
|
23
|
+
* no settings gate (mirrors verify-before-complete / roadmap-progress).
|
|
24
|
+
*
|
|
25
|
+
* Exit codes (dispatcher contract): 0 allow · 2 warn (+ `{decision,reason}`
|
|
26
|
+
* JSON on stdout).
|
|
27
|
+
*/
|
|
28
|
+
import fs from "node:fs";
|
|
29
|
+
import path from "node:path";
|
|
30
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
31
|
+
|
|
32
|
+
const EXIT_ALLOW = 0;
|
|
33
|
+
const EXIT_WARN = 2;
|
|
34
|
+
|
|
35
|
+
type JsonValue = string | number | boolean | null | JsonValue[] | { [k: string]: JsonValue };
|
|
36
|
+
type JsonObject = { [k: string]: JsonValue };
|
|
37
|
+
|
|
38
|
+
// Tool names across platforms whose command field carries a shell command
|
|
39
|
+
// (kept in lock-step with verify_before_complete_hook.COMMAND_TOOLS).
|
|
40
|
+
const COMMAND_TOOLS: ReadonlySet<string> = new Set([
|
|
41
|
+
"launch-process",
|
|
42
|
+
"launch_process",
|
|
43
|
+
"Bash",
|
|
44
|
+
"BashTool",
|
|
45
|
+
"run-process",
|
|
46
|
+
"runProcess",
|
|
47
|
+
"shell",
|
|
48
|
+
"execute_shell",
|
|
49
|
+
"RunShellCommand",
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
// A shell command that CREATES a pull request. Anchored on a shell separator so
|
|
53
|
+
// it matches inside a chained command (`git push && gh pr create …`) but not a
|
|
54
|
+
// substring of another word. `gh pr view/checks/list/comment` do not match.
|
|
55
|
+
const _GH_PR_CREATE = /(?:^|[\s;&|`(])gh\s+pr\s+create\b/i;
|
|
56
|
+
|
|
57
|
+
// A non-shell tool whose NAME means "create a pull request" (github-api / MCP).
|
|
58
|
+
const _CREATE_PR_TOOL = /(?:create[_-]?pull_?request|createpullrequest|pulls[._-]create|create_pr\b)/i;
|
|
59
|
+
|
|
60
|
+
// A GitHub pull-request URL as printed by `gh pr create` / returned as html_url.
|
|
61
|
+
const _PR_URL = /https?:\/\/github\.com\/[^\s"'`<>]+\/pull\/\d+/i;
|
|
62
|
+
|
|
63
|
+
function _isObject(v: unknown): v is JsonObject {
|
|
64
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Return [tool_name, command_text] from a tool-event payload. */
|
|
68
|
+
function _extractCommand(payload: JsonObject): [string | null, string | null] {
|
|
69
|
+
const toolRaw = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"];
|
|
70
|
+
const tool = typeof toolRaw === "string" ? toolRaw : null;
|
|
71
|
+
if (!(tool !== null && COMMAND_TOOLS.has(tool))) {
|
|
72
|
+
return [tool, null];
|
|
73
|
+
}
|
|
74
|
+
const ti = payload["tool_input"];
|
|
75
|
+
if (_isObject(ti)) {
|
|
76
|
+
for (const key of ["command", "cmd", "shell_command"]) {
|
|
77
|
+
const v = ti[key];
|
|
78
|
+
if (typeof v === "string" && v) {
|
|
79
|
+
return [tool, v];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (const key of ["command", "cmd"]) {
|
|
84
|
+
const v = payload[key];
|
|
85
|
+
if (typeof v === "string" && v) {
|
|
86
|
+
return [tool, v];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return [tool, null];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Best-effort extraction of the tool-output text from the envelope. */
|
|
93
|
+
function _toolOutput(envelope: JsonObject): string {
|
|
94
|
+
for (const key of ["tool_response", "tool_result", "toolResponse", "output", "result", "stdout"]) {
|
|
95
|
+
const v = envelope[key];
|
|
96
|
+
if (typeof v === "string") {
|
|
97
|
+
return v;
|
|
98
|
+
}
|
|
99
|
+
if (_isObject(v) || Array.isArray(v)) {
|
|
100
|
+
return JSON.stringify(v);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return JSON.stringify(envelope);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** True when this tool event created a pull request. */
|
|
107
|
+
function _isPrCreate(tool: string | null, command: string | null): boolean {
|
|
108
|
+
if (command !== null && _GH_PR_CREATE.test(command)) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
return tool !== null && _CREATE_PR_TOOL.test(tool);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function main(): number {
|
|
115
|
+
let envelope: JsonValue;
|
|
116
|
+
try {
|
|
117
|
+
const raw = _readStdin();
|
|
118
|
+
envelope = raw.trim() ? (JSON.parse(raw) as JsonValue) : {};
|
|
119
|
+
} catch {
|
|
120
|
+
return EXIT_ALLOW; // never block on a malformed envelope
|
|
121
|
+
}
|
|
122
|
+
if (!_isObject(envelope)) {
|
|
123
|
+
return EXIT_ALLOW;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const [tool, command] = _extractCommand(envelope);
|
|
127
|
+
if (!_isPrCreate(tool, command)) {
|
|
128
|
+
return EXIT_ALLOW;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const match = _PR_URL.exec(_toolOutput(envelope));
|
|
132
|
+
if (match === null) {
|
|
133
|
+
return EXIT_ALLOW; // create attempted but no URL produced (failed / dry-run) — do not nag
|
|
134
|
+
}
|
|
135
|
+
const url = match[0];
|
|
136
|
+
|
|
137
|
+
// `reason` (≤ 200 chars) goes to stderr; `additional_context` is what
|
|
138
|
+
// surfaces back to the model on platforms that support it — so the
|
|
139
|
+
// actionable instruction lives there (a stderr-only reason would not
|
|
140
|
+
// change the reply that this hook exists to shape).
|
|
141
|
+
const reason = `PR created this turn (${url}) — end your reply with this raw URL as the literal last line (direct-answers/reply-close).`;
|
|
142
|
+
const additional_context =
|
|
143
|
+
`You created a pull request this turn: ${url}\n\n` +
|
|
144
|
+
`Per the direct-answers rule (reply-close): a PR created this turn must appear ` +
|
|
145
|
+
`as the raw URL on the LITERAL LAST LINE of your reply — not inline mid-message. ` +
|
|
146
|
+
`Before ending the turn, make your final line exactly:\n${url}\n` +
|
|
147
|
+
`If it already is, no action needed.`;
|
|
148
|
+
process.stdout.write(`${JSON.stringify({ decision: "warn", reason, additional_context })}\n`);
|
|
149
|
+
return EXIT_WARN;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function _readStdin(): string {
|
|
153
|
+
return fs.readFileSync(0, "utf-8");
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function _isCliEntry(): boolean {
|
|
157
|
+
if (process.argv[1] === undefined) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
|
|
161
|
+
if (import.meta.url === argvUrl) {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
// Symlinked invocation (installed projection, or macOS /var → /private/var
|
|
165
|
+
// temp dirs) makes the raw URLs differ; compare realpaths so the guard fires.
|
|
166
|
+
try {
|
|
167
|
+
const here = fs.realpathSync(fileURLToPath(import.meta.url));
|
|
168
|
+
const argv = fs.realpathSync(path.resolve(process.argv[1]));
|
|
169
|
+
return here === argv;
|
|
170
|
+
} catch {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (_isCliEntry()) {
|
|
176
|
+
process.exit(main());
|
|
177
|
+
}
|
|
@@ -84,6 +84,17 @@
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
},
|
|
87
|
+
"consistency": {
|
|
88
|
+
"type": "object",
|
|
89
|
+
"additionalProperties": true,
|
|
90
|
+
"properties": {
|
|
91
|
+
"cross_source": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"enum": ["on", "auto", "off"],
|
|
94
|
+
"description": "Consumed by the cross-source-consistency rule. When the agent works from multiple sources (ticket text, an attached image/mockup, the spec, the codebase) it checks them against each other and asks before proceeding on a discrepancy. on (default) = surface every real cross-source contradiction / silent-scope-expansion as one question; auto = surface only high-confidence contradictions, state low-confidence as an assumption; off = no cross-source checking."
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
87
98
|
"code_style": {
|
|
88
99
|
"type": "object",
|
|
89
100
|
"additionalProperties": true,
|
|
@@ -26,6 +26,7 @@ const qualityCadence = z.enum(['end_of_roadmap', 'per_phase', 'per_step']);
|
|
|
26
26
|
const regenCadence = z.enum(['per_step', 'every_5_steps', 'phase_boundary']);
|
|
27
27
|
const worktreeMode = z.enum(['off', 'on', 'ask']);
|
|
28
28
|
const fidelityMode = z.enum(['strict', 'structural', 'hard-floor']);
|
|
29
|
+
const crossSourceMode = z.enum(['on', 'auto', 'off']);
|
|
29
30
|
const richSkillsMode = z.enum(['on', 'ask', 'off']);
|
|
30
31
|
const replyMethod = z.enum(['replies_endpoint', 'create_review_comment', 'auto']);
|
|
31
32
|
const confidenceBand = z.enum(['off', 'low', 'medium', 'high']);
|
|
@@ -203,6 +204,11 @@ export const settingsSchema = z.object({
|
|
|
203
204
|
'How strictly the agent must follow a user-provided prototype / mockup / design system (consumed by the design-fidelity rule). strict = build 1:1, every visible deviation needs confirmation; structural = structure locked, silent gaps fillable with a stated assumption; hard-floor = any deviation is never autonomous.',
|
|
204
205
|
),
|
|
205
206
|
}).default({ fidelity_mode: 'strict' }),
|
|
207
|
+
consistency: z.object({
|
|
208
|
+
cross_source: crossSourceMode.default('on').describe(
|
|
209
|
+
'Consumed by the cross-source-consistency rule. When the agent works from multiple sources (ticket text, an attached image/mockup, the spec, the codebase) it checks them against each other and asks before proceeding on a discrepancy — instead of silently guessing. on (default) = surface every real cross-source contradiction / silent-scope-expansion as one question; auto = surface only high-confidence contradictions, state low-confidence as an assumption; off = no cross-source checking.',
|
|
210
|
+
),
|
|
211
|
+
}).default({ cross_source: 'on' }),
|
|
206
212
|
tokens: z.object({
|
|
207
213
|
rich_skills: richSkillsMode.default('on').describe(
|
|
208
214
|
'Whether skills marked token_budget_class: rich may load in full (exempt from telegraph-speak + thin-projector trimming), consumed by the token-budget-discipline rule. on = allowed (default); off = fall back to standard condensed behavior; ask = surface an estimated token delta (tokens, not dollars) and ask once per session before loading.',
|
|
@@ -282,6 +288,9 @@ export const settingsSchema = z.object({
|
|
|
282
288
|
max_parallel: z.number().int().min(1).default(3).describe(
|
|
283
289
|
'Hard cap on subagents running in parallel during /do-in-parallel, /do-competitively, and /judge runs. Raise for faster fan-out, lower if you hit rate limits or want lower token spend.',
|
|
284
290
|
),
|
|
291
|
+
adversarial_council: z.enum(['off', 'ask', 'on']).default('off').describe(
|
|
292
|
+
'Opt-in adversarial-verification-council mode (subagent-orchestration Mode 9, ADR-122). off (default) = never runs; ask = offer it on an explicit high-risk change; on = auto-run on high-risk changes. Advisory only — a panel of distinct-model skeptics red-teams a real change for defect FINDING coverage and NEVER auto-gates it (Hard Floor). Stays default-off until the adversarial-council-finding-coverage claim is backed.',
|
|
293
|
+
),
|
|
285
294
|
}),
|
|
286
295
|
worktrees: z.object({
|
|
287
296
|
mode: worktreeMode.default('ask').describe(
|