@terreno/agent-plugin 0.0.0-stage → 58.0.0-beta.2

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 (98) hide show
  1. package/.claude-plugin/plugin.json +32 -0
  2. package/CHANGELOG.md +2213 -0
  3. package/LICENSE +21 -0
  4. package/README.md +57 -2
  5. package/agents/pre-commit.md +65 -0
  6. package/agents/ui-verifier.md +93 -0
  7. package/package.json +32 -4
  8. package/references/async-review-bots.md +76 -0
  9. package/references/documentation-contract.md +61 -0
  10. package/references/execution-state.schema.json +77 -0
  11. package/references/github-attention-contract.md +165 -0
  12. package/references/independent-review.md +31 -0
  13. package/references/lifecycle-contract.md +211 -0
  14. package/references/loop-engineering.md +125 -0
  15. package/references/pick-roast-loop.md +112 -0
  16. package/references/pr-deployments.md +69 -0
  17. package/references/product-ci.md +164 -0
  18. package/references/push-ownership.md +91 -0
  19. package/references/stage-result.schema.json +82 -0
  20. package/references/subagent-briefing.md +43 -0
  21. package/references/testing-plan.md +163 -0
  22. package/references/user-guide.md +171 -0
  23. package/skills/1-grow/SKILL.md +145 -0
  24. package/skills/1-grow/references/grilling.md +243 -0
  25. package/skills/2-pick/SKILL.md +170 -0
  26. package/skills/2-pick/references/mocking.md +34 -0
  27. package/skills/2-pick/references/testing.md +43 -0
  28. package/skills/3-roast/SKILL.md +168 -0
  29. package/skills/4-brew/SKILL.md +201 -0
  30. package/skills/5-taste/SKILL.md +311 -0
  31. package/skills/ai-prompt-governance/SKILL.md +100 -0
  32. package/skills/attach-pr-media/SKILL.md +89 -0
  33. package/skills/attach-pr-media/scripts/upload-pr-media.sh +151 -0
  34. package/skills/backend-test-env/SKILL.md +64 -0
  35. package/skills/backfill-regression/SKILL.md +101 -0
  36. package/skills/backfill-user-guide/SKILL.md +96 -0
  37. package/skills/bootstrap-mcp-server/SKILL.md +244 -0
  38. package/skills/building-admin-interfaces/SKILL.md +86 -0
  39. package/skills/building-admin-interfaces/agents/openai.yaml +4 -0
  40. package/skills/building-admin-interfaces/references/nav-and-shell.md +42 -0
  41. package/skills/building-admin-interfaces/references/patterns-and-tools.md +74 -0
  42. package/skills/building-admin-interfaces/references/screens-and-routes.md +50 -0
  43. package/skills/building-terreno-apps/SKILL.md +294 -0
  44. package/skills/building-terreno-apps/agents/openai.yaml +4 -0
  45. package/skills/building-terreno-apps/references/navigation.md +108 -0
  46. package/skills/building-terreno-apps/references/route-structure.md +104 -0
  47. package/skills/building-terreno-apps/references/screen-patterns.md +174 -0
  48. package/skills/debug-syncdb-with-mcp/SKILL.md +75 -0
  49. package/skills/deploy-gcp/SKILL.md +73 -0
  50. package/skills/deploy-gcp/references/troubleshooting.md +29 -0
  51. package/skills/generate-release-announcements/SKILL.md +145 -0
  52. package/skills/generate-sdk/SKILL.md +165 -0
  53. package/skills/mongoose-schema-safety/SKILL.md +164 -0
  54. package/skills/pick-roast-loop/SKILL.md +152 -0
  55. package/skills/planning-loop/SKILL.md +161 -0
  56. package/skills/prd/SKILL.md +138 -0
  57. package/skills/set-up-social-login/SKILL.md +76 -0
  58. package/skills/store-assets/SKILL.md +221 -0
  59. package/skills/store-assets/examples/screenshots.yaml +31 -0
  60. package/skills/store-assets/examples/storeAssets.config.json +44 -0
  61. package/skills/store-assets/scripts/banner.ts +165 -0
  62. package/skills/store-assets/scripts/config.ts +255 -0
  63. package/skills/store-assets/scripts/devClient.ts +635 -0
  64. package/skills/store-assets/scripts/devices.ts +286 -0
  65. package/skills/store-assets/scripts/icon.ts +81 -0
  66. package/skills/store-assets/scripts/maestro/goHome.yaml +21 -0
  67. package/skills/store-assets/scripts/maestro/login.yaml +27 -0
  68. package/skills/store-assets/scripts/maestro/openApp.yaml +26 -0
  69. package/skills/store-assets/scripts/screenshots.ts +848 -0
  70. package/skills/taste-sweep/SKILL.md +172 -0
  71. package/skills/terreno-backend-api/SKILL.md +355 -0
  72. package/skills/terreno-backend-api/agents/openai.yaml +4 -0
  73. package/skills/terreno-backend-api/references/custom-routes.md +132 -0
  74. package/skills/terreno-backend-api/references/model-router.md +112 -0
  75. package/skills/terreno-backend-api/references/server-setup.md +116 -0
  76. package/skills/terreno-backend-tests/SKILL.md +176 -0
  77. package/skills/terreno-data-fetching/SKILL.md +288 -0
  78. package/skills/terreno-data-fetching/agents/openai.yaml +4 -0
  79. package/skills/terreno-data-fetching/references/auth-and-tokens.md +89 -0
  80. package/skills/terreno-data-fetching/references/realtime.md +50 -0
  81. package/skills/terreno-data-fetching/references/sdk-customization.md +55 -0
  82. package/skills/terreno-frontend-tests/SKILL.md +190 -0
  83. package/skills/terreno-mobile-tests/SKILL.md +127 -0
  84. package/skills/terreno-test-setup/SKILL.md +81 -0
  85. package/skills/terreno-test-setup/references/backend.md +131 -0
  86. package/skills/terreno-test-setup/references/frontend.md +169 -0
  87. package/skills/terreno-test-setup/references/mobile.md +134 -0
  88. package/skills/terreno-ui/SKILL.md +252 -0
  89. package/skills/terreno-ui/agents/openai.yaml +4 -0
  90. package/skills/terreno-ui/references/data-display.md +87 -0
  91. package/skills/terreno-ui/references/feedback.md +122 -0
  92. package/skills/terreno-ui/references/forms.md +119 -0
  93. package/skills/terreno-ui/references/layout.md +124 -0
  94. package/skills/terreno-ui/references/theming.md +87 -0
  95. package/skills/update-docs/SKILL.md +82 -0
  96. package/skills/upgrading-terreno/SKILL.md +93 -0
  97. package/skills/upgrading-terreno/references/ordering.md +40 -0
  98. package/skills/verify-ui-changes/SKILL.md +605 -0
@@ -0,0 +1,164 @@
1
+ ---
2
+ name: mongoose-schema-safety
3
+ description: >-
4
+ Invoke when making any Mongoose schema change: adding/removing/renaming
5
+ fields, creating a new model, adding indexes, or writing a backfill migration.
6
+ Provides the five-type pattern, risk matrix, type file checklist, and rollout
7
+ safety steps for Terreno backends.
8
+ ---
9
+ # Mongoose Schema Safety — Terreno
10
+
11
+ Typical Terreno apps keep models under `backend/src/models/` and types under `backend/src/types/models/`. The Terreno monorepo also uses `example-backend/` and `@terreno/ai` — adjust paths below to match your repo.
12
+
13
+ ## Documentation
14
+
15
+ 1. Read the app's model/API docs before changing schemas, types, or indexes.
16
+ 2. Implement against that design.
17
+ 3. Update those docs in the same slice. Schema field `description`s are public docs via OpenAPI.
18
+ 4. Ship without matching docs is a failed slice.
19
+
20
+ ## Where Schemas and Types Live
21
+
22
+ | Package | Schemas | Types |
23
+ |---------|---------|-------|
24
+ | `@terreno/api` (built-in models like `User`, `ConsentForm`) | `api/src/models/*.ts` | `api/src/types/*.ts` (or co-located in the model file via `mongoose.Schema<Doc, Model, Methods>` generics) |
25
+ | `example-backend` (`User`, `Todo`, `Configuration`) | `example-backend/src/models/*.ts` | `example-backend/src/types/models/*.ts` (`userTypes.ts`, `todoTypes.ts`, …) |
26
+ | `@terreno/ai` (`AIRequest`, `GptHistory`) | `ai/src/models/*.ts` | `ai/src/types/index.ts` |
27
+
28
+ Every field in every schema **must** have a `description` (see the API rule `01-model-field-descriptions.md`). Descriptions flow through to the OpenAPI spec via `mongoose-to-swagger`.
29
+
30
+ ## The Five-Type Pattern
31
+
32
+ Every model has manually-maintained TypeScript types. **Types are NOT auto-generated** — every schema change must include a matching type update in the same commit/PR.
33
+
34
+ ```typescript
35
+ import type {DefaultDoc, DefaultModel, DefaultStatics} from "@terreno/api";
36
+
37
+ // 1. Instance methods (on the document)
38
+ export type YourModelMethods = {
39
+ customMethod: (this: YourModelDocument, param: string) => Promise<void>;
40
+ };
41
+
42
+ // 2. Static methods (on the model class) — extend DefaultStatics for findExactlyOne / findOneOrNone
43
+ export type YourModelStatics = DefaultStatics<YourModelDocument> & {
44
+ customStatic: (this: YourModelModel, param: string) => Promise<YourModelDocument>;
45
+ };
46
+
47
+ // 3. Model type combining document + statics
48
+ export type YourModelModel = DefaultModel<YourModelDocument> & YourModelStatics;
49
+
50
+ // 4. Schema type
51
+ export type YourModelSchema = mongoose.Schema<YourModelDocument, YourModelModel, YourModelMethods>;
52
+
53
+ // 5. Document type (the shape of a single record)
54
+ export type YourModelDocument = DefaultDoc & YourModelMethods & {
55
+ fieldName: string;
56
+ optionalField?: number;
57
+ enumField: "value1" | "value2";
58
+ };
59
+ ```
60
+
61
+ Follow existing type files in `example-backend/src/types/models/` and `ai/src/types/index.ts` for naming and structure.
62
+
63
+ ## Statics & Methods — Direct Assignment
64
+
65
+ Define statics and methods by direct assignment on the schema — not via `.method()` / `.static()` / `.add()`:
66
+
67
+ ```typescript
68
+ schema.methods = {
69
+ getDisplayName(this: YourModelDocument): string {
70
+ return this.name;
71
+ },
72
+ };
73
+ schema.statics = {
74
+ async findByEmail(this: YourModelModel, email: string) {
75
+ return this.findOneOrNone({email});
76
+ },
77
+ };
78
+ ```
79
+
80
+ ## Critical Mongoose Rules
81
+
82
+ - **Never use `Model.findOne`** — use `Model.findExactlyOne` (throws on 0 or many) or `Model.findOneOrNone` (throws on many). These come from the `findExactlyOne` / `findOneOrNone` plugins in `@terreno/api`.
83
+ - Apply the standard plugins (`createdUpdatedPlugin`, `isDeletedPlugin`, `findOneOrNone`, `findExactlyOne`) on every new model. Most existing models go through `addDefaultPlugins`.
84
+ - `checkModelsStrict()` runs at non-prod startup (`server.ts`) and validates schema consistency — keep it passing.
85
+
86
+ ## Migration files
87
+
88
+ Schema and data changes that must run once per environment belong in
89
+ `migrations/<YYYYMMDDHHmmss>-<slug>.ts` with required `up` and optional `down`.
90
+ Generate a draft with `terreno-migrate generate --dir ./migrations --models ./src/models.ts`,
91
+ then `terreno-migrate up --dir ./migrations --dry` before wet apply.
92
+ See [Run MongoDB migrations](../../../../docs/how-to/run-mongodb-migrations.md).
93
+
94
+ Admin **Scripts** (`ScriptRunner` + `BackgroundTask`) stay for one-off operator
95
+ tools. Do not use Scripts as the primary path for versioned schema backfills.
96
+
97
+ ## Schema Change Risk Matrix
98
+
99
+ | Change Type | Risk Level | Required Mitigation |
100
+ |-------------|-----------|---------------------|
101
+ | Add optional field | Low | Safe to ship directly (still requires `description`) |
102
+ | Add required field | High | Must provide a default value, OR write a versioned migration (`terreno-migrate generate` / `up`) with a backfill before wet apply |
103
+ | Remove field | Medium | Soft-remove first (mark optional, stop writing); hard-remove in next PR after deploys settle |
104
+ | Rename field | High | Three-step: add new → backfill migration → remove old (separate PRs) |
105
+ | Change field type | Critical | Treat as rename: new field + versioned migration + remove old |
106
+ | Add index | Medium | Prefer `terreno-migrate generate` for the index; build can slow writes on large collections — coordinate with ops |
107
+ | Remove index | Low | Safe to ship directly |
108
+ | Add unique index | High | Dedup in a versioned migration first; otherwise the index build fails on existing duplicates |
109
+
110
+ ## One-off admin scripts
111
+
112
+ Ad-hoc operator tools (counts, reseeds, support fixes) still live as admin
113
+ Scripts using `ScriptRunner` and `BackgroundTask`:
114
+
115
+ ```typescript
116
+ import type {ScriptContext, ScriptResult, ScriptRunner} from "@terreno/api";
117
+
118
+ export const run: ScriptRunner = async (wetRun, ctx) => {
119
+ const results: string[] = [];
120
+ if (wetRun) {
121
+ // commit changes
122
+ }
123
+ return {success: true, results};
124
+ };
125
+ ```
126
+
127
+ Always run with `wetRun = false` first. Use `ctx.checkCancellation()`,
128
+ `ctx.addLog()`, and `ctx.updateProgress()` for long-running tasks. Do not put
129
+ repeatable schema backfills here — use `migrations/` and `terreno-migrate`.
130
+
131
+ ## Cross-Package Ripple
132
+
133
+ A schema change in one place often ripples:
134
+
135
+ - **API surface affected?** Regenerate the SDK with `cd example-frontend && bun run sdk` (or invoke the `generate-sdk` skill). The OpenAPI spec is derived from the schema, so the frontend hooks will go stale otherwise.
136
+ - **`modelRouter` config?** If you added/removed a field, update `queryFields`, `populatePaths`, and `responseHandler` for any router that touches the model.
137
+ - **Admin panel?** If the model is registered in `AdminApp`, update `listFields` so the table reflects the new shape.
138
+ - **Populated refs?** If another model references this one via `ObjectId` + `ref`, and the referenced document shape changed, the consumer's populated type may need updating.
139
+
140
+ ## Post-Change Checklist
141
+
142
+ - [ ] All new fields have a `description` (flows to OpenAPI)
143
+ - [ ] Type file updated in the same commit/PR — field names, optionality, enum values, array types, refs, statics/methods all match the schema
144
+ - [ ] For a new model: all five types (`Document`, `Methods`, `Statics`, `Model`, `Schema`) created
145
+ - [ ] Statics/methods assigned directly on schema (`schema.statics = {...}`, `schema.methods = {...}`) — not `.static()` / `.method()`
146
+ - [ ] Other model type files checked — any model that populates this one updated if its shape changed
147
+ - [ ] Versioned migration written (`migrations/` + `terreno-migrate`) and dry-run verified for any backfill; unique-index dedup runs before the index is added
148
+ - [ ] `modelRouter` config updated (`queryFields`, `populatePaths`, `responseHandler`) if needed
149
+ - [ ] `AdminApp` `listFields` updated if the model is in the admin panel
150
+ - [ ] `bun run sdk` run from `example-frontend/` if the API response shape changed
151
+ - [ ] Docs updated when the public shape or operator steps changed
152
+ - [ ] Test covers old-format document behavior (missing new field) if the change rolls out before a backfill
153
+ - [ ] Unique index: dedup migration written and run before the index is added
154
+ - [ ] `checkModelsStrict()` still passes (it runs on non-prod startup)
155
+ - [ ] No `Model.findOne` introduced — use `findExactlyOne` / `findOneOrNone`
156
+
157
+ ## Common Pitfalls
158
+
159
+ - Adding a required field without a default — first deploy fails for documents that pre-date the field
160
+ - Skipping the type file update — TS happily compiles older callers but new ones break at runtime
161
+ - Adding a `unique` index without dedup — index build fails on collections with existing duplicates
162
+ - Renaming a field in one PR — frontend gets old field, backend writes new field, neither side is happy
163
+ - Forgetting to regenerate the SDK after a shape change — frontend types drift from reality
164
+ - Using `.method()` / `.static()` API — terreno's convention is direct assignment, and mixing styles makes types hard to maintain
@@ -0,0 +1,152 @@
1
+ ---
2
+ name: pick-roast-loop
3
+ description: Drive an approved plan through every Pick–Roast cycle until all tasks pass or a genuine human decision is required. Continue through recoverable engineering failures, keep a complete run ledger, and when input is required present the overall state, completed work and evidence, options, recommendation, and exact question. Not for Grow, Brew, Taste, or CI monitoring.
4
+ ---
5
+
6
+ # Pick–Roast loop (outer recovery driver)
7
+
8
+ Drive an **approved** task list through implementation and independent proof. This is
9
+ an outer recovery loop around Pick's inner loop: normally invoke Pick once and let it
10
+ continue task by task; reinvoke only when Pick or Roast had to exit with actionable
11
+ engineering work remaining.
12
+
13
+ Read the shared [`lifecycle contract`](../../references/lifecycle-contract.md),
14
+ [`pick-roast inner loop`](../../references/pick-roast-loop.md),
15
+ [`PR deployments`](../../references/pr-deployments.md), and
16
+ [`subagent briefing`](../../references/subagent-briefing.md). The ledger must conform
17
+ to [`execution-state.schema.json`](../../references/execution-state.schema.json).
18
+
19
+ ## Scope
20
+
21
+ - Included: Pick, each task's Roast, focused retries, execution-state persistence, and
22
+ one accumulated report.
23
+ - Excluded: Grow/plan approval, Brew/PR submission, Taste/CI/review monitoring, release,
24
+ deployment, and unrelated cleanup.
25
+ - Never invoke Brew or Taste. Successful completion emits `next: brew`.
26
+
27
+ ## Preconditions
28
+
29
+ - A human-approved IP/task contract exists.
30
+ - The current branch, task list, and execution-state location are resolvable.
31
+ - At least one task is incomplete or has a non-terminal Roast result.
32
+
33
+ If the plan is missing or unapproved, stop at a human gate. Do not silently run Grow or
34
+ invent acceptance criteria.
35
+
36
+ ## Run ledger
37
+
38
+ Create one compact `ledger` array in execution state before invoking a stage. Append one
39
+ schema-valid entry after every Pick/Roast result:
40
+
41
+ - task id and short outcome
42
+ - attempt number and head SHA
43
+ - files changed
44
+ - Roast verdict and criterion failures
45
+ - focused fix/hypothesis used for each retry
46
+ - checks, artifacts, and docs evidence
47
+ - blockers, decisions, and residual risks
48
+
49
+ Do not stream a recap after each cycle. Preserve stage evidence, but defer the
50
+ human-facing report until completion or a genuine human gate.
51
+
52
+ ## Drive
53
+
54
+ 1. **Reconstruct once.** Read the approved task graph and execution state. Identify the
55
+ next incomplete or failed task. Verify branch/head and prior attempts.
56
+ 2. **Invoke the named stage.** After reconstructing, invoke `next.stage` only when it is pick or roast.
57
+ Use Pick for implementation/rework, or Roast when Pick completed the task but
58
+ exited before proof. Pass the current task, exact prior evidence, and the same
59
+ task-scoped briefing. Pick owns normal task → Roast → next-task progression.
60
+ - If `next.stage` is `brew`, or every in-scope task already Roast-passed, finish
61
+ with `next: brew`. Do not invoke Brew.
62
+ - If `next.stage` is `taste` or `grow`, stop with `FAIL`. This loop does not run
63
+ those stages.
64
+ - If `next.stage` is unset, default to Pick.
65
+ 3. **Consume the result.** Update the ledger, then classify:
66
+ - `PASS` with all tasks Roast-passed → finish with `next: brew`.
67
+ - `FAIL` with `next: pick` or `next: roast` and a concrete engineering action →
68
+ reinvoke that stage in a fresh context with prior evidence and the same
69
+ task-scoped briefing.
70
+ - `BLOCKED` with a `block` entry whose `kind` is `human`, or `next.human: true` →
71
+ present the human gate.
72
+ - `BLOCKED` for environment/access/external state → attempt safe autonomous
73
+ remediation or a bounded retry when a new hypothesis exists. Never relabel it
74
+ `human` merely to stop.
75
+ - A terminal non-human blocker with no safe remediation → stop and report it as
76
+ blocked; do not ask the human a decision question unless they can actually decide it.
77
+ 4. **Bound retries by evidence.** A retry must add a new hypothesis, changed setup, or
78
+ new evidence. Never repeat the same failed command/approach. After two focused
79
+ failures for the same task and stage with no new hypothesis, classify the underlying
80
+ decision or capability honestly instead of looping.
81
+ 5. **Continue silently.** Repeat steps 2–4, invoking only the stage named by durable
82
+ state and passing the same task-scoped briefing every time, until every task passes
83
+ Roast or a stop condition below is reached.
84
+
85
+ ## Genuine human gate
86
+
87
+ Ask for input only for:
88
+
89
+ - unresolved product semantics or acceptance criteria
90
+ - architecture, security, privacy, data ownership, or public compatibility choices
91
+ - destructive/irreversible operations or policy-required approval
92
+ - material scope expansion with multiple valid outcomes
93
+ - credentials/permissions the human can provide and no authorized alternative exists
94
+
95
+ Before the question, provide this overview in plain language:
96
+
97
+ 1. **Goal and state:** plan name, current task, completed/total tasks, current head.
98
+ 2. **What happened:** work completed, Roast results, retries, and decisive evidence.
99
+ 3. **Why input is needed:** the exact decision and why engineering evidence cannot
100
+ choose it.
101
+ 4. **Options:** two to four concrete choices with impact and risk.
102
+ 5. **Recommendation:** one default and its rationale.
103
+
104
+ End with **one exact question** the human can answer in one message. Then close with
105
+ PR deployment URLs when a PR has them. Do not expose chain-of-thought, raw transcripts,
106
+ or unexplained stage YAML.
107
+
108
+ ## Completion report
109
+
110
+ When all tasks Roast-pass, lead with:
111
+
112
+ `PASS — <passed>/<total> tasks independently verified. Next: Brew.`
113
+
114
+ Then report:
115
+
116
+ - `Completed`: every task and shipped behavior
117
+ - `Roast history`: failures found and how each was resolved
118
+ - `Verification`: checks, runtime evidence, artifacts, and docs
119
+ - `Changes`: commits/head and important files
120
+ - `Residual risk`: explicit remaining risk or `None identified`
121
+ - `Next`: `4-brew`
122
+
123
+ When stopped, use the same report plus `Blocker`. Include everything from the ledger
124
+ once; do not duplicate per-cycle narration. Close wait-for-human and done reports with
125
+ PR deployment URLs when a PR has them.
126
+
127
+ ## Stop conditions
128
+
129
+ - `PASS`: every in-scope task has Roast `PASS` on the recorded head.
130
+ - `BLOCKED` (human): a genuine human gate above.
131
+ - `BLOCKED` (non-human): retries are exhausted and no safe autonomous action exists.
132
+ - `FAIL`: state is inconsistent/corrupt or the named next stage cannot be invoked.
133
+
134
+ Ordinary test failures, lint failures, implementation defects, and Roast findings are
135
+ not terminal while a concrete engineering action remains.
136
+
137
+ ## Emit
138
+
139
+ After the human-facing report, include one collapsed stage-result payload. Since outer
140
+ loops are not stages, set `stage` to the last stage invoked (`pick` or `roast`).
141
+
142
+ ```yaml
143
+ v: 2
144
+ stage: pick
145
+ status: PASS
146
+ next: brew
147
+ action: Submit the fully Roast-verified plan with Brew.
148
+ ```
149
+
150
+ For a human gate, use `status: BLOCKED`, `next: null`, and an `ask` entry containing
151
+ the exact question, recommendation, and options. For a non-human terminal blocker, use
152
+ a `block` array entry with `kind: environment`, `access`, or `external`, and omit `ask`.
@@ -0,0 +1,161 @@
1
+ ---
2
+ name: planning-loop
3
+ description: Drive the planning plugin from the current task list, optionally restricting which stages run (Grow, Pick, Roast, Brew, Taste). Not a sixth stage — an outer loop that invokes existing stage skills. Use when asked to run the planning loop, walk the task list, or restrict work to selected phases.
4
+ ---
5
+
6
+ # Planning loop (outer driver)
7
+
8
+ Not a stage. The five stages stay Grow, Pick, Roast, Brew, Taste. This skill
9
+ walks the **current** task list and invokes those stage skills in order.
10
+
11
+ Pick owns the inner **pick → roast → next-task → brew** loop (see
12
+ `plugins/terreno-planning/references/pick-roast-loop.md`). This outer loop
13
+ must **not** Pick then Roast per task as a second driver. If `pick` is in
14
+ the requested phases, invoke Pick **once**; Pick roasts each task and
15
+ continues. If `roast` is requested **with** `pick`, do not start a second
16
+ Roast driver.
17
+
18
+ ## When to use
19
+
20
+ - The user asks to run the planning loop, walk the task list, or keep going
21
+ until the list is empty.
22
+ - The user names phases (`grow`, `pick`, `roast`, `brew`, `taste`) and wants
23
+ only those stages.
24
+ - Default when the user says "planning loop" with no phases:
25
+ **Grow, then Pick** (Pick includes Roast for each task, then Brew).
26
+
27
+ ## Parse phases
28
+
29
+ Read the user message for a phase list, in this order:
30
+
31
+ 1. `phases=` (comma-separated, case-insensitive)
32
+ 2. A bare comma-separated list of allowed tokens (`grow,roast` or
33
+ `grow, pick, brew`)
34
+ 3. Tokens after `/planning-loop` or the skill name
35
+
36
+ Allowed tokens: `grow`, `pick`, `roast`, `brew`, `taste`.
37
+
38
+ Ignore unknown tokens. Deduplicate while preserving order.
39
+
40
+ If nothing remains after filtering, use `grow,pick,roast`.
41
+ That default still means Grow then Pick — Roast is owned by Pick, not a
42
+ second outer-loop pass.
43
+
44
+ ## Read first
45
+
46
+ Read the shared [`lifecycle contract`](../../references/lifecycle-contract.md),
47
+ [`loop engineering`](../../references/loop-engineering.md),
48
+ [`pick-roast inner loop`](../../references/pick-roast-loop.md), and
49
+ [`PR deployments`](../../references/pr-deployments.md). When Brew or Taste is
50
+ selected, also read [`product CI`](../../references/product-ci.md). Then:
51
+
52
+ 1. `plugins/README.md` — Hosts and stage skills
53
+ 2. Each selected stage skill under `plugins/terreno-planning/skills/`
54
+
55
+ ## Drive the selected phases
56
+
57
+ Stay on the current branch. Do not start a nested PR. One logical commit
58
+ per completed unit of work.
59
+
60
+ ### Grow (`grow`)
61
+
62
+ If `grow` is selected and the task list is empty or missing, invoke
63
+ `1-grow` once (shape / confirm the list). Skip Grow when a current
64
+ list already exists unless the user asked to reshape.
65
+
66
+ If Grow emits `FAIL`, stop. Do not invent tasks.
67
+
68
+ ### Pick (`pick`) — includes Roast
69
+
70
+ If `pick` is selected, invoke `2-pick` **once**. Pick:
71
+
72
+ 1. Takes the next unchecked task
73
+ 2. Implements it
74
+ 3. Invokes Roast for that task
75
+ 4. On Roast `PASS`, continues to the next unchecked task
76
+ 5. After the last task, emits `next: brew` (unless `brew` was excluded — then
77
+ stop after the last Roast `PASS` and tell the user Brew is the next
78
+ human/agent step)
79
+
80
+ Do not wrap Pick in an outer per-task loop. Do not invoke Roast yourself
81
+ when Pick is in the phase list.
82
+
83
+ If Pick emits `FAIL`, stop.
84
+
85
+ Honor Pick's `next` / `wait` when it yields.
86
+
87
+ ### Roast (`roast`) without Pick
88
+
89
+ If `roast` is selected and `pick` is **not**, invoke `3-roast`
90
+ once for the current in-progress task (prove / tests). Do not start Pick's
91
+ inner loop.
92
+
93
+ If Roast emits `FAIL`, stop.
94
+
95
+ ### Skip Roast when Pick is selected
96
+
97
+ If both `pick` and `roast` appear in `phases=`, treat Roast as already
98
+ owned by Pick. Do not invoke `3-roast` as a second driver.
99
+
100
+ ### Brew (`brew`)
101
+
102
+ If `brew` is selected, invoke `4-brew` after the selected pre-submit stages.
103
+ Pick emits `next: brew` at the end of its inner loop; it does not invoke Brew itself.
104
+
105
+ If Brew emits `FAIL`, **do not stop the outer loop**. Read Brew's `next`
106
+ field and continue with that stage in the same invocation:
107
+
108
+ - `next: pick` — invoke `2-pick` (which will Roast again as part of
109
+ its inner loop)
110
+ - `next: roast` — invoke `3-roast` (only when Pick is not driving)
111
+ - `next: brew` — invoke `4-brew` again for a submission-only retry; honor
112
+ `wait` when provided
113
+
114
+ Keep following Brew `FAIL` → `next` until Brew emits `PASS` or `FAIL` with
115
+ no recoverable `next`, or a non-Brew stage emits `FAIL`. Then stop.
116
+
117
+ If Brew emits `PASS`, continue to Taste only when `taste` is selected.
118
+
119
+ ### Taste (`taste`)
120
+
121
+ If `taste` is selected, invoke `5-taste` after Brew `PASS` (or
122
+ after the last selected earlier stage if Brew was omitted). Taste reacts
123
+ to review on the current PR; it does not walk the task list.
124
+
125
+ If Taste emits `PASS`, stop. If Taste emits `FAIL` with a new evidence-based
126
+ hypothesis, invoke fresh Taste; a `FAIL` without one is `BLOCKED`. On `BLOCKED`, stop
127
+ and escalate per [`push ownership`](../../references/push-ownership.md#escalation).
128
+ Never stop on a red PR without that escalation. If Taste emits `PENDING`, honor
129
+ `wait` / `next`. During that bound, prefer the product-CI provider's native watch hook
130
+ or a harness event subscription; use a timer only when no hook applies. Invoke fresh
131
+ Taste as soon as the hook returns. Taste already waited in-process for CI on the
132
+ previous invocation; `PENDING` means that wait timed out or a second push landed.
133
+
134
+ ## Isolation and hosts
135
+
136
+ Same rules as the stage skills: one git checkout, no nested worktrees for
137
+ the loop itself, no extra `gh` auth, no `git config`. Cursor, Claude,
138
+ Codex, and Gemini all invoke this the same way — only the skill path
139
+ differs (see Hosts in `plugins/README.md`).
140
+
141
+ ## Emit (required)
142
+
143
+ After the last stage you ran, emit **only** a YAML object in a collapsed
144
+ Markdown `<details>` block. Use `status: PASS` when every selected stage
145
+ that ran emitted `PASS` (or Brew `FAIL` that you recovered by following
146
+ `next` through to a later `PASS`). Use `FAIL` if any stage stopped the
147
+ loop. Use `PENDING` if a stage asked you to wait.
148
+
149
+ ```yaml
150
+ v: 2
151
+ stage: pick
152
+ status: PASS
153
+ next: brew
154
+ action: Planning loop finished selected phases.
155
+ ```
156
+
157
+ Set `stage` to the last stage skill you invoked (`grow` | `pick` |
158
+ `roast` | `brew` | `taste`). Required keys are `v`, `stage`, `status`,
159
+ `next`, and `action`. Omit `wait` unless the last stage asked you to
160
+ wait (`wait` is a positive integer). After that YAML, close with PR
161
+ deployment URLs when the current PR has them.
@@ -0,0 +1,138 @@
1
+ ---
2
+ name: prd
3
+ description: Interview the app owner and write a full product requirements document (problem, why now, solution, user stories, measurable success metrics, constraints, rollout, out of scope), then publish it where the repository tracks work. Sized for one owner and one or two developers. Runs ahead of Grow; explicit invocation only.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # PRD — seed
8
+
9
+ Interview the person who owns the app, then write a full product PRD that Grow can shape
10
+ into an implementation plan without re-asking product questions.
11
+
12
+ Assume a small team: one owner who is also PM, designer, and final approver, plus one or
13
+ two developers. Skip ceremony a team that size does not need (stakeholder sign-off, RACI,
14
+ persona decks). Keep what it does need: a clear problem, measurable success, and the
15
+ constraints a developer would otherwise discover mid-build.
16
+
17
+ Adapted from [to-spec](https://github.com/mattpocock/skills/blob/main/skills/engineering/to-spec/SKILL.md)
18
+ (MIT, © Matt Pocock), keeping only the product half. The interview and the success-metric
19
+ rule are adapted from the [awesome-copilot prd skill](https://github.com/github/awesome-copilot/blob/main/skills/prd/SKILL.md)
20
+ (MIT). Implementation decisions, test seams, and testing decisions belong to Grow.
21
+
22
+ ## Process
23
+
24
+ 1. **Gather before asking.** Read the conversation, any linked prototype, demo, mock, or
25
+ ticket, and enough of the repository to know how the product behaves today in the
26
+ affected area. Use the project's domain vocabulary. Never ask what you can look up.
27
+ If a prototype exists, it is the source for the solution; link it instead of
28
+ re-describing it.
29
+ 2. **Interview.** Follow Grow's [grilling procedure](../1-grow/references/grilling.md)
30
+ for the mechanics: frontier rounds, selectable options with a recommended default, the
31
+ structured question tool when the harness has one, get to the bottom of every vague
32
+ answer, and confirm shared understanding before writing. Use the product tree below
33
+ instead of Grow's design tree. Ask at least one round even when the conversation looks
34
+ complete; confirm what you inferred instead of assuming it.
35
+ 3. **Write the PRD** with the template below, from the user's perspective. No file paths,
36
+ modules, schemas, or code.
37
+ 4. **Apply the success-metric rule.** Every success metric and guardrail is concrete and
38
+ measurable: a quantity, a threshold, and how it is measured. Replace adjectives
39
+ ("fast", "easy", "intuitive", "better") with numbers. If the owner cannot set a target
40
+ after you pressed once, write `TBD` and name what decides it. Never invent a number.
41
+ 5. **Publish.** Follow the repository's existing tracking convention (issue tracker,
42
+ planning directory, or spec folder). If none exists, open an issue in the repository's
43
+ tracker. Do not apply readiness labels; Grow owns approval.
44
+ 6. **Hand off.** Return the PRD link and any `TBD` items. Recommend Grow with the PRD as
45
+ its input.
46
+
47
+ ## Product tree
48
+
49
+ Work the frontier in this order of parents. Children unlock when the parent is
50
+ executable.
51
+
52
+ | Branch | Settle before writing |
53
+ | --- | --- |
54
+ | **Problem** | Who hits it, how often, what they do today instead, and what it costs them |
55
+ | **Why now** | What makes this worth doing before the rest of the backlog, and what it pushes back |
56
+ | **Solution** | The user-visible behavior and main flows; which prototype, if any, is the reference |
57
+ | **Success** | Metrics with targets, how and when they are measured, and guardrails that would make you turn it off |
58
+ | **Constraints** | Data, privacy, safety, performance, cost (including AI model cost), platforms, and the people who must learn the change |
59
+ | **Rollout** | Behind a flag or experiment, or straight to everyone; who to tell or train; whether a developer must review it or agent review is enough |
60
+ | **Scope** | What is explicitly out, and what is deferred to a later version |
61
+
62
+ Push hardest on **Success**. "Users like it" is not done. Ask what number would make the
63
+ owner call it a win, what number would make them roll it back, and where the number comes
64
+ from.
65
+
66
+ <prd-template>
67
+
68
+ ## Problem Statement
69
+
70
+ The problem the user faces, from the user's perspective: who, how often, today's
71
+ workaround, and its cost.
72
+
73
+ ## Why Now
74
+
75
+ Why this beats the rest of the backlog, and what it displaces.
76
+
77
+ ## Solution
78
+
79
+ The solution, from the user's perspective: the behavior and the main flows. Link the
80
+ reference prototype or demo when one exists.
81
+
82
+ ## User Stories
83
+
84
+ A LONG, numbered list of user stories. Each story uses the format:
85
+
86
+ 1. As an <actor>, I want a <feature>, so that <benefit>
87
+
88
+ <user-story-example>
89
+ 1. As a mobile bank customer, I want to see balance on my accounts, so that I can make better informed decisions about my spending
90
+ </user-story-example>
91
+
92
+ The list is extensive and covers every aspect of the feature, including edge cases and
93
+ error states.
94
+
95
+ ## Success Metrics
96
+
97
+ A numbered list. Each metric states what is measured, the target, how it is measured, and
98
+ when it is evaluated.
99
+
100
+ <success-metric-example>
101
+ 1. Search returns results within 200 ms at p95 for a 10k-record dataset, measured by the load test before launch.
102
+ 2. At least 85% of new users finish onboarding within 3 minutes, measured by the analytics funnel 30 days after launch.
103
+ 3. Weekly active editors: TBD — owner sets the target after two weeks of baseline data.
104
+ </success-metric-example>
105
+
106
+ **Guardrails.** Measurable thresholds that mean turn it off or roll it back.
107
+
108
+ <guardrail-example>
109
+ 1. Support tickets about checkout rise above 5 per week, measured in the help desk.
110
+ </guardrail-example>
111
+
112
+ ## Constraints
113
+
114
+ Limits the solution must respect: data and privacy, safety, performance, cost, platforms,
115
+ and the change load on the people who use it.
116
+
117
+ ## Rollout
118
+
119
+ Flag or experiment versus full launch, who must be told or trained, and the review level:
120
+ developer review required, or low-risk enough for agent review.
121
+
122
+ ## Out of Scope
123
+
124
+ What this PRD does not cover, and what is deferred to a later version.
125
+
126
+ </prd-template>
127
+
128
+ ## Success conditions
129
+
130
+ - The owner confirmed shared understanding before the PRD was written.
131
+ - The PRD has every template section and no implementation detail.
132
+ - Every success metric and guardrail is measurable or `TBD` with its decider.
133
+ - The PRD is published and its link is returned.
134
+
135
+ ## Blocked conditions
136
+
137
+ - The owner cannot state the problem or who has it. Stop after that round; do not write a
138
+ PRD around a guessed problem.