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:
2026-05-13 17:00:11 +02:00
parent 0e6bbbf8b7
commit 89d47cce5c
9 changed files with 37 additions and 44 deletions

View File

@@ -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.