@brunosps00/dev-workflow 2.2.0 → 2.4.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/plugin.json +1 -1
- package/CHANGELOG.md +121 -0
- package/README.md +25 -15
- package/lib/constants.js +39 -36
- package/lib/doctor.js +1 -1
- package/lib/init.js +8 -0
- package/lib/instruction-health.js +38 -0
- package/lib/post-update.js +2 -1
- package/lib/validate.js +3 -1
- package/package.json +1 -1
- package/scaffold/agent-registry.json +17 -1
- package/scaffold/agents/core/dw-finding-refuter.md +55 -0
- package/scaffold/config/routing.json +61 -23
- package/scaffold/en/agent-instructions.md +32 -137
- package/scaffold/en/commands/dw-analyze-project.md +2 -0
- package/scaffold/en/commands/dw-autopilot.md +36 -241
- package/scaffold/en/commands/dw-brainstorm.md +1 -1
- package/scaffold/en/commands/dw-bugfix.md +10 -35
- package/scaffold/en/commands/dw-claude-run.md +47 -45
- package/scaffold/en/commands/dw-codex-run.md +48 -45
- package/scaffold/en/commands/dw-context-budget.md +6 -14
- package/scaffold/en/commands/dw-copilot-run.md +47 -41
- package/scaffold/en/commands/dw-find-skills.md +3 -1
- package/scaffold/en/commands/dw-generate-pr.md +2 -2
- package/scaffold/en/commands/dw-goal.md +25 -5
- package/scaffold/en/commands/dw-help.md +3 -3
- package/scaffold/en/commands/dw-install-aws-skills.md +2 -0
- package/scaffold/en/commands/dw-install-azure-skills.md +2 -0
- package/scaffold/en/commands/dw-plan.md +15 -8
- package/scaffold/en/commands/dw-qa.md +3 -0
- package/scaffold/en/commands/dw-resume.md +5 -11
- package/scaffold/en/commands/dw-review.md +154 -10
- package/scaffold/en/commands/dw-run.md +47 -177
- package/scaffold/en/commands/dw-secure-audit.md +4 -0
- package/scaffold/en/commands/dw-skill-health.md +39 -0
- package/scaffold/en/commands/dw-triage.md +8 -0
- package/scaffold/en/commands/dw-update.md +18 -4
- package/scaffold/en/references/automode.md +71 -0
- package/scaffold/en/references/command-routing.md +54 -0
- package/scaffold/en/references/execution-contract.md +55 -0
- package/scaffold/en/references/invariants.md +88 -0
- package/scaffold/en/references/untrusted-input.md +69 -0
- package/scaffold/en/templates/constitution-template.md +1 -0
- package/scaffold/en/templates/frontend-quality-template.md +43 -0
- package/scaffold/en/templates/task-template.md +20 -40
- package/scaffold/en/templates/tasks-template.md +9 -6
- package/scaffold/en/templates/techspec-template.md +4 -0
- package/scaffold/en/templates/triage-record-template.md +5 -0
- package/scaffold/pt-br/agent-instructions.md +32 -137
- package/scaffold/pt-br/commands/dw-analyze-project.md +3 -1
- package/scaffold/pt-br/commands/dw-autopilot.md +36 -241
- package/scaffold/pt-br/commands/dw-brainstorm.md +1 -1
- package/scaffold/pt-br/commands/dw-bugfix.md +10 -35
- package/scaffold/pt-br/commands/dw-claude-run.md +47 -46
- package/scaffold/pt-br/commands/dw-codex-run.md +48 -45
- package/scaffold/pt-br/commands/dw-context-budget.md +6 -14
- package/scaffold/pt-br/commands/dw-copilot-run.md +47 -43
- package/scaffold/pt-br/commands/dw-find-skills.md +3 -1
- package/scaffold/pt-br/commands/dw-generate-pr.md +2 -2
- package/scaffold/pt-br/commands/dw-goal.md +25 -5
- package/scaffold/pt-br/commands/dw-help.md +3 -3
- package/scaffold/pt-br/commands/dw-install-aws-skills.md +2 -0
- package/scaffold/pt-br/commands/dw-install-azure-skills.md +2 -0
- package/scaffold/pt-br/commands/dw-plan.md +15 -8
- package/scaffold/pt-br/commands/dw-qa.md +3 -0
- package/scaffold/pt-br/commands/dw-resume.md +7 -11
- package/scaffold/pt-br/commands/dw-review.md +154 -10
- package/scaffold/pt-br/commands/dw-run.md +47 -177
- package/scaffold/pt-br/commands/dw-secure-audit.md +5 -1
- package/scaffold/pt-br/commands/dw-skill-health.md +39 -0
- package/scaffold/pt-br/commands/dw-triage.md +8 -0
- package/scaffold/pt-br/commands/dw-update.md +18 -4
- package/scaffold/pt-br/references/automode.md +72 -0
- package/scaffold/pt-br/references/command-routing.md +54 -0
- package/scaffold/pt-br/references/execution-contract.md +55 -0
- package/scaffold/pt-br/references/invariants.md +88 -0
- package/scaffold/pt-br/references/untrusted-input.md +70 -0
- package/scaffold/pt-br/templates/constitution-template.md +1 -0
- package/scaffold/pt-br/templates/frontend-quality-template.md +43 -0
- package/scaffold/pt-br/templates/task-template.md +20 -40
- package/scaffold/pt-br/templates/tasks-template.md +9 -6
- package/scaffold/pt-br/templates/techspec-template.md +4 -0
- package/scaffold/pt-br/templates/triage-record-template.md +5 -0
- package/scaffold/scripts/hooks/git-guardrails.mjs +12 -0
- package/scaffold/scripts/hooks/session-cost.mjs +122 -7
- package/scaffold/scripts/lib/workflow-contract.mjs +101 -0
- package/scaffold/skill-registry.json +35 -23
- package/scaffold/skills/dw-chaos-engineering/SKILL.md +126 -0
- package/scaffold/skills/dw-chaos-engineering/references/vector-catalog.md +43 -0
- package/scaffold/skills/dw-cli-run/SKILL.md +39 -215
- package/scaffold/skills/dw-cli-run/references/dispatch-tuning.md +14 -72
- package/scaffold/skills/dw-codebase-intel/SKILL.md +5 -39
- package/scaffold/skills/dw-codebase-intel/agents/intel-updater.md +1 -1
- package/scaffold/skills/dw-codebase-intel/references/agents-detail.md +7 -0
- package/scaffold/skills/dw-codebase-intel/references/files-in-dw-intel-detail.md +16 -0
- package/scaffold/skills/dw-codebase-intel/references/how-dw-intel-reads-this-detail.md +12 -0
- package/scaffold/skills/dw-codebase-intel/references/how-to-compose-the-typical-flow-detail.md +11 -0
- package/scaffold/skills/dw-council/SKILL.md +2 -17
- package/scaffold/skills/dw-council/references/integration-with-other-dw-commands-detail.md +7 -0
- package/scaffold/skills/dw-council/references/phase-2-tensions-and-rebuttals-detail.md +15 -0
- package/scaffold/skills/dw-debug-protocol/references/six-step-triage.md +1 -0
- package/scaffold/skills/dw-domain-modeling/SKILL.md +1 -1
- package/scaffold/skills/dw-execute-phase/SKILL.md +12 -32
- package/scaffold/skills/dw-execute-phase/agents/executor.md +15 -252
- package/scaffold/skills/dw-execute-phase/agents/plan-checker.md +4 -207
- package/scaffold/skills/dw-execute-phase/references/atomic-commits.md +8 -18
- package/scaffold/skills/dw-execute-phase/references/de-sloppify-pass-optional-cleanup-task-detail.md +12 -0
- package/scaffold/skills/dw-execute-phase/references/deviation-rules-during-execution-detail.md +8 -0
- package/scaffold/skills/dw-execute-phase/references/how-the-two-agents-compose-detail.md +7 -0
- package/scaffold/skills/dw-execute-phase/references/plan-verification.md +9 -155
- package/scaffold/skills/dw-execute-phase/references/wave-coordination.md +6 -97
- package/scaffold/skills/dw-git-discipline/SKILL.md +2 -2
- package/scaffold/skills/dw-grilling/SKILL.md +1 -1
- package/scaffold/skills/dw-incident-response/SKILL.md +1 -64
- package/scaffold/skills/dw-incident-response/references/the-five-phases-detail.md +66 -0
- package/scaffold/skills/dw-llm-eval/SKILL.md +6 -53
- package/scaffold/skills/dw-llm-eval/references/agent-tool-use-evaluation-detail.md +23 -0
- package/scaffold/skills/dw-llm-eval/references/anti-patterns-will-block-in-dw-review-code-only-detail.md +9 -0
- package/scaffold/skills/dw-llm-eval/references/bounded-decisions.md +76 -0
- package/scaffold/skills/dw-llm-eval/references/consistency-run-to-run-stability-detail.md +10 -0
- package/scaffold/skills/dw-llm-eval/references/integration-with-dev-workflow-commands-detail.md +6 -0
- package/scaffold/skills/dw-llm-eval/references/judge-calibration.md +5 -0
- package/scaffold/skills/dw-llm-eval/references/the-oracle-ladder-detail.md +15 -0
- package/scaffold/skills/dw-memory/SKILL.md +4 -50
- package/scaffold/skills/dw-memory/references/context-budget.md +8 -56
- package/scaffold/skills/dw-memory/references/promotion-decision-test-detail.md +30 -0
- package/scaffold/skills/dw-minimalism/SKILL.md +4 -5
- package/scaffold/skills/dw-review-rigor/SKILL.md +31 -88
- package/scaffold/skills/dw-review-rigor/references/composition-audit.md +160 -0
- package/scaffold/skills/dw-review-rigor/references/refutation-pass.md +124 -0
- package/scaffold/skills/dw-review-rigor/references/the-five-rules-detail.md +56 -0
- package/scaffold/skills/dw-simplification/SKILL.md +2 -55
- package/scaffold/skills/dw-simplification/references/pattern-recognition-detail.md +11 -0
- package/scaffold/skills/dw-simplification/references/the-five-rules-detail.md +48 -0
- package/scaffold/skills/dw-source-grounding/SKILL.md +21 -56
- package/scaffold/skills/dw-source-grounding/references/the-protocol-detect-fetch-implement-cite-detail.md +58 -0
- package/scaffold/skills/dw-testing-discipline/SKILL.md +25 -177
- package/scaffold/skills/dw-testing-discipline/references/agent-guardrails.md +9 -167
- package/scaffold/skills/dw-testing-discipline/references/core-rules.md +3 -3
- package/scaffold/skills/dw-testing-discipline/references/mutation-testing.md +19 -0
- package/scaffold/skills/dw-testing-discipline/references/patterns.md +3 -12
- package/scaffold/skills/dw-ui-discipline/SKILL.md +2 -59
- package/scaffold/skills/dw-ui-discipline/references/frontend-engineering.md +46 -0
- package/scaffold/skills/dw-ui-discipline/references/the-four-grounding-questions-detail.md +61 -0
- package/scaffold/skills/dw-verify/SKILL.md +26 -148
- package/scaffold/skills/dw-verify/references/verification-discovery-and-attribution.md +2 -2
- package/scaffold/skills/humanizer/SKILL.md +2 -1
- package/scaffold/skills/security-review/SKILL.md +6 -184
- package/scaffold/skills/security-review/references/do-not-flag-detail.md +49 -0
- package/scaffold/skills/security-review/references/modern-threats.md +5 -0
- package/scaffold/skills/security-review/references/quick-patterns-reference-detail.md +56 -0
- package/scaffold/skills/security-review/references/review-process-detail.md +112 -0
- package/scaffold/skills/vercel-react-best-practices/SKILL.md +1 -90
- package/scaffold/skills/vercel-react-best-practices/references/quick-reference-detail.md +92 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
|
|
5
|
+
const tools = new Set(['local', 'codex', 'claude', 'copilot']);
|
|
6
|
+
const tiers = new Set(['light', 'standard', 'heavy']);
|
|
7
|
+
|
|
8
|
+
// A small executable contract for the agent-authored execution-plan.json.
|
|
9
|
+
// This validates assignments, not account access or authorization on its own.
|
|
10
|
+
export function validatePlan(plan) {
|
|
11
|
+
const issues = [];
|
|
12
|
+
if (!plan || !['1.0', '1.1'].includes(plan.schema_version)) return ['Unsupported execution plan schema'];
|
|
13
|
+
if (!Array.isArray(plan.tasks) || !plan.tasks.length) return ['tasks must be a nonempty array'];
|
|
14
|
+
if (typeof plan.approved !== 'boolean') issues.push('approved must be a boolean');
|
|
15
|
+
const ids = new Set();
|
|
16
|
+
for (const task of plan.tasks) {
|
|
17
|
+
if (!task || typeof task.id !== 'string' || !task.id.trim()) {
|
|
18
|
+
issues.push('Every task needs a nonempty string id');
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (ids.has(task.id)) issues.push(`Duplicate task ${task.id}`);
|
|
22
|
+
ids.add(task.id);
|
|
23
|
+
if (!Array.isArray(task.depends_on) || task.depends_on.some(id => typeof id !== 'string')) issues.push(`${task.id}: depends_on must be a string array`);
|
|
24
|
+
if (plan.schema_version === '1.1' && !task.execution) issues.push(`${task.id}: missing execution assignment`);
|
|
25
|
+
if (task.execution) {
|
|
26
|
+
const e = task.execution;
|
|
27
|
+
if (typeof e !== 'object' || Array.isArray(e)) { issues.push(`${task.id}: execution must be an object`); continue; }
|
|
28
|
+
if (!tiers.has(e.complexity)) issues.push(`${task.id}: invalid complexity`);
|
|
29
|
+
if (typeof e.rationale !== 'string' || !e.rationale.trim()) issues.push(`${task.id}: missing rationale`);
|
|
30
|
+
if (!Array.isArray(e.agents) || e.agents.some(a => typeof a !== 'string')) issues.push(`${task.id}: agents must be a string array`);
|
|
31
|
+
for (const assignment of [e, ...(Array.isArray(e.fallbacks) ? e.fallbacks : [])]) {
|
|
32
|
+
if (!assignment || typeof assignment !== 'object' || Array.isArray(assignment)) { issues.push(`${task.id}: invalid fallback assignment`); continue; }
|
|
33
|
+
if (!tools.has(assignment.tool)) issues.push(`${task.id}: invalid tool`);
|
|
34
|
+
if (typeof assignment.model !== 'string' || !assignment.model.trim()) issues.push(`${task.id}: missing model`);
|
|
35
|
+
if (typeof assignment.effort !== 'string' || !assignment.effort.trim()) issues.push(`${task.id}: missing effort`);
|
|
36
|
+
if (assignment.tool !== 'local' && [assignment.model, assignment.effort].includes('inherit')) issues.push(`${task.id}: external assignments must resolve model and effort`);
|
|
37
|
+
}
|
|
38
|
+
if (e.fallbacks !== undefined && !Array.isArray(e.fallbacks)) issues.push(`${task.id}: fallbacks must be an array`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const tasks = new Map(plan.tasks.filter(t => t?.id).map(t => [t.id, t]));
|
|
42
|
+
const visiting = new Set(), visited = new Set();
|
|
43
|
+
function visit(id) {
|
|
44
|
+
if (visiting.has(id)) { issues.push(`Dependency cycle at ${id}`); return; }
|
|
45
|
+
if (visited.has(id)) return;
|
|
46
|
+
visiting.add(id);
|
|
47
|
+
for (const dep of tasks.get(id)?.depends_on || []) {
|
|
48
|
+
if (!ids.has(dep)) issues.push(`${id}: unknown dependency ${dep}`);
|
|
49
|
+
else visit(dep);
|
|
50
|
+
}
|
|
51
|
+
visiting.delete(id); visited.add(id);
|
|
52
|
+
}
|
|
53
|
+
if (!issues.length) for (const id of ids) visit(id);
|
|
54
|
+
return issues;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function resolveAssignment(plan, taskId, availableTools) {
|
|
58
|
+
const issues = validatePlan(plan);
|
|
59
|
+
if (issues.length) throw new Error(issues.join('; '));
|
|
60
|
+
if (plan.approved !== true) throw new Error('Execution plan is not approved');
|
|
61
|
+
const task = plan.tasks.find(t => t.id === taskId);
|
|
62
|
+
if (!task) throw new Error(`Unknown task ${taskId}`);
|
|
63
|
+
// Legacy plans never imply permission to start another CLI.
|
|
64
|
+
const assignment = task.execution || { tool: 'local', model: 'inherit', effort: 'inherit', agents: [] };
|
|
65
|
+
const candidates = [assignment, ...(assignment.fallbacks || [])];
|
|
66
|
+
const chosen = candidates.find(c => availableTools.includes(c.tool));
|
|
67
|
+
if (!chosen) throw new Error(`No approved executor available for ${taskId}`);
|
|
68
|
+
return { ...chosen, agents: assignment.agents || [], fallback: chosen !== assignment };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function readyTasks(plan, completedIds) {
|
|
72
|
+
const issues = validatePlan(plan);
|
|
73
|
+
if (issues.length) throw new Error(issues.join('; '));
|
|
74
|
+
const done = new Set(completedIds);
|
|
75
|
+
return plan.tasks.filter(t => !done.has(t.id) && t.depends_on.every(id => done.has(id))).map(t => t.id);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Callers fingerprint actual inputs (including relevant untracked files) and
|
|
79
|
+
// environment. Unknown values fail closed. Time/message boundaries are irrelevant.
|
|
80
|
+
export function reusableEvidence(evidence, current) {
|
|
81
|
+
if (!evidence || evidence.exit_code !== 0 || !current) return false;
|
|
82
|
+
for (const key of ['command', 'input_fingerprint', 'environment_fingerprint']) {
|
|
83
|
+
if (typeof current[key] !== 'string' || !current[key] || evidence[key] !== current[key]) return false;
|
|
84
|
+
}
|
|
85
|
+
return Array.isArray(current.scope) && current.scope.length > 0 && Array.isArray(evidence.scope)
|
|
86
|
+
&& current.scope.every(item => evidence.scope.includes(item));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
90
|
+
try {
|
|
91
|
+
const [mode, file, taskId, available = 'local'] = process.argv.slice(2);
|
|
92
|
+
if (!['validate', 'resolve', 'ready'].includes(mode) || !file) throw new Error('Usage: workflow-contract.mjs validate|resolve|ready <plan.json> [task-id|completed-csv] [available-tools-csv]');
|
|
93
|
+
const plan = JSON.parse(readFileSync(file, 'utf8'));
|
|
94
|
+
if (mode === 'validate') {
|
|
95
|
+
const issues = validatePlan(plan);
|
|
96
|
+
console.log(JSON.stringify({ status: issues.length ? 'BLOCKED' : 'PASS', issues }));
|
|
97
|
+
if (issues.length) process.exitCode = 1;
|
|
98
|
+
} else if (mode === 'resolve') console.log(JSON.stringify(resolveAssignment(plan, taskId, available.split(','))));
|
|
99
|
+
else console.log(JSON.stringify(readyTasks(plan, taskId ? taskId.split(',') : [])));
|
|
100
|
+
} catch (error) { console.error(error.message); process.exitCode = 1; }
|
|
101
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"trigger": "API QA, endpoint testing, HTTP recipe generation",
|
|
10
10
|
"expected_output": "A selected API testing recipe and evidence path for the active stack.",
|
|
11
11
|
"load_policy": "lazy-references",
|
|
12
|
-
"context_limit":
|
|
12
|
+
"context_limit": 8000,
|
|
13
13
|
"invocation": "explicit",
|
|
14
14
|
"exportable": true,
|
|
15
15
|
"bundled": true
|
|
@@ -22,20 +22,32 @@
|
|
|
22
22
|
"trigger": "Docker Compose service selection or local infrastructure setup",
|
|
23
23
|
"expected_output": "A selected service recipe and composition guidance.",
|
|
24
24
|
"load_policy": "lazy-references",
|
|
25
|
-
"context_limit":
|
|
25
|
+
"context_limit": 8000,
|
|
26
26
|
"invocation": "explicit",
|
|
27
27
|
"exportable": true,
|
|
28
28
|
"bundled": true
|
|
29
29
|
},
|
|
30
|
+
{
|
|
31
|
+
"name": "dw-chaos-engineering",
|
|
32
|
+
"kind": "protocol",
|
|
33
|
+
"tier": "specialty",
|
|
34
|
+
"owner": "manual,dw-qa,dw-review",
|
|
35
|
+
"trigger": "Explicit request to adversarially test or stress an implemented change",
|
|
36
|
+
"expected_output": "Chaos report with per-attack classification, minimal repros, and the routing of each finding.",
|
|
37
|
+
"load_policy": "lazy-references",
|
|
38
|
+
"context_limit": 8000,
|
|
39
|
+
"invocation": "explicit",
|
|
40
|
+
"bundled": true
|
|
41
|
+
},
|
|
30
42
|
{
|
|
31
43
|
"name": "dw-cli-run",
|
|
32
44
|
"kind": "protocol",
|
|
33
45
|
"tier": "core",
|
|
34
46
|
"owner": "dw-codex-run,dw-claude-run,dw-copilot-run",
|
|
35
|
-
"trigger": "
|
|
36
|
-
"expected_output": "
|
|
47
|
+
"trigger": "Execute an approved task through a supported external CLI adapter",
|
|
48
|
+
"expected_output": "Reviewed task handoff with durable session, acceptance evidence and next task or blocker.",
|
|
37
49
|
"load_policy": "lazy-references",
|
|
38
|
-
"context_limit":
|
|
50
|
+
"context_limit": 8000,
|
|
39
51
|
"bundled": true
|
|
40
52
|
},
|
|
41
53
|
{
|
|
@@ -46,7 +58,7 @@
|
|
|
46
58
|
"trigger": "Codebase indexing or codebase intelligence query",
|
|
47
59
|
"expected_output": ".dw/intel index files or a cited answer from the index.",
|
|
48
60
|
"load_policy": "lazy-references",
|
|
49
|
-
"context_limit":
|
|
61
|
+
"context_limit": 8000,
|
|
50
62
|
"bundled": true
|
|
51
63
|
},
|
|
52
64
|
{
|
|
@@ -57,7 +69,7 @@
|
|
|
57
69
|
"trigger": "Council mode or high-impact architectural debate",
|
|
58
70
|
"expected_output": "Advisor positions, tension synthesis, and decision recommendation.",
|
|
59
71
|
"load_policy": "lazy-references",
|
|
60
|
-
"context_limit":
|
|
72
|
+
"context_limit": 8000,
|
|
61
73
|
"bundled": true
|
|
62
74
|
},
|
|
63
75
|
{
|
|
@@ -68,7 +80,7 @@
|
|
|
68
80
|
"trigger": "Native Grill domain vocabulary: challenge fuzzy/overloaded terms, cross-check against code, persist a canonical glossary to .dw/domain",
|
|
69
81
|
"expected_output": "Canonical terms with discouraged synonyms persisted lazily to .dw/domain (single or multi-context), or fuzzy-term findings.",
|
|
70
82
|
"load_policy": "lazy-references",
|
|
71
|
-
"context_limit":
|
|
83
|
+
"context_limit": 8000,
|
|
72
84
|
"exportable": false,
|
|
73
85
|
"bundled": true
|
|
74
86
|
},
|
|
@@ -80,7 +92,7 @@
|
|
|
80
92
|
"trigger": "Native Grill decision-tree interview: sharpen a plan/PRD to shared understanding, exactly one decision per turn with a recommended answer",
|
|
81
93
|
"expected_output": "A dependency-ordered decision tree, resolved decisions with recommendations, and an explicit shared-understanding gate.",
|
|
82
94
|
"load_policy": "lazy-references",
|
|
83
|
-
"context_limit":
|
|
95
|
+
"context_limit": 8000,
|
|
84
96
|
"exportable": false,
|
|
85
97
|
"bundled": true
|
|
86
98
|
},
|
|
@@ -92,7 +104,7 @@
|
|
|
92
104
|
"trigger": "Bugfix, QA fix loop, or non-reproducible failure",
|
|
93
105
|
"expected_output": "Six-step triage, root cause, guard, and verification path.",
|
|
94
106
|
"load_policy": "lazy-references",
|
|
95
|
-
"context_limit":
|
|
107
|
+
"context_limit": 8000,
|
|
96
108
|
"bundled": true
|
|
97
109
|
},
|
|
98
110
|
{
|
|
@@ -103,7 +115,7 @@
|
|
|
103
115
|
"trigger": "Task execution, plan-checking, waves, checkpoint recovery",
|
|
104
116
|
"expected_output": "Plan-check verdict, wave execution report, or checkpoint summary.",
|
|
105
117
|
"load_policy": "lazy-references",
|
|
106
|
-
"context_limit":
|
|
118
|
+
"context_limit": 8000,
|
|
107
119
|
"bundled": true
|
|
108
120
|
},
|
|
109
121
|
{
|
|
@@ -114,7 +126,7 @@
|
|
|
114
126
|
"trigger": "Commit creation, branch hygiene, PR generation",
|
|
115
127
|
"expected_output": "Atomic commit plan and git hygiene checks.",
|
|
116
128
|
"load_policy": "lazy-references",
|
|
117
|
-
"context_limit":
|
|
129
|
+
"context_limit": 8000,
|
|
118
130
|
"bundled": true
|
|
119
131
|
},
|
|
120
132
|
{
|
|
@@ -125,7 +137,7 @@
|
|
|
125
137
|
"trigger": "Production critical bug, outage, incident, SEV workflow",
|
|
126
138
|
"expected_output": "Incident triage, communication, resolution, and postmortem artifacts.",
|
|
127
139
|
"load_policy": "lazy-references",
|
|
128
|
-
"context_limit":
|
|
140
|
+
"context_limit": 8000,
|
|
129
141
|
"bundled": true
|
|
130
142
|
},
|
|
131
143
|
{
|
|
@@ -136,7 +148,7 @@
|
|
|
136
148
|
"trigger": "AI, LLM, RAG, classifier, agent, or tool-use feature",
|
|
137
149
|
"expected_output": "Eval strategy, oracle choice, dataset requirements, and result checks.",
|
|
138
150
|
"load_policy": "lazy-references",
|
|
139
|
-
"context_limit":
|
|
151
|
+
"context_limit": 8000,
|
|
140
152
|
"bundled": true
|
|
141
153
|
},
|
|
142
154
|
{
|
|
@@ -147,7 +159,7 @@
|
|
|
147
159
|
"trigger": "Task execution memory, checkpointing, compaction",
|
|
148
160
|
"expected_output": "Updated workflow memory and task-local memory guidance.",
|
|
149
161
|
"load_policy": "lazy-references",
|
|
150
|
-
"context_limit":
|
|
162
|
+
"context_limit": 8000,
|
|
151
163
|
"bundled": true
|
|
152
164
|
},
|
|
153
165
|
{
|
|
@@ -171,7 +183,7 @@
|
|
|
171
183
|
"trigger": "Code review, implementation review, or review consolidation",
|
|
172
184
|
"expected_output": "Deduplicated findings ordered by defensible severity.",
|
|
173
185
|
"load_policy": "always-small",
|
|
174
|
-
"context_limit":
|
|
186
|
+
"context_limit": 8000,
|
|
175
187
|
"bundled": true
|
|
176
188
|
},
|
|
177
189
|
{
|
|
@@ -205,7 +217,7 @@
|
|
|
205
217
|
"trigger": "Refactor analysis, code smells, complexity, or behavior-preserving simplification",
|
|
206
218
|
"expected_output": "Simplification target, risk, behavior-preserving checks, and recommendation.",
|
|
207
219
|
"load_policy": "lazy-references",
|
|
208
|
-
"context_limit":
|
|
220
|
+
"context_limit": 8000,
|
|
209
221
|
"exportable": true,
|
|
210
222
|
"bundled": true
|
|
211
223
|
},
|
|
@@ -217,7 +229,7 @@
|
|
|
217
229
|
"trigger": "Library/framework/API decision, technical research, dependency audit",
|
|
218
230
|
"expected_output": "Cited source-grounded decision with version and retrieval date.",
|
|
219
231
|
"load_policy": "lazy-references",
|
|
220
|
-
"context_limit":
|
|
232
|
+
"context_limit": 8000,
|
|
221
233
|
"bundled": true
|
|
222
234
|
},
|
|
223
235
|
{
|
|
@@ -228,7 +240,7 @@
|
|
|
228
240
|
"trigger": "Writing, reviewing, or debugging tests",
|
|
229
241
|
"expected_output": "Test placement, invariant, anti-pattern checks, and verification guidance.",
|
|
230
242
|
"load_policy": "lazy-references",
|
|
231
|
-
"context_limit":
|
|
243
|
+
"context_limit": 8000,
|
|
232
244
|
"bundled": true
|
|
233
245
|
},
|
|
234
246
|
{
|
|
@@ -239,7 +251,7 @@
|
|
|
239
251
|
"trigger": "UI design, redesign, visual QA, accessibility, or frontend polish",
|
|
240
252
|
"expected_output": "Grounding answers, state matrix, accessibility checks, and visual risks.",
|
|
241
253
|
"load_policy": "lazy-references",
|
|
242
|
-
"context_limit":
|
|
254
|
+
"context_limit": 8000,
|
|
243
255
|
"bundled": true
|
|
244
256
|
},
|
|
245
257
|
{
|
|
@@ -250,7 +262,7 @@
|
|
|
250
262
|
"trigger": "Completion claim, commit, PR generation, or fixed bug status",
|
|
251
263
|
"expected_output": "Fresh verification report with cited command evidence.",
|
|
252
264
|
"load_policy": "always-small",
|
|
253
|
-
"context_limit":
|
|
265
|
+
"context_limit": 8000,
|
|
254
266
|
"exportable": true,
|
|
255
267
|
"bundled": true
|
|
256
268
|
},
|
|
@@ -288,7 +300,7 @@
|
|
|
288
300
|
"trigger": "Security review, sensitive code, OWASP checks, auth/payment/input surfaces",
|
|
289
301
|
"expected_output": "High-confidence security findings or explicit pass.",
|
|
290
302
|
"load_policy": "lazy-references",
|
|
291
|
-
"context_limit":
|
|
303
|
+
"context_limit": 8000,
|
|
292
304
|
"exportable": true,
|
|
293
305
|
"bundled": true
|
|
294
306
|
},
|
|
@@ -300,7 +312,7 @@
|
|
|
300
312
|
"trigger": "React/Next.js performance, hydration, data fetching, bundle or render issues",
|
|
301
313
|
"expected_output": "Selected performance rule references and metric-driven recommendations.",
|
|
302
314
|
"load_policy": "lazy-references",
|
|
303
|
-
"context_limit":
|
|
315
|
+
"context_limit": 8000,
|
|
304
316
|
"invocation": "explicit",
|
|
305
317
|
"exportable": true,
|
|
306
318
|
"bundled": true
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dw-chaos-engineering
|
|
3
|
+
description: Use to adversarially test a change you just implemented. Maps the attack surface, writes tests that try to break it, classifies each KILLED/SURVIVED/INCONCLUSIVE. Local only, writes tests only, 3 rounds max. Ask for it by name.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Write
|
|
7
|
+
- Bash
|
|
8
|
+
- Grep
|
|
9
|
+
- Glob
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Chaos Engineering
|
|
13
|
+
|
|
14
|
+
> Adapted from the chaos-engineering skill in [`samsantosb/ship-it`](https://github.com/samsantosb/ship-it)
|
|
15
|
+
> (MIT © Samuel Santos). The vector catalogue and the KILLED/SURVIVED/INCONCLUSIVE vocabulary come from
|
|
16
|
+
> there; target resolution, criticality anchoring and finding routing are rewritten for `.dw/`.
|
|
17
|
+
|
|
18
|
+
Where the rest of the pipeline builds, this tries to break. It takes a change that is already implemented
|
|
19
|
+
and writes tests whose only purpose is to prove it fails.
|
|
20
|
+
|
|
21
|
+
**An attack that SURVIVED is also a result.** The goal is not bugs at any cost — it is mapping where the
|
|
22
|
+
code holds and where it gives, and leaving the tests that matter as regression inheritance.
|
|
23
|
+
|
|
24
|
+
## When to use
|
|
25
|
+
|
|
26
|
+
Invoked by name, never automatically — it writes files, runs the suite and costs real time. Ask for it
|
|
27
|
+
after an implementation is complete and its normal tests pass: post-`/dw-run`, post-`/dw-bugfix`, or on an
|
|
28
|
+
open PR before merge.
|
|
29
|
+
|
|
30
|
+
Do not use it to find a known bug (that is `/dw-bugfix`), to review code (`/dw-review`), or on a change
|
|
31
|
+
that has no tests yet — chaos measures resilience, it does not substitute for coverage.
|
|
32
|
+
|
|
33
|
+
## Step 0 — Baseline gate
|
|
34
|
+
|
|
35
|
+
**The target's existing tests must pass before any attack.** Run the project's configured suite scoped to
|
|
36
|
+
the touched files.
|
|
37
|
+
|
|
38
|
+
A red baseline stops the run. With a broken environment you cannot tell a finding from noise, and every
|
|
39
|
+
subsequent classification is worthless. Report the failing baseline and stop — that is a `BLOCKED` outcome
|
|
40
|
+
under `.dw/references/automode.md`, not a failed run.
|
|
41
|
+
|
|
42
|
+
## Step 1 — Resolve the target
|
|
43
|
+
|
|
44
|
+
First that exists: the PR diff · the local diff against the base branch · the files named in
|
|
45
|
+
`.dw/spec/<prd>/tasks/` or `.dw/bugfixes/<slug>/TASK.md`. Only what changed is in scope — the rest of the
|
|
46
|
+
repository is not the target.
|
|
47
|
+
|
|
48
|
+
Read the acceptance criteria if the target has them. Every promise is attackable by negation.
|
|
49
|
+
|
|
50
|
+
## Step 2 — Attack plan
|
|
51
|
+
|
|
52
|
+
Cross the diff with `references/vector-catalog.md` and select the vectors that actually apply. Not every
|
|
53
|
+
vector fits every diff; prioritize by impact × probability.
|
|
54
|
+
|
|
55
|
+
**Criticality is anchored, not assumed.** `.dw/rules/concerns.md` (the Concerns Map) and
|
|
56
|
+
`.dw/constitution.md` define what is critical *in this project*. Without them severity is opinion; with
|
|
57
|
+
them, a finding against the thing the project protects is critical by definition.
|
|
58
|
+
|
|
59
|
+
Show the plan before building: target, surface, selected vectors as hypotheses, and the vectors left out
|
|
60
|
+
with one line each on why.
|
|
61
|
+
|
|
62
|
+
## Step 3 — Build the arsenal
|
|
63
|
+
|
|
64
|
+
Follow the project's test conventions and the `dw-testing-discipline` skill — it owns *how* a test is
|
|
65
|
+
written (the anti-pattern catalogue, the agent guardrails, flaky discipline). This skill owns only the
|
|
66
|
+
attack protocol.
|
|
67
|
+
|
|
68
|
+
- One group per vector, one case per attack, named for the hypothesis rather than the implementation.
|
|
69
|
+
- **Simulate hostility with mocks and fixtures.** The test describes a hostile world; it never depends on
|
|
70
|
+
a real one.
|
|
71
|
+
- **Each attack asserts the CORRECT behaviour** — what the system should do under chaos — never the bug.
|
|
72
|
+
So a failing attack is a real finding, and the same test becomes a free regression once it is fixed.
|
|
73
|
+
|
|
74
|
+
## Step 4 — Run and classify
|
|
75
|
+
|
|
76
|
+
- **KILLED** — the attack broke it. Produce the minimal reproduction: the smallest hostile input that
|
|
77
|
+
still kills.
|
|
78
|
+
- **SURVIVED** — the code held. A result, not a wasted test.
|
|
79
|
+
- **INCONCLUSIVE** — the *test* is wrong (bad mock, flake, environment limit). Fix and rerun, at most
|
|
80
|
+
twice; still inconclusive after that, record it as such and drop it. Never inflate the report.
|
|
81
|
+
|
|
82
|
+
**Round cap: 3.** The initial plan plus at most two deepening rounds on what killed or nearly did. The
|
|
83
|
+
INCONCLUSIVE retry cap is independent — never burn a round chasing a verdict on a broken test.
|
|
84
|
+
|
|
85
|
+
## Step 5 — Triage
|
|
86
|
+
|
|
87
|
+
Severity comes from the criticality anchor, not from how alarming the input looked.
|
|
88
|
+
|
|
89
|
+
Before sealing each finding, apply the **defense-lawyer test**: is there a reading where this behaviour is
|
|
90
|
+
intentional — an ADR, a project rule, an adjacent comment? If yes, mark it `contestable` and record the
|
|
91
|
+
doubt. The report separates fact from interpretation, the same way `dw-review-rigor` separates a finding
|
|
92
|
+
from an unresolved lead.
|
|
93
|
+
|
|
94
|
+
## Step 6 — Report and routing
|
|
95
|
+
|
|
96
|
+
Report to `<target>/QA/chaos-report.md`, following the target convention `/dw-qa` already uses.
|
|
97
|
+
|
|
98
|
+
Where each result goes:
|
|
99
|
+
|
|
100
|
+
| Result | Destination |
|
|
101
|
+
|---|---|
|
|
102
|
+
| SURVIVED covering a real gap no existing test covered | Promote as a permanent regression |
|
|
103
|
+
| KILLED on an open PR | Test ships **unskipped** — it blocks the merge on purpose, and `/dw-review` rejects |
|
|
104
|
+
| KILLED on already-merged code | Open `.dw/bugfixes/NNN-slug/` via `/dw-bugfix`; never reopen the landed work |
|
|
105
|
+
| SURVIVED but redundant, or INCONCLUSIVE | Discard. The arsenal is not an accumulation |
|
|
106
|
+
|
|
107
|
+
## Hard limits
|
|
108
|
+
|
|
109
|
+
- **Local only.** Never fire a request at staging, production or a partner API. A hostile world is
|
|
110
|
+
simulated, without exception.
|
|
111
|
+
- **Tests only.** Production code is read-only here. Finding and fixing are separate roles by design.
|
|
112
|
+
- **Three rounds.** Infinite chaos is procrastination with extra steps.
|
|
113
|
+
- **No theatrical chaos**: no scenarios impossible by construction to pad the report, no asserting the
|
|
114
|
+
current buggy behaviour, and no calling KILLED when what broke was the mock or the clock.
|
|
115
|
+
- Never leave a red test ownerless. A KILLED on an open PR blocks merge on purpose — that is the signal
|
|
116
|
+
working. A red suite with no report and no owner is sabotage.
|
|
117
|
+
|
|
118
|
+
## Structured Return
|
|
119
|
+
|
|
120
|
+
- **Status:** `PASS` when the run completed with no unfixed KILLED, `FINDINGS` when attacks killed, `BLOCKED` when the baseline is red or the target cannot be resolved, `NOT_APPLICABLE` when no implemented change is in scope.
|
|
121
|
+
- **Scope:** target resolved, files attacked, vectors selected and vectors deliberately skipped.
|
|
122
|
+
- **Evidence:** per-attack classification with the minimal reproduction for each kill, and the baseline result.
|
|
123
|
+
- **Artifacts:** chaos report path, test files written, and where each shipped.
|
|
124
|
+
- **Decisions:** vector selection, severity anchoring, and every `contestable` downgrade with its reading.
|
|
125
|
+
- **Risks:** inconclusive attacks, vectors out of scope, and coverage the rounds did not reach.
|
|
126
|
+
- **Next Step:** the fix route for each kill (`/dw-bugfix` or the PR's own branch), or merge-clean.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Vector catalogue
|
|
2
|
+
|
|
3
|
+
Cross the diff with this list and pick what applies. Selecting every vector for every diff is how a chaos
|
|
4
|
+
run turns into theatre — the skipped vectors, each with one line on why, are part of the plan.
|
|
5
|
+
|
|
6
|
+
## Boundaries
|
|
7
|
+
Zero · negative · `MAX_SAFE_INTEGER` and the language's numeric ceiling · empty, one, and N+1 · the
|
|
8
|
+
off-by-one at a page or batch edge · leap day · a timezone that is not the author's · DST transition.
|
|
9
|
+
|
|
10
|
+
## Nulls and absence
|
|
11
|
+
An optional field omitted entirely (not sent as null) · `null` versus `undefined` where the code treats
|
|
12
|
+
them alike · empty object versus missing object · a field the external API stopped returning.
|
|
13
|
+
|
|
14
|
+
## Broken money
|
|
15
|
+
Rounding at the cent · installments that do not sum to the total · negative amounts · a discount above
|
|
16
|
+
100% · float arithmetic where decimal is required · currency mismatch · a refund larger than the payment.
|
|
17
|
+
|
|
18
|
+
## Hostile dependencies
|
|
19
|
+
The external API returns 500 · 429 with and without `Retry-After` · a timeout with no response at all ·
|
|
20
|
+
truncated JSON · valid JSON with the wrong shape · the cache is down · a database deadlock · a job dies
|
|
21
|
+
mid-flight leaving its work half-applied.
|
|
22
|
+
|
|
23
|
+
## Concurrency and idempotency
|
|
24
|
+
The same request submitted twice · a duplicated webhook · a job reprocessed after a retry · a cron racing
|
|
25
|
+
a live request · two writers on the same row · a read between a check and its use.
|
|
26
|
+
|
|
27
|
+
## Hostile payloads
|
|
28
|
+
Emoji and combining characters · mixed encodings · a 10k-character string in a field sized for 50 ·
|
|
29
|
+
injection strings that must remain inert · HTML inside free text · a number arriving as a string · deeply
|
|
30
|
+
nested structures.
|
|
31
|
+
|
|
32
|
+
## Impossible state
|
|
33
|
+
An enum value outside the domain · an orphaned foreign key · an expired session presented as valid · a
|
|
34
|
+
status transition the state machine does not define · a record referencing a deleted parent.
|
|
35
|
+
|
|
36
|
+
## Contract violation
|
|
37
|
+
An external type that flipped between deploys · an unknown enum member · an extra unexpected field · page
|
|
38
|
+
2 of a paginated response arriving empty · a schema version the code does not know.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
Each attack asserts what the system **should** do under that condition. An attack written to assert the
|
|
43
|
+
current broken behaviour is not an attack — it is a regression test for the bug.
|