Skip to content

Latest commit

 

History

History
413 lines (352 loc) · 134 KB

File metadata and controls

413 lines (352 loc) · 134 KB

phoenix domain vocabulary (TERMS)

The repo-owned vocabulary spine: the nouns of phoenix — the products, the domain entities, the backend/fate/testing/infra terms a contributor or a CI-spawned agent must share to read the codebase the same way. Each term gets a short canonical definition and, where it disambiguates a known naming drift, a note on what the term is not.

This file churns — it lags shipped surfaces over time as features land and names move. It is maintained incrementally (not hand-frozen); when the code and this file disagree, the code is authoritative and this file is the doc to fix.

The why and binding decisions live in .decisions/; how the current code is shaped lives in .patterns/. This file names the what.

Core / shape

Term Definition Not
kamp.us The product/site being reborn as phoenix.
kampus Three senses: (1) the tech-lineage shape (worker + Durable Object patterns phoenix is rebuilt from); (2) the site-shell product (landing, profile, auth); (3) the kampus client CLI — the one authenticated surface humans + agents use to hit the deployed kamp.us API (ADR 0045; designed, not built). "server"
phoenix This project: kamp.us reborn as a single Cloudflare Worker (React 19 + Effect + fate, alchemy-managed).
Worker The one Cloudflare Worker serving both the SPA (via ASSETS) and the API: /fate (data), /fate/live (SSE), /api/* (health, auth). HTTP via Effect HttpRouter / HttpApiBuilder — no Hono, no GraphQL. "server"
bootstrap merge arm The one safe way a status bootstrap surface writes into a file that already exists (ADR 0334): either the JSON key-merge arm (parse, merge declared keys, preserve unknown keys verbatim, refuse malformed JSON without writing) or the append-if-absent arm (one marker-delimited block appended once to a text file; byte-identical no-op when present). Both refuse unparseable targets and paths outside the repo root, and both stay idempotent — a re-run over an adopted repo writes nothing. settings-patch and dep-pin take the JSON arm; claude-md-section takes the append arm. an overwrite (no surface ever replaces or deletes content it did not declare); the old never-overwrite refusal (existsalready, retired by ADR 0334 for adoption surfaces); a bespoke merge engine (only these two shapes exist)

Products (domains)

Term Definition Not
admin console The admin/ops console shell (features/admin-console, epic #2711, shell in #2740): the gated, extensible surface an admin opens to reach platform-operations tooling. Its one seam today is the admin.probe fate view — the server-authoritative "may THIS caller open the console?" signal (a synthetic singleton like funnel.summary) the SPA reads to decide whether to mount+fetch the lazy console bundle, carrying ONLY the fact that the gate passed (no identity, capability list, or admin roster). One gate, on the admin.probe resolver: the requireAdmin capability gate (Admin.over(platform)), whose denial is the invisible künye Denied (ADR 0107 / ADR 0098 §2) — the phoenix-admin-console dark-ship flag that once sat in front of it was retired at 100% rollout (#3671) — a non-admin cannot distinguish "not an admin" from "not signed in". English descriptive term; a Turkish brand noun for the console is a follow-up product decision. a per-app admin page (it is the one cross-platform ops shell); a probe that leaks admin-ness (it carries only the gate-passed fact); a user-facing product surface (admin/ops only)
kullanıcılar (user roster) The gated user-roster admin-console module (features/user-admin + src/admin/kullanicilar/, #3200): the read view an admin opens inside the shipped admin console shell to list every account — one UserAdmin row per user (kullanıcı adı, e-posta, role, banned, tier, kayıt), paginated (first/after keyset) and searchable (search substring). Backed by the userAdmin.list fate list root, gated by the default-off phoenix-user-admin dark-ship flag (ADR 0083) + requireAdmin (ADR 0107) — a non-admin gets the invisible Denied. The role/banned standing is JOINED past the gate (moderatorsAmong for the moderates-tuple role, the batched user_ban_event projection for banned), never read off the retired user.role column. READ-ONLY: the per-user actions (rol ata, yasakla/kaldır) wire into these rows behind their own seams later. Turkish for "users". the admin console shell itself (this is one module registered into it, not a new shell); a per-user action surface (read-only list + search only); a source that reads the retired user.role column (role comes from the moderates relation)
bildirim The notification feature (features/bildirim, epic #1666): the recipient-keyed store + read model behind the /bildirimler center page and the topbar unread badge — the notification D1 table, the Notification domain service, and the bildirim.* fate views/mutations (list / unreadCount / markRead / markAllRead). Ships dark behind the single default-off phoenix-bildirim flag every emitter sibling reuses. Turkish for "notification". the report (bildir) feature (content-reporting for moderation — bildir, a different lexeme and module); an emitter (siblings #1695–#1699 produce notifications; this is the spine)
divan The proving-ground reviewer surface (features/divan): the gated destination where the established community (yazar + moderatör) reviews a çaylak's sandboxed work and promotes (mod-direct) or vouches (kefil) them toward yazar — work "goes before the divan". Reads the sandboxBacklogWhere backlog over a yazar-OR-mod gate. Its topbar entry (divanTo NavLink, Topbar.tsx) is a destination under the ratified nav element taxonomy (destination / primary action / utility / signal — wayfinder map #2583, fork #2586). Turkish for "council/court". a widening of inline çaylak visibility — it is a gated destination that reads the sandbox backlog, not a change to who sees sandboxed items inline; not a primary action (it goes nowhere near the + gönderi CTA class)
divan section nav (boxed-pill tabs) The intra-/divan section switcher (.kp-divan__nav-tab, DivanPage.tsx / Divan.css): the çaylaklar (roster) ↔ raporlar (mod queue) tab row shown when raporlarVisible. Each tab is a boxed pill1px border + r-sm + a resting surface fill, switching to an accent-faint fill + accent border on aria-current. Under the ratified nav taxonomy (map #2583, fork #2586) these are intra-destination destination switchers, and the map flags the resting boxed fill as a containment-law violation candidate (the nav-surface inventory #2585): a section tab may paint accent on the active state (transient state paint is legal) but should not carry a boxed resting chrome. the divan topbar entry (that is the destination-level divanTo link, one level up); a containment-legal transient accent (the violation is the resting boxed fill, not the active-state accent)
authoring brief The GitHub issue a fresh authoring session works out of to author one fabrika skill — the boot document that makes a stateless session workable (founder workflow ruling, #4650). Carries six fields: the skill + its destination directory, the v1 baseline path (reference only, #4638), the incidents from the ruled KEEP corpus the rebuild must not regress — enumerated in packages/fabrika-cli/src/eval/incident-corpus/ruled-keeps.json at 66 members plus 1 pending (#4642, corrected #4823), the existing verbs it may assume (#4635), pointers to the two fabrika convention docs, and the output contract — skill-reviewer runs on the authored skill before the PR opens (runbook step 5.5, #4650), then one PR carrying SKILL.md + the derived contract spec, linked back with Fixes #<brief>. Format: claude-plugins/fabrika/docs/authoring-brief-contract.md. a write-code ticket (a brief is fired by a human starting a fresh session; what keeps it out of the coder pool is that it is emitted assigned, not label-absence — review-plan flips every planned child to status:triaged regardless — the brief-is-not-write-code rule (the brief contract)); a design spec (it supplies ground, not architecture — the two-layer split is the session's judgment); an eval case (it cites incident issues; the bar, harness and corpus are #4649's)
fabrika The kamp.us agent pipeline rebuilt from first principles as its own plugin (claude-plugins/fabrika/, epic #4648) — thin skill wrappers over deterministic CLI verbs, every skill written under writing-for-agents (the authoring discipline that replaced the retired /skill-creator door, founder ruling 2026-08-18). Built beside — and now instead of — the v1 kampus-pipeline plugin, which is retired and deleted (#5937): fabrika is the one pipeline. Founder-sealed name (#4631), styled lowercase like the sibling brand nouns. Turkish for "factory". the v1 kampus-pipeline plugin (retired, #5937 — fabrika is net-new, not a rename or refactor of it)
derived CLI contract (contract spec) The per-skill specification an authoring session emits for the fabrika verbs its skill needs, and the artifact a write-code agent implements from: verb inventory, per-verb inputs/flags, output shape, exit-status semantics, error taxonomy, scope + zero-scope behavior, and literal examples. "Derived" is the method (#4638): the session works out which deterministic work belongs in the CLI and writes the contract, and that spec is what the CLI implements — so it must be readable without the authoring transcript. Lands as contract.md beside its skill; the format and the interface convention every verb meets are in claude-plugins/fabrika/docs/cli-interface-convention.md. a description of an existing implementation (the contract comes first, the verb is built to it); a port of a v1 kampus-pipeline script (#4638 banned the v1 corpus as a source of truth even before its deletion, #5937); the skill's own prose (judgment stays in the wrapper, determinism moves to the verb)
fabrika-cli The deterministic verb package fabrika's skills call: packages/fabrika-cli/, binary fabrika, invoked as fabrika <group> <verb> … — one registered group per skill, the first being adr (#4725). It is the deterministic half of fabrika's two-layer split: what a skill would otherwise re-derive per session lives here as a verb, and the skill fence is one invocation of it. It calls pipeline-cli nowhere — no import, no subprocess (ADR 0238), which is why it is a separate package rather than a group inside the v1 router: a fabrika tethered to the pipeline it exists to replace can never replace it, so v1 is a reference for semantics and scars, never a dependency. pipeline-cli (the v1 router — the frozen comparison baseline, and never an upstream); the derived CLI contract (that is the per-skill spec; this is the implementation built to it); a general-purpose CLI (internal pipeline tooling only)
hook surface Where fabrika declares its Claude Code hooks and what a declaration may say: one file, claude-plugins/fabrika/hooks.json, whose every command is a plain literal fabrika <group> <verb> string calling a verb implemented in packages/fabrika-cli/ (cli-interface-convention rules 5 and 6; ADRs 0232 / 0238). It carries no dispatch script, data dir or version pin — the repo-root shim decides which copy runs. A declaration is exercised, not merely written: the golden test runs the argv it reads out of hooks.json against captured real envelopes (ADR 0180). The convention, and the single interim fail-open dispatch-failure policy point (owned by #5079), are in claude-plugins/fabrika/docs/hook-surface.md. v1's hook pack (retired and deleted with the kampus-pipeline plugin, #5937 — it was never a dependency); a wrapper or dispatch script (rule 5 admits no such shape); the hook verb group (that is the implementation the surface invokes; the surface is the declaration)
wire format The byte-level agreement two fabrika skills meet through on a GitHub artifact (ADR 0241) — the acceptance-criteria block, the verdict marker, and every format after them. A format exists by being one row in packages/fabrika-cli/src/wire/registry.ts (key, purpose, owner module, producers, consumers, emit, read) with a schema module owning its bytes; fabrika wire formats projects that registry at runtime and claude-plugins/fabrika/docs/wire-formats.md indexes it. Formats land with their first consumer, never in a batch. a serialization format (JSON/msgpack — a wire format is one named artifact-level agreement, not an encoding); a skill contract (contract.md specifies the verbs a skill calls; a wire format is what two skills hand each other); shape restated in a skill body or a second doc (banned — the shape lives in the schema module and is cited)
schema module The typed module that owns one wire format's bytes and nothing else — composing them and reading them back (emit / read, under packages/fabrika-cli/src/wire/, e.g. verdict-marker.ts). Its read is total: Found / Absent / Malformed (wire/format.ts), with Found non-empty by type, so a drifted artifact can never come back as a plausible empty value. A new format is a sibling schema module plus a registry row — never a branch inside a verb (ADR 0241). a verb (the wire leaves are adapters that select a module with --format); a home for the judgement halves (which deviation class a finding is, when a criterion is worth writing, when to flip a verdict — those stay in the skills); a validator that returns a well-formed empty value on unreadable or unparsable bytes
eval case One authored prompt-plus-assertions unit in a skill's eval set (epic #4649) — a /skill-creator evals/evals.json entry (id, prompt, expected_output, expectations) plus its per-case eval_metadata.json sidecar, decoded by packages/fabrika-cli/src/eval/skill-eval-set.ts (#4674). Its execution tier (deterministic CLI-layer vs judgment-graded) is derived from its assertions, never authored as a field. a corpus entry (that is the stage-keyed CorpusEntry of the model-tiering corpus — a different model that coexists); a unit test (an eval case runs a skill, and its assertions may need a grader)
eval set The collection of eval cases one skill's authoring session produced (epic #4649) — the unit the unattended runner executes and the fabrika ship gate reads. Born once, in the /skill-creator session that wrote the skill, and consumed by the harness unchanged. the incident corpus (the committed, growing set of incident-derived cases, #4675); the corpus manifest (the pre-existing per-stage ground truth serving the model-tiering scorecard)
incident corpus The committed, growing set of incident-derived eval cases fabrika's regression floor is measured against (#4675, epic #4649), at packages/fabrika-cli/src/eval/incident-corpus/: the cases in the reused /skill-creator format plus a provenance ledger binding each case to the real artifact — an issue, PR, commit or posted verdict — it pins. Grows by a written intake rule, not by memory: a new incident becomes a case within days (#4637), authored at the deterministic tier wherever its assertions name an observable. A re-diagnosis is appended as a correction, never substituted for the original claim. the corpus manifest (the pre-existing per-stage ground truth serving the model-tiering scorecard — same module, different body of truth); an eval set (that is one skill's authored cases; the incident corpus is cross-skill and incident-sourced)
regression floor The 100%-must-pass subset of the eval suite — the incident-derived cases (#4675) — as distinct from the graded pass rate the judgment axis reports. Founder-ruled at 100% and growing (#4637): every incident becomes a case, so the floor rises with each failure the pipeline survives. the graded judgment bar (90% per stage, and a trend co-gate — a rate, not a floor); a flaky-test tolerance (a flaky case on this floor is a defect of the case)
eval record The head-bound PR comment a review run leaves behind carrying one graded cell's measurement, defined in ADR 0253 (coined by #4769): a marker line in its own eval namespace — eval: RECORDED @ <sha> — <clause>, the SHA-bound verdict grammar reused for the binding only — over a fenced JSON payload carrying the (stage, surface, model) cell (ADR 0243's cell key), the model / CLI / harness pins, the cell aggregate spelled as ScorecardCell (gradedRuns / passedRuns / passRate) and a per-case block spelled as ADR 0252 §1 (runs / passed / noVerdict / dispersion / perRun). Its second token is an availability token, RECORDED | UNRECORDABLE, never a polarity: a below-bar run is still RECORDED at its real rate, and five NoVerdict runs are UNRECORDABLE rather than a 0.0 rate for a measurement nobody took. One record per (head, cell), latest in-force wins, ACL-gated fail-closed (ADR 0055). Owned by its own schema module packages/fabrika-cli/src/wire/eval-record.ts plus one registry row — verdict-marker.ts is not widened to admit it. a SHA-bound verdict (an eval record is a measurement, not a judgement: it carries RECORDED/UNRECORDABLE and never PASS/FAIL, sits under the eval root rather than a review-* one, and no ship-gate scan reads it — the 90% bar belongs to #4681's gate, not to the record); a committed scorecard (claude-plugins/fabrika/reports/eval/<date>.json — the downstream aggregate #4680 derives from these comments; a comment accumulates no series); an eval case or an eval set (those are the authored inputs — one prompt-plus-assertions unit, and one skill's collection of them; an eval record is what running them at one head produced); a row of corpus (eval-harness) or of the incident corpus (graded ground truth; an eval record is a measurement taken against it); a committed per-run file (committing it would move the head it binds and self-invalidate it)
committed scorecard One eval run's scorecard persisted as a committed file at claude-plugins/fabrika/reports/eval/<date>.json (founder ruling on #4765). Ruled: the location, and that the format is the existing Scorecard type — the file's body is that type's toJson serialization, which #4680 settled as a superset: the same decisionRef / framing / baseline / cells keys and the same per-cell stage / surface / model / gradedRuns / passedRuns / passRate spellings, widened by a top-level recordedAt (the series' ordering key) and, per cell, the #4637 pins triple, a source naming the eval record's head SHA, an outcome, unmeasuredCases and the case list. <date> is the run's UTC YYYY-MM-DD, with a -2, -3 … suffix for a second run that day — a committed point is appended to, never rewritten. That name is also the membership rule: the directory is shared with the eval layer's other dated artifacts (the #4679 cost baselines), so the trend reads the files named as series points and skips the rest rather than globbing *.json. A cell whose pin is blank or which cites no eval record is rejected rather than committed, in both directions: fabrika grade scorecard refuses to write it and decodeCommittedScorecard refuses to read it back as a point. The accumulated files are the series the trend co-gate (#4680) reads back and the merge gate (#4681) grades against; the definition, its producers and what is deliberately left open are in packages/fabrika-cli/src/eval/README.md. the in-memory Scorecard/ScorecardCell types or fabrika grade report --json output (that is the same shape before it is committed anywhere); a PR comment (a comment accumulates no series); the repo-root reports/ directory (the file is colocated with the fabrika plugin)
dispersion The minority-verdict count of the graded axis's five runs (#4678): min(passed, runs − passed), an integer in 02 at five runs, carried on the head-bound eval-result artifact and the committed scorecard row beside runs and passed so it is re-derivable. It is the fact the median throws away — a 3–2 pass and a 5–0 pass are the same verdict and different facts — and it is recorded, never gating: no verdict in the merge gate (#4681) branches on it. Defined in ADR 0252. a variance, a standard deviation, or a per-run verdict list (it is a count of runs); an input to the trend co-gate (that reads the pass-rate series and nothing else — #4678's prose claiming otherwise is corrected by 0252); a flakiness gate
two-week decline The trend co-gate's flag condition on one (stage × surface × model) pass-rate series over the committed scorecards (#4680), defined in ADR 0252: over the trailing 14 days anchored on the newest point and split into two 7-day halves with at least 3 points each, the series is declining iff the mean drops by more than 0.05 (strictly — a drop of exactly one case's worth in a twenty-case corpus is steady, and the difference is rounded to 4dp before the comparison so the boundary is decidable) and the halves do not overlap (max(new) < min(old)); otherwise steady. Too few points is insufficient-data, a third answer that is never a pass. Computable since #4680, which landed the ordering key at the spelling 0252 named — a committed scorecard carries recordedAt — and the reader that evaluates it (fabrika grade trend). Ships observe-only under the #4766 founder guardrail — it flags, and cannot red a PR until a later ADR arms it against a real recorded series. a merge-blocking red today (#4681's below-bar reds on the 90% bar alone until arming); a slope fit or a statistical test (it is two half-means plus a non-overlap clause); a rule that mixes cells (one series per cell key); an inclusive ≥ 0.05 threshold (one regressing case out of twenty lands exactly on 0.05 and does not flag)
funnel / conversion funnel The conversion-funnel readout (features/funnel, #1589): the mod-gated, dark-shipped surface that measures the human çaylak→yazar journey. Its tracer read is the tier population — a humans-only (user.type = 'human') GROUP BY tier count of how many accounts sit at each rung of the authorship ladder (FunnelSummary, the funnel.summary fate view). Read-gated by the ViewFunnel capability (founder/mod). The Phase-2 rate/time metrics extend this same service. a public metrics page (founder/mod only); a per-product stat (that is stats, the landing counts); an agent/bot metric (humans-only by construction)
depo kampus's internal asset store / CDN (ADR 0144, supersedes 0044's imge). Built in-tree: both alchemy stacks under infra/depo (depo.ts, the R2 read path; doorman.ts, the authed write path) plus the doorman worker under infra/depo/worker/, and the packages/depo client+CLI — all unit-tested workspace members. Build state only; whether either stack is deployed is not asserted here. A decoupled infra primitive, never user-facing: its own infra/depo alchemy stack, R2-backed, public-read at depo.kamp.us (capability-URL — GitHub-embeddable ⇒ never read-sensitive), writes through a doorman worker (pasaport apiKey, content-addressed write-once), client is a standalone depo CLI. Turkish for "depot/warehouse". First consumer: agent Playwright screenshots → GitHub PR descriptions — via ADR 0144's review-ui producer coin, which is distinct from fabrika's review-ui visual-review gate (the two names coexist and neither supersedes the other — founder ruling (a), 2026-08-08 on #4904; see 0144's qualifying note). The producer was never built standalone; its capture-and-embed leg lives in the fabrika gate over the @kampus/fabrika-cli/capture seam. Renamed from imge (the imgur-style scope is rejected). the imgur-style public image/video product (that scope is rejected, ADR 0144)
pano HN-style link & discussion aggregator with threaded comments. Turkish for "board". "board", "pinboard"
pasaport Identity/auth/profiles/karma domain; wraps better-auth. Turkish for "passport". "auth" (broader)
raporlar (mod queue) The moderator-only moderation-queue view inside /divan (#1701, src/components/divan/Raporlar.tsx): renders the open content_report queue via the Moderate-gated report.listOpen read. The entry shows iff the viewer carries the trusted server-side isModerator signal — keyed on isModerator, never tier, so a dual-role yazar+moderator still sees it; the client gate is a courtesy, the read stays Moderate-gated server-side. Resolve actions are #1702–#1704's lane. Turkish for "reports". the report (bildir) capture feature (users filing a report — this is the mod-side queue over those rows); a tier-gated surface (it keys on the Relation-axis moderator signal, not the authorship ladder)
reaction The ungated, karma-free per-user-presence feature (features/reaction/Reaction.ts, #1861): the third instance of the polymorphic per-(user, target) presence pattern after vote and bookmark. One canonical write surface Reaction.react upserts a viewer's single reaction across the three targets (definition | post | comment) into the cross-product user_reaction table (PK (user_id, target_kind, target_id), cardinality one-per-(user, target)) — a palette emoji sets/changes it, a null retracts, re-reacting the same emoji is an idempotent no-op (changed: false); batched readMine mirrors the viewer's reaction with no N+1, and clearTarget is the removal-substrate cleanup home. Modeled on bookmark's pure-presence shape, not vote: no score, no hot-score recompute, and — deliberately — no karma and no tier gate (see the reaction / vote divergence in the Not column). Unlike bookmark it carries a value: the chosen emoji, constrained to the curated REACTION_EMOJI palette. a score- or karma-bearing surface; a tier-gated one — reaction is ungated, so any authenticated user (a çaylak included) may react; there is no VoterStanding floor and no KarmaBump collaborator (those are vote's alone). A future reader must not "fix" the ungatedness by wiring the tier gate — the ungatedness is the point
reaction aggregate (reactions / myReaction) The read half of reaction (Reaction.readAggregate, #1862): a target's per-emoji COUNT(*) tallies (ordered by the REACTION_EMOJI palette, only non-zero members) plus the viewer's own current emoji, exposed on the post / comment / definition fate views as the embedded scalar field reactions — the score twin, so an agent reading a view sees reactions as first-class data. Batched across a page in ONE GROUP BY read + one readMine (no N+1), stamped by stampReactionAggregate (features/fate/reaction-aggregate.ts) — the value-carrying analogue of stampViewerScalars. The viewer's-own wire lexeme is myReaction: the bare my* form (the myVote twin, since reaction is vote's twin), carrying the palette emoji value, NOT the is* presence-boolean form (isSaved) — a reaction has a value, so it mirrors myVote, not isSaved. A target with no reactions and no viewer reaction carries the empty aggregate ({counts: [], myReaction: null}), never a missing field. the myVote/isSaved presence booleans (those are boolean scalars; the reaction aggregate is a structured {counts, myReaction} object); a per-target N+1 read (it is one batched GROUP BY); the write path (Reaction.react — the aggregate is read-only)
report (bildir) The content-reporting feature (features/report): users flag a post/comment/definition for moderation. The Turkish brand lexeme bildir lives on the user-facing copy (the ReportButton labels bildir / bildirildi / zaten bildirildi); the technical surface stays English per the convention — module dir features/report, the Report service, the content_report table. (No bildir-specific exemption is needed: report conforms — Turkish brand on the copy, English technical identifiers.) the /report pipeline skill or the report-agent (which file GitHub issues) — unrelated
rss / feed The feed-generation feature (features/rss): emits RSS/Atom feeds of pano/sözlük activity.
sözlük (sozluk) Turkish dev-terms dictionary; community definitions ranked by upvotes. Turkish for "dictionary". "dictionary"
stats Landing-page aggregate counts (query-only feature).
text Small shared text-utility "app" under features/ — a named grouping, not a product domain. a product domain
vote Shared vote + karma write engine (features/vote/Vote.ts); sözlük and pano delegate to it. The per-target tables definition_vote / post_vote / comment_vote (PK (target_id, voter_id)) are the score-truth source — the cached score on the target row is rebuilt from COUNT(*) on them. The cross-product user_vote table (PK (user_id, target_kind, target_id)) is the myVote presence mirror, not the score truth. the score-truth store (those are the per-target *_vote tables); user_vote is only the myVote mirror, not the authoritative score

Domain entities

Term Definition Not
base feed The viewer-invariant feed projection, identical bytes for every viewer, the cacheable unit (leg B). the per-viewer response (that is the viewer overlay composed over it)
bookmark (kaydet) A per-user post save — pure presence (a post_bookmark row means saved). The structural twin of vote stripped of score/karma: per-user presence row + batched readMine + changed-returning toggle. One lexeme per layer, mirroring vote (#1138): engine Bookmark (vote: Vote); per-target row post_bookmark (vote: post_vote); presence intent input value (vote: value); wire viewer-scalar + result presence field both isSaved (vote: both myVote). Two deviations are deliberate, not drift: the brand term stays Turkish kaydet (Turkish-product / English-technical split), and the wire scalar uses the is* convention (isSaved, the isDraft twin) where vote uses bare myVote. the bare lexemes saved/bookmarked for the wire/result field (the field is isSaved); a score-bearing vote
comment A threaded reply on a pano post.
contribution An item in a profile's activity feed (a definition/post/comment); a discriminant-tagged fate view.
çaylak The un-promoted tier on the earned-authorship ladder (visitor < çaylak < yazar): an authenticated contributor whose work is sandboxed — it goes before the divan for review before becoming public. Promoted to yazar when a yazar vouches (kefil) for them and a net-karma bar is met. The standing is read via Kunye against the ladder (ADR 0107; see the Authz section). Turkish for "rookie/novice". a logged-out visitor or a banned account; a yazar (the promoted tier); a moderatör (the Relation-axis authority, a separate axis)
definition A community-written meaning under a sözlük term; upvotable; its score is its net up-vote tally.
feed snapshot The persisted, versioned dehydrated fate cache restored at boot to paint the last-seen feed (leg A). an HTTP cache entry
incelemede (in-review badge) The owner-only in-review state badge (ReviewBadge, #2200) a çaylak sees on their OWN sandboxed post/definition detail while the item awaits divan review — the shared render across the pano + sözlük detail surfaces. Driven by the owner-scoped sandboxed wire flag (only ever true for the author), with state carried by the word (not color alone) on AA-contrast tokens. Turkish for "under review". the profile katkıların sandbox badge (#1291 — a separate render on the profile list); a moderator-facing signal (it is owner-only: only the çaylak author sees it)
karma Reputation points; the vote engine writes karma deltas atomically with votes (same Drizzle batch). "rep" (use karma)
künye Two roles. (1) Reputation DO — designed, not built (#41). The planned per-user Durable Object for karma / invite-only access / karma-gated privileges / agent registration; not shipped — today the only Durable Object is LiveDO, karma lives in D1 (user_profile.total_karma), and Kunye (features/kunye/Kunye.ts) is a plain Context.Service (it reads standing fresh from pasaport, holds no DO state). (2) The kamp.us authz home (ADR 0107)apps/web/worker/features/kunye/ hosts the capability instances (Authorship, Moderate, Admin), the adapter Layers that fill packages/authz's ports (CurrentActorLive ← pasaport session, RelationStoreLive ← D1 relation tuples, AgentAuthorityV1), and the earned-standing service — the authz / earned-standing half of the split. Turkish for "byline/credits". authn/identity (that is pasaport); the vocab-free authz mechanism (that is packages/authz)
mecmua_post (Drizzle table) mecmua's own worker-private D1 post entity (apps/web/worker/features/mecmua/, #2496) — the long-form store behind a mecmua post: id, title (başlık), markdown body, slug, authorId, createdAt/updatedAt, and the mecmua-specific publishedAt (null while draft). Modeled on pano's Post shape but drops its link-sharing columns (url/host/score/hotScore/commentCount/tags/sandboxedAt) — mecmua is long-form authoring, not link-sharing. Multiple drafts per author allowed; a worker-private store, not a shared @kampus/db-schema *_record. a reuse of the pano Post entity (mecmua Post is its own type — no pano Post reuse); a link-sharing row (no url/host/score); a shared *_record store (it is worker-private)
MecmuaPostView The fate read-view for a mecmua_post (features/mecmua/views.ts, #2496), mirroring the pano PostView / FateDataView idiom — the public read-shape a reading agent resolves over the public GET route (story 8). A read-shape declaration, not a table. the Drizzle store (that is mecmua_post); the pano PostView (mecmua is its own type)
MecmuaPostVisibility The draft-mask over a mecmua_post (features/mecmua/, #2496): the null-safe published test that hides a draft (null publishedAt) from public reads and exposes a published row. Per #2463 it has no sandbox arm — mecmua carries no çaylak sandbox, so unlike pano's PostVisibility there is only a draft-vs-published branch, never a sandboxed-visibility one. pano's PostVisibility (which carries a sandbox arm); a çaylak sandbox mask (mecmua has none)
notification One recipient-keyed notification row (bildirim): a plain-text kind (emitters mint kinds without a migration), a polymorphic target reference (post/comment/definition/user, no FK — liveness resolved at read time), an optional verbatim actor_id, an aggregate count slot ("3 yeni oy", #1698), and read state as a nullable read_at stamp — "read but we don't know when" is unrepresentable. Every read/write predicate carries recipient_id, so touching another user's notification matches zero rows by construction. a row with a boolean read flag (read state is the read_at stamp); a cross-user broadcast
post A pano submission (link or text).
profile A user's public page with a contributions feed; carries totalKarma.
REACTION_EMOJI (palette) The curated, closed, ordered set of emoji a reaction may carry (db/reaction-emoji.ts, #1859/#1861) — one runtime tuple (["👍", "❤️", "😂", "🤔", "😢", "🔥"], the TARGET_KINDS idiom) that the user_reaction.emoji value column, the ReactionEmojiSchema wire decoder, and every display path all source from, so code and UI never drift from the palette decision. A curated fixed set, not a free picker: ReactionEmojiSchema (Schema.Literals) decodes only a palette member, so an arbitrary emoji is structurally unrepresentable at the wire boundary. a free-form emoji picker; a per-app or per-target palette (it is one template shared across pano + sözlük)
roster (divan.roster) The pending-çaylak review roster the divan reads (Divan.roster / buildRosterDivanRosterRow, #1287/#1423): every çaylak with ≥1 sandboxed, not-removed item, grouped by author and joined to each çaylak's identity (handle + karma) in ONE batched profile read, so the single divan.roster fate request carries every row's identity in-batch with no per-row by-id waterfall (ADR 0021). the per-author sandbox backlog (that is Divan.backlogOf); a client speculative "roster probe" (a guaranteed-unauthorized pre-auth fetch short-circuited in #2209 — incidental prose, not a term)
score A definition/post/comment's net up-vote tally; a denormalized cache bumped inside the vote batch.
tag A label on a pano post.
target tombstone The render for a notification whose target no longer resolves: foldTargetHrefs (features/bildirim/target.ts) yields a null targetUrl for removed content or a deleted/unbootstrapped account, and the center page renders a plain dead row — never a broken link or a crash. a deleted notification (the row stays, only its link is gone); a client-side 404
term A sözlük dictionary entry (has a slug + title). "word"
unread badge The topbar unread-count chip on the user menu: rendered only when the recipient's unread count > 0 (and phoenix-bildirim is on). Reads at shell mount; a mark-read receipt carries the fresh count, but live SSE refresh is #1700's lane. an always-visible counter (absent at 0 or flag-off); a live-updating badge (that is #1700)
viewer overlay The thin per-viewer read (myVote/isSaved presence) composed over the base after session resolve.
yasak (ban) An admin action (#970, epic #968) that refuses a user's sessions at the auth boundary — a banned account's existing AND future sessions are treated as anonymous (Pasaport.validateSession reads the ban-state fresh per request and returns null), not merely flagged. Ban-state is a projection of the append-only user_ban_event log (features/pasaport/ban.ts resolveBanState): the latest event wins, so it can never drift from history and every ban/unban is one audited row (actor, target, reason, optional expiry, time). Reversible by unban (a later event), and a ban with an elapsed expiresAt self-lifts. requireAdmin-gated (Admin.over(platform), ADR 0107) and dark behind the default-off phoenix-user-ban flag. Turkish for "ban/prohibition". a content-removal (that is the ADR-0096 substrate slice — ban acts on the user/session surface, not the content); a mutable banned column (the never-migrated better-auth field is deliberately not resurrected — state is the event-log projection); a moderatör power (it is the admin capability, a distinct authority)
yazar The promoted full-author tier on the earned-authorship ladder (visitor < çaylak < yazar): an established author whose work is no longer sandboxed and who reviews çaylak work in the divan, vouching (kefil) for a çaylak's promotion toward yazar. The floor for OpenTerm (open a sözlük başlık) and for casting a vouch (ADR 0107; see the Authz section). Turkish for "author/writer". a çaylak (the un-promoted tier); a moderatör (the Relation-axis moderates authority, a separate axis)

Authz (capabilities — ADR 0107)

The vocab-free mechanism lives in packages/authz; the kamp.us instances + standing live in künye (apps/web/worker/features/kunye/). Depth is in .patterns/authz-capability-as-effect.md + ADR 0107; this names the nouns.

Term Definition Not
packages/authz The vocab-free capability-as-Effect authorization mechanism: a privileged op requires an unforgeable Grant proof, obtained only by discharging a typed check and flowed through the Effect context (R) channel — omitting .provide is a compile error. Two axes: Level (the earned authorship ladder visitor < çaylak < yazar, a global account-level standing) and Relation (assigned, resource-scoped authority — moderates, admin). Declares the ports (CurrentActor, RelationStore, AgentAuthority) and names no kamp.us noun, no fate, no D1. a central PDP / a stringly decide(action) boundary; better-auth's AC model (authn only); the kamp.us instances (those are künye)
capability A class-as-capability named by what it authorizes (Authorship, Moderate, Admin) — the class is at once the proof tag, the Grant type, the discharge verb, and .provide. The kamp.us instances are künye-owned. a level compared at the callsite; a user.role string check (retired, ADR 0107)
Authorship (OpenTerm / AddEntry) The Level-axis künye capability rights (features/kunye/Authorship.ts): OpenTerm (floor yazar, open a sözlük başlık) and AddEntry (floor çaylak, add an entry), each a single Capability.Level flooring the global standing read from Kunye against the visitor < çaylak < yazar ladder and denying with RequiresLevel (FORBIDDEN). One class = one right (the tag IS the right). a per-product standing; the sözlük write-path wiring (that is #1203); the Relation axis (Moderate/Admin)
PublishMecmua The Level-axis capability that gates publishing a mecmua post (features/mecmua/, #2497; ADR 0107 §7): a Capability.Level floored at yazar on the visitor < çaylak < yazar ladder, modeled directly on OpenTerm — reads the global account-level standing via Kunye.tierOf and denies with RequiresLevel (FORBIDDEN). The yazar floor is load-bearing: a çaylak cannot publish — authorship is earned, against the one global künye identity (not per-product). Gates the mecmua.publish / mecmua.saveDraft mutations; denial copy is Turkish. a per-product standing (it reads the one global künye standing); an inline if (tier === 'yazar'); a Relation-axis authority (it is Level-axis, the OpenTerm twin)
AgentAuthority The dormant agent-attenuation seam (ADR 0107 §6): an authz port that combines an agent's own + human-root standing so an agent's authority ⊆ its human root. v1 is humans-only — features/kunye/AgentAuthorityV1 fills it fail-closed (an agent is admitted nothing); v1.1 swaps that one Layer for the real policy with no edit to packages/authz. The framework's additive-completeness litmus. a capability/right; a check at the callsite; a packages/authz edit point
Tier / authorship ladder The visitor < çaylak < yazar earned-authorship Scale (features/kunye/standing.ts authorshipLadder, ADR 0107 §4) the Authorship/Vouch Capability.Level instances floor against. Since #1203 the live tier is a server-managed user.tier column read via Kunye.tierOf, not derived from karma; visitor is never stored — it is only the read-time rank of a no-account principal, so an authenticated account is always ≥ çaylak. a karma-derived tier (the tierForKarma / KARMA_THRESHOLDS math survives only as the promotion/karma input); a user.role string
Vouch (kefil) The author-vouch capability (features/kunye/vouch.ts, ADR 0107 §2-3): a Capability.Level floored at yazar — a yazar vouches for a çaylak's promotion. Its OWN right (named by what it authorizes) even though it shares OpenTerm's yazar floor. Vouch.require discharges a Grant iff global standing gte yazar, else the public RequiresLevel (FORBIDDEN). Turkish user-facing copy: kefil. Routing the authority through the framework makes self-promotion structurally impossible. an inline if (tier === 'yazar'); opening a term (that is OpenTerm); the vouch record (that is VouchLedger)
VouchLedger The D1-backed store of the vouch act (features/kunye/VouchLedger.ts, the authorship_vouch table) — records / reads / counts / withdraws a yazar's vouch, preserving the voucher. Active-by-existence (#1289): no withdrawn column — a vouch is active iff its row exists AND the candidate is still çaylak; a promotion or a withdrawal frees the slot. The persistence seam only; the authority to vouch is the Vouch capability. Concurrent-vouch cap VOUCH_CONCURRENT_CAP (= 3). the vouch authority (that is Vouch); a row carrying an active/withdrawn flag column
tandem (resolveTandem) The order-independent tandem resolver (features/pasaport/tandem.ts, #1289): the single idempotent path that flips a çaylak → yazar the moment both halves hold — (≥ 1 active vouch) AND (net karma ≥ VOUCH_PROMOTION_KARMA_BAR, = 15). Fired from both triggers (the vouch act and the bar-crossing vote) in either arrival order, so promotion never depends on which landed first. Holds no authority — it is not a capability; the yazar never holds a promote right (North Star #1194). a promote capability; a karma-only auto-promotion (a vouch is always required)

Backend architecture (Effect)

Term Definition Not
AppConfig The Config.all(...) surface for reading worker env (e.g. ENVIRONMENT); bare effect/Config, no WorkerEnvironment cast.
Auth A type alias re-exporting better-auth's instance type — export type Auth = BetterAuth (features/pasaport/Pasaport.ts, import type {Auth as BetterAuth} from "better-auth"); the typed handle for the better-auth instance, not a session-carrying service. The per-request session carrier is CurrentUser (ADR 0042), provided per request alongside LivePublisher. the per-request session service (that is CurrentUser, ADR 0042)
BETTER_AUTH_SECRET The signing secret, bound secret_text via Config.redacted (REQUIRED, no default); read in better-auth-live.ts.
Context.Service The Effect service class form; one per feature folder (Sozluk, Pano, Vote, Pasaport, Stats).
Data.TaggedError The tagged-error model; each _tag maps to a wire code. a plain Error
Database (tag) The Effect service holding the raw D1Database; the swappable DB seam both Drizzle and better-auth derive from, so features and auth share ONE handle. DatabaseLive binds PHOENIX_DB. There is no test handle: unit tests substitute the higher Drizzle seam directly (a Layer.succeed(Drizzle, …) double) and provide no Database; the real handle exists only at integration, against real remote D1 (ADR 0082 — the in-memory node:sqlite DatabaseTest of ADR 0040 is deleted). passing concrete db/auth handles
Drizzle (service) Worker-level singleton holding the drizzle builder; the DB seam for feature code (worker/db/Drizzle.ts). Derives its handle from the Database tag. drizzle (the library)
Drizzle.run / Drizzle.batch Callbacks feature code uses for single / atomic-multi queries; wrap Effect.tryPromise with a tagged DrizzleError. batch is atomic (all-or-none). a raw Effect.tryPromise
Effect.fn Service-method wrapper giving auto spans + stack frames; span names are "Service.method".
ENVIRONMENT Plain plain_text binding gating better-auth's dev/prod split; the sole real runtime consumer is better-auth-live.ts.
HttpApiBuilder Effect's typed-JSON HTTP layer; serves the GET /api/health group (health.ts).
HttpRouter Effect's imperative router; raw-Request/SSE routes (/fate, /fate/live, /api/auth/*) via HttpRouter.add. Replaced Hono (ADR 0027). Hono
keyset Cursor pagination helpers (worker/db/keyset.ts): KeysetPage, keysetAfter, forwardPage. The page-envelope vocabulary. offset pagination
worker runtime The ONE isolate-level ManagedRuntime (worker singletons + the composed FateServer) the compile step runs every fate handler through; built once in worker init, never disposed on Cloudflare (ADRs 0041/0042). a per-request runtime

fate (the data layer)

Term Definition Not
fate The Relay-inspired typed data client (@nkzw/fate); the data layer end to end (GraphQL + Relay torn out). GraphQL, Relay
data view (dataView) fate's per-entity field declaration. Views are the schema. A fate data view is a read-shape declaration, NOT a Drizzle table — see the definition_record/comment_record store-of-record note below (#853). The _record-suffixed Drizzle tables were renamed off *_view precisely so "view" is reserved for fate data views (DefinitionView/CommentView). a GraphQL type; a Drizzle store-of-record table
ConnectionResult fate's connection payload (items + pagination). Edge, PageInfo
Entity<> The type a resolved view produces; the shared client/server type contract.
LiveDO The unified void-aligned live-view Durable Object — ONE class, two roles, state.storage KV. Fans out mutations' live.* events to subscribers over SSE (ADR 0037). two classes named ConnectionDO + TopicDO (see below)
ConnectionDO / TopicDO The former, superseded two-class live-view design. Today there is ONE class, LiveDO, with two roles (connection, topic) dispatched via resolveRole(state.id.name) — not two Durable Object classes (ADR 0037). live Durable Object class names (they are roles of LiveDO, not classes)
void The upstream live-streaming Durable Object reference (VoidLiveStreamDurableObject) that LiveDO mirrors; the design authority for LiveDO's DEFAULT_LIMITS, the queue-full→410 behavior, the first-failed-probe reap, and the stale/replay model. inventing LiveDO limits/reap semantics from scratch
optimistic slice One per-mutation optimistic-update unit (epic #1637): the client writes the mutation's effect into fate's normalized cache the instant the user acts, then reconciles by canonical id against the server frame (ADR 0125) — adds are A1 client-append + canonical-id dedup (an optimistic temp node the server row replaces, no flash/dupe), deletes are D1 reply-aware drop (a plain edge-drop for a leaf, a conservative [silindi] tombstone when replies are loaded), with rollback on rejection. Each slice ships dark behind its own default-off flag, retired once it graduates to served-on; epic #1637's family has fully graduated and every gate is inlined, so no optimistic-slice flag is declared today — what is still flagged is read off the live registry (apps/web/src/flags/keys.ts), never off this row. The DOM-free decision helpers are hook-free modules beside their surface (apps/web/src/pages/) or in the shared fate client layer (apps/web/src/fate/); their shape is .patterns/fate-mutations-client.md. one shared epic-wide flag (each slice has an independent dark-ship lifecycle); a client-invented final id (the server id is canonical — the temp node reconciles to it); a roster of dark-ship flag names (they graduate and retire — apps/web/src/flags/keys.ts is the live declared set)
role (connection / topic) LiveDO's two roles: connection owns one client's SSE stream + subscriptions; topic owns a topic's subscriber registry, publish fan-out, and reap alarm.
shaper Maps a DB row to an Entity field set (shapers.ts).
source A Fate.source(ViewClass, {id}, handlers) loader entry delegating to Effect services (sources.ts); fate never queries D1. The loader half (silent reads). a source that throws not-found
useView / useListView Client hooks reading a single entity / a paginated list from the normalized cache.
useLiveView / useLiveListView Client hooks subscribing a view/list to live SSE updates. Drop-in for the non-live variants.
useRequest Client hook resolving a screen's whole composed view tree in one batched request.
ViewRef A normalized handle to an entity (type + id), not its data; resolved via useView.

fate-effect

Term Definition Not
fate-effect The workspace package (packages/fate-effect): fate's structure × Effect's semantics — phoenix's anti-corruption layer over fate. Core exports: Fate, FateDataView, FateServer, FateInterpreter (the native serving path the /fate route runs — ADR 0043), LivePublisher (+ CurrentUser) (ADR 0042). rewriting fate
Fate constructors Fate.query/list/mutation/source — value constructors pairing a pure-data definition (Schema input, success view, declared error union) with an Effect.fn handler. raw generators as handlers
FateServer The package-owned service tag (HttpRouter idiom — one server per worker). FateServer.layer(config) is the only composite; init-time throws for duplicate wire names and sourceless entities. per-feature server tags
FateInterpreter The native Effect serving path the /fate route runs (FateInterpreter.handleRequest) — no runtime on the request path, RequestResolver batching, spans nesting under the router's request span (ADR 0043). the compiled FateExecutor path (the differential-oracle baseline only)
fateWireCode The one canonical name for the fate wire-error code concept — the FateWireCode annotation key (@kampus/fate-effect) the codec derives wire codes from; one edit per new error. Both ends of the seam spell it FateWireCode: the package annotation key and the SPA literal-union type (src/lib/fateWireCodes.ts). The SPA list + the canonical export name are both guarded against drift by apps/web/worker/features/fate/wireCodes.unit.test.ts. This is one concept under one name (#851, consolidated #1032) — not the ErrorCode / ScreenErrorCode / "wire code" / "boundary" five-way spelling it drifted into. a WIRE_CODE_BY_TAG-style registry; four-plus different names for one concept
CurrentUser The per-request session carrier (packages/fate-effect, CurrentUser.ts): a Context.Service holding the resolved CurrentUserInfo (id / email / name / image) or undefined for anonymous traffic, provided per request alongside LivePublisher (ADR 0042). CurrentUser.required fails UNAUTHORIZED for an anonymous request. This — not Auth — is the per-request session service. the better-auth instance type (that is Auth); a worker-level singleton (it is per-request)
LivePublisher The per-request live-publish service whose publish is Effect<void, never>waitUntil + error-swallowing live inside the layer (livePublisherFor), once. Provided per request alongside CurrentUser.
loader / resolver split source = loader (the dataloader byIds workhorse; E = never, absence = fewer rows) vs operations = resolvers (domain ops, typed errors). Reads silent, writes loud. a source that throws on not-found

Testing

Term Definition Not
test tiers (unit / integration) The two live tiers (ADR 0082, extended by 0104). unit — pure logic + in-process service contracts, no DB: the Drizzle storage seam is substituted, no SQL engine, no deployed worker. integration — real behavior over real remote Cloudflare D1 (+ DOs) via the alchemy Test.make idiom, black-box over HTTP/SSE. There is no in-memory SQL tier. the retired T0–T3 four-tier model; a node:sqlite D1 stand-in (deleted #579)
*.unit.test.ts The pure-test naming convention inside the unit vitest project (the glob catches both *.unit.test.ts and plain *.test.ts service-contract tests). a third vitest project
golden real-payload fixture A committed sample of a runtime-emitted artifact (a harness hook payload, a platform event) captured from an actual live spawn — the only ground truth for anything runtime-defined, over docs / an agent's summary / an inferred contract (ADR 0180). You capture it before coding to any doc-defined contract; a hook/harness handler's test asserts against it and that test blocks merge. The motivating miss: #2925's WorktreeCreate hook was built to a fabricated worktree_path payload and fail-closed every spawn. a hand-authored / doc-assumed payload (that is exactly what it replaces); an advisory check (it is blocking); a mock (it is a real captured sample)
runFateOp Deleted (ADR 0105). The former in-process op-test harness running a fate operation through the compiled fate server over a per-op disposed ManagedRuntime. Removed as a zero-consumer dead end; interpreter dispatch is unit-tested in fate-effect (Executor.test.ts / Codegen.test.ts), route reachability at the integration tier (ADR 0082), and the light app seam is resolveWire. a live test helper (it no longer exists)

Infra / store

Term Definition Not
alchemy (alchemy-effect) The infra-as-Effect layer: one Effect program for infra + runtime, replacing wrangler.jsonc, the Hono entry, manual binding access, and hand-written DO classes (ADR 0026). wrangler
alchemy.run.ts The stack definition (Alchemy.Stack) declaring the worker + D1 + DOs; replaces wrangler.jsonc.
ASSETS The static-assets binding serving the built SPA from dist/client.
D1-direct The architecture (ADR 0009): resolvers read/write D1 directly — no projection layer.
definition_record / comment_record (Drizzle tables) The authoritative mutated stores of record for sözlük definitions and pano comments (D1-direct, ADR 0009; Drizzle exports definitionRecord / commentRecord). Renamed off the projection-era definition_view / comment_view (#853) — that old name lied about the module kind and collided one capital apart with the fate DefinitionView / CommentView data views in the same feature folders. The _record suffix reads as "store of record" and stays distinct from the fate data-view tags (bare definition/comment was rejected because it would overlap those tags). These tables are stores of record, NOT fate data views. a read-projection; the fate DefinitionView / CommentView data views
@kampus/db-schema The leaf package (packages/db-schema) holding the ONE canonical Drizzle declaration of the shared D1 tables — term_record, definition_record, post_record, comment_record — that more than one consumer reads. Depends only on drizzle-orm, so the worker, @kampus/preview-seed, and @kampus/fts-backfill all import it with no dependency cycle; the worker schema re-exports it. Replaces the three hand-mirrored copies whose silent column drift was caught only by real-D1 CI (#859/#903). worker-only tables (better-auth, votes, stats, user_profile, content_report) or the FTS5 virtual tables — those stay worker-private
localState Alchemy.localState() — the offline state store for local dev; CI/deploy use the Cloudflare-hosted store (ADR 0031).
PHOENIX_DB The single D1 database; the canonical store for every product table. ALWAYS a real remote Cloudflare DB (no offline local D1) even in dev/integration. an offline local D1
R2 / R2Bucket Cloudflare object-storage binding that backs depo (ADR 0144, supersedes 0044); provisioned in-tree by the infra/depo stack (infra/depo/depo.ts), which is depo's own stack, not apps/web. Build state only; deploy state is not asserted here.
secret_text / plain_text alchemy worker binding kinds; Config.redactedsecret_text, plain Configplain_text.
stage alchemy deploy --stage <name> → an isolated worker + D1 + DOs per stage.
workerd The local Workers runtime the dev worker and the integration-test deploy run on (sidecar). Needs Node 26 (Node 25 breaks the spawn). miniflare

Feature flags (shipped — ADRs 0081/0093)

Term Definition Not
Flagship Cloudflare Flagship — the chosen feature-flag substrate (ADR 0081); phoenix reads flags server-side + in React and drives Flagship's attribute targeting + consistent-hash percentage rollout. a home-grown flag table, env-var flags
effective serving What a flag actually serves, computed rules-first (#1726, packages/anka-ops flagship-core.ts): the no-match split — a conditions-empty rules[] entry carrying rollout: {percentage} — serves on to N% and lets the remainder fall to defaultVariation; rendered on@100% (split) / on@N% (ramping) / off (default), with a +N targeting rules note. The answer flag get / flag list print. the bare defaultVariation reduction (it lies about a split-released flag); the dashboard's "zero targeting rules" reading (the split IS a rules[] entry)
feature flag A named, runtime-flippable toggle gating a code path; the containment seam for ship-behind-flag delivery. Declared per a naming grammar + lifecycle convention (.patterns/feature-flags-schema-lifecycle.md).
ship-behind-flag The agent delivery workflow (.patterns/feature-flags-agent-workflow.md): merge a feature dark behind a flag, validate in production, then a human flips it on (ADR 0083, deploy-vs-release).
flag targeting / percentage rollout Flagship attribute targeting + consistent-hash percentage rollout (.patterns/feature-flags-targeting.md) — the same user always lands the same arm.
split release / kill The no-match split is THE release lever (#1726): a release sets the split percentage — anka-ops flag open <key> (full 100%) for a full release, anka-ops flag open <key> --percent N for a ramp — never a defaultVariation flip. kill (anka-ops flag close <key>) is the true kill switch: clear the split AND set the default off, because a bare defaultVariation flip does NOT turn a split-released flag off. Writes dry-run by default; --execute applies. flag open/flag close are the human release act (ADR 0083). a defaultVariation flip (neither the release nor the kill); an agent act (agents deploy, humans release)
phantom release A ship-it release-queue defect: a status:awaiting-release label that points a human releaser at a flag flip that does not exist, eroding trust in the queue. Two mis-fires closed it — labeling an ungated ship (an a11y/UX foundation with no dark-ship flag) as awaiting-release (#1257), and a merely-illustrative docs/example mention of a genuinely-declared flag key mis-firing ship-it's Step 5b signal (c), now scoped to require the key in a real gating context, not documentation prose (#2897). a genuine dark ship (a PR that really introduced a default-off FlagshipFlag in the diff — that queues a real awaiting-release); a flag flip/kill act (ship-it never flips a flag — it only surfaces the queue)
@kampus/anka-ops The operator CLI for anka-built apps (packages/anka-ops, epic #2089, ADR 0045) — the single authenticated surface an operator (human or agent) runs scoped infra ops from, and the single home for the Cloudflare Flagship read/flip surface (relocated from the retired @kampus/cf-utils, ruling #3326). node src/bin.ts flag <list|get|open|close|graduate> reads and flips Flagship flags across every env from the terminal, so a release flip is a traceable, reviewable command instead of an untraceable dashboard click. Built on a typed Effect read client (FlagshipRead) wrapping the canonical @distilled.cloud/cloudflare flagship ops — the same transport @kampus/d1-rest runs D1 over, no third raw-curl copy (#941) — over a pure, unit-tested decodeEnv/decodeFlagState core; creds from $CLOUDFLARE_API_TOKEN/$CLOUDFLARE_ACCOUNT_ID at runtime, never source. the flag IaC (declaring/creating flags — that stays in apps/web/worker/features/flagship/resources.ts); a dashboard flip; a new raw-curl client

Edge-resolved shell state (ADR 0179)

The worker-first HTML render that injects the geometry-critical shell state at the edge so the first paint is already correct — zero CLS, no boot→fetch waterfall. Coined by ADR 0179 (§Vocabulary impact), the law the build epic #2926 implements against; the governing principle is cohesiveness (one source of truth, everything renders at the same time, correctness over milliseconds). This names the nouns.

Term Definition Not
shell state (edge-resolved) The above-the-fold, geometry-critical state the worker resolves and injects at the edge (ADR 0179 §1–2) so the initial paint is already correct — zero CLS, no boot→fetch waterfall. Exactly the nav-shaping flags (MECMUA_PUBLIC_READ / MECMUA_FEED) + session presence (signedIn) + reserved chip slots when signed in. Shell-critical = state whose wrong value moves geometry at first paint (the geometry law, founder ruling #2830); nothing else may gate shell geometry. Resolved per request under the full-session userId context via env.ASSETS.fetch + a streaming HTMLRewriter, never cached. chip values (karma / unread count / avatar — those late-fill into the reserved slots from fate, #2160); below-fold flag/data state (stays on the client useFlag fetch path); a cached response (viewer-dependent HTML carries signedIn, never cached — ADR 0170 intact)
window.__BOOT__ contract The <script>window.__BOOT__={…}</script> payload the streaming HTMLRewriter appends to the asset response (ADR 0179 §2–3), read synchronously by a unified useFlag — a key that is a member of __BOOT__ resolves with loading: false and no fetch; every other key keeps the existing fetch path. Carries three booleans (the two nav flags + signedIn) and no fate data. Membership is defined by the shell-key manifest and enforced by a fail-closed guard across the worker/client seam. Never-hang invariant (§4): Effect.timeout wraps the boot reads, and on timeout or any Flagship/D1 failure the worker falls back to the untransformed, byte-identical asset response while the client treats __BOOT__ as optional and keeps its fetch fallback — a Flagship outage degrades to today's edge-direct behavior. a cached response (the HTML is never cached — every hard reload renders fresh); a localStorage mirror (rejected — one source of truth); a fate-data carrier (three booleans only)
shell-key manifest The single declared source enumerating which flag keys are shell keys (ADR 0179 §3) — consumed by both the worker __BOOT__ injection and the client useFlag, with a fail-closed guard so a shell key can never drift out of sync across the two sides. Same idiom as the fanned-mutations classifier (ADR 0155). A key's membership in the manifest is what makes useFlag resolve it synchronously off __BOOT__ instead of fetching. an arbitrary flag list (only geometry-critical keys qualify — the geometry law); a one-sided declaration (both worker and client read the same manifest, guard-enforced); the containment flag the edge-render path once shipped behind (it gated the injection, never named a shell key, and retired with #3672)

Search (FTS — shipped, ADR 0080)

Term Definition Not
site search v1 is a lexical search bar (/search?q=), not semantic discovery — ADR 0080 splits the two. semantic search (a separate product)
term_search / post_search The SQLite FTS5 virtual tables backing sözlük/pano search; kept current by a dual-write sync path off term_record / post_record.
fts-backfill Direct-D1 one-time CLI re-indexing existing summary rows into the FTS5 tables through the dual-write path (packages/fts-backfill). a runtime backfill route
⌘K command palette (single search contract) The single search entry point on kamp.us — "the one search contract made physical" (ADR 0186). One ⌘K palette, one affordance, over the global search contract: the three legacy "ara" surfaces (topbar / subnav / inline) collapse into it. The collapse is incremental, surface-by-surface, with #2995 (sözlük search → ⌘K) as fold step 1; each remaining surface folds toward the end-state the ADR fixes. v1 is search-only. a command runner (v1 is search-only; a command-runner evolution is out of scope); a per-surface search reimplementation (a11y — keyboard / AT / reduced-motion — is code-authoritative via the a11y-spine contract, not redone per fold); a deferred big-bang (the collapse is incremental, surface-by-surface, each fold toward the ADR-fixed end-state)

Run-evidence / CI gating (ADRs 0054/0056/0058/0092)

Term Definition Not
ambient ADR discovery The .decisions/ discovery model (ADR 0126, superseding 0066's storage half; ADR 0129 dropped the SessionStart hook): the committed index.md is deleted — frontmatter is the row (id/title/status/date/tags; filenames keep NNNN-slug so ls .decisions/ alone is a usable map), and no on-demand id · title · status map ships today — v1's decisions-index compact rendered one and was deleted with its package (#6100), with #6332 tracking the gap (it was never auto-injected into session context either; ADR 0129 dropped that indirection). Discovery is the CLAUDE.md contract alone, uniform across every context (session, subagent, CI): ls .decisions/ + frontmatter. Main history stays 100% PR-connected — no bot regenerate push. a committed/bot-regenerated index.md (the drift + GH013-rejected-push failure class 0126 deletes, #1718); a SessionStart hook auto-injecting the map (dropped, ADR 0129)
run-evidence bundle A SHA-bound, machine-readable manifest of a CI run the merge gates trust instead of prose (ADR 0054). trusting prose / a green checkmark alone
crabbox The run-evidence pipeline: crabbox-manifest (pure transform: run-summary + JUnit + logs → manifest) feeding the gate consumers (.patterns/crabbox-run-evidence.md).
SHA-bound verdict A gate verdict pinned to the exact head SHA it reviewed (ADR 0058); a re-push invalidates it. an unpinned PASS comment
fail-closed gate The ADR 0092 invariant: a gate whose enforcement scans zero scope must fail, never silently no-op. a silent no-op gate
declared restrictive sentinel The one restrictive answer a safety-answer script (a script whose stdout a call site reads as a safety value) declares as its usage-miss emission (ADR 0234): a usage-miss exits non-zero and prints EITHER nothing (the silent class, the default) OR exactly the declared sentinel and nothing else; verify-extraction.sh check 9 verifies against the declaration. Deleting or weakening a value-sensitive sentinel to green the check is banned — the check must never be satisfiable by the fail-open edit. the permissive/skip answer (the sentinel is the answer that holds the guard armed — containment-marker.sh's flag/ARMED); a diagnostic (those go to stderr per the IO contract, .patterns/skill-script-io-contract.md); a license for silent-class scripts to print on a usage-miss (they stay under the empty-stdout assertion)
control-plane The .claude/ + .github/ + gate-critical-skills surface a human merges by hand; the pipeline refuses to self-ship it (ADRs 0053/0063/0065). an agent-merged control-plane PR
isolation:worktree The worktree-isolated agent-spawn mode: a spawned pipeline lane (coder / reviewer / shipper / adr / canon) works on its OWN git worktree copy under .claude/worktrees/ instead of the owner's primary checkout, so parallel lanes never collide on one working tree. Wired through the worktree-guard (PreToolUse mis-write + SubagentStop reap) and drained by worktree-sweep; bootstrap-deps are provisioned per ADR 0109. the owner's primary checkout (a non-worktree subagent shares it, and CAN mutate its git state); the WorktreeCreate fast-path provisioning hook (create-worktree.sh of #2924/ADR 0178 — the file exists but hooks.json no longer registers it, reverted #2938, so provisioning falls back to the harness default path)
worktree-sweep The safe-by-default bulk reaper (pipeline-cli worktree-sweep [--execute], packages/pipeline-cli/src/tools/worktree-sweep/, #1243/#2785) that reclaims the two leaked worktree classes accumulating on an operator's machine — the harness-provisioned build trees under .claude/worktrees/ and the $TMPDIR-rooted review-head-* detached checkouts the review gates materialize. The pure classifier marks a tree removable ONLY when CLEAN, reachable from origin/main, and provably not-in-use (unlocked, mtime-idle, no open PR — the #2240 liveness guard); git worktree remove runs WITHOUT --force so git itself refuses a dirty/live tree (reported KEPT). DRY-RUN by default; SessionStart-installed via the plugin's --execute hook. a blanket worktree remove --force (never — dirty/live/unmerged trees are KEPT); the worktree-guard (that is the PreToolUse mis-write guard + SubagentStop reaper — this is the periodic bulk drain)
leak-guard The pure, IO-free no-local-paths matcher + CI-callable scan (fabrika guard leak-guard scan <file>, packages/fabrika-cli/src/guard/leak.ts, #173; the comment-body arms scan-comment/scan-pr stay in packages/pipeline-cli/src/tools/leak-guard/ until that package is deleted) — the write-time enforcement of the repo's no-local-paths rule after a machine-local path once shipped to main (#158). findLeaks(filePath, text) flags a machine-local home / user / sibling-clone / vault path only in a SHARED artifact surface — doc (markdown, plus anything under .decisions//.patterns/) or shell (.sh, added in #4496 once epic #4435 began extracting pipeline shell out of markdown fences) — or in a PR/issue comment body; exit 2 on a leak — CI fail-closes, the pre-commit hook fail-opens (#332). A precise deny-list of the specific #158 leak dirs, NOT a broad home-dir catch-all, so an unrelated dotfile dir or the scratch tmpdir PASSES. a general regex over arbitrary source (it scopes to the two named surfaces + comment bodies — .ts/.yml/.json are deliberately out); a broad home-dir catch-all (only the specific #158 leak dirs match — the load-bearing false-positive safety)
verdict post (guarded verdict-emit path) The single mandated choke point for emitting a gate verdict marker (pipeline-cli verdict post, #2102): every review-* gate posts its SHA-bound PASS/FAIL through the deterministic tool, which runs the emissionDefect gate and refuses fail-closed unless every @ <sha> field is a clean 40-hex head SHA (closing the mktemp-path leak #2683, the empty-@- case #2646, cross-namespace bodies). The guarded emit path is mandatory across review-code/-doc/-skill/-trivial (#2824) — a bare gh pr comment / jq hand-post that skips the guard is FORBIDDEN (the emit-side hole #2789/#2816/#2818), and any genuinely unavoidable raw post MUST first pass leak-guard scan-comment (#2823). a hand-rolled gh api …/comments / gh pr comment verdict post (forbidden — emissionDefect never runs off the guard); the native APPROVE review path (posts a review, not a guardable comment — gated by a verdict validate read-back instead)
right-sized fan-out (trivial-diff tier) Routing a review to a gate sized to the diff: a trivially-classified PR takes the lighter gate instead of the full review-code/review-doc/review-skill fan-out, capturing the saving at the gate's prompt cost, never its authority to FAIL (ADR 0120). Shipped-but-dormant — off by default, adoption gated behind #1560's two-axis measurement (ADR 0112). Composed from the classifier (#1557) + the lighter gate (#1558) + the executor wiring (#1559), all of which retired with the v1 tree (ADR 0303) — read ADR 0120 for the shape. skipping the gate for a small diff (ADR 0120 option (b), rejected); an adopted/on lever
trivial-diff classifier The deterministic, fail-closed predicate (pipeline-cli trivial-diff classify, #1557) that marks a unified diff trivial only on a hard-AND of bounds — single small/doc-or-comment-only file, no new surface, and no path matching the live CONTROL_PLANE_RE re-resolved from origin/main. Any failed bound, parse error, or unreadable boundary ⇒ non-trivial (default-deny). a taste/vibe call; a stale-boundary snapshot; a third "unknown" verdict
lighter gate (review-trivial) The reduced-prompt but still fail-closed verify path (review-trivial skill, #1558) a trivially-classified diff can take: a tight scoped checklist (right change vs AC, no leaked secret, no leaked machine-local, home, absolute or sibling-repo path) run by an independent reviewer, emitting a SHA-bound PASS/FAIL in the existing review namespace. Re-affirms triviality itself and DECLINEs to the full path if the diff is not actually trivial. a skipped gate (only the prompt cost is reduced, never the authority to FAIL); a self-review by the author (the split-role firewall holds); a new verdict marker namespace
corpus (eval-harness) The labeled ground-truth set per pipeline stage the graded eval-harness reads (eval-harness/corpus/*.json, epic #1842; ADRs 0146/0112). The graded generalization of ADR 0112 §1's single frozen input — many pinned inputs per stage (happy path + at least one edge/error class), each carrying the recorded baseline decision artifact as its ground-truth label, pinned by issue/PR identifier and grown append-only. Big enough that a pass-rate is meaningful, not n=1. ADR 0112 §1's single frozen input (this is the set that generalizes it); "a recent issue" (every entry is pinned by id); a live-queried expectation (the label is the recorded baseline)
graded oracle (eval-harness) The per-corpus-entry quality grade (eval-harness/oracle.ts gradeEntry, #1849) — ADR 0112 §3's binary same-decision-artifact oracle applied to each corpus entry rather than one frozen input, so the harness can compute a pass-rate over the set. Pure and total (a malformed/absent artifact grades fail with a stated mismatch, never a throw). The statistical form the binary n=1 oracle lacks — the evidence a stochastic model swap needs (ADR 0146). ADR 0112 §3's binary single-input oracle (this grades the whole corpus); a bare pass/fail boolean (a fail carries the field-level mismatch)
pass-rate (eval-harness) The fraction of a (stage × model)'s graded corpus runs that reproduce their recorded label — the quality statistic n=1 cannot supply, distinguishing a model that reliably reproduces the baseline from one that got lucky once. Counts only repair-forcing gate outcomes: a crash/infra flake is a failure-classifier TRANSIENT death, excluded so churn isn't inflated with flakiness the model doesn't own. The graded quality axis of ADR 0112 §4's two-axis veto for a stochastic swap. a single-run PASS (a pass-rate is over the whole corpus); a rate that counts infra flakes as model fails (TRANSIENT deaths are excluded)
repair-churn cost (eval-harness) The net-token price of a stochastic model swap (eval-harness/repair-churn.ts, #1850): the extra write-code→review→repair cycles a fail-prone cheaper model forces, priced as a geometric expectation from the pass-rate (expectedExtraCycles = (1 − passRate) / passRate, churnTokens = expectedExtraCycles × tokensPerRepairCycle), so a swap is judged on amortizedTokensPerRun = tokensPerRun + churnTokens — a negative netSaving being the crossover ADR 0112 §2's per-run meter cannot see. Token inputs reuse the token-spend four-usage-component reconstruction read-only — no second meter. the per-run token delta alone (churn is the cost that delta hides); a hidden NaN at pass-rate 0 (it is an honest +Infinity = "never adopt"); a new token meter (it reuses token-spend)
live stage key A member of STAGES in packages/fabrika-cli/src/eval/corpus.ts — the eval harness's live stage vocabulary (ADR 0244): what --stage accepts, what a CorpusManifest groups entries under, what a CaptureRun.stage carries, and what the runner and the scorecard join on. A group key always names a stage that exists now, so a group key may be looked up in STAGES. A name enters STAGES only once its skill exists on disk and there is committed ground truth to grade under it (the stage-admission rule in packages/fabrika-cli/src/eval/README.md). a recorded row's own stage field (that is recorded provenance, and it is never resolved against STAGES); a home for a retired stage name — a retained row's old key must never reappear in STAGES (ADR 0244 §3: that would make --stage write-code runnable again and re-admit new rows under a dead pipeline); a record of provenance when it sits on a capture manifest (CaptureRun.stage is join material, so re-keying it to the live successor is the migration — ADR 0244 §4); a plan of the fabrika skill set (it records what the harness can actually grade today)
recorded provenance A committed corpus row's own stage field — which pipeline actually produced the labeled artifact, frozen at record time exactly as its label is (ADR 0244, extending ADR 0112 §1's growth rule from label to stage). The founder ruling on #4977 is that recorded provenance wins: the six v1-produced rows keep their original write-code / review-code keys, each retired name admitted only through its own Recorded*Entry schema member inside the live group that succeeded it. A row whose stage is absent from STAGES is not corrupt — it is a record of a pipeline that no longer exists. a live stage key (a row's stage is never a pointer into STAGES, and resolving it against the live set is banned); re-keyable (re-keying a v1 row onto a fabrika stage name republishes a v1 measurement as a fabrika baseline — the thing the ruling exists to prevent); a key new rows may be filed under (a recorded-only schema member decodes history, it never accepts new rows); indistinguishable from a live-key row while a v1 name is still live (ADR 0244 §2's stated limit, since resolved — ADR 0243 collapsed the review stage, so STAGES is triage / build / review / ship-it and both retired keys, write-code and review-code, are now recorded-only); anything that applies to incident-corpus/ (ADR 0244 §5 — those files carry no stage key at all, and the ruling must not be extended to them)
review surface The sub-discriminator every review eval-corpus entry and label carries — code, doc or skill (REVIEW_SURFACES) — which selects both the admissible label shape and the grader (ADR 0243). The corpus keeps one live review stage key and gradeEntry dispatches on the (stage, surface) pair, never on stage alone; surface is required, with no default and no inference, so a review entry without one is a decode failure rather than a row graded by a fallback rubric. A PR reviewed on two surfaces produces one row per surface for the same inputRef — no composite label, no primary-surface tiebreak — and a pass-rate is reported per surface, never averaged across surfaces (§4). a GitHub label, a triage input, or the runtime rubric-router (ADR 0243 §5 — the review skill's rubric selection stays derived from the diff); a stage key (three live review-* stages was the rejected alternative, §6; review-code survives only as recorded provenance); the v1 review-* skill family or the verdict-marker namespace class (`/^(review

rite-audit (the çaylak→yazar audit harness — epic #1510)

The judgment-audit harness for the earned-authorship rite: a deployed-stage walk that asks "can a real person complete the çaylak→yazar rite end to end, no human in the loop?", not "does each unit test pass". Nothing of it survives in the tree. The explorer was specced as a v1 skill and retired unbuilt with the kampus-pipeline plugin (#5937); its lifecycle/runner/serializer packages were deleted as consumerless (#6346). Two nouns outlive it because they name things that still exist, and they are what this section keeps.

Term Definition Not
rite (çaylak→yazar) The earned-authorship rite the harness audits: the full walk from çaylak to yazar — self-register, write sandboxed work, get vouched (kefil) in the divan, watch the tier flip on the profile. The product subject of rite-audit; walkable only where phoenix-authorship-loop is forced on (the audit stage). the authz mechanism (that is künye / packages/authz); a single capability check
audit env class / authorship-loop force-on The rite-audit gating prerequisite (#1511). audit is a dedicated fourth deploy class in the ENVIRONMENT taxonomy (development / preview / production / audit, apps/web/worker/environment.ts; ADR 0088). The force-on seam is AUTHORSHIP_LOOP_RULES (features/flagship/resources.ts): a single environment-targeting rule serving the phoenix-authorship-loop flag on iff the request's environment attribute equals auditaudit-only, prod-never (production can never map to audit, so the rite is walkable only on the audit stage; the flag stays default-off everywhere else, the dark-ship safe state). a production flag flip (phoenix-authorship-loop on in prod releases v1 to the public); a default-on or percentage-targeted rollout

Orphan-heal (ADR 0205)

How an open PR that no lane owns and that is red on its head becomes pullable board work. The crew that once framed these two nouns is gone (ADR 0279); the detector, the heal-item and the pull loop that consumes it are not.

Term Definition Not
orphan red PR An open, not-draft, CI-red-on-head PR sitting in no engine lane (not opened-from-a-triaged-issue by an engine, no active claim), red past a short grace window (ADR 0205; live instance #3501). Invisible to the engine pull loop by construction — engines heal only lanes they own — so the detector converts it into a heal-item rather than any engine adopting it directly. a reviewer-FAIL PR inside an engine's own lane (that is the existing in-lane coder repair path); a draft or mid-CI PR (the grace window + not-draft predicate exclude both); a PR any engine may free-scan-adopt (rejected — that would broaden engine mutation authority to PRs whose intent it doesn't own)
heal-item The triaged, immediately-claimable issue ("heal red CI on PR #N", pointing at #N + the failing check) that a scheduled detector emits to convert an orphan red PR into pullable board work (ADR 0205). Idempotent — one heal-item per PR. An engine pulls it like any other claimable work, thereby owning a lane bound to #N, heals with the unchanged diagnose→repair→re-run-CI machinery, and closes it on green. a free-scan adoption step (the whole point is that the lane exists before any engine touches #N); a chief-of-staff duty (the detector is a cron/poller, board-native rather than riding any role's attention — and that seat itself left with ADR 0279); founder-directed targeting (that is EngineNudge, #3534 — complementary)

Deterministic tracker mechanics (the Tracker service — epic #3247)

Wave 1 of the #3247 emission (epic #3258): the recurring GitHub-tracker interactions stop being hand-composed gh api envelopes re-derived per skill and become shared pipeline-cli verbs against a domain-shaped Tracker service. This names the noun.

Term Definition Not
Tracker (GitHub-issue layer) The shared Effect service (tag + provided layer, epic #3258) consolidating the Github/GithubLive idiom into one domain-shaped GitHub-issue tracker abstraction — issues / labels / comments / claims / maps. Signatures are domain-shaped (claim / apply-triage / post-verdict / graduate) with NO GitHub semantics leaking through (no sub_issue ids, label strings, or REST idioms in the signature); its claim verb is the ADR-0115 issue-claim envelope. GithubTrackerLive is its only implementation. anything past the tracker surface — the merge/review substrate (merge queue, §CP CODEOWNERS, the ADR 0055 ACL trust root) stays GitHub-native, never behind this service. Also not a pluggable-adapter surface (GithubTrackerLive is the sole impl; the GitHub/Asana/local-markdown adapter future is the separate epic #3256)

wayfinder (the ideation layer — epic #2421)

The pre-triage ideation layer that sits upstream of the execution pipeline: where the pipeline (report → triage → plan-epic → review-* → ship-it) drains already-decided work, wayfinder is where a fuzzy destination is charted into a workable plan. It coins its own vocabulary; this names those nouns. The v1 wayfinder skill retired with the kampus-pipeline plugin (#5937); the living successor is fabrika's wayfinding skill, which owns the map-issue shape.

Term Definition Not
wayfinder The ideation-layer skill/construct (epic #2421) upstream of the execution pipeline: charts a fuzzy destination into a living wayfinder:map issue and works its open frontier down until a concrete plan is ready to hand to triage / plan-epic. Two modes — chart (open/rewrite a map) and work (advance one frontier ticket) — and one preserved human seam (founder-decision-fork). Produces a clarified plan, never code or a merge. the execution pipeline (wayfinder feeds it, is not part of it); a code-writing or merging skill; a decision-maker (it frames founder decisions, never resolves them)
wayfinder:map The GitHub label + issue shape a wayfinder map carries: an issue-shape marker (not a type:*, not a status:* pipeline state) marking an issue as a living map whose body has the four sections destination / decisions-so-far / open frontier / graduated fog — the shared-state contract the chart/work modes and the wayfinder CLI read and write. Reuses ordinary issue infra, so it ripples no intake floor. Not write-code-pickable. a type:* or status:* label (it is neither — reusing issue infra is the point); a pickable execution issue (only the work it graduates becomes pickable)
wayfinder:backlog The GitHub label + queue holding fuzzy destinations: fog awaiting charting, one step upstream of triage — an issue carrying it is deliberately not status:needs-triage and not write-code-pickable. triage routes a report here on the sharpened fog discriminator — no buildable deliverable ⇒ fog ⇒ wayfinder:backlog — swapping the labels in one intent (add wayfinder:backlog, drop status:needs-triage), so fog enters through the type-blind /report like everything else and the fog-vs-buildable call stays where classification already lives. Coined in ADR 0203. Charting is the ordinary exit; ADR 0210 amends 0203 in part by adding a second one — fog left uncharted for 3 weeks expires and comes back with a pitch — which does not reach a cluster parked by design — carried, for now, by the named new products ADR 0072 §4 freezes (imge / kampus-CLI / künye), or the axis:pipeline-hardening standing lane: that exemption is tested first, and bare milestone-absence never confers it. The enumeration is the interim carrier only — the founder ruled (2026-07-25, on ADR 0210's PR) that a frozen cluster gets its own status:frozen label; the label is not created yet, and the rule keys on it only once the frozen clusters carry it. The standing-lane exemption ADR 0208 grants this label (see the standing lane row) is from milestone homing, not from the clock — uncharted fog still expires. a status:* pipeline state (it is a routing/queue label, not an intake lifecycle stage — an issue here is not status:needs-triage); wayfinder:map (the backlog holds un-charted fog, a map is a living charted destination); a write-code-pickable issue (only what a map graduates becomes pickable); a home for concrete work (a nameable buildable deliverable is never routed here)
destination A wayfinder map's ## Destination section: the named end-state the map steers toward — one or two sentences, concrete enough to tell "arrived" from "not yet." The fixed star, changed only in chart mode. a task or acceptance criterion (it is the direction, not a unit of work); a mutable running log (it is the stable target)
decision-so-far An entry in a map's ## Decisions-so-far accreting answer log: a settled decision or established fact, appended (never deleted) as work mode resolves each frontier ticket, naming what was decided and its source ticket (— from #N). A later revisit adds a superseding entry, keeping the log auditable. the record of motion (that is fog-graduation / ## Graduated fog); an open question (that is the frontier); an editable/overwritten field (append-only)
frontier A map's ## Open frontier: the live edge of the unknown — the open investigation/decision tickets kept as native sub-issues of the map. Shrinks as tickets are answered, grows as answers reveal new unknowns; a map is "done enough" for pipeline handoff when it holds no more answerable unknowns. a settled decision (that is a decision-so-far); a copied task list (frontier tickets are real linkable sub-issues, referenced by number)
fog-graduation The map's forward motion: a frontier ticket's answer landing in decisions-so-far and the ticket graduating off ## Open frontier into ## Graduated fog — often spawning the next frontier ticket (→ spawned #M). ## Graduated fog records how the fog cleared (the history of motion), distinct from decisions-so-far's record of what was decided. The three move in lockstep, so a resolved unknown is never left without a recorded answer. a decision-so-far (that records what; fog-graduation records how it moved); deleting the ticket (it moves to graduated fog, staying auditable)
founder-decision-fork The one preserved human seam: a frontier ticket that is a product/direction choice the founder must make — not an answerable question of fact. wayfinder surfaces the fork (options + trade-offs on the map) and stops, never auto-resolving it — the human-in-the-loop boundary the whole ideation layer preserves (the product-driven-decision boundary, ADR 0078). an investigation ticket (which work mode clears autonomously); a decision wayfinder makes on its own authority (it frames, never decides)

Campaigns (the roadmap campaign layer — epic #2652)

The roadmap-layer container for audit/work waves: a bounded, milestone-backed push drained through the platform lane concurrent with the active product arc. Coined by the campaign-skill epic #2652 (roadmap map #2620, decisions #2641); grounded in ROADMAP.md ## Campaigns + ADR 0072 (milestones-encode-sequencing) and ADR 0078 (engineering-led on platform). This names the nouns.

Term Definition Not
campaign A bounded, milestone-backed roadmap object drained through the platform lane, running concurrent with the active product arc (ROADMAP.md ## Campaigns; milestone-as-strategic-sequencing per ADR 0072, engineering-led per ADR 0078). Each campaign owns its own milestone; the first instance is the Mentor Audit campaign (milestone #27, the parked #2551–2570 mentor-audit cluster). a product-arc milestone (a campaign runs alongside the product arc, engineering-led, not on it); a label-only bucket with no milestone; a feature-breakdown epic (decomposition stays with epics + sub-issues, ADR 0072)
wave label The shared GitHub label marking an audit/work wave (e.g. mentor-audit) that a campaign formalizes into a milestone-backed object — the mentor-audit wave entered as bulk report-filed issues under one shared label (#2641). The label is the raw wave; the campaign is its recorded, milestone-backed form. a milestone (the label is pre-campaign; formalizing it creates the milestone + assignments); a type:* / status:* pipeline label (it marks a wave, not a pipeline state)
founder-approval trace The fail-closed approval marker on a wave label that gates campaign creation — a campaign is created only with the trace present. Invoker-agnostic: a human OR an agent may invoke the campaign skill, but the trace (not the invoker's identity) is the gate — the gated-audit-wave play, findings returned to the founder for approval before filing (#2641). the invoker's identity (the trace is the gate, not who invokes); a default-open path (absent trace ⇒ no campaign — fail-closed); wayfinder's founder-decision-fork (a different human seam)
standing lane A permanent, milestone-less workstream — milestone-less by design, not by neglect — exempt from the 100%-homed rule (every open issue milestone-homed or killed — the rule that amends ADR 0072 §4/§5 in part, relocating its freeze-by-absence signal from milestone absence onto these two labels). Exactly two exist, keyed by label: wayfinder:backlog (fog is upstream of arcs — it homes when charted, ADR 0203) and axis:pipeline-hardening (a permanent lane, not an arc). Nothing else inherits the exemption without a founder ruling; home-or-kill sweeps skip these labels instead of force-fitting a milestone (ADR 0208, extending ADR 0202). a campaign or arc (those are bounded and milestone-backed; a standing lane never completes into a milestone); an unhomed-by-neglect issue (that gets homed or killed); an open judgment category (the exemption is the label match, exactly two)
paused campaign A campaign that is alive but not being executed: its GitHub milestone stays open, and no lane opens against it. It is the third State value in ROADMAP.md's ## Campaigns table, coined by ADR 0304 so one cell can answer both "is this campaign alive" and "may a lane open here". It is also the state a new row is written in: appending a campaign records it, and flipping the cell to active is the separate act that makes it dispatchable. Resuming is that same flip — the one-cell edit that used to be a focus declaration. Guarded by roadmap-guard I5, which requires an open milestone under a paused row exactly as under an active one. done (that means the milestone closed; a paused campaign's milestone is open); a board freeze (pausing every campaign turns the fence off, admitting everything — it is not a global stop); a queued arc (arcs sequence ahead and pin their milestone lazily; a campaign never queues)
scope admission The predicate deciding whether an issue's home is pinned by an active campaign — computed in exactly one place (#5015) and consumed at both fabrika build seams: build pick's pool filter (off-campaign work is never offered) and build claim's refusal (an off-campaign number handed over directly is refused, which is where the fence gets teeth, #5016). Its input is the State column of ROADMAP.md's ## Campaigns table (ADR 0304, which retired the separate ## Focus surface ADR 0298 governed); no active row admits every issue — running no campaign is the off switch, not a board-wide freeze — and a table that reads but does not parse is UNKNOWN, never "nothing is active". The refusal is overridable, but only explicitly: the override is named at the call site and recorded on the issue, so a silent override is not one. Fabrika-only per ADR 0238 — no v1 fence is built. Coined by ADR 0245. priority (campaign membership confers a home, never a band — ADR 0219; admitted work still ranks by priority exactly as before); dependency eligibility (the separate build eligible predicate, derived from the blocked_by graph — is this in an active campaign vs are its blockers closed, never merged into one answer, and a scope refusal never reads as blocked); the milestone pick-order tiebreaker of ADR 0072 (which orders within a priority bucket and never excludes); ready-for:agent (the audience axis build pick's label filter already carries — a different question from campaign membership)
campaign lifecycle (active/paused/done) The three campaign statesactive (draining, and dispatchable), paused (alive, not being executed) and done (complete) — carried in the ROADMAP.md ## Campaigns table's State column, with guard coverage: roadmap-guard's I5 symmetry (#2660) fails closed when the cell and the milestone's open/closed reality disagree. paused joined the set with ADR 0304, which made the cell the dispatch permission. a one-way / write-once status (a paused campaign resumes by flipping the cell back); an unguarded free-text field (I5 covers every state); a queued arc state (campaigns are not sequenced ahead)
Pipeline Anywhere The pipeline-productization program (an active campaign in ROADMAP.md ## Campaigns; wayfinder map #4319): make the phoenix-homed pipeline (ADR 0201) fully consumable by non-phoenix repos across its three channels — plugins, CLI, and reusable workflows (the first two validated live outside phoenix, #4333; workflows are the unbuilt channel). GA shape per ADR 0221: two customer tiers (tier 1 same-org — kamp-us repos calling phoenix's reusable workflows by reference with secrets: inherit; tier 2 outside adopter — explicit-secrets inputs + config seams, dogfooded on a founder-owned personal-account repo outside the kamp-us org), four staged GA gates (mechanism beta → RC → GA → post-GA fresh-bootstrap proof) replacing milestone-closure-as-proxy, and a hybrid guard menu where every guard declares its prerequisite band (tier 0 plugins+CLI → tier 1 file-scanners → tier 2 process → tier 3 control plane) enforced by doctor per selected guard, default install tier 0. an extraction of the pipeline to its own repo (rejected — phoenix stays home, ADR 0201); milestone-closure-as-GA (GA is the four checkable gates); a flat guard menu or globally-forced tiers (prerequisites are per-guard facts, selection is preference); the guard-band tiers ≠ the customer tiers (same word, two ladders — bands gate guards, customer tiers name who consumes)

Factory governance (direction binds at intake — ADR 0210)

How the roadmap steers the factory (ADR 0210, ruled on wayfinder:map #3227): direction binds structurally at intake, never at merge — no finished PR ever fails for direction, and platform work is budgeted through a founder-set lane quota per cycle (2 of 6 lanes, over-quota work parking in priority order), never exempted and never judged per-item. The pattern is Shape Up's shaped-pitch / appetite / betting-table plus a cadence heartbeat, adopted for the AFK factory. This names the nouns.

Term Definition Not
pitch The intake-binding work brief (ADR 0210) — Problem / Arc / Appetite / Rabbit-holes / No-gos — required at triage before work enters the drain. Arc-unhomed work parks only when it carries the wayfinder:backlog fog label, and that fog-parked work auto-expires after 3 weeks unless it is parked by design (see the Not column); an important idea comes back with a pitch. Agents may DRAFT a pitch; only the founder APPROVES. Shape Up's shaped pitch, adopted as the roadmap's binding carrier. a merge-time conformance artifact (no finished PR ever fails for direction); an epic breakdown (decomposition stays with plan-epic); an agent-approvable form (approval is a founder seat); a reprieve from kill — outside the fog label, kill/close remains a valid triage verdict per ADR 0202, which ADR 0210 amends in part rather than overturns; a clock on parked-by-design work — one of the named clusters ADR 0072 §4 freezes by design (imge / kampus-CLI / künye) or the axis:pipeline-hardening standing lane is neither clocked nor killed, and that test runs first — bare milestone-absence does not qualify; the enumeration is the interim carrier until the founder-ruled status:frozen label (2026-07-25, on ADR 0210's PR) is created and applied — but ADR 0208 exempts wayfinder:backlog from milestone homing, not from the clock, so fog itself still expires; a replacement for charting — charting stays wayfinder:backlog's ordinary exit per ADR 0203, which 0210 amends in part by adding the expiry as a second exit
appetite The founder-set spend budget on a pitched bet (ADR 0210), acting as a circuit breaker: a bet that exhausts its appetite auto-parks and requires a founder re-pitch — the factory cannot silently overspend founder intent. Set only at the betting table. Shape Up's appetite, made structural. an estimate (it is a willingness-to-spend budget, not a prediction); an advisory number (exhaustion auto-parks, structurally); an agent-settable value (a founder seat)
betting table The founder seat (ADR 0210) where a pitch is approved or declined and its appetite is set — a named human authority that does not translate to agents (agents only draft pitches). Shape Up's betting table as the intent-seat, the direction-side sibling of ADR 0078's decision boundary. a standing meeting/ceremony (it is an authority/seat, not a ritual); an agent role; wayfinder's founder-decision-fork (a different human seam — that one frames a map fork, this one bets work into the drain)
cycle heartbeat The machine-computed arc/lane/appetite audit written for founder read every cycle — founder-set cycle: 2 weeks (ADR 0210; build epic #3948). The heartbeat is AUDIT, not enforcement — it informs the founder's next bets and gates nothing. an enforcement gate (it blocks no work and no merge); a hand-written status report (machine-computed); the roadmap's binding mechanism (binding lives at intake — the heartbeat only observes)

Binding-at-intake (the pitch layer — epic #3947)

Direction stops depending on founder attention and binds structurally at intake: work enters a build lane only as a founder-approved bet, platform spend is budgeted by a lane quota rather than argued case-by-case, and a bet that outspends its appetite parks for a re-pitch (founder ruling #3909; founder-set numbers #3227). The §PITCH format contract lived in the v1 intake-formats doc (retired with the kampus-pipeline plugin, #5937); pipeline-cli pitch-guard still enforces the shape. This names the nouns.

Term Definition Not
pitch The five-field bet document — Problem / Arc / Appetite / Rabbit-holes / No-gos — carried as a ## Pitch body section on lane-entering work, drafted by triage and approved only by the founder via an unstamped, write+-authored pitch-approved: appetite <N> cycles · <ISO> comment. Binds at intake: pitch-guard reds unpitched pickable work. Its Arc field restates the ADR 0202 home the rubric step already assigned — one arc question, never two. an estimate or a plan (plan-epic still owns decomposition); a merge-time conformance gate (explicitly founder-rejected — a finished PR never fails for direction, #3909); an agent-satisfiable artifact (the draft is agent work, the approval is a founder seat)
appetite The founder-set spend ceiling on a bet, denominated in 2-week cycles (cycle length founder-set, #3227) and carried in the pitch's Appetite field. A budget answering "how much is this worth?", bound to the approval that names the same number — rewriting it un-approves the pitch. a duration estimate or a deadline (it says what the work is worth, not how long it takes); an agent's number (an agent may draft one; only the founder's pitch-approved: marker binds it)
bet Lane-entering work that carries a founder-approved pitch — the unit the factory is licensed to start. Exactly the pitch-required scope: a type:epic, or a type:feature with no parent; an epic's child inherits its epic's bet rather than placing its own. any status:triaged issue (a triaged issue with no approved pitch is not yet a bet); a type:bug / type:chore / type:decision / type:investigation (maintenance and questions are out of scope); a sub-issue (it inherits the epic's bet)
platform lane An active build lane classified platform — the budgeted share of the flat build-lane WIP that platform/infra work may occupy, capped by quota (2 of 6, #3227) rather than exempted or judged case-by-case. The classification predicate and the quota check are pipeline-cli lane work (#3964/#3965), implemented in exactly one place. a standing lane (that is the milestone-exemption label pair of ADR 0208 — a homing concept, not a WIP budget); an exemption from the pitch requirement (platform work is budgeted, never exempted, #3909); an engine claim-deconfliction lane (#3766 family — a different mechanism)
unparented lane The open slice of the backlog that has no parent issue and is not required to get one — bugs, chores and small items that arrive every week outside any epic. Small unparented items are batched into runs that share a review context (one reviewer pass, one CI run) rather than force-fitted under a parent, because a hierarchy invented before the dependency structure is known is a guess that decays (ADR 0278). a standing lane (that is a milestone-homing exemption, ADR 0208 — an unparented issue is still milestone-homed or killed); an exemption from the pitch requirement (a type:feature with no parent is exactly a bet and still needs an approved pitch, ADR 0210); a permanent state (a parent may be added later as optional cleanup)
park / expiry The holding state a bet enters when it exhausts its appetite (auto-park, awaiting a founder re-pitch) and the 3-week timeout (#3227) after which parked work that never earned a pitch disappears. The carrier and its semantics are defined once by #3966 (the appetite circuit breaker), and how they relate to ADR 0072 §4 is an open founder question — deliberately unanswered here, and never inferable from a pitch field. a kill (a park is reversible by a founder re-pitch; a kill is close not-planned); the wayfinder:backlog standing lane (fog awaiting charting is a different state with a different remedy); anything a pitch field decides (§PITCH encodes no park semantics)

Design coverage (the descriptive/normative firewall — ADR 0194)

The boundary the design-coverage extractor is built on (ADR 0194, issue #3152): an agent may auto-generate the descriptive half of the design docs (the component inventory) but never the normative half (the founder-authored four pillars / prohibitions / role-token values in design-system-manifest.md). Grounded in ADR 0078 (design-law is founder-authored) and ADR 0162 (the four-pillars design law).

Term Definition Not
descriptive/normative firewall The hard boundary (ADR 0194) separating what a design-coverage extractor/agent MAY write from what only the founder writes. Descriptive (agent-writable): the component inventory — primitives that exist, their props/slots, and a per-component when-to-use. Normative (founder-authored, never auto-written): the four pillars, the prohibitions, and the role-token values in design-system-manifest.md. The edge case — a per-component when-to-use — is firewalled by living on the component but being @agent-generated and referencing the manifest's law, never minting new law (the ADR 0078 guard at the doc layer). a license to auto-edit the manifest (the normative half is out of the agent's reach); a soft convention (it is a fail-closed drift-guarded boundary); a per-component copy of the law (a when-to-use references the law, it does not restate it)
descriptive component inventory The agent-writable half of the design docs (ADR 0194): the catalogue of which primitives exist, their props/slots, and each one's when-to-use, extracted from JSDoc-on-code and rendered into one central curated-hybrid index (inline the when-to-use core, link to source for depth — the Effect-TS/effect LLMS.md idiom). Kept fresh by a generate command + fail-closed drift guard (pre-commit + CI). the normative design law (the four pillars / prohibitions / role tokens — founder-authored); a hand-maintained doc (it is generated + drift-guarded); a place new design law may be introduced (it only describes + references the law)
@agent directive A human-seeded JSDoc tag on a component (ADR 0194) that steers the extractor — the protected seed the generate step must preserve rather than overwrite. Rides alongside the descriptive tags (@component, @slot, prop docs) that source the component inventory; keeps the tag vocabulary lean, a deliberately-minimal v1 expected to evolve with real use. a descriptive tag the extractor regenerates (@component/@slot/prop docs are generated; @agent is preserved); design law (a directive steers extraction, it does not mint pillars/prohibitions/role tokens); a frozen final schema (the tag vocabulary iterates as gaps surface)
taste skill (the taste voice) The factory's design-taste primitive (ADR 0209): a library of per-aspect taste skills — strict generative rules with the why attached (decision tables with hard thresholds, text flowcharts, imperative + concrete-value + one-line-why + named-counterexample rules) — loaded by name into existing generalist agent spawns (coder/planner) when creating UI. Grounded exclusively in the repo design law: the manifest (ADR 0162), the descriptive inventory (ADR 0194), the blessed goldens (ADR 0183); seeded from emilkowalski/skills (MIT, attributed) plus repo-grown manifest-grounded seeds for the uncovered aspects. The taste voice names the primitive as a whole. The library lives under claude-plugins/fabrika/skills/ as taste-<aspect>/ dirs (taste-<aspect>-<mode>/ where one aspect needs several procedures), each SKILL.md optionally paired with a values-only STANDARDS.md, and every rule tagged LAW (cited to the design law, binding) or CRAFT (an advisory default that yields to LAW). a persona agent or a new agent def (it loads into existing spawns); an author of normative design law (the 0194 firewall holds — law changes flow through ADR-ratify→transcribe); a fourth design artifact (it consults the three that exist); a replacement for the gate substrate (agent-browser composes with it, never replaces it — the packages 0209 named are deleted, fabrika-cli's capture module and ui verbs carry that work today, and ADR 0306 records that the gate's own shape is owed a re-decision); a control-plane surface (a taste-* dir stays .sh-free, which is what keeps it out of CODEOWNERS)

fabrika skill nouns (the modality partition — epic #4904)

The eight skill names the founder locked on wayfinder:map #4891 and epic #4904 transcribed. The factory is cut by modality — text versus rendered-visual — and the cut is symmetric on both sides: build / build-ui construct, review / review-ui judge. Two of the eight redefine a reading that is live in this repo; the dated record of what each word meant before is ADR 0242, and the rows below carry only the current reading. These name fabrika skills (claude-plugins/fabrika/skills/); the v1 skills that once shared some of these names retired with the kampus-pipeline plugin (#5937).

Five more names sit in the same register from a second founder ruling on epic #5017: the ideation quintetwayfinding, grilling, prototyping, graduate, handoff — five independently invocable skills that compose, landing at the same claude-plugins/fabrika/skills/<name>/. They sit upstream of the modality eight: the quintet works a question down to one spec issue, which then enters the board as ordinary status:needs-triage work. One of the five spells a word this repo already uses for other things; the founder ruled keep the name (comment) and ADR 0246 is the dated disambiguation the graduate row below points at.

Term Definition Not
build fabrika's text-construction skill (brief #4707, renamed from v1's write-code under #4906): it constructs code, prose and plans — one loop plus per-surface reference files, not a router. Redefinition — ADR 0242 §2 records what the bare noun meant before. Rendered-visual construction is not its scope; that is build-ui. the pnpm build compile step, or the build lane of the WIP model (both survive as compounds and are NOT renamed — the bare noun in a fabrika context names the skill, and ADR 0242 §2 accepts the homonym rather than propagating a rename); v1's write-code (the frozen baseline, read for its scars, never ported — ADR 0238); a router that hands off per surface
build-ui fabrika's design-system construction skill (brief #4941): it generates and edits user-facing visual surfaces against the four-pillars design law (ADR 0162), and owns nothing textual. The visual half of the modality line, ruled on the measured evidence that the UI sample first-passes the design gate ~60% FAIL against ~12–20% for code. build (code, prose and plans — anything text); review-ui (that judges a rendered surface; this constructs it); a mode or branch inside build (the split is structural, not conditional)
check-epic-plan fabrika's plan-checking skill (brief #4948), in the planning lane — the planner's downstream neighbour, not its replacement: a 100%-deterministic floor expressed as a verb (the hard-defect set of the epic ledger) plus a thin advisory judgement layer over it (acceptance-criteria checkability, brief fidelity) that annotates a pass and never blocks. a member of the review family (plan-quality was moved out of it — review must not absorb it); plan-epic (that writes the ledger; this decides whether it clears the floor); a second blocking reviewer (the real judgement it holds is advisory by construction, ADR 0047)
front-door fabrika's operating entry point (brief #4952): the human-typed /fabrika skill that orients a cold operating session with live status and a command menu. It exists because fabrika orients a fresh authoring session completely (three convention docs) and a fresh operating session not at all. an authoring entry point (the authoring docs already cover that); a dispatcher that does the work (it orients — what is in flight, what is blocked, which skill to reach for)
governance fabrika's governance-corpus integrity skill (brief #4949) — the single owner of one judgement with two halves, both homeless in v1: does a change contradict the decision corpus (v1's ADR sweep, embedded in review-doc), and does it quietly weaken a gate (v1's gate-invariant-preservation check, embedded in review-skill). It guards from outside the review skill: on a harness-touching diff its namespace is derived-required, so a review PASS with no governance verdict is not a complete gate result. a part of review (review invokes it and does not own it); a general policy skill (exactly the two judgements above); a merge-gate substitute (it emits a verdict in its own namespace)
graduate fabrika's spec-synthesis skill and the fifth member of the ideation quintet (ruled on #5017, at claude-plugins/fabrika/skills/graduate/): it runs on a completed grilling session or a wayfinding map and synthesizes one spec issue — problem / solution / decisions / out-of-scope — linked back to the decision trail as its primary source. It files through the existing report verb machinery (dedup, footer, provenance), lands status:needs-triage, and writes no board state: type, priority, milestone and pickability stay triage's sole authority, and a lane-entering spec's pitch stamp stays a founder seat (the skill may pre-draft the five fields). Its direction is generative — something is born. Specs are non-persistent: a spec issue closes once implemented and is never maintained. A kept homonym — three other live surfaces spell this word, and ADR 0246 §2 is the rule for telling them apart: read the namespace, never the vibe. /graduate, claude-plugins/fabrika/skills/graduate/, and the bare unqualified noun in a fabrika or ideation context (beside wayfinding / grilling / prototyping / handoff) all mean this skill; everywhere else the qualifier is mandatory. Tracker.graduate / tracker graduate — the graduation-close envelope (ADR 0190, tracker.ts), which records an audit comment and closes a source issue with state_reason=completed: terminal, the opposite direction from this one — and writing it as bare graduate outside a Tracker signature or context is banned by ADR 0246 §2; anka-ops flag graduate <key> — the Flagship flag-lifecycle verb (flag.ts, ADR 0136) that files the retirement chore for a fully-open prod flag; fog-graduation (its own row in the wayfinder register above) — a frontier ticket moving into ## Graduated fog, motion within a map rather than a named surface, and the closest neighbour of all, since this skill reads exactly those maps; the plain-English "an optimistic slice graduates to served-on", which names no surface and needs no ruling; a triage authority (it writes no board state) or a closer of its own source (it emits a spec issue, it never closes the grilling session or the map); an opening to re-open rename-vs-keep, which ADR 0246 bans — and no pre-existing sense is renamed, deprecated or rescoped to make room for it
grilling fabrika's question-frontier skill and the quintet's shared primitive (ruled on #5017, at claude-plugins/fabrika/skills/grilling/): frontier rounds of numbered questions, each carrying a recommended answer, worked down until the fog clears. The division of labour is the point — facts are the agent's job (answered by subagents), decisions are the founder's. Standalone and invoked by wayfinding; the layered primitive/wrapper split is adopted deliberately, and shared machinery (filing, session state) lives in verbs rather than being duplicated across the five. a mode inside wayfinding (it is independently invocable, and the wrapper composes it); a question set that sends the founder off to look facts up (facts are the agent's job — only decisions reach him); a bare question list (every question carries a recommended answer); review (that judges a finished artifact; this interrogates an unfinished one)
handoff fabrika's session-continuity skill (ruled on #5017, at claude-plugins/fabrika/skills/handoff/): it packs a session so a fresh one continues it — compaction for continuity, keeping the founder-cited grounding's meaning of the word. anything graduation-flavoured — naming this skill after graduation is explicitly ruled out, precisely so it never collides with the grounding's vocabulary; graduate (that synthesizes a spec issue out of a decision trail; this carries a live session forward); v1's epic handoff note (the Done / Affects-siblings / Watch-out comment write-code writes on a parent epic — a comment format, not a skill, and v1 is frozen under ADR 0238)
prototyping fabrika's throwaway-code skill (ruled on #5017, at claude-plugins/fabrika/skills/prototyping/): it writes disposable code answering one question — logic as a single HTML state-machine walkthrough, UI as variants on one route — marks the artifact disposable, and captures the decision back to the decision trail. product code, or a seed the product grows from — the prototype never grows into the product; build / build-ui (those construct the shipped artifact; this answers one question and is thrown away); an exploration carrying several questions at once (one question per prototype); an artifact anyone maintains (it is marked disposable by construction)
review fabrika's one text-review skill (brief #4959): a single gate that judges every textual artifact class — code, docs, skills — and emits N namespaced verdicts rather than N skills each emitting one (the marker format already admits it: the namespace class in verdict-marker.ts, `/^(review check-epic-plan)(-[a-z0-9]+)*$/, admits a whole review-family, so one skill can emitreview-code, review-docandreview-skill` verdicts under it). Per-surface leaves are rubric files, promoted to a skill only when consumed by ≥2 skills or needing their own eval identity. Redefinition — see ADR 0242 §3.
review-ui fabrika's visual-modality review gate (brief #4718): it judges rendered-visual artifacts against the four-pillars design law (ADR 0162), as a calibrated judge of this repo's founder-ratified law — rubric-grounded pairwise screenshot judging, never a general taste model. Renamed from v1's review-design, which is the same skill under its superseded name, never a predecessor to port. the same name as ADR 0144's review-ui — 0144 coined that spelling for a standalone Playwright-capture-and-depo put skill. The two are distinct names that coexist, and neither supersedes the other: 0144 keeps status: accepted (founder ruling (a), 2026-08-08 on epic #4904), and a qualifying note at its clause (#4951) is what disambiguates a reader landing there. 0144's skill was never built; its capture-and-embed function landed as a leg of this gate over the @kampus/fabrika-cli/capture seam (ADR 0183), and ADR 0242 §4 records how the two readings coexist. Also not build-ui (that constructs; this judges) and not a text gate (review)
wayfinding fabrika's fog-charting skill (ruled on #5017, at claude-plugins/fabrika/skills/wayfinding/): it opens a map issue plus decision tickets (research / prototype / grilling / task), gates the frontier on blocking edges, spends one fresh session per ticket, and summarizes each resolution back to the map. For foggy multi-session work only — it wraps grilling, which stays independently invocable underneath it. the default route into work — work plannable in one session skips wayfinding entirely (grillinggraduate → one issue), and that smallest path is first-class, not a shortcut; v1's wayfinder skill and the wayfinder:map / wayfinder:backlog artifacts it coined (epic #2421, rows in the wayfinder register above) — v1 is frozen and reimplemented, never called (ADR 0238), and those rows are unchanged by this one; a replacement for grilling (it composes the primitive rather than absorbing it)

Apps

Term Definition Not
apps/web (@phoenix/web) The ONE app/worker today — serves the SPA (via ASSETS) + the API. The multi-app structure (ADR 0057) exists but web is the sole occupant.