Initial Commit
This commit is contained in:
22
openspec/templates/README.md
Normal file
22
openspec/templates/README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# OpenSpec change templates
|
||||
|
||||
Copy these files when starting a new change. Do **not** author from scratch — every template field exists because skipping it has cost the project a real incident.
|
||||
|
||||
## When to use
|
||||
|
||||
- New package — copy all three.
|
||||
- New requirement on an existing package — copy `spec-delta.md`, write a single `## ADDED Requirements` section, and add the `proposal.md` + `tasks.md`.
|
||||
- Spec-conformance audit (no behavior change) — copy `proposal.md` and use the `*-spec-conformance` pattern; the spec delta is purely additive `**Verified by:**` lines under `## MODIFIED Requirements`.
|
||||
|
||||
## Files
|
||||
|
||||
- `proposal.md` — why, what, source mapping (mandatory for migrated packages), out-of-scope.
|
||||
- `tasks.md` — concrete checklist. Every box must reflect work actually done in this change. No retroactive ticking.
|
||||
- `spec-delta.md` — copy into `specs/<cap>/spec.md`. Every requirement carries a `**Verified by:**` line at authoring time.
|
||||
|
||||
## Hard rules
|
||||
|
||||
1. Read `../suaveplan/enterprise/<pkg>.md` before opening the templates if the package is migrated. (See AGENTS.md Section 14.)
|
||||
2. Every requirement in the spec delta has a `**Verified by:**` line. (See AGENTS.md Section 13.)
|
||||
3. Every requirement that derives from `enterprise/<pkg>.md` cites a line range in `proposal.md` `## Source mapping`. Requirements with no source must be listed in the "no source line" table with a justification.
|
||||
4. `tasks.md` checkboxes are ticked only when the work is genuinely done.
|
||||
153
openspec/templates/missing-specs-runbook.md
Normal file
153
openspec/templates/missing-specs-runbook.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# Missing-spec runbook
|
||||
|
||||
24 packages either lack a folded `openspec/specs/<cap>/spec.md` entirely or have one that the conformance script cannot find for them. This runbook groups them by remediation type so an agent can work them in dependency order without re-discovering the categorisation.
|
||||
|
||||
For every group: read `openspec/AGENTS.md` Sections 13 and 14 first. Use templates in `openspec/templates/`. The 4-gate triple in `CLAUDE.md` "Pre-publish gate" applies.
|
||||
|
||||
---
|
||||
|
||||
## Group 1 — Fold existing archive specs (4 packages)
|
||||
|
||||
These packages have specs in `openspec/archive/2026-04-18-enterprise-crypto-family/specs/<cap>/` that were never folded into `openspec/specs/`. **Mechanical archival cleanup** — no spec writing needed.
|
||||
|
||||
| Package | Archive cap → fold to |
|
||||
|---|---|
|
||||
| crypto-browser | `crypto-browser-engine` → `openspec/specs/crypto-browser-engine/spec.md` |
|
||||
| crypto-keys | `crypto-keys` → `openspec/specs/crypto-keys/spec.md` |
|
||||
| crypto-sodium | `crypto-sodium-engine` → `openspec/specs/crypto-sodium-engine/spec.md` |
|
||||
| crypto-vault | `crypto-vault` → `openspec/specs/crypto-vault/spec.md` |
|
||||
|
||||
### Per-package steps
|
||||
|
||||
1. Copy `openspec/archive/2026-04-18-enterprise-crypto-family/specs/<cap>/spec.md` to `openspec/specs/<cap>/spec.md`.
|
||||
2. Verify the spec uses `### Requirement: <name>` heading style; rewrite if not.
|
||||
3. Add `**Verified by:**` lines under every requirement. The implementations and tests already exist in `packages/crypto/<pkg>/`. Map scenarios to `it(...)` titles.
|
||||
4. Confirm `openspec/package-cap-map.yml` has the entry (already populated for crypto-browser and crypto-sodium).
|
||||
5. Run `bun scripts/openspec-conformance.ts @suaveplan/<pkg>` — must be 0 errors. Plus the standard 4-gate triple.
|
||||
6. No new OpenSpec change folder needed (this is a fold, not a contract change). Note the fold in a single `chore: fold archived crypto-family specs` commit.
|
||||
|
||||
---
|
||||
|
||||
## Group 2 — Package→cap mapping only (2 packages)
|
||||
|
||||
| Package | Reason script missed it |
|
||||
|---|---|
|
||||
| random | Owns 4 caps (`random-utilities`, `seeded-prng`, `noise-functions`, `statistical-distributions`) — script defaulted to single-cap lookup |
|
||||
| readline | Specified inside `cli` cap — script defaulted to looking for a `readline` cap |
|
||||
|
||||
### Per-package steps
|
||||
|
||||
1. Confirm `openspec/package-cap-map.yml` lists the package's caps (both already added).
|
||||
2. Confirm the conformance script honors the YAML (see "Script integration" below).
|
||||
3. Run conformance — should now find the spec.
|
||||
4. If any of the mapped caps lack `**Verified by:**` lines, treat as Group 5 (annotation only) for that cap.
|
||||
|
||||
---
|
||||
|
||||
## Group 3 — Brand-new specs from enterprise source (15 packages)
|
||||
|
||||
Each package has a canonical source at `../suaveplan/enterprise/<pkg>.md`. Per AGENTS.md Section 14, every requirement must cite a line range in the source.
|
||||
|
||||
| Package | Genesis path | Enterprise source |
|
||||
|---|---|---|
|
||||
| db | `packages/database/db/` | `../suaveplan/enterprise/db.md` |
|
||||
| db-sqlite | `packages/database/db-sqlite/` | `../suaveplan/enterprise/db-sqlite.md` |
|
||||
| storage | `packages/storage/storage/` | `../suaveplan/enterprise/storage.md` |
|
||||
| streams | `packages/flow/streams/` | `../suaveplan/enterprise/streams.md` |
|
||||
| qrcode | `packages/barcode/qrcode/` | `../suaveplan/enterprise/qrcode.md` |
|
||||
| barcode | `packages/barcode/barcode/` | `../suaveplan/enterprise/barcode.md` |
|
||||
| api-schemas | `packages/api/api-schemas/` | `../suaveplan/enterprise/api-schemas.md` |
|
||||
| fsm | `packages/flow/fsm/` | `../suaveplan/enterprise/fsm.md` |
|
||||
| domain-normalizer | `packages/emails/domain-normalizer/` | `../suaveplan/enterprise/domain-normalizer.md` |
|
||||
| suppression | `packages/emails/suppression/` | `../suaveplan/enterprise/suppression.md` |
|
||||
| compress-image | `packages/image/compress-image/` | `../suaveplan/enterprise/compress-image.md` |
|
||||
| metadata | `packages/audio/metadata/` | `../suaveplan/enterprise/metadata.md` |
|
||||
| diff | `packages/data/diff/` | `../suaveplan/enterprise/diff.md` |
|
||||
| password-formats | `packages/crypto/password-formats/` | `../suaveplan/enterprise/password-formats.md` |
|
||||
| security-codes | `packages/platform/security-codes/` | `../suaveplan/enterprise/security-codes.md` |
|
||||
|
||||
### Per-package steps
|
||||
|
||||
1. Read `../suaveplan/enterprise/<pkg>.md` end-to-end.
|
||||
2. Read the genesis implementation under `packages/<plugin>/<pkg>/src/`.
|
||||
3. Read existing tests to know what scenarios are already pinned.
|
||||
4. Create `openspec/changes/<pkg>-spec-init/` from `openspec/templates/`:
|
||||
- `proposal.md` with `## Source mapping` table covering every requirement (line ranges in enterprise source) and a `## Requirements with no source line` table for genesis-only additions (e.g. 100% coverage policy).
|
||||
- `tasks.md` with the standard 7-section structure.
|
||||
- `specs/<cap>/spec.md` with `### Requirement:` blocks. Every requirement carries `**Verified by:**` at authoring time.
|
||||
5. If the spec exposes drift (e.g. enterprise source mandates an OTel histogram the impl doesn't emit), **fix inline** — do not defer. Standard from prior conformance audits.
|
||||
6. Run the 4-gate triple:
|
||||
- `bunx turbo lint typecheck test --filter=@suaveplan/<pkg>`
|
||||
- `bunx turbo test:coverage --filter=@suaveplan/<pkg>` — 100/100/100/100
|
||||
- `bun scripts/openspec-conformance.ts @suaveplan/<pkg>` — 0 errors
|
||||
- `bunx turbo build --filter=@suaveplan/<pkg>`
|
||||
7. Fold spec delta into `openspec/specs/<cap>/spec.md`. Move change folder to `openspec/archive/<yyyy-mm-dd>-<change-id>/`.
|
||||
|
||||
### Suggested order (foundation first)
|
||||
|
||||
1. db (substrate for db-sqlite, surrealdb, etc.)
|
||||
2. db-sqlite (depends on db)
|
||||
3. streams (substrate for many media/data packages)
|
||||
4. storage (depends on streams)
|
||||
5. fsm (control-flow leaf with broad fan-in)
|
||||
6. diff (leaf, used by undo/sync packages)
|
||||
7. domain-normalizer, suppression, security-codes (leaves)
|
||||
8. qrcode, barcode (codes leaves)
|
||||
9. api-schemas (depends on validation)
|
||||
10. compress-image, metadata (media leaves)
|
||||
11. password-formats (security leaf)
|
||||
|
||||
---
|
||||
|
||||
## Group 4 — Genesis-original specs (no enterprise source) (7 packages)
|
||||
|
||||
These have no `../suaveplan/enterprise/<pkg>.md` and need specs derived from the implementation.
|
||||
|
||||
| Package | Genesis path |
|
||||
|---|---|
|
||||
| testing-integration | `packages/testing/testing-integration/` |
|
||||
| testing-integration-garage-s3 | `packages/testing/testing-integration-garage-s3/` |
|
||||
| testing-integration-mailpit | `packages/testing/testing-integration-mailpit/` |
|
||||
| testing-integration-postgres | `packages/testing/testing-integration-postgres/` |
|
||||
| testing-integration-redis | `packages/testing/testing-integration-redis/` |
|
||||
| testing-integration-surrealdb | `packages/testing/testing-integration-surrealdb/` |
|
||||
| testing-integration-typesense | `packages/testing/testing-integration-typesense/` |
|
||||
|
||||
### Per-package steps
|
||||
|
||||
1. Read the genesis implementation under `packages/testing/<pkg>/src/`.
|
||||
2. Read the package's `CLAUDE.md` blurb (in `packages` listing) for intent.
|
||||
3. Create `openspec/changes/<pkg>-spec-init/` from templates.
|
||||
4. In `proposal.md`:
|
||||
- **`## Source mapping` is required even with no source.** Every requirement appears in the second table (`## Requirements with no source line`) with a justification — typically "Derived from genesis-original implementation; no enterprise/<pkg>.md predecessor."
|
||||
- In a `## Design rationale` section (add to the template if absent), explain why this is genesis-original and what design decisions shape the contract.
|
||||
5. Draft `specs/testing-integration*/spec.md` with `### Requirement:` blocks for every observable behavior. Every requirement carries `**Verified by:**`.
|
||||
6. Run the 4-gate triple. Fold and archive.
|
||||
|
||||
### Suggested order
|
||||
|
||||
1. `testing-integration` (core — `ServiceFixture<TConfig>`, `TestEnvironment`, `HealthPoller`, `skipIfUnavailable`).
|
||||
2. The 6 adapters in any order (they depend on the core but not on each other).
|
||||
|
||||
---
|
||||
|
||||
## Script integration — package-cap-map.yml lookup
|
||||
|
||||
The conformance script (`scripts/openspec-conformance.ts`) currently searches for `openspec/specs/<bare>/spec.md` where `<bare>` is the package's short name. To honour `openspec/package-cap-map.yml`:
|
||||
|
||||
1. At script start, load `openspec/package-cap-map.yml` once. Parse to a `Record<string, string[]>`.
|
||||
2. In the per-package routine, look up `<bare>` in the map. Default to `[<bare>]`.
|
||||
3. For each cap in the resolved list:
|
||||
- Check `openspec/specs/<cap>/spec.md` exists and parses.
|
||||
- Run all spec-side checks (Verified-by lines, retroactive ticking, etc.) against that file.
|
||||
- Aggregate findings under the same package report.
|
||||
4. For change-folder matching (`openspec/changes/*/specs/<cap>/spec.md`), also iterate the resolved cap list rather than hard-coding `<bare>`.
|
||||
|
||||
This is a small refactor — the existing `findRelatedChangeFolders` function already reads `**Package**:` frontmatter; it just needs to also accept any of the package's caps when matching `specs/<cap>/`.
|
||||
|
||||
---
|
||||
|
||||
## Out of scope for the runbook
|
||||
|
||||
- The 11 packages reclassified by the Batch C agent as "spec.md missing entirely" (qrcode, barcode, api-schemas, fsm, domain-normalizer, suppression, compress-image, metadata, diff, password-formats, security-codes) are now in **Group 3** of this runbook — they have enterprise source. The runbook supersedes the prior reclassification.
|
||||
- `enterprise-package-migration` skill in `.claude/skills/` already covers Group 3 + 4 workflows. This runbook is the *triage list*; the skill is the *execution playbook*.
|
||||
51
openspec/templates/proposal.md
Normal file
51
openspec/templates/proposal.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# <Change title>
|
||||
|
||||
**Package**: `@suaveplan/<pkg>`
|
||||
**Status**: PROPOSED
|
||||
**Type**: <new-package | feature | bug-fix | spec-conformance | refactor>
|
||||
|
||||
## Why
|
||||
|
||||
<2–4 sentences explaining the motivation. What problem does this solve? What broke or is broken without it? Cite incidents, audits, or user requests.>
|
||||
|
||||
## What changes
|
||||
|
||||
<Bullet list of every public-surface change. New exports, new behaviors, modified signatures, removed APIs. Be exhaustive — anything not listed here will be missed at review time.>
|
||||
|
||||
- ADDED: `<symbol>` — <one-line description>
|
||||
- MODIFIED: `<symbol>` — <what changed>
|
||||
- REMOVED: `<symbol>` — <why; link to deprecation notice>
|
||||
|
||||
## Out of scope
|
||||
|
||||
<Bullet list of things explicitly NOT in this change, with reason. This prevents scope drift and gives reviewers a clear boundary.>
|
||||
|
||||
- <thing> — <why deferred>
|
||||
|
||||
## Source mapping
|
||||
|
||||
> **REQUIRED for any package migrated from `../suaveplan/`.** Delete this entire section if the package is genesis-original (no `enterprise/<pkg>.md` exists).
|
||||
|
||||
This change derives from `../suaveplan/enterprise/<pkg>.md`.
|
||||
|
||||
| Requirement | Source lines | Notes |
|
||||
|---|---|---|
|
||||
| <requirement name from spec-delta> | L<start>-L<end> | <verbatim / reworded / extended> |
|
||||
|
||||
### Requirements with no source line
|
||||
|
||||
| Requirement | Justification |
|
||||
|---|---|
|
||||
| <requirement name> | <why it's added in genesis above the source baseline> |
|
||||
|
||||
## Verification approach
|
||||
|
||||
<How will every requirement be verified? List the test files that will exist after this change ships, grouped by requirement. Every requirement in the spec delta must have a `**Verified by:**` line pointing at concrete `it(...)` titles in these files.>
|
||||
|
||||
- `src/<feature>/<feature>.test.ts` — covers requirements <names>
|
||||
- `src/<feature>/<feature>.spec-conformance.test.ts` — pins type-level / observability / strict-mode scenarios for requirements <names>
|
||||
- `tests/dep-graph.test.ts` — pins dependency invariants
|
||||
|
||||
## Migration impact
|
||||
|
||||
<For changes that modify or remove existing public surface: list every consumer in the monorepo (`grep` `@suaveplan/<pkg>` in other packages) and how they're affected. For new packages or pure additions, write "None — additive only.">
|
||||
61
openspec/templates/spec-delta.md
Normal file
61
openspec/templates/spec-delta.md
Normal file
@@ -0,0 +1,61 @@
|
||||
<!-- markdownlint-disable MD024 -->
|
||||
|
||||
# Capability Spec Delta: <capability> (<change-id>)
|
||||
|
||||
**Package**: `@suaveplan/<pkg>`
|
||||
**Status**: PROPOSED
|
||||
|
||||
> Every requirement below carries a `**Verified by:**` line at authoring time. No exceptions. (See `openspec/AGENTS.md` Section 13.)
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: <Name in plain English>
|
||||
|
||||
The package SHALL <one-sentence behavior contract>. <Optional: one or two sentences of context — what callers can rely on, what they can't.>
|
||||
|
||||
#### Scenario: <one observable behavior>
|
||||
|
||||
- **WHEN** <precondition / call site>
|
||||
- **THEN** <observable outcome — a thing a test can assert>
|
||||
|
||||
#### Scenario: <another observable behavior>
|
||||
|
||||
- **WHEN** <…>
|
||||
- **THEN** <…>
|
||||
|
||||
**Verified by:** `src/<feature>/<feature>.test.ts::"<exact it title>"` AND `src/<feature>/<feature>.spec-conformance.test.ts::"<exact it title>"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: <Next requirement>
|
||||
|
||||
…
|
||||
|
||||
**Verified by:** `<file>::"<title>"` AND `<file>::"<title>"`
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
> Use this section when a requirement already exists in `openspec/specs/<cap>/spec.md` and you are changing its body or scenarios. Quote the full new requirement body — reviewers compare it against the existing folded spec.
|
||||
|
||||
### Requirement: <Existing name, unchanged or reworded>
|
||||
|
||||
<New body.>
|
||||
|
||||
#### Scenario: <new or modified scenario>
|
||||
|
||||
- **WHEN** <…>
|
||||
- **THEN** <…>
|
||||
|
||||
**Verified by:** `<file>::"<title>"`
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
> Use this section when a requirement is being deleted. Cite the deprecation notice or the change that replaces it.
|
||||
|
||||
### Requirement: <Name being removed>
|
||||
|
||||
**Reason:** <why; link to replacement change-id if any>
|
||||
|
||||
**Migration:** <what callers should do>
|
||||
|
||||
<!-- markdownlint-enable MD024 -->
|
||||
62
openspec/templates/tasks.md
Normal file
62
openspec/templates/tasks.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Tasks — <change title>
|
||||
|
||||
> Every checkbox MUST reflect work actually done in this change. Do not retroactively tick boxes for work that was already in main when this change opened. Do not tick a box for a test that doesn't exist or doesn't pin the requirement it claims to verify. Retroactive ticking is the failure mode this template guards against.
|
||||
|
||||
## 0. Pre-flight (non-negotiable)
|
||||
|
||||
- [ ] 0.1 Confirm clean working tree (`git status` reports nothing) and no in-flight worktrees with uncommitted work (`git worktree list` then `git status` in each)
|
||||
- [ ] 0.2 If any worktrees exist under `.claude/worktrees/`, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (`git worktree remove`) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
|
||||
- [ ] 0.3 Confirm the package set in `MANIFEST.md` matches `find packages -maxdepth 3 -name package.json` count. Drift here means a prior change archived without regenerating the manifest.
|
||||
- [ ] 0.4 §0a Sync (worktree-isolated agents ONLY): run `git merge-base --is-ancestor <EXPECTED_BASE> HEAD` against the orchestrator-supplied SHA. If false, `git fetch /home/paul/web/genesis genesis && git merge FETCH_HEAD --no-edit`. Then re-verify. Empirically the harness forks worktrees from a stale ref — this gate prevents Wave-N-blind work that re-invents interfaces from earlier merges.
|
||||
|
||||
## 1. Spec authoring
|
||||
|
||||
- [ ] 1.1 Read `../suaveplan/enterprise/<pkg>.md` end-to-end (skip if not a migration)
|
||||
- [ ] 1.2 Read `openspec/specs/<cap>/spec.md` (if it exists)
|
||||
- [ ] 1.3 Read `openspec/AGENTS.md` Sections 13 and 14
|
||||
- [ ] 1.4 Draft `proposal.md` from `openspec/templates/proposal.md`
|
||||
- [ ] 1.5 Fill in `## Source mapping` table — every requirement cites a line range OR appears in the "no source line" table with justification
|
||||
- [ ] 1.6 Draft `specs/<cap>/spec.md` from `openspec/templates/spec-delta.md`
|
||||
- [ ] 1.7 Every requirement in the spec delta carries a `**Verified by:**` line naming concrete `it(...)` titles
|
||||
|
||||
## 2. Implementation
|
||||
|
||||
- [ ] 2.1 <implementation task 1>
|
||||
- [ ] 2.2 <implementation task 2>
|
||||
|
||||
## 3. Tests
|
||||
|
||||
- [ ] 3.1 Unit tests at `src/<feature>/<feature>.test.ts` covering every scenario
|
||||
- [ ] 3.2 Spec-conformance tests at `src/<feature>/<feature>.spec-conformance.test.ts` pinning type-level / observability / strict-mode / lifecycle scenarios
|
||||
- [ ] 3.3 Integration / contract / property tests where the spec demands them
|
||||
- [ ] 3.4 Every `it(...)` carries `{ timeout: 5000 }` (or 30000 for genuinely async)
|
||||
|
||||
## 4. Documentation
|
||||
|
||||
- [ ] 4.1 Sibling `.md` for every implementation `.ts` (≥200 words, basic + advanced examples, full API reference)
|
||||
- [ ] 4.2 README links every co-located `.md` under `## Modules`
|
||||
- [ ] 4.3 Update `CLAUDE.md` package listing if this is a new package or removes a package
|
||||
|
||||
## 5. Pre-archive verification (the 5-gate triple)
|
||||
|
||||
- [ ] 5.1 `bun run check` — Biome 0 errors / 0 warnings / 0 info across the whole monorepo (catches stray suppressions and schema-version drift)
|
||||
- [ ] 5.2 `bunx turbo lint typecheck test --filter=@suaveplan/<pkg>` — green
|
||||
- [ ] 5.3 `bunx turbo test:coverage --filter=@suaveplan/<pkg>` — 100/100/100/100
|
||||
- [ ] 5.4 `bun scripts/openspec-conformance.ts @suaveplan/<pkg>` — exit 0, no `error` findings
|
||||
- [ ] 5.5 `bunx turbo build --filter=@suaveplan/<pkg>` — green
|
||||
|
||||
## 6. Pre-archive 7-row checklist (AGENTS.md Section 13)
|
||||
|
||||
- [ ] 6.1 Generics threaded; `expectTypeOf` assertions on every literal-type claim
|
||||
- [ ] 6.2 Zod schemas wired at every declared boundary
|
||||
- [ ] 6.3 Every error code in `error-codes.ts` thrown by at least one production path
|
||||
- [ ] 6.4 Strict-mode behaviors tested both on and off
|
||||
- [ ] 6.5 OTel instruments emitted from production paths and asserted with a real in-memory `MeterProvider`
|
||||
- [ ] 6.6 Lifecycle dedup tested where claimed (in-flight Promise, idempotent set/load)
|
||||
- [ ] 6.7 No retroactive tick — every box above reflects work done in this change
|
||||
|
||||
## 7. Archive
|
||||
|
||||
- [ ] 7.1 Fold spec delta into `openspec/specs/<cap>/spec.md`
|
||||
- [ ] 7.2 Move `openspec/changes/<change-id>/` → `openspec/archive/<yyyy-mm-dd>-<change-id>/`
|
||||
- [ ] 7.3 Refresh `MANIFEST.md` if package set or deps changed
|
||||
Reference in New Issue
Block a user