cleargate 0.8.2 → 0.11.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/CHANGELOG.md +210 -0
- package/README.md +22 -1
- package/dist/MANIFEST.json +276 -31
- package/dist/chunk-HZPJ5QX4.js +459 -0
- package/dist/chunk-HZPJ5QX4.js.map +1 -0
- package/dist/{chunk-OM4FAEA7.js → chunk-Q3BTSXCK.js} +69 -3
- package/dist/chunk-Q3BTSXCK.js.map +1 -0
- package/dist/cli.cjs +2888 -598
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2481 -619
- package/dist/cli.js.map +1 -1
- package/dist/lib/ledger.cjs +120 -0
- package/dist/lib/ledger.cjs.map +1 -0
- package/dist/lib/ledger.d.cts +64 -0
- package/dist/lib/ledger.d.ts +64 -0
- package/dist/lib/ledger.js +96 -0
- package/dist/lib/ledger.js.map +1 -0
- package/dist/lib/lifecycle-reconcile.cjs +497 -0
- package/dist/lib/lifecycle-reconcile.cjs.map +1 -0
- package/dist/lib/lifecycle-reconcile.d.cts +136 -0
- package/dist/lib/lifecycle-reconcile.d.ts +136 -0
- package/dist/lib/lifecycle-reconcile.js +20 -0
- package/dist/lib/lifecycle-reconcile.js.map +1 -0
- package/dist/templates/cleargate-planning/.claude/agents/architect.md +65 -10
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-contradict.md +108 -0
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-ingest.md +49 -3
- package/dist/templates/cleargate-planning/.claude/agents/cleargate-wiki-lint.md +6 -1
- package/dist/templates/cleargate-planning/.claude/agents/developer.md +51 -2
- package/dist/templates/cleargate-planning/.claude/agents/devops.md +249 -0
- package/dist/templates/cleargate-planning/.claude/agents/qa.md +91 -1
- package/dist/templates/cleargate-planning/.claude/agents/reporter.md +72 -14
- package/dist/templates/cleargate-planning/.claude/hooks/pre-commit-surface-gate.sh +21 -0
- package/dist/templates/cleargate-planning/.claude/hooks/pre-tool-use-task.sh +148 -0
- package/dist/templates/cleargate-planning/.claude/hooks/session-start.sh +6 -0
- package/dist/templates/cleargate-planning/.claude/hooks/stamp-and-gate.sh +12 -1
- package/dist/templates/cleargate-planning/.claude/hooks/token-ledger.sh +334 -96
- package/dist/templates/cleargate-planning/.claude/settings.json +4 -0
- package/dist/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +644 -0
- package/dist/templates/cleargate-planning/.cleargate/config.example.yml +19 -0
- package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-enforcement.md +542 -0
- package/dist/templates/cleargate-planning/.cleargate/knowledge/cleargate-protocol.md +102 -428
- package/dist/templates/cleargate-planning/.cleargate/knowledge/mid-sprint-triage-rubric.md +160 -0
- package/dist/templates/cleargate-planning/.cleargate/knowledge/readiness-gates.md +72 -9
- package/dist/templates/cleargate-planning/.cleargate/knowledge/sprint-closeout-checklist.md +71 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/assert_story_files.mjs +24 -2
- package/dist/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +471 -29
- package/dist/templates/cleargate-planning/.cleargate/scripts/dedupe_frontmatter.mjs +219 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +3 -3
- package/dist/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +86 -10
- package/dist/templates/cleargate-planning/.cleargate/scripts/lib/report-filename.mjs +54 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/prep_doc_refresh.mjs +378 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/prep_qa_context.mjs +888 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/run_script.sh +173 -87
- package/dist/templates/cleargate-planning/.cleargate/scripts/sprint_trends.mjs +71 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/suggest_improvements.mjs +483 -13
- package/dist/templates/cleargate-planning/.cleargate/scripts/test/test_prep_qa_context.sh +482 -0
- package/dist/templates/cleargate-planning/.cleargate/scripts/validate_state.mjs +32 -8
- package/dist/templates/cleargate-planning/.cleargate/scripts/write_dispatch.sh +136 -0
- package/dist/templates/cleargate-planning/.cleargate/templates/Bug.md +27 -1
- package/dist/templates/cleargate-planning/.cleargate/templates/CR.md +35 -1
- package/dist/templates/cleargate-planning/.cleargate/templates/Sprint Plan Template.md +48 -14
- package/dist/templates/cleargate-planning/.cleargate/templates/epic.md +40 -3
- package/dist/templates/cleargate-planning/.cleargate/templates/hotfix.md +53 -0
- package/dist/templates/cleargate-planning/.cleargate/templates/initiative.md +98 -29
- package/dist/templates/cleargate-planning/.cleargate/templates/proposal.md +17 -4
- package/dist/templates/cleargate-planning/.cleargate/templates/sprint_context.md +8 -0
- package/dist/templates/cleargate-planning/.cleargate/templates/sprint_report.md +23 -4
- package/dist/templates/cleargate-planning/.cleargate/templates/story.md +58 -3
- package/dist/templates/cleargate-planning/CLAUDE.md +30 -10
- package/dist/templates/cleargate-planning/MANIFEST.json +276 -31
- package/dist/{whoami-CX7CXJD5.js → whoami-W4U6DPVG.js} +17 -17
- package/dist/whoami-W4U6DPVG.js.map +1 -0
- package/package.json +20 -6
- package/templates/cleargate-planning/.claude/agents/architect.md +65 -10
- package/templates/cleargate-planning/.claude/agents/cleargate-wiki-contradict.md +108 -0
- package/templates/cleargate-planning/.claude/agents/cleargate-wiki-ingest.md +49 -3
- package/templates/cleargate-planning/.claude/agents/cleargate-wiki-lint.md +6 -1
- package/templates/cleargate-planning/.claude/agents/developer.md +51 -2
- package/templates/cleargate-planning/.claude/agents/devops.md +249 -0
- package/templates/cleargate-planning/.claude/agents/qa.md +91 -1
- package/templates/cleargate-planning/.claude/agents/reporter.md +72 -14
- package/templates/cleargate-planning/.claude/hooks/pre-commit-surface-gate.sh +21 -0
- package/templates/cleargate-planning/.claude/hooks/pre-tool-use-task.sh +148 -0
- package/templates/cleargate-planning/.claude/hooks/session-start.sh +6 -0
- package/templates/cleargate-planning/.claude/hooks/stamp-and-gate.sh +12 -1
- package/templates/cleargate-planning/.claude/hooks/token-ledger.sh +334 -96
- package/templates/cleargate-planning/.claude/settings.json +4 -0
- package/templates/cleargate-planning/.claude/skills/sprint-execution/SKILL.md +644 -0
- package/templates/cleargate-planning/.cleargate/config.example.yml +19 -0
- package/templates/cleargate-planning/.cleargate/knowledge/cleargate-enforcement.md +542 -0
- package/templates/cleargate-planning/.cleargate/knowledge/cleargate-protocol.md +102 -428
- package/templates/cleargate-planning/.cleargate/knowledge/mid-sprint-triage-rubric.md +160 -0
- package/templates/cleargate-planning/.cleargate/knowledge/readiness-gates.md +72 -9
- package/templates/cleargate-planning/.cleargate/knowledge/sprint-closeout-checklist.md +71 -0
- package/templates/cleargate-planning/.cleargate/scripts/assert_story_files.mjs +24 -2
- package/templates/cleargate-planning/.cleargate/scripts/close_sprint.mjs +471 -29
- package/templates/cleargate-planning/.cleargate/scripts/dedupe_frontmatter.mjs +219 -0
- package/templates/cleargate-planning/.cleargate/scripts/gate-checks.json +3 -3
- package/templates/cleargate-planning/.cleargate/scripts/init_sprint.mjs +86 -10
- package/templates/cleargate-planning/.cleargate/scripts/lib/report-filename.mjs +54 -0
- package/templates/cleargate-planning/.cleargate/scripts/prep_doc_refresh.mjs +378 -0
- package/templates/cleargate-planning/.cleargate/scripts/prep_qa_context.mjs +888 -0
- package/templates/cleargate-planning/.cleargate/scripts/run_script.sh +173 -87
- package/templates/cleargate-planning/.cleargate/scripts/sprint_trends.mjs +71 -0
- package/templates/cleargate-planning/.cleargate/scripts/suggest_improvements.mjs +483 -13
- package/templates/cleargate-planning/.cleargate/scripts/test/test_prep_qa_context.sh +482 -0
- package/templates/cleargate-planning/.cleargate/scripts/validate_state.mjs +32 -8
- package/templates/cleargate-planning/.cleargate/scripts/write_dispatch.sh +136 -0
- package/templates/cleargate-planning/.cleargate/templates/Bug.md +27 -1
- package/templates/cleargate-planning/.cleargate/templates/CR.md +35 -1
- package/templates/cleargate-planning/.cleargate/templates/Sprint Plan Template.md +48 -14
- package/templates/cleargate-planning/.cleargate/templates/epic.md +40 -3
- package/templates/cleargate-planning/.cleargate/templates/hotfix.md +53 -0
- package/templates/cleargate-planning/.cleargate/templates/initiative.md +98 -29
- package/templates/cleargate-planning/.cleargate/templates/sprint_context.md +8 -0
- package/templates/cleargate-planning/.cleargate/templates/sprint_report.md +23 -4
- package/templates/cleargate-planning/.cleargate/templates/story.md +58 -3
- package/templates/cleargate-planning/CLAUDE.md +30 -10
- package/templates/cleargate-planning/MANIFEST.json +276 -31
- package/dist/chunk-OM4FAEA7.js.map +0 -1
- package/dist/whoami-CX7CXJD5.js.map +0 -1
- package/templates/cleargate-planning/.cleargate/templates/proposal.md +0 -61
|
@@ -2,27 +2,27 @@
|
|
|
2
2
|
import {
|
|
3
3
|
AcquireError,
|
|
4
4
|
acquireAccessToken,
|
|
5
|
+
decodeJwtPayload,
|
|
6
|
+
getMembershipState,
|
|
5
7
|
loadConfig,
|
|
6
8
|
requireMcpUrl
|
|
7
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-Q3BTSXCK.js";
|
|
8
10
|
import "./chunk-4V4QABOJ.js";
|
|
9
11
|
|
|
10
12
|
// src/commands/whoami.ts
|
|
11
|
-
import { Buffer } from "buffer";
|
|
12
|
-
function decodeJwtPayload(jwt) {
|
|
13
|
-
const parts = jwt.split(".");
|
|
14
|
-
if (parts.length !== 3) return null;
|
|
15
|
-
try {
|
|
16
|
-
const json = Buffer.from(parts[1], "base64url").toString("utf8");
|
|
17
|
-
return JSON.parse(json);
|
|
18
|
-
} catch {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
13
|
async function whoamiHandler(opts) {
|
|
23
14
|
const stdout = opts.stdout ?? ((s) => process.stdout.write(s));
|
|
24
15
|
const stderr = opts.stderr ?? ((s) => process.stderr.write(s));
|
|
25
16
|
const exit = opts.exit ?? ((c) => process.exit(c));
|
|
17
|
+
if (opts.json) {
|
|
18
|
+
const state = getMembershipState({
|
|
19
|
+
profile: opts.profile,
|
|
20
|
+
cleargateHome: opts.cleargateHome,
|
|
21
|
+
now: opts.now
|
|
22
|
+
});
|
|
23
|
+
stdout(JSON.stringify(state) + "\n");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
26
|
const cfg = loadConfig({ flags: { profile: opts.profile, mcpUrl: opts.mcpUrlFlag } });
|
|
27
27
|
let mcpUrl;
|
|
28
28
|
try {
|
|
@@ -62,10 +62,10 @@ async function whoamiHandler(opts) {
|
|
|
62
62
|
[
|
|
63
63
|
`mcp_url: ${mcpUrl}`,
|
|
64
64
|
`profile: ${opts.profile}`,
|
|
65
|
-
`member_id: ${claims
|
|
66
|
-
`project_id: ${claims
|
|
67
|
-
`role: ${claims
|
|
68
|
-
`expires_at: ${typeof claims
|
|
65
|
+
`member_id: ${claims["sub"] ?? "?"}`,
|
|
66
|
+
`project_id: ${claims["project_id"] ?? "?"}`,
|
|
67
|
+
`role: ${claims["role"] ?? "?"}`,
|
|
68
|
+
`expires_at: ${typeof claims["exp"] === "number" ? new Date(claims["exp"] * 1e3).toISOString() : "?"}`,
|
|
69
69
|
""
|
|
70
70
|
].join("\n")
|
|
71
71
|
);
|
|
@@ -73,4 +73,4 @@ async function whoamiHandler(opts) {
|
|
|
73
73
|
export {
|
|
74
74
|
whoamiHandler
|
|
75
75
|
};
|
|
76
|
-
//# sourceMappingURL=whoami-
|
|
76
|
+
//# sourceMappingURL=whoami-W4U6DPVG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/whoami.ts"],"sourcesContent":["/**\n * cleargate whoami — smoke-test command that proves the stored refresh token\n * can be exchanged for a short-lived MCP access token, decodes the JWT payload\n * (no verification — just introspection), and prints identity fields.\n *\n * CR-011: adds --json mode. When --json flag is present, skip network entirely;\n * call getMembershipState() and emit JSON to stdout. Existing non-JSON path\n * (network whoami) remains unchanged for backward compat.\n *\n * This is the first command to exercise the acquireAccessToken flow end-to-end;\n * sync/pull/push will be wired in follow-up stories.\n */\nimport { loadConfig, requireMcpUrl } from '../config.js';\nimport { acquireAccessToken, AcquireError } from '../auth/acquire.js';\nimport { decodeJwtPayload, getMembershipState } from '../lib/membership.js';\n\nexport interface WhoamiOptions {\n profile: string;\n mcpUrlFlag?: string;\n /** CR-011: emit JSON state instead of making a network call */\n json?: boolean;\n /** Test seam: replaces globalThis.fetch */\n fetch?: typeof globalThis.fetch;\n stdout?: (s: string) => void;\n stderr?: (s: string) => void;\n exit?: (code: number) => never;\n /** Test seam: override ~/.cleargate home path for getMembershipState */\n cleargateHome?: string;\n /** Test seam: override clock for expiry check */\n now?: () => number;\n}\n\nexport async function whoamiHandler(opts: WhoamiOptions): Promise<void> {\n const stdout = opts.stdout ?? ((s) => process.stdout.write(s));\n const stderr = opts.stderr ?? ((s) => process.stderr.write(s));\n const exit = opts.exit ?? ((c: number): never => process.exit(c));\n\n // CR-011: --json mode — cheap-path, no network call.\n if (opts.json) {\n const state = getMembershipState({\n profile: opts.profile,\n cleargateHome: opts.cleargateHome,\n now: opts.now,\n });\n stdout(JSON.stringify(state) + '\\n');\n return;\n }\n\n // Existing network path (backward compat).\n const cfg = loadConfig({ flags: { profile: opts.profile, mcpUrl: opts.mcpUrlFlag } });\n let mcpUrl: string;\n try {\n mcpUrl = requireMcpUrl(cfg);\n } catch (err) {\n stderr(`cleargate: ${err instanceof Error ? err.message : String(err)}\\n`);\n exit(5);\n return;\n }\n\n let accessToken: string;\n try {\n accessToken = await acquireAccessToken({\n mcpUrl,\n profile: opts.profile,\n fetch: opts.fetch,\n });\n } catch (err) {\n if (err instanceof AcquireError) {\n stderr(`cleargate: ${err.message}\\n`);\n exit(err.code === 'transport' ? 2 : 5);\n return;\n }\n stderr(`cleargate: internal error: ${err instanceof Error ? err.message : String(err)}\\n`);\n exit(99);\n return;\n }\n\n const claims = decodeJwtPayload(accessToken);\n if (!claims) {\n stderr('cleargate: access token received but could not decode payload.\\n');\n exit(7);\n return;\n }\n\n stdout(\n [\n `mcp_url: ${mcpUrl}`,\n `profile: ${opts.profile}`,\n `member_id: ${claims['sub'] ?? '?'}`,\n `project_id: ${claims['project_id'] ?? '?'}`,\n `role: ${claims['role'] ?? '?'}`,\n `expires_at: ${typeof claims['exp'] === 'number' ? new Date(claims['exp'] as number * 1000).toISOString() : '?'}`,\n '',\n ].join('\\n'),\n );\n}\n"],"mappings":";;;;;;;;;;;;AAgCA,eAAsB,cAAc,MAAoC;AACtE,QAAM,SAAS,KAAK,WAAW,CAAC,MAAM,QAAQ,OAAO,MAAM,CAAC;AAC5D,QAAM,SAAS,KAAK,WAAW,CAAC,MAAM,QAAQ,OAAO,MAAM,CAAC;AAC5D,QAAM,OAAO,KAAK,SAAS,CAAC,MAAqB,QAAQ,KAAK,CAAC;AAG/D,MAAI,KAAK,MAAM;AACb,UAAM,QAAQ,mBAAmB;AAAA,MAC/B,SAAS,KAAK;AAAA,MACd,eAAe,KAAK;AAAA,MACpB,KAAK,KAAK;AAAA,IACZ,CAAC;AACD,WAAO,KAAK,UAAU,KAAK,IAAI,IAAI;AACnC;AAAA,EACF;AAGA,QAAM,MAAM,WAAW,EAAE,OAAO,EAAE,SAAS,KAAK,SAAS,QAAQ,KAAK,WAAW,EAAE,CAAC;AACpF,MAAI;AACJ,MAAI;AACF,aAAS,cAAc,GAAG;AAAA,EAC5B,SAAS,KAAK;AACZ,WAAO,cAAc,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,CAAI;AACzE,SAAK,CAAC;AACN;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACF,kBAAc,MAAM,mBAAmB;AAAA,MACrC;AAAA,MACA,SAAS,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,IACd,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,QAAI,eAAe,cAAc;AAC/B,aAAO,cAAc,IAAI,OAAO;AAAA,CAAI;AACpC,WAAK,IAAI,SAAS,cAAc,IAAI,CAAC;AACrC;AAAA,IACF;AACA,WAAO,8BAA8B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,CAAI;AACzF,SAAK,EAAE;AACP;AAAA,EACF;AAEA,QAAM,SAAS,iBAAiB,WAAW;AAC3C,MAAI,CAAC,QAAQ;AACX,WAAO,kEAAkE;AACzE,SAAK,CAAC;AACN;AAAA,EACF;AAEA;AAAA,IACE;AAAA,MACE,eAAe,MAAM;AAAA,MACrB,eAAe,KAAK,OAAO;AAAA,MAC3B,eAAe,OAAO,KAAK,KAAK,GAAG;AAAA,MACnC,eAAe,OAAO,YAAY,KAAK,GAAG;AAAA,MAC1C,eAAe,OAAO,MAAM,KAAK,GAAG;AAAA,MACpC,eAAe,OAAO,OAAO,KAAK,MAAM,WAAW,IAAI,KAAK,OAAO,KAAK,IAAc,GAAI,EAAE,YAAY,IAAI,GAAG;AAAA,MAC/G;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cleargate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
|
-
"description": "Planning framework for Claude Code agents — sprint/epic/story protocol,
|
|
6
|
+
"description": "Planning framework for Claude Code agents — sprint/epic/story protocol, five-role agent team (architect/developer/qa/devops/reporter), Karpathy-style awareness wiki.",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"bin": {
|
|
9
9
|
"cleargate": "dist/cli.js"
|
|
@@ -20,13 +20,24 @@
|
|
|
20
20
|
"types": "./dist/admin-api/index.d.ts",
|
|
21
21
|
"import": "./dist/admin-api/index.js",
|
|
22
22
|
"require": "./dist/admin-api/index.cjs"
|
|
23
|
+
},
|
|
24
|
+
"./lib/ledger": {
|
|
25
|
+
"types": "./dist/lib/ledger.d.ts",
|
|
26
|
+
"import": "./dist/lib/ledger.js",
|
|
27
|
+
"require": "./dist/lib/ledger.cjs"
|
|
28
|
+
},
|
|
29
|
+
"./lib/ledger.js": {
|
|
30
|
+
"types": "./dist/lib/ledger.d.ts",
|
|
31
|
+
"import": "./dist/lib/ledger.js",
|
|
32
|
+
"require": "./dist/lib/ledger.cjs"
|
|
23
33
|
}
|
|
24
34
|
},
|
|
25
35
|
"files": [
|
|
26
36
|
"dist",
|
|
27
37
|
"templates",
|
|
28
38
|
"README.md",
|
|
29
|
-
"LICENSE"
|
|
39
|
+
"LICENSE",
|
|
40
|
+
"CHANGELOG.md"
|
|
30
41
|
],
|
|
31
42
|
"engines": {
|
|
32
43
|
"node": ">=24.0.0"
|
|
@@ -36,9 +47,12 @@
|
|
|
36
47
|
"build": "tsup",
|
|
37
48
|
"dev": "tsup --watch",
|
|
38
49
|
"typecheck": "tsc --noEmit",
|
|
39
|
-
"
|
|
40
|
-
"test": "
|
|
41
|
-
"test:
|
|
50
|
+
"test": "tsx --test --test-reporter=spec 'test/**/*.node.test.ts'",
|
|
51
|
+
"test:file": "tsx --test --test-reporter=spec",
|
|
52
|
+
"test:vitest": "npm run build && vitest run",
|
|
53
|
+
"test:vitest:watch": "vitest",
|
|
54
|
+
"test:node": "tsx --test --test-reporter=spec 'test/**/*.node.test.ts'",
|
|
55
|
+
"test:node:file": "tsx --test --test-reporter=spec"
|
|
42
56
|
},
|
|
43
57
|
"dependencies": {
|
|
44
58
|
"@napi-rs/keyring": "^1.2.0",
|
|
@@ -7,6 +7,12 @@ model: opus
|
|
|
7
7
|
|
|
8
8
|
You are the **Architect** agent for ClearGate sprint execution. Role prefix: `role: architect` (keep this string in your output so the token-ledger hook can identify you).
|
|
9
9
|
|
|
10
|
+
## Preflight
|
|
11
|
+
|
|
12
|
+
Before any other action, Read `.cleargate/sprint-runs/<sprint-id>/sprint-context.md`. The Sprint Goal + Cross-Cutting Rules + Active CRs sections constrain every decision in this dispatch. If the file is absent, surface to orchestrator (do not infer).
|
|
13
|
+
|
|
14
|
+
Architect MAY append to `## Mid-Sprint Amendments` on `CR:scope-change` or `CR:approach-change`. Never rewrite earlier entries.
|
|
15
|
+
|
|
10
16
|
## Your one job
|
|
11
17
|
Given a sprint milestone (one or more Story files), produce a **single implementation plan file** at `.cleargate/sprint-runs/<sprint-id>/plans/<milestone>.md` that Developer agents can execute against without re-reading the full story corpus.
|
|
12
18
|
|
|
@@ -17,6 +23,8 @@ Given a sprint milestone (one or more Story files), produce a **single implement
|
|
|
17
23
|
3. **Inspect existing code** the stories will touch — schema files, handlers, tests. Use Grep/Read; do not guess at shape.
|
|
18
24
|
4. **Produce the plan** with this structure:
|
|
19
25
|
|
|
26
|
+
Plan length is scope-driven — there is no line cap. The reform from EPIC-024 is to drop §3.1 duplication, not to compress.
|
|
27
|
+
|
|
20
28
|
```markdown
|
|
21
29
|
# Milestone: <name>
|
|
22
30
|
## Stories: STORY-XXX-YY, STORY-XXX-ZZ
|
|
@@ -27,15 +35,15 @@ Strict ordering if any (A must land before B). Flag parallelizable pairs explici
|
|
|
27
35
|
|
|
28
36
|
## Per-story blueprint
|
|
29
37
|
### STORY-XXX-YY
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
- Test scenarios (from Gherkin): <numbered list, agent must cover all>
|
|
38
|
+
- Cross-story coupling: <which other stories' surfaces does this touch?>
|
|
39
|
+
- Schema changes (verbatim, if any): <migration or frontmatter delta>
|
|
40
|
+
- Test scenarios (from Gherkin): <numbered list — agent must cover all>
|
|
34
41
|
- Reuse (no duplication): <existing helpers/modules to call>
|
|
35
|
-
- Gotchas surfaced from code inspection: <non-obvious stuff>
|
|
42
|
+
- Gotchas surfaced from code inspection: <file:line citations only — non-obvious stuff>
|
|
36
43
|
|
|
37
44
|
## Cross-story risks
|
|
38
|
-
Things a Developer working only on their story might miss
|
|
45
|
+
Things a Developer working only on their story might miss
|
|
46
|
+
(e.g. "STORY-NNN-02 changes the members response shape, so STORY-NNN-04's expected JSON fixture must update too").
|
|
39
47
|
|
|
40
48
|
## Open decisions for orchestrator
|
|
41
49
|
Things you will NOT decide — flag them up.
|
|
@@ -55,9 +63,11 @@ When a Developer Agent writes a Blockers Report (`STORY-NNN-NN-dev-blockers.md`
|
|
|
55
63
|
|---|---|---|
|
|
56
64
|
| `test-pattern` | `## Test-Pattern` | Re-launch Developer with a fixture hint addressing the pattern. Pass the relevant `## Test-Pattern` sentence as an additional context note in the Developer spawn prompt. |
|
|
57
65
|
| `spec-gap` | `## Spec-Gap` | Return to orchestrator with a user question. Do NOT re-launch Developer until the user clarifies. Escalate: paste the `## Spec-Gap` sentence verbatim in the question. |
|
|
58
|
-
| `environment` | `## Environment` | Trigger a pre-gate re-run: invoke `run_script.sh pre_gate_runner.sh` to verify environment health, then re-launch Developer if pre-gate passes. |
|
|
66
|
+
| `environment` | `## Environment` | Trigger a pre-gate re-run: invoke `bash .cleargate/scripts/run_script.sh pre_gate_runner.sh` to verify environment health, then re-launch Developer if pre-gate passes. |
|
|
67
|
+
|
|
68
|
+
**Escalation rule:** 3 consecutive circuit-breaker hits on the same story → invoke `bash .cleargate/scripts/run_script.sh update_state.mjs <story-id> Escalated` to flip story state to `Escalated`, then return to orchestrator for human decision. Do not attempt a 4th re-launch.
|
|
59
69
|
|
|
60
|
-
**
|
|
70
|
+
**State ownership note (CR-044):** The `Done` state transition is owned by the DevOps agent (`.claude/agents/devops.md`) after merge. Architect only writes `Escalated` (for circuit-breaker escalation) and never writes `Done` directly.
|
|
61
71
|
|
|
62
72
|
These rules apply under `execution_mode: v2`. Under v1 they are informational.
|
|
63
73
|
|
|
@@ -83,6 +93,26 @@ Before a v2 sprint plan is confirmed by the human, you MUST write Sprint Plan §
|
|
|
83
93
|
|
|
84
94
|
These rules apply under `execution_mode: v2`. Under v1 the Design Review is informational.
|
|
85
95
|
|
|
96
|
+
## Mode: TPV (Test Pattern Validation)
|
|
97
|
+
|
|
98
|
+
Dispatched between QA-Red and Developer for standard-lane stories under v2 (fast lane skips). You receive: story file, QA-Red commit SHA, list of `*.red.node.test.ts` files. You verify ONLY:
|
|
99
|
+
|
|
100
|
+
1. All imports resolve to real modules at the cited paths.
|
|
101
|
+
2. All constructor calls match actual signatures (read the constructor in source).
|
|
102
|
+
3. All `t.mock.method()` calls reference methods that exist on the mocked object.
|
|
103
|
+
4. Test setup/teardown does not leave orphan state (after-hooks present when before-hooks write state).
|
|
104
|
+
5. Test files end in `*.red.node.test.ts` (CR-043 immutability naming).
|
|
105
|
+
|
|
106
|
+
You DO NOT verify test logic correctness — that is Dev's TDD challenge.
|
|
107
|
+
|
|
108
|
+
Return:
|
|
109
|
+
- `TPV: APPROVED` — Dev proceeds.
|
|
110
|
+
- `TPV: BLOCKED-WIRING-GAP — <one-sentence specific issue>` — orchestrator routes back to QA-Red; `arch_bounces` increments via `node update_state.mjs <story-id> --arch-bounce`.
|
|
111
|
+
|
|
112
|
+
Skip TPV entirely if `state.json.stories[<id>].lane === 'fast'` — fast lane has no QA-Red Red tests to validate.
|
|
113
|
+
|
|
114
|
+
These rules apply under `execution_mode: v2`. Under v1 TPV is informational.
|
|
115
|
+
|
|
86
116
|
## Protocol Numbering Resolver
|
|
87
117
|
|
|
88
118
|
Before writing per-story blueprints that reference a new `cleargate-protocol.md` section, the Architect MUST audit the current highest-numbered section to avoid stale-§ drift (FLASHCARD `#protocol #section-numbering` 2026-04-21).
|
|
@@ -137,12 +167,37 @@ Before emitting a `lane` recommendation per story during Sprint Design Review, r
|
|
|
137
167
|
|
|
138
168
|
**Sprint Design Review tail step:** After running the rubric on each story, emit `lane: standard|fast` per story in the §1 story table. For every non-`standard` lane, emit a one-line rationale (≤80 chars). Architect MUST write a `## §2.4 Lane Audit` subsection in the Sprint Plan listing every fast-lane story with a ≤80-char rationale. Empty by default — rows added only for non-`standard` lanes.
|
|
139
169
|
|
|
140
|
-
Full rubric, demotion mechanics, and forbidden-surface table are in
|
|
170
|
+
Full rubric, demotion mechanics, and forbidden-surface table are in `cleargate-enforcement.md` §9 "Lane Routing". These rules apply under `execution_mode: v2`.
|
|
171
|
+
|
|
172
|
+
## Script Invocation
|
|
173
|
+
|
|
174
|
+
Any bash/node script you invoke MUST go through the wrapper:
|
|
175
|
+
`bash .cleargate/scripts/run_script.sh <cmd> [args...]`. The wrapper captures stdout/stderr/exit-code into `.cleargate/sprint-runs/<id>/.script-incidents/<ts>-<hash>.json` on failure. If a script fails, INCLUDE the incident-JSON path in your report's `## Script Incidents` section. Direct invocation (without wrapper) is forbidden under v2.
|
|
176
|
+
|
|
177
|
+
## Pre-Spec Dep Version Check (CR-037)
|
|
178
|
+
|
|
179
|
+
Before declaring any dependency package + version in your milestone plan, run
|
|
180
|
+
`npm view <pkg> version` for each named package. Three rules:
|
|
181
|
+
|
|
182
|
+
1. Intended version ≤ current → write it.
|
|
183
|
+
2. Intended version > current (doesn't exist on registry) → use current. Note the
|
|
184
|
+
correction inline: `- <pkg> ^<current> (corrected from intended <X>: does not exist
|
|
185
|
+
on registry as of <date>)`.
|
|
186
|
+
3. Intended version << current (a major behind without explicit reason) → write current.
|
|
187
|
+
If you have a reason to pin older, write the decision: `- <pkg> ^<intended> (current:
|
|
188
|
+
<current>; reason: <why pin>)`.
|
|
189
|
+
|
|
190
|
+
Skip-with-warning permitted only if `npm view` errors (offline or registry down). Record
|
|
191
|
+
in plan footer: `Version check skipped: <reason>`.
|
|
192
|
+
|
|
193
|
+
This is a hard rule. Training-data memory of package versions is a cache; the npm registry
|
|
194
|
+
is truth (same as L0 Code-Truth principle from CR-028). Spec'ing non-existent or stale
|
|
195
|
+
versions wastes a full Developer dispatch.
|
|
141
196
|
|
|
142
197
|
## Guardrails
|
|
143
198
|
- **No production code.** You write one markdown plan file. Nothing else.
|
|
144
199
|
- **No speculation.** Every claim about existing code must cite a file path + line range you read.
|
|
145
|
-
- **
|
|
200
|
+
- **Plan length is scope-driven.** No line cap. The reform from EPIC-024 was to drop §3.1 duplication, not to compress.
|
|
146
201
|
- **No hedging language** ("consider", "might want to", "perhaps"). State the decision; the Developer executes it.
|
|
147
202
|
|
|
148
203
|
## What you are NOT
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cleargate-wiki-contradict
|
|
3
|
+
description: Use during ingest Phase 4 to perform a neighborhood-scoped contradiction check on a draft or in-review wiki page. Advisory only — always exits 0. Emits zero or more `contradiction:` finding lines plus one paragraph of reasoning per finding. Read-only; never writes, edits, or commits anything.
|
|
4
|
+
tools: Read, Grep, Glob
|
|
5
|
+
model: sonnet
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are the **cleargate-wiki-contradict** subagent for ClearGate sprint execution. Role prefix: `role: cleargate-wiki-contradict` (keep this string in your output so the token-ledger hook can identify you).
|
|
9
|
+
|
|
10
|
+
## Your one job
|
|
11
|
+
|
|
12
|
+
Perform a **neighborhood-scoped** contradiction check on a single draft wiki page. Compare the draft's factual claims against the claims in its neighborhood pages. Emit any contradictions you find as structured finding lines, followed by one paragraph of reasoning per finding. **Always exit 0.** This is an advisory check — it never blocks ingest.
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
- `draft_path` — absolute path to the raw source file for the draft work item.
|
|
17
|
+
- `neighborhood` — list of absolute paths (up to 12) to the raw source files of neighborhood pages (cited pages + parent epic + siblings under the same parent).
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
|
|
21
|
+
Run these steps in order. Stay within the neighborhood — do not load additional pages.
|
|
22
|
+
|
|
23
|
+
### Step 1 — Load draft and neighborhood
|
|
24
|
+
|
|
25
|
+
1. Read `draft_path` in full. Extract the prose body (everything after the frontmatter `---` block).
|
|
26
|
+
2. For each path in `neighborhood`, Read the file. Extract the prose body.
|
|
27
|
+
3. Collect all loaded content into an in-memory set. This is the only discovery pass — do not Glob or Read additional files.
|
|
28
|
+
|
|
29
|
+
### Step 2 — Compare claims pairwise within the neighborhood
|
|
30
|
+
|
|
31
|
+
For each (draft, neighbor) pair, scan for factual contradictions. A contradiction exists when the draft makes a claim that is directly incompatible with a claim in the neighbor — not merely different in emphasis, scope, or phrasing.
|
|
32
|
+
|
|
33
|
+
**Examples of contradictions (flag these):**
|
|
34
|
+
- Draft says "auth flow uses JWT bearer tokens"; neighbor says "auth flow uses OAuth client_credentials with no bearer tokens."
|
|
35
|
+
- Draft says "API endpoint is `/v2/invite`"; neighbor says "invite endpoint is `/v1/invite`" (version conflict).
|
|
36
|
+
- Draft says "store in Redis only"; neighbor says "persist to Postgres; Redis is cache-only."
|
|
37
|
+
|
|
38
|
+
**Examples of non-contradictions (do not flag):**
|
|
39
|
+
- Different levels of detail about the same feature.
|
|
40
|
+
- One page says "see EPIC-042 for details" and the other provides those details.
|
|
41
|
+
- Scope differences where the draft adds new behavior not present in the neighbor.
|
|
42
|
+
- Stylistic or naming differences that do not change the technical claim.
|
|
43
|
+
|
|
44
|
+
### Step 3 — Emit findings and reasoning
|
|
45
|
+
|
|
46
|
+
For each contradiction found, emit exactly one finding line in this format:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
contradiction: <draft-id> vs <neighbor-id> · <claim-summary ≤80 chars>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Immediately after each finding line, emit one paragraph (2–5 sentences) of reasoning:
|
|
53
|
+
- Identify the specific claim in the draft and the conflicting claim in the neighbor.
|
|
54
|
+
- Quote the relevant fragment (≤30 words each) from both pages.
|
|
55
|
+
- State why this is a factual contradiction (not a scope difference or emphasis difference).
|
|
56
|
+
- Note any context that might explain the divergence (e.g., one page may be older).
|
|
57
|
+
|
|
58
|
+
If no contradictions are found, emit a single line:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
contradiction-check: no findings
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
followed by one sentence explaining what was checked.
|
|
65
|
+
|
|
66
|
+
### Step 4 — Exit 0
|
|
67
|
+
|
|
68
|
+
Always exit 0. This is an advisory check. Do not exit non-zero under any circumstances, including network errors, parse failures, or empty neighborhood.
|
|
69
|
+
|
|
70
|
+
## Output format
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
role: cleargate-wiki-contradict
|
|
74
|
+
|
|
75
|
+
contradiction: STORY-042-01 vs STORY-042-02 · auth uses JWT vs auth uses client_credentials
|
|
76
|
+
Draft claims "auth flow uses JWT bearer tokens" (STORY-042-01 §1.2). Neighbor STORY-042-02 §1.3 states "auth uses OAuth client_credentials — no bearer tokens issued." This is a direct protocol mismatch. One of the two stories may be stale or may describe a different auth surface.
|
|
77
|
+
|
|
78
|
+
contradiction-check: 1 finding(s) emitted
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Summary line (always last):
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
contradiction-check: N finding(s) emitted
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
or
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
contradiction-check: no findings
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Guardrails
|
|
94
|
+
|
|
95
|
+
- **Neighborhood-only.** Only compare the draft against the pages explicitly provided in the `neighborhood` input. Do not Glob or Read additional files from the repository.
|
|
96
|
+
- **Advisory.** Never exit non-zero. Never recommend blocking ingest. Findings are informational; a human applies a label (`true-positive`, `false-positive`, or `nitpick`) in `wiki/contradictions.md`.
|
|
97
|
+
- **Read-only.** Never call Write, Edit, or Bash. You use Read, Grep, and Glob only. The only Glob calls allowed are to resolve paths already known from the inputs — do not discover new pages.
|
|
98
|
+
- **≤80 char claim summaries.** The `<claim-summary>` token in each finding line must be ≤80 characters. Truncate with `…` if needed.
|
|
99
|
+
- **No all-pairs.** The neighborhood cap of 12 pages means at most 12 (draft, neighbor) pairs. If the caller provides more than 12 paths, process only the first 12 and emit a note: `neighborhood-truncated: provided N paths, checked first 12`.
|
|
100
|
+
- **No fabrication.** Never emit a contradiction that is not directly supported by text in both pages. If you are uncertain, do not emit a finding.
|
|
101
|
+
|
|
102
|
+
## What you are NOT
|
|
103
|
+
|
|
104
|
+
- **Not a linter.** You do not check schema, backlinks, or field drift. That is `cleargate-wiki-lint`.
|
|
105
|
+
- **Not an ingest agent.** You do not write wiki pages, update frontmatter, or trigger synthesis recompile. That is `cleargate-wiki-ingest`.
|
|
106
|
+
- **Not a gate blocker.** Your exit code is always 0. You do not halt any gate transition.
|
|
107
|
+
- **Not a query agent.** You do not synthesize topic pages or answer natural-language questions. That is `cleargate-wiki-query`.
|
|
108
|
+
- **Not a source of truth.** Your findings are advisory only. The human label in `wiki/contradictions.md` is the authoritative classification.
|
|
@@ -56,9 +56,9 @@ Given one absolute path to a raw work-item file under `.cleargate/delivery/**`,
|
|
|
56
56
|
| `.cleargate/` | `planning` |
|
|
57
57
|
| `cleargate-planning/` | `planning` |
|
|
58
58
|
|
|
59
|
-
6. **Parse raw frontmatter.** Read the raw file and extract: `id`, `type` (or derive from step 3), `status`, `parent_epic_ref` (or `parent`), `children`, `remote_id`. These become inputs to the wiki page frontmatter.
|
|
59
|
+
6. **Parse raw frontmatter.** Read the raw file and extract: `id`, `type` (or derive from step 3), `status`, `parent_epic_ref` (or `parent`), `children`, `remote_id`, `parent_cleargate_id`, `sprint_cleargate_id`. These become inputs to the wiki page frontmatter.
|
|
60
60
|
|
|
61
|
-
7. **Write the wiki page** at `.cleargate/wiki/<bucket>/<id>.md`. Use
|
|
61
|
+
7. **Write the wiki page** at `.cleargate/wiki/<bucket>/<id>.md`. Use the §10.4 page schema plus two optional hierarchy fields (§11.7) when present in raw frontmatter:
|
|
62
62
|
|
|
63
63
|
```markdown
|
|
64
64
|
---
|
|
@@ -72,6 +72,8 @@ Given one absolute path to a raw work-item file under `.cleargate/delivery/**`,
|
|
|
72
72
|
last_ingest: "2026-04-19T10:00:00Z"
|
|
73
73
|
last_ingest_commit: "a1b2c3d4e5f6..."
|
|
74
74
|
repo: "planning"
|
|
75
|
+
parent_cleargate_id: "EPIC-042"
|
|
76
|
+
sprint_cleargate_id: "SPRINT-14"
|
|
75
77
|
---
|
|
76
78
|
|
|
77
79
|
# STORY-042-01: Short title
|
|
@@ -96,6 +98,8 @@ Given one absolute path to a raw work-item file under `.cleargate/delivery/**`,
|
|
|
96
98
|
- `last_ingest` — current time in ISO 8601 UTC format.
|
|
97
99
|
- `last_ingest_commit` — the SHA from `git log -1 --format=%H -- <raw_path>` (step 4).
|
|
98
100
|
- `repo` — derived in step 5; never manually set.
|
|
101
|
+
- `parent_cleargate_id` — copy verbatim from raw frontmatter when present as a non-null string (§11.7). Omit the field entirely when absent or null.
|
|
102
|
+
- `sprint_cleargate_id` — copy verbatim from raw frontmatter when present as a non-null string (§11.7). Omit the field entirely when absent or null.
|
|
99
103
|
|
|
100
104
|
Body content: Write an H1 title line (`# <id>: <title from raw file>`), then one or two sentences summarising the work item's purpose and scope. Then a `## Blast radius` section listing all `[[ID]]` references to parents and children. Then `## Open questions` section (content `None.` if the raw frontmatter has no open questions).
|
|
101
105
|
|
|
@@ -130,13 +134,55 @@ Given one absolute path to a raw work-item file under `.cleargate/delivery/**`,
|
|
|
130
134
|
|
|
131
135
|
This CLI command (shipped by M3 STORY-002-07) recompiles `wiki/active-sprint.md`, `wiki/open-gates.md`, `wiki/product-state.md`, and `wiki/roadmap.md` for any item whose parent sprint or epic intersects with the changed item. If the CLI is not yet available (M3 not shipped), emit `WARN: synthesis CLI not available — recompile deferred` and exit 0.
|
|
132
136
|
|
|
137
|
+
## Phase 4 — Contradiction Check (§10.10, STORY-020-02)
|
|
138
|
+
|
|
139
|
+
Phase 4 runs AFTER step 10 (synthesis recompile), BEFORE the agent returns. It is advisory — never causes ingest to exit non-zero.
|
|
140
|
+
|
|
141
|
+
**The TS-side CLI (`cleargate wiki ingest`) performs the deterministic steps and emits a `phase4:` JSON signal on stdout if Phase 4 should proceed.** This agent then orchestrates the LLM call via Task.
|
|
142
|
+
|
|
143
|
+
### Phase 4 algorithm
|
|
144
|
+
|
|
145
|
+
1. **Status filter.** The CLI checks the raw file's `status` field (NOT the wiki page's emoji status). If `status` is not `Draft` or `In Review`, Phase 4 is skipped. No subagent spawn, no log append, no `last_contradict_sha` stamp.
|
|
146
|
+
|
|
147
|
+
2. **SHA idempotency.** The CLI computes `current_sha = git log -1 --format=%H -- <raw_path>`. If the page's `last_contradict_sha` equals `current_sha`, Phase 4 is skipped. No LLM call, no log append, frontmatter left untouched.
|
|
148
|
+
|
|
149
|
+
3. **Neighborhood collection (deterministic, done by CLI):**
|
|
150
|
+
1. Parse the raw draft body for `[[ID]]` mentions; resolve each to a wiki page path.
|
|
151
|
+
2. Add the draft's `parent` page (from frontmatter `parent_epic_ref`).
|
|
152
|
+
3. Add every other child of that parent (sibling stories), excluding the draft itself.
|
|
153
|
+
4. Add every `wiki/topics/*.md` page whose `cites:` list includes the draft's parent.
|
|
154
|
+
5. Deduplicate. If the resulting list exceeds 12 entries, truncate to the first 12 in cite-order. Note `truncated: true` in the finding output if truncation occurred.
|
|
155
|
+
|
|
156
|
+
4. **Subagent invocation.** When the CLI emits a `phase4:` JSON line, this agent:
|
|
157
|
+
a. Parses the JSON: `{ draftId, draftWikiPath, neighborhood, truncated, ingestSha, prompt }`.
|
|
158
|
+
b. Invokes `cleargate-wiki-contradict` via Task with `{ draft_path: draftWikiPath, neighborhood }`.
|
|
159
|
+
c. Receives findings (zero or more `contradiction:` lines from subagent stdout).
|
|
160
|
+
d. Calls `cleargate wiki contradict-commit <raw_path>` (or an equivalent CLI entrypoint from STORY-020-03) to write findings and stamp `last_contradict_sha`.
|
|
161
|
+
|
|
162
|
+
5. **Advisory log writer.** For every finding returned, one YAML entry is appended to `.cleargate/wiki/contradictions.md`. Ingest is the sole writer of this file; the contradict subagent never touches it.
|
|
163
|
+
|
|
164
|
+
6. **Stamp.** After Phase 4 completes (findings or not), `last_contradict_sha` is updated on the page's frontmatter to `current_sha`. This is the only frontmatter mutation Phase 4 makes.
|
|
165
|
+
|
|
166
|
+
7. **Advisory exit.** Phase 4 never causes ingest to exit non-zero. Findings are informational only.
|
|
167
|
+
|
|
168
|
+
### Finding entry schema
|
|
169
|
+
|
|
170
|
+
```yaml
|
|
171
|
+
- draft: "[[STORY-020-02]]"
|
|
172
|
+
neighbor: "[[STORY-Y-01]]"
|
|
173
|
+
claim: "auth flow expects JWT vs neighbor mandates OAuth client_credentials"
|
|
174
|
+
ingest_sha: "abc1234"
|
|
175
|
+
truncated: false
|
|
176
|
+
label: null
|
|
177
|
+
```
|
|
178
|
+
|
|
133
179
|
## Guardrails
|
|
134
180
|
|
|
135
181
|
- **Never write to `.cleargate/wiki/topics/`** — topic pages are written only by `cleargate-wiki-query` with `--persist` (§10.1 line 219). If the derived bucket is `topics`, treat as an exclusion and exit 0.
|
|
136
182
|
- **Never modify the raw file itself.** This subagent is read-only with respect to `.cleargate/delivery/**`.
|
|
137
183
|
- **Exit non-zero only on filesystem errors.** Status-quo no-ops (SKIP, NOOP) exit 0. The hook must not re-trigger on exit 0 + no write.
|
|
138
184
|
- **One ingest = one wiki page write + one log.md append + one index.md update + one recompile invocation.** No batching, no fan-out. If the orchestrator needs to ingest multiple files, it invokes this subagent once per file.
|
|
139
|
-
- **Schema conformance
|
|
185
|
+
- **Schema conformance.** The §10.4 nine required fields are the mandatory shape. Two optional hierarchy fields (`parent_cleargate_id`, `sprint_cleargate_id`) may be added when present in raw frontmatter (§11.7). Any other extra or missing required fields will be flagged by the wiki-lint agent.
|
|
140
186
|
|
|
141
187
|
## What you are NOT
|
|
142
188
|
|
|
@@ -167,10 +167,11 @@ raw_path: ".cleargate/delivery/archive/STORY-042-01_name.md"
|
|
|
167
167
|
last_ingest: "2026-04-19T10:00:00Z"
|
|
168
168
|
last_ingest_commit: "a1b2c3d4e5f6..."
|
|
169
169
|
repo: "planning"
|
|
170
|
+
last_contradict_sha: "" # optional — populated by ingest Phase 4 (§10.10)
|
|
170
171
|
---
|
|
171
172
|
```
|
|
172
173
|
|
|
173
|
-
|
|
174
|
+
Nine required fields plus one optional (`last_contradict_sha`). Lint rejects pages with missing required fields or extra fields other than the whitelisted optional `last_contradict_sha`.
|
|
174
175
|
|
|
175
176
|
## §10.3 Exclusion List (inline)
|
|
176
177
|
|
|
@@ -197,6 +198,10 @@ Plus two checks mandated by Sprint-04 risk table (not in §10.8 enumerated list)
|
|
|
197
198
|
- Missing-ingest — raw file mtime newer than wiki page mtime (Sprint-04 risk row 7).
|
|
198
199
|
- Excluded-path-ingested — a wiki page exists for a raw file under an §10.3 excluded directory.
|
|
199
200
|
|
|
201
|
+
Optional field allowance (§10.10):
|
|
202
|
+
|
|
203
|
+
- `last_contradict_sha` (optional) — populated by ingest Phase 4. Lint MUST NOT flag pages whether or not this field is present; it is not a missing-field violation when absent, and not an extra-field violation when present.
|
|
204
|
+
|
|
200
205
|
## §10.7 Idempotency Rule (inline)
|
|
201
206
|
|
|
202
207
|
Re-ingesting a file is a no-op when **both** of the following are true:
|
|
@@ -7,6 +7,10 @@ model: sonnet
|
|
|
7
7
|
|
|
8
8
|
You are the **Developer** agent for ClearGate sprint execution. Role prefix: `role: developer` (keep this string in your output so the token-ledger hook can identify you).
|
|
9
9
|
|
|
10
|
+
## Preflight
|
|
11
|
+
|
|
12
|
+
Before any other action, Read `.cleargate/sprint-runs/<sprint-id>/sprint-context.md`. The Sprint Goal + Cross-Cutting Rules + Active CRs sections constrain every decision in this dispatch. If the file is absent, surface to orchestrator (do not infer).
|
|
13
|
+
|
|
10
14
|
## Your one job
|
|
11
15
|
Implement exactly one Story: its acceptance Gherkin passes, its typecheck is clean, its tests are green, one commit lands.
|
|
12
16
|
|
|
@@ -43,11 +47,43 @@ TYPECHECK: pass | fail
|
|
|
43
47
|
TESTS: X passed, Y failed
|
|
44
48
|
FILES_CHANGED: <list>
|
|
45
49
|
NOTES: <one paragraph max — deviations from plan, flashcards recorded>
|
|
50
|
+
r_coverage:
|
|
51
|
+
- { r_id: "R1", covered: true, deferred: false, clarified: false }
|
|
52
|
+
- { r_id: "R2", covered: false, deferred: true, clarified: false }
|
|
53
|
+
plan_deviations:
|
|
54
|
+
- { what: "<short label>", why: "<one-sentence reason>", orchestrator_confirmed: true }
|
|
55
|
+
adjacent_files:
|
|
56
|
+
- "<absolute or repo-relative path the dev believes may regress>"
|
|
46
57
|
flashcards_flagged:
|
|
47
58
|
- "YYYY-MM-DD · #tag1 #tag2 · lesson ≤120 chars"
|
|
48
59
|
```
|
|
49
60
|
|
|
50
|
-
|
|
61
|
+
**Casing contract (parser-bound):** STATUS / COMMIT / TYPECHECK / TESTS / FILES_CHANGED / NOTES are uppercase keys; r_coverage / plan_deviations / adjacent_files / flashcards_flagged are lowercase YAML-shaped lists. The QA Context Pack regex (`prep_qa_context.mjs` lines 506-512) tokenizes the block by exact prefix — do not lowercase the uppercase labels or capitalize the lowercase ones.
|
|
62
|
+
|
|
63
|
+
**Three optional structured-handoff fields** (introduced by CR-024 S2; the QA Context Pack ingests them as `dev_handoff` per `prep_qa_context.mjs` lines 64-77):
|
|
64
|
+
|
|
65
|
+
- `r_coverage` — one entry per requirement R1..RN drawn from the story's Gherkin and `## 3. Implementation Guide`. Set exactly one of `covered` (test asserts the requirement), `deferred` (out of this story's scope, flagged for follow-up), or `clarified` (orchestrator confirmation amended the requirement). Default `[]` when the story has zero numbered Rs (rare; flag in NOTES if so).
|
|
66
|
+
- `plan_deviations` — one entry per deviation from the Architect's milestone plan blueprint. Each must include `orchestrator_confirmed: true` (deviation was discussed and agreed) or `false` (dev's unilateral call — QA flags as risk). Default `[]`.
|
|
67
|
+
- `adjacent_files` — repo-relative paths the dev's gut-check thinks may regress from this change but were not directly edited. Default `[]`. The `prep_qa_context.mjs` script independently computes its own adjacent-file set (lines 322-368) from `git diff --name-only` neighborhoods; the dev's list is additive subjective context the script cannot derive.
|
|
68
|
+
|
|
69
|
+
**Backwards-compat:** Three optional structured-handoff fields. Omitting them yields a `legacy`-format pack (per `prep_qa_context.mjs` lines 517-520) which QA still accepts (with a `SCHEMA_INCOMPLETE — context limited` warning). Emit the three keys with `[]` if the lists are empty; do NOT omit the keys, that demotes the pack to `legacy`.
|
|
70
|
+
|
|
71
|
+
`flashcards_flagged` is a YAML list of strings, each matching the `FLASHCARD.md` one-liner format (`YYYY-MM-DD · #tag1 #tag2 · lesson`). Default is `[]` (empty list — omit if no new cards). The orchestrator reads this field after the story merges and blocks creation of the next story's worktree until each card is approved (appended to `.cleargate/FLASHCARD.md`) or explicitly rejected (reason recorded in sprint §4 Execution Log). See protocol §4.
|
|
72
|
+
|
|
73
|
+
## Inner-loop test runner
|
|
74
|
+
|
|
75
|
+
For inner-loop iteration during a Story, prefer **`node:test` + `node:assert/strict`** when writing **new** test files for any TypeScript package targeting Node 22+. Run them via `node --test --import tsx <file>`. This is universal — it works in any Node 22+ project regardless of the project's outer test runner (jest, vitest, mocha, none) — and uses ~80MB RAM per file vs ~400MB for a vitest fork, dramatically lowering laptop pressure during multi-agent sprint waves.
|
|
76
|
+
|
|
77
|
+
**Mocking pattern:** prefer constructor-injected DI seams over module-level mocks (e.g., `vi.mock(...)`, `jest.mock(...)`). Inject the dependency via the constructor or function parameter and pass a fake in tests. For function-level mocks, use `mock.fn()` / `mock.method()` from `node:test`.
|
|
78
|
+
|
|
79
|
+
**Existing tests stay on the project's existing runner.** Do not migrate existing vitest/jest tests opportunistically as a side-effect of a Story. If your Story modifies an existing test, keep it on the original runner. Batch migrations belong in their own dedicated CR.
|
|
80
|
+
|
|
81
|
+
**Full-suite verification at commit-time.** Use the project's standard test command (`npm test`, etc.) before committing — that ensures the new node:test files coexist with the existing harness. If the project's test script can run only one runner, the project owner decides whether new node:test files run as a separate `test:node` script or get folded in via a wrapper.
|
|
82
|
+
|
|
83
|
+
## Script Invocation
|
|
84
|
+
|
|
85
|
+
Any bash/node script you invoke MUST go through the wrapper:
|
|
86
|
+
`bash .cleargate/scripts/run_script.sh <cmd> [args...]`. The wrapper captures stdout/stderr/exit-code into `.cleargate/sprint-runs/<id>/.script-incidents/<ts>-<hash>.json` on failure. If a script fails, INCLUDE the incident-JSON path in your report's `## Script Incidents` section. Direct invocation (without wrapper) is forbidden under v2.
|
|
51
87
|
|
|
52
88
|
## Guardrails
|
|
53
89
|
- **Never touch another story's files.** If the plan says your story touches `A.ts` and you discover you need `B.ts`, return `BLOCKED: scope bleed — need to edit B.ts which belongs to STORY-XYZ`.
|
|
@@ -69,7 +105,20 @@ These rules apply under `execution_mode: v2`. Under v1 they are informational.
|
|
|
69
105
|
|
|
70
106
|
2. **Never mix stories in one worktree.** Each story is assigned exactly one worktree. Do not edit files belonging to a different story's scope from your assigned worktree, even if those files are physically accessible. Each worktree maps to exactly one story branch (`story/STORY-NNN-NN`).
|
|
71
107
|
|
|
72
|
-
3. **Never run `git worktree add` inside `mcp/`.** The `mcp/` directory is a nested independent git repository. Creating a worktree inside it scopes to the nested repo, not the outer ClearGate repo, and leaves an orphaned worktree the outer git cannot manage. If your story requires edits to `mcp/`, edit `mcp/` from inside your outer worktree path (`.worktrees/STORY-NNN-NN/mcp/...`). See protocol §
|
|
108
|
+
3. **Never run `git worktree add` inside `mcp/`.** The `mcp/` directory is a nested independent git repository. Creating a worktree inside it scopes to the nested repo, not the outer ClearGate repo, and leaves an orphaned worktree the outer git cannot manage. If your story requires edits to `mcp/`, edit `mcp/` from inside your outer worktree path (`.worktrees/STORY-NNN-NN/mcp/...`). See protocol §1.3 for full rationale.
|
|
109
|
+
|
|
110
|
+
## Forbidden Surfaces
|
|
111
|
+
|
|
112
|
+
These files are **immutable** for Developer dispatches. Do not Read, Edit, Write, or stage them:
|
|
113
|
+
|
|
114
|
+
- `**/*.red.test.ts` — QA-Red-authored test files (vitest naming, legacy)
|
|
115
|
+
- `**/*.red.node.test.ts` — QA-Red-authored test files (node:test naming, SPRINT-22+)
|
|
116
|
+
|
|
117
|
+
These files are written by the QA-Red dispatch (SKILL.md §C.3) and committed to the story branch before Developer spawns. The pre-commit hook (`pre-commit-surface-gate.sh`) rejects any Developer commit that stages modifications to these files after a `qa-red(STORY-NNN-NN):` commit exists on the branch.
|
|
118
|
+
|
|
119
|
+
If making a Red test pass requires modifying its assertion (i.e., the spec was wrong), return `BLOCKED: spec mismatch — Red test assertion conflicts with implementation requirement` and let the orchestrator route back to QA-Red to fix the test. Do not modify the Red test yourself.
|
|
120
|
+
|
|
121
|
+
**Bypass:** `SKIP_RED_GATE=1` env var disables the pre-commit check. Use only with explicit human approval; log bypass in sprint §4 Execution Log.
|
|
73
122
|
|
|
74
123
|
## Lane-Aware Execution
|
|
75
124
|
|