Files
2026-05-27 23:29:53 +01:00

72 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Tasks — `@suaveplan/api-secrets-vault`
## 0. Pre-flight (non-negotiable)
- [x] 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)
- [x] 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.
- [x] 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.
## 1. Spec authoring
- [x] 1.1 Read design doc (§3, §5, §13.2)
- [x] 1.2 Read `openspec/AGENTS.md` Sections 13 and 14
- [x] 1.3 Draft `proposal.md`
- [x] 1.4 Draft `specs/api-secrets-vault/spec.md`
- [x] 1.5 Every requirement carries `**Verified by:**`
## 2. Implementation
- [x] 2.1 Scaffold `packages/api-stack/api/api-secrets-vault/`
- [x] 2.2 `src/adapter/` — `createVaultSecretsAdapter`
- [x] 2.3 `src/allowlist/` — per-plugin allowlist enforcement
- [x] 2.4 `src/watcher/` — vault `secret.updated` → bus `secret.changed`
- [x] 2.5 `src/error-codes/error-codes.ts` (feature-folder per CLAUDE.md "No flat modules at src/ root")
- [x] 2.6 `src/index.ts` — explicit named re-exports + side-effect `error-codes` import
- [x] 2.7 `src/from-vault/` — `fromVault(vault: Vault)` bridge to a real `@suaveplan/vault.Vault`
- [x] 2.8 `src/otel/` — `getSecretsVaultInstruments` + `api.secrets.reads_total{backend="vault"}` counter
- [x] 2.9 `src/types/` — structural `VaultSecretsBackend` contract
## 3. Tests
- [x] 3.1 `src/adapter/adapter.test.ts`
- [x] 3.2 `src/adapter/adapter.spec-conformance.test.ts` — passes `runSecretsConformance`
- [x] 3.3 `src/watcher/watcher.test.ts`
- [x] 3.4 `tests/dep-graph.test.ts`
- [x] 3.5 Every `it(...)` carries `{ timeout: 5000 }` (30000 for crypto-heavy unlock; 120000 for the shared `beforeAll`)
- [x] 3.6 `src/allowlist/allowlist.test.ts` — INVALID_OPTIONS / NOT_ALLOWED arms
- [x] 3.7 `src/error-codes/error-codes.test.ts` — registry shape + class identity
- [x] 3.8 `src/otel/instruments.test.ts` — counter emission
- [x] 3.9 `src/from-vault/from-vault.test.ts` — WRITE_FAILED error wrapping (structural shim around `vault.items`; integration suite drives the bridge against the real Vault)
- [x] 3.10 `tests/integration.test.ts` — REAL `@suaveplan/vault.Vault` end-to-end (shared `beforeAll` unlock + OWASP-min Argon2id params + separate locked-vault describe to isolate `zeroizeAll()`)
## 4. Documentation
- [x] 4.1 Sibling `.md` per implementation `.ts` (`docs:check` → 7/7 = 100%)
- [x] 4.2 `README.md` `## Modules`
- [x] 4.3 Update `CLAUDE.md` package listing (orchestrator)
## 5. Pre-archive verification (the 5-gate triple)
- [x] 5.1 `bun run check` — biome clean (no fixes applied on rerun)
- [x] 5.2 `bunx turbo lint typecheck test --filter=@suaveplan/api-secrets-vault` — green
- [x] 5.3 `bunx turbo test:coverage --filter=@suaveplan/api-secrets-vault` — **100/100/100/100** across adapter, allowlist, error-codes, from-vault, otel, watcher
- [x] 5.4 `bun scripts/openspec-conformance.ts packages/api-stack/api/api-secrets-vault` — **PASS (0 error, 0 warn, 0 info)**
- [x] 5.5 `bunx turbo build --filter=@suaveplan/api-secrets-vault` — vite build clean, dts emitted
## 6. Pre-archive 7-row checklist
- [x] 6.1 Generics threaded — `SuaveplanError<SecretsVaultCode>` parameterises throwables; no `unknown` leaks in public d.ts (conformance verified)
- [x] 6.2 Zod schemas wired at boundaries — `allowlist`, `adapter`, `watcher` all validate construction options with `safeParse` and raise `SECRETS_VAULT.INVALID_OPTIONS` on failure
- [x] 6.3 Every `SECRETS_VAULT.*` code thrown by a production path — NOT_FOUND, NOT_ALLOWED, VAULT_LOCKED, VAULT_UNAVAILABLE, WRITE_FAILED, INVALID_OPTIONS all asserted in tests against real throw sites
- [x] 6.4 Strict-mode: locked vault raises `VAULT_LOCKED` from BOTH `get` and `require`; no plaintext fallback (covered by `adapter.test.ts` + integration `locked-vault` describe)
- [x] 6.5 OTel `api.secrets.reads_total{backend="vault"}` asserted — `adapter.test.ts::"get returns stored value AND increments reads_total"` flushes the in-memory exporter and finds the metric
- [x] 6.6 Lifecycle dedup — adapter `dispose()` idempotent (3× call test); watcher subscription single (`listenerCount === 1` assertion); watcher dispose idempotent + survives lazy backend unsubscribes (in-listener disposed-flag guard)
- [x] 6.7 No retroactive tick — every box ticked above reflects evidence in this branch
## 7. Archive
- [x] 7.1 Fold spec delta into `openspec/specs/api-secrets-vault/spec.md`
- [x] 7.2 Move folder to archive
- [x] 7.3 Tick `8.14` in umbrella tasks
- [x] 7.4 Refresh `MANIFEST.md`