agentplane 0.2.26 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/assets/AGENTS.md +123 -526
- package/assets/agents/UPGRADER.json +10 -9
- package/assets/framework.manifest.json +112 -7
- package/assets/policy/check-routing.mjs +180 -0
- package/assets/policy/dod.code.md +25 -0
- package/assets/policy/dod.core.md +32 -0
- package/assets/policy/dod.docs.md +32 -0
- package/assets/policy/examples/migration-note.md +6 -0
- package/assets/policy/examples/pr-note.md +16 -0
- package/assets/policy/examples/unit-test-pattern.md +19 -0
- package/assets/policy/governance.md +37 -0
- package/assets/policy/incidents.md +36 -0
- package/assets/policy/security.must.md +7 -0
- package/assets/policy/workflow.branch_pr.md +34 -0
- package/assets/policy/workflow.direct.md +46 -0
- package/assets/policy/workflow.md +9 -0
- package/assets/policy/workflow.release.md +31 -0
- package/assets/policy/workflow.upgrade.md +20 -0
- package/bin/agentplane.js +41 -88
- package/bin/dist-guard.js +124 -0
- package/dist/.build-manifest.json +5 -5
- package/dist/agents/agents-template.d.ts +7 -0
- package/dist/agents/agents-template.d.ts.map +1 -1
- package/dist/agents/agents-template.js +41 -2
- package/dist/cli/command-guide.d.ts.map +1 -1
- package/dist/cli/command-guide.js +18 -9
- package/dist/cli/command-snippets.d.ts +1 -1
- package/dist/cli/command-snippets.js +1 -1
- package/dist/cli/run-cli/commands/core.js +2 -2
- package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/ide.js +8 -3
- package/dist/cli/run-cli/commands/init/ui.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/ui.js +1 -2
- package/dist/cli/run-cli/commands/init/write-agents.d.ts +2 -0
- package/dist/cli/run-cli/commands/init/write-agents.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-agents.js +24 -5
- package/dist/cli/run-cli/commands/init/write-workflow.d.ts +5 -0
- package/dist/cli/run-cli/commands/init/write-workflow.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-workflow.js +6 -0
- package/dist/cli/run-cli/commands/init.d.ts +2 -0
- package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init.js +47 -19
- package/dist/cli/run-cli.d.ts.map +1 -1
- package/dist/cli/run-cli.js +125 -7
- package/dist/commands/doctor.run.d.ts.map +1 -1
- package/dist/commands/doctor.run.js +11 -6
- package/dist/commands/release/apply.command.d.ts.map +1 -1
- package/dist/commands/release/apply.command.js +9 -4
- package/dist/commands/release/plan.command.d.ts.map +1 -1
- package/dist/commands/release/plan.command.js +9 -3
- package/dist/commands/task/add.d.ts.map +1 -1
- package/dist/commands/task/add.js +32 -0
- package/dist/commands/task/doc.command.d.ts.map +1 -1
- package/dist/commands/task/doc.command.js +1 -0
- package/dist/commands/task/finish.d.ts.map +1 -1
- package/dist/commands/task/finish.js +9 -1
- package/dist/commands/task/new.d.ts.map +1 -1
- package/dist/commands/task/new.js +41 -4
- package/dist/commands/task/plan.d.ts.map +1 -1
- package/dist/commands/task/plan.js +7 -1
- package/dist/commands/task/shared.d.ts +7 -0
- package/dist/commands/task/shared.d.ts.map +1 -1
- package/dist/commands/task/shared.js +37 -0
- package/dist/commands/task/start-ready.js +1 -1
- package/dist/commands/upgrade.command.d.ts.map +1 -1
- package/dist/commands/upgrade.command.js +2 -2
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +263 -294
- package/dist/commands/workflow-build.command.d.ts.map +1 -1
- package/dist/commands/workflow-build.command.js +7 -0
- package/dist/commands/workflow-playbook.command.d.ts.map +1 -1
- package/dist/commands/workflow-playbook.command.js +0 -1
- package/dist/shared/policy-gateway.d.ts +15 -0
- package/dist/shared/policy-gateway.d.ts.map +1 -0
- package/dist/shared/policy-gateway.js +49 -0
- package/dist/shared/protected-paths.d.ts.map +1 -1
- package/dist/shared/protected-paths.js +1 -0
- package/dist/shared/runtime-artifacts.d.ts +2 -2
- package/dist/shared/runtime-artifacts.d.ts.map +1 -1
- package/dist/shared/runtime-artifacts.js +4 -0
- package/dist/workflow-runtime/build.d.ts +1 -1
- package/dist/workflow-runtime/build.d.ts.map +1 -1
- package/dist/workflow-runtime/build.js +14 -2
- package/package.json +2 -2
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "UPGRADER",
|
|
3
|
-
"role": "
|
|
4
|
-
"description": "
|
|
3
|
+
"role": "Review and finalize framework upgrades after `agentplane upgrade`.",
|
|
4
|
+
"description": "Validates replace-first upgrade results, ensures policy consistency, and preserves local incident history (`.agentplane/policy/incidents.md` append-only).",
|
|
5
5
|
"inputs": [
|
|
6
6
|
"An upgrade run directory (typically `.agentplane/.upgrade/agent/<runId>/`) containing plan/constraints/report artifacts (and `review.json` when available).",
|
|
7
|
-
"The list of files
|
|
8
|
-
"The current workspace versions of `AGENTS.md`
|
|
7
|
+
"The list of changed files from the upgrade report (`files.json` / `review.json`).",
|
|
8
|
+
"The current workspace versions of `AGENTS.md` or `CLAUDE.md`, `.agentplane/agents/*.json`, and `.agentplane/policy/*`."
|
|
9
9
|
],
|
|
10
10
|
"outputs": [
|
|
11
|
-
"
|
|
12
|
-
"A short
|
|
11
|
+
"Validated upgraded policy/agent files with no contradictions against the canonical policy priority order.",
|
|
12
|
+
"A short upgrade review report describing checks run and any follow-up actions.",
|
|
13
13
|
"A commit (direct mode) or PR note/patch (branch_pr) referencing the upgrade run directory used as input."
|
|
14
14
|
],
|
|
15
15
|
"permissions": [
|
|
@@ -20,9 +20,10 @@
|
|
|
20
20
|
"workflow": [
|
|
21
21
|
"Follow shared workflow rules in AGENTS.md and `agentplane quickstart` / `agentplane role <ROLE>` output.",
|
|
22
22
|
"Treat `AGENTS.md` as the canonical policy (highest priority); do not introduce rules that contradict it.",
|
|
23
|
-
"Load the upgrade run artifacts (runDir) and
|
|
24
|
-
"
|
|
25
|
-
"
|
|
23
|
+
"Load the upgrade run artifacts (runDir) and inspect changed files from `files.json` / `review.json`.",
|
|
24
|
+
"Treat managed files as replace-first outputs from upgrade; do not re-introduce manual merge paths.",
|
|
25
|
+
"For `.agentplane/policy/incidents.md`, ensure local history is append-only and not overwritten.",
|
|
26
|
+
"Reconcile `.agentplane/agents/*.json` only when required to remove contradictions with policy.",
|
|
26
27
|
"Run local checks appropriate for the touched surfaces (lint and relevant tests) and record evidence in the task verification log.",
|
|
27
28
|
"Produce a concise report: conflicts, decisions, and resulting file list; reference the runDir for traceability."
|
|
28
29
|
]
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": 1,
|
|
3
3
|
"files": [
|
|
4
|
-
{
|
|
5
|
-
"path": "AGENTS.md",
|
|
6
|
-
"source_path": "AGENTS.md",
|
|
7
|
-
"type": "markdown",
|
|
8
|
-
"merge_strategy": "agents_policy_markdown",
|
|
9
|
-
"required": true
|
|
10
|
-
},
|
|
11
4
|
{
|
|
12
5
|
"path": ".agentplane/agents/CODER.json",
|
|
13
6
|
"source_path": "agents/CODER.json",
|
|
@@ -84,6 +77,118 @@
|
|
|
84
77
|
"type": "json",
|
|
85
78
|
"merge_strategy": "agent_json_3way",
|
|
86
79
|
"required": true
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"path": ".agentplane/policy/check-routing.mjs",
|
|
83
|
+
"source_path": "policy/check-routing.mjs",
|
|
84
|
+
"type": "text",
|
|
85
|
+
"merge_strategy": "agents_policy_markdown",
|
|
86
|
+
"required": true
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"path": ".agentplane/policy/dod.code.md",
|
|
90
|
+
"source_path": "policy/dod.code.md",
|
|
91
|
+
"type": "markdown",
|
|
92
|
+
"merge_strategy": "agents_policy_markdown",
|
|
93
|
+
"required": true
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"path": ".agentplane/policy/dod.core.md",
|
|
97
|
+
"source_path": "policy/dod.core.md",
|
|
98
|
+
"type": "markdown",
|
|
99
|
+
"merge_strategy": "agents_policy_markdown",
|
|
100
|
+
"required": true
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"path": ".agentplane/policy/dod.docs.md",
|
|
104
|
+
"source_path": "policy/dod.docs.md",
|
|
105
|
+
"type": "markdown",
|
|
106
|
+
"merge_strategy": "agents_policy_markdown",
|
|
107
|
+
"required": true
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"path": ".agentplane/policy/examples/migration-note.md",
|
|
111
|
+
"source_path": "policy/examples/migration-note.md",
|
|
112
|
+
"type": "markdown",
|
|
113
|
+
"merge_strategy": "agents_policy_markdown",
|
|
114
|
+
"required": true
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"path": ".agentplane/policy/examples/pr-note.md",
|
|
118
|
+
"source_path": "policy/examples/pr-note.md",
|
|
119
|
+
"type": "markdown",
|
|
120
|
+
"merge_strategy": "agents_policy_markdown",
|
|
121
|
+
"required": true
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"path": ".agentplane/policy/examples/unit-test-pattern.md",
|
|
125
|
+
"source_path": "policy/examples/unit-test-pattern.md",
|
|
126
|
+
"type": "markdown",
|
|
127
|
+
"merge_strategy": "agents_policy_markdown",
|
|
128
|
+
"required": true
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"path": ".agentplane/policy/governance.md",
|
|
132
|
+
"source_path": "policy/governance.md",
|
|
133
|
+
"type": "markdown",
|
|
134
|
+
"merge_strategy": "agents_policy_markdown",
|
|
135
|
+
"required": true
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"path": ".agentplane/policy/incidents.md",
|
|
139
|
+
"source_path": "policy/incidents.md",
|
|
140
|
+
"type": "markdown",
|
|
141
|
+
"merge_strategy": "agents_policy_markdown",
|
|
142
|
+
"required": true
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"path": ".agentplane/policy/security.must.md",
|
|
146
|
+
"source_path": "policy/security.must.md",
|
|
147
|
+
"type": "markdown",
|
|
148
|
+
"merge_strategy": "agents_policy_markdown",
|
|
149
|
+
"required": true
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"path": ".agentplane/policy/workflow.branch_pr.md",
|
|
153
|
+
"source_path": "policy/workflow.branch_pr.md",
|
|
154
|
+
"type": "markdown",
|
|
155
|
+
"merge_strategy": "agents_policy_markdown",
|
|
156
|
+
"required": true
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"path": ".agentplane/policy/workflow.direct.md",
|
|
160
|
+
"source_path": "policy/workflow.direct.md",
|
|
161
|
+
"type": "markdown",
|
|
162
|
+
"merge_strategy": "agents_policy_markdown",
|
|
163
|
+
"required": true
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"path": ".agentplane/policy/workflow.md",
|
|
167
|
+
"source_path": "policy/workflow.md",
|
|
168
|
+
"type": "markdown",
|
|
169
|
+
"merge_strategy": "agents_policy_markdown",
|
|
170
|
+
"required": true
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"path": ".agentplane/policy/workflow.release.md",
|
|
174
|
+
"source_path": "policy/workflow.release.md",
|
|
175
|
+
"type": "markdown",
|
|
176
|
+
"merge_strategy": "agents_policy_markdown",
|
|
177
|
+
"required": true
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"path": ".agentplane/policy/workflow.upgrade.md",
|
|
181
|
+
"source_path": "policy/workflow.upgrade.md",
|
|
182
|
+
"type": "markdown",
|
|
183
|
+
"merge_strategy": "agents_policy_markdown",
|
|
184
|
+
"required": true
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"path": "AGENTS.md",
|
|
188
|
+
"source_path": "AGENTS.md",
|
|
189
|
+
"type": "markdown",
|
|
190
|
+
"merge_strategy": "agents_policy_markdown",
|
|
191
|
+
"required": true
|
|
87
192
|
}
|
|
88
193
|
]
|
|
89
194
|
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
function collectPaths(text, re) {
|
|
5
|
+
const out = [];
|
|
6
|
+
for (const match of text.matchAll(re)) {
|
|
7
|
+
const value = String(match[1] ?? "").trim();
|
|
8
|
+
if (value) out.push(value);
|
|
9
|
+
}
|
|
10
|
+
return out;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function isRepoRelative(p) {
|
|
14
|
+
if (!p) return false;
|
|
15
|
+
if (path.isAbsolute(p)) return false;
|
|
16
|
+
if (p.startsWith("../") || p.includes("/../")) return false;
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function readLines(filePath) {
|
|
21
|
+
return fs.readFileSync(filePath, "utf8").split(/\r?\n/).length;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function assertFilesExist(repoRoot, paths, label, errors) {
|
|
25
|
+
for (const relPath of paths) {
|
|
26
|
+
if (!isRepoRelative(relPath)) {
|
|
27
|
+
errors.push(`${label} path is not repo-relative: ${relPath}`);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const absPath = path.join(repoRoot, relPath);
|
|
31
|
+
if (!fs.existsSync(absPath)) {
|
|
32
|
+
errors.push(`${label} path does not exist: ${relPath}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function listFilesRecursive(dirPath, relPrefix = "") {
|
|
38
|
+
if (!fs.existsSync(dirPath)) return [];
|
|
39
|
+
const entries = fs.readdirSync(dirPath).toSorted((a, b) => a.localeCompare(b));
|
|
40
|
+
const out = [];
|
|
41
|
+
for (const entry of entries) {
|
|
42
|
+
if (entry.startsWith(".")) continue;
|
|
43
|
+
const abs = path.join(dirPath, entry);
|
|
44
|
+
const rel = relPrefix ? `${relPrefix}/${entry}` : entry;
|
|
45
|
+
const st = fs.statSync(abs);
|
|
46
|
+
if (st.isDirectory()) {
|
|
47
|
+
out.push(...listFilesRecursive(abs, rel));
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (st.isFile()) out.push(rel);
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function main() {
|
|
56
|
+
const repoRoot = process.cwd();
|
|
57
|
+
const codexPath = path.join(repoRoot, "AGENTS.md");
|
|
58
|
+
const claudePath = path.join(repoRoot, "CLAUDE.md");
|
|
59
|
+
const hasCodex = fs.existsSync(codexPath);
|
|
60
|
+
const hasClaude = fs.existsSync(claudePath);
|
|
61
|
+
let gatewayPath = codexPath;
|
|
62
|
+
if (!hasCodex && hasClaude) gatewayPath = claudePath;
|
|
63
|
+
const gatewayFileName = path.basename(gatewayPath);
|
|
64
|
+
if (!hasCodex && !hasClaude) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
"Policy routing check failed:\n- Missing policy gateway file: AGENTS.md or CLAUDE.md",
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
const text = fs.readFileSync(gatewayPath, "utf8");
|
|
70
|
+
const errors = [];
|
|
71
|
+
|
|
72
|
+
const lineCount = text.split(/\r?\n/).length;
|
|
73
|
+
if (lineCount > 250) {
|
|
74
|
+
errors.push(`${gatewayFileName} exceeds policy budget (<=250 lines): got ${lineCount}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const requiredHeadings = [
|
|
78
|
+
"# PURPOSE",
|
|
79
|
+
"## PROJECT",
|
|
80
|
+
"## SOURCES OF TRUTH",
|
|
81
|
+
"## COMMANDS",
|
|
82
|
+
"## TOOLING",
|
|
83
|
+
"## LOAD RULES",
|
|
84
|
+
"## MUST / MUST NOT",
|
|
85
|
+
"## CORE DOD",
|
|
86
|
+
"## SIZE BUDGET",
|
|
87
|
+
"## CANONICAL DOCS",
|
|
88
|
+
"## REFERENCE EXAMPLES",
|
|
89
|
+
];
|
|
90
|
+
for (const heading of requiredHeadings) {
|
|
91
|
+
if (!text.includes(heading)) {
|
|
92
|
+
errors.push(`Missing required heading: ${heading}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (!text.includes("MUST NOT load unrelated policy modules")) {
|
|
97
|
+
errors.push("Missing strict routing guard: MUST NOT load unrelated policy modules");
|
|
98
|
+
}
|
|
99
|
+
if (!text.includes("MUST NOT use wildcard policy paths")) {
|
|
100
|
+
errors.push("Missing strict routing guard: MUST NOT use wildcard policy paths");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (/->\s*LOAD\s+`/i.test(text) || /-\s*IF\s+.*->/i.test(text)) {
|
|
104
|
+
errors.push("Legacy IF/LOAD routing syntax is forbidden; use @path imports in LOAD RULES");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const importPaths = collectPaths(text, /`@([^`\s]+)`/g);
|
|
108
|
+
const docPaths = collectPaths(text, /-\s*DOC\s+`([^`]+)`/g);
|
|
109
|
+
const examplePaths = collectPaths(text, /-\s*EXAMPLE\s+`([^`]+)`/g);
|
|
110
|
+
const wildcardPolicyPaths = [...importPaths, ...docPaths, ...examplePaths].filter((p) =>
|
|
111
|
+
p.includes("*"),
|
|
112
|
+
);
|
|
113
|
+
for (const wildcard of wildcardPolicyPaths) {
|
|
114
|
+
errors.push(`Wildcard policy path is not allowed: ${wildcard}`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (importPaths.length < 6) {
|
|
118
|
+
errors.push(`Expected at least 6 @import paths, got ${importPaths.length}`);
|
|
119
|
+
}
|
|
120
|
+
if (docPaths.length < 6) {
|
|
121
|
+
errors.push(`Expected at least 6 DOC paths, got ${docPaths.length}`);
|
|
122
|
+
}
|
|
123
|
+
if (examplePaths.length < 3) {
|
|
124
|
+
errors.push(`Expected at least 3 EXAMPLE paths, got ${examplePaths.length}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const incidentsPath = ".agentplane/policy/incidents.md";
|
|
128
|
+
if (!docPaths.includes(incidentsPath)) {
|
|
129
|
+
errors.push(`Missing canonical DOC path: ${incidentsPath}`);
|
|
130
|
+
}
|
|
131
|
+
if (!importPaths.includes(incidentsPath)) {
|
|
132
|
+
errors.push(`Missing @import rule for incidents path: ${incidentsPath}`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
assertFilesExist(repoRoot, [...new Set(importPaths)], "IMPORT", errors);
|
|
136
|
+
assertFilesExist(repoRoot, [...new Set(docPaths)], "DOC", errors);
|
|
137
|
+
assertFilesExist(repoRoot, [...new Set(examplePaths)], "EXAMPLE", errors);
|
|
138
|
+
|
|
139
|
+
const policyDir = path.join(repoRoot, ".agentplane", "policy");
|
|
140
|
+
const policyFiles = listFilesRecursive(policyDir);
|
|
141
|
+
const markdownModules = policyFiles.filter((relPath) => relPath.endsWith(".md"));
|
|
142
|
+
|
|
143
|
+
for (const relPath of markdownModules) {
|
|
144
|
+
const abs = path.join(policyDir, relPath);
|
|
145
|
+
const moduleLines = readLines(abs);
|
|
146
|
+
if (moduleLines > 100) {
|
|
147
|
+
errors.push(
|
|
148
|
+
`Policy module exceeds budget (<=100 lines): .agentplane/policy/${relPath} (${moduleLines})`,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const importedMarkdown = [...new Set(importPaths.filter((p) => p.endsWith(".md")))];
|
|
154
|
+
let worstCaseLoadedLines = 0;
|
|
155
|
+
for (const relPath of importedMarkdown) {
|
|
156
|
+
const abs = path.join(repoRoot, relPath);
|
|
157
|
+
if (!fs.existsSync(abs)) continue;
|
|
158
|
+
worstCaseLoadedLines += readLines(abs);
|
|
159
|
+
}
|
|
160
|
+
if (worstCaseLoadedLines > 600) {
|
|
161
|
+
errors.push(
|
|
162
|
+
`Worst-case loaded policy graph exceeds budget (<=600 lines): ${worstCaseLoadedLines}`,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const incidentFiles = policyFiles.filter((relPath) => /incident/i.test(path.basename(relPath)));
|
|
167
|
+
if (incidentFiles.length !== 1 || incidentFiles[0] !== "incidents.md") {
|
|
168
|
+
errors.push(
|
|
169
|
+
`Policy incidents must use a single file (.agentplane/policy/incidents.md). Found: ${incidentFiles.join(", ") || "none"}`,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (errors.length > 0) {
|
|
174
|
+
throw new Error(`Policy routing check failed:\n- ${errors.join("\n- ")}`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
process.stdout.write("policy routing OK\n");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
main();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# DoD: code
|
|
2
|
+
|
|
3
|
+
Apply when task changes implementation/source code.
|
|
4
|
+
|
|
5
|
+
## Minimum checks
|
|
6
|
+
|
|
7
|
+
- `agentplane task verify-show <task-id>` (read declared verification contract first)
|
|
8
|
+
- Run all checks listed in task `## Verify Steps` (or record approved skips)
|
|
9
|
+
- `agentplane verify <task-id> --ok|--rework --by <ROLE> --note "..."`
|
|
10
|
+
|
|
11
|
+
## Verification notes contract
|
|
12
|
+
|
|
13
|
+
Record verification in task notes using this compact template:
|
|
14
|
+
|
|
15
|
+
- `Command`: exact command string.
|
|
16
|
+
- `Result`: `pass` or `fail`.
|
|
17
|
+
- `Evidence`: short output summary (key lines only).
|
|
18
|
+
- `Scope`: what paths/behavior the check covers.
|
|
19
|
+
|
|
20
|
+
For skipped checks, record all fields:
|
|
21
|
+
|
|
22
|
+
- `Skipped`: command not executed.
|
|
23
|
+
- `Reason`: concrete blocker.
|
|
24
|
+
- `Risk`: impact of skipping.
|
|
25
|
+
- `Approval`: who approved the skip.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# DoD: core
|
|
2
|
+
|
|
3
|
+
The task is complete only if all core checks are true:
|
|
4
|
+
|
|
5
|
+
1. Preflight summary was produced.
|
|
6
|
+
2. Plan + task graph was presented and approved.
|
|
7
|
+
3. Executable task traceability exists for all repo mutations.
|
|
8
|
+
4. Required task documentation sections are populated.
|
|
9
|
+
5. Verification steps are executed and results recorded.
|
|
10
|
+
6. Drift was either absent or explicitly re-approved.
|
|
11
|
+
7. Final repo state contains no unintended tracked changes.
|
|
12
|
+
|
|
13
|
+
## Required task notes template
|
|
14
|
+
|
|
15
|
+
Every non-trivial task README must contain non-empty sections:
|
|
16
|
+
|
|
17
|
+
- `Summary`
|
|
18
|
+
- `Scope`
|
|
19
|
+
- `Plan`
|
|
20
|
+
- `Risks`
|
|
21
|
+
- `Verify Steps`
|
|
22
|
+
- `Rollback Plan`
|
|
23
|
+
- `Notes`
|
|
24
|
+
|
|
25
|
+
## Material drift criteria
|
|
26
|
+
|
|
27
|
+
Treat drift as material and require re-approval when at least one is true:
|
|
28
|
+
|
|
29
|
+
- Files outside approved scope are modified.
|
|
30
|
+
- Network or outside-repo access becomes necessary and was not approved.
|
|
31
|
+
- Planned scope expands by more than 5 additional files versus approved plan.
|
|
32
|
+
- Verification contract changes (new required checks, changed pass criteria, or skipped mandatory checks).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# DoD: docs/policy
|
|
2
|
+
|
|
3
|
+
Apply when task changes docs or policy files only.
|
|
4
|
+
|
|
5
|
+
## Minimum checks
|
|
6
|
+
|
|
7
|
+
- `node .agentplane/policy/check-routing.mjs`
|
|
8
|
+
- `agentplane doctor`
|
|
9
|
+
- Targeted lint/tests if docs generation or scripts were changed.
|
|
10
|
+
|
|
11
|
+
## Verification notes contract
|
|
12
|
+
|
|
13
|
+
Record docs/policy verification in task notes using this template:
|
|
14
|
+
|
|
15
|
+
- `Command`: exact command string.
|
|
16
|
+
- `Result`: `pass` or `fail`.
|
|
17
|
+
- `Evidence`: short output summary.
|
|
18
|
+
- `Scope`: changed docs/policy paths covered by the check.
|
|
19
|
+
- `Links`: updated canonical docs/examples referenced by the change.
|
|
20
|
+
|
|
21
|
+
For skipped checks, record:
|
|
22
|
+
|
|
23
|
+
- `Skipped`: command not executed.
|
|
24
|
+
- `Reason`: concrete blocker.
|
|
25
|
+
- `Risk`: impact of skipping.
|
|
26
|
+
- `Approval`: who approved the skip.
|
|
27
|
+
|
|
28
|
+
## Evidence checklist
|
|
29
|
+
|
|
30
|
+
- Confirm canonical links are valid.
|
|
31
|
+
- Confirm no duplicate/conflicting rule text remains.
|
|
32
|
+
- Confirm routing/load-rule examples match actual module paths and commands.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Example: Policy Migration Note
|
|
2
|
+
|
|
3
|
+
- Before: monolithic gateway file mixed policy and procedures.
|
|
4
|
+
- After: policy gateway routes by trigger to explicit canonical modules and one incident log (`.agentplane/policy/incidents.md`).
|
|
5
|
+
- Compatibility: keep one canonical template in `packages/agentplane/assets/AGENTS.md`; render to selected gateway file name at install time.
|
|
6
|
+
- Enforcement: run `node .agentplane/policy/check-routing.mjs` in CI.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Example: PR Note
|
|
2
|
+
|
|
3
|
+
```md
|
|
4
|
+
### Summary
|
|
5
|
+
|
|
6
|
+
Implemented policy-gateway refactor for AGENTS.md and moved workflow detail into modular files.
|
|
7
|
+
|
|
8
|
+
### Verification
|
|
9
|
+
|
|
10
|
+
- node .agentplane/policy/check-routing.mjs
|
|
11
|
+
- bun run agents:check
|
|
12
|
+
|
|
13
|
+
### Risks
|
|
14
|
+
|
|
15
|
+
- Routing ambiguity if new modules are added without updating AGENTS load rules.
|
|
16
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Example: Unit Test Pattern
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
import { execFile } from "node:child_process";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
|
|
8
|
+
const execFileAsync = promisify(execFile);
|
|
9
|
+
|
|
10
|
+
describe("policy routing check", () => {
|
|
11
|
+
it("passes for current repository policy files", async () => {
|
|
12
|
+
await expect(
|
|
13
|
+
execFileAsync("node", ["scripts/check-policy-routing.mjs"], {
|
|
14
|
+
cwd: process.cwd(),
|
|
15
|
+
}),
|
|
16
|
+
).resolves.toBeDefined();
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Policy Governance
|
|
2
|
+
|
|
3
|
+
## Incident source of truth
|
|
4
|
+
|
|
5
|
+
- `.agentplane/policy/incidents.md` is the single incident registry.
|
|
6
|
+
- Incident-derived and situational rules MUST be added only to `incidents.md`.
|
|
7
|
+
- MUST NOT create additional incident policy files under `.agentplane/policy/`.
|
|
8
|
+
|
|
9
|
+
## Stabilization criteria
|
|
10
|
+
|
|
11
|
+
Use `stabilized` only when one of these is true:
|
|
12
|
+
|
|
13
|
+
1. The same failure class recurs at least 2 times in 30 days.
|
|
14
|
+
2. A single Sev-1 / production-blocking failure has reproducible steps and evidence.
|
|
15
|
+
|
|
16
|
+
Promotion from `incidents.md` into canonical policy modules is allowed only when:
|
|
17
|
+
|
|
18
|
+
1. The incident is `stabilized`.
|
|
19
|
+
2. Enforcement is defined (`CI`, `test`, `lint`, or policy check script).
|
|
20
|
+
3. Policy gateway load rules are updated if routing behavior changes.
|
|
21
|
+
|
|
22
|
+
## Canonical module immutability
|
|
23
|
+
|
|
24
|
+
- Canonical modules are immutable by default during feature delivery tasks.
|
|
25
|
+
- Canonical modules MAY be changed only in a dedicated policy task with explicit user approval.
|
|
26
|
+
- Every canonical policy edit MUST include `node .agentplane/policy/check-routing.mjs` in verification evidence.
|
|
27
|
+
|
|
28
|
+
## Policy budget
|
|
29
|
+
|
|
30
|
+
- The policy gateway file (`AGENTS.md` or `CLAUDE.md`) MUST remain compact (target <= 250 lines).
|
|
31
|
+
- Detailed procedures MUST be placed in canonical modules listed in the gateway file.
|
|
32
|
+
- If a policy change needs >20 new lines in the gateway file, move detail to a module and keep only routing + hard gate in gateway.
|
|
33
|
+
|
|
34
|
+
## Rule quality
|
|
35
|
+
|
|
36
|
+
- MUST rules should be enforceable by tooling where possible.
|
|
37
|
+
- Non-enforceable guidance should be marked as SHOULD and kept out of hard-gate sections.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Policy Incidents Log
|
|
2
|
+
|
|
3
|
+
This is the single file for incident-derived and situational policy rules.
|
|
4
|
+
|
|
5
|
+
## Entry contract
|
|
6
|
+
|
|
7
|
+
- Add entries append-only.
|
|
8
|
+
- Every entry MUST include: `id`, `date`, `scope`, `failure`, `rule`, `evidence`, `enforcement`, `state`.
|
|
9
|
+
- `rule` MUST be concrete and testable (`MUST` / `MUST NOT`).
|
|
10
|
+
- `state` values: `open`, `stabilized`, `promoted`.
|
|
11
|
+
|
|
12
|
+
## Entry template
|
|
13
|
+
|
|
14
|
+
- id: `INC-YYYYMMDD-NN`
|
|
15
|
+
- date: `YYYY-MM-DD`
|
|
16
|
+
- scope: `<affected scope>`
|
|
17
|
+
- failure: `<observed failure mode>`
|
|
18
|
+
- rule: `<new or refined MUST/MUST NOT>`
|
|
19
|
+
- evidence: `<task ids / logs / links>`
|
|
20
|
+
- enforcement: `<CI|test|lint|script|manual>`
|
|
21
|
+
- state: `<open|stabilized|promoted>`
|
|
22
|
+
|
|
23
|
+
<!-- example:start
|
|
24
|
+
- id: INC-20260305-01
|
|
25
|
+
- date: 2026-03-05
|
|
26
|
+
- scope: commit-msg hook in repo development mode
|
|
27
|
+
- failure: commit-msg rejected valid commits because stale-dist check blocked src_dirty/git_head_changed
|
|
28
|
+
- rule: commit-msg MUST validate subject semantics and MUST NOT block on stale dist freshness checks
|
|
29
|
+
- evidence: task 20260305-HOOKS-FIX, commit 9fe55c73
|
|
30
|
+
- enforcement: test + hook script
|
|
31
|
+
- state: open
|
|
32
|
+
example:end -->
|
|
33
|
+
|
|
34
|
+
## Entries
|
|
35
|
+
|
|
36
|
+
- None yet.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Security MUST Rules
|
|
2
|
+
|
|
3
|
+
- MUST NOT commit secrets, credentials, or private keys.
|
|
4
|
+
- MUST NOT access outside-repo files without explicit user approval.
|
|
5
|
+
- MUST NOT perform network actions when approval is required and not granted.
|
|
6
|
+
- MUST NOT modify auth/crypto/security-critical codepaths without explicit scope approval.
|
|
7
|
+
- MUST report security-sensitive drift immediately and stop before mutation.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Workflow: branch_pr
|
|
2
|
+
|
|
3
|
+
Use this module when `workflow_mode=branch_pr`.
|
|
4
|
+
|
|
5
|
+
## Required sequence
|
|
6
|
+
|
|
7
|
+
1. CHECKPOINT A: plan/approve on base checkout.
|
|
8
|
+
2. Start work with dedicated task branch + worktree.
|
|
9
|
+
3. Keep single-writer discipline per task worktree.
|
|
10
|
+
4. Publish/update PR artifacts.
|
|
11
|
+
5. Verify on task branch.
|
|
12
|
+
6. CHECKPOINT B: integrate on base branch by INTEGRATOR.
|
|
13
|
+
7. CHECKPOINT C: finish task(s) on base with verification evidence.
|
|
14
|
+
|
|
15
|
+
## Command contract
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
agentplane work start <task-id> --agent <ROLE> --slug <slug> --worktree
|
|
19
|
+
agentplane task start-ready <task-id> --author <ROLE> --body "Start: ..."
|
|
20
|
+
agentplane pr open <task-id> --branch task/<task-id>/<slug> --author <ROLE>
|
|
21
|
+
agentplane pr update <task-id>
|
|
22
|
+
agentplane verify <task-id> --ok|--rework --by <ROLE> --note "..."
|
|
23
|
+
agentplane integrate <task-id> --branch task/<task-id>/<slug> --merge-strategy squash --run-verify
|
|
24
|
+
agentplane finish <task-id> --author INTEGRATOR --body "Verified: ..." --result "..." --commit <git-rev> --close-commit
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Constraints
|
|
28
|
+
|
|
29
|
+
- MUST NOT perform mutating actions before explicit user approval.
|
|
30
|
+
- Task documentation updates MAY be batched within one turn before approval.
|
|
31
|
+
- MUST run `task plan approve` then `task start-ready` as `Step 1 -> wait -> Step 2` (never parallel).
|
|
32
|
+
- MUST stop and request re-approval on material drift.
|
|
33
|
+
- Planning and closure happen on base checkout.
|
|
34
|
+
- Do not export task snapshots from task branches.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Workflow: direct
|
|
2
|
+
|
|
3
|
+
Use this module when `workflow_mode=direct`.
|
|
4
|
+
|
|
5
|
+
## Required sequence
|
|
6
|
+
|
|
7
|
+
1. CHECKPOINT A: run preflight and publish summary.
|
|
8
|
+
2. CHECKPOINT B: build task graph and obtain explicit user approval.
|
|
9
|
+
3. Create/reuse task ID.
|
|
10
|
+
4. Fill task docs (`Summary/Scope/Plan/Risks/Verify Steps/Rollback/Notes`).
|
|
11
|
+
Batched doc updates are allowed: sections may be updated in one turn/message via one full-doc payload or multiple `task doc set` operations, as long as approval has not started yet.
|
|
12
|
+
5. Approve plan (if required), then start task sequentially.
|
|
13
|
+
6. Implement changes in current checkout.
|
|
14
|
+
7. Run verification commands from loaded DoD modules.
|
|
15
|
+
8. Record verification result (`agentplane verify ...`) for the task scope.
|
|
16
|
+
9. CHECKPOINT C: finish task with traceable evidence.
|
|
17
|
+
|
|
18
|
+
## Command contract
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
agentplane task new --title "..." --description "..." --priority med --owner <ROLE> --tag <tag>
|
|
22
|
+
agentplane task plan set <task-id> --text "..." --updated-by <ROLE>
|
|
23
|
+
agentplane task plan approve <task-id> --by ORCHESTRATOR
|
|
24
|
+
agentplane task start-ready <task-id> --author <ROLE> --body "Start: ..."
|
|
25
|
+
agentplane verify <task-id> --ok|--rework --by <ROLE> --note "..."
|
|
26
|
+
agentplane finish <task-id> --author <ROLE> --body "Verified: ..." --result "..." --commit <git-rev> --close-commit
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## ERROR RECOVERY
|
|
30
|
+
|
|
31
|
+
If any step fails:
|
|
32
|
+
|
|
33
|
+
1. Stop mutation immediately.
|
|
34
|
+
2. Record failure details in task `Notes` (`what failed`, `where`, `impact`).
|
|
35
|
+
3. Mark task blocked: `agentplane block <task-id> --author <ROLE> --body "Blocked: ..."`.
|
|
36
|
+
4. Request re-approval before scope/risk changes.
|
|
37
|
+
5. If failure is process/policy-related, append entry to `.agentplane/policy/incidents.md`.
|
|
38
|
+
|
|
39
|
+
## Constraints
|
|
40
|
+
|
|
41
|
+
- MUST NOT perform mutating actions before explicit user approval.
|
|
42
|
+
- Task documentation updates MAY be batched within one turn before approval.
|
|
43
|
+
- MUST run `task plan approve` then `task start-ready` as `Step 1 -> wait -> Step 2` (never parallel).
|
|
44
|
+
- MUST stop and request re-approval on material drift.
|
|
45
|
+
- Do not use worktrees in direct mode.
|
|
46
|
+
- Do not perform `branch_pr`-only operations.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Workflow Policy Index
|
|
2
|
+
|
|
3
|
+
This document is an index for workflow procedures.
|
|
4
|
+
Use `AGENTS.md` load rules to decide which module to read.
|
|
5
|
+
|
|
6
|
+
- Direct workflow: `.agentplane/policy/workflow.direct.md`
|
|
7
|
+
- Branch PR workflow: `.agentplane/policy/workflow.branch_pr.md`
|
|
8
|
+
- Release workflow: `.agentplane/policy/workflow.release.md`
|
|
9
|
+
- Upgrade workflow: `.agentplane/policy/workflow.upgrade.md`
|