guardian-framework 0.1.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.
Files changed (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +463 -0
  3. package/dist/cli.js +12958 -0
  4. package/dist/exports.js +12765 -0
  5. package/package.json +61 -0
  6. package/templates/languages/go-patterns.md +411 -0
  7. package/templates/languages/java-patterns.md +545 -0
  8. package/templates/languages/python-patterns.md +312 -0
  9. package/templates/languages/rust-patterns.md +232 -0
  10. package/templates/languages/typescript-patterns.md +313 -0
  11. package/templates/pi/INDEX.md +437 -0
  12. package/templates/pi/agent/AGENTS.md +166 -0
  13. package/templates/pi/agents/architecture-coordinator.md +40 -0
  14. package/templates/pi/agents/architecture-validator.md +36 -0
  15. package/templates/pi/agents/bootstrap-implementer.md +37 -0
  16. package/templates/pi/agents/issue-factory.md +31 -0
  17. package/templates/pi/agents/operations-validator.md +32 -0
  18. package/templates/pi/agents/security-validator.md +33 -0
  19. package/templates/pi/architecture/CHANGELOG.md +78 -0
  20. package/templates/pi/architecture/decisions/ADR-template.md +76 -0
  21. package/templates/pi/architecture/diagrams/system-overview.md +159 -0
  22. package/templates/pi/architecture/modules/module-template.md +152 -0
  23. package/templates/pi/context/checklists.md +91 -0
  24. package/templates/pi/context/domain-workflow.md +180 -0
  25. package/templates/pi/context/output-formats.md +135 -0
  26. package/templates/pi/context/patterns-base.md +47 -0
  27. package/templates/pi/context/patterns.md +38 -0
  28. package/templates/pi/context/project.md +88 -0
  29. package/templates/pi/domain/exploration.md +93 -0
  30. package/templates/pi/domain/ubiquitous-language.md +24 -0
  31. package/templates/pi/extensions/architect-lib/generators.ts +528 -0
  32. package/templates/pi/extensions/architect-lib/helpers.ts +344 -0
  33. package/templates/pi/extensions/architect-lib/types.ts +117 -0
  34. package/templates/pi/extensions/architect.ts +1425 -0
  35. package/templates/pi/extensions/ask-user-question.ts +579 -0
  36. package/templates/pi/extensions/bash-guard.ts +556 -0
  37. package/templates/pi/extensions/config-reload.ts +115 -0
  38. package/templates/pi/extensions/coordinator.ts +304 -0
  39. package/templates/pi/extensions/curator.ts +543 -0
  40. package/templates/pi/extensions/domain-explorer.ts +990 -0
  41. package/templates/pi/extensions/filechanges.ts +656 -0
  42. package/templates/pi/extensions/goal-loop.ts +717 -0
  43. package/templates/pi/extensions/hooks.ts +452 -0
  44. package/templates/pi/extensions/kanban.ts +547 -0
  45. package/templates/pi/extensions/pipeline.ts +1246 -0
  46. package/templates/pi/extensions/plan-mode.ts +209 -0
  47. package/templates/pi/extensions/project-scaffolder.ts +284 -0
  48. package/templates/pi/extensions/read-only-mode.ts +192 -0
  49. package/templates/pi/extensions/redaction.ts +128 -0
  50. package/templates/pi/extensions/session-persistence.ts +174 -0
  51. package/templates/pi/extensions/slash-commands.ts +229 -0
  52. package/templates/pi/extensions/snippets.ts +201 -0
  53. package/templates/pi/extensions/validation-runner.ts +100 -0
  54. package/templates/pi/github/agents/architecture-coordinator.agent.md +27 -0
  55. package/templates/pi/github/agents/architecture-validator.agent.md +20 -0
  56. package/templates/pi/github/agents/bootstrap-implementer.agent.md +20 -0
  57. package/templates/pi/github/agents/epic-planner.agent.md +70 -0
  58. package/templates/pi/github/agents/issue-factory.agent.md +20 -0
  59. package/templates/pi/github/agents/operations-validator.agent.md +20 -0
  60. package/templates/pi/github/agents/security-validator.agent.md +20 -0
  61. package/templates/pi/github/copilot/settings.json +16 -0
  62. package/templates/pi/github/copilot-instructions.md +155 -0
  63. package/templates/pi/github/instructions/architecture.instructions.md +71 -0
  64. package/templates/pi/github/instructions/validation.instructions.md +69 -0
  65. package/templates/pi/github/workflows/01-planning-workflow.md +75 -0
  66. package/templates/pi/github/workflows/02-issue-generation-workflow.md +69 -0
  67. package/templates/pi/github/workflows/03-implementation-workflow.md +80 -0
  68. package/templates/pi/github/workflows/04-validation-workflow.md +68 -0
  69. package/templates/pi/preflight_report.json +99 -0
  70. package/templates/pi/prompts/blueprint-update.md +262 -0
  71. package/templates/pi/prompts/blueprint-validate.md +218 -0
  72. package/templates/pi/prompts/bug-fix.md +50 -0
  73. package/templates/pi/prompts/ci-blueprint.md +131 -0
  74. package/templates/pi/prompts/context-refresh.md +258 -0
  75. package/templates/pi/prompts/epic-plan.md +356 -0
  76. package/templates/pi/prompts/epic-template.md +186 -0
  77. package/templates/pi/prompts/feature-development.md +131 -0
  78. package/templates/pi/prompts/git-issues.md +243 -0
  79. package/templates/pi/prompts/hotfix.md +71 -0
  80. package/templates/pi/prompts/issue-closeout.md +342 -0
  81. package/templates/pi/prompts/issue-draft.md +218 -0
  82. package/templates/pi/prompts/issue-implementation-series.md +173 -0
  83. package/templates/pi/prompts/issue-merge.md +372 -0
  84. package/templates/pi/prompts/issue-template-set.md +392 -0
  85. package/templates/pi/prompts/issue-template.md +207 -0
  86. package/templates/pi/prompts/pattern-extract.md +269 -0
  87. package/templates/pi/prompts/plan-to-issues.md +430 -0
  88. package/templates/pi/prompts/refactoring.md +82 -0
  89. package/templates/pi/prompts/scope-analyzer.md +254 -0
  90. package/templates/pi/prompts/sync-check.md +230 -0
  91. package/templates/pi/scripts/categorize-issues.sh +171 -0
  92. package/templates/pi/scripts/ci/check_architecture_conformance.sh +748 -0
  93. package/templates/pi/scripts/ci/check_planning_packet.py +228 -0
  94. package/templates/pi/scripts/ci/run_hardening_stages.sh +264 -0
  95. package/templates/pi/scripts/ci/run_preflight.sh +649 -0
  96. package/templates/pi/scripts/ci/run_stage.sh +193 -0
  97. package/templates/pi/scripts/ci/stage_docs_policy.sh +82 -0
  98. package/templates/pi/scripts/ci/stage_integration.sh +3 -0
  99. package/templates/pi/scripts/ci/stage_lint.sh +130 -0
  100. package/templates/pi/scripts/ci/stage_migration_verify.sh +3 -0
  101. package/templates/pi/scripts/ci/stage_package_build.sh +3 -0
  102. package/templates/pi/scripts/ci/stage_release_readiness.sh +3 -0
  103. package/templates/pi/scripts/ci/stage_remaining.sh +242 -0
  104. package/templates/pi/scripts/ci/stage_security.sh +3 -0
  105. package/templates/pi/scripts/ci/stage_static_analysis.sh +114 -0
  106. package/templates/pi/scripts/ci/stage_unit.sh +119 -0
  107. package/templates/pi/scripts/ci/validate_agent_output.py +181 -0
  108. package/templates/pi/scripts/ci/validate_agent_output.sh +243 -0
  109. package/templates/pi/scripts/create-feature-branch.sh +136 -0
  110. package/templates/pi/scripts/create-mr.sh +117 -0
  111. package/templates/pi/scripts/fetch-issues.sh +131 -0
  112. package/templates/pi/scripts/generate-architecture.sh +161 -0
  113. package/templates/pi/scripts/git/close-epic.sh +69 -0
  114. package/templates/pi/scripts/git/close-issue.sh +35 -0
  115. package/templates/pi/scripts/git/create-tracking-issue.sh +174 -0
  116. package/templates/pi/scripts/git/link-issue-to-epic.sh +51 -0
  117. package/templates/pi/scripts/git/update-tracking-issue.sh +66 -0
  118. package/templates/pi/scripts/languages/go/validate-architecture.sh +139 -0
  119. package/templates/pi/scripts/languages/go/validate-canonical.sh +129 -0
  120. package/templates/pi/scripts/languages/go/validate-ci.sh +132 -0
  121. package/templates/pi/scripts/languages/go/validate-integration.sh +156 -0
  122. package/templates/pi/scripts/languages/go/validate-operations.sh +146 -0
  123. package/templates/pi/scripts/languages/go/validate-security.sh +135 -0
  124. package/templates/pi/scripts/languages/go/validate-tests.sh +125 -0
  125. package/templates/pi/scripts/languages/java/validate-annotations.sh +185 -0
  126. package/templates/pi/scripts/languages/java/validate-architecture.sh +159 -0
  127. package/templates/pi/scripts/languages/java/validate-canonical.sh +114 -0
  128. package/templates/pi/scripts/languages/java/validate-ci.sh +269 -0
  129. package/templates/pi/scripts/languages/java/validate-integration.sh +149 -0
  130. package/templates/pi/scripts/languages/java/validate-operations.sh +142 -0
  131. package/templates/pi/scripts/languages/java/validate-security.sh +174 -0
  132. package/templates/pi/scripts/languages/java/validate-spring-architecture.sh +227 -0
  133. package/templates/pi/scripts/languages/java/validate-tests.sh +159 -0
  134. package/templates/pi/scripts/languages/python/validate-architecture.sh +99 -0
  135. package/templates/pi/scripts/languages/python/validate-canonical.sh +124 -0
  136. package/templates/pi/scripts/languages/python/validate-ci.sh +130 -0
  137. package/templates/pi/scripts/languages/python/validate-integration.sh +119 -0
  138. package/templates/pi/scripts/languages/python/validate-operations.sh +107 -0
  139. package/templates/pi/scripts/languages/python/validate-security.sh +68 -0
  140. package/templates/pi/scripts/languages/python/validate-tests.sh +102 -0
  141. package/templates/pi/scripts/languages/rust/validate-architecture.sh +188 -0
  142. package/templates/pi/scripts/languages/rust/validate-canonical.sh +146 -0
  143. package/templates/pi/scripts/languages/rust/validate-ci.sh +147 -0
  144. package/templates/pi/scripts/languages/rust/validate-integration.sh +149 -0
  145. package/templates/pi/scripts/languages/rust/validate-operations.sh +154 -0
  146. package/templates/pi/scripts/languages/rust/validate-security.sh +153 -0
  147. package/templates/pi/scripts/languages/rust/validate-tests.sh +150 -0
  148. package/templates/pi/scripts/languages/typescript/validate-architecture.sh +157 -0
  149. package/templates/pi/scripts/languages/typescript/validate-canonical.sh +135 -0
  150. package/templates/pi/scripts/languages/typescript/validate-ci.sh +244 -0
  151. package/templates/pi/scripts/languages/typescript/validate-integration.sh +166 -0
  152. package/templates/pi/scripts/languages/typescript/validate-operations.sh +162 -0
  153. package/templates/pi/scripts/languages/typescript/validate-security.sh +169 -0
  154. package/templates/pi/scripts/languages/typescript/validate-tests.sh +158 -0
  155. package/templates/pi/scripts/merge-mr.sh +95 -0
  156. package/templates/pi/scripts/mr-validation.sh +228 -0
  157. package/templates/pi/scripts/validate-architecture-readiness.sh +153 -0
  158. package/templates/pi/scripts/validate-architecture.sh +22 -0
  159. package/templates/pi/scripts/validate-canonical.sh +22 -0
  160. package/templates/pi/scripts/validate-ci.sh +37 -0
  161. package/templates/pi/scripts/validate-integration.sh +22 -0
  162. package/templates/pi/scripts/validate-operations.sh +22 -0
  163. package/templates/pi/scripts/validate-security.sh +22 -0
  164. package/templates/pi/scripts/validate-tests.sh +22 -0
  165. package/templates/pi/scripts/validate-ubiquitous-language.sh +291 -0
  166. package/templates/pi/scripts/validation-cache.sh +139 -0
  167. package/templates/pi/skills/agents/architecture-coordinator.md +178 -0
  168. package/templates/pi/skills/agents/architecture-generator.md +79 -0
  169. package/templates/pi/skills/agents/architecture-validator.md +74 -0
  170. package/templates/pi/skills/agents/ci-mr-validator.md +46 -0
  171. package/templates/pi/skills/agents/code-developer.md +76 -0
  172. package/templates/pi/skills/agents/commit.md +46 -0
  173. package/templates/pi/skills/agents/curator.md +71 -0
  174. package/templates/pi/skills/agents/debug.md +59 -0
  175. package/templates/pi/skills/agents/documentation-maintainer.md +36 -0
  176. package/templates/pi/skills/agents/goal-loop.md +125 -0
  177. package/templates/pi/skills/agents/hooks.md +122 -0
  178. package/templates/pi/skills/agents/integration-validator.md +35 -0
  179. package/templates/pi/skills/agents/issue-creator.md +75 -0
  180. package/templates/pi/skills/agents/issue-factory.md +143 -0
  181. package/templates/pi/skills/agents/kanban.md +85 -0
  182. package/templates/pi/skills/agents/land.md +59 -0
  183. package/templates/pi/skills/agents/operations-validator.md +43 -0
  184. package/templates/pi/skills/agents/pipeline.md +113 -0
  185. package/templates/pi/skills/agents/plan-mode.md +77 -0
  186. package/templates/pi/skills/agents/pull.md +40 -0
  187. package/templates/pi/skills/agents/push.md +41 -0
  188. package/templates/pi/skills/agents/security-validator.md +85 -0
  189. package/templates/pi/skills/agents/session-persistence.md +119 -0
  190. package/templates/pi/skills/agents/slash-commands.md +117 -0
  191. package/templates/pi/skills/agents/snippets.md +99 -0
  192. package/templates/pi/skills/agents/subagent-registry.md +78 -0
  193. package/templates/pi/skills/agents/test-validator.md +42 -0
  194. package/templates/pi/skills/validators/architecture-validator.md +43 -0
  195. package/templates/pi/skills/validators/ci-validator.md +27 -0
  196. package/templates/pi/skills/validators/context-compaction.md +73 -0
  197. package/templates/pi/skills/validators/integration-validator.md +38 -0
  198. package/templates/pi/skills/validators/model-registry.md +96 -0
  199. package/templates/pi/skills/validators/operations-validator.md +34 -0
  200. package/templates/pi/skills/validators/security-guards.md +72 -0
  201. package/templates/pi/skills/validators/security-validator.md +41 -0
  202. package/templates/pi/skills/validators/system-prompt-tiers.md +69 -0
  203. package/templates/pi/skills/validators/test-validator.md +33 -0
  204. package/templates/pi/types.ts +62 -0
  205. package/templates/pi/validators/README.md +93 -0
  206. package/templates/pi/validators/default.toml +209 -0
  207. package/templates/pi/validators/spring.toml +142 -0
  208. package/templates/pi/workpad.md +53 -0
  209. package/templates/project/java/Dockerfile +14 -0
  210. package/templates/project/java/README.md +40 -0
  211. package/templates/project/java/pom.xml +132 -0
  212. package/templates/project/typescript/Dockerfile +15 -0
  213. package/templates/project/typescript/README.md +29 -0
  214. package/templates/project/typescript/package.json +23 -0
  215. package/templates/project/typescript/tsconfig.json +21 -0
  216. package/templates/workflow.md +123 -0
@@ -0,0 +1,304 @@
1
+ /**
2
+ * Coordinator Extension for pi
3
+ *
4
+ * Master orchestrator for Guardian workflows.
5
+ * Uses guardian_scope, guardian_validate, and ask_user_question tools.
6
+ * Zero external dependencies — self-contained pi extension.
7
+ */
8
+
9
+ type ExtensionContext = {
10
+ ui: { notify(message: string, level?: string): void };
11
+ shell: {
12
+ execute(
13
+ command: string,
14
+ options?: { signal?: AbortSignal },
15
+ ): Promise<{ exitCode: number; stdout: string }>;
16
+ };
17
+ tools: { execute(name: string, params: Record<string, unknown>): Promise<unknown> };
18
+ };
19
+
20
+ type ToolCallEvent = { toolName: string; toolCallId: string; input: { command: string } };
21
+
22
+ type ExtensionAPI = {
23
+ on(event: string, handler: (event: unknown, ctx: ExtensionContext) => void | Promise<void>): void;
24
+ registerTool(options: {
25
+ name: string;
26
+ label: string;
27
+ description: string;
28
+ parameters: unknown;
29
+ execute(
30
+ toolCallId: string,
31
+ params: Record<string, unknown>,
32
+ signal: AbortSignal,
33
+ onUpdate: (update: { type: string; message: string }) => void,
34
+ ctx: ExtensionContext,
35
+ ): unknown | Promise<unknown>;
36
+ }): void;
37
+ };
38
+
39
+ function isToolCallEventType(name: string, event: unknown): event is ToolCallEvent {
40
+ return (event as ToolCallEvent)?.toolName === name;
41
+ }
42
+
43
+ const Type = {
44
+ Array: (items: unknown, options: Record<string, unknown> = {}) => ({
45
+ ...options,
46
+ items,
47
+ type: "array",
48
+ }),
49
+ Object: (properties: Record<string, unknown>) => ({ properties, type: "object" }),
50
+ Optional: (schema: unknown) => schema,
51
+ String: (options: Record<string, unknown> = {}) => ({ ...options, type: "string" }),
52
+ };
53
+
54
+ const VALIDATORS = {
55
+ architecture: ".pi/scripts/validate-architecture.sh",
56
+ canonical: ".pi/scripts/validate-canonical.sh",
57
+ ci: ".pi/scripts/validate-ci.sh",
58
+ integration: ".pi/scripts/validate-integration.sh",
59
+ operations: ".pi/scripts/validate-operations.sh",
60
+ security: ".pi/scripts/validate-security.sh",
61
+ tests: ".pi/scripts/validate-tests.sh",
62
+ } as const;
63
+
64
+ type ValidatorName = keyof typeof VALIDATORS;
65
+
66
+ function isValidatorName(value: string): value is ValidatorName {
67
+ return Object.hasOwn(VALIDATORS, value);
68
+ }
69
+
70
+ function classifyScope(fileCount: number, lineChanges: number): string {
71
+ if (fileCount > 15 || lineChanges > 500) return "critical";
72
+ if (fileCount > 5 || lineChanges > 200) return "complex";
73
+ if (fileCount > 2 || lineChanges > 50) return "moderate";
74
+ return "simple";
75
+ }
76
+
77
+ // ── Delegation role types ──
78
+ // Role determines whether a subagent can spawn its own subagents.
79
+ // "leaf" (default) = cannot delegate further.
80
+ // "orchestrator" = can delegate, bounded by max_spawn_depth.
81
+ const DELEGATION_ROLES = ["leaf", "orchestrator"] as const;
82
+ type DelegationRole = (typeof DELEGATION_ROLES)[number];
83
+ const DEFAULT_MAX_SPAWN_DEPTH = 1; // 1 = flat (leaf-only)
84
+
85
+ function resolveDelegationRole(role?: string): DelegationRole {
86
+ if (role === "orchestrator") return "orchestrator";
87
+ return "leaf";
88
+ }
89
+
90
+ function toolResult(text: string) {
91
+ return { content: [{ type: "text" as const, text }] };
92
+ }
93
+
94
+ function toolError(text: string) {
95
+ return { content: [{ type: "text" as const, text }], isError: true };
96
+ }
97
+
98
+ export default function (pi: ExtensionAPI) {
99
+ pi.on("session_start", async (_event, ctx) => {
100
+ ctx.ui.notify("Guardian coordinator ready", "info");
101
+ });
102
+
103
+ // ── guardian_scope ──
104
+ pi.registerTool({
105
+ name: "guardian_scope",
106
+ label: "Guardian Scope",
107
+ description: "Classify current git diff scope using Guardian thresholds",
108
+ parameters: Type.Object({}),
109
+ async execute(_toolCallId, _params, signal, _onUpdate, ctx) {
110
+ if (signal?.aborted) {
111
+ return toolError("Scope classification aborted");
112
+ }
113
+
114
+ // Try diff against HEAD, fall back to unstaged diff if HEAD doesn't exist (fresh repo)
115
+ let diff;
116
+ try {
117
+ diff = await ctx.shell.execute("git diff --numstat HEAD", { signal });
118
+ } catch {
119
+ try {
120
+ diff = await ctx.shell.execute("git diff --numstat", { signal });
121
+ } catch {
122
+ return toolResult("Scope: unknown (fresh repo, no commit history yet)");
123
+ }
124
+ }
125
+ const rows = diff.stdout.split("\n").filter((line) => line.trim());
126
+ const fileCount = rows.length;
127
+ const lineChanges = rows.reduce((sum, row) => {
128
+ const [added, removed] = row.split(/\s+/);
129
+ const a = Number.parseInt(added, 10);
130
+ const r = Number.parseInt(removed, 10);
131
+ return sum + (Number.isFinite(a) ? a : 0) + (Number.isFinite(r) ? r : 0);
132
+ }, 0);
133
+
134
+ const scope = classifyScope(fileCount, lineChanges);
135
+ return toolResult(
136
+ `Scope: **${scope}**\n- Files: ${fileCount}\n- Line changes: ~${lineChanges}\n\nThresholds: simple (<3 files, <50 lines) → moderate (<6 files, <200 lines) → complex (<16 files, <500 lines) → critical (16+ files or 500+ lines)`,
137
+ );
138
+ },
139
+ });
140
+
141
+ // ── guardian_validate ──
142
+ pi.registerTool({
143
+ name: "guardian_validate",
144
+ label: "Guardian Validate",
145
+ description: "Run Guardian validation scripts for specific categories",
146
+ parameters: Type.Object({
147
+ validators: Type.Array(Type.String(), {
148
+ description:
149
+ "Categories: ci, tests, operations, security, integration, architecture, canonical",
150
+ }),
151
+ scope: Type.Optional(
152
+ Type.String({ description: "Scope: simple, moderate, complex, critical" }),
153
+ ),
154
+ }),
155
+ async execute(_toolCallId, params, signal, onUpdate, ctx) {
156
+ const results: Record<string, { passed: boolean; output: string }> = {};
157
+ const validators = Array.isArray(params.validators)
158
+ ? params.validators.filter((v): v is string => typeof v === "string")
159
+ : [];
160
+
161
+ if (validators.length === 0) {
162
+ return toolError(
163
+ "No validators specified. Available: ci, tests, operations, security, integration, architecture, canonical",
164
+ );
165
+ }
166
+
167
+ for (const validator of validators) {
168
+ if (signal?.aborted) break;
169
+
170
+ if (!isValidatorName(validator)) {
171
+ results[validator] = { passed: false, output: `Unsupported validator: ${validator}` };
172
+ continue;
173
+ }
174
+
175
+ onUpdate({ content: [{ type: "text", text: `Running ${validator} validation...` }] });
176
+
177
+ const scriptPath = VALIDATORS[validator];
178
+ try {
179
+ const result = await ctx.shell.execute(`bash ${scriptPath}`, { signal });
180
+ results[validator] = { passed: result.exitCode === 0, output: result.stdout };
181
+ } catch (error) {
182
+ results[validator] = { passed: false, output: `Error: ${error}` };
183
+ }
184
+ }
185
+
186
+ const lines: string[] = [];
187
+ const allPassed = Object.values(results).every((r) => r.passed);
188
+
189
+ lines.push(`## Validation Results — ${allPassed ? "✅ All Passed" : "❌ Some Failed"}\n`);
190
+ for (const [name, result] of Object.entries(results)) {
191
+ lines.push(`### ${name}: ${result.passed ? "✅ PASS" : "❌ FAIL"}`);
192
+ // Show last 15 lines of output to keep it readable
193
+ const output = result.output.trim();
194
+ if (output) {
195
+ const tail = output.split("\n").slice(-15).join("\n");
196
+ lines.push(`\`\`\`\n${tail}\n\`\`\``);
197
+ }
198
+ lines.push("");
199
+ }
200
+
201
+ return toolResult(lines.join("\n"));
202
+ },
203
+ });
204
+
205
+ // ── guardian_coordinate ──
206
+ pi.registerTool({
207
+ name: "guardian_coordinate",
208
+ label: "Guardian Coordinate",
209
+ description: "Orchestrate a Guardian workflow with scope classification and validation",
210
+ parameters: Type.Object({
211
+ task: Type.String({ description: "Task description" }),
212
+ scope: Type.Optional(Type.String({ description: "Override scope classification" })),
213
+ validators: Type.Optional(Type.Array(Type.String())),
214
+ }),
215
+ async execute(_toolCallId, params, signal, onUpdate, ctx) {
216
+ // 1. Classify scope
217
+ let scope = typeof params.scope === "string" ? params.scope : undefined;
218
+ if (!scope) {
219
+ const scopeResult = await ctx.tools.execute("guardian_scope", {});
220
+ // Parse the text result to extract scope
221
+ const text =
222
+ (scopeResult as { content?: Array<{ text?: string }> })?.content?.[0]?.text ?? "";
223
+ const match = text.match(/Scope:\s+\*\*(\w+)\*\*/);
224
+ scope = match?.[1] ?? "moderate";
225
+ }
226
+
227
+ onUpdate({ content: [{ type: "text", text: `Scope: ${scope}` }] });
228
+
229
+ // 2. Determine validators
230
+ const validatorMap: Record<string, string[]> = {
231
+ simple: ["ci", "canonical"],
232
+ moderate: ["ci", "architecture", "canonical"],
233
+ complex: ["ci", "architecture", "security", "tests", "integration", "canonical"],
234
+ critical: [
235
+ "ci",
236
+ "architecture",
237
+ "security",
238
+ "operations",
239
+ "tests",
240
+ "integration",
241
+ "canonical",
242
+ ],
243
+ };
244
+
245
+ const validators = Array.isArray(params.validators)
246
+ ? params.validators.filter((v): v is string => typeof v === "string")
247
+ : (validatorMap[scope] ?? validatorMap.moderate);
248
+
249
+ onUpdate({ content: [{ type: "text", text: `Validators: ${validators.join(", ")}` }] });
250
+
251
+ // 3. Run validators
252
+ const validationResults = await ctx.tools.execute("guardian_validate", { validators, scope });
253
+
254
+ // 4. Build coordination result
255
+ const lines: string[] = [
256
+ "## Coordination Report",
257
+ "",
258
+ `**Task:** ${params.task}`,
259
+ `**Scope:** ${scope}`,
260
+ `**Validators:** ${validators.join(", ")}`,
261
+ "",
262
+ "### Next Steps",
263
+ scope === "critical"
264
+ ? "- Request human approval before proceeding"
265
+ : "- Proceed with implementation",
266
+ ];
267
+
268
+ // Append validation results
269
+ const valText =
270
+ (validationResults as { content?: Array<{ text?: string }> })?.content?.[0]?.text ?? "";
271
+ if (valText) {
272
+ lines.push("", "### Validation", valText);
273
+ }
274
+
275
+ return toolResult(lines.join("\n"));
276
+ },
277
+ });
278
+
279
+ // ── Block catastrophic commands only (lightweight safety net) ──
280
+ // Git commit/push are allowed — agents need them for autonomous workflows.
281
+ // Destructive operations are blocked to prevent irreversible damage.
282
+ pi.on("tool_call", async (event) => {
283
+ if (!isToolCallEventType("bash", event)) return;
284
+
285
+ const cmd = event.input.command;
286
+
287
+ // Only block truly catastrophic operations
288
+ const catastrophic = [
289
+ { pattern: /(?<!\bgit\s+)\brm\s+-rf?\b/, reason: "recursive file deletion (rm -rf)" },
290
+ { pattern: /\bsudo\b/, reason: "elevated privileges (sudo)" },
291
+ { pattern: /\bgit\s+reset\s+--hard\b/, reason: "git reset --hard (discard all changes)" },
292
+ { pattern: /\bgit\s+clean\s+-[a-zA-Z]*f/, reason: "git clean -f (delete untracked files)" },
293
+ ];
294
+
295
+ for (const { pattern, reason } of catastrophic) {
296
+ if (pattern.test(cmd)) {
297
+ return {
298
+ block: true,
299
+ reason: `Guardian blocked: ${reason}. Use safer alternatives or confirm with the user.`,
300
+ };
301
+ }
302
+ }
303
+ });
304
+ }