docs: strip dead docs/superpowers/ refs across ADRs + guides + glossary
The docs/superpowers/{specs,plans}/ directory was archived to .archive/
in an earlier session (and .archive/ is gitignored). Every md link
into that path is now a broken reference for anyone consuming the
template fresh.
Stripped:
- ADR-011: **Spec:** header line
- ADR-015: **Spec:** + **Plan:** header lines
- ADR-016: **Spec:** + **Plan:** header lines + footer "Spec —"
bullet (the design rationale is captured in the ADR body itself)
- ADR-017: **Spec:** + **Plan:** header lines
- ADR-018: **Spec:** + **Plan:** header lines
- guides/realtime.md: inline "the full spec" link + footer
[Spec] entry (folded its description into the ADR-016 entry)
- guides/events-and-jobs.md: inline "the full spec" link
- architecture/vertical-feature-spec.md: stale "Deleted" subsection
referencing docs/superpowers/plans/*
Updated:
- glossary.md "PRD" entry: clarified status flow now matches the
shipped pnpm work prd-ship lifecycle (draft -> in-review ->
approved -> shipped); removed the parenthetical pointing at
docs/superpowers/specs/ as a definition of "spec"
- glossary.md "spec" flagged-ambiguity: rewritten to reflect that
durable design lives in ADRs (docs/decisions/adr-NNN-*.md) and
implementation seeds live in PRDs (docs/work/prds/*.prd.md) —
"spec" should be avoided in this template
Preserved (legitimate refs to the SuperPowers plugin, not the dir):
- agent-first-workflow-and-conformance.md mentions of
`superpowers:brainstorming` — these reference the external
plugin skill, not a file in the repo
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -606,11 +606,7 @@ Identity presenters do not require R27/R28 tests. Void-output controllers (e.g.,
|
||||
- `docs/guides/adding-a-feature.md` — new recipe (small feature + mature feature, per addendum v5)
|
||||
- `docs/guides/testing-strategy.md` — new placement table
|
||||
|
||||
### 11.4 Deleted
|
||||
|
||||
- `docs/superpowers/plans/*` — 6 stale plan files from previous architecture
|
||||
|
||||
### 11.5 AGENTS.md
|
||||
### 11.4 AGENTS.md
|
||||
|
||||
All rewritten:
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
**Status:** Accepted
|
||||
**Date:** 2026-05-05
|
||||
**Supersedes:** none
|
||||
**Spec:** docs/superpowers/specs/2026-05-05-tdd-foundation-design.md
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ core-events is scaffolded. `IJobQueue` (in `@repo/core-shared/jobs`) and the
|
||||
`gen event`/`gen job` generators remain fully functional without core-events.
|
||||
|
||||
**Date:** 2026-05-08
|
||||
**Spec:** docs/superpowers/specs/2026-05-08-events-and-jobs-design.md
|
||||
**Plan:** docs/superpowers/plans/2026-05-08-events-and-jobs.md
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
**Status:** Optional — scaffold via `pnpm turbo gen core-package realtime`. The package is not in the default template; this ADR documents the design that the generator emits.
|
||||
**Date:** 2026-05-08
|
||||
**Spec:** docs/superpowers/specs/2026-05-08-realtime-design.md
|
||||
**Plan:** docs/superpowers/plans/2026-05-08-realtime-layer.md
|
||||
|
||||
## Context
|
||||
|
||||
@@ -103,4 +101,3 @@ Items surfaced by the final branch review that were intentionally not landed in
|
||||
- ADR-010 — Turborepo boundaries
|
||||
- ADR-014 — Instrumentation & Sentry logging (span+capture sandwich reused for realtime handlers)
|
||||
- ADR-015 — Cross-feature events and background jobs (`IEventBus` reused as the bridge source)
|
||||
- Spec — docs/superpowers/specs/2026-05-08-realtime-design.md
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
**Status:** Accepted
|
||||
**Date:** 2026-05-11
|
||||
**Spec:** docs/superpowers/specs/2026-05-11-opentelemetry-migration-design.md
|
||||
**Plan:** docs/superpowers/plans/2026-05-11-opentelemetry-migration.md
|
||||
**Supersedes (impl section):** ADR-014
|
||||
|
||||
## Context
|
||||
@@ -37,12 +35,14 @@ This ADR migrates the substrate to OpenTelemetry: code emits OTel spans, logs, a
|
||||
## Consequences
|
||||
|
||||
**Positive:**
|
||||
|
||||
- Vendor swaps are exporter swaps. Adding Honeycomb / Datadog / Grafana Cloud / Tempo is just adding their exporter alongside Sentry's.
|
||||
- Auto-instrumentations (HTTP, undici, pg) reduce manual span boilerplate.
|
||||
- New `IMetrics` signal available; metrics call sites can land per-feature opportunistically.
|
||||
- PII scrubbing is vendor-neutral — applies before any exporter sees the data.
|
||||
|
||||
**Negative:**
|
||||
|
||||
- Sentry-native error UX is slightly degraded (errors arrive as OTel log records instead of native Sentry events). Acceptable per vendor-neutrality goal.
|
||||
- Breadcrumb semantics shift from buffered cross-span to per-span events. Acceptable.
|
||||
- Browser is still Sentry-direct — observability stack is asymmetric server vs. browser until a future browser migration.
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
**Status:** Accepted
|
||||
**Date:** 2026-05-11
|
||||
**Spec:** docs/superpowers/specs/2026-05-11-audit-and-compliance-design.md
|
||||
**Plan:** docs/superpowers/plans/2026-05-11-audit-and-compliance.md
|
||||
**Companion guide:** docs/guides/audit-and-compliance.md
|
||||
|
||||
## Context
|
||||
@@ -62,12 +60,14 @@ audit data is lossless and long-retention with privileged erasure.
|
||||
## Consequences
|
||||
|
||||
**Positive:**
|
||||
|
||||
- DPA-compliant baseline ships with the optional package.
|
||||
- Vendor-neutral via stdout JSON + log shipper; any aggregator works.
|
||||
- OTel correlation gives compliance auditors one-click pivot to traces.
|
||||
- Type-enforced exclusion of "what not to log" prevents categories of mistakes.
|
||||
|
||||
**Negative:**
|
||||
|
||||
- Boilerplate at every record() call site (IP/UA explicit).
|
||||
- core-audit ↔ auth coupling for the user-collection hook is awkward
|
||||
(manual install via generator next-steps).
|
||||
|
||||
@@ -204,8 +204,8 @@ The `bindAll()` decision that selects OTel+Sentry instrumentation when a DSN env
|
||||
## Workflow
|
||||
|
||||
**PRD**:
|
||||
The top-level requirements doc at `docs/work/prds/<date>-<slug>.prd.md`. Status flows `draft → in-review → approved → superseded`. `pnpm work decompose` refuses to run on `draft`.
|
||||
_Avoid:_ spec (use "spec" only for `docs/superpowers/specs/` design docs).
|
||||
The top-level requirements doc at `docs/work/prds/<date>-<slug>.prd.md`. Status flows `draft → in-review → approved → shipped` (`pnpm work prd-ship` auto-flips on epic completion). `pnpm work decompose` refuses to run on `draft`.
|
||||
_Avoid:_ spec (in this template the **ADR** is the durable design record; PRDs are the implementation seed).
|
||||
|
||||
**Epic**:
|
||||
A large body of work, one folder under `docs/work/<epic-slug>/` with `_epic.md`. Decomposed from a PRD.
|
||||
@@ -264,7 +264,7 @@ The shipping rhythm. One vertical slice closes one task, becomes one PR, lands a
|
||||
- **"schema"** — qualify: **Zod schema** (input/output contracts) | **Payload collection schema** (CMS field definitions).
|
||||
- **"config"** — qualify: **Payload config** | **Next config** | **Vitest config** | **TS config**.
|
||||
- **"bind"** — DI binding (`bind<I>(SYMBOL).toDynamicValue(...)`); not a `Function.prototype.bind`.
|
||||
- **"spec"** — `docs/superpowers/specs/` design doc; never a PRD or a Jest spec file.
|
||||
- **"spec"** — avoid in this template. Durable design records are **ADRs** (`docs/decisions/adr-NNN-*.md`); implementation seeds are **PRDs** (`docs/work/prds/*.prd.md`). Never use "spec" to refer to a Jest spec file either.
|
||||
- **"controller"** — one verb-noun pair per file; never a multi-method MVC controller.
|
||||
- **"module"** — avoid for packages (use "package"); reserve for Node ESM/CJS module semantics if needed.
|
||||
- **"coverage"** — qualify when ambiguous: **L0 coverage** (per-layer thresholds, test-time) | **diff coverage / L1** (cover-the-diff gate) | **aggregate coverage / L2** (committed summary.json) | **mutation coverage / L3** (Stryker mutation score, not line coverage).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Events and Jobs
|
||||
|
||||
Walkthrough for adding cross-feature events and background jobs to a feature. For the architectural rationale, see [ADR-015](../decisions/adr-015-events-and-jobs.md) and [the full spec](../superpowers/specs/2026-05-08-events-and-jobs-design.md).
|
||||
Walkthrough for adding cross-feature events and background jobs to a feature. For the architectural rationale, see [ADR-015](../decisions/adr-015-events-and-jobs.md).
|
||||
|
||||
> **Prerequisite — `@repo/core-events` is optional.**
|
||||
> The event bus (`IEventBus`, `InMemoryEventBus`, `PayloadJobsEventBus`) lives
|
||||
@@ -12,13 +12,13 @@ Walkthrough for adding cross-feature events and background jobs to a feature. Fo
|
||||
>
|
||||
> Background jobs (`IJobQueue`, `gen job`) work without core-events — they only
|
||||
> require `@repo/core-shared/jobs`. Cross-feature event fanout (`gen event
|
||||
> consume`) additionally requires core-events.
|
||||
consume`) additionally requires core-events.
|
||||
|
||||
The three rules to keep in mind:
|
||||
|
||||
- **E0** — Events are for cross-feature decoupling. In-feature reactions are direct use-case calls.
|
||||
- **E1** — Event contracts are public; handlers are private (never re-exported, ESLint-enforced).
|
||||
- **J0** — Jobs are for *deferred* work (latency, retries, cron). Synchronous code stays synchronous.
|
||||
- **J0** — Jobs are for _deferred_ work (latency, retries, cron). Synchronous code stays synchronous.
|
||||
|
||||
Three generators do the boilerplate. Each one inserts at fixed `// <gen:*>` anchor comments that are present in every feature.
|
||||
|
||||
@@ -225,16 +225,20 @@ sendWelcomeEmailJob(mailer),
|
||||
**For dev-seed, register the slug** with the `InMemoryJobQueue` so `enqueue` actually fires:
|
||||
|
||||
```ts
|
||||
if ("register" in queue && typeof (queue as { register?: unknown }).register === "function") {
|
||||
(queue as { register: (slug: string, h: (input: unknown) => Promise<void>) => void }).register(
|
||||
"marketing-pages.send-welcome-email",
|
||||
async (input) => {
|
||||
const wrapped = marketingPagesContainer.get<ISendWelcomeEmailJob>(
|
||||
MARKETING_PAGES_SYMBOLS.ISendWelcomeEmailJob,
|
||||
);
|
||||
await wrapped(input as SendWelcomeEmailInput);
|
||||
},
|
||||
);
|
||||
if (
|
||||
"register" in queue &&
|
||||
typeof (queue as { register?: unknown }).register === "function"
|
||||
) {
|
||||
(
|
||||
queue as {
|
||||
register: (slug: string, h: (input: unknown) => Promise<void>) => void;
|
||||
}
|
||||
).register("marketing-pages.send-welcome-email", async (input) => {
|
||||
const wrapped = marketingPagesContainer.get<ISendWelcomeEmailJob>(
|
||||
MARKETING_PAGES_SYMBOLS.ISendWelcomeEmailJob,
|
||||
);
|
||||
await wrapped(input as SendWelcomeEmailInput);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
@@ -265,16 +269,16 @@ Job cron schedules don't live in the feature's job file or generator output —
|
||||
|
||||
Six fixed anchor comments live in every feature:
|
||||
|
||||
| File | Anchor | Used by |
|
||||
|---|---|---|
|
||||
| `src/index.ts` | `// <gen:events>` | `gen event publish` |
|
||||
| `src/di/symbols.ts` | `// <gen:event-handler-symbols>` | `gen event consume` |
|
||||
| `src/di/symbols.ts` | `// <gen:job-symbols>` | `gen job` |
|
||||
| `src/di/bind-production.ts` | `// <gen:event-handlers>` | `gen event consume` |
|
||||
| `src/di/bind-production.ts` | `// <gen:jobs>` | `gen job` |
|
||||
| `src/di/bind-dev-seed.ts` | `// <gen:event-handlers>` | `gen event consume` |
|
||||
| `src/di/bind-dev-seed.ts` | `// <gen:jobs>` | `gen job` |
|
||||
| `src/integrations/cms/index.ts` | `// <gen:job-tasks>` | `gen event consume`, `gen job` |
|
||||
| File | Anchor | Used by |
|
||||
| ------------------------------- | -------------------------------- | ------------------------------ |
|
||||
| `src/index.ts` | `// <gen:events>` | `gen event publish` |
|
||||
| `src/di/symbols.ts` | `// <gen:event-handler-symbols>` | `gen event consume` |
|
||||
| `src/di/symbols.ts` | `// <gen:job-symbols>` | `gen job` |
|
||||
| `src/di/bind-production.ts` | `// <gen:event-handlers>` | `gen event consume` |
|
||||
| `src/di/bind-production.ts` | `// <gen:jobs>` | `gen job` |
|
||||
| `src/di/bind-dev-seed.ts` | `// <gen:event-handlers>` | `gen event consume` |
|
||||
| `src/di/bind-dev-seed.ts` | `// <gen:jobs>` | `gen job` |
|
||||
| `src/integrations/cms/index.ts` | `// <gen:job-tasks>` | `gen event consume`, `gen job` |
|
||||
|
||||
A CI guard at `packages/core-eslint/anchors.test.js` asserts the anchors stay present in every feature. Remove an anchor and CI fails — restore it and the test goes green.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> **Prerequisite:** This guide assumes `@repo/core-realtime` is present. If you started from the slim template, run `pnpm turbo gen core-package realtime` first.
|
||||
|
||||
Walkthrough for adding Socket.IO realtime channels, broadcasts, and inbound handlers to a feature. For the architectural rationale, see [ADR-016](../decisions/adr-016-realtime-layer.md) and [the full spec](../superpowers/specs/2026-05-08-realtime-design.md).
|
||||
Walkthrough for adding Socket.IO realtime channels, broadcasts, and inbound handlers to a feature. For the architectural rationale, see [ADR-016](../decisions/adr-016-realtime-layer.md).
|
||||
|
||||
The three rules to keep in mind:
|
||||
|
||||
@@ -294,6 +294,5 @@ The six ADR-015 anchors (`<gen:events>`, `<gen:event-handler-symbols>`, `<gen:jo
|
||||
|
||||
## Related
|
||||
|
||||
- [ADR-016](../decisions/adr-016-realtime-layer.md) — design decision record
|
||||
- [ADR-016](../decisions/adr-016-realtime-layer.md) — design decision record (full design including topology, auth gates, and v1 scope)
|
||||
- [ADR-015](../decisions/adr-015-events-and-jobs.md) — cross-feature events and background jobs (bus-bridge pattern)
|
||||
- [Spec](../superpowers/specs/2026-05-08-realtime-design.md) — full design including topology, auth gates, and v1 scope
|
||||
|
||||
Reference in New Issue
Block a user