@vegastack/skills 0.9.1 → 0.11.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/README.md +8 -3
- package/dist/index.js +5 -5
- package/package.json +1 -1
- package/skill/dev-architect/SKILL.md +96 -0
- package/skill/dev-architect/agents/openai.yaml +4 -0
- package/skill/dev-architect/references/ai-agents.md +89 -0
- package/skill/dev-architect/references/conventions.md +93 -0
- package/skill/{architect → dev-architect}/references/data.md +43 -44
- package/skill/dev-architect/references/infra.md +98 -0
- package/skill/dev-architect/references/mobile.md +75 -0
- package/skill/{architect → dev-architect}/references/pinned-facts.md +17 -16
- package/skill/dev-architect/references/principles.md +117 -0
- package/skill/{architect → dev-architect}/references/security.md +37 -44
- package/skill/dev-architect/references/stack.md +38 -0
- package/skill/dev-architect/references/web.md +102 -0
- package/skill/{architect → dev-architect}/refresh/REFRESH.md +8 -6
- package/skill/{architect → dev-architect}/refresh/sources.json +5 -10
- package/skill/dev-chronicle/SKILL.md +45 -0
- package/skill/dev-chronicle/agents/openai.yaml +4 -0
- package/skill/dev-chronicle/references/conventions.md +93 -0
- package/skill/dev-chronicle/refresh/REFRESH.md +3 -0
- package/skill/dev-chronicle/refresh/sources.json +6 -0
- package/skill/dev-debug/SKILL.md +43 -0
- package/skill/dev-debug/agents/openai.yaml +4 -0
- package/skill/dev-debug/references/conventions.md +93 -0
- package/skill/dev-debug/references/loop-ladder.md +20 -0
- package/skill/dev-debug/refresh/REFRESH.md +3 -0
- package/skill/dev-debug/refresh/sources.json +6 -0
- package/skill/dev-implement/SKILL.md +41 -36
- package/skill/dev-implement/references/conventions.md +93 -0
- package/skill/dev-implement/references/ledger-and-resume.md +27 -0
- package/skill/dev-implement/scripts/evidence-check.mjs +57 -0
- package/skill/dev-implement/scripts/lib/gh.mjs +93 -0
- package/skill/dev-implement/scripts/preflight.mjs +101 -0
- package/skill/dev-intake/SKILL.md +39 -33
- package/skill/dev-intake/references/brief-template.md +27 -12
- package/skill/dev-intake/references/conventions.md +93 -0
- package/skill/dev-intake/scripts/brief-lint.mjs +87 -0
- package/skill/dev-plan/SKILL.md +53 -0
- package/skill/dev-plan/agents/openai.yaml +4 -0
- package/skill/dev-plan/references/conventions.md +93 -0
- package/skill/dev-plan/references/plan-format.md +54 -0
- package/skill/dev-plan/refresh/REFRESH.md +3 -0
- package/skill/dev-plan/refresh/sources.json +6 -0
- package/skill/dev-plan/scripts/plan-lint.mjs +86 -0
- package/skill/dev-review/SKILL.md +69 -0
- package/skill/dev-review/agents/openai.yaml +4 -0
- package/skill/dev-review/assets/review-known-patterns.md.template +30 -0
- package/skill/dev-review/references/conventions.md +93 -0
- package/skill/dev-review/references/cross-agent.md +39 -0
- package/skill/dev-review/references/dispatch-prompts.md +104 -0
- package/skill/dev-review/references/security-axis.md +33 -0
- package/skill/dev-review/refresh/REFRESH.md +3 -0
- package/skill/dev-review/refresh/sources.json +6 -0
- package/skill/dev-setup/SKILL.md +14 -9
- package/skill/dev-setup/assets/agents-section.md.template +2 -2
- package/skill/dev-setup/assets/dev-profile.md.template +23 -5
- package/skill/dev-setup/references/conventions.md +93 -0
- package/skill/dev-setup/references/stack-playbooks.md +1 -1
- package/skill/dev-ship/SKILL.md +14 -7
- package/skill/dev-ship/references/conventions.md +93 -0
- package/skill/dev-ship/references/runbook.md +1 -1
- package/skill/dev-ship/scripts/ship-gate.mjs +213 -0
- package/skill/dev-status/SKILL.md +45 -0
- package/skill/dev-status/agents/openai.yaml +4 -0
- package/skill/dev-status/references/conventions.md +93 -0
- package/skill/dev-status/refresh/REFRESH.md +3 -0
- package/skill/dev-status/refresh/sources.json +6 -0
- package/skill/dev-status/scripts/status.mjs +152 -0
- package/skill/skill-maintainer/references/release-ops.md +3 -3
- package/skill/skillify/SKILL.md +1 -1
- package/skill/skillify/references/eval-playbook.md +6 -0
- package/skill-integrity.json +93 -33
- package/skill/architect/SKILL.md +0 -68
- package/skill/architect/agents/openai.yaml +0 -4
- package/skill/architect/assets/adr-template.md +0 -21
- package/skill/architect/assets/arch-template.md +0 -20
- package/skill/architect/references/advisory.md +0 -102
- package/skill/architect/references/ai-agents.md +0 -95
- package/skill/architect/references/infra.md +0 -128
- package/skill/architect/references/mobile.md +0 -78
- package/skill/architect/references/principles.md +0 -91
- package/skill/architect/references/project-profile.md +0 -37
- package/skill/architect/references/stack.md +0 -38
- package/skill/architect/references/web.md +0 -152
|
@@ -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,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,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// dev-plan guard: deterministic checks on a drafted plan comment. Placeholders
|
|
3
|
+
// and structural gaps block; nothing here warns. The banned-placeholder list's
|
|
4
|
+
// single home is this file — brief-lint defers inline-plan checks to it.
|
|
5
|
+
//
|
|
6
|
+
// Exit codes: 0 pass · 2 blocked (this guard has no warn class).
|
|
7
|
+
// Usage: node plan-lint.mjs --file <plan.md> --json
|
|
8
|
+
import { readFileSync } from 'node:fs';
|
|
9
|
+
import { resolve } from 'node:path';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
// Self-contained on purpose: plan-lint ships with dev-plan and must run on a
|
|
12
|
+
// standalone install, so it carries its own tiny flag/result helpers instead of
|
|
13
|
+
// importing dev-implement's lib.
|
|
14
|
+
|
|
15
|
+
export const bannedPlaceholders = [
|
|
16
|
+
/\bTBD\b/,
|
|
17
|
+
/\bTODO\b/,
|
|
18
|
+
/implement later/i,
|
|
19
|
+
/fill in details/i,
|
|
20
|
+
/add appropriate error handling/i,
|
|
21
|
+
/\badd validation\b/i,
|
|
22
|
+
/handle edge cases/i,
|
|
23
|
+
/write tests for the above/i,
|
|
24
|
+
/similar to task \d+/i,
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
export function lintPlan(text) {
|
|
28
|
+
const blocks = [];
|
|
29
|
+
|
|
30
|
+
if (!/<!--\s*vsk:v1\s+type=plan\b/.test(text)) blocks.push('missing plan marker (<!-- vsk:v1 type=plan rev=n -->)');
|
|
31
|
+
|
|
32
|
+
for (const pattern of bannedPlaceholders) {
|
|
33
|
+
const hit = pattern.exec(text);
|
|
34
|
+
if (hit) blocks.push(`banned placeholder: "${hit[0]}" — plans carry the actual content`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// A Task-header line not carried by a checkbox would otherwise be absorbed
|
|
38
|
+
// into the previous task's chunk and inherit its sections — detect it.
|
|
39
|
+
// Anchored to the line START so mid-line references ("consumes Task 2's
|
|
40
|
+
// output") never false-block.
|
|
41
|
+
for (const line of text.split('\n')) {
|
|
42
|
+
const t = line.trim();
|
|
43
|
+
if (/^(\*\*|[-*]\s+\*\*)?Task \d+:/.test(t) && !/^- \[[ x]\]/.test(t)) {
|
|
44
|
+
blocks.push(`task line without a checkbox: "${t.slice(0, 60)}"`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const tasks = text.split(/^- \[[ x]\] \*\*Task /m).slice(1);
|
|
49
|
+
if (tasks.length === 0) blocks.push('no checkbox tasks found (- [ ] **Task N: ...**)');
|
|
50
|
+
tasks.forEach((task, index) => {
|
|
51
|
+
const n = index + 1;
|
|
52
|
+
if (!/Files\s*—/.test(task)) blocks.push(`task ${n}: missing "Files —" line with exact paths`);
|
|
53
|
+
if (!/Interfaces\s*—/.test(task)) blocks.push(`task ${n}: missing "Interfaces —" block (consumes/produces)`);
|
|
54
|
+
if (!/Steps[:\s]/.test(task)) blocks.push(`task ${n}: missing "Steps" line`);
|
|
55
|
+
if (/failing test/i.test(task) && !task.includes('```')) {
|
|
56
|
+
blocks.push(`task ${n}: a failing-test step must carry the actual test code in a fenced block`);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return { blocks, warns: [] };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const invokedDirectly = process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
64
|
+
if (invokedDirectly) {
|
|
65
|
+
const argv = process.argv.slice(2);
|
|
66
|
+
const json = argv.includes('--json');
|
|
67
|
+
const fileIndex = argv.indexOf('--file');
|
|
68
|
+
let outcome;
|
|
69
|
+
if (fileIndex === -1 || !argv[fileIndex + 1]) {
|
|
70
|
+
outcome = { blocks: ['usage: plan-lint.mjs --file <plan.md> [--json]'], warns: [] };
|
|
71
|
+
} else {
|
|
72
|
+
try {
|
|
73
|
+
outcome = lintPlan(readFileSync(argv[fileIndex + 1], 'utf8'));
|
|
74
|
+
} catch (error) {
|
|
75
|
+
outcome = { blocks: [`cannot read plan: ${error.message}`], warns: [] };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const ok = outcome.blocks.length === 0;
|
|
79
|
+
if (json) {
|
|
80
|
+
console.log(JSON.stringify({ guard: 'plan-lint', ok, ...outcome }, null, 2));
|
|
81
|
+
} else {
|
|
82
|
+
console.log(`plan-lint: ${ok ? 'pass' : 'BLOCKED'}`);
|
|
83
|
+
for (const b of outcome.blocks) console.log(` block: ${b}`);
|
|
84
|
+
}
|
|
85
|
+
process.exit(ok ? 0 : 2);
|
|
86
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dev-review
|
|
3
|
+
description: Independent review of finished implementation work — a diff against its brief and plan. Use when dev-implement's review step runs, when asked to "review this branch/diff/issue", "give this a second pair of eyes", "check the finished work on issue N", when a cross-agent session (Claude or Codex) is handed a REVIEW REQUEST, or when review findings need a fix loop, re-review, or adjudication. Not for reviewing an unbuilt plan (dev-plan's approval gate), architecture review (dev-architect), shipping gates (dev-ship), or generic PR review in repos outside this workflow.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dev-review
|
|
7
|
+
|
|
8
|
+
Review is a specified system, not a vibe: fresh eyes per axis, severities with teeth, a bounded fix loop, and every dismissal on the record. The reviewer's job is findings or verified absence of findings — never praise. Formats follow the `dev-setup` skill's `references/conventions.md`; the reviewer briefs live in [dispatch-prompts](references/dispatch-prompts.md).
|
|
9
|
+
|
|
10
|
+
Nearest neighbors: `dev-implement` invokes this per dev.md's `review:` knob and applies the findings; `dev-ship` consumes the verdict marker; `dev-plan`'s approval gate reviews plans before build — this skill reviews built work after.
|
|
11
|
+
|
|
12
|
+
## Inputs — files, never pasted context
|
|
13
|
+
|
|
14
|
+
Build the review package first: `git log --oneline <base>..<head>` + `git diff --stat` + `git diff -U10`, written to `.vegastack/.tmp/<issue>-<slug>/review-<base7>..<head7>.diff`. Reviewers get paths — the brief (issue body), the plan comment, the package file, the project's `.vegastack/review-known-patterns.md` — plus the binding constraints copied verbatim. Reviewers write their full reports to `.tmp` files and return short status; a dead reviewer's findings survive on disk.
|
|
15
|
+
|
|
16
|
+
## The axes — parallel, fresh, never merged
|
|
17
|
+
|
|
18
|
+
| Axis | Runs | Judges |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| **Spec** | always | the diff vs the CURRENT brief + plan: missing, scope creep, implemented-but-wrong — quoting the brief line per finding; includes the tests-are-real rubric |
|
|
21
|
+
| **Standards** | always | project rules (known-patterns file + repo docs, which override) + the fixed smell baseline pasted in full into its prompt |
|
|
22
|
+
| **Security** | on `risky`, or when touch points hit auth, money, user data, or external input | data-flow traces, exploitability before severity — method in [security-axis](references/security-axis.md) |
|
|
23
|
+
|
|
24
|
+
Each axis is a fresh subagent with no memory of writing the code (its prompt: [dispatch-prompts](references/dispatch-prompts.md)). Axes report separately and are never re-ranked into one list — a change can pass one axis and fail another, and merging lets one mask the other.
|
|
25
|
+
|
|
26
|
+
**Never pre-judge.** A dispatch containing "do not flag…", "don't treat X as a defect", or "at most minor" is forbidden — if you believe something is a false positive, let the reviewer raise it and adjudicate it openly in the loop.
|
|
27
|
+
|
|
28
|
+
## The review comment — one per cycle, rounds appended, marker always current
|
|
29
|
+
|
|
30
|
+
One comment per review cycle. **The single marker at the top is edited every round** to the newest `round`/`sha`/`verdict` — consumers (ship-gate) read the first marker, so a stale round-1 `needs-fixes` must never sit above a clean round 3. Prior rounds stay as plain `## Review — round <n>` sections appended below, carrying no markers of their own.
|
|
31
|
+
|
|
32
|
+
```markdown
|
|
33
|
+
<!-- vsk:v1 type=review round=<n> sha=<head7> agent=<claude|codex> verdict=<clean|needs-fixes> -->
|
|
34
|
+
## Review — round <n> @ <sha7>
|
|
35
|
+
|
|
36
|
+
**Verdict: <clean|needs-fixes>** — spec: <counts> · standards: <counts> · security: <counts | n/a (no surface)>
|
|
37
|
+
|
|
38
|
+
### <Axis> axis
|
|
39
|
+
**Finding [N]: <title>** — **[SEVERITY]** (confidence: high|medium|low) `path/file.ts:42`
|
|
40
|
+
<issue> / <why it matters> / <fix, fenced snippet> / <quoted brief line, spec axis>
|
|
41
|
+
|
|
42
|
+
<details><summary>Nitpicks and low-confidence (N) — non-blocking</summary>…</details>
|
|
43
|
+
|
|
44
|
+
Reviewed: <sha7> · axes: <list> · reviewer: <mode>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Severities: `[CRITICAL]` (security axis: exploitable now — blocks) > `[MUST-FIX]` (wrong, broken, or contradicts the brief — blocks) > `[SHOULD-FIX]` (convention or quality, does not block) > `[NIT]`. Finding IDs are `Finding [N]` — never `#N`, which GitHub auto-links. Low-confidence findings and nitpicks go in the collapsed block, never the main list. Group one recurring defect across files into one finding with a location list.
|
|
48
|
+
|
|
49
|
+
## The loop — 3 rounds max, then open adjudication
|
|
50
|
+
|
|
51
|
+
`[CRITICAL]` and `[MUST-FIX]` findings enter the loop; `[SHOULD-FIX]`/`[NIT]` are fixed opportunistically or recorded as deferred minors — they never extend it.
|
|
52
|
+
|
|
53
|
+
- **Rounds 1–2:** resume (or redispatch) the implementer with the open findings verbatim and the report-file path. It fixes, re-runs the covering tests, appends its fix report to the same file.
|
|
54
|
+
- **Round 3:** a fresh implementer — "a prior implementer attempted this; read the report file for what was tried." A loop surviving two resumes usually means the implementer can't see its own problem.
|
|
55
|
+
- **Every round:** the re-review is scoped to the fix diff (`FIX_BASE..HEAD`, a new package file); the re-reviewer verdicts each finding **ADDRESSED / NOT ADDRESSED** ("attempted" is not addressed), and new breakage in the fix diff joins the open list. Out-of-scope observations become deferred minors.
|
|
56
|
+
- **At the cap:** adjudicate each open finding yourself, openly — parked with a ruling ("why the code stands"), or fixed forward — every adjudication lands in the evidence comment's Review line and the ledger. Adjudicating early to end a loop is pre-judging with a different name.
|
|
57
|
+
|
|
58
|
+
## Noise controls — hard filters, not politeness
|
|
59
|
+
|
|
60
|
+
- Default quiet profile: spec, bugs, and security always; style only where a documented rule exists. The comment count is the noise metric.
|
|
61
|
+
- `.vegastack/review-known-patterns.md` (seed: [template](assets/review-known-patterns.md.template)) holds the project's never-flag patterns — each entry REQUIRES a **"Still flag if:"** exception clause; a suppression without one is a blind spot. Operator dismissals of findings get appended there by dev-implement's corrections loop, so a dismissed pattern stays dismissed.
|
|
62
|
+
|
|
63
|
+
## Cross-agent — the independence upgrade
|
|
64
|
+
|
|
65
|
+
The dev.md `review:` knob maps to exactly three states — `subagent` (fresh-subagent axes always, cross-agent never), `cross-agent-risky` (subagent axes normally; the other agent on `risky` — the recommended default where the CLI exists), `cross-agent` (the other agent always). When it runs on the other agent, follow [cross-agent](references/cross-agent.md): announce the invocation to the operator at trigger time, send the `REVIEW REQUEST (vsk cross-agent v1)` handoff (`codex exec` from Claude; `claude -p` from Codex), and summarize the outcome at the end. The reviewing agent posts its own review comment (`agent=codex`), so independence is verifiable. CLI absent → fall back to the manual relay and note that dev-setup recommends installing it.
|
|
66
|
+
|
|
67
|
+
## Closing
|
|
68
|
+
|
|
69
|
+
End with the plain-language summary: verdict, what was found and fixed, what was adjudicated and why, and what's worth the operator double-checking.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Review known patterns — {{owner/repo}}
|
|
2
|
+
|
|
3
|
+
The project's never-flag list. Every entry REQUIRES a "Still flag if:" exception clause — a suppression without one is a blind spot, not a calibration. dev-implement's corrections loop appends an entry whenever the operator dismisses a review finding, so dismissed patterns stay dismissed. Repo-documented standards override the reviewer's baseline; this file overrides neither — it only suppresses specific recurring false positives.
|
|
4
|
+
|
|
5
|
+
Format, one entry per pattern:
|
|
6
|
+
|
|
7
|
+
```markdown
|
|
8
|
+
## <short pattern name>
|
|
9
|
+
|
|
10
|
+
**Pattern:** <what the reviewer keeps flagging, concretely — code shape, file area>
|
|
11
|
+
**Why it's safe here:** <the project fact that makes it a false positive>
|
|
12
|
+
**Still flag if:** <the exception that makes it a real finding after all>
|
|
13
|
+
**Origin:** <date + issue where the dismissal happened — operator (<username>)>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Worked examples (replace with real entries)
|
|
17
|
+
|
|
18
|
+
### Sequential awaits in setup scripts
|
|
19
|
+
|
|
20
|
+
**Pattern:** consecutive `await` calls in bootstrap/setup code flagged as a parallelization miss.
|
|
21
|
+
**Why it's safe here:** setup steps have ordering dependencies the reviewer can't see locally (labels before issues, scaffold before wiring).
|
|
22
|
+
**Still flag if:** the awaits are inside a hot request path or a loop over user data.
|
|
23
|
+
**Origin:** seeded example — delete when the first real entry lands.
|
|
24
|
+
|
|
25
|
+
### Direct `gh` CLI calls without a wrapper
|
|
26
|
+
|
|
27
|
+
**Pattern:** scripts shelling to `gh` flagged as needing an API client abstraction.
|
|
28
|
+
**Why it's safe here:** the workflow standardizes on `gh` for auth and pagination; a wrapper would duplicate it.
|
|
29
|
+
**Still flag if:** arguments are interpolated into a shell string instead of an execFile arg array.
|
|
30
|
+
**Origin:** seeded example — delete when the first real entry lands.
|
|
@@ -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.
|