@terreno/agent-plugin 0.0.0-stage → 57.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +32 -0
- package/CHANGELOG.md +2155 -0
- package/LICENSE +21 -0
- package/README.md +57 -2
- package/agents/pre-commit.md +65 -0
- package/agents/ui-verifier.md +93 -0
- package/package.json +32 -4
- package/references/async-review-bots.md +76 -0
- package/references/documentation-contract.md +61 -0
- package/references/execution-state.schema.json +77 -0
- package/references/github-attention-contract.md +165 -0
- package/references/independent-review.md +31 -0
- package/references/lifecycle-contract.md +211 -0
- package/references/loop-engineering.md +125 -0
- package/references/pick-roast-loop.md +112 -0
- package/references/pr-deployments.md +69 -0
- package/references/product-ci.md +164 -0
- package/references/push-ownership.md +91 -0
- package/references/stage-result.schema.json +82 -0
- package/references/subagent-briefing.md +43 -0
- package/references/testing-plan.md +163 -0
- package/references/user-guide.md +171 -0
- package/skills/1-grow/SKILL.md +145 -0
- package/skills/1-grow/references/grilling.md +243 -0
- package/skills/2-pick/SKILL.md +170 -0
- package/skills/2-pick/references/mocking.md +34 -0
- package/skills/2-pick/references/testing.md +43 -0
- package/skills/3-roast/SKILL.md +168 -0
- package/skills/4-brew/SKILL.md +201 -0
- package/skills/5-taste/SKILL.md +311 -0
- package/skills/ai-prompt-governance/SKILL.md +100 -0
- package/skills/attach-pr-media/SKILL.md +89 -0
- package/skills/attach-pr-media/scripts/upload-pr-media.sh +151 -0
- package/skills/backend-test-env/SKILL.md +64 -0
- package/skills/backfill-regression/SKILL.md +101 -0
- package/skills/backfill-user-guide/SKILL.md +96 -0
- package/skills/bootstrap-mcp-server/SKILL.md +244 -0
- package/skills/building-admin-interfaces/SKILL.md +83 -0
- package/skills/building-admin-interfaces/agents/openai.yaml +4 -0
- package/skills/building-admin-interfaces/references/nav-and-shell.md +42 -0
- package/skills/building-admin-interfaces/references/patterns-and-tools.md +73 -0
- package/skills/building-admin-interfaces/references/screens-and-routes.md +50 -0
- package/skills/building-terreno-apps/SKILL.md +280 -0
- package/skills/building-terreno-apps/agents/openai.yaml +4 -0
- package/skills/building-terreno-apps/references/navigation.md +102 -0
- package/skills/building-terreno-apps/references/route-structure.md +91 -0
- package/skills/building-terreno-apps/references/screen-patterns.md +191 -0
- package/skills/debug-syncdb-with-mcp/SKILL.md +75 -0
- package/skills/deploy-gcp/SKILL.md +73 -0
- package/skills/deploy-gcp/references/troubleshooting.md +29 -0
- package/skills/generate-release-announcements/SKILL.md +145 -0
- package/skills/generate-sdk/SKILL.md +156 -0
- package/skills/mongoose-schema-safety/SKILL.md +164 -0
- package/skills/pick-roast-loop/SKILL.md +152 -0
- package/skills/planning-loop/SKILL.md +161 -0
- package/skills/prd/SKILL.md +138 -0
- package/skills/set-up-social-login/SKILL.md +76 -0
- package/skills/store-assets/SKILL.md +221 -0
- package/skills/store-assets/examples/screenshots.yaml +31 -0
- package/skills/store-assets/examples/storeAssets.config.json +44 -0
- package/skills/store-assets/scripts/banner.ts +165 -0
- package/skills/store-assets/scripts/config.ts +255 -0
- package/skills/store-assets/scripts/devClient.ts +635 -0
- package/skills/store-assets/scripts/devices.ts +286 -0
- package/skills/store-assets/scripts/icon.ts +81 -0
- package/skills/store-assets/scripts/maestro/goHome.yaml +21 -0
- package/skills/store-assets/scripts/maestro/login.yaml +27 -0
- package/skills/store-assets/scripts/maestro/openApp.yaml +26 -0
- package/skills/store-assets/scripts/screenshots.ts +848 -0
- package/skills/taste-sweep/SKILL.md +172 -0
- package/skills/terreno-backend-api/SKILL.md +355 -0
- package/skills/terreno-backend-api/agents/openai.yaml +4 -0
- package/skills/terreno-backend-api/references/custom-routes.md +132 -0
- package/skills/terreno-backend-api/references/model-router.md +116 -0
- package/skills/terreno-backend-api/references/server-setup.md +116 -0
- package/skills/terreno-backend-tests/SKILL.md +176 -0
- package/skills/terreno-data-fetching/SKILL.md +276 -0
- package/skills/terreno-data-fetching/agents/openai.yaml +4 -0
- package/skills/terreno-data-fetching/references/auth-and-tokens.md +93 -0
- package/skills/terreno-data-fetching/references/realtime.md +45 -0
- package/skills/terreno-data-fetching/references/sdk-customization.md +84 -0
- package/skills/terreno-frontend-tests/SKILL.md +190 -0
- package/skills/terreno-mobile-tests/SKILL.md +127 -0
- package/skills/terreno-test-setup/SKILL.md +81 -0
- package/skills/terreno-test-setup/references/backend.md +131 -0
- package/skills/terreno-test-setup/references/frontend.md +169 -0
- package/skills/terreno-test-setup/references/mobile.md +134 -0
- package/skills/terreno-ui/SKILL.md +252 -0
- package/skills/terreno-ui/agents/openai.yaml +4 -0
- package/skills/terreno-ui/references/data-display.md +85 -0
- package/skills/terreno-ui/references/feedback.md +122 -0
- package/skills/terreno-ui/references/forms.md +119 -0
- package/skills/terreno-ui/references/layout.md +124 -0
- package/skills/terreno-ui/references/theming.md +87 -0
- package/skills/update-docs/SKILL.md +82 -0
- package/skills/upgrading-terreno/SKILL.md +86 -0
- package/skills/upgrading-terreno/references/ordering.md +40 -0
- 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.
|