@vegastack/vegafactory 0.19.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/LICENSE +21 -0
- package/README.md +417 -0
- package/dist/dashboard-artifact.json +21240 -0
- package/dist/index.js +22752 -0
- package/dist/run-wrapper.js +377 -0
- package/package.json +46 -0
- package/skill/dev-architect/SKILL.md +106 -0
- package/skill/dev-architect/agents/openai.yaml +4 -0
- package/skill/dev-architect/references/ai-agents.md +96 -0
- package/skill/dev-architect/references/conventions.md +113 -0
- package/skill/dev-architect/references/data.md +89 -0
- package/skill/dev-architect/references/infra.md +99 -0
- package/skill/dev-architect/references/mobile.md +75 -0
- package/skill/dev-architect/references/pinned-facts.md +133 -0
- package/skill/dev-architect/references/principles.md +117 -0
- package/skill/dev-architect/references/security.md +90 -0
- package/skill/dev-architect/references/stack.md +38 -0
- package/skill/dev-architect/references/web.md +102 -0
- package/skill/dev-architect/refresh/REFRESH.md +31 -0
- package/skill/dev-architect/refresh/sources.json +239 -0
- package/skill/dev-chronicle/SKILL.md +52 -0
- package/skill/dev-chronicle/agents/openai.yaml +4 -0
- package/skill/dev-chronicle/references/conventions.md +113 -0
- package/skill/dev-chronicle/references/styles.md +75 -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 +113 -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 +81 -0
- package/skill/dev-implement/agents/openai.yaml +4 -0
- package/skill/dev-implement/assets/workflows/implement-children.js +12 -0
- package/skill/dev-implement/references/ask-route.md +80 -0
- package/skill/dev-implement/references/changelog-and-chronicle.md +21 -0
- package/skill/dev-implement/references/conventions.md +113 -0
- package/skill/dev-implement/references/ledger-and-resume.md +52 -0
- package/skill/dev-implement/references/parallel-children.md +35 -0
- package/skill/dev-implement/references/worktrees.md +63 -0
- package/skill/dev-implement/refresh/REFRESH.md +3 -0
- package/skill/dev-implement/refresh/sources.json +6 -0
- package/skill/dev-implement/scripts/children.mjs +479 -0
- package/skill/dev-implement/scripts/effective-policy.mjs +694 -0
- package/skill/dev-implement/scripts/evidence-check.mjs +107 -0
- package/skill/dev-implement/scripts/evidence-upload.mjs +181 -0
- package/skill/dev-implement/scripts/learning.mjs +41 -0
- package/skill/dev-implement/scripts/lib/approval.mjs +1182 -0
- package/skill/dev-implement/scripts/lib/gh.mjs +101 -0
- package/skill/dev-implement/scripts/preflight.mjs +153 -0
- package/skill/dev-implement/scripts/questions.mjs +381 -0
- package/skill/dev-implement/scripts/reclaim.mjs +116 -0
- package/skill/dev-implement/scripts/recovery.mjs +213 -0
- package/skill/dev-implement/scripts/worktree.mjs +991 -0
- package/skill/dev-intake/SKILL.md +80 -0
- package/skill/dev-intake/agents/openai.yaml +4 -0
- package/skill/dev-intake/references/ask-route.md +80 -0
- package/skill/dev-intake/references/brief-template.md +89 -0
- package/skill/dev-intake/references/conventions.md +113 -0
- package/skill/dev-intake/refresh/REFRESH.md +3 -0
- package/skill/dev-intake/refresh/sources.json +6 -0
- package/skill/dev-intake/scripts/brief-lint.mjs +87 -0
- package/skill/dev-intake/scripts/lib/approval.mjs +1182 -0
- package/skill/dev-intake/scripts/questions.mjs +381 -0
- package/skill/dev-plan/SKILL.md +54 -0
- package/skill/dev-plan/agents/openai.yaml +4 -0
- package/skill/dev-plan/references/ask-route.md +80 -0
- package/skill/dev-plan/references/conventions.md +113 -0
- package/skill/dev-plan/references/plan-format.md +82 -0
- package/skill/dev-plan/refresh/REFRESH.md +3 -0
- package/skill/dev-plan/refresh/sources.json +6 -0
- package/skill/dev-plan/scripts/lib/approval.mjs +1182 -0
- package/skill/dev-plan/scripts/plan-lint.mjs +319 -0
- package/skill/dev-plan/scripts/questions.mjs +381 -0
- package/skill/dev-review/SKILL.md +76 -0
- package/skill/dev-review/agents/openai.yaml +4 -0
- package/skill/dev-review/assets/review-known-patterns.md.template +32 -0
- package/skill/dev-review/references/conventions.md +113 -0
- package/skill/dev-review/references/cross-agent.md +39 -0
- package/skill/dev-review/references/dispatch-prompts.md +121 -0
- package/skill/dev-review/references/security-axis.md +45 -0
- package/skill/dev-review/refresh/REFRESH.md +5 -0
- package/skill/dev-review/refresh/sources.json +6 -0
- package/skill/dev-setup/SKILL.md +113 -0
- package/skill/dev-setup/agents/openai.yaml +4 -0
- package/skill/dev-setup/assets/agents-section.md.template +24 -0
- package/skill/dev-setup/assets/dev-profile.md.template +102 -0
- package/skill/dev-setup/assets/factory-board.yml.template +162 -0
- package/skill/dev-setup/assets/hooks/decision-nudge.mjs +30 -0
- package/skill/dev-setup/assets/hooks/prompt-skill-mention.mjs +29 -0
- package/skill/dev-setup/assets/hooks/session-end.mjs +14 -0
- package/skill/dev-setup/assets/hooks/session-start.mjs +178 -0
- package/skill/dev-setup/assets/hooks/ship-guard.mjs +738 -0
- package/skill/dev-setup/assets/hooks/skill-activated.mjs +47 -0
- package/skill/dev-setup/assets/hooks/stop-heartbeat.mjs +14 -0
- package/skill/dev-setup/assets/workflows/implement-children.js +12 -0
- package/skill/dev-setup/references/ask-route.md +80 -0
- package/skill/dev-setup/references/conventions.md +113 -0
- package/skill/dev-setup/references/github-app.md +286 -0
- package/skill/dev-setup/references/harness-facts.md +169 -0
- package/skill/dev-setup/references/stack-playbooks.md +124 -0
- package/skill/dev-setup/refresh/REFRESH.md +13 -0
- package/skill/dev-setup/refresh/sources.json +602 -0
- package/skill/dev-setup/scripts/effective-policy.mjs +694 -0
- package/skill/dev-setup/scripts/questions.mjs +381 -0
- package/skill/dev-setup/scripts/ship-policy.mjs +195 -0
- package/skill/dev-ship/SKILL.md +56 -0
- package/skill/dev-ship/agents/openai.yaml +4 -0
- package/skill/dev-ship/references/conventions.md +113 -0
- package/skill/dev-ship/references/runbook.md +72 -0
- package/skill/dev-ship/refresh/REFRESH.md +3 -0
- package/skill/dev-ship/refresh/sources.json +6 -0
- package/skill/dev-ship/scripts/lib/approval.mjs +1182 -0
- package/skill/dev-ship/scripts/ship-gate.mjs +485 -0
- package/skill/dev-status/SKILL.md +56 -0
- package/skill/dev-status/agents/openai.yaml +4 -0
- package/skill/dev-status/references/conventions.md +113 -0
- package/skill/dev-status/refresh/REFRESH.md +3 -0
- package/skill/dev-status/refresh/sources.json +6 -0
- package/skill/dev-status/scripts/effective-policy.mjs +694 -0
- package/skill/dev-status/scripts/status.mjs +311 -0
- package/skill/skill-maintainer/SKILL.md +82 -0
- package/skill/skill-maintainer/agents/openai.yaml +4 -0
- package/skill/skill-maintainer/references/release-ops.md +61 -0
- package/skill/skill-maintainer/references/standards.md +137 -0
- package/skill/skill-maintainer/refresh/REFRESH.md +40 -0
- package/skill/skill-maintainer/refresh/sources.json +103 -0
- package/skill/skill-scan/SKILL.md +59 -0
- package/skill/skill-scan/agents/openai.yaml +4 -0
- package/skill/skill-scan/refresh/REFRESH.md +18 -0
- package/skill/skill-scan/refresh/sources.json +133 -0
- package/skill/skill-scan/scripts/lib/skillspector.mjs +226 -0
- package/skill/skill-scan/scripts/skill-scan.mjs +1002 -0
- package/skill/skillify/SKILL.md +108 -0
- package/skill/skillify/agents/openai.yaml +4 -0
- package/skill/skillify/assets/templates/README.md.template +26 -0
- package/skill/skillify/assets/templates/REFRESH.md.template +16 -0
- package/skill/skillify/assets/templates/SKILL.md.template +27 -0
- package/skill/skillify/assets/templates/evals.json.template +12 -0
- package/skill/skillify/assets/templates/openai.yaml.template +4 -0
- package/skill/skillify/assets/templates/skill.test.ts.template +27 -0
- package/skill/skillify/assets/templates/sources.json.template +6 -0
- package/skill/skillify/assets/templates/trigger-queries.json.template +1 -0
- package/skill/skillify/references/authoring.md +103 -0
- package/skill/skillify/references/eval-playbook.md +112 -0
- package/skill/skillify/refresh/REFRESH.md +23 -0
- package/skill/skillify/refresh/sources.json +6 -0
- package/skill/skillify/scripts/scaffold-skill.mjs +334 -0
- package/skill/skillify/scripts/trigger-check.mjs +209 -0
- package/skill/vegafactory-setup/SKILL.md +77 -0
- package/skill/vegafactory-setup/agents/openai.yaml +4 -0
- package/skill/vegafactory-setup/assets/control-room/boards.md.template +17 -0
- package/skill/vegafactory-setup/assets/control-room/decisions.md.template +5 -0
- package/skill/vegafactory-setup/assets/control-room/group.md.template +44 -0
- package/skill/vegafactory-setup/assets/control-room/onboarding/dispatcher-box.md.template +86 -0
- package/skill/vegafactory-setup/assets/control-room/onboarding/new-repo.md.template +13 -0
- package/skill/vegafactory-setup/assets/control-room/onboarding/new-teammate.md.template +12 -0
- package/skill/vegafactory-setup/assets/control-room/org.md.template +60 -0
- package/skill/vegafactory-setup/assets/control-room/people.csv.template +2 -0
- package/skill/vegafactory-setup/assets/control-room/repos.md.template +7 -0
- package/skill/vegafactory-setup/assets/control-room/rules/CODEOWNERS.template +6 -0
- package/skill/vegafactory-setup/assets/control-room/rules/README.md.template +9 -0
- package/skill/vegafactory-setup/assets/control-room/rules/stats-privacy.md.template +44 -0
- package/skill/vegafactory-setup/assets/control-room/templates/README.md.template +9 -0
- package/skill/vegafactory-setup/references/control-room.md +149 -0
- package/skill/vegafactory-setup/references/conventions.md +113 -0
- package/skill/vegafactory-setup/refresh/REFRESH.md +5 -0
- package/skill/vegafactory-setup/refresh/sources.json +6 -0
- package/skill-integrity.json +252 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Workflow conventions
|
|
2
|
+
|
|
3
|
+
Artifact authority.
|
|
4
|
+
|
|
5
|
+
Defaults resolve repo, group, then org; locks require explicit org delegation. Repository dispatch/commands never inherit; registers concatenate. Policy/migration uses dev-setup's `scripts/effective-policy.mjs` and vegafactory-setup's control-room reference.
|
|
6
|
+
|
|
7
|
+
## Comment metadata markers
|
|
8
|
+
|
|
9
|
+
Comments open:
|
|
10
|
+
|
|
11
|
+
```markdown
|
|
12
|
+
<!-- vsk:v1 type=<type> rev=<n> [key=value ...] -->
|
|
13
|
+
## <Human title> (v<n>)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
| type | required keys | instances |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `approval` | `scope=<brief\|brief+plan\|plan\|consolidated\|none>` and schema-v2 JSON | one per approval event |
|
|
19
|
+
| `questions` | `rev` | one per ask round; earlier rounds stay as record (dev-setup's `references/ask-route.md`) |
|
|
20
|
+
| `plan` | `rev` | one, edited in place |
|
|
21
|
+
| `ledger` | `branch` | one, edited in place |
|
|
22
|
+
| `evidence` | `rev branch sha` | one, edited in place |
|
|
23
|
+
| `review` | `round sha agent=<claude\|codex> verdict=<clean\|needs-fixes>` | one per review cycle, rounds appended inside |
|
|
24
|
+
| `decision` | — | one per decision proposal |
|
|
25
|
+
| `handback` | — | one per stop event |
|
|
26
|
+
|
|
27
|
+
`rev=<n>` and `(v<n>)` start at 1 only on brief, plan, questions and evidence; other types have neither. Locate by marker, never heading/legacy fallback.
|
|
28
|
+
|
|
29
|
+
## Operator identity
|
|
30
|
+
|
|
31
|
+
Use parenthesized GitHub usernames:
|
|
32
|
+
|
|
33
|
+
- Approval: `Approved by (<username>) on DD-MM-YYYY: "<their words>"`
|
|
34
|
+
- Register line: `- DD-MM-YYYY (<username>) — <decision>`
|
|
35
|
+
|
|
36
|
+
Approval.mjs’s publisher/relay contract lets current-policy provider-envelope publishers attest listed operators’ session words. Other recorders may only relay independently read identical operator-published scoped grants within complete authority history, without lifecycle mutations. Relays inherit source authority/lifecycle; account attestation cannot authenticate off-platform speech.
|
|
37
|
+
|
|
38
|
+
## Scoped approval records
|
|
39
|
+
|
|
40
|
+
Use only dev-implement’s `scripts/lib/approval.mjs` and follow its contract. Refresh current policy and complete GitHub histories. `ArtifactRef={repo,issue,kind,artifactId,rev,digest}` binds brief issue-node or unique plan/protocol comment-node identity, revision and canonical SHA-256.
|
|
41
|
+
|
|
42
|
+
Post exactly one approval comment: matching scope marker, then one fenced JSON `ApprovalRecord={schemaVersion:2,id,operator,scope,source:{kind,ref,quote},artifacts,supersedes,revokes}`. Exclude outer Markdown fences, future alternatives and unresolved source locators; validate the whole body with approval.mjs's `parseApproval`. Source kind is `session` or `github-comment`, with inspectable words. Reuse valid current grants/relays; avoid counterfactual plan-only or redundant approvals. Scope is `brief`, `plan` or `brief+plan`; planning requires brief, implementation both, research execution also its protocol. Empty-artifact revocations remove exact earlier IDs. Conflicts explicitly supersede; newest never wins.
|
|
43
|
+
|
|
44
|
+
Preserve legacy comments. Without writes, inventory refusals/current digests and request reconfirmation. For duplicate canonical plans preserve both identities/bodies and request record-preserving reconciliation; never delete to clear ambiguity. Follow approval.mjs’s exact correction schema, operator-publisher and target checks. Only malformed or demonstrably invalid-source targets qualify, never valid authority or unavailable/inconsistent facts. Resolve source facts first; corrections grant no scope. Exact child checkpoint actions bind one selected code child's branch/ref/base/tasks/files; other actions never substitute.
|
|
45
|
+
|
|
46
|
+
Consolidated parent events bind frozen manifests, canonical artifacts and exact task/action subsets. Use inline UTF-8 or immutable repository/commit/path plus blob hash, never local paths. Canonical `approvalBindings` authorize; requested `recordBinding` only audits. Follow approval.mjs’s preparation/research/recovery provenance, receipts, adapters, counted attempts and fresh admission; retain immutable history and unverified legacy records. Keep checkpoint/private/live/shipping gates separate.
|
|
47
|
+
|
|
48
|
+
Canonicalization normalizes CRLF; its only exceptions are structural plan checkboxes and one validated JSON `{tasks:[{id,evidenceUrls}]}` block between `<!-- vsk:progress:start -->` / `<!-- vsk:progress:end -->`. IDs must exist; URLs are HTTP(S); unknown fields/duplicates refuse. Stable task IDs/order, interfaces, actions, revisions and all other bytes remain scope. Brief/protocol bodies have no mutable fields; fenced examples stay immutable and grant no authority.
|
|
49
|
+
|
|
50
|
+
## Revision markers
|
|
51
|
+
|
|
52
|
+
Scope edits increment marker/heading revisions and append `Revisions: v2 — DD-MM-YYYY: <change>, per (<username>) correction`; preserve earlier lines and obtain fresh approval. Validated progress changes need neither.
|
|
53
|
+
|
|
54
|
+
## Scope classes
|
|
55
|
+
|
|
56
|
+
Intake explains scope; operator overrides:
|
|
57
|
+
|
|
58
|
+
- **`research`** — inquiry; throwaway code allowed, never merged. No branch/PR/changelog; evidence comment contains findings and recommendation.
|
|
59
|
+
- **`quick-build`** — existing flow: draft brief+plan together, approve both, then `ready`.
|
|
60
|
+
- **`full-plan`** — new ground: approve brief, `needs-plan`, separate grounded planning session, `needs-operator`, approve plan, `ready`. Split multiple deliverables into independently classified epic children.
|
|
61
|
+
|
|
62
|
+
Scope ratchet: `dev-plan`.
|
|
63
|
+
|
|
64
|
+
## Labels
|
|
65
|
+
|
|
66
|
+
One state; flips set assignees (colors: dev-setup):
|
|
67
|
+
|
|
68
|
+
| label | meaning | assignee |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| `needs-operator` | question, brief or plan approval, proposal | the operator |
|
|
71
|
+
| `needs-plan` | brief approved; awaiting planning (full-plan only) | the operator |
|
|
72
|
+
| `ready` | approved — an agent may start | nobody |
|
|
73
|
+
| `working` | claimed; ledger shows live progress | the runner |
|
|
74
|
+
| `for-operator` | done — evidence posted, awaiting operator review | the operator |
|
|
75
|
+
|
|
76
|
+
Modifiers coexist with state: `risky` · scope `research` / `quick-build` / `full-plan` · `epic` (map parents without a native Epic type). Boards mirror states one-way.
|
|
77
|
+
|
|
78
|
+
## Titles, types, hierarchy
|
|
79
|
+
|
|
80
|
+
- **Title prefixes:** issues, branches and PRs use dev.md's `branch:` types plus `research:`; PR title = issue title.
|
|
81
|
+
- **Native issue types/fields:** Feature (feat) · Bug (fix) · Task (docs/chore/refactor/research) · Epic for parents (else label); intake sets Priority/Effort. Scope classes stay labels.
|
|
82
|
+
- **Hierarchy:** epic parent = map only (Destination · Decisions so far · Not clear yet · Out of scope), with native child sub-issues. Issues are work units (brief, approvals, branch, PR, evidence); tasks are checkboxes **only in the plan comment**. Blockers use dependencies; phases use milestones. Only non-epic issues get `ready`.
|
|
83
|
+
|
|
84
|
+
## The ledger
|
|
85
|
+
|
|
86
|
+
One implementation ledger:
|
|
87
|
+
|
|
88
|
+
```markdown
|
|
89
|
+
<!-- vsk:v1 type=ledger branch=<branch> -->
|
|
90
|
+
## Ledger — <branch>
|
|
91
|
+
- <issue>-T<N>: complete (commits <base7>..<head7>[, review clean | K parked])
|
|
92
|
+
- <issue>-T<N>: fix round <R>/3 (<X> addressed, <Y> open — <one-liners>; commits <a>..<b>)
|
|
93
|
+
- Ruling: <what> — <why> — cost if wrong: <cost>
|
|
94
|
+
- <issue>-T<N>: parked — <finding> — Ruling: <why the code stands>
|
|
95
|
+
- Deferred minor: <one-liner>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
**Resume protocol:** brief → plan comment → ledger → `git log`; then reconcile task IDs, canonical approval history, edited authority, source/evidence, ownership and delivery effects. Preserve completed work/provenance; stale heartbeat is not stop proof. Preparation never implies issue completion. Dev-implement's ledger reference owns recovery detail.
|
|
100
|
+
|
|
101
|
+
## `.vegastack/` workspaces
|
|
102
|
+
|
|
103
|
+
Drafts/reports: `.vegastack/.tmp/<issue-number>-<title-slug>/` (pre-issue: `intake-<slug>`), self-ignored by a `.gitignore` containing `*`. Branch checkouts: root-ignored `.vegastack/.worktrees/<issue-number>-<title-slug>/`; main stays on its default branch. Keep both outside `.git/`. Subagents save full reports and return short status. `<path-to-this-skill>` means SKILL.md’s directory.
|
|
104
|
+
|
|
105
|
+
## Verification gate
|
|
106
|
+
|
|
107
|
+
Prove claims with fresh command output and exit codes; report failures and skips. Delegate only substantial independent parallel work, never your own verification; keep spawn counts low. Guards block machine-verifiable failures (exit 2); heuristics warn. Guards contain no AI inference; unverifiable state fails closed.
|
|
108
|
+
|
|
109
|
+
## Review bindings
|
|
110
|
+
|
|
111
|
+
One fenced JSON each: `{"reviewBinding":{sha,baseSha,scopeDigest,verdict,findings:[{id,status}]}}` in review; `{"adjudication":{sha,reviewCommentId,operator,source:{kind,ref,quote},findings:[{id,disposition,reason}]}}` in evidence. Use full commit IDs and canonical-plan scopeDigest; status=open/resolved; disposition=accept-risk. Every open finding requires same-review operator acceptance. dev-ship’s README defines source checks. No prose exceptions.
|
|
112
|
+
|
|
113
|
+
Communicate starts/findings/direction plainly; self-contained outcomes include paths and remaining checks. Avoid invented labels/arrows; visualize usefully. Challenge ambiguity with options; never guess silently.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Chronicle styles
|
|
2
|
+
|
|
3
|
+
dev.md's `chronicle-style:` knob picks the voice (`plain` default · `story` · `witty`) and `emoji:` the emoji budget (`none` default · `sparing`). Tone changes; the facts and the length do not.
|
|
4
|
+
|
|
5
|
+
## The rule, every style
|
|
6
|
+
|
|
7
|
+
- Domain keywords and terms stay exact — file names, flags, labels, knob names and issue numbers are copied, never paraphrased, because the operator searches the chronicle for the terms they remember.
|
|
8
|
+
- Every factual field (What, Why, Changed, Decisions) says what it means in its first clause, so a reader skimming one field gets the fact.
|
|
9
|
+
- How it went stays under about 100 words unless something genuinely fought back — a real fight earns the space; a smooth build does not.
|
|
10
|
+
- Entries cover the substance and stop: no filler, no restated summaries, no closing moral.
|
|
11
|
+
|
|
12
|
+
## plain
|
|
13
|
+
|
|
14
|
+
Short declarative sentences and no figures of speech. The default, because it reads the same to every reader in every month.
|
|
15
|
+
|
|
16
|
+
## story
|
|
17
|
+
|
|
18
|
+
Narrative sentences in plain words: cause then effect, what was tried then what held. The same facts told in order, with no metaphor.
|
|
19
|
+
|
|
20
|
+
## witty
|
|
21
|
+
|
|
22
|
+
Wit lives in two places only: the entry title and the first sentence of How it went; everywhere else the entry reads as plain. The boundary is mannered prose: metaphor and flourish that display the writer rather than convey the idea are out; when a literal phrase is available, use it.
|
|
23
|
+
|
|
24
|
+
## Emoji
|
|
25
|
+
|
|
26
|
+
`none`: no emoji anywhere. `sparing`: at most one per entry, in the title or the footer, never inside a field's facts — a fact line with an emoji reads as decoration where the reader wanted the fact.
|
|
27
|
+
|
|
28
|
+
## Worked examples
|
|
29
|
+
|
|
30
|
+
All three tell the same fictional change so the styles compare: project ledgerly, issue [#42](https://github.com/example/ledgerly/issues/42), branch `feat/42-invoice-reminders` — a nightly `send-reminders` job on pg-boss at `06:00 UTC`, a `reminderAt` column on invoices, a `--dry-run` flag; the first nightly run sent nothing because the job compared `reminderAt` in server-local time, fixed on the second attempt by storing and comparing in UTC.
|
|
31
|
+
|
|
32
|
+
### Example — plain
|
|
33
|
+
|
|
34
|
+
<example>
|
|
35
|
+
## 14-08-2026 — Invoice reminders now chase late payers on their own ([#42](https://github.com/example/ledgerly/issues/42))
|
|
36
|
+
|
|
37
|
+
- **What:** Overdue invoices get a reminder email without anyone remembering to send one. A nightly `send-reminders` job runs on pg-boss at `06:00 UTC`, reads each invoice's new `reminderAt` column, and emails the customer when the time has passed. `send-reminders --dry-run` prints who would be emailed and sends nothing.
|
|
38
|
+
- **Why:** Reminders were sent by hand from a spreadsheet, so late invoices slipped whenever the person who owned the spreadsheet was out.
|
|
39
|
+
- **How it went:** The first nightly run sent nothing. The job compared `reminderAt` in server-local time while the column held UTC, so every invoice looked a few hours early. The second attempt stores and compares in UTC, and `--dry-run` was added so the next mistake shows up in a log before it reaches a customer.
|
|
40
|
+
- **Changed:** `reminderAt` column on invoices · `send-reminders` job on pg-boss, nightly at `06:00 UTC` · `--dry-run` flag on the job
|
|
41
|
+
- **Decisions:** none
|
|
42
|
+
|
|
43
|
+
— approved by (avery) · built by claude · branch feat/42-invoice-reminders
|
|
44
|
+
<rationale>Every field states its fact first and How it went names the fight in two sentences.</rationale>
|
|
45
|
+
</example>
|
|
46
|
+
|
|
47
|
+
### Example — story
|
|
48
|
+
|
|
49
|
+
<example>
|
|
50
|
+
## 14-08-2026 — Invoice reminders now chase late payers on their own ([#42](https://github.com/example/ledgerly/issues/42))
|
|
51
|
+
|
|
52
|
+
- **What:** Late invoices used to wait for a person; now a nightly `send-reminders` job on pg-boss runs at `06:00 UTC`, checks each invoice's new `reminderAt` column, and emails the customer once that time has passed. Anyone unsure what tomorrow's run will do can run `send-reminders --dry-run` and read the list without sending a thing.
|
|
53
|
+
- **Why:** Reminders came from a hand-kept spreadsheet, so whenever its owner was out, late invoices went quiet and stayed that way.
|
|
54
|
+
- **How it went:** The job shipped, the first night came, and nothing went out. The cause was a time-zone mismatch: the job compared `reminderAt` in server-local time while the column held UTC, so every invoice looked a few hours early and was skipped. The second attempt stores and compares in UTC, and `--dry-run` was added so the next surprise appears in a log instead of a customer's inbox.
|
|
55
|
+
- **Changed:** `reminderAt` column on invoices · `send-reminders` job on pg-boss, nightly at `06:00 UTC` · `--dry-run` flag on the job
|
|
56
|
+
- **Decisions:** none
|
|
57
|
+
|
|
58
|
+
— approved by (avery) · built by claude · branch feat/42-invoice-reminders
|
|
59
|
+
<rationale>The same facts in cause-then-effect order, still no metaphor.</rationale>
|
|
60
|
+
</example>
|
|
61
|
+
|
|
62
|
+
### Example — witty
|
|
63
|
+
|
|
64
|
+
<example>
|
|
65
|
+
## 14-08-2026 — Invoice reminders now nag late payers so nobody else has to ([#42](https://github.com/example/ledgerly/issues/42))
|
|
66
|
+
|
|
67
|
+
- **What:** Overdue invoices get a reminder email without anyone remembering to send one. A nightly `send-reminders` job runs on pg-boss at `06:00 UTC`, reads each invoice's new `reminderAt` column, and emails the customer when the time has passed. `send-reminders --dry-run` prints who would be emailed and sends nothing.
|
|
68
|
+
- **Why:** Reminders were sent by hand from a spreadsheet, so late invoices slipped whenever the person who owned the spreadsheet was out.
|
|
69
|
+
- **How it went:** The job's first night on duty, it reminded exactly nobody. The job compared `reminderAt` in server-local time while the column held UTC, so every invoice looked a few hours early. The second attempt stores and compares in UTC, and `--dry-run` was added so the next mistake shows up in a log before it reaches a customer.
|
|
70
|
+
- **Changed:** `reminderAt` column on invoices · `send-reminders` job on pg-boss, nightly at `06:00 UTC` · `--dry-run` flag on the job
|
|
71
|
+
- **Decisions:** none
|
|
72
|
+
|
|
73
|
+
— approved by (avery) · built by claude · branch feat/42-invoice-reminders
|
|
74
|
+
<rationale>The joke sits in the title and the opener only; the fields below are word-for-word plain.</rationale>
|
|
75
|
+
</example>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dev-debug
|
|
3
|
+
description: Reproduce-first bug work. Use when given a bug to fix — "debug this", "this is broken and I don't know why", "users report X fails", "login intermittently 500s", implementing a fix-type issue whose brief carries a Reproduction section, or when a fix keeps not fixing the symptom. Not for writing the bug up as an issue (dev-intake), building planned features (dev-implement — this skill governs the diagnosis inside its dark mode), or reviewing a finished fix (dev-review).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dev-debug
|
|
7
|
+
|
|
8
|
+
Act: reproduce first, then shrink, suspect, test, prove and clean, in that order, because a fix without a red command fixes a guess.
|
|
9
|
+
|
|
10
|
+
The failure this skill prevents: reading code, forming one theory, and "fixing" something that was not the cause. The discipline is a hard order — **reproduce, shrink, suspect, test, prove, clean** — and each phase has a completion criterion you can check, not vibe. It runs inside dev-implement's dark mode: no operator questions; missing-artifact stops are one `handback` comment; every phase result is a ledger checkpoint.
|
|
11
|
+
|
|
12
|
+
Nearest neighbors: `dev-intake`'s bug variant writes the brief this skill executes; `dev-implement` owns the surrounding build ceremony; `dev-review` judges the finished fix.
|
|
13
|
+
|
|
14
|
+
## Phase 1 — the red command comes before any theory
|
|
15
|
+
|
|
16
|
+
Build **one named command** that demonstrates the bug: it fails right now *because of this bug's exact symptom*, and will pass once it's truly fixed. The completion criterion, all four checkable:
|
|
17
|
+
|
|
18
|
+
- **Red-capable** — it asserts the reported symptom, not "runs without erroring"; you have run it at least once and its invocation + failing output (redacted) go in the ledger.
|
|
19
|
+
- **Deterministic** — same verdict every run; a flaky bug substitutes a pinned, stated reproduction rate ("~1 in 12 across 50 runs").
|
|
20
|
+
- **Fast** — seconds, not minutes; a tight loop is the whole superpower here.
|
|
21
|
+
- **Agent-runnable** — no human in the loop.
|
|
22
|
+
|
|
23
|
+
Pick the cheapest rung that reaches the bug from the [loop ladder](references/loop-ladder.md). Can't build one after walking the ladder → stop: one `handback` comment, `needs-operator`. A handback lists what was tried, one line per ladder rung, and asks for the artifacts by name (logs, HAR, recording, environment access). Proceeding to theories without a red command is the exact failure this skill exists to prevent.
|
|
24
|
+
|
|
25
|
+
## Phase 2 — shrink until everything left is load-bearing
|
|
26
|
+
|
|
27
|
+
Run the loop, watch it go red on the *reported* symptom (the wrong bug means the wrong fix). Then minimise: cut inputs, callers, config, and steps **one at a time**, re-running after each cut, keeping only what the failure needs. Done when removing any remaining element turns the loop green. The minimal repro shrinks the suspect space and becomes Phase 5's regression test.
|
|
28
|
+
|
|
29
|
+
## Phase 3 — suspects: 3–5, ranked, falsifiable, posted, then GO
|
|
30
|
+
|
|
31
|
+
List 3–5 candidate causes ranked most-likely first — a single hypothesis anchors on the first plausible idea. Each must be **falsifiable**: "if X is the cause, then changing Y makes the bug disappear / Z makes it worse." A suspect whose prediction you can't state is a vibe — discard or sharpen it. Post the ranked list to the ledger and proceed, because dark mode holds and the operator's re-rank arrives asynchronously whenever it comes.
|
|
32
|
+
|
|
33
|
+
## Phase 4 — test suspects one variable at a time
|
|
34
|
+
|
|
35
|
+
Every probe maps to one suspect's prediction. Prefer a debugger/REPL breakpoint over logs; when logging, target the boundaries that separate suspects, because a blanket log buries the signal. **Every debug log carries a `[DEBUG-<4hex>]` tag** (one random tag per session): cleanup becomes a single grep, and ship-gate blocks any tag that survives into the diff. Performance bugs: logs lie — measure a baseline first (timing harness, profiler, query plan), then bisect.
|
|
36
|
+
|
|
37
|
+
## Phase 5 — regression test before the fix
|
|
38
|
+
|
|
39
|
+
Write the failing test before touching the fix, at a correct seam: one where the test exercises the real bug pattern as it occurs at the call site. If the only reachable seam is too shallow to replicate the trigger, that is itself a finding — record it in the ledger and evidence; a false-confidence test is worse than a named gap. With a correct seam: minimal repro → failing test → watch it fail → fix → watch it pass → re-run the original un-minimised Phase 1 loop green.
|
|
40
|
+
|
|
41
|
+
## Phase 6 — clean up and teach
|
|
42
|
+
|
|
43
|
+
Before hand-back, all checkable: the original repro re-runs green · `git diff <base>... | grep -F '[DEBUG-'` comes back empty (fixed-string grep; ship-gate backstops the added lines) · throwaway harnesses deleted · the winning suspect and its evidence named in the evidence comment and the commit message — the next debugger learns what it actually was, not just that it went away.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Workflow conventions
|
|
2
|
+
|
|
3
|
+
Artifact authority.
|
|
4
|
+
|
|
5
|
+
Defaults resolve repo, group, then org; locks require explicit org delegation. Repository dispatch/commands never inherit; registers concatenate. Policy/migration uses dev-setup's `scripts/effective-policy.mjs` and vegafactory-setup's control-room reference.
|
|
6
|
+
|
|
7
|
+
## Comment metadata markers
|
|
8
|
+
|
|
9
|
+
Comments open:
|
|
10
|
+
|
|
11
|
+
```markdown
|
|
12
|
+
<!-- vsk:v1 type=<type> rev=<n> [key=value ...] -->
|
|
13
|
+
## <Human title> (v<n>)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
| type | required keys | instances |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `approval` | `scope=<brief\|brief+plan\|plan\|consolidated\|none>` and schema-v2 JSON | one per approval event |
|
|
19
|
+
| `questions` | `rev` | one per ask round; earlier rounds stay as record (dev-setup's `references/ask-route.md`) |
|
|
20
|
+
| `plan` | `rev` | one, edited in place |
|
|
21
|
+
| `ledger` | `branch` | one, edited in place |
|
|
22
|
+
| `evidence` | `rev branch sha` | one, edited in place |
|
|
23
|
+
| `review` | `round sha agent=<claude\|codex> verdict=<clean\|needs-fixes>` | one per review cycle, rounds appended inside |
|
|
24
|
+
| `decision` | — | one per decision proposal |
|
|
25
|
+
| `handback` | — | one per stop event |
|
|
26
|
+
|
|
27
|
+
`rev=<n>` and `(v<n>)` start at 1 only on brief, plan, questions and evidence; other types have neither. Locate by marker, never heading/legacy fallback.
|
|
28
|
+
|
|
29
|
+
## Operator identity
|
|
30
|
+
|
|
31
|
+
Use parenthesized GitHub usernames:
|
|
32
|
+
|
|
33
|
+
- Approval: `Approved by (<username>) on DD-MM-YYYY: "<their words>"`
|
|
34
|
+
- Register line: `- DD-MM-YYYY (<username>) — <decision>`
|
|
35
|
+
|
|
36
|
+
Approval.mjs’s publisher/relay contract lets current-policy provider-envelope publishers attest listed operators’ session words. Other recorders may only relay independently read identical operator-published scoped grants within complete authority history, without lifecycle mutations. Relays inherit source authority/lifecycle; account attestation cannot authenticate off-platform speech.
|
|
37
|
+
|
|
38
|
+
## Scoped approval records
|
|
39
|
+
|
|
40
|
+
Use only dev-implement’s `scripts/lib/approval.mjs` and follow its contract. Refresh current policy and complete GitHub histories. `ArtifactRef={repo,issue,kind,artifactId,rev,digest}` binds brief issue-node or unique plan/protocol comment-node identity, revision and canonical SHA-256.
|
|
41
|
+
|
|
42
|
+
Post exactly one approval comment: matching scope marker, then one fenced JSON `ApprovalRecord={schemaVersion:2,id,operator,scope,source:{kind,ref,quote},artifacts,supersedes,revokes}`. Exclude outer Markdown fences, future alternatives and unresolved source locators; validate the whole body with approval.mjs's `parseApproval`. Source kind is `session` or `github-comment`, with inspectable words. Reuse valid current grants/relays; avoid counterfactual plan-only or redundant approvals. Scope is `brief`, `plan` or `brief+plan`; planning requires brief, implementation both, research execution also its protocol. Empty-artifact revocations remove exact earlier IDs. Conflicts explicitly supersede; newest never wins.
|
|
43
|
+
|
|
44
|
+
Preserve legacy comments. Without writes, inventory refusals/current digests and request reconfirmation. For duplicate canonical plans preserve both identities/bodies and request record-preserving reconciliation; never delete to clear ambiguity. Follow approval.mjs’s exact correction schema, operator-publisher and target checks. Only malformed or demonstrably invalid-source targets qualify, never valid authority or unavailable/inconsistent facts. Resolve source facts first; corrections grant no scope. Exact child checkpoint actions bind one selected code child's branch/ref/base/tasks/files; other actions never substitute.
|
|
45
|
+
|
|
46
|
+
Consolidated parent events bind frozen manifests, canonical artifacts and exact task/action subsets. Use inline UTF-8 or immutable repository/commit/path plus blob hash, never local paths. Canonical `approvalBindings` authorize; requested `recordBinding` only audits. Follow approval.mjs’s preparation/research/recovery provenance, receipts, adapters, counted attempts and fresh admission; retain immutable history and unverified legacy records. Keep checkpoint/private/live/shipping gates separate.
|
|
47
|
+
|
|
48
|
+
Canonicalization normalizes CRLF; its only exceptions are structural plan checkboxes and one validated JSON `{tasks:[{id,evidenceUrls}]}` block between `<!-- vsk:progress:start -->` / `<!-- vsk:progress:end -->`. IDs must exist; URLs are HTTP(S); unknown fields/duplicates refuse. Stable task IDs/order, interfaces, actions, revisions and all other bytes remain scope. Brief/protocol bodies have no mutable fields; fenced examples stay immutable and grant no authority.
|
|
49
|
+
|
|
50
|
+
## Revision markers
|
|
51
|
+
|
|
52
|
+
Scope edits increment marker/heading revisions and append `Revisions: v2 — DD-MM-YYYY: <change>, per (<username>) correction`; preserve earlier lines and obtain fresh approval. Validated progress changes need neither.
|
|
53
|
+
|
|
54
|
+
## Scope classes
|
|
55
|
+
|
|
56
|
+
Intake explains scope; operator overrides:
|
|
57
|
+
|
|
58
|
+
- **`research`** — inquiry; throwaway code allowed, never merged. No branch/PR/changelog; evidence comment contains findings and recommendation.
|
|
59
|
+
- **`quick-build`** — existing flow: draft brief+plan together, approve both, then `ready`.
|
|
60
|
+
- **`full-plan`** — new ground: approve brief, `needs-plan`, separate grounded planning session, `needs-operator`, approve plan, `ready`. Split multiple deliverables into independently classified epic children.
|
|
61
|
+
|
|
62
|
+
Scope ratchet: `dev-plan`.
|
|
63
|
+
|
|
64
|
+
## Labels
|
|
65
|
+
|
|
66
|
+
One state; flips set assignees (colors: dev-setup):
|
|
67
|
+
|
|
68
|
+
| label | meaning | assignee |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| `needs-operator` | question, brief or plan approval, proposal | the operator |
|
|
71
|
+
| `needs-plan` | brief approved; awaiting planning (full-plan only) | the operator |
|
|
72
|
+
| `ready` | approved — an agent may start | nobody |
|
|
73
|
+
| `working` | claimed; ledger shows live progress | the runner |
|
|
74
|
+
| `for-operator` | done — evidence posted, awaiting operator review | the operator |
|
|
75
|
+
|
|
76
|
+
Modifiers coexist with state: `risky` · scope `research` / `quick-build` / `full-plan` · `epic` (map parents without a native Epic type). Boards mirror states one-way.
|
|
77
|
+
|
|
78
|
+
## Titles, types, hierarchy
|
|
79
|
+
|
|
80
|
+
- **Title prefixes:** issues, branches and PRs use dev.md's `branch:` types plus `research:`; PR title = issue title.
|
|
81
|
+
- **Native issue types/fields:** Feature (feat) · Bug (fix) · Task (docs/chore/refactor/research) · Epic for parents (else label); intake sets Priority/Effort. Scope classes stay labels.
|
|
82
|
+
- **Hierarchy:** epic parent = map only (Destination · Decisions so far · Not clear yet · Out of scope), with native child sub-issues. Issues are work units (brief, approvals, branch, PR, evidence); tasks are checkboxes **only in the plan comment**. Blockers use dependencies; phases use milestones. Only non-epic issues get `ready`.
|
|
83
|
+
|
|
84
|
+
## The ledger
|
|
85
|
+
|
|
86
|
+
One implementation ledger:
|
|
87
|
+
|
|
88
|
+
```markdown
|
|
89
|
+
<!-- vsk:v1 type=ledger branch=<branch> -->
|
|
90
|
+
## Ledger — <branch>
|
|
91
|
+
- <issue>-T<N>: complete (commits <base7>..<head7>[, review clean | K parked])
|
|
92
|
+
- <issue>-T<N>: fix round <R>/3 (<X> addressed, <Y> open — <one-liners>; commits <a>..<b>)
|
|
93
|
+
- Ruling: <what> — <why> — cost if wrong: <cost>
|
|
94
|
+
- <issue>-T<N>: parked — <finding> — Ruling: <why the code stands>
|
|
95
|
+
- Deferred minor: <one-liner>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
**Resume protocol:** brief → plan comment → ledger → `git log`; then reconcile task IDs, canonical approval history, edited authority, source/evidence, ownership and delivery effects. Preserve completed work/provenance; stale heartbeat is not stop proof. Preparation never implies issue completion. Dev-implement's ledger reference owns recovery detail.
|
|
100
|
+
|
|
101
|
+
## `.vegastack/` workspaces
|
|
102
|
+
|
|
103
|
+
Drafts/reports: `.vegastack/.tmp/<issue-number>-<title-slug>/` (pre-issue: `intake-<slug>`), self-ignored by a `.gitignore` containing `*`. Branch checkouts: root-ignored `.vegastack/.worktrees/<issue-number>-<title-slug>/`; main stays on its default branch. Keep both outside `.git/`. Subagents save full reports and return short status. `<path-to-this-skill>` means SKILL.md’s directory.
|
|
104
|
+
|
|
105
|
+
## Verification gate
|
|
106
|
+
|
|
107
|
+
Prove claims with fresh command output and exit codes; report failures and skips. Delegate only substantial independent parallel work, never your own verification; keep spawn counts low. Guards block machine-verifiable failures (exit 2); heuristics warn. Guards contain no AI inference; unverifiable state fails closed.
|
|
108
|
+
|
|
109
|
+
## Review bindings
|
|
110
|
+
|
|
111
|
+
One fenced JSON each: `{"reviewBinding":{sha,baseSha,scopeDigest,verdict,findings:[{id,status}]}}` in review; `{"adjudication":{sha,reviewCommentId,operator,source:{kind,ref,quote},findings:[{id,disposition,reason}]}}` in evidence. Use full commit IDs and canonical-plan scopeDigest; status=open/resolved; disposition=accept-risk. Every open finding requires same-review operator acceptance. dev-ship’s README defines source checks. No prose exceptions.
|
|
112
|
+
|
|
113
|
+
Communicate starts/findings/direction plainly; self-contained outcomes include paths and remaining checks. Avoid invented labels/arrows; visualize usefully. Challenge ambiguity with options; never guess silently.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# The loop ladder
|
|
2
|
+
|
|
3
|
+
How to build the red command, cheapest rung that reaches the bug first. The goal is always the same: symptom in, verdict out, seconds per run, no human.
|
|
4
|
+
|
|
5
|
+
1. **Failing test** at whatever seam reaches the bug — unit, integration, or e2e. First choice when the code path is importable.
|
|
6
|
+
2. **Curl / HTTP script** against a running dev server, asserting on status/body — for bugs that live in the request path.
|
|
7
|
+
3. **CLI invocation with a fixture input**, diffing stdout/exit code against known-good — for tools and scripts.
|
|
8
|
+
4. **Headless browser script** (Playwright or equivalent) driving the UI and asserting on DOM, console, or network — when the bug needs a real browser.
|
|
9
|
+
5. **Captured-trace replay** — save a real request/payload/event log once, replay it through the code path in isolation; turns "only happens with production data" into a loop.
|
|
10
|
+
6. **Throwaway harness** — boot the minimal slice of the system (one service, mocked deps) that exercises the path with a single call. Deleted in Phase 6.
|
|
11
|
+
7. **Property/fuzz loop** — for "sometimes wrong output": run hundreds of random inputs and trap the failure mode; the trapped case seeds the minimised repro.
|
|
12
|
+
8. **Bisection harness** — when the bug appeared between two known states (commit, dataset, version): automate "boot at state X, check, report" so `git bisect run` can drive it.
|
|
13
|
+
|
|
14
|
+
## Tightening
|
|
15
|
+
|
|
16
|
+
A loop earns its keep on three axes — make it **faster** (mock the slow dependency, cache the boot), **sharper** (assert the exact symptom, not a proxy), **more deterministic** (pin the clock, the seed, the ordering). A 30-second flaky loop is barely better than none; a 2-second deterministic one changes what's possible.
|
|
17
|
+
|
|
18
|
+
## When no rung works
|
|
19
|
+
|
|
20
|
+
That's a stop, not a license to guess: `handback` with the rungs tried, why each failed, and the specific artifact or access that would unlock one (a HAR of the failing request, server logs around the timestamp, a screen recording, an environment credential). The operator trades one artifact for a loop; nobody trades theories for luck.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Refresh contract — dev-debug
|
|
2
|
+
|
|
3
|
+
Evergreen: this skill asserts no version pins, vendor mechanisms, numeric limits, or dated claims — its content is diagnosis discipline (the phase order, the red-command criterion, the ladder), all versionless. Revisit if a future edit introduces a volatile fact.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dev-implement
|
|
3
|
+
description: Implement an approved GitHub issue end to end without further user input. Use when given an issue to build — "do issue 12", "implement" plus an issue URL or number, "pick up the next ready issue", "go dark on" an issue — when resuming a dead or compacted session's working issue the operator hands over, when returning to apply corrections the user left on a for-operator issue, or for a trivial fix asked directly in chat — one or two files, no new dependency. Not for a new feature or capability asked in chat, or writing or approving issues (dev-intake), planning them (dev-plan), reviewing finished work (dev-review), or creating PRs and merging (dev-ship).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dev-implement
|
|
7
|
+
|
|
8
|
+
Act: implement approved work and return evidence in its issue.
|
|
9
|
+
|
|
10
|
+
One issue/session: preflight → claim → build → verify → review → evidence. The operator reads the result in the issue; PRs and merges are `dev-ship`'s, on the operator's word. The ledger discipline lives in [ledger-and-resume](references/ledger-and-resume.md).
|
|
11
|
+
|
|
12
|
+
Nearest neighbors: `dev-plan` supplies the tasks; `dev-review` judges execution. Route unresolved decisions through `needs-operator`; never guess. dev.md's knobs govern this skill; its `## Architecture` section governs stack-touching choices.
|
|
13
|
+
|
|
14
|
+
## Direct requests — trivial only, tightly bounded
|
|
15
|
+
|
|
16
|
+
When the operator asks in chat for a change, their words are the approval — build, verify, report; no issue needed. The bound is trivial: a behavior change beyond the asked words, a new dependency, or more than 1–2 files routes to `dev-intake` instead. Branch `<type>/<slug>`, in its own worktree like everything else ([worktrees](references/worktrees.md)); the changelog and chronicle rules apply when behavior changes; shipping still goes through dev-ship's words.
|
|
17
|
+
|
|
18
|
+
## Preflight — all must hold, or stop and say which failed
|
|
19
|
+
|
|
20
|
+
- Run the guard first: `node <path-to-this-skill>/scripts/preflight.mjs --issue <n> --me $(gh api user -q .login) --json` (add `--repo <o/r> --dev-md <path>` outside the project root). Exit 2 stops you with its reasons; exit 1 passes with warnings, which go into the ledger. Resume and corrections runs pass `--expect working` / `--expect for-operator`.
|
|
21
|
+
- Scoped intent follows conventions: policy-operator session publisher or verified identical grant relay. Preserve canonical `approvalBindings`; relay `recordBinding` is audit-only. Reconfirm legacy records; preserve preparation/research provenance; reread recovery authority.
|
|
22
|
+
- Then the judgment checks: read the complete brief plus parent issue and milestone; read the brief's touch points in the current code, because they drift between approval and execution — the version-impact line, volatile dependency claims per `dev-architect`'s verify protocol, and a full-plan issue's plan included. A material decision left open — even outside a formal Assumptions section — or reality contradicting brief or plan is a stop: one `handback` comment with the smallest question, `needs-operator`.
|
|
23
|
+
- Resume verified unfinished work only within its original authority, using [ledger-and-resume](references/ledger-and-resume.md): brief → plan → ledger → `git log` → fresh source reconciliation. Restore a missing worktree with `worktree.mjs restore --issue <n> --slug <slug> --write`. Only the operator may abandon a claim, via `node <path-to-this-skill>/scripts/reclaim.mjs --issue <n>` (`working` → `ready`, unassign; a fresh ledger requires `--force`).
|
|
24
|
+
|
|
25
|
+
## Claim
|
|
26
|
+
|
|
27
|
+
One session owns one issue — one claim at a time, because dev-status reads each ledger as one session's heartbeat. Assign yourself and remove any other assignee, swap `ready` → `working`, and cut the branch and its worktree with `node <path-to-this-skill>/scripts/worktree.mjs create --issue <n> --slug <slug> --type <type> --write --json` (epic child: add `--parent <parent-branch>`; the full matrix is [worktrees](references/worktrees.md)). Then create the ledger comment as your first write, recording the worktree path, because its edit time is the claim's only liveness signal and a claim whose session dies before writing it is invisible. Record each task's base sha before starting it. Every label flip this skill makes carries the assignee conventions' Labels table names — a hand-back to `for-operator` assigns the issue's operator and drops the runner, so the operator's notification is GitHub's own and needs no extra tooling.
|
|
28
|
+
|
|
29
|
+
## Build — dark, test-first, checkpointed
|
|
30
|
+
|
|
31
|
+
No questions. Every ledger checkpoint line is also the chat update — one text, two destinations — and in a headless run the issue is the only channel. A `fix:` issue's diagnosis runs under `dev-debug`, whose phases govern the investigation and whose winning suspect feeds the evidence comment. A spike the brief flagged runs first; its result opens the evidence comment. Then work the plan task by task:
|
|
32
|
+
|
|
33
|
+
- **Red before green**, because a test written after the code proves only that the code runs. Write the failing test first — at the seams the brief names, and only there, because a seam the brief did not name is one review cannot judge — watch it fail for the stated reason, implement the minimal code, watch it pass. One slice at a time. The tests-are-real rubric (implementation-coupled, tautological, horizontal-sliced — defined in `dev-review`'s dispatch prompts) applies to your own tests before a reviewer sees them.
|
|
34
|
+
- **Checkpoint the ledger** after every task and tick the matching `[x]` in the plan comment in the same pass — the reference says why both writes matter.
|
|
35
|
+
- **Independent children use the CLI owner.** A registered parent runs declared disjoint groups through `vegafactory children run`, then `children join` under current integration authority. Branches and printed commands never prove execution. The CLI bounds owned processes, verifies acceptance at exact commits and preserves partial joins. Ordinary work stays serial; [worktrees](references/worktrees.md) gives the execution and recovery contract.
|
|
36
|
+
- The scope ratchet is a stop condition: work revealed bigger than the issue's scope class (or plainly exceeding one session) → one `handback` comment proposing the upgrade or split (dev-plan's ratchet rules), `needs-operator`, stop.
|
|
37
|
+
|
|
38
|
+
The approved brief and plan are the scope. Extras you notice go in the evidence comment's Not done / limits line as a follow-up note, not in the diff; an assumption you had to make is stated in the summary. Tests are sized like their neighbours — one focused test per behaviour the brief states, at the seams it names. When the code can just change, change it: no feature flag, compat shim or parallel path for a caller that does not exist, because each is a moving part nobody asked for. Decide routine things yourself and ledger the rulings; a structural choice — a new dependency, table or service — checks `dev-architect`'s trigger discipline first, and a moving part with no named trigger is a stop condition. Hitting any stop condition — the brief's out-of-scope section, dev.md's stop-list, the scope ratchet — ends dark mode with one `handback` comment stating the smallest decision needed, your recommendation attached — and where that decision has options, the handback comment carries the round rendered by `scripts/questions.mjs`, so the operator's reply parses like any other (`references/ask-route.md`).
|
|
39
|
+
|
|
40
|
+
**Honesty over green**: a failing test gets fixed at the root or reported as failing, because weakening a test, an assertion, or acceptance to pass is a cover-up, and cover-ups surface at review with interest.
|
|
41
|
+
|
|
42
|
+
Verified lessons live in the recovery packet, never vendor memory. [Ledger and resume](references/ledger-and-resume.md) defines their owned commands, validation, bounded next-session context, undo and protected-rule limits.
|
|
43
|
+
|
|
44
|
+
## Changelog and chronicle — before hand-back
|
|
45
|
+
|
|
46
|
+
Every behavior-changing branch carries its changelog entry per dev.md's `changelog:` knob and, when dev.md says `chronicle: on`, its story entry — both on the branch, landing atomically with the merge; the per-knob mechanics and the entry's first-line rule live in [changelog-and-chronicle](references/changelog-and-chronicle.md). Docs the brief names as affected get updated in the same branch.
|
|
47
|
+
|
|
48
|
+
## Verify — the gate function
|
|
49
|
+
|
|
50
|
+
Before claiming any status, run the proving command fresh and read its exit code (conventions' verification gate); a subagent's diff or report file is evidence, its say-so is not.
|
|
51
|
+
|
|
52
|
+
- Run what dev.md's `tests:` knob requires; a `risky` issue gets focused security, failure, and recovery checks on top; a `## Verify` runbook means run the app and smoke-check the flows it names. Post-release checks live in `## Ship` and belong to dev-ship.
|
|
53
|
+
- Run the skill-scan guard, unconditionally: `node <path-to-skill-scan>/scripts/skill-scan.mjs --json` — it reads dev.md's `skill-scan:` knob itself and exits 0 when the project authors no skills. Exit 2 blocks the hand-back: fix the finding, or take it to the operator for a justified baseline rule — a suppression needs the operator's word, because a widened rule hides the next finding too. Findings below the blocking bar are the security axis's to triage at review.
|
|
54
|
+
- UI changed and `ui-evidence: playwright` → capture screenshots of the key states and upload each with `node <path-to-this-skill>/scripts/evidence-upload.mjs --repo <o/r> --issue <n> --file <png> --write --json` — it reads dev.md's `evidence-repo:` knob and names the file `<this-repo-name>/<issue-number>/<timestamp>-<name>.png` (dry-run without `--write`; exit 2 says what it refused). Link them in the evidence comment as links, because private-repo images don't render inline. Evidence repo unreachable → name local paths and say so, and the hand-back proceeds, because evidence is a link, not a gate.
|
|
55
|
+
- dev.md's Ship or Verify section is an empty TODO next to visible machinery → finish normally, then suggest re-running dev-setup.
|
|
56
|
+
|
|
57
|
+
## Independent review — invoke dev-review
|
|
58
|
+
|
|
59
|
+
Run `dev-review` per dev.md's `review:` knob — fresh subagent axes by default, cross-agent (Codex↔Claude, announced to the operator) per the knob's mapping; it owns the axes, severities, review comment, bounded fix loop, and adjudication rules. Apply its findings through its loop and re-run the affected checks. Disagree with a finding → adjudicate openly per its rules, because a skipped finding is a decision made in secret. Every target harness spawns the axes (Claude Code subagents, Codex agents, Hermes `delegate_task`); only a headless run that cannot spawn runs the axis briefs itself, labeled as a self-review, because independence is the one thing it lacks.
|
|
60
|
+
|
|
61
|
+
## The evidence comment — exactly one, edited in place
|
|
62
|
+
|
|
63
|
+
```markdown
|
|
64
|
+
<!-- vsk:v1 type=evidence rev=1 branch=<name> sha=<sha7> -->
|
|
65
|
+
## Result (v1)
|
|
66
|
+
**Done:** what changed, in behavior terms
|
|
67
|
+
**Tests:** <command> → <fresh result>
|
|
68
|
+
**Review:** <mode> — <verdict; adjudications and rulings surfaced, in order made>
|
|
69
|
+
**Changelog:** <entry added / none, with reason>
|
|
70
|
+
**Docs:** brief v<n>, plan v<n> — in sync | unchanged since approval
|
|
71
|
+
**UI evidence:** <links> (when applicable)
|
|
72
|
+
**Decision:** <register-format proposals> (only choices passing dev.md's Decisions test)
|
|
73
|
+
**Not done / limits:** the honest list
|
|
74
|
+
Branch: <name> @ <sha7>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The tail's sha stays bare, because GitHub auto-links it once the branch is pushed while a hand-written `/commit/` link 404s until then. The `**Review:**` line is the one home of surfaced rulings: every ledger `Ruling:` appears there, in the order made. Run `node <path-to-this-skill>/scripts/evidence-check.mjs --file <draft> --issue <n> --json` before posting — it checks the draft's shape and, with `--issue`, that the plan comment's `[x]` boxes reflect the ledger's completed tasks; exit 2 means fix, don't post. The evidence comment is the operator's whole read: one line per field, the Not done / limits list complete, and the closing recap repeats it in under 150 words. Post it, swap `working` → `for-operator` with the assignee moved to the operator, and stop; the recap repeats the evidence content rather than replacing it.
|
|
78
|
+
|
|
79
|
+
## Corrections loop — code and docs move together
|
|
80
|
+
|
|
81
|
+
The operator's comments on a `for-operator` issue are the new frontier. A 🚀 reaction from a listed operator on any comment of that issue starts the headless corrections run and nothing else does, because a reaction is the one signal that survives a notification-only read. The correction input is the reacted comment plus every operator comment posted since the hand-back, and the approval rules are unchanged — a reaction is a start signal, never an approval. Corrections reuse the same worktree, restored if gone. Applying a correction is one pass: the code change + the affected brief/plan sections edited to match (revision markers bumped, `Revisions:` line appended) + a ledger line + the evidence comment updated in place — its `sha` to the new head and its `Docs:` line to the new revisions. Run the checks the correction touched. An operator dismissal of a review finding gets appended to `.vegastack/review-known-patterns.md` with its "Still flag if:" clause. Then back to `for-operator`. A correction that changes scope goes back through `needs-operator` and intake's recording rule; any other lands without re-approval.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const meta = {
|
|
2
|
+
name: 'implement-children',
|
|
3
|
+
description: 'Compatibility entry that directs independent children to the verified CLI owner',
|
|
4
|
+
whenToUse: 'An older installation invokes this workflow; use vegafactory children run from the registered parent session.',
|
|
5
|
+
phases: [{ title: 'Build children', detail: 'the verified CLI owns child execution and integration' }],
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// Retain the discoverable name for existing installations. A saved workflow
|
|
9
|
+
// cannot replace durable execution, subscription qualification or source checks.
|
|
10
|
+
export default async function () {
|
|
11
|
+
throw new Error('Use vegafactory children run from the registered parent session; this legacy workflow does not execute children.')
|
|
12
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# The ask route
|
|
2
|
+
|
|
3
|
+
Where a round of questions goes when a skill needs the user. Two surfaces: the harness's question tool, or the issue itself. This file is the one home for the route, the comment shape and the reply grammar; `scripts/questions.mjs` is the deterministic method behind them, and the marker row lives in [conventions](conventions.md).
|
|
4
|
+
|
|
5
|
+
## The route
|
|
6
|
+
|
|
7
|
+
Three steps, in this order, first match wins:
|
|
8
|
+
|
|
9
|
+
1. `VSK_ASK_ROUTE` is set to `issue` or `tool` — the dispatcher and CI set it; any other non-empty value is refused rather than guessed.
|
|
10
|
+
2. This harness and this run have no question tool → `issue`.
|
|
11
|
+
3. The asker is not the issue's operator → `issue`. An unresolved asker or operator is also `issue`.
|
|
12
|
+
|
|
13
|
+
Otherwise the tool. The issue route needs an issue: where none exists yet — dev-intake's interview runs before its issue is created — the skill creates the issue first, at `needs-operator` with the operator assigned and the request as its body, and posts the round to it; the brief is written into that issue once the round is answered. On the tool route the issue is created after approval, as before. Settle it deterministically rather than by judgement:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
node <path-to-this-skill>/scripts/questions.mjs route --tool <name|none> --asker <login> --operator <login> --json
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Which tool each harness has — and the Codex Plan-mode gating on `request_user_input` — is recorded in dev-setup's `references/harness-facts.md` (a backticked path, not a link: this file ships into dev-intake, dev-plan and dev-implement, which do not carry that reference) and not restated here. The operator identity comes from the caller under dev.md's `operators:` knob; the script takes both logins as inputs and never resolves them itself.
|
|
20
|
+
|
|
21
|
+
The bias is deliberate: a round in a comment is always readable by whoever owns the issue, and a round put to the wrong person is not.
|
|
22
|
+
|
|
23
|
+
## The comment
|
|
24
|
+
|
|
25
|
+
One comment per round, marker first, the whole round wrapped in `<questions>` tags so the parser and the model both find it inside a comment that may carry prose around it:
|
|
26
|
+
|
|
27
|
+
```markdown
|
|
28
|
+
<!-- vsk:v1 type=questions rev=1 -->
|
|
29
|
+
## Questions (v1)
|
|
30
|
+
|
|
31
|
+
<questions>
|
|
32
|
+
**Q1.** Where does the reminder queue live?
|
|
33
|
+
- a) A Postgres table
|
|
34
|
+
- b) A Redis list (recommended — Redis is already a dependency)
|
|
35
|
+
|
|
36
|
+
**Q2.** How late may a reminder fire?
|
|
37
|
+
- a) Within the hour (recommended — matches the existing cron cadence)
|
|
38
|
+
- b) Same day
|
|
39
|
+
|
|
40
|
+
Reply with `1: a` per question, or `all recommended`.
|
|
41
|
+
</questions>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
No question, option or reason may carry an HTML comment delimiter or a `questions` block tag: a round can be read back out of a comment anyone may have written, so text that could close the block or forge a marker is refused in both directions. Every question carries at least two options and exactly one recommendation, and every recommendation carries its one-line reason — a round that cannot say which way it leans is a round that has not been thought through, and the renderer refuses it. Options run `a` through `h`. After posting, the label moves to `needs-operator` and the session ends.
|
|
45
|
+
|
|
46
|
+
## Replying
|
|
47
|
+
|
|
48
|
+
Anyone on the issue may answer, in an ordinary comment, one line per question:
|
|
49
|
+
|
|
50
|
+
- `1: b`
|
|
51
|
+
- `2: a — the cron already runs` (trailing prose after the dash is kept)
|
|
52
|
+
- `3: other — a third way` (`other` is accepted for any question)
|
|
53
|
+
- `all recommended` on its own line fills every question not answered explicitly
|
|
54
|
+
|
|
55
|
+
An explicit line always beats `all recommended`. Bulleted lines, a `.` instead of `:`, and upper-case letters all parse. Surrounding prose is ignored; the first answer to a question stands and a repeat is reported. A numbered line whose letter runs straight into prose with no dash (`1: a is wrong, go with b`) is malformed, not an answer of `a` — the parser reports it and the question is re-asked.
|
|
56
|
+
|
|
57
|
+
## Re-asks
|
|
58
|
+
|
|
59
|
+
Parse before asking anything. A later session has no `round.json` on disk, so it reads the round back out of the posted comment — that is what the `<questions>` wrapper is for, and `--round <comment.md>` takes it in place of `--spec`. What comes back is answered questions, still-open questions, and malformed lines. If nothing is open, continue — never re-ask an answered question. If something is open, post a second comment at `rev=<n+1>` carrying only the open questions **at their original numbers**, so `**Q3.**` stays Q3. Earlier `questions` comments are left in place as record. A reply with no answer line at all is malformed, not empty: it gets one re-ask naming the expected shape.
|
|
60
|
+
|
|
61
|
+
## What it is not
|
|
62
|
+
|
|
63
|
+
An answer is not an approval. Any teammate may answer a round; only the operator approves, and approval is still its own `approval` marker comment recording the operator's own words in the `(<username>)` format ([conventions](conventions.md)). A round that is fully answered unblocks the work; it does not move the issue to `ready`.
|
|
64
|
+
|
|
65
|
+
Assignment is not this route's job either — the label moving to `needs-operator` is what puts the issue on the operator.
|
|
66
|
+
|
|
67
|
+
## Commands
|
|
68
|
+
|
|
69
|
+
Save the reply comment to `.vegastack/.tmp/<issue>-<slug>/reply.md` first; the parser reads a file, never a network.
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
node <path-to-this-skill>/scripts/questions.mjs render --spec round.json --rev 1 --json
|
|
73
|
+
node <path-to-this-skill>/scripts/questions.mjs parse --comment reply.md --round asked.md --json
|
|
74
|
+
node <path-to-this-skill>/scripts/questions.mjs re-ask --round asked.md --comment reply.md --rev 2 --json
|
|
75
|
+
node <path-to-this-skill>/scripts/questions.mjs route --tool none --asker <login> --operator <login> --json
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`asked.md` is the posted `questions` comment; `--spec round.json` takes the same round as JSON instead, where the rendering session still has it. A spec is `{ "questions": [ { "text": "…", "options": [ { "letter": "a", "text": "…" }, { "letter": "b", "text": "…", "recommended": true, "reason": "…" } ] } ] }`.
|
|
79
|
+
|
|
80
|
+
Exit codes: 0 pass · 1 answers still open or malformed, and for `re-ask` nothing left to ask · 2 refusal or usage error.
|