@vegastack/skills 0.10.0 → 0.11.1

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 (58) hide show
  1. package/README.md +5 -0
  2. package/package.json +1 -1
  3. package/skill/dev-architect/SKILL.md +7 -4
  4. package/skill/dev-architect/references/conventions.md +93 -0
  5. package/skill/dev-chronicle/SKILL.md +45 -0
  6. package/skill/dev-chronicle/agents/openai.yaml +4 -0
  7. package/skill/dev-chronicle/references/conventions.md +93 -0
  8. package/skill/dev-chronicle/refresh/REFRESH.md +3 -0
  9. package/skill/dev-chronicle/refresh/sources.json +6 -0
  10. package/skill/dev-debug/SKILL.md +43 -0
  11. package/skill/dev-debug/agents/openai.yaml +4 -0
  12. package/skill/dev-debug/references/conventions.md +93 -0
  13. package/skill/dev-debug/references/loop-ladder.md +20 -0
  14. package/skill/dev-debug/refresh/REFRESH.md +3 -0
  15. package/skill/dev-debug/refresh/sources.json +6 -0
  16. package/skill/dev-implement/SKILL.md +41 -36
  17. package/skill/dev-implement/references/conventions.md +93 -0
  18. package/skill/dev-implement/references/ledger-and-resume.md +27 -0
  19. package/skill/dev-implement/scripts/evidence-check.mjs +57 -0
  20. package/skill/dev-implement/scripts/lib/gh.mjs +93 -0
  21. package/skill/dev-implement/scripts/preflight.mjs +101 -0
  22. package/skill/dev-intake/SKILL.md +39 -33
  23. package/skill/dev-intake/references/brief-template.md +27 -12
  24. package/skill/dev-intake/references/conventions.md +93 -0
  25. package/skill/dev-intake/scripts/brief-lint.mjs +87 -0
  26. package/skill/dev-plan/SKILL.md +53 -0
  27. package/skill/dev-plan/agents/openai.yaml +4 -0
  28. package/skill/dev-plan/references/conventions.md +93 -0
  29. package/skill/dev-plan/references/plan-format.md +54 -0
  30. package/skill/dev-plan/refresh/REFRESH.md +3 -0
  31. package/skill/dev-plan/refresh/sources.json +6 -0
  32. package/skill/dev-plan/scripts/plan-lint.mjs +86 -0
  33. package/skill/dev-review/SKILL.md +69 -0
  34. package/skill/dev-review/agents/openai.yaml +4 -0
  35. package/skill/dev-review/assets/review-known-patterns.md.template +30 -0
  36. package/skill/dev-review/references/conventions.md +93 -0
  37. package/skill/dev-review/references/cross-agent.md +39 -0
  38. package/skill/dev-review/references/dispatch-prompts.md +104 -0
  39. package/skill/dev-review/references/security-axis.md +33 -0
  40. package/skill/dev-review/refresh/REFRESH.md +3 -0
  41. package/skill/dev-review/refresh/sources.json +6 -0
  42. package/skill/dev-setup/SKILL.md +7 -5
  43. package/skill/dev-setup/assets/agents-section.md.template +2 -2
  44. package/skill/dev-setup/assets/dev-profile.md.template +4 -3
  45. package/skill/dev-setup/references/conventions.md +93 -0
  46. package/skill/dev-ship/SKILL.md +14 -7
  47. package/skill/dev-ship/references/conventions.md +93 -0
  48. package/skill/dev-ship/references/runbook.md +1 -1
  49. package/skill/dev-ship/scripts/ship-gate.mjs +213 -0
  50. package/skill/dev-status/SKILL.md +45 -0
  51. package/skill/dev-status/agents/openai.yaml +4 -0
  52. package/skill/dev-status/references/conventions.md +93 -0
  53. package/skill/dev-status/refresh/REFRESH.md +3 -0
  54. package/skill/dev-status/refresh/sources.json +6 -0
  55. package/skill/dev-status/scripts/status.mjs +152 -0
  56. package/skill/skillify/SKILL.md +1 -1
  57. package/skill/skillify/references/eval-playbook.md +6 -0
  58. package/skill-integrity.json +78 -14
@@ -1,62 +1,68 @@
1
1
  ---
2
2
  name: dev-intake
3
- description: Turn ideas, brainstorms, feature requests, or SOW documents into GitHub issues an agent can implement without further questions. Use when asked to "turn this into issues", "create tasks from this SOW", "write up an issue for" a feature or bug, "plan this as issues", "slice this epic", or when the user gives approval on a drafted issue and it needs recording. Produces complete inline build briefs with labels, milestones, and blocker links. Not for implementing issues (dev-implement), creating PRs or merging (dev-ship), or project bootstrap (dev-setup).
3
+ description: Turn ideas, brainstorms, feature requests, bug reports, or SOW documents into GitHub issues an agent can act on without further questions. Use when asked to "turn this into issues", "create tasks from this SOW", "write up an issue for" a feature or bug, "users report X — make an issue", "plan this as issues", "slice this epic", or when the user gives approval on a drafted issue and it needs recording. Not for writing the implementation plan of an approved issue (dev-plan), implementing issues (dev-implement), creating PRs or merging (dev-ship), or project bootstrap (dev-setup).
4
4
  ---
5
5
 
6
6
  # dev-intake
7
7
 
8
- Requirements come in as the user's brainstorm, feature thought, or SOW; issues go out complete enough that a fresh agent needs nothing but the URL. Every question gets asked **here** — once implementation starts, dark mode means no questions, so an under-specified issue becomes either an interruption or a guess. This skill exists to make both impossible.
8
+ Requirements come in as the operator's brainstorm, feature thought, bug report, or SOW; issues go out complete enough that a fresh agent needs nothing but the URL. Every question gets asked **here** — once implementation starts, dark mode means no questions, so an under-specified issue becomes either an interruption or a guess. Artifact formats (markers, operator identity, labels, revisions) follow the `dev-setup` skill's `references/conventions.md`.
9
9
 
10
- Nearest neighbor: `dev-implement` consumes what this produces — intake writes and gets approval, implement builds. If `.vegastack/dev.md` is missing, run `dev-setup` first, then continue here.
10
+ Nearest neighbors: `dev-plan` owns the how once a brief is approved — intake owns the what/why and the approval mechanics; `dev-implement` builds. If `.vegastack/dev.md` is missing → run `dev-setup` first, then continue.
11
11
 
12
12
  ## Ground before you ask
13
13
 
14
- Finding facts is your job, never the user's — and a brief built on unverified facts is a confident mistake waiting for dark mode. The source can be one sentence in chat; thinner material just means the grounding and interview carry more weight. Before the first question:
14
+ Finding facts is your job, never the operator's — a brief built on unverified facts is a confident mistake waiting for dark mode. Before the first question:
15
15
 
16
- - **Read the touched code.** Open the actual paths the feature would change: current behavior, existing patterns to reuse, where the new work plugs in. The brief cites these real paths later — a brief naming no files is a sign this step was skipped.
17
- - **Verify dependencies.** Any library, service, or API capability the approach leans on gets checked against current official docs (docs tools or web search), noted with the date. Stack, schema, auth, and infra approach choices route through `dev-architect` — its verify-before-you-recommend protocol governs the check (pinned facts first, live docs on a miss or a fact older than 60 days); skip lookups for long-stable basics — judgment, not ritual.
18
- - **Cross-check the request** against product docs and current behavior. A contradiction is pushback, never a silent resolution: "you asked for X; the code/docs currently do Y — which wins?" Push back on cost the same way: when a simpler version covers most of the need, name it.
19
- - **Triage every unknown** into exactly three bins: *findable* → find it now, yourself; *only-the-user-knows* → ask, with a recommendation; *only-running-code-can-tell* → flag it as a spike that becomes the issue's first step. Guessing is not a bin.
16
+ - **Read the touched code.** Open the actual paths the work would change: current behavior, patterns to reuse, where it plugs in. The brief cites these real paths later — a brief naming no files is a sign this step was skipped.
17
+ - **Verify dependencies.** Any library, service, or API capability the approach leans on gets checked against current official docs, noted with the date. Stack, schema, auth, and infra choices route through `dev-architect` — its verify protocol governs the check.
18
+ - **Cross-check the request** against product docs and current behavior. A contradiction is pushback, never a silent resolution: "you asked for X; the code currently does Y — which wins?" Push back on cost the same way: when a simpler version covers most of the need, name it.
19
+ - **Triage every unknown** into exactly three bins: *findable* → find it now, yourself; *only-the-operator-knows* → ask, with a recommendation; *only-running-code-can-tell* → a `research` issue or the issue's first spike step. Guessing is not a bin.
20
20
 
21
- ## The interview
21
+ ## Scope the work — say it out loud
22
+
23
+ Every issue gets exactly one scope call, announced with its reason, applied as a label, and recorded in the brief's `**Scope:**` line so the reasoning survives the conversation. The operator can override it:
22
24
 
23
- Ask in rounds using your harness's question tool (AskUserQuestion in Claude Code, `request_user_input` in Codex where the mode allows; no tool available → draft with recommended answers marked `TODO confirm` and say so). Each round covers the current frontier: every open decision that does not depend on another answer.
25
+ - **`research`** — a question to answer, not code to keep. The brief is the question plus what "answered" looks like.
26
+ - **`quick-build`** — the objective test (conventions' wording): *a small change AND the flow being changed already exists in the repo to read*. Missing either half — no existing flow, or not actually small — means it is not quick-build; familiarity with the kind of app doesn't count.
27
+ - **`full-plan`** — big or new ground: a new subsystem, a restructuring, a brand-new flow.
24
28
 
25
- - Number the questions. Give each a **recommended answer with a one-line reason**, so the user can reply "all recommended" or override by number.
26
- - Stop asking when the bar is met: *a fresh agent could implement each issue without asking anything.* Test every brief against that sentence before calling it done.
27
- - Do not re-ask what the material or an earlier round already settled.
29
+ In doubt between two classes, take the heavier one. Re-classification after this point belongs to `dev-plan`'s one-way ratchet — never silently downgrade.
28
30
 
29
- ## The angles, in order
31
+ ## The interview
30
32
 
31
- Work the design the way a joint product-and-tech review would; each round's answers feed the next:
33
+ Ask in rounds with your harness's question tool (no tool available → documented defaults marked `TODO confirm`, and say so). Each round covers the current frontier: every open decision that doesn't depend on another answer. Number the questions; give each a **recommended answer with a one-line reason** so the operator can reply "all recommended"; never re-ask what the material or an earlier round already settled. A vague or self-contradicting answer gets pushback with concrete options — simple words, a mermaid or ASCII sketch when a picture beats prose — never silent absorption. Stop when the bar is met: *a fresh agent could act on each issue without asking anything.*
32
34
 
33
- 1. **Product** — who this is for, the observable outcome, what's in and out of scope now, how it splits into slices or phases, priority.
34
- 2. **Behavior** — primary and alternate flows, rules, permissions, validations, edge and failure cases; for UI, the states, components, and copy.
35
- 3. **Technical** — only the choices that are genuinely the user's: approach trade-offs, data and interface implications, integrations, migration; recommend one and say why — checking `dev-architect` first so a brief never proposes a recorded rejection or a moving part without its trigger. When the project versions releases (dev.md `changelog:` knob), settle the intended version impact (patch/minor/major) here — the brief records it and dev-implement's changelog entry starts from it. Routine implementation stays the implementer's.
36
- 4. **Quality and risk** — what proves it works (test cases, acceptance), what earns the `risky` label, what should stop a dark run beyond the standing stop-list.
35
+ The angles, in order — product (who, observable outcome, in/out of scope, slices, priority) → behavior (flows, rules, permissions, edge and failure cases; UI states and copy) → technical (only choices genuinely the operator's, each with a recommendation, checked against `dev-architect`; settle the version impact where the project versions releases) → quality and risk (what proves it works, what earns `risky`, what stops a dark run). Deep approach trade-offs beyond the operator's choices belong to `dev-plan`, not this interview.
37
36
 
38
- These are the brief template's sections in interview form — a question exists only where reading the material, the codebase, and sensible defaults cannot fill a section.
37
+ **Bug variant** (`fix:` issues): reproduction steps — or the artifacts needed to obtain them (logs, HAR, recording) — are a required brief section, and the brief names `dev-debug` as the implement path. A bug that can't be reproduced yet becomes a `research` issue first.
39
38
 
40
- ## Slicing
39
+ ## Slicing and hierarchy
41
40
 
42
- - One issue = one outcome that fits one agent session, sliced vertically (a thin working path through the stack beats a layer at a time).
43
- - Blockers use native issue dependencies (blocked-by); phases use milestones; hierarchy uses parent/sub-issues. Labels never duplicate these.
44
- - A large feature gets a parent issue holding the map and child issues holding the work. **Only child issues ever get `ready`** — a parent brief is context, not an executable task, and an agent must never pick it up whole.
45
- - Deliberately deferred work ("someday, not now") lives in the parent's out-of-scope section, not as its own issue — icebox issues clutter the tracker. Create a tracking issue for it only when the user asks.
41
+ - One issue = one outcome that fits one agent session, sliced vertically. Blockers use native dependencies; phases use milestones; parents use native sub-issues.
42
+ - Deliberately deferred work ("someday, not now") lives in the parent's out-of-scope section, never as its own issue — icebox issues clutter the tracker; a tracking issue exists only on the operator's ask.
43
+ - **Epics:** a multi-deliverable feature gets a parent whose body is a map, never a task — `Destination` (one or two lines every session orients to) · `Decisions so far` (one-line gists linking closed children) · `Not clear yet` (in-scope questions you cannot yet state precisely — the test is whether the question can be phrased sharply now, not answered now; don't pre-slice fog) · `Out of scope` (the tempting adjacent work, named). A mermaid overview when it helps. Each child is classified independently. **Only children ever get `ready`.**
44
+ - Titles carry the type prefix (dev.md `branch:` type list + `research:`) and the native issue type where the org has them — issue, branch, and PR always agree.
46
45
 
47
46
  ## The brief
48
47
 
49
- Every issue body follows [brief-template](references/brief-template.md): Outcome · Out of scope · Rules and edge cases · UI states (when there is UI) · Approach and touch points · Tests and acceptance · Risks and stop conditions · Assumptions. Write the sections that apply and delete the ones that don't — an empty "N/A" section is noise, not diligence. Details live inline in the issue; links to docs are supporting material, never a substitute for the brief. Evidence over confidence: touch points name real paths, dependency claims carry their check date, and anything material the grounding could not verify goes in **Assumptions — confirm or correct**, never asserted as fact.
48
+ The issue body follows [brief-template](references/brief-template.md), marker line included. Inline over linked; concrete over abstract; evidence over confidence — touch points name real paths, dependency claims carry their check date, and anything unverifiable goes to **Assumptions — confirm or correct**, never asserted. Tests-and-acceptance names the **seams** — the public boundaries tests will live at — because dark mode can't ask later.
49
+
50
+ **Quick-build issues get their plan now:** after the brief has consensus, invoke `dev-plan`'s inline mode in this same conversation and post brief (description) + plan (comment) together — the operator's single approval covers both.
51
+
52
+ Before posting any brief, run `node <path-to-this-skill>/scripts/brief-lint.mjs --file <draft> --scope <class> --json` (add `--fix` for fix:-type briefs — it requires the Reproduction section) — structure gaps block (exit 2), quality smells only warn; fix blocks before the operator ever sees the draft. Inline plans additionally pass `dev-plan`'s plan-lint.
50
53
 
51
54
  ## Labels and approval
52
55
 
53
- - A new issue starts at `needs-operator`. Add `risky` when it touches security, money, user data, or production. (Label names come from dev.md's `labels:` knob; the defaults are used throughout this skill family's prose.)
54
- - Approval is only the user's explicit words — "approved", "go ahead", clearly tied to this issue, in chat or on the issue. Labels, silence, or the passage of time never create approval.
55
- - Record it once: comment `Approved by <user> on <date>: "<their words>"`, then swap `needs-operator` → `ready`. That comment is what dev-implement's preflight looks for.
56
- - An issue with an unconfirmed entry in its Assumptions section cannot go `ready` — the recorded approval covers the ledger the user saw, so resolve every entry (confirmed, corrected, or moved to a spike) first.
57
- - An issue that settles a directional decision — one that passes the Decisions test in `.vegastack/dev.md` — records it as one comment starting `Decision:`, in the register's line format; dev-ship appends it at merge after naming it in the merge confirmation. A decision that stands regardless of the issue's fate may go into the register immediately on the user's explicit yes in the same conversation — note "recorded" on the comment so dev-ship doesn't append it twice. Choices that fail the test are brief content, never register lines.
58
- - The user edits or corrects a draft → apply, and summarize what changed since they last read it.
56
+ - A new issue starts at `needs-operator`, plus its scope label; add `risky` when it touches security, money, user data, or production. (Names come from dev.md's `labels:` knob.)
57
+ - Approval is only the operator's explicit words, clearly tied to the issue. Labels, silence, or time never create approval.
58
+ - Record it as one approval marker comment per conventions — `scope=brief`, or `scope=brief+plan` when the inline plan was posted with it — quoting the operator's words in the operator (username) format. That comment is what preflight verifies.
59
+ - Then flip the state: `research` and `quick-build` → `ready`; `full-plan` → `needs-plan` (dev-plan takes it from there).
60
+ - An issue with an unresolved Assumptions entry cannot leave `needs-operator` — resolve every entry (confirmed, corrected, or moved to a spike) first; the section is deleted once resolved.
61
+ - A directional decision this work settles — one passing the Decisions test in dev.md — is proposed as one register line on the operator's yes; `dev-ship` records at merge.
62
+ - The operator edits a draft → apply, and summarize what changed since they last read it.
59
63
 
60
64
  ## After approval
61
65
 
62
- An approved issue that later needs a material change flips back to `needs-operator` with one comment naming what changed; the new approval is recorded the same way. Small wording fixes that change no behavior don't reopen anything.
66
+ An approved issue that later needs a material change flips back to `needs-operator` with one comment naming what changed; the new approval is recorded the same way, and the brief's revision marker bumps. Small wording fixes that change no behavior don't reopen anything.
67
+
68
+ End every run with the plain-language summary: what was created or changed, the scope calls made and why, and exactly what awaits the operator's word.
@@ -1,13 +1,21 @@
1
1
  # Issue brief template
2
2
 
3
- The issue body a `ready` issue must have. Write the sections that apply, delete the rest. The test for every section: would a fresh agent have to guess or ask without it?
3
+ The issue body a workable issue must have. Write the sections that apply, delete the rest. The test for every section: would a fresh agent have to guess or ask without it?
4
4
 
5
5
  ```markdown
6
+ <!-- vsk:v1 type=brief rev=1 scope=research|quick-build|full-plan -->
7
+ **Scope:** research | quick-build | full-plan — the announced reason for the call, one line.
8
+
6
9
  ## Outcome
7
10
 
8
11
  What exists when this is done, in observable terms — what the user can do, what the
9
12
  system produces. One paragraph.
10
13
 
14
+ Research issues replace Outcome and the build sections with two headings brief-lint
15
+ expects verbatim in spirit: `## The question` (what this issue resolves) and
16
+ `## What answered looks like` (the evidence that closes it). Risks/stop conditions
17
+ and Assumptions still apply.
18
+
11
19
  ## Out of scope
12
20
 
13
21
  The nearby things this issue deliberately does NOT do. This is what stops scope creep
@@ -18,6 +26,12 @@ in dark mode — name the tempting adjacent work.
18
26
  The behavior that isn't obvious: validations, permissions, limits, empty/error/concurrent
19
27
  cases, what happens on failure. Bullet list, one behavior per line.
20
28
 
29
+ ## Reproduction <!-- fix: issues only -->
30
+
31
+ The exact steps (or attached artifacts — logs, HAR, recording) that demonstrate the
32
+ bug today, and the observed vs expected behavior. A bug without this is a `research`
33
+ issue, not a fix. The implement path is dev-debug.
34
+
21
35
  ## UI states <!-- only when there is UI -->
22
36
 
23
37
  Loading, empty, error, success, disabled. Which design-system components. Copy for
@@ -26,19 +40,18 @@ user-facing text. Responsive and keyboard behavior when it matters.
26
40
  ## Approach and touch points
27
41
 
28
42
  The chosen technical approach in a few lines: which parts of the codebase change,
29
- new/changed interfaces or schemas, data migrations. Routine choices (file names,
30
- helpers, fixtures) stay the implementer's — don't specify them.
31
- Name the docs and changelog surfaces this change must update (README section, user
32
- docs, the changelog entry's gist).
43
+ new/changed interfaces or schemas, data migrations. Routine choices stay the
44
+ implementer's — don't specify them. Name the docs and changelog surfaces this change
45
+ must update. Task-level detail belongs to the plan (dev-plan), not here.
33
46
  **Version impact:** patch | minor | major, one-line reason — only when the project
34
- versions releases (dev.md `changelog:` knob); dev-implement's changelog entry or
35
- changeset starts from this line.
47
+ versions releases (dev.md `changelog:` knob).
36
48
 
37
49
  ## Tests and acceptance
38
50
 
39
51
  What proves it works: the cases tests must cover (success, boundary, failure,
40
- authorization where relevant) and the commands to run. Acceptance = the Outcome plus
41
- these passing.
52
+ authorization where relevant), the commands to run, and the **seams** — the public
53
+ boundaries tests live at (dark mode can't negotiate seams later; they're settled
54
+ here). Acceptance = the Outcome plus these passing.
42
55
 
43
56
  ## Risks and stop conditions
44
57
 
@@ -48,9 +61,10 @@ through — beyond the standing stop-list in .vegastack/dev.md.
48
61
  ## Assumptions — confirm or correct
49
62
 
50
63
  Anything material the grounding investigation could not verify, one per line, each
51
- awaiting the user's confirm/correct. The issue cannot go `ready` while one is
52
- unconfirmed. Verified facts never appear here — they live in their section with
53
- their evidence. Delete the section once every entry is resolved.
64
+ awaiting the operator's confirm/correct. The issue cannot leave needs-operator while
65
+ one is unconfirmed. Verified facts never appear here — they live in their section
66
+ with their evidence. Delete the whole section once every entry is resolved (its
67
+ presence alone blocks preflight).
54
68
  ```
55
69
 
56
70
  ## Writing rules
@@ -59,4 +73,5 @@ their evidence. Delete the section once every entry is resolved.
59
73
  - Concrete over abstract: "rejects amounts over 10,000 with error E402" beats "validates input".
60
74
  - Evidence over confidence: touch points name real file paths; a dependency capability claim carries the doc check and its date; what couldn't be verified goes to Assumptions, never stated as fact.
61
75
  - The brief binds the agent, so ambiguity is a bug in the brief — if two readings exist, the interview wasn't done.
76
+ - Post-approval edits follow the revision-marker rule in dev-setup's `references/conventions.md` (heading `(v2)`, marker `rev=2`, a `Revisions:` line).
62
77
  - A `Decision:` comment exists only for a choice that passes the Decisions test in `.vegastack/dev.md` — feature requests and implementation details never qualify; they are brief content, not register lines.
@@ -0,0 +1,93 @@
1
+ # Workflow conventions
2
+
3
+ The single spec for the artifacts every dev-family skill reads and writes. One home per rule: skills cite this file, never restate it. Everything here is harness-neutral.
4
+
5
+ ## Comment metadata markers
6
+
7
+ Every workflow-generated issue comment opens with an invisible HTML marker followed by a human heading:
8
+
9
+ ```markdown
10
+ <!-- vsk:v1 type=<type> rev=<n> [key=value ...] -->
11
+ ## <Human title> (v<n>)
12
+ ```
13
+
14
+ | type | required keys | instances |
15
+ |---|---|---|
16
+ | `approval` | `scope=<brief\|brief+plan\|plan>` | one per approval event |
17
+ | `plan` | `rev` | one, edited in place |
18
+ | `ledger` | `branch` | one, edited in place |
19
+ | `evidence` | `rev branch sha` | one, edited in place |
20
+ | `review` | `round sha agent=<claude\|codex> verdict=<clean\|needs-fixes>` | one per review cycle, rounds appended inside |
21
+ | `decision` | — | one per decision proposal |
22
+ | `handback` | — | one per stop event |
23
+
24
+ `rev=<n>` and the matching `(v<n>)` heading suffix appear only on revisable artifacts — the brief (issue description), `plan`, and `evidence` — starting at `rev=1`/`(v1)`. Single-event comments (`approval`, `decision`, `handback`) and the `ledger` carry neither. Scripts and agents locate comments strictly by marker, never by heading text. A comment without its marker does not count as the artifact — there is no legacy fallback.
25
+
26
+ ## Operator identity
27
+
28
+ Every human reference in every artifact — approvals, revisions, decisions, changelog attributions, review adjudications — is written `operator (<github-username>)`:
29
+
30
+ - Approval: `Approved by operator (<username>) on DD-MM-YYYY: "<their words>"`
31
+ - Register line: `- DD-MM-YYYY operator (<username>) — <decision>`
32
+
33
+ ## Revision markers
34
+
35
+ Any artifact edited after its first approval: the heading gains `(v2)`, the marker gains `rev=2`, and a `Revisions:` line is appended at the bottom — `v2 — DD-MM-YYYY: <what changed>, per operator (<username>) correction`. Existing revision lines are never rewritten.
36
+
37
+ ## Scope classes
38
+
39
+ Set at intake, applied as a label, announced with its reason (operator can override):
40
+
41
+ - **`research`** — a question to answer; throwaway code allowed, never merged. No branch/PR/changelog; findings + recommendation are the evidence comment.
42
+ - **`quick-build`** — small change and the flow being changed already exists in the repo to read. Brief (description) + plan (comment) are drafted in the same conversation; **one approval covers both**; then straight to `ready`.
43
+ - **`full-plan`** — big or new ground. Brief approval → `needs-plan` → a separate, fresh-grounded planning session posts the plan → `needs-operator` → "plan approved" → `ready`. Multi-deliverable work becomes an epic; each sub-issue is classified independently.
44
+
45
+ Scope calls are revisited through the one-way ratchet, whose rules and mechanics live in the `dev-plan` skill — the one home for upgrade/downgrade behavior.
46
+
47
+ ## Labels
48
+
49
+ State — exactly one per issue (creation colors live in dev-setup's labels row, their one home):
50
+
51
+ | label | meaning |
52
+ |---|---|
53
+ | `needs-operator` | waiting on the operator: a question, a brief or plan to approve, a proposal |
54
+ | `needs-plan` | brief approved; waiting for the planning stage (full-plan only) |
55
+ | `ready` | fully approved — an agent may start |
56
+ | `working` | claimed, in progress; the ledger comment shows live progress |
57
+ | `for-operator` | done — evidence posted, awaiting operator review |
58
+
59
+ Modifiers (may coexist with the state label): `risky` · scope `research` / `quick-build` / `full-plan` · `epic` (map parents, only where the org has no native Epic issue type).
60
+
61
+ ## Titles, types, hierarchy
62
+
63
+ - **Title prefixes** on issues, branches, and PRs identically: dev.md's `branch:` knob type list (that knob stays the list's one home) plus `research:` for research issues. PR title = issue title.
64
+ - **Native issue types** where the org defines them: Feature (feat) · Bug (fix) · Task (docs/chore/refactor/research) · Epic for parents (label fallback otherwise).
65
+ - **Hierarchy:** epic parent = map only (Destination · Decisions so far as one-line gists · Not clear yet · Out of scope), children attached as native sub-issues; issues = the unit of work (brief in description, own approvals/branch/PR/evidence); tasks = checkboxes **in the plan comment only**. Blockers use native issue dependencies; phases use milestones. Only issues — never epics — get `ready`. GitHub caps issue bodies and comments at ~65,536 characters; what a plan nearing that cap means is the `dev-plan` ratchet's call.
66
+
67
+ ## The ledger
68
+
69
+ Maintained by the implement session as one comment, edited in place:
70
+
71
+ ```markdown
72
+ <!-- vsk:v1 type=ledger branch=<branch> -->
73
+ ## Ledger — <branch>
74
+ - Task <N>: complete (commits <base7>..<head7>[, review clean | K parked])
75
+ - Task <N>: fix round <R>/3 (<X> addressed, <Y> open — <one-liners>; commits <a>..<b>)
76
+ - Ruling: <what> — <why> — cost if wrong: <cost>
77
+ - Task <N>: parked — <finding> — Ruling: <why the code stands>
78
+ - Deferred minor: <one-liner>
79
+ ```
80
+
81
+ **Resume protocol:** a fresh, compacted, or (operator-handed) takeover session reads, in order: the brief → the plan comment → the ledger → `git log` on the branch — **nothing else**. Tasks with a `complete` line are DONE, never re-executed; a task whose last line is a fix round resumes at the next round. After compaction, trust the ledger and `git log` over recollection. Every `Ruling:` line surfaces in the evidence comment — a ruling that dies with the session was a decision made in secret.
82
+
83
+ ## `.vegastack/.tmp/` workspace
84
+
85
+ All transitory artifacts — subagent reports, review packages, plan drafts, extracted diffs — live at `.vegastack/.tmp/<issue-number>-<title-slug>/` (pre-issue intake drafts, which have no number yet: `.vegastack/.tmp/intake-<slug>/`), kept out of git by a self-ignoring `.gitignore` (`printf '*\n' > .vegastack/.tmp/.gitignore`, created on first use). Subagents write full reports to files there and return only short status — a dead subagent's findings survive on disk, and the primary session never holds full reports in context. The workspace lives in the working tree (never under `.git/`, which harnesses protect from writes).
86
+
87
+ ## Verification gate
88
+
89
+ Before claiming any status: **IDENTIFY** the command that proves the claim → **RUN** it fresh and complete → **READ** the full output and exit code → only then claim, with the evidence. "Should pass", a previous run, or a subagent's say-so are never evidence. Guard scripts follow the same doctrine: machine-verifiable facts **block** (exit 2 with the reason); regex or judgment heuristics only **warn** — no AI inference inside guards, and an unverifiable state fails closed.
90
+
91
+ ## Plain-language collaboration
92
+
93
+ Every skill run ends with a simple-language summary: what happened, which paths were taken — cross-agent invocations announced at trigger time AND summarized at the end — and what is worth the operator double-checking. Use mermaid or ASCII diagrams in issues wherever a picture beats prose. A vague or self-contradicting operator answer gets pushback with concrete options, never silent absorption.
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env node
2
+ // dev-intake guard: deterministic checks on a drafted brief before posting.
3
+ // Missing structure blocks; quality smells only warn (heuristics never block).
4
+ // Inline quick-build plans are linted separately by dev-plan's plan-lint — the
5
+ // banned-placeholder list lives there, its single home.
6
+ //
7
+ // Exit codes: 0 pass · 1 pass-with-warnings · 2 blocked (reasons printed).
8
+ // Usage: node brief-lint.mjs --file <brief.md> --scope <research|quick-build|full-plan> --json
9
+ import { readFileSync } from 'node:fs';
10
+ import { resolve } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+
13
+ const REQUIRED_HEADINGS = {
14
+ research: [/^##\s+.*question/im, /^##\s+.*answered/im],
15
+ 'quick-build': [/^##\s+Outcome\b/m, /^##\s+Tests and acceptance\b/m, /^##\s+Approach/m],
16
+ 'full-plan': [/^##\s+Outcome\b/m, /^##\s+Out of scope\b/m, /^##\s+Tests and acceptance\b/m, /^##\s+Approach/m],
17
+ };
18
+
19
+ const VAGUE_SMELLS = [
20
+ /\bworks (properly|correctly|as expected)\b/i,
21
+ /\buser[- ]friendly\b/i,
22
+ /\brobust(ly)?\b/i,
23
+ /\betc\.?\b/i,
24
+ ];
25
+
26
+ export function lintBrief(text, scope, { fix = false } = {}) {
27
+ const blocks = [];
28
+ const warns = [];
29
+
30
+ if (!REQUIRED_HEADINGS[scope]) {
31
+ return { blocks: [`unknown scope class "${scope}" (research | quick-build | full-plan)`], warns };
32
+ }
33
+ if (!/<!--\s*vsk:v1\s+type=brief\b/.test(text)) blocks.push('missing brief marker (<!-- vsk:v1 type=brief rev=n scope=... -->)');
34
+ if (scope !== 'research' && !/^\*\*Scope:\*\*/m.test(text)) {
35
+ blocks.push('missing the **Scope:** line — the announced reason must survive the conversation');
36
+ }
37
+ if (fix && !/^##\s+Reproduction\b/m.test(text)) {
38
+ blocks.push('fix-type brief without a ## Reproduction section — an unreproducible bug is research first');
39
+ }
40
+
41
+ for (const heading of REQUIRED_HEADINGS[scope]) {
42
+ if (!heading.test(text)) blocks.push(`missing required section for ${scope}: ${heading.source}`);
43
+ }
44
+
45
+ if (scope !== 'research') {
46
+ const approach = text.split(/^(?=##\s)/m).find((chunk) => /^##\s+Approach/.test(chunk));
47
+ if (approach && !/`[^`]*[/.][^`]*`/.test(approach)) {
48
+ blocks.push('Approach and touch points names no real backticked paths — grounding was skipped or unrecorded');
49
+ }
50
+ }
51
+
52
+ for (const smell of VAGUE_SMELLS) {
53
+ const hit = smell.exec(text);
54
+ if (hit) warns.push(`vague wording: "${hit[0]}" — name the observable behavior instead`);
55
+ }
56
+
57
+ return { blocks, warns };
58
+ }
59
+
60
+ const invokedDirectly = process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url);
61
+ if (invokedDirectly) {
62
+ const argv = process.argv.slice(2);
63
+ const json = argv.includes('--json');
64
+ const get = (flag) => { const i = argv.indexOf(flag); return i === -1 ? undefined : argv[i + 1]; };
65
+ let outcome;
66
+ const file = get('--file');
67
+ const scope = get('--scope');
68
+ if (!file || !scope) {
69
+ outcome = { blocks: ['usage: brief-lint.mjs --file <brief.md> --scope <class> [--fix] [--json]'], warns: [] };
70
+ } else {
71
+ try {
72
+ outcome = lintBrief(readFileSync(file, 'utf8'), scope, { fix: argv.includes('--fix') });
73
+ } catch (error) {
74
+ outcome = { blocks: [`cannot read brief: ${error.message}`], warns: [] };
75
+ }
76
+ }
77
+ const ok = outcome.blocks.length === 0;
78
+ const exitCode = ok ? (outcome.warns.length ? 1 : 0) : 2;
79
+ if (json) {
80
+ console.log(JSON.stringify({ guard: 'brief-lint', ok, ...outcome }, null, 2));
81
+ } else {
82
+ console.log(`brief-lint: ${ok ? (outcome.warns.length ? 'pass with warnings' : 'pass') : 'BLOCKED'}`);
83
+ for (const b of outcome.blocks) console.log(` block: ${b}`);
84
+ for (const w of outcome.warns) console.log(` warn: ${w}`);
85
+ }
86
+ process.exit(exitCode);
87
+ }
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: dev-plan
3
+ description: Write the implementation plan for an approved issue before any code exists. Use when asked to "plan issue 12", "write the plan for" a feature or issue, "plan this before building", when picking up an issue labeled needs-plan, when an approved brief needs its technical approach worked out, or when dev-intake requests the inline plan for a quick-build issue. Not for writing or approving the brief itself (dev-intake), not for executing an approved plan (dev-implement), not for architecture stack advice (dev-architect — this skill consults it while planning).
4
+ ---
5
+
6
+ # dev-plan
7
+
8
+ The planning stage: an approved brief goes in, an operator-approved plan comes out, and only then does code exist. Plans are written against the repo **as it is now** — a separate session from intake for `full-plan` issues, because code drifts between brief approval and build. Formats follow the `dev-setup` skill's `references/conventions.md` (cited by name — read it wherever dev-setup is installed).
9
+
10
+ Nearest neighbors: `dev-intake` owns the brief and its approval mechanics — this skill owns the how; `dev-implement` executes what this produces, task by task. If `.vegastack/dev.md` is missing → run `dev-setup` first.
11
+
12
+ ## Every run
13
+
14
+ 1. Read `.vegastack/dev.md` and the issue: brief (description), recorded brief approval (`type=approval` marker), scope label. Full-plan issues arrive labeled `needs-plan`; anything else at this door is either intake's inline request (below) or a misroute — say so.
15
+ 2. **Re-ground.** Open the brief's touch points in the current code; verify the flow, names, and shapes the plan will build on. A brief claim that no longer matches reality goes back to the operator (`handback` comment, `needs-operator`) — never plan on top of drift.
16
+ 3. Stack-bearing choices (schema, hosting, services, jobs, auth) check `dev-architect` — its verify protocol governs platform claims, and no plan re-proposes a recorded rejection.
17
+
18
+ ## The questionnaire
19
+
20
+ Numbered rounds over the full frontier (every open question whose prerequisites are settled), each question carrying a recommended answer so the operator can reply "all recommended":
21
+
22
+ 1. **Approaches** — 2–3 candidates with the trade-off that matters and one recommendation. Never a single option.
23
+ 2. **System design** — schema, interfaces, migration shape, failure modes; what breaks at the edges.
24
+ 3. **Risk** — blast radius, what a rollback looks like, what should stop a dark run beyond the standing stop-list.
25
+ 4. **Brief challenge** — anything planning revealed the brief missed or got wrong goes back to the operator as a question, never silently absorbed into the plan.
26
+
27
+ A vague or self-contradicting answer gets pushback with concrete options — simple words, a mermaid or ASCII sketch in the issue when a picture beats prose (conventions' collaboration rule).
28
+
29
+ ## The plan
30
+
31
+ Post one comment per [plan-format](references/plan-format.md): Goal · Approach (alternatives named) · Constraints · ordered `- [ ]` tasks, each with exact Files, an Interfaces block (consumes/produces with exact signatures), and Steps that put the failing test before the code. Before posting:
32
+
33
+ - Self-review: every brief requirement maps to a task; names and types are consistent across tasks; no banned placeholders (the list lives in plan-format).
34
+ - Run this skill's plan-lint: `node <path-to-this-skill>/scripts/plan-lint.mjs --file <draft> --json`; exit 2 = fix before posting (placeholders and structural gaps block).
35
+
36
+ Checkboxes belong to the implement session — never pre-tick them.
37
+
38
+ ## Labels and approval
39
+
40
+ Post the plan → flip to `needs-operator`. On the operator's "plan approved": record `<!-- vsk:v1 type=approval scope=plan -->` with their quoted words (`operator (<username>)` format), flip to `ready`, stop — building is dev-implement's.
41
+
42
+ ## The ratchet — one home, this file
43
+
44
+ - **Upgrade (any time, no permission needed to propose):** planning reveals the work is bigger than its scope label — a quick-build that needs real design, an issue that is actually several deliverables. Stop, post one `handback` comment proposing the reclassification or the epic split (parent map + sub-issues, each classified fresh), `needs-operator`. Never silently plan a monster: a plan approaching GitHub's ~65,536-character comment cap is the slicing telling you it wants to be an epic.
45
+ - **Downgrade (operator's yes only):** planning reveals the work is trivial — propose skipping to `ready` with the brief's inline approach, and wait for the yes.
46
+
47
+ ## Quick-build inline mode
48
+
49
+ Invoked from inside dev-intake's conversation, after the brief has consensus: same format, proportionally small (a four-item task list is a fine plan), posted as the plan comment alongside the brief. The operator's single approval covers both (`scope=brief+plan`) — no `needs-plan` stop, no second exchange. The re-grounding step collapses to what intake already read; the ratchet still applies.
50
+
51
+ ## Closing
52
+
53
+ End every run with the plain-language summary: what was planned, which approach won and why, what the operator should double-check, and what happens next.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "dev-plan"
3
+ short_description: "Plan an approved issue before any code exists"
4
+ default_prompt: "Use $dev-plan to write the implementation plan for this approved issue."
@@ -0,0 +1,93 @@
1
+ # Workflow conventions
2
+
3
+ The single spec for the artifacts every dev-family skill reads and writes. One home per rule: skills cite this file, never restate it. Everything here is harness-neutral.
4
+
5
+ ## Comment metadata markers
6
+
7
+ Every workflow-generated issue comment opens with an invisible HTML marker followed by a human heading:
8
+
9
+ ```markdown
10
+ <!-- vsk:v1 type=<type> rev=<n> [key=value ...] -->
11
+ ## <Human title> (v<n>)
12
+ ```
13
+
14
+ | type | required keys | instances |
15
+ |---|---|---|
16
+ | `approval` | `scope=<brief\|brief+plan\|plan>` | one per approval event |
17
+ | `plan` | `rev` | one, edited in place |
18
+ | `ledger` | `branch` | one, edited in place |
19
+ | `evidence` | `rev branch sha` | one, edited in place |
20
+ | `review` | `round sha agent=<claude\|codex> verdict=<clean\|needs-fixes>` | one per review cycle, rounds appended inside |
21
+ | `decision` | — | one per decision proposal |
22
+ | `handback` | — | one per stop event |
23
+
24
+ `rev=<n>` and the matching `(v<n>)` heading suffix appear only on revisable artifacts — the brief (issue description), `plan`, and `evidence` — starting at `rev=1`/`(v1)`. Single-event comments (`approval`, `decision`, `handback`) and the `ledger` carry neither. Scripts and agents locate comments strictly by marker, never by heading text. A comment without its marker does not count as the artifact — there is no legacy fallback.
25
+
26
+ ## Operator identity
27
+
28
+ Every human reference in every artifact — approvals, revisions, decisions, changelog attributions, review adjudications — is written `operator (<github-username>)`:
29
+
30
+ - Approval: `Approved by operator (<username>) on DD-MM-YYYY: "<their words>"`
31
+ - Register line: `- DD-MM-YYYY operator (<username>) — <decision>`
32
+
33
+ ## Revision markers
34
+
35
+ Any artifact edited after its first approval: the heading gains `(v2)`, the marker gains `rev=2`, and a `Revisions:` line is appended at the bottom — `v2 — DD-MM-YYYY: <what changed>, per operator (<username>) correction`. Existing revision lines are never rewritten.
36
+
37
+ ## Scope classes
38
+
39
+ Set at intake, applied as a label, announced with its reason (operator can override):
40
+
41
+ - **`research`** — a question to answer; throwaway code allowed, never merged. No branch/PR/changelog; findings + recommendation are the evidence comment.
42
+ - **`quick-build`** — small change and the flow being changed already exists in the repo to read. Brief (description) + plan (comment) are drafted in the same conversation; **one approval covers both**; then straight to `ready`.
43
+ - **`full-plan`** — big or new ground. Brief approval → `needs-plan` → a separate, fresh-grounded planning session posts the plan → `needs-operator` → "plan approved" → `ready`. Multi-deliverable work becomes an epic; each sub-issue is classified independently.
44
+
45
+ Scope calls are revisited through the one-way ratchet, whose rules and mechanics live in the `dev-plan` skill — the one home for upgrade/downgrade behavior.
46
+
47
+ ## Labels
48
+
49
+ State — exactly one per issue (creation colors live in dev-setup's labels row, their one home):
50
+
51
+ | label | meaning |
52
+ |---|---|
53
+ | `needs-operator` | waiting on the operator: a question, a brief or plan to approve, a proposal |
54
+ | `needs-plan` | brief approved; waiting for the planning stage (full-plan only) |
55
+ | `ready` | fully approved — an agent may start |
56
+ | `working` | claimed, in progress; the ledger comment shows live progress |
57
+ | `for-operator` | done — evidence posted, awaiting operator review |
58
+
59
+ Modifiers (may coexist with the state label): `risky` · scope `research` / `quick-build` / `full-plan` · `epic` (map parents, only where the org has no native Epic issue type).
60
+
61
+ ## Titles, types, hierarchy
62
+
63
+ - **Title prefixes** on issues, branches, and PRs identically: dev.md's `branch:` knob type list (that knob stays the list's one home) plus `research:` for research issues. PR title = issue title.
64
+ - **Native issue types** where the org defines them: Feature (feat) · Bug (fix) · Task (docs/chore/refactor/research) · Epic for parents (label fallback otherwise).
65
+ - **Hierarchy:** epic parent = map only (Destination · Decisions so far as one-line gists · Not clear yet · Out of scope), children attached as native sub-issues; issues = the unit of work (brief in description, own approvals/branch/PR/evidence); tasks = checkboxes **in the plan comment only**. Blockers use native issue dependencies; phases use milestones. Only issues — never epics — get `ready`. GitHub caps issue bodies and comments at ~65,536 characters; what a plan nearing that cap means is the `dev-plan` ratchet's call.
66
+
67
+ ## The ledger
68
+
69
+ Maintained by the implement session as one comment, edited in place:
70
+
71
+ ```markdown
72
+ <!-- vsk:v1 type=ledger branch=<branch> -->
73
+ ## Ledger — <branch>
74
+ - Task <N>: complete (commits <base7>..<head7>[, review clean | K parked])
75
+ - Task <N>: fix round <R>/3 (<X> addressed, <Y> open — <one-liners>; commits <a>..<b>)
76
+ - Ruling: <what> — <why> — cost if wrong: <cost>
77
+ - Task <N>: parked — <finding> — Ruling: <why the code stands>
78
+ - Deferred minor: <one-liner>
79
+ ```
80
+
81
+ **Resume protocol:** a fresh, compacted, or (operator-handed) takeover session reads, in order: the brief → the plan comment → the ledger → `git log` on the branch — **nothing else**. Tasks with a `complete` line are DONE, never re-executed; a task whose last line is a fix round resumes at the next round. After compaction, trust the ledger and `git log` over recollection. Every `Ruling:` line surfaces in the evidence comment — a ruling that dies with the session was a decision made in secret.
82
+
83
+ ## `.vegastack/.tmp/` workspace
84
+
85
+ All transitory artifacts — subagent reports, review packages, plan drafts, extracted diffs — live at `.vegastack/.tmp/<issue-number>-<title-slug>/` (pre-issue intake drafts, which have no number yet: `.vegastack/.tmp/intake-<slug>/`), kept out of git by a self-ignoring `.gitignore` (`printf '*\n' > .vegastack/.tmp/.gitignore`, created on first use). Subagents write full reports to files there and return only short status — a dead subagent's findings survive on disk, and the primary session never holds full reports in context. The workspace lives in the working tree (never under `.git/`, which harnesses protect from writes).
86
+
87
+ ## Verification gate
88
+
89
+ Before claiming any status: **IDENTIFY** the command that proves the claim → **RUN** it fresh and complete → **READ** the full output and exit code → only then claim, with the evidence. "Should pass", a previous run, or a subagent's say-so are never evidence. Guard scripts follow the same doctrine: machine-verifiable facts **block** (exit 2 with the reason); regex or judgment heuristics only **warn** — no AI inference inside guards, and an unverifiable state fails closed.
90
+
91
+ ## Plain-language collaboration
92
+
93
+ Every skill run ends with a simple-language summary: what happened, which paths were taken — cross-agent invocations announced at trigger time AND summarized at the end — and what is worth the operator double-checking. Use mermaid or ASCII diagrams in issues wherever a picture beats prose. A vague or self-contradicting operator answer gets pushback with concrete options, never silent absorption.
@@ -0,0 +1,54 @@
1
+ # The plan format
2
+
3
+ The comment a plan lives in, verbatim. dev-implement executes it task by task and ticks the checkboxes; plan-lint enforces the deterministic parts.
4
+
5
+ ````markdown
6
+ <!-- vsk:v1 type=plan rev=1 -->
7
+ ## Plan (v1)
8
+
9
+ **Goal:** <one sentence: what exists when this plan is done>
10
+ **Approach:** <2–3 sentences — and the alternatives considered with why they lost, one line each>
11
+ **Constraints:** <binding requirements from the brief and Architecture facts, exact values, one per line>
12
+
13
+ ### Tasks
14
+
15
+ - [ ] **Task 1: <name>**
16
+ - Files — Create: `exact/path.ts` · Modify: `exact/path.ts` (<which area>) · Test: `exact/path.test.ts`
17
+ - Interfaces — Consumes: <exact signatures/names from earlier tasks> · Produces: <exact names, parameter and return types later tasks rely on — an implementer may see only this task; this block is how they learn what neighbors use>
18
+ - Steps: write the failing test (the actual test code, fenced) → run it, expect FAIL with <reason> → implement the minimal code → run, expect PASS → commit `<type>: <message>`
19
+ - [ ] **Task 2: …**
20
+
21
+ **Revisions:** (absent until a post-approval edit; then one line per edit)
22
+ ````
23
+
24
+ ## Rules
25
+
26
+ - **Task size:** the smallest unit that carries its own test cycle and is worth a fresh reviewer's look. Fold setup/scaffolding/docs into the task whose deliverable needs them; split only where a reviewer could reject one task while approving its neighbor. Each task ends independently verifiable.
27
+ - **Prose tasks** (docs, skill text, config) swap the test-first Steps for edit → verify (the concrete command: `bun run check`, a link-resolution run, a rendered read-through) → commit. The verify step is never omitted.
28
+ - **Revisions:** post-approval edits follow the revision-marker rule in dev-setup's `references/conventions.md` — bump the heading/marker version and append the `Revisions:` line.
29
+
30
+ ## Banned placeholders
31
+
32
+ These are plan failures — plan-lint rejects them, and a human reviewer should too:
33
+
34
+ - "TBD", "TODO", "implement later", "fill in details"
35
+ - "Add appropriate error handling" / "add validation" / "handle edge cases"
36
+ - "Write tests for the above" without the actual test code
37
+ - "Similar to Task N" — repeat the content; tasks are read out of order
38
+ - Steps that describe what to do without showing how (code steps require code blocks)
39
+ - References to types, functions, or files no task defines
40
+
41
+ ## Self-review before posting
42
+
43
+ 1. **Coverage:** walk the brief section by section — every requirement points at a task; list any gap (a gap is a question for the operator, not a silent omission).
44
+ 2. **Placeholder scan:** search the draft for the banned list above; fix inline.
45
+ 3. **Consistency:** names, signatures, and paths used in later tasks match what earlier tasks define — `clearLayers()` in Task 3 but `clearFullLayers()` in Task 7 is a bug now, not at build time.
46
+
47
+ ## Worked micro-example
48
+
49
+ ```markdown
50
+ - [ ] **Task 1: reminder schedule column**
51
+ - Files — Modify: `server/db/schema/invoices.ts` (invoices table) · Test: `server/db/schema/invoices.test.ts`
52
+ - Interfaces — Produces: `invoices.reminderAt: timestamp | null` (Drizzle column), read by Task 2's query
53
+ - Steps: failing test asserting the column exists in the generated schema → run, expect FAIL "no such column" → add the column + regenerate → run, expect PASS → commit `feat: reminder schedule column`
54
+ ```
@@ -0,0 +1,3 @@
1
+ # Refresh contract — dev-plan
2
+
3
+ Evergreen: this skill asserts no version pins, vendor mechanisms beyond long-stable GitHub comment behavior (the ~65,536-character comment cap is stated as approximate and directional), numeric vendor limits, or dated claims — its content is planning discipline (questionnaire, plan format, ratchet), all versionless. Revisit if a future edit introduces a volatile fact.
@@ -0,0 +1,6 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "retrievalBaseline": "2026-08-28",
4
+ "note": "Evergreen waiver recorded in REFRESH.md; sources deliberately empty.",
5
+ "sources": []
6
+ }