gsd-pi 2.41.0-dev.cac69f9 → 2.42.0-dev.97e9e30

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 (115) hide show
  1. package/dist/resources/extensions/gsd/auto/loop.js +80 -0
  2. package/dist/resources/extensions/gsd/auto/phases.js +2 -2
  3. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  4. package/dist/resources/extensions/gsd/auto-dashboard.js +2 -0
  5. package/dist/resources/extensions/gsd/auto.js +28 -1
  6. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
  7. package/dist/resources/extensions/gsd/commands/catalog.js +32 -0
  8. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
  9. package/dist/resources/extensions/gsd/context-injector.js +74 -0
  10. package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
  11. package/dist/resources/extensions/gsd/custom-verification.js +145 -0
  12. package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
  13. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
  14. package/dist/resources/extensions/gsd/definition-loader.js +352 -0
  15. package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
  16. package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
  17. package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
  18. package/dist/resources/extensions/gsd/engine-types.js +8 -0
  19. package/dist/resources/extensions/gsd/execution-policy.js +8 -0
  20. package/dist/resources/extensions/gsd/graph.js +225 -0
  21. package/dist/resources/extensions/gsd/run-manager.js +134 -0
  22. package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
  23. package/dist/resources/skills/create-workflow/SKILL.md +103 -0
  24. package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  25. package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
  26. package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  27. package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  28. package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  29. package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  30. package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  31. package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  32. package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  33. package/dist/web/standalone/.next/BUILD_ID +1 -1
  34. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  35. package/dist/web/standalone/.next/build-manifest.json +2 -2
  36. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  37. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  38. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  39. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  40. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  41. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  42. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  43. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  44. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  45. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  46. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  47. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  48. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  49. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/index.html +1 -1
  54. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  61. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  62. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  63. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  64. package/package.json +1 -1
  65. package/packages/pi-coding-agent/package.json +1 -1
  66. package/pkg/package.json +1 -1
  67. package/src/resources/extensions/gsd/auto/loop.ts +91 -0
  68. package/src/resources/extensions/gsd/auto/phases.ts +2 -2
  69. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  70. package/src/resources/extensions/gsd/auto-dashboard.ts +2 -0
  71. package/src/resources/extensions/gsd/auto.ts +31 -1
  72. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
  73. package/src/resources/extensions/gsd/commands/catalog.ts +32 -0
  74. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
  75. package/src/resources/extensions/gsd/context-injector.ts +100 -0
  76. package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
  77. package/src/resources/extensions/gsd/custom-verification.ts +180 -0
  78. package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
  79. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
  80. package/src/resources/extensions/gsd/definition-loader.ts +462 -0
  81. package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
  82. package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
  83. package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
  84. package/src/resources/extensions/gsd/engine-types.ts +71 -0
  85. package/src/resources/extensions/gsd/execution-policy.ts +43 -0
  86. package/src/resources/extensions/gsd/graph.ts +312 -0
  87. package/src/resources/extensions/gsd/run-manager.ts +180 -0
  88. package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
  89. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
  90. package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
  91. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
  92. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
  93. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
  94. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
  95. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
  96. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
  97. package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
  98. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
  99. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
  100. package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
  101. package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
  102. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
  103. package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
  104. package/src/resources/skills/create-workflow/SKILL.md +103 -0
  105. package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  106. package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
  107. package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  108. package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  109. package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  110. package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  111. package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  112. package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  113. package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  114. /package/dist/web/standalone/.next/static/{EnGUNqHeGbE0tuuUkTJVA → PXrI5DoWsm7rwAVnEU2rD}/_buildManifest.js +0 -0
  115. /package/dist/web/standalone/.next/static/{EnGUNqHeGbE0tuuUkTJVA → PXrI5DoWsm7rwAVnEU2rD}/_ssgManifest.js +0 -0
@@ -118,6 +118,51 @@ console.log('\n── Loop guard: arg order is normalized ──');
118
118
  assertEq(getToolCallLoopCount(), 2, 'Should detect as same call regardless of key order');
119
119
  }
120
120
 
121
+ // ═══════════════════════════════════════════════════════════════════════════
122
+ // Nested/array arguments produce distinct hashes
123
+ // ═══════════════════════════════════════════════════════════════════════════
124
+
125
+ console.log('\n── Loop guard: nested args are not stripped ──');
126
+
127
+ {
128
+ resetToolCallLoopGuard();
129
+
130
+ // Simulate ask_user_questions-style calls with different nested content
131
+ for (let i = 1; i <= 5; i++) {
132
+ const result = checkToolCallLoop('ask_user_questions', {
133
+ questions: [{ id: `q${i}`, question: `Question ${i}?` }],
134
+ });
135
+ assertTrue(result.block === false, `Nested call ${i} with unique content should be allowed`);
136
+ assertEq(getToolCallLoopCount(), 1, `Each unique nested call should reset count to 1`);
137
+ }
138
+
139
+ // Truly identical nested calls should still be detected
140
+ resetToolCallLoopGuard();
141
+ for (let i = 1; i <= 4; i++) {
142
+ checkToolCallLoop('ask_user_questions', {
143
+ questions: [{ id: 'same', question: 'Same?' }],
144
+ });
145
+ }
146
+ const blocked = checkToolCallLoop('ask_user_questions', {
147
+ questions: [{ id: 'same', question: 'Same?' }],
148
+ });
149
+ assertTrue(blocked.block === true, 'Identical nested calls should still be blocked');
150
+ }
151
+
152
+ // ═══════════════════════════════════════════════════════════════════════════
153
+ // Nested object key order is normalized
154
+ // ═══════════════════════════════════════════════════════════════════════════
155
+
156
+ console.log('\n── Loop guard: nested key order is normalized ──');
157
+
158
+ {
159
+ resetToolCallLoopGuard();
160
+
161
+ checkToolCallLoop('tool', { outer: { b: 2, a: 1 } });
162
+ const result = checkToolCallLoop('tool', { outer: { a: 1, b: 2 } });
163
+ assertEq(getToolCallLoopCount(), 2, 'Same nested args in different key order should match');
164
+ }
165
+
121
166
  // ═══════════════════════════════════════════════════════════════════════════
122
167
 
123
168
  report();
@@ -0,0 +1,38 @@
1
+ /**
2
+ * workflow-engine.ts — WorkflowEngine interface.
3
+ *
4
+ * Defines the contract every engine implementation must satisfy.
5
+ * Imports only from the leaf-node engine-types.
6
+ */
7
+
8
+ import type {
9
+ EngineState,
10
+ EngineDispatchAction,
11
+ CompletedStep,
12
+ ReconcileResult,
13
+ DisplayMetadata,
14
+ } from "./engine-types.js";
15
+
16
+ /** A pluggable workflow engine that drives the auto-loop. */
17
+ export interface WorkflowEngine {
18
+ /** Unique identifier for this engine (e.g. "dev", "custom"). */
19
+ readonly engineId: string;
20
+
21
+ /** Derive the current engine state from the project on disk. */
22
+ deriveState(basePath: string): Promise<EngineState>;
23
+
24
+ /** Decide what the loop should do next given current state. */
25
+ resolveDispatch(
26
+ state: EngineState,
27
+ context: { basePath: string },
28
+ ): Promise<EngineDispatchAction>;
29
+
30
+ /** Reconcile state after a step has been executed. */
31
+ reconcile(
32
+ state: EngineState,
33
+ completedStep: CompletedStep,
34
+ ): Promise<ReconcileResult>;
35
+
36
+ /** Return UI-facing metadata for progress display. */
37
+ getDisplayMetadata(state: EngineState): DisplayMetadata;
38
+ }
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: create-workflow
3
+ description: Conversational guide for creating valid YAML workflow definitions. Use when asked to "create a workflow", "new workflow definition", "build a workflow", "workflow YAML", "define workflow steps", or "workflow from template".
4
+ ---
5
+
6
+ <essential_principles>
7
+ You are a workflow definition author. You help users create valid V1 YAML workflow definitions that the GSD workflow engine can execute.
8
+
9
+ **V1 Schema Basics:**
10
+
11
+ - Every definition requires `version: 1`, a non-empty `name`, and at least one step in `steps[]`.
12
+ - Optional top-level fields: `description` (string), `params` (key-value defaults for `{{ key }}` substitution).
13
+ - Each step requires: `id` (unique string), `name` (non-empty string), `prompt` (non-empty string).
14
+ - Each step optionally has: `requires` or `depends_on` (array of step IDs), `produces` (array of artifact paths), `context_from` (array of step IDs), `verify` (verification policy object), `iterate` (fan-out config object).
15
+ - YAML uses **snake_case** keys: `depends_on`, `context_from`. The engine converts to camelCase internally.
16
+
17
+ **Validation Rules:**
18
+
19
+ - Step IDs must be unique across the workflow.
20
+ - Dependencies (`requires`/`depends_on`) must reference existing step IDs — no dangling refs.
21
+ - A step cannot depend on itself.
22
+ - The dependency graph must be acyclic (no circular dependencies).
23
+ - `produces` paths must not contain `..` (path traversal rejected).
24
+ - `iterate.source` must not contain `..` (path traversal rejected).
25
+ - `iterate.pattern` must be a valid regex with at least one capture group.
26
+
27
+ **Four Verification Policies:**
28
+
29
+ 1. `content-heuristic` — Checks artifact content. Optional: `minSize` (number), `pattern` (string).
30
+ 2. `shell-command` — Runs a shell command. Required: `command` (non-empty string).
31
+ 3. `prompt-verify` — Asks an LLM to verify. Required: `prompt` (non-empty string).
32
+ 4. `human-review` — Pauses for human approval. No extra fields required.
33
+
34
+ **Parameter Substitution:**
35
+
36
+ - Define defaults in top-level `params: { key: "default_value" }`.
37
+ - Use `{{ key }}` placeholders in step prompts — the engine replaces them at runtime.
38
+ - CLI overrides take precedence over definition defaults.
39
+ - Parameter values must not contain `..` (path traversal guard).
40
+ - Any unresolved `{{ key }}` after substitution causes an error.
41
+
42
+ **Path Traversal Guard:**
43
+
44
+ - The engine rejects any `produces` path or `iterate.source` containing `..`.
45
+ - Parameter values are also checked for `..` during substitution.
46
+
47
+ **Output Location:**
48
+
49
+ - Finished definitions go in `.gsd/workflow-defs/<name>.yaml`.
50
+ - After writing, tell the user to validate with `/gsd workflow validate <name>`.
51
+ </essential_principles>
52
+
53
+ <routing>
54
+ Determine the user's intent and route to the appropriate workflow:
55
+
56
+ **"I want to create a workflow from scratch" / "new workflow" / "build a workflow":**
57
+ → Read `workflows/create-from-scratch.md` and follow it.
58
+
59
+ **"I want to start from a template" / "from an example" / "customize a template":**
60
+ → Read `workflows/create-from-template.md` and follow it.
61
+
62
+ **"Help me understand the schema" / "what fields are available?":**
63
+ → Read `references/yaml-schema-v1.md` and explain the relevant parts.
64
+
65
+ **"How does verification work?" / "verify policies":**
66
+ → Read `references/verification-policies.md` and explain.
67
+
68
+ **"How do I use context_from / iterate / params?":**
69
+ → Read `references/feature-patterns.md` and explain the relevant feature.
70
+
71
+ **If intent is unclear, ask one clarifying question:**
72
+ - "Do you want to create a workflow from scratch, or start from an existing template?"
73
+ - Then route based on the answer.
74
+ </routing>
75
+
76
+ <reference_index>
77
+ Read these files when you need detailed schema knowledge during workflow authoring:
78
+
79
+ - `references/yaml-schema-v1.md` — Complete field-by-field V1 schema reference. Read when you need to explain any field's type, constraints, or defaults.
80
+ - `references/verification-policies.md` — All four verify policies with complete YAML examples. Read when helping the user choose or configure verification for a step.
81
+ - `references/feature-patterns.md` — Usage patterns for `context_from`, `iterate`, and `params` with complete YAML examples. Read when the user wants context chaining, fan-out iteration, or parameterized workflows.
82
+ </reference_index>
83
+
84
+ <templates_index>
85
+ Available templates in `templates/`:
86
+
87
+ - `workflow-definition.yaml` — Blank scaffold with all fields shown as comments. Copy and fill for a quick start.
88
+ - `blog-post-pipeline.yaml` — Linear chain with params and content-heuristic verification.
89
+ - `code-audit.yaml` — Iterate-based fan-out with shell-command verification.
90
+ - `release-checklist.yaml` — Diamond dependency graph with human-review verification.
91
+ </templates_index>
92
+
93
+ <output_conventions>
94
+ When assembling the final YAML:
95
+
96
+ 1. Use 2-space indentation consistently.
97
+ 2. Quote string values that contain special YAML characters (`:`, `{`, `}`, `[`, `]`, `#`).
98
+ 3. Always include `version: 1` as the first field.
99
+ 4. Order top-level fields: `version`, `name`, `description`, `params`, `steps`.
100
+ 5. Order step fields: `id`, `name`, `prompt`, `requires`, `produces`, `context_from`, `verify`, `iterate`.
101
+ 6. Write the file to `.gsd/workflow-defs/<name>.yaml`.
102
+ 7. After writing, tell the user: "Run `/gsd workflow validate <name>` to check the definition."
103
+ </output_conventions>
@@ -0,0 +1,128 @@
1
+ <feature_patterns>
2
+ Advanced workflow features: `context_from`, `iterate`, and `params`. Each section includes a complete YAML example.
3
+
4
+ **Feature 1: `context_from` — Context Chaining**
5
+
6
+ Injects artifacts from prior steps as context when the current step runs. The value is an array of step IDs.
7
+
8
+ ```yaml
9
+ version: 1
10
+ name: research-and-synthesize
11
+ steps:
12
+ - id: gather
13
+ name: Gather sources
14
+ prompt: "Find and summarize the top 5 sources on the topic."
15
+ produces:
16
+ - sources.md
17
+
18
+ - id: analyze
19
+ name: Analyze sources
20
+ prompt: "Analyze the gathered sources for key themes."
21
+ requires:
22
+ - gather
23
+ context_from:
24
+ - gather
25
+ produces:
26
+ - analysis.md
27
+
28
+ - id: synthesize
29
+ name: Write synthesis
30
+ prompt: "Synthesize the analysis into a coherent report."
31
+ requires:
32
+ - analyze
33
+ context_from:
34
+ - gather
35
+ - analyze
36
+ produces:
37
+ - report.md
38
+ ```
39
+
40
+ How it works:
41
+ - `context_from: [gather]` means the engine includes artifacts from the `gather` step when executing `analyze`.
42
+ - You can reference multiple prior steps: `context_from: [gather, analyze]`.
43
+ - The referenced steps must exist in the workflow (they are validated as step IDs).
44
+ - `context_from` does not imply a dependency — if you want the step to wait, also add the ID to `requires`.
45
+
46
+ **Feature 2: `iterate` — Fan-Out Iteration**
47
+
48
+ Reads an artifact, applies a regex pattern, and creates one sub-execution per match. The capture group extracts the iteration variable.
49
+
50
+ ```yaml
51
+ version: 1
52
+ name: file-by-file-review
53
+ steps:
54
+ - id: inventory
55
+ name: List files to review
56
+ prompt: "List all TypeScript files in src/ that need review, one per line."
57
+ produces:
58
+ - file-list.txt
59
+
60
+ - id: review
61
+ name: Review each file
62
+ prompt: "Review the file for code quality issues."
63
+ requires:
64
+ - inventory
65
+ iterate:
66
+ source: file-list.txt
67
+ pattern: "^(.+\\.ts)$"
68
+ produces:
69
+ - reviews/
70
+ ```
71
+
72
+ How it works:
73
+ - `source`: Path to an artifact (relative to the run directory). Must not contain `..`.
74
+ - `pattern`: A regex string applied with the global flag. Must contain at least one capture group `(...)`.
75
+ - The engine reads the source artifact, applies the pattern, and creates one execution per match.
76
+ - Each capture group match becomes available as the iteration variable.
77
+ - The regex is validated at definition-load time — invalid regex or missing capture groups are rejected.
78
+
79
+ Pattern requirements:
80
+ - Must be a valid JavaScript regex.
81
+ - Must contain at least one non-lookahead capture group: `(...)` not `(?:...)`.
82
+ - Example valid patterns: `^(.+)$`, `- (.+\.ts)`, `\[(.+?)\]`.
83
+
84
+ **Feature 3: `params` — Parameterized Workflows**
85
+
86
+ Define default parameter values at the top level. Use `{{ key }}` placeholders in step prompts. CLI overrides take precedence.
87
+
88
+ ```yaml
89
+ version: 1
90
+ name: blog-post
91
+ description: Generate a blog post on a configurable topic.
92
+ params:
93
+ topic: "AI in healthcare"
94
+ audience: "technical professionals"
95
+ word_count: "1500"
96
+ steps:
97
+ - id: outline
98
+ name: Create outline
99
+ prompt: "Create a detailed outline for a blog post about {{ topic }} targeting {{ audience }}."
100
+ produces:
101
+ - outline.md
102
+
103
+ - id: draft
104
+ name: Write draft
105
+ prompt: "Write a {{ word_count }}-word blog post about {{ topic }} for {{ audience }} based on the outline."
106
+ requires:
107
+ - outline
108
+ context_from:
109
+ - outline
110
+ produces:
111
+ - draft.md
112
+ verify:
113
+ policy: content-heuristic
114
+ minSize: 500
115
+ ```
116
+
117
+ How it works:
118
+ - `params` is a top-level object mapping string keys to string default values.
119
+ - `{{ key }}` in any step prompt is replaced with the corresponding param value.
120
+ - Merge order: definition `params` (defaults) ← CLI overrides (win).
121
+ - After substitution, any remaining `{{ key }}` that has no value causes an error — all placeholders must resolve.
122
+ - Parameter values must not contain `..` (path traversal guard).
123
+ - Keys in `{{ }}` match `\w+` (letters, digits, underscore).
124
+
125
+ Common usage:
126
+ - Make workflows reusable across different topics, projects, or configurations.
127
+ - Users override defaults at run time: `/gsd workflow run blog-post topic="Rust performance"`.
128
+ </feature_patterns>
@@ -0,0 +1,76 @@
1
+ <verification_policies>
2
+ The `verify` field on a step defines how the engine validates the step's output. It must be an object with a `policy` field set to one of four values.
3
+
4
+ **Policy 1: `content-heuristic`**
5
+
6
+ Checks the artifact content against size and pattern criteria. All sub-fields are optional.
7
+
8
+ ```yaml
9
+ verify:
10
+ policy: content-heuristic
11
+ minSize: 500 # optional — minimum byte size of the artifact
12
+ pattern: "## Summary" # optional — string pattern that must appear in the artifact
13
+ ```
14
+
15
+ Fields:
16
+ - `policy`: `"content-heuristic"` (required)
17
+ - `minSize`: number (optional) — minimum artifact size in bytes
18
+ - `pattern`: string (optional) — text pattern to match in the artifact content
19
+
20
+ Use when: You want a lightweight sanity check that the step produced substantive output.
21
+
22
+ **Policy 2: `shell-command`**
23
+
24
+ Runs a shell command to verify the step's output. The command's exit code determines pass/fail.
25
+
26
+ ```yaml
27
+ verify:
28
+ policy: shell-command
29
+ command: "test -f output/report.md && wc -l output/report.md | awk '{print ($1 > 10)}'"
30
+ ```
31
+
32
+ Fields:
33
+ - `policy`: `"shell-command"` (required)
34
+ - `command`: string (required, non-empty) — shell command to execute
35
+
36
+ Use when: You need programmatic verification — file existence, test suite execution, linting, compilation, etc.
37
+
38
+ **Policy 3: `prompt-verify`**
39
+
40
+ Sends a verification prompt to an LLM to evaluate the step's output.
41
+
42
+ ```yaml
43
+ verify:
44
+ policy: prompt-verify
45
+ prompt: "Review the generated API documentation. Does it cover all endpoints with request/response examples? Answer PASS or FAIL with reasoning."
46
+ ```
47
+
48
+ Fields:
49
+ - `policy`: `"prompt-verify"` (required)
50
+ - `prompt`: string (required, non-empty) — the verification prompt sent to the LLM
51
+
52
+ Use when: Verification requires judgment that can't be expressed as a shell command — quality assessment, completeness review, style conformance.
53
+
54
+ **Policy 4: `human-review`**
55
+
56
+ Pauses execution and waits for a human to approve or reject the step's output.
57
+
58
+ ```yaml
59
+ verify:
60
+ policy: human-review
61
+ ```
62
+
63
+ Fields:
64
+ - `policy`: `"human-review"` (required)
65
+ - No additional fields.
66
+
67
+ Use when: The step produces work that requires human judgment — design decisions, public-facing content, security-sensitive changes.
68
+
69
+ **Validation Details:**
70
+
71
+ The engine validates the `verify` object at definition-load time:
72
+ - `policy` must be one of the four strings above. Any other value is rejected.
73
+ - `shell-command` requires a non-empty `command` field. Missing or empty `command` is rejected.
74
+ - `prompt-verify` requires a non-empty `prompt` field. Missing or empty `prompt` is rejected.
75
+ - `content-heuristic` and `human-review` have no required sub-fields beyond `policy`.
76
+ </verification_policies>
@@ -0,0 +1,46 @@
1
+ <schema_reference>
2
+ V1 Workflow Definition Schema — complete field-by-field reference extracted from `definition-loader.ts`.
3
+
4
+ **Top-Level Fields:**
5
+
6
+ | Field | Type | Required | Default | Description |
7
+ |-------|------|----------|---------|-------------|
8
+ | `version` | number | **yes** | — | Must be exactly `1`. |
9
+ | `name` | string | **yes** | — | Non-empty workflow name. |
10
+ | `description` | string | no | `undefined` | Optional human-readable description. |
11
+ | `params` | object | no | `undefined` | Key-value map of parameter defaults. Values must be strings. Used for `{{ key }}` substitution in step prompts. |
12
+ | `steps` | array | **yes** | — | Non-empty array of step objects. |
13
+
14
+ **Step Fields:**
15
+
16
+ | Field | Type | Required | Default | Description |
17
+ |-------|------|----------|---------|-------------|
18
+ | `id` | string | **yes** | — | Unique identifier within the workflow. Must be non-empty. No two steps can share an ID. |
19
+ | `name` | string | **yes** | — | Human-readable step name. Must be non-empty. |
20
+ | `prompt` | string | **yes** | — | The prompt dispatched for this step. Must be non-empty. Supports `{{ key }}` parameter placeholders. |
21
+ | `requires` | string[] | no | `[]` | IDs of steps that must complete before this step runs. Alternative name: `depends_on`. |
22
+ | `depends_on` | string[] | no | `[]` | Alias for `requires`. If both are present, `requires` takes precedence. |
23
+ | `produces` | string[] | no | `[]` | Artifact paths produced by this step (relative to run directory). Paths must not contain `..`. |
24
+ | `context_from` | string[] | no | `undefined` | Step IDs whose artifacts are injected as context when this step runs. |
25
+ | `verify` | object | no | `undefined` | Verification policy for this step. See verification-policies.md for details. |
26
+ | `iterate` | object | no | `undefined` | Fan-out iteration config. See feature-patterns.md for details. |
27
+
28
+ **Validation Rules:**
29
+
30
+ 1. `version` must be exactly `1` (number, not string).
31
+ 2. `name` must be a non-empty string.
32
+ 3. `steps` must be a non-empty array of objects.
33
+ 4. Each step must have non-empty `id`, `name`, and `prompt`.
34
+ 5. Step IDs must be unique — duplicates are rejected.
35
+ 6. Dependencies must reference existing step IDs — dangling references are rejected.
36
+ 7. A step cannot depend on itself.
37
+ 8. The dependency graph must be acyclic — cycles are detected and rejected.
38
+ 9. `produces` paths and `iterate.source` must not contain `..` (path traversal guard).
39
+ 10. Unknown top-level or step-level fields are silently accepted for forward compatibility.
40
+
41
+ **Type Notes:**
42
+
43
+ - `requires` / `depends_on`: The engine reads `requires` first. If absent, it falls back to `depends_on`. Both must be arrays of strings if present.
44
+ - `params` values must be strings. During substitution, each `{{ key }}` in a step prompt is replaced with the merged param value (definition defaults ← CLI overrides). Any unresolved placeholder after substitution causes an error.
45
+ - Parameter values and `produces` paths are guarded against path traversal (`..` is rejected).
46
+ </schema_reference>
@@ -0,0 +1,60 @@
1
+ # Example: Blog Post Pipeline
2
+ # Demonstrates: context chaining (context_from), parameters (params),
3
+ # and content-heuristic verification across a 3-step linear chain.
4
+
5
+ version: 1
6
+ name: blog-post-pipeline
7
+ description: >-
8
+ Research a topic, create an outline, and draft a blog post.
9
+ Uses params for topic/audience, context_from for chaining,
10
+ and content-heuristic verification at every step.
11
+
12
+ params:
13
+ topic: "AI"
14
+ audience: "developers"
15
+
16
+ steps:
17
+ - id: research
18
+ name: Research the topic
19
+ prompt: >-
20
+ Research the topic "{{ topic }}" for an audience of {{ audience }}.
21
+ Write detailed findings including key trends, important facts,
22
+ and relevant examples. Save the results to research.md.
23
+ requires: []
24
+ produces:
25
+ - research.md
26
+ verify:
27
+ policy: content-heuristic
28
+ minSize: 200
29
+
30
+ - id: outline
31
+ name: Create an outline
32
+ prompt: >-
33
+ Using the research findings, create a structured blog post outline
34
+ targeting {{ audience }}. Include section headings, key points
35
+ for each section, and a logical flow. Save to outline.md.
36
+ requires:
37
+ - research
38
+ context_from:
39
+ - research
40
+ produces:
41
+ - outline.md
42
+ verify:
43
+ policy: content-heuristic
44
+
45
+ - id: draft
46
+ name: Write the draft
47
+ prompt: >-
48
+ Write a complete blog post draft following the outline.
49
+ The post should be engaging for {{ audience }}, cover all
50
+ outlined sections, and include a compelling introduction
51
+ and conclusion. Save to draft.md.
52
+ requires:
53
+ - outline
54
+ context_from:
55
+ - outline
56
+ produces:
57
+ - draft.md
58
+ verify:
59
+ policy: content-heuristic
60
+ minSize: 500
@@ -0,0 +1,60 @@
1
+ # Example: Code Audit
2
+ # Demonstrates: iterate (fan-out over file list), shell-command verification,
3
+ # prompt-verify, and content-heuristic across a 3-step workflow.
4
+
5
+ version: 1
6
+ name: code-audit
7
+ description: >-
8
+ Inventory TypeScript files, audit each one for quality issues,
9
+ and produce a consolidated report. Uses iterate to fan-out
10
+ audits across discovered files.
11
+
12
+ steps:
13
+ - id: inventory
14
+ name: Inventory source files
15
+ prompt: >-
16
+ List all TypeScript source files in the project that should
17
+ be audited. Write one file path per line as a Markdown list
18
+ item (e.g. "- src/index.ts"). Save the list to inventory.md.
19
+ requires: []
20
+ produces:
21
+ - inventory.md
22
+ verify:
23
+ policy: content-heuristic
24
+
25
+ - id: audit-file
26
+ name: Audit individual file
27
+ prompt: >-
28
+ Review the file for code quality issues including unused imports,
29
+ missing error handling, type safety gaps, and potential bugs.
30
+ Document each finding with the line number and a recommended fix.
31
+ Append results to audit-results.md.
32
+ requires:
33
+ - inventory
34
+ context_from:
35
+ - inventory
36
+ produces:
37
+ - audit-results.md
38
+ iterate:
39
+ source: inventory.md
40
+ pattern: "^- (.+\\.ts)$"
41
+ verify:
42
+ policy: shell-command
43
+ command: "test -f audit-results.md"
44
+
45
+ - id: report
46
+ name: Compile audit report
47
+ prompt: >-
48
+ Compile all individual file audit results into a single
49
+ comprehensive audit report. Group findings by severity
50
+ (critical, warning, info), include summary statistics,
51
+ and provide prioritized recommendations. Save to audit-report.md.
52
+ requires:
53
+ - audit-file
54
+ context_from:
55
+ - audit-file
56
+ produces:
57
+ - audit-report.md
58
+ verify:
59
+ policy: prompt-verify
60
+ prompt: "Does the report cover all audited files and group findings by severity? Answer PASS or FAIL."
@@ -0,0 +1,66 @@
1
+ # Example: Release Checklist
2
+ # Demonstrates: diamond dependency pattern (version-bump and test-suite
3
+ # both depend on changelog, publish depends on both), shell-command
4
+ # verification, and human-review policy.
5
+
6
+ version: 1
7
+ name: release-checklist
8
+ description: >-
9
+ Prepare a software release: generate changelog, bump version,
10
+ run tests, and publish release notes. Uses a diamond dependency
11
+ pattern where publish waits for both version-bump and test-suite.
12
+
13
+ steps:
14
+ - id: changelog
15
+ name: Generate changelog
16
+ prompt: >-
17
+ Review recent commits and generate a changelog draft.
18
+ Group changes by category (features, fixes, breaking changes).
19
+ Follow Keep a Changelog format. Save to CHANGELOG-draft.md.
20
+ requires: []
21
+ produces:
22
+ - CHANGELOG-draft.md
23
+ verify:
24
+ policy: content-heuristic
25
+
26
+ - id: version-bump
27
+ name: Bump version number
28
+ prompt: >-
29
+ Based on the changelog, determine the appropriate semver bump
30
+ (major, minor, or patch). Write the new version number to
31
+ version.txt as a single line (e.g. "1.2.3").
32
+ requires:
33
+ - changelog
34
+ produces:
35
+ - version.txt
36
+ verify:
37
+ policy: shell-command
38
+ command: "grep -E '^[0-9]+\\.[0-9]+\\.[0-9]+$' version.txt"
39
+
40
+ - id: test-suite
41
+ name: Run test suite
42
+ prompt: >-
43
+ Run the full test suite and capture results. Include test
44
+ counts (passed, failed, skipped), execution time, and any
45
+ failure details. Save results to test-results.md.
46
+ requires:
47
+ - changelog
48
+ produces:
49
+ - test-results.md
50
+ verify:
51
+ policy: shell-command
52
+ command: "test -f test-results.md"
53
+
54
+ - id: publish
55
+ name: Publish release
56
+ prompt: >-
57
+ Compile the final release notes combining the changelog,
58
+ version number, and test results. Format for GitHub Releases
59
+ with proper Markdown. Save to release-notes.md.
60
+ requires:
61
+ - version-bump
62
+ - test-suite
63
+ produces:
64
+ - release-notes.md
65
+ verify:
66
+ policy: human-review
@@ -0,0 +1,32 @@
1
+ version: 1
2
+ name: my-workflow
3
+ # description: A brief description of what this workflow accomplishes.
4
+
5
+ # params:
6
+ # topic: "default value"
7
+ # target: "another default"
8
+
9
+ steps:
10
+ - id: step-one
11
+ name: First step
12
+ prompt: "Describe what this step should accomplish."
13
+ # requires: []
14
+ produces:
15
+ - output.md
16
+ # context_from:
17
+ # - some-prior-step
18
+ # verify:
19
+ # policy: content-heuristic
20
+ # minSize: 100
21
+ # pattern: "## Summary"
22
+ # verify:
23
+ # policy: shell-command
24
+ # command: "test -f output.md"
25
+ # verify:
26
+ # policy: prompt-verify
27
+ # prompt: "Does the output meet quality standards? Answer PASS or FAIL."
28
+ # verify:
29
+ # policy: human-review
30
+ # iterate:
31
+ # source: file-list.txt
32
+ # pattern: "^(.+)$"