Skip to the content.

Generation Contract

Generation is the product horizon for a piece of fak work. It answers: “which horizon is this optimizing for, and what evidence would move it closer to now?” It is not priority, not a branch strategy, and not a runtime exposure flag.

This contract backs epic #1625. The matching issue labels are gen/now, gen/next, gen/second-next, and gen/future.

Streams

Stream Label Milestone Meaning
now gen/now Generation G0 - Now / Immediate Improves the current product, operator loop, or trunk hygiene with a clear witness and no dependency on a future architecture bet.
next gen/next Generation G1 - Next Gen Near-term foundation that should be runnable by agents soon, but still needs a gate, dogfood run, schema, or default-exposure proof.
second-next gen/second-next Generation G2 - Second Next Gen Architectural option that needs simulation, compatibility policy, or cross-generation dependency management before it can become active product work.
future gen/future Generation G3 - Future Research, market narrative, standards analogue, or long-horizon option that should stay visible without pretending it is on the current release train.

Every generation issue should also carry the generation label. The stream label and milestone should agree. If they do not, treat the mismatch as intake drift: fix the label or milestone before using the issue for dispatch.

The compatibility promise that lets later-horizon architecture work influence current APIs without a per-generation branch is pinned in docs/generation-abi-compatibility-policy.md: the frozen wire ABI stays additive-only and the versioned JSONL schemas never edit a shipped /N in place, so concurrent generations share one trunk without a flag day.

Orthogonality

Generation is independent of priority. A gen/future issue can be high-value or urgent to study, and a gen/now issue can be small cleanup. Priority answers “how valuable or urgent is this?” Generation answers “which horizon owns the evidence?”

Generation is independent of shared trunk. All streams still land through main, by explicit path, with the same witness, DCO, and ship-stamp rules as any other fak work. A stream label never authorizes a feature branch, a side worktree escape, or stale trunk hygiene. The branchless team workflow is spelled out in docs/generation-concurrent-trunk-playbook.md: stream labels partition evidence and horizon, while dos arbitrate, path scope, and runtime gates decide whether concurrent work can safely run. Loop scheduling for concurrent generation workers is pinned in docs/generation-loop-scheduling.md: generation labels select readiness checks and override gates, while lane pressure, priority, and path leases still decide the admitted wave.

Generation is independent of runtime feature gates. A generation label says why the work exists and what evidence promotes it. A feature gate decides whether the code is reachable, default-on, default-off, or operator-only at runtime. Next-generation code can land inert behind a gate; now-generation docs can ship with no runtime gate at all. The branchless exposure contract is pinned in docs/notes/GENERATION-BRANCHLESS-FEATURE-GATING-2026-06-30.md: generation metadata is planning data, while flags, command modes, doc status, and no-op scaffolds own runtime exposure.

Generation is independent of completion percentage. Ongoing optimization programs still report a frontier and trend. Discrete deliverables can report completion. Do not turn a never-done optimization program into a fake percent because it has a generation label.

Promotion Verbs

For gen/future work specifically, the retire verb is operationalized by a closed sunset-trigger vocabulary, a review cadence, and a four-piece retirement-evidence contract in docs/generation-future-sunset-criteria.md (the kill machinery), which pairs with the valuation in docs/generation-future-real-options-model.md. A gen/future bet is retired only by a named trigger from that closed set, on a stated cadence, with a witnessed evidence trail — never by label movement alone.

Promotion should preserve issue history. Prefer updating labels, milestone, and the evidence comment over opening a duplicate issue in another stream.

Evidence

Promotion evidence depends on the surface:

Demotion or retirement evidence is equally concrete:

Debt Metric

The milestone report carries a lightweight debt_score for each generation lane. It is an operator signal, not a priority score or gate:

debt_score =
  stale_issues
  + 3 * missing_witnesses
  + 2 * unpromoted_bets
  + 2 * label_ship_mismatches

The inputs are intentionally cheap:

Promotion evidence that should reduce debt: closed witnessed child work, a previously unreadable issue becoming measurable, a later-horizon bet moving to a nearer stream with evidence, or commit/release sidecars matching issue labels.

Demotion or retirement evidence that should increase or resolve debt: repeated missing witnesses, stale-risk work with no owner, a later-horizon bet whose assumption failed, or a label/ship mismatch that proves the stream cannot be trusted.

Invalidating assumption: the current metric uses tracked epic child counts as a cheap proxy for stale issues and promotion state. If GitHub issue age, project-field history, or commit sidecar coverage becomes cheap to read, the weights should be recalibrated against those stronger witnesses.

Intake Rules

At issue creation:

Issue views expose the four dispatchable stream lanes:

Those views require both the stream label and its matching milestone. A missing issue in a view usually means the label and milestone are not bound yet.

Examples

gen/now: add a report field that immediately helps the operator decide today’s dispatch lane, with a captured command output as witness.

gen/next: add a default-off route or schema that can be dogfooded by agents after one focused gate lands.

gen/second-next: define cross-generation dependency edges or a compatibility policy that later code can enforce. The option-contract shape such a bet must carry — assumption set, reversible seam, cost to keep alive, promotion trigger, and kill trigger — is pinned in docs/generation-second-next-option-contracts.md, the gen/second-next companion to the gen/future real-options model. The metadata and reporting for a dependency that crosses a generation boundary — how the edge is recorded and how a stalled forward bet surfaces in the debt metric — is pinned in docs/generation-cross-generation-dependency-edges.md.

gen/future: research a standards analogue or market-facing narrative, with a memo that names the decision it could influence.

Program Maps

Cache and context work has both immediate reliability value and long-horizon architecture value. The active classification and promotion rules are pinned in docs/notes/GENERATION-CACHE-CONTEXT-PROGRAM-MAP-2026-06-30.md.

Anti-Patterns

Commits And Releases

Do not put gen/* in every commit subject. Subjects stay optimized for the existing witness path: Conventional Commits, an issue reference when the commit resolves an issue, and the (fak <leaf>) ship stamp. Generation metadata is a body sidecar when the commit advances a generation issue:

feat(tools): preserve generation sidecars #1634 (fak tools)

Generation: gen/now
Closes #1634

fak commit --preview preserves that sidecar in text and JSON output. The sidecar is normalized from now, next, second-next, or future to the matching gen/* label. A malformed sidecar is advisory so old commits keep working, but the fix is to use one of the four labels exactly.

Release notes preserve generation without changing subjects. The release context reads the sidecar from git commit bodies, and the release-note renderer adds a machine-readable generations frontmatter block, a ## Generation summary, and per-commit [gen/*] bullet suffixes when metadata exists. A release with no generation sidecars keeps the old note shape.

Generation remains orthogonal in these artifacts:

Assumptions To Recheck