Claude Cursor Skill

living-docs

Run a project's engineering decisions as a living log — MADR-lite ADRs (supersede, never delete) for decisions expensive to reverse, issues for the work (and its cheap-to-reverse choices), research artifacts, an optional PRD, a project constitution, and living Mermaid architectur

LLM Mart · 0 points · 3 views 33 listing impressions 0 install-command copies

#research

Virus-scanned Reviewed automatically before listing.

Full trust report

Download ejklock-living-docs-skill-skills_living-docs-81120ac.zip · 52 KB
Part of ejklock/living-docs-skill — 3 skills

Install

skills CLI npx skills add https://github.com/ejklock/living-docs-skill/tree/main/skills/living-docs
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install ejklock-living-docs-skill@llmmart
Git git clone https://github.com/ejklock/living-docs-skill.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole ejklock/living-docs-skill collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Living Docs

Living Docs is a decision log with a gate. It records the engineering decisions a future reader would pay to rediscover, traces each from its rationale to the code, and refuses to let a record exist unindexed, untyped, or silently rewritten. The spine — every piece of knowledge has exactly one home, that home is indexed, and a material decision ships with its record — carries a small set of record types: ADRs, issues, research, a constitution, an optional PRD, and living architecture views.

This skill is stack-agnostic. It governs how decisions are recorded and maintained, never what technology a project uses.


Using this skill (progressive disclosure)

This SKILL.md is a slim stub — a trigger plus a task→topic router. The living-docs CLI holds the full, authoritative conventions and templates and discloses them progressively. Before authoring anything, load the topic for your task and operate from it, not from this stub:

  • living-docs guide --list — discover every topic.
  • living-docs guide <topic> — load that topic's full rules (+ template).

Piped output is minified JSON (machine default); --plain for human text, --json to force JSON.

Write ONLY the body below the closing ---. Frontmatter and indexes are CLI-owned: living-docs set / supersede / index.

  • The spine invariants → living-docs guide spine.
  • Authoring mechanics — CLI owns every deterministic step, you write only the prose → living-docs guide procedure.

The one rule that decides whether to write a record

Write an ADR when a future reader would pay to rediscover why you chose this over the alternatives — i.e. the decision is expensive to reverse. Otherwise put the choice in the issue that carries the work. When in doubt, it is an issue. A record is earned by materiality, never by the fact that a change touched structure or behavior — do not manufacture a record per layer.


When to invoke

  • Standing up documentation for a project (creating docs/ structure, the docs index, ADR/issue directories) → living-docs guide procedure.
  • Adopting living-docs in an existing/brownfield project (decisions already made but undocumented) → living-docs guide procedure, Adopting living docs in an existing project: inventory the decisions, confirm each with the user before recording any ADR, never back-fill by inference alone. A bundle authored under an older organization is brought current by living-docs index and living-docs fmt, then living-docs check.
  • Writing or editing an ADR (a decision expensive to reverse, with its rejected alternatives) → living-docs guide adr (load guide procedure first if not already loaded this session). A test-strategy decision (non-default level/technique, bar deviation) is an ADR tags: [testing], not a new record type.
  • Writing or editing a PRD (an optional product/feature spec: who asked, what is out of scope, what success looks like) → living-docs guide prd (load guide procedure first). A PRD without who-asked/out-of-scope is just a large issue — keep it an issue.
  • Establishing or amending the constitution (foundational scope, non-negotiables) → living-docs guide constitution (load guide procedure first).
  • Creating or editing an issue/ticket (the unit of work; it carries any cheap-to-reverse decision inline) → living-docs guide issue-workflow (load guide procedure first).
  • Recording research (technology evaluation, external trade-offs) → load the research-artifacts skill. It owns the OKF research-note format, the source discipline, and the research → decision → issue traceable chain, and links back here for the ADR/issue artifacts. Pairs with the deep-research skill.
  • Drawing or updating an architecture, data-flow, or tool-calling diagramliving-docs guide architecture-diagrams.
  • A doc has grown too large or mixes concerns → split into a semantic indexliving-docs guide semantic-index.
  • Reading the corpus as an agent (what governs X now) → run living-docs read (active records only, supersede chains collapsed; --topic <term> to filter, --full for bodies — ADR 0050), never index.md directly. A raw record whose body opens with a SUPERSEDED or DEPRECATED callout is history — follow the successor link or discard it, never plan on it.
  • Sizing a record's body (aim ~100 lines, check advises at 120; research exempt; never trim a load-bearing rationale) → living-docs guide size-targets.
  • Enforcing the no-drift maintenance rule after any structural change → run living-docs check; treat a non-zero exit as blocked; treat each advisory (SIZE, LIVENESS stale-proposed, MOVED-SOURCE) as work to schedule. Detail → living-docs guide check; the maintaining loop → guide procedure.
  • Authoring or checking the OKF format of any doc (frontmatter type, reserved index.md/log.md, bundle-relative links, # References) → living-docs guide okf-format.
  • Understanding the doc trail (constitution → PRD → ADR → issues → code) and which record type answers which question → living-docs guide doc-trail.
Files (living-docs-skill)
  • hooks
    • pre-commit 1.1 KB · in bundle
    • session-context.sh 1.5 KB
      #!/usr/bin/env bash
      #
      # session-context.sh — SessionStart hook for the living-docs authoring contract
      # (deterministic point-of-use teaching).
      #
      # Emits one context line stating the body-only rule and the resolved CLI binary,
      # so every session receives the rule at t=0 instead of behind a skill trigger.
      # Also points core.hooksPath at .githooks/ when the repo ships one, arming the
      # pre-commit doc-gate. Always exits 0.
      
      set -u
      
      ROOT="${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
      
      resolve_bin() {
        if command -v living-docs >/dev/null 2>&1; then
          command -v living-docs
        elif [ -x "$ROOT/target/release/living-docs" ]; then
          printf '%s' "$ROOT/target/release/living-docs"
        fi
      }
      
      arm_githooks() {
        [ -d "$ROOT/.githooks" ] || return 0
        git -C "$ROOT" config core.hooksPath .githooks 2>/dev/null || true
      }
      
      arm_githooks
      
      BIN="$(resolve_bin)"
      if [ -n "$BIN" ]; then
        BIN_NOTE="CLI: $BIN"
      else
        BIN_NOTE="CLI not built — run \`make build\` (or \`cargo build --release --manifest-path cli/Cargo.toml\`) before authoring docs"
      fi
      
      printf 'living-docs: %s. Docs authoring contract: write ONLY the body below the closing --- of a record. Numbering, frontmatter, supersede links, and index rows are CLI-owned — `living-docs new <type> "<title>"`, `living-docs set <NNNN> <key> <value>`, `living-docs supersede <old> <new>`, `living-docs index`, `living-docs fmt`. A hand-written one fails `living-docs check` at commit.\n' "$BIN_NOTE"
      
      exit 0
      
  • rules
    • adr-conventions.md 6.9 KB
      # ADR Conventions (MADR-lite)
      
      An Architecture Decision Record captures **one** decision: the context that forced it, the choice made, and the consequences accepted. ADRs are how a future reader understands *why* the code is the way it is — and why a tempting alternative was not taken.
      
      ## Format
      
      Each ADR is an **OKF concept** (`type: ADR`) — see the `okf-knowledge-format` skill. Use a lightweight MADR structure — frontmatter plus three body sections, no ceremony:
      
      - **`status` (frontmatter)** — `Proposed` | `Accepted` | `Superseded` | `Deprecated`. Lives in the YAML frontmatter, not a body line. Supersession is recorded with the `supersedes` / `superseded_by` frontmatter keys (NNNN).
      - **Context** — the forces at play: the problem, constraints, and what made a decision necessary. Written so a newcomer understands the pressure without prior knowledge.
      - **Decision** — the choice, stated in active voice ("We will…"). Specific and testable.
      - **Consequences** — what becomes easier, what becomes harder, what is now forbidden. Include the trade-offs you are knowingly accepting, not just the upside.
      
      See `templates/adr.md` for the skeleton.
      
      ## Rules
      
      1. **One decision per ADR.** If you are recording two decisions, write two ADRs. Bundled decisions can't be superseded independently.
      2. **Number sequentially, never reuse.** `docs/adr/NNNN-kebab-slug.md`. The number is permanent even after the ADR is superseded.
      3. **Supersede, never delete or rewrite.** When a decision changes:
         - Set the old ADR's frontmatter `status: Superseded` and `superseded_by: NNNN` (do not edit its Decision/Context — that is history).
         - Write a new ADR with `supersedes: NNNN` that references the one it supersedes in its Context.
         - If the old ADR is only *partially* affected, annotate the affected section with a pointer to the new ADR rather than rewriting it.
         - `supersede` also writes a callout at the top of the old ADR's body, above its heading, naming the successor. Never write or edit that callout by hand; it is the signal that stops a reader from acting on a retired record.
      4. **Record load-bearing rejections.** When a design candidate is rejected for a reason a future explorer would otherwise re-discover the hard way, that reason is an ADR. Skip ephemeral ("not worth it now") or self-evident reasons.
      5. **Link the evidence.** If the decision rests on research, link the research artifact bundle-relative (`/research/<…>/report.md`). If it implements a requirement, link the PRD/issue.
      6. **Name the fitness function for measurable characteristics.** When an ADR decides a measurable architecture characteristic (a latency budget, a dependency-direction rule, a coupling/granularity constraint), the Consequences section SHOULD name the **fitness function** that enforces it — the executable check (a test, a build/lint rule, an arch-unit assertion) that lives in the suite and fails when the characteristic is violated. The ADR records *why*; the fitness function keeps it true. A measurable decision without an instrument is a vibe (see `memory/lessons.md`).
      7. **Index every ADR, and keep an active view.** Add a row to `docs/adr/index.md` (OKF reserved listing — number, title, status). The index carries no frontmatter; the decision log is the listing plus each ADR's `status`/`superseded_by` frontmatter. **As the corpus grows, split the listing by status** — an `## Active` section above a `## Superseded` section — so a reader sees what is *in force* without reading through history. Append-only + supersede means `docs/adr/` only grows; this convention keeps "indexed or it doesn't exist" from degrading into "indexed but unreadable by volume". `status` already lives in frontmatter, so the split is mechanical. Each retired row names its successor under a one-line history note atop the section; `living-docs index` writes both — never hand-edit a row or the note. See the worked [`examples/linkly/docs/adr/index.md`](../../../examples/linkly/docs/adr/index.md).
      8. **Bind measurable decisions to a check (optional `## Verification`).** When an ADR must be honored in code, add a `## Verification` block (see `templates/adr.md`): the files it touches and **checkable** verification criteria — ideally a named fitness function (rule 6). This closes the doc → implement → verify loop a review step can consume; a structural decision a future agent must respect should not leave "did we honor it?" to inspection. Omit the block for a purely advisory record.
      9. **Test-strategy decisions are ADRs, not a new record type.** A *test* decision with a rejected alternative and a consequence — a non-default test level/technique for a behavior, a deviation from the project's standing test bar, a deliberate decision not to test a seam (with the risk accepted), a golden-master/characterization oracle choice — is recorded as an ordinary ADR carrying `tags: [testing]` (a "test-strategy ADR"). The *what/how* of testing lives in the tests themselves (the scenarios and the suite); the ADR holds only the *why*. There is deliberately **no "Test Decision Record"** — the field's direction is "**Any** Decision Record" (one template absorbs domain decisions, MADR 3.0), and "TDR" already names "Technical Debt Record". Provenance (instrumentalized, not invented): the *what* is Specification by Example / Given-When-Then (ADZIC; NORTH); the *vocabulary* of a test decision (policy/strategy/approach/level) is ISTQB / ISO-IEC-IEEE 29119; the absorb-into-ADR stance is MADR "Any Decision Records" (ZIMMERMANN).
      
      10. **Materiality — a decision earns an ADR only when it is expensive to reverse.** The trail is gated by *materiality*, not by *layer*. A decision gets its own ADR when it changes a stated invariant or constitution article, a public contract or schema, a dependency direction or module boundary, or a pinned external dependency — or it reverses a prior ADR. A decision that is cheap to reverse lives in the body of the issue that carries the work, not in an ADR. The one test: **"would a future reader pay to rediscover this?"** A *material* decision shipped without its ADR is an incomplete change; a cheap one recorded in its issue is complete. Do not manufacture a record per layer.
          - *Stays in the issue:* "we'll name the flag `--include-stale`, not `--with-stale`" — a rename, reversible in one commit. Put it in the issue's `## Decision`; do not open an ADR.
          - *Earns an ADR:* "records live as `.md` in git, never in a database" — fixes the source of truth every verb and every consumer builds on; expensive to reverse. Write the ADR.
      
      ## Anti-patterns
      
      - Editing an accepted ADR's Decision to reflect a new choice — that erases history. Supersede instead.
      - "Status: Accepted" with an empty Consequences section — every decision has trade-offs; if you can't name them, the decision isn't understood yet.
      - An ADR that restates the code. ADRs explain *why*, not *what*. The code says what.
      - Re-litigating a decision an existing ADR already settled without marking the contradiction explicitly.
      
    • architecture-diagrams.md 7.4 KB
      # Architecture Docs & Diagrams
      
      Architecture documentation shows *how the system fits together* — the structure ADRs decide and the context index names, made visual. It is **living**: every diagram must match the code at all times, and a structural change updates its diagram in the same change (see `rules/maintenance-invariant.md`).
      
      Diagrams are authored in **Mermaid** so they live in version control as text, diff cleanly in PRs, and render in most viewers — no binary image drift.
      
      ## Where it lives (CLI-owned, ADR 0036)
      
      Views are registry records in `docs/architecture/`, scaffolded and indexed by the CLI —
      one file per concern, never a single mega-file:
      
      ```bash
      living-docs new view "Context" --kind context     # docs/architecture/context.md
      living-docs new view "Backends" --kind container
      living-docs index view                            # regenerates architecture/index.md
      ```
      
      `--kind` seeds the CLI-validated `kind:` frontmatter from the closed vocabulary `context |
      container | component | flow | sequence | state | data-model | deployment`; the generated
      `architecture/index.md` sorts rows in that C4/arc42 zoom order (kind rank, then filename),
      so the index reads outside-in without hand-maintenance. The docs-handwrite hook covers
      `architecture/` exactly like the numbered type directories: records are born via `new
      view`, the index via `living-docs index`, and only the body below the closing `---` is
      hand-edited. Views carry no status and are never superseded — they are living documents
      updated in place; git history is the trail.
      
      The architecture index (`index.md`, OKF reserved listing, no frontmatter) is reachable from the bundle-root `docs/index.md`. Each view file is a standalone **OKF concept** (`type: Architecture View`): frontmatter, then a single `#` H1, then `##` sections. A legacy single `docs/architecture.md` is brought current by re-creating each of its diagrams as a view record.
      
      ## The standard views
      
      Cover the views the system actually has — don't invent diagrams for their own sake. Common ones:
      
      | `--kind` | View | Mermaid type | Answers |
      |---|---|---|---|
      | `context` | **Context / high-level** | `flowchart` / `graph` | What are the major components and how do they connect to the outside world? |
      | `container` | **Containers** | `flowchart` | What deployable/runnable pieces exist and how do they talk? (C4 level 2) |
      | `component` | **Module layout** | `flowchart` | How is the code organized into modules and what depends on what? |
      | `flow` | **Process / data flow** | `flowchart` with direction | How does data move through a key operation (ingest, backfill, request)? |
      | `sequence` | **Tool-calling / request flow** | `sequenceDiagram` | How does a request actually execute across actors over time? |
      | `state` | **State** | `stateDiagram-v2` | What states does an entity move through? (lifecycles, retention) |
      | `data-model` | **Data model** | `erDiagram` | What entities exist and how do they relate? (schema, FKs, cardinality) |
      | `deployment` | **Deployment** | `flowchart` | Where does each container run and over what infrastructure? |
      
      ## Per-view instrument binding (which views are checked vs inspection)
      
      "Living — must match code" is only real for a view that has an instrument keeping it honest; the rest rely on the no-drift discipline (inspection), which a constraint-without-an-instrument is a vibe. State, per view, how drift is caught — and prefer a deterministic check where one exists:
      
      | View | Drift caught by | Kind |
      |---|---|---|
      | **Module layout** | a **dependency-conformance check** if your project has one (ArchUnit · dependency-cruiser · Deptrac · import-linter) on a committed ruleset | deterministic |
      | **Data model** | a schema/migration diff or ORM-schema check, where one exists | partial |
      | **Context / module / component** | **distill-from-code** where an oracle exists — generate the view from the dependency graph rather than hand-drawing it, so it cannot drift from the imports it depicts | deterministic where wired |
      | **Process / sequence / state** | the no-drift maintenance rule (review/inspection) — no deterministic oracle | inspection |
      
      Where a deterministic oracle exists, **prefer distilling the view from code** over hand-drawing it; reserve inspection for the views that genuinely have no oracle (the judgement residue), and say so per view rather than asserting "must match code" uniformly. A structural conformance rule SHOULD link back to the **ADR** that motivated it (the rule's ADR is its provenance; the ADR's fitness function is its instrument — `rules/adr-conventions.md` rule 6).
      
      ## Completeness checklist (arc42 / C4 / ISO-42010 as vocabulary, not a new index)
      
      The bundle's *index* stays as defined above. Borrow the established frameworks only as a **completeness checklist + shared vocabulary** — not a competing layout: does the architecture cover context/scope, building-block (container/component) structure, runtime/dynamic behavior, deployment, cross-cutting concepts, the decision trail (ADRs), **quality requirements / NFRs** (the quality-attribute scenarios — see `rules/prd-conventions.md`), risks, and glossary? Use **C4** levels (context → container → component) as the zoom vocabulary for the structural views, and **ISO-42010**'s concern→view traceability as the discipline that every stakeholder concern is framed by at least one view. Adopt the names and the checklist; do not import arc42's 12-section template as a parallel index — the existing index, typed views, and ADRs already cover it. Provenance (instrumentalized, not invented): arc42 (STARKE; HRUSCHKA), C4 (BROWN), ISO/IEC/IEEE 42010, Views-and-Beyond (CLEMENTS et al., SEI).
      
      ## Tool-calling / sequence diagrams (when applicable)
      
      When the system's behaviour is best understood as a *conversation between actors over time* — an MCP/tool call, an agent invoking tools, a client→server→DB round trip — use a `sequenceDiagram` to make the flow concrete. Show the actors as participants and each call/return as a message. This is the clearest way to evidence "how it actually works" for tool-driven or multi-actor systems.
      
      ```mermaid
      sequenceDiagram
          participant Client
          participant Server as MCP Server
          participant DB as SQLite
          Client->>Server: tool call (args)
          Server->>DB: query / write
          DB-->>Server: rows / result
          Server-->>Client: structured result
      ```
      
      Include a sequence diagram only where it earns its place — a tool surface, a lifecycle with ordering, a non-obvious multi-step flow. Skip it for trivially linear calls.
      
      ## Rules
      
      1. **Mermaid, in-repo, text.** No exported PNG/SVG that can silently drift from the code.
      2. **No-drift.** A change to schema, data flow, module layout, or a component relationship updates the relevant diagram(s) in the *same* change. A structural PR with a stale diagram is incomplete.
      3. **Use context-index vocabulary.** Name nodes and participants with the project's domain/module terms, not ad-hoc labels — diagrams and prose must agree.
      4. **One view per diagram.** Don't cram the data model and the request flow into one graph. Split by concern; index each.
      5. **Indexed.** Every view file is listed in the architecture index, which is listed in the top-level Docs index.
      
      ## Anti-patterns
      
      - A diagram that contradicts the code — worse than no diagram, because it misleads with authority.
      - Screenshot/exported-image diagrams that can't diff and rot immediately.
      - A single mega-diagram trying to show everything at once.
      - Diagrams added but never wired into the index (orphans).
      
    • check.md 3.6 KB
      # living-docs check & quality checks
      
      ## living-docs check — the deterministic instrument
      
      `living-docs check [docs/]` mechanically validates the invariants a machine checks better than
      prose: frontmatter/`type`, directory-index membership + root reachability, link resolution,
      supersede integrity, Mermaid fences, and **unfilled `{{PLACEHOLDER}}` slots** (a violation — a
      scaffold left half-authored fails the gate). *A constraint without an instrument is a vibe* — so
      the checkable invariants get a checker. Wire it into the project's quality gate / CI; a docs PR
      that fails it does not merge. It does **not** check docs-first mirroring or "one home per fact"
      semantics — those have no sound oracle and stay with the reviewer.
      
      It also emits **advisories** — findings that never move the exit code, surfaced as work to
      schedule:
      
      - `SIZE` — a decision/execution body past the ~120-line target (aim ~100; research exempt).
      - `MOVED-SOURCE` — a record whose linked source path moved.
      - `LIVENESS stale-proposed` (ADR 0049) — an ADR still at its seed status (`Proposed`) whose
        linked issue is already `closed`/`done`/`Superseded`: the work landed but the record never
        left its birth state. Currency has a sound oracle where materiality does not, so the checkable
        part lives in the tool; the exit code stays put.
      
      ```bash
      living-docs check docs   # check the project's bundle; exit 1 on any violation
      ```
      
      It is a native Rust binary (correct without shelling out to a hand-rolled markdown/YAML
      parser): `serde_yaml` for frontmatter, `pulldown-cmark` for link extraction and resolution
      (every link form — inline, titled, angle-bracket, reference-style, images), and a native
      directory-index/reachability BFS plus supersede-chain walk for the OKF structural graph.
      No host tools to install — install the binary itself via `./install.sh` or
      `make cli-install`. `living-docs check --mermaid-only` validates Mermaid fences in-process
      via the pure-Rust merman-core parser (ADR 0013) — no Docker, no host tools.
      
      A worked, lint-clean corpus lives in [`examples/linkly/`](../../examples/linkly/) — copy its shapes.
      
      ## Quality checks
      
      Before considering a docs change complete. The frontmatter, indexing, link-resolution,
      supersede, and placeholder items are enforced by `living-docs check` — run it rather than
      eyeballing them; the rest are judgement:
      
      - [ ] Every concept doc opens with OKF frontmatter carrying a non-empty `type`; `status` is in frontmatter, not a body line.
      - [ ] Directory listings are `index.md` with no frontmatter (except the bundle-root `docs/index.md` → `okf_version`); cross-links are bundle-relative (`/…`).
      - [ ] Every new doc is linked from its directory `index.md` **and** the bundle-root `docs/index.md`.
      - [ ] No concept appears in two files (cross-reference instead).
      - [ ] No unfilled `{{PLACEHOLDER}}` slot remains in any record.
      - [ ] Superseded ADRs/PRDs carry frontmatter `status: Superseded` + `superseded_by: NNNN`; the superseding record sets `supersedes` and links back.
      - [ ] A Superseded or Deprecated record's body opens with its exact CLI-written callout above the heading, and no active record opens with one; `living-docs fmt` is the remediation.
      - [ ] Any structural code change in the same task updated its doc, including its Mermaid diagram(s).
      - [ ] Architecture diagrams use Mermaid (in-repo text) and match the code.
      - [ ] The constitution is singular (`docs/constitution.md`) — no NNNN prefix, no index entry.
      - [ ] Each index file's links all resolve (no dangling references).
      - [ ] Docs-first respected: the repo body matches the published tracker/wiki copy.
      
    • code-comment-hygiene.md 1.9 KB
      # Code comments must not reference doc artifacts
      
      A docblock or code comment must never name or number a documentation artifact. This covers an ADR, PRD, issue, constitution article, research note, or delivery slice. Remove references such as `see ADR 0046`, `constitution rule 4`, `issue 0028`, or `slice R3b`.
      
      ## Why
      
      Doc numbers change. A record is superseded, an issue closes, a slice is renamed between plan rounds. A comment that points at one of these rots the moment the artifact moves, and the code then lies about where its reason lives. The spine of this skill is one home per fact: a decision's home is its doc, never a comment beside the code.
      
      ## What to write instead
      
      Keep the reason when it is load-bearing, but state the invariant itself. Never point at the document that recorded it.
      
      - Bad: `// batch size capped at 500 - see ADR 0046`
      - Good: `// batch size capped at 500: larger payloads exceed the 6 MB request limit`
      
      The traceability chain (constitution -> PRD -> ADR -> issue -> code) lives in the docs and their indexes, which the doc-gate keeps in sync. Code stays self-explanatory; the docs carry the numbering.
      
      ## The ban is enforced by a gate, not a prompt line
      
      Instructions never block; only gates block. Keep the ban honest with a pre-commit or CI step that rejects any diff introducing a doc-artifact citation in code, and let the author state the invariant instead:
      
      ```bash
      # pre-commit / CI: reject a doc-artifact citation in staged code
      git diff --cached -U0 -- '*.rs' '*.ts' '*.py' | grep -nE '^\+.*(ADR|PRD|issue)[ -]?[0-9]{4}' && {
        echo "state the invariant itself; the docs carry the numbering, not the code" >&2
        exit 1
      }
      ```
      
      ## Scope
      
      This bans references to the project's own living-docs artifacts and delivery slices. It does not ban an external specification identifier such as an RFC, a W3C standard, or a CVE. Those are stable identifiers the code legitimately implements against.
      
    • constitution-conventions.md 3.2 KB
      # Constitution Conventions
      
      The Product Constitution is the **foundational source of truth** for a project: what the product is, what it is not, the data model it is built on, and the invariants that hold in all circumstances. Every other document in the doc trail sits under it and must be consistent with it.
      
      The doc trail flows: **constitution → PRD → ADR → issues → code**.
      
      ## Format
      
      The constitution is an **OKF concept** (`type: Constitution`) — see the `okf-knowledge-format` skill. `status` (`Draft` | `Ratified` | `Amended`) lives in the frontmatter, not a body line. See `templates/constitution.md`. Core sections:
      
      - **Product** — the core value and the audience in one or two sentences. The north star.
      - **Scope boundaries** — what is in scope, what is explicitly out, and what defers to which phase.
      - **Data model / schema foundation** — the core entities and relationships as a Mermaid diagram, with prose describing invariants.
      - **Non-negotiables** — constraints that hold regardless of feature, phase, or implementation. Each must be falsifiable.
      - **Amendment log** — dated amendments appended below the original content; sections above are immutable once ratified.
      
      ## Rules
      
      1. **One per project.** The constitution lives at `docs/constitution.md`. There is no NNNN prefix and it is not listed as a concept in any `index.md` — it is singular, the bundle's root of trace.
      2. **PRDs sit under the constitution; they never replace it.** A PRD specifies a feature or capability within the scope the constitution defines. If a PRD requires expanding that scope, the constitution must be amended first.
      3. **Only foundational scope or schema shifts amend the constitution.** Adding a feature does not amend the constitution. Changing what the product fundamentally is, who it is for, or what its core data model looks like does.
      4. **Append-only once ratified.** After the constitution is ratified, changes are recorded as dated Amendment sections at the bottom (`## Amendment N — YYYY-MM-DD: <summary>`). The original sections above are never silently edited.
      5. **Diagrams are Mermaid only.** No ASCII art, no image attachments.
      6. **Non-negotiables are falsifiable.** "Be secure" is not a non-negotiable. "All user data at rest is encrypted with AES-256" is.
      7. **The constitution is the root of the trace.** When reviewing any PRD, ADR, or issue, the chain should resolve back to the constitution. Work that cannot be traced to the constitution is out of scope.
      8. **The doc language is a non-negotiable.** If the user has declared a documentation language (default English otherwise), pin it here as a non-negotiable line so it survives across sessions — see `rules/doc-language.md`.
      
      ## Anti-patterns
      
      - Writing a constitution per feature instead of per project. One project, one constitution.
      - A PRD that implicitly changes scope without amending the constitution first — the constitution and PRD are then contradictory.
      - Treating the constitution as a living editable document after ratification. Silent edits break the paper trail; amend instead.
      - Non-negotiables that are aspirational rather than falsifiable — they provide no enforcement anchor.
      - An empty Scope Boundaries section. If the out-of-scope items are not named, scope is undefined and PRDs will drift.
      
    • doc-trail.md 3.7 KB
      # Doc trail & record types
      
      ## Doc trail
      
      A decision is traceable from its rationale down to the code. Only what a change earns appears — a routine change is just an issue and code; a material decision earns an ADR; a PRD appears only when there is a spec worth pinning.
      
      ```mermaid
      flowchart LR
        C[constitution] --> P[PRD optional]
        P --> A[ADR]
        A --> I[issues]
        C --> I
        I --> K[code]
      ```
      
      ## The record types — one question each
      
      Four types answer four genuinely different questions, plus an optional PRD. Term overlap is what makes an agent write two records for one change, so each type is defined by the *one question it answers* and by when it is **not** that type.
      
      | Type | The one question it answers | When it is NOT this type |
      |---|---|---|
      | **ADR** | What did we choose, what did we reject, and why? (a decision expensive to reverse) | If no alternative was rejected and a future engineer would do nothing differently without it → put the choice in the issue, not an ADR. |
      | **Issue** | What is the change, and how do we know it is done? | If there is no diff to make, only a claim about the outside world → it is research. |
      | **Research** | What does external evidence say? | If no external source backs it → it is opinion, not research. |
      | **Constitution** | What never changes here? | If it can change per feature → it is a PRD or an ADR, not the constitution. |
      | **PRD** (optional) | Who asked, what is out of scope, what does success look like? | If there is no who-asked / out-of-scope worth pinning → it is a large issue. |
      
      There is no separate record for behavior: behavior is specified by tests, and a test-strategy *decision* is an ADR `tags: [testing]`. Rationale for a choice is the ADR; the change that realizes it is the issue; the evidence behind it is research. One fact, one home.
      
      ## The leak table — content in the wrong record
      
      Agents learn boundaries from counterexamples better than from definitions. Each row is content that commonly leaks, the type it lands in, and where it belongs.
      
      | Leaked content | Landed in | Belongs in |
      |---|---|---|
      | Test results, benchmark numbers, JSON output | ADR | issue (or research if externally sourced) |
      | Implementation checkpoints / a delivery plan | ADR | issue |
      | A deferred decision ("Needs an ADR") | issue | decide in the issue now, or open the ADR now |
      | A source-less claim about the industry | ADR Context | research, or delete |
      | A cheap, easily-reversed choice given its own ADR | ADR | the issue's body |
      | An unfilled `{{PLACEHOLDER}}` | any record | fill it, or remove the slot (`check` fails on it) |
      
      ## Document map
      
      | Type | Lives in | Purpose | Mutability |
      |---|---|---|---|
      | Project guide | `CLAUDE.md` / `README.md` (root) | Entry point: scope, stack, docs index, mandatory workflows | Live — edit freely |
      | Constitution | `docs/constitution.md` | Foundational source of truth: product scope, non-negotiables | Amend-only once ratified (amendment log) |
      | Architecture | `docs/architecture/` + index | Living Mermaid views: structure, data model, flows | Live — must match code |
      | ADR | `docs/adr/NNNN-slug.md` | One decision expensive to reverse, with its alternatives | Append-only (supersede) |
      | PRD | `docs/prd/NNNN-slug.md` | One feature/product requirement spec | Append-only once accepted |
      | Issue | `docs/issues/NNNN-slug.md` | Tracker mirror (body), one per ticket; carries cheap decisions inline | Body editable; published copy follows |
      | Research | `docs/research/NNNN-<slug>.md` | External evidence with sourced claims | Append-only (evidence is dated) |
      
      Each directory carries its own `index.md` listing (OKF §6, no frontmatter). The project guide's "Docs index" links to the bundle-root `docs/index.md`. See `rules/semantic-index.md` for the indexing contract.
      
    • issue-workflow.md 2.7 KB
      # Issue Workflow (docs-first)
      
      Issues are authored **in the repo first**, then published to the tracker. The repo file is the source of truth; the tracker entry is a mirror that must stay byte-identical in body. Each issue is an **OKF concept** (`type: Issue`) — see the `okf-knowledge-format` skill.
      
      ## The workflow
      
      1. **Create** — write `docs/issues/NNNN-slug.md`: OKF frontmatter (`type`, `title`, `status`, `labels`, `blocked_by`, `tracker`) followed by the issue **body**. Add a row to `docs/issues/index.md`. *Then* publish to the tracker, stripping the frontmatter so only the body is sent (e.g. pipe the content below the closing `---` to `gh issue create --body-file -`).
      2. **Edit** — update the body file first, then push to the tracker (`gh issue edit <n> --body-file …`, frontmatter stripped).
      3. **Identical bodies** — the repo file's body (everything below the closing `---`) and the tracker issue body must match exactly. If they diverge, the repo wins; re-sync. Frontmatter is repo-only.
      4. **Metadata lives in frontmatter** — number, title, labels, blocked-by, status, and tracker number live in the issue file's **frontmatter** (and are mirrored into the `docs/issues/index.md` listing), *not* in the body. The body is portable prose; the frontmatter carries the tracker-specific fields.
      5. **Prefer editing the body over adding comments** — so each issue keeps a single, coherent source of truth rather than a scattered comment thread.
      
      See `templates/issue.md` for the body skeleton.
      
      ## Body structure
      
      A good issue body states, in order:
      
      - **What / Why** — the change and its motivation. If it implements a PRD or ADR, link it ("Implements ADR NNNN").
      - **Scope** — what's included; for removals/refactors, what's explicitly kept.
      - **Acceptance** — observable, testable conditions for "done".
      - **Plan** — a short outline (and slicing, for large tasks) so a reader knows the approach.
      
      ## Rules
      
      1. **Number consistently** with the project's scheme; index every issue.
      2. **Link bidirectionally** — body links to its PRD/ADR; the PRD/ADR's decision log or the issue index links back.
      3. **Closing keywords** belong in the PR that resolves the issue (`Closes #NN`), not scattered in the body.
      4. **Historical issue bodies are not rewritten** when superseded — set the frontmatter `status` (e.g. `superseded`) and annotate the `index.md` row, leaving the body as closed history.
      
      ## Why docs-first
      
      A tracker is an external system that can change auth, API, or vendor. The repo is durable, diffable, and reviewable in the same PR as the code. Authoring in the repo means the issue is versioned alongside the work it describes, and the body survives any tracker migration.
      
    • okf-format.md 2.3 KB
      # Format: OKF-conformant
      
      The five Core invariants (in the living-docs SKILL.md) govern *organization and lifecycle*; the **Open Knowledge Format** governs the *file format* so the corpus stays portable and agent-parseable. Every doc in the system is also an OKF concept. Load the `okf-knowledge-format` skill (it vendors the spec) when authoring or checking format.
      
      > **OKF is a thin, swappable dependency — not a foundation (version risk).** OKF is **v0.1
      > from a single vendor**; a backward-incompatible v0.2 is a real possibility. The five Core
      > invariants do **not** depend on OKF — they depend only on a small set of frontmatter fields, so an
      > OKF break cannot take the governance layer down with it. Keep the boundary explicit:
      > - **Required by Living Docs** (the fact contract `living-docs check` enforces): a non-empty
      >   `type`, and `status` + `superseded_by` on superseded records. These are *ours*; they survive
      >   regardless of OKF.
      > - **Inherited from OKF** (format conventions): reserved `index.md`/`log.md`, the bundle-root
      >   `okf_version`, bundle-relative links, the `# References` heading (§8). If OKF changes, only
      >   this row moves — re-pin the version in the `okf-knowledge-format` skill and adjust.
      
      Two rules apply to every concept file:
      
      1. **Frontmatter with a required `type`.** Every non-reserved `.md` doc opens with a YAML frontmatter block whose `type` names the doc kind (`Constitution`, `PRD`, `ADR`, `Issue`, `Context`, `Architecture View`, `Research`, `Reference`). Recommended: `title`, `description`, `tags`, `timestamp`. Living-docs adds producer keys: `status`, `supersedes`, `superseded_by`. **Status moves into frontmatter — no `**Status:**` body line.**
      2. **Reserved files + bundle-relative links.** The bundle root is `docs/`. Directory listings are `index.md` (OKF §6, no frontmatter — except the bundle-root `docs/index.md`, which carries `okf_version: "0.1"`). Optional `log.md` records directory history (§7). Cross-link with `/`-prefixed bundle-relative paths (`/adr/0007-slug.md`); list sources under a `# References` heading (§8), each entry formatted per `rules/citation-conventions.md` — **ABNT NBR 6023 structure, always carrying the link**, with connective labels in the project doc language (default English: `Available at: <URL>. Accessed on: <date>`) per `rules/doc-language.md`.
      
    • prd-conventions.md 3.6 KB
      # PRD Conventions
      
      A PRD is **optional**. Write one when a feature has a "who asked / what is out of scope / what success looks like" worth pinning down before the work starts. A PRD without that is just a large issue — keep it an issue. A PRD answers *what and why*; the ADRs and issues it spawns answer *how*.
      
      ## Format
      
      Each PRD is an **OKF concept** (`type: PRD`) — see the `okf-knowledge-format` skill. `status` (`Draft` | `Accepted` | `Implemented` | `Superseded`) lives in the frontmatter, not a body line. See `templates/prd.md`. Core sections:
      
      - **Problem / Motivation** — the user or system pain. Lead with the problem, not the solution. If you can't state the problem without naming a solution, grill it first (`grill-me`).
      - **Who asked** — the stakeholder or need driving this. A PRD with no identifiable requester is a solution looking for a problem.
      - **Goals** — what success looks like, as outcomes (not tasks).
      - **Non-goals** — what this explicitly does *not* cover. The most valuable section: it bounds scope and prevents creep.
      - **Requirements** — testable statements of what the system must do. Each must be falsifiable: "Search returns in <200ms at p95", not "search should be fast". A quality requirement (performance, availability, scale, security) states its measure and how it is verified.
      - **Acceptance criteria** — observable conditions that prove the requirement is met.
      - **Open questions** — unresolved decisions, each headed toward an ADR.
      
      ## Relationship to the constitution
      
      A PRD sits **under** the constitution — it specifies a feature within the product's established principles and constraints. A PRD never replaces or overrides the constitution. If a PRD requires a change at constitution level, resolve that separately before accepting the PRD.
      
      ## Rules
      
      1. **One capability per PRD.** Number sequentially: `docs/prd/NNNN-slug.md`. Index in `docs/prd/index.md` (OKF reserved listing, no frontmatter).
      2. **Problem before solution.** A PRD that opens with the implementation has skipped the thinking. Restate the underlying problem first.
      3. **Non-goals are mandatory.** An empty Non-goals section means scope is undefined. Name at least what tempting-but-excluded things are out.
      4. **Requirements are testable and measurable.** "The system should be fast" is not a requirement; "Search returns in <200ms at p95" is. A quality requirement without a way to verify it is a vibe — state the instrument (a load test, a CI floor, a security check) or, only for the genuine residue, explicit inspection.
      5. **Success metrics are mandatory.** State how success will be measured after delivery — quantified outcomes (not task completion) that would confirm the problem is solved.
      6. **Append-only once accepted.** A PRD under active design is editable. Once accepted and being implemented, changes are recorded as amendments or new ADRs — not silent edits to the requirements.
      7. **PRDs spawn issues.** Each requirement becomes one or more issues (see `rules/issue-workflow.md`). The PRD links to them; the issues link back to the PRD.
      8. **Open questions resolve into ADRs.** When an open question is answered with a load-bearing rationale expensive to reverse, write an ADR and link it from the PRD. A cheap resolution goes in the issue that carries the work.
      
      ## Anti-patterns
      
      - A PRD that is a task list. Tasks are issues; the PRD is the spec they serve.
      - A PRD written for a change that had no "who asked / out of scope" to pin — it should have been an issue.
      - No acceptance criteria — then "done" is a matter of opinion.
      - Editing accepted requirements in place when scope changes — amend or supersede so the history of what was agreed survives.
      
    • procedure.md 5.6 KB
      # Procedure
      
      ## Authoring mechanics — CLI-first (hard rule)
      
      The dividing line is **determinism**: a step with a single correct output given its inputs is
      the CLI's job; the judgment prose (the "why") is yours to write directly in the file. Applied:
      
      - **Use the CLI verb for every mechanical step — never hand-do it:** `new` (number + frontmatter
        + skeleton), `set <ref> <key> <value>` (set `status`/`description`/`owner`), `supersede <old>
        <new>` (links + status on both records), `index` (regenerate the listing), `check` (the gate,
        must pass).
      - **One authoring path: scaffold, then edit the body.** `new` writes the numbered file with
        its frontmatter and title heading filled and every body section as a `{{SLOT: hint}}`
        placeholder; the hint says what belongs in the slot and vanishes with it. Replace every slot
        with prose, or delete the slot and its heading when the record has nothing to say there —
        `check` fails on any slot left behind.
      - **Write the body prose directly.** The CLI must never author rationale, so there is no
        paragraph-editing verb — editing the body is a normal edit, not a process error. What *is* a
        process error is hand-numbering a doc, hand-writing frontmatter, hand-maintaining an index row,
        or hand-wiring `supersedes`/`superseded_by` when `supersede` does it deterministically. Write
        each paragraph as ONE line — never hard-wrap prose at a fixed column; the reading surface
        soft-wraps. `living-docs fmt` unwraps hard-wrapped paragraphs (ADR 0046), so a wrapped body is
        a `fmt` diff, not a style choice.
      - **When a deterministic frontmatter mutation has no verb yet** and you keep doing it by hand,
        add it as a `living-docs set` key rather than normalizing the hand-edit.
      
      ## Setting up living docs in a new project
      
      1. Create the project guide (`CLAUDE.md` or equivalent) with a **Docs index** section. Use `templates/claude-hard-rules.md` as the starting point for the hard-rules section; fill in the placeholders before committing.
      2. Create `docs/` with the directories the project needs (`adr/`, `issues/`, and `prd/`/`research/`/`architecture/` as they earn their place). Seed `docs/constitution.md` from `templates/constitution.md`. Add the bundle-root `docs/index.md` (carrying `okf_version: "0.1"`), and give each directory its own `index.md` listing from day one — even if near-empty.
      3. Seed the architecture views (`docs/architecture/`) with the high-level Mermaid diagrams the system already has, once it is worth drawing (`rules/architecture-diagrams.md`).
      4. Record any already-made decisions as ADRs so they are not re-litigated — but **confirm each with the user before recording** (see *Adopting living docs in an existing project*, steps 2–4); never back-fill an ADR by inference alone.
      
      ## Adopting living docs in an existing project (brownfield)
      
      An existing codebase already embodies decisions that were never written down. The failure mode here is the agent **back-filling ADRs by inference and presenting them as settled** — recording decisions the user was never asked to confirm. Adoption is therefore an *elicitation* exercise, not a transcription one.
      
      1. **Scaffold without deciding.** Create `docs/` + each directory's `index.md` and the bundle-root `docs/index.md`. This is mechanical — no decisions are made here.
      2. **Read the existing context first, then inventory the decisions — as candidates, not records.** Harvest what the project already carries: the code itself, plus the `README`, the agent guides (`CLAUDE.md` / `AGENTS.md`), package manifests, and any design notes. From that, produce a *list* of the load-bearing decisions the project appears to embody (stack, boundaries, data model, key trade-offs). Do **not** write ADRs yet.
      3. **Present the inventory to the user and confirm each.** For every candidate, state the inferred decision and the alternatives it appears to have ruled out, and ask the user to confirm, correct, or discard it — grill the load-bearing ones (`grill-me` if installed). The user owns the decision; the agent only surfaces what the code implies.
      4. **Record only the confirmed decisions as ADRs.** These are origin records — they supersede nothing. Capture the chosen option *and* the rejected alternatives the user confirmed. A candidate the user discards, or one whose rationale nobody actually knows, is **not** invented into an ADR.
      5. **Seed the architecture views** with the high-level Mermaid diagrams the system already has, then resume the *Maintaining* loop below.
      
      ## Maintaining living docs (every task)
      
      1. **Before coding:** read the relevant constitution and ADRs (`living-docs read` gives the in-force view). Decisions there are not to be re-opened casually. If a link or a search lands on a raw record whose body opens with a `SUPERSEDED` or `DEPRECATED` callout, treat it as history: follow the successor link or discard the record, never plan on it.
      2. **While working:** if you make a decision with a load-bearing rationale that is expensive to reverse, **grill it before recording it** — surface the decision, ≥2 materially-distinct alternatives, and a recommendation to the user (run the `grill-me` companion if installed, else inline), then write an ADR capturing the chosen option *and* the rejected ones. A cheap, easily-reversed choice goes in the issue's body, not a new ADR. Never record a decision the user was not asked about.
      3. **In the same change:** update every doc the structural change touches — index rows, architecture diagrams, the records that governed it. Run `living-docs check`.
      4. **Never** leave an index stale, an orphan file unlinked, a diagram contradicting the code, or a superseded decision silently edited.
      
    • semantic-index.md 4.7 KB
      # Semantic Index Organization
      
      Documentation is organized by **meaning, not by accident of growth**. When a body of knowledge is large, it is split into semantically coherent files, each with a single concern, all reachable from one index. The index is the entry point; the group files are the content.
      
      This applies to any large doc — most commonly the domain/module **context** (vocabulary), but equally to research, ADR collections, or any directory that accumulates files.
      
      ## The indexing contract
      
      1. **Every directory has an `index.md`** — the OKF reserved directory listing (§6), for collections (ADRs/issues/research) and split single docs (context) alike. It lists every file with a one-line description and carries **no frontmatter** (the sole exception: the bundle-root `docs/index.md`, which may declare `okf_version: "0.1"`).
      2. **Every file is reachable from an index, and from the bundle-root `docs/index.md`** linked by the project guide. No orphans.
      3. **One concept, one file.** Each group file owns a coherent slice of the vocabulary or content. A concept appears in exactly one group file; other files cross-reference it. Every group/concept file opens with OKF frontmatter carrying a non-empty `type`.
      4. **The index carries no content** — only intro framing + a table/list of pointers. Content lives in the group files, never duplicated into the index.
      5. **Links resolve.** Every pointer in an index points to a file that exists; prefer bundle-relative (`/…`) links. Check after every split or move.
      
      ## When and how to split a large doc
      
      Split when a doc passes ~200 lines or starts mixing unrelated concerns.
      
      1. **Map sections → groups.** Lay out a source map: each section of the old file → exactly one new group file. Decide group boundaries by *meaning* (write-path vs read-path, domain concepts vs storage shapes), not by length.
      2. **Content-preserving move.** Move vocabulary verbatim. Do not reword, add, or drop terms during a split — that conflates two changes and makes the diff unreviewable. Reword in a *separate* later change if needed.
      3. **One concept lands once.** If two sections discuss the same concept, pick its home and cross-reference from the other.
      4. **Build the index** — intro paragraph + a TOC table linking every group file with a one-line description. See `templates/context-index.md`.
      5. **Cut over.** Repoint the live pointers (project guide's Docs index, maintenance rules) to the new index. Delete the old monolith. Leave *historical* mentions (in ADR/issue "Consequences") untouched — they are history.
      6. **Completeness review.** Diff the old content against the union of new files: every term present exactly once, nothing lost or duplicated, all index links resolve, old file removed.
      
      ## Reading the corpus — the in-force view, not the raw index
      
      The corpus is append-only (supersede, never rewrite): right for history, wrong as the thing an agent reads. An `index.md` lists **everything**, including superseded links and stale records, and leaves supersede-chain resolution to the reader — who then plans on whichever record they opened first.
      
      **Agents read `living-docs read`, never `index.md` directly** (ADR 0050). It compiles the in-force view: active records only (superseded/deprecated withheld), supersede chains collapsed to the head with a one-line lineage (`supersedes 0131 via 0133`), grouped **constitution and PRDs first, then ADRs, then the rest** by number, so the reader orients before drilling in.
      
      - `living-docs read` — the whole active view (title + description per record).
      - `living-docs read --topic <term>` — only records whose title, description, or body contains the term (case-insensitive).
      - `living-docs read --full` — full record bodies instead of the one-line index entries.
      
      `index.md` remains the generated on-disk artifact and the human/browser entry point; `read` is the agent's read surface over the same records.
      
      A raw record opened directly still carries its own stop signal: a body that opens with a `SUPERSEDED` or `DEPRECATED` callout is history. Follow the successor link or discard the record; never plan on it; read `living-docs read` for what is in force.
      
      ## Heading discipline
      
      Each group file is a standalone document: it leads with a single `#` H1 title, then `##` sections. Do not carry over `##`-as-top-level headings from the section you extracted — promote them to H1 so the file reads as its own document.
      
      ## Anti-patterns
      
      - An index that duplicates content from the group files — now there are two homes and they will drift.
      - Splitting by line count into arbitrary "part 1 / part 2" files instead of by meaning.
      - Rewording vocabulary during a split — bundles two changes, breaks the content-preserving guarantee.
      - A group file with two unrelated concerns because "it was already there."
      
    • size-targets.md 1.5 KB
      # Doc Size Targets
      
      **Aim for ~100 body lines; the checker advises at 120.** The target is uniform across
      decision and execution records — ADR, PRD, issue. Exempt: research (long-form dated
      evidence), the constitution, context and architecture docs, and the reserved
      `index.md`/`log.md` listings.
      
      Body lines are what follows the closing frontmatter fence; the frontmatter block is
      never counted.
      
      ## Why a target at all
      
      Two costs grow linearly with prose length, and both are paid on every doc:
      
      1. **Authoring cost.** When the author is an agent, every body line is output tokens.
         Terse records are the single largest authoring saving available — larger than any
         cheaper-model scheme, because the mechanical half is already free (the CLI) and the
         judgment half cannot be delegated.
      2. **Reading and compaction cost.** Long docs are the first casualties of context
         compaction, and every reader — human or agent — pays the length again on every
         load. A record that fits in ~100 lines survives both.
      
      ## The two standing rules
      
      1. **Advisory, never a gate.** `living-docs check` prints a `SIZE` note for an
         over-target body and always leaves the exit code untouched. Judgment prose is never
         truncated to satisfy a number.
      2. **The target never trumps the rationale.** A load-bearing why stays, whatever the
         line count. Trim connective prose, restated cross-links, and content another doc
         already owns (one home per fact) — never the decision's substance.
      
    • spine.md 1.4 KB
      # Core invariants (the spine)
      
      These five invariants hold across **every** document type — ADR, PRD, constitution, issue,
      research, architecture. Everything else in this skill is one of these five applied to a
      specific document type. When a rule seems unclear, re-derive the right action from these.
      
      1. **Docs-first.** Author the body in the repo (`docs/…`) *before* publishing anywhere external
         (tracker, wiki). The repo file is the source of truth; the external copy is a mirror.
      2. **One home per fact.** Each concept, decision, or requirement lives in exactly one file. No
         duplication — cross-reference instead of copying. Duplicated prose is drift waiting to happen.
      3. **Indexed or it doesn't exist.** Every doc is reachable from an index (an `index.md` listing in
         its directory, and the bundle-root `docs/index.md` that the project guide links). No orphan
         files.
      4. **Supersede, never rewrite history.** Decisions and requirements are append-only records. When
         something changes, mark the old record superseded and write a new one — never silently edit the
         past.
      5. **No structural change without its doc.** New module, moved files, schema change, new data flow
         → update the relevant doc (and its diagram, if it has one) in the same change. No "I'll
         document it later."
      
      When in doubt, re-derive the right action from these five. The other topics are just these
      invariants applied to each document type.
      
  • templates
    • adr.md 1.1 KB
      ---
      type: ADR
      title: <Short decision title>
      description: <One sentence — the decision and its scope.>
      status: Proposed
      timestamp: <ISO 8601 datetime, e.g. 2026-06-13T00:00:00Z>
      ---
      
      # NNNN. <Short decision title>
      
      ## Context
      
      {{CONTEXT: the forces at play and what forced a decision, written for a newcomer; link the research or issue that motivates it; no solution here}}
      
      ## Decision
      
      We will {{DECISION}}.
      
      {{REJECTED_ALTERNATIVES: each alternative considered and the reason it lost; an ADR with no rejected alternative belongs in the issue}}
      
      ## Consequences
      
      **Easier / gained:**
      - {{GAINED}}
      
      **Harder / accepted trade-offs:**
      - {{COST}}
      
      **Follow-ups:**
      - {{FOLLOW_UP: a follow-up is an issue to open, never a deferred decision}}
      
      ## Verification
      
      **Implementation impact:** {{IMPLEMENTATION_IMPACT: the files or modules this decision touches}}
      
      **Verification criteria:**
      - {{VERIFICATION_CRITERION: a checkable condition, not an aspiration}}
      - {{FITNESS_FUNCTION: the test or lint that fails when the decision is violated; drop the whole section for a purely advisory record}}
      
      # References
      
      [1] [{{SOURCE}}]({{URL}})
      
    • architecture-index.md 568 B
      # Architecture
      
      Living architecture of the project, one view per concern, sequenced outside-in:
      context, containers, components, then runtime behavior (flows, sequences, states),
      data, and deployment. Each view names its drift instrument; update the relevant view
      in the same change as any structural code change (see `rules/maintenance-invariant.md`).
      
      * [Context](context.md) - context
      * [Backends](backends.md) - container
      * [Module layout](modules.md) - component
      * [Request round trip](request-round-trip.md) - sequence
      * [Data model](data-model.md) - data-model
      
    • architecture-view.md 495 B
      ---
      type: Architecture View
      title: <View name>
      description: <One sentence — what this view shows.>
      kind: component
      timestamp: <ISO 8601 datetime>
      ---
      
      # <View name>
      
      {{ORIENTATION_SENTENCE: what this view shows and for whom; one view per concern, nodes named with the context vocabulary}}
      
      ```mermaid
      flowchart LR
          A[Module A] --> B[Module B]
      ```
      
      ## Drift instrument
      
      Drift caught by: {{INSTRUMENT: the conformance check, schema diff, or inspection rule that catches drift for this view}}
      
    • claude-hard-rules.md 8.2 KB
      # CLAUDE.md — Hard Rules Template
      
      Copy this block into the project's `CLAUDE.md` and fill in the `<placeholders>`. Adapt the table of locations to match the project's actual directory structure.
      
      ---
      
      ## Living Docs
      
      Living Docs is a **decision log with a gate**. It records the engineering decisions a future reader would pay to rediscover, and refuses to let a record exist unindexed, untyped, or silently rewritten. It is not a per-layer paperwork requirement.
      
      **The one rule that decides whether to write a record:**
      
      > Write an **ADR** when a future reader would pay to rediscover *why* you chose this over the alternatives — i.e. the decision is expensive to reverse. Otherwise put the choice in the **issue** that carries the work. When in doubt, it is an issue, not an ADR.
      
      Most changes need no new decision record. A record is earned by materiality (a choice that is expensive to reverse), never by the fact that a change touched structure or behavior. Do not manufacture a record per layer.
      
      Load-bearing decisions are always confirmed with you before an ADR is recorded; the agent never back-fills a decision by inference.
      
      ## Doc-trail
      
      Records exist so a decision can be traced from its rationale to the code:
      
      ```
      constitution → PRD (optional) → ADR → issues → code
      ```
      
      Only what the change earns: a routine change is just an issue and code. A material decision earns an ADR in the same change. A product/feature spec earns a PRD when there is a "who asked / what is out of scope" worth pinning; a PRD without that is just a large issue.
      
      ## Locations
      
      Adapt this table to the project's actual paths before committing the rules.
      
      | Artifact | Location |
      |---|---|
      | Constitution | `docs/constitution.md` |
      | PRDs | `docs/prd/` |
      | ADRs | `docs/adr/` |
      | Issues | `docs/issues/` |
      | Research | `docs/research/` |
      
      ---
      
      ## Hard rules
      
      ### 1. Docs-first for material decisions
      
      A change that makes a decision expensive to reverse — an architecture, dependency, schema, or public-contract choice — ships its ADR in the same PR. A routine change shipping without a new record is complete; a material decision shipping without its ADR is not.
      
      ### 2. Diagrams are always Mermaid
      
      All diagrams in documentation must be Mermaid. Existing ASCII diagrams are converted whenever their containing doc is touched. Never introduce image-based or ASCII diagrams.
      
      ### 3. Semantic doc groups with OKF index files
      
      Every directory of documentation is a semantic group and must contain an `index.md` (the OKF reserved listing — no frontmatter, except the bundle-root `docs/index.md`, which declares `okf_version: "0.1"`). Every concept document opens with OKF frontmatter carrying a non-empty `type`; `status` and supersession live in frontmatter, never a body line. Every new document is linked from its group's `index.md` with bundle-relative (`/…`) links, and new groups are linked from the root docs index. No orphan documents. See the `okf-knowledge-format` skill.
      
      ### 4. The record types
      
      Four types answer four distinct questions. If a candidate record does not answer one of these, it is not that type — do not open it:
      
      - **ADR** — *what did we choose, what did we reject, and why?* A decision expensive to reverse, with its alternatives. `docs/adr/NNNN-slug.md`.
      - **Issue** — *what is the change, and how do we know it is done?* The unit of work; it carries any cheap-to-reverse choice inline.
      - **Research** — *what does external evidence say?* Dated evaluation of outside sources, in the OKF format (see the `research-artifacts` skill).
      - **Constitution** — *what never changes here?* The singleton of scope and non-negotiables.
      
      A **PRD** is optional: a product/feature spec with who-asked and out-of-scope. Behavior is specified by tests, not by a separate record type. A test-strategy *decision* is an ADR `tags: [testing]`.
      
      ### 5. Issues local-first
      
      Draft the issue as `docs/issues/NNNN-slug.md` first, linked from the issues index. Launch on the tracker, stripping the OKF frontmatter so only the body is sent. Backfill the tracker number into the issue's frontmatter (`tracker`) and the index. The local file is the trace; the tracker is execution state.
      
      ### 6. No comments in code
      
      Self-documenting names, small single-purpose functions, and extracted variables replace comments. A comment is permitted only for a constraint the code cannot express — a non-obvious external contract, a deliberate workaround with its reason. Never comment to narrate what the code does, restate history, or address a reviewer. No commented-out code. Never reference a project doc artifact from a docblock or comment — no ADR, PRD, issue, constitution article, research note, or delivery-slice name or number (for example `see ADR 0046` or `slice R2`); doc numbers change when records are superseded, so the reference rots — state the invariant itself and let the docs carry the numbering. External specification identifiers (an RFC, a CVE) are stable and remain allowed.
      
      ### 7. All internal artifacts in English
      
      Code, documentation, commit messages, ADRs, and issue drafts are written in English. Conversation language follows the user.
      
      ### 8. Generated artifact names describe what they do
      
      Migrations, scripts, and auto-named artifacts use descriptive names. For example: `--name <what_it_does>`, never auto-generated whimsical names. The name must let a future reader understand the artifact's purpose without opening it.
      
      ### 9. Quality gates — all must pass before merge
      
      All of the following must pass on every PR. No exceptions, no deferrals.
      
      | Gate | Command |
      |---|---|
      | Tests | `<test command>` |
      | Type checking | `<typecheck command>` |
      | Lint at zero warnings | `<lint command at zero warnings>` |
      | Mutation testing (changed code, per file) | `<mutation testing >= N% on changed code, per file>` |
      
      The docs-update rule from rule 1 is also a quality gate: a PR failing `living-docs check` does not merge.
      
      ### 10. Author docs through the living-docs CLI — never hand-do deterministic steps
      
      The dividing line is determinism: any documentation step with a single correct output given its inputs goes through the `living-docs` CLI; only the judgment prose (the "why") is authored by hand, directly in the file.
      
      - Use the CLI verb for every mechanical step: `living-docs new <type> "<title>"` (number + frontmatter + skeleton), `living-docs set <ref> <key> <value>` (sets `status`/`description`/`owner`), `living-docs supersede <old> <new>` (wires `supersedes`/`superseded_by` + status on both records), `living-docs index [type]` (regenerates the index), `living-docs check` (the doc-gate, must pass).
      - Write the body prose directly — there is no paragraph-editing verb, because wrapping a text edit in the CLI adds no determinism. Editing the body is a normal edit; hand-numbering a doc, hand-writing frontmatter, hand-maintaining an index row, or hand-wiring supersede links is a process error. Each paragraph is ONE line — never hard-wrap prose at a fixed column (`living-docs fmt` unwraps it).
      - When a deterministic frontmatter mutation has no verb yet and it keeps being done by hand, harden it into a `living-docs set` key rather than normalizing the hand-edit.
      - A record whose body opens with a `> **SUPERSEDED …**` or `> **DEPRECATED …**` callout is history. Follow the successor link, or discard the record if it has none; never plan on it. Read `living-docs read` for what is in force. The callout is CLI-written by `supersede`, `set`, or `fmt` — never by hand.
      
      **Write ONLY the body below the closing `---`.** Numbering, frontmatter (`type`, `title`, `status`, `supersedes`, `superseded_by`, `timestamp`), and index rows are CLI-owned; `description` and `tags` are yours.
      
      This rule is enforced by one gate, not prose: `living-docs check` runs at commit and in CI, and a hand-written record fails there in the session that authored it. Wire it once per project with:
      
      - **`living-docs install hooks [--dir <path>] [--docs-dir <bundle>] [--dry-run]`** (every harness): materializes the session-teaching script, wires it into `.claude/settings.json`, and installs a `pre-commit` hook running `living-docs check <bundle>`. Remove everything it wrote with the sibling `living-docs uninstall hooks [--dir <path>] [--dry-run]`.
      - **Knob:** `LIVING_DOCS_BUNDLE=<dir>` (docs bundle scope).
      
    • constitution.md 1.1 KB
      ---
      type: Constitution
      title: <Product> Constitution
      description: Foundational scope, data model, and non-negotiables for <product>.
      status: Draft
      timestamp: <ISO 8601 datetime>
      ---
      
      # Product Constitution
      
      ## Product
      
      {{PRODUCT: what the product is and who it serves, in one or two sentences; every PRD and ADR must be consistent with it}}
      
      ## Scope Boundaries
      
      **In scope:**
      
      - {{IN_SCOPE}}
      
      **Explicitly out of scope:**
      
      - {{OUT_OF_SCOPE: the tempting-but-excluded capability, named so it cannot creep in}}
      
      **Phase boundaries:**
      
      - Phase 1: {{PHASE_1_SCOPE}}
      - Phase 2: {{PHASE_2_SCOPE}}
      
      ## Data Model / Schema Foundation
      
      ```mermaid
      erDiagram
          ENTITY_A {
              type field "description"
          }
          ENTITY_B {
              type field "description"
          }
          ENTITY_A ||--o{ ENTITY_B : "relationship"
      ```
      
      {{DATA_MODEL: the core entities, cardinalities and invariants the diagram above shows}}
      
      ## Non-negotiables
      
      - {{NON_NEGOTIABLE: a constraint that holds regardless of feature or phase, falsifiable against the running system}}
      
      ## Amendment Log
      
      Amendments are appended here as `## Amendment N — YYYY-MM-DD: summary`; the sections above are not edited once ratified.
      
    • context-index.md 921 B
      # Context — Domain & Module Vocabulary
      
      The shared language for this project: the names used consistently across code, docs,
      and reviews. This index is the entry point; each group file owns one coherent slice of
      the vocabulary. A concept lives in exactly one file — cross-reference, never duplicate.
      
      ## Groups
      
      | File | Covers |
      |---|---|
      | [domain-concepts.md](domain-concepts.md)         | Core domain entities and rules |
      | [modules-<group-a>.md](modules-group-a.md)        | <e.g. write-path modules> |
      | [modules-<group-b>.md](modules-group-b.md)        | <e.g. read-path modules> |
      | [<shapes>.md](shapes.md)                          | <e.g. read/response shapes> |
      | [<storage>.md](storage.md)                        | <e.g. storage internals> |
      
      Each group file is a standalone OKF concept: `type: Context` frontmatter, one `#` title, then `##` sections. Add a row here whenever a new group file is created.
      
    • glossary.md 1.2 KB
      ---
      type: Context
      title: "Glossary"
      description: Definitions of the terms and acronyms used across the project docs.
      tags: [glossary, vocabulary, context]
      timestamp: 2026-06-15T00:00:00Z
      ---
      # Glossary
      
      Single home for every term and acronym the docs use. **Definitions are in the project doc language** (see `rules/doc-language.md`); term names, code identifiers, and acronym headwords/expansions stay in their original form. Each term is defined **once** here — other docs link to it rather than redefine. Keep entries alphabetical; split into grouped context files (`rules/semantic-index.md`) once this passes ~200 lines.
      
      ## Acronyms
      
      The headword is the acronym **as-is**; the expansion is the spelled-out form (may stay in its original language); the definition is in the doc language.
      
      | Acronym | Expansion | Definition |
      |---|---|---|
      | ADR | Architecture Decision Record | <one-line definition in the project doc language> |
      | PRD | Product Requirements Document | <one-line definition in the project doc language> |
      | OKF | Open Knowledge Format | <one-line definition in the project doc language> |
      
      ## Terms
      
      | Term | Definition | See also |
      |---|---|---|
      | <Term> | <one-line definition in the project doc language> | <links to related entries / ADRs> |
      
    • issue.md 663 B
      ---
      type: Issue
      title: <Issue title>
      description: <One sentence — the change and its motivation.>
      status: open
      timestamp: <ISO 8601 datetime>
      ---
      
      ## <Issue title>
      
      {{SUMMARY: the change and why; link the ADR or PRD it implements bundle-relative, e.g. Implements [ADR NNNN](/adr/NNNN-slug.md)}}
      
      ### Scope
      
      {{SCOPE: what is included; for a removal or refactor, what is explicitly kept}}
      
      ### Decision
      
      {{DECISION: any cheap-to-reverse choice made here, with the option not taken; remove the section when the issue decides nothing}}
      
      ### Acceptance
      
      - {{ACCEPTANCE_CRITERION: an observable, testable condition}}
      
      ### Plan
      
      {{PLAN: the slices, for a large task}}
      
    • prd.md 1.1 KB
      ---
      type: PRD
      title: <Feature / capability name>
      description: <One sentence — what capability this specifies.>
      status: Draft
      timestamp: <ISO 8601 datetime>
      ---
      
      # NNNN. <Feature / capability name>
      
      ## Problem / Motivation
      
      {{PROBLEM: who asked and what hurts, stated as a problem not a solution}}
      
      ## Goals
      
      - {{GOAL: what success looks like, not a task}}
      
      ## Non-goals
      
      - {{NON_GOAL: the tempting-but-excluded thing}}
      
      ## Requirements
      
      - {{REQUIREMENT: a falsifiable statement of what the system must do; a quality requirement names its measure and how it is verified}}
      
      ## Acceptance criteria
      
      - {{ACCEPTANCE_CRITERION: an observable condition proving a requirement is met}}
      
      ## Success metrics
      
      - {{SUCCESS_METRIC: a quantified outcome after delivery, not task completion}}
      
      ## Open questions
      
      - {{OPEN_QUESTION: resolved by an ADR when expensive to reverse, otherwise in the issue that carries the work}}
      
      ## Related
      
      - Constitution: [/constitution.md](/constitution.md)
      - Issues: [/issues/NNNN-<slug>.md](/issues/NNNN-<slug>.md)
      - Research: [/research/NNNN-<slug>.md](/research/NNNN-<slug>.md)
      
    • research.md 952 B
      ---
      type: Research
      title: <Short question or investigation title>
      description: <One sentence — the question this record answers.>
      status: Draft
      timestamp: <ISO 8601 datetime>
      ---
      
      # NNNN. <Short question or investigation title>
      
      ## Question
      
      {{QUESTION: stated so that an answer could be wrong; link the pending decision that motivated it}}
      
      ## Method
      
      {{METHOD: what was read or measured, against which version, with which tool, over what sample, and on which date}}
      
      ## Findings
      
      | Finding | Evidence | Confidence |
      |---|---|---|
      | {{FINDING: one row per finding, contradicting evidence included}} | {{EVIDENCE: traceable to a reference below}} | high / medium / low |
      
      ## Implications
      
      {{IMPLICATIONS: the decisions this evidence supports or rules out; the decision itself is an ADR}}
      
      ## Open Questions
      
      {{OPEN_QUESTIONS: where the edge of the evidence is}}
      
      # References
      
      [1] [{{SOURCE}}]({{URL}}). Available at: {{URL}}. Accessed on: {{DATE}}.
      
  • tests
    • fixtures
      • 01-fence-link-clean
        • docs
          • foo.md 144 B
            ---
            type: Reference
            title: Foo
            description: ""
            ---
            
            # Foo
            
            An example link that must NOT be followed:
            
            ```md
            See [bad](./does-not-exist.md)
            ```
            
          • index.md 27 B
            # Index
            
            - [Foo](./foo.md)
            
      • 02-fence-link-dirty
        • docs
          • foo.md 62 B
            ---
            type: Reference
            ---
            # Foo
            
            See [bad](./does-not-exist.md)
            
          • index.md 27 B
            # Index
            
            - [Foo](./foo.md)
            
      • 03-link-forms
        • docs
          • bar.md 58 B
            ---
            type: Reference
            title: Bar
            description: ""
            ---
            
            # Bar
            
          • foo.md 145 B
            ---
            type: Reference
            title: Foo
            description: ""
            ---
            
            # Foo
            
            - [a](./bar.md "Title")
            - [b](<./bar.md>)
            - [c](./bar.md)
            - [d][ref]
            
            [ref]: ./bar.md
            
          • index.md 45 B
            # Index
            
            - [Foo](./foo.md)
            - [Bar](./bar.md)
            
      • 04-frontmatter-quoted-commented
        • docs
          • a.md 24 B
            ---
            type: "ADR"
            ---
            # A
            
          • b.md 24 B
            ---
            type: 'ADR'
            ---
            # B
            
          • c.md 42 B
            ---
            type: ADR  # storage decision
            ---
            # C
            
          • index.md 51 B
            # Index
            
            - [A](./a.md)
            - [B](./b.md)
            - [C](./c.md)
            
      • 05-nested-key-trap
        • docs
          • foo.md 38 B
            ---
            meta:
              type: Reference
            ---
            # Foo
            
          • index.md 27 B
            # Index
            
            - [Foo](./foo.md)
            
      • 06-block-scalar-ok
        • docs
          • foo.md 28 B
            ---
            type: |
              ADR
            ---
            # Foo
            
          • index.md 27 B
            # Index
            
            - [Foo](./foo.md)
            
      • 07-supersede-broken
        • docs
          • 0001-old.md 65 B
            ---
            type: ADR
            status: Superseded
            superseded_by: "9999"
            ---
            # Old
            
          • index.md 32 B
            # Index
            
            - [Old](./0001-old.md)
            
      • 08-reference-link-broken
        • docs
          • foo.md 75 B
            ---
            type: Reference
            ---
            # Foo
            
            See [the bar][b].
            
            [b]: ./does-not-exist.md
            
          • index.md 27 B
            # Index
            
            - [Foo](./foo.md)
            
      • 09-okf-canonical
        • docs
          • datasets
            • crypto_bitcoin.md 2 KB
              ---
              type: BigQuery Dataset
              title: Cryptocurrency Bitcoin
              description: This BigQuery public dataset contains a complete history of the Bitcoin blockchain and updates every 10 minutes.
              tags: [bitcoin, blockchain, cryptocurrency, data-analytics, gcp, public data]
              resource: https://bigquery.googleapis.com/v2/projects/bigquery-public-data/datasets/crypto_bitcoin
              timestamp: 2026-05-28T22:44:47+00:00
              ---
              
              The `crypto_bitcoin` dataset provides a comprehensive and up-to-date record of the entire Bitcoin blockchain. It includes detailed information about [blocks](../tables/blocks.md), [transactions](../tables/transactions.md), transaction [inputs](../tables/inputs.md), and [outputs](../tables/outputs.md). This dataset is part of the BigQuery Public Datasets program, making it freely accessible for analysis and research into Bitcoin's operations, economics, and historical trends. Researchers, developers, and enthusiasts can use this data to understand transaction patterns, network activity, and the overall state of the Bitcoin network.
              
              # Schema
              
              This dataset contains the following tables, providing a complete history of the Bitcoin blockchain:
              
              *   [blocks](../tables/blocks.md)
              *   [inputs](../tables/inputs.md)
              *   [outputs](../tables/outputs.md)
              *   [transactions](../tables/transactions.md)
              
              # Common query patterns
              
              ```sql
              -- Count the total number of blocks in the Bitcoin blockchain
              SELECT
                  COUNT(*)
              FROM
                  `bigquery-public-data.crypto_bitcoin.blocks`;
              ```
              
              ```sql
              -- Get the total number of transactions over time
              SELECT
                  DATE(block_timestamp) AS transaction_date,
                  COUNT(transaction_id) AS total_transactions
              FROM
                  `bigquery-public-data.crypto_bitcoin.transactions`
              GROUP BY
                  transaction_date
              ORDER BY
                  transaction_date DESC
              LIMIT 100;
              ```
              
              # Citations
              
              [1] [BigQuery Public Dataset: crypto_bitcoin](https://bigquery.googleapis.com/v2/projects/bigquery-public-data/datasets/crypto_bitcoin)
              [2] [Bitcoin in BigQuery: blockchain analytics on public data](https://cloud.google.com/blog/products/gcp/bitcoin-in-bigquery-blockchain-analytics-on-public-data)
              
            • index.md 181 B
              # BigQuery Dataset
              
              * [Cryptocurrency Bitcoin](crypto_bitcoin.md) - This BigQuery public dataset contains a complete history of the Bitcoin blockchain and updates every 10 minutes.
              
          • tables
            • blocks.md 728 B
              ---
              type: BigQuery Table
              title: Bitcoin Blocks Table
              description: Details about the Bitcoin Blocks BigQuery table, including its schema.
              tags: [bigquery, bitcoin, blockchain, blocks]
              resource: https://bigquery.googleapis.com/v2/projects/bigquery-public-data/datasets/crypto_bitcoin/tables/blocks
              timestamp: 2026-05-28T22:43:59+00:00
              ---
              
              # Schema
              
              | Field | Type |
              | --- | --- |
              | hash | hex_string |
              | size | bigint |
              | stripped_size | bigint |
              | weight | bigint |
              | number | bigint |
              | version | bigint |
              | merkle_root | hex_string |
              | timestamp | bigint |
              | nonce | hex_string |
              | bits | hex_string |
              | coinbase_param | hex_string |
              | transaction_count | bigint |
              
              # Citations
              - https://github.com/blockchain-etl/bitcoin-etl
              
            • index.md 434 B
              # BigQuery Table
              
              * [Bitcoin Blocks Table](blocks.md) - Details about the Bitcoin Blocks BigQuery table, including its schema.
              * [Bitcoin Transaction Inputs](inputs.md) - Details about transaction inputs on the Bitcoin blockchain.
              * [Bitcoin Transactions](transactions.md) - A comprehensive table detailing all transactions on the Bitcoin blockchain.
              * [Outputs](outputs.md) - Outputs from all transactions in the Bitcoin blockchain.
              
            • inputs.md 2.1 KB
              ---
              type: BigQuery Table
              title: Bitcoin Transaction Inputs
              description: Details about transaction inputs on the Bitcoin blockchain.
              tags: [bitcoin, blockchain, cryptocurrency, etl, inputs, transactions]
              resource: https://bigquery.googleapis.com/v2/projects/bigquery-public-data/datasets/crypto_bitcoin/tables/inputs
              timestamp: 2026-05-28T22:44:24+00:00
              ---
              
              This table, part of the public [crypto_bitcoin](../datasets/crypto_bitcoin.md) dataset, contains detailed information about every input used in Bitcoin transactions. Each row represents a single transaction input, which typically references an unspent output from a previous transaction. This table is crucial for tracing the flow of Bitcoin and understanding the history of transactions. It records where the coins originated (`spent_transaction_hash` and `spent_output_index`) and the associated `value` transferred. This table can be joined with the [transactions](transactions.md) table on `transaction_hash` and [outputs](outputs.md) to reconstruct the full transaction graph.
              
              # Schema
              
              *   `transaction_hash`: STRING
              *   `block_hash`: STRING
              *   `block_number`: INTEGER
              *   `block_timestamp`: TIMESTAMP
              *   `index`: INTEGER
              *   `spent_transaction_hash`: STRING
              *   `spent_output_index`: INTEGER
              *   `script_asm`: STRING
              *   `script_hex`: STRING
              *   `sequence`: INTEGER
              *   `required_signatures`: INTEGER
              *   `type`: STRING
              *   `addresses`: REPEATED STRING
              *   `value`: NUMERIC
              
              # Common query patterns
              
              ```sql
              SELECT *
              FROM `bigquery-public-data.crypto_bitcoin.inputs`
              WHERE transaction_hash = 'YOUR_TRANSACTION_HASH_HERE'
              LIMIT 10
              ```
              
              ```sql
              SELECT
                  block_number,
                  SUM(value) AS total_input_value
              FROM `bigquery-public-data.crypto_bitcoin.inputs`
              WHERE block_number = 600000 -- Example block number
              GROUP BY block_number
              ```
              
              ```sql
              SELECT DISTINCT
                  address
              FROM `bigquery-public-data.crypto_bitcoin.inputs`,
                  UNNEST(addresses) AS address
              WHERE block_timestamp >= '2023-01-01'
              LIMIT 10
              ```
              
              # Citations
              
              [1] [BigQuery Table: inputs](https://bigquery.googleapis.com/v2/projects/bigquery-public-data/datasets/crypto_bitcoin/tables/inputs)
              [2] [blockchain-etl/bitcoin-etl](https://github.com/blockchain-etl/bitcoin-etl)
              
            • outputs.md 2.2 KB
              ---
              type: BigQuery Table
              title: Outputs
              description: Outputs from all transactions in the Bitcoin blockchain.
              tags: [bitcoin, blockchain, etl, outputs, transactions]
              resource: https://bigquery.googleapis.com/v2/projects/bigquery-public-data/datasets/crypto_bitcoin/tables/outputs
              timestamp: 2026-05-28T22:44:32+00:00
              ---
              
              The `outputs` table contains records of all transaction outputs within the Bitcoin blockchain. Each row in this table represents a single output from a Bitcoin transaction, detailing the amount transferred, the destination addresses, and other script-related information. This table is crucial for understanding the flow of Bitcoin and analyzing transaction patterns, especially when linked with the `[transactions](transactions.md)` and `[inputs](inputs.md)` tables.
              
              # Schema
              
              - `transaction_hash`: The hash of the transaction this output belongs to.
              - `block_hash`: The hash of the block containing this transaction.
              - `block_number`: The number of the block containing this transaction.
              - `block_timestamp`: The timestamp of the block containing this transaction.
              - `index`: The zero-based index of this output within its transaction.
              - `script_asm`: The script in assembly format.
              - `script_hex`: The script in hexadecimal format.
              - `required_signatures`: The number of signatures required to spend this output.
              - `type`: The type of the output script.
              - `addresses`: (REPEATED) Array of destination addresses for this output.
              - `value`: The value of the output in satoshis.
              
              # Common query patterns
              
              ```sql
              SELECT
                t.*
              FROM
                `bigquery-public-data.crypto_bitcoin.outputs` AS t
              WHERE
                t.transaction_hash = 'some_transaction_hash'
              ```
              
              ```sql
              SELECT
                SUM(t.value) AS total_output_value
              FROM
                `bigquery-public-data.crypto_bitcoin.outputs` AS t
              WHERE
                t.block_number = 123456
              ```
              
              ```sql
              SELECT
                t.type,
                COUNT(*) AS output_count
              FROM
                `bigquery-public-data.crypto_bitcoin.outputs` AS t
              WHERE
                t.block_timestamp BETWEEN TIMESTAMP('2023-01-01') AND TIMESTAMP('2023-01-31')
              GROUP BY
                t.type
              ORDER BY
                output_count DESC
              ```
              
              # Citations
              
              [1] [Outputs Table](https://bigquery.googleapis.com/v2/projects/bigquery-public-data/datasets/crypto_bitcoin/tables/outputs)
              [2] [Bitcoin ETL on GitHub](https://github.com/blockchain-etl/bitcoin-etl)
              
            • transactions.md 5.5 KB
              ---
              type: BigQuery Table
              title: Bitcoin Transactions
              description: A comprehensive table detailing all transactions on the Bitcoin blockchain.
              tags: [bitcoin, blockchain, crypto, etl, public data, transactions]
              resource: https://bigquery.googleapis.com/v2/projects/bigquery-public-data/datasets/crypto_bitcoin/tables/transactions
              timestamp: 2026-05-28T22:45:04+00:00
              ---
              
              The `transactions` table in the [crypto_bitcoin](../datasets/crypto_bitcoin.md) dataset provides a complete record of every transaction ever processed on the Bitcoin blockchain. Each row represents a single transaction, offering granular details such as its hash, size, associated [block](blocks.md) information (hash, number, timestamp), and the total input and output values. Importantly, it includes detailed arrays for both [inputs](inputs.md) and [outputs](outputs.md), each specifying spent transaction details, script information, involved addresses, and values. This table is essential for in-depth analysis of transaction flows, tracing funds, and understanding the economic activity within the Bitcoin network. The grain is one row per transaction, with data spanning the entire history of the Bitcoin blockchain, partitioned by `block_timestamp_month`.
              
              # Schema
              - `hash` STRING REQUIRED: The hash of this transaction
              - `size` INTEGER: The size of this transaction in bytes
              - `virtual_size` INTEGER: The virtual transaction size (differs from size for witness transactions)
              - `version` INTEGER: Protocol version specified in block which contained this transaction
              - `lock_time` INTEGER: Earliest time that miners can include the transaction in their hashing of the Merkle root to attach it in the latest block of the blockchain
              - `block_hash` STRING REQUIRED: Hash of the block which contains this transaction
              - `block_number` INTEGER REQUIRED: Number of the block which contains this transaction
              - `block_timestamp` TIMESTAMP REQUIRED: Timestamp of the block which contains this transaction
              - `block_timestamp_month` DATE REQUIRED: Month of the block which contains this transaction
              - `input_count` INTEGER: The number of inputs in the transaction
              - `output_count` INTEGER: The number of outputs in the transaction
              - `input_value` NUMERIC: Total value of inputs in the transaction
              - `output_value` NUMERIC: Total value of outputs in the transaction
              - `is_coinbase` BOOLEAN: True if this transaction is a coinbase transaction
              - `fee` NUMERIC: The fee paid by this transaction
              - `inputs` RECORD REPEATED: Transaction inputs
                - `index` INTEGER REQUIRED: 0-indexed number of an input within a transaction
                - `spent_transaction_hash` STRING: The hash of the transaction which contains the output that this input spends
                - `spent_output_index` INTEGER: The index of the output this input spends
                - `script_asm` STRING: Symbolic representation of the bitcoin's script language op-codes
                - `script_hex` STRING: Hexadecimal representation of the bitcoin's script language op-codes
                - `sequence` INTEGER: A number intended to allow unconfirmed time-locked transactions to be updated before being finalized
                - `required_signatures` INTEGER: The number of signatures required to authorize the spent output
                - `type` STRING: The address type of the spent output
                - `addresses` STRING REPEATED: Addresses which own the spent output
                - `value` NUMERIC: The value in base currency attached to the spent output
              - `outputs` RECORD REPEATED: Transaction outputs
                - `index` INTEGER REQUIRED: 0-indexed number of an output within a transaction
                - `script_asm` STRING: Symbolic representation of the bitcoin's script language op-codes
                - `script_hex` STRING: Hexadecimal representation of the bitcoin's script language op-codes
                - `required_signatures` INTEGER: The number of signatures required to authorize spending of this output
                - `type` STRING: The address type of the output
                - `addresses` STRING REPEATED: Addresses which own this output
                - `value` NUMERIC: The value in base currency attached to this output
              
              # Common query patterns
              ```sql
              -- Get the total number of transactions per day
              SELECT
                  DATE(block_timestamp) AS transaction_date,
                  COUNT(hash) AS transaction_count
              FROM
                  `bigquery-public-data.crypto_bitcoin.transactions`
              WHERE
                  block_timestamp BETWEEN '2023-01-01' AND '2023-01-31'
              GROUP BY
                  transaction_date
              ORDER BY
                  transaction_date DESC;
              ```
              ```sql
              -- Find transactions involving a specific address as an output
              SELECT
                  t.hash AS transaction_hash,
                  t.block_timestamp
              FROM
                  `bigquery-public-data.crypto_bitcoin.transactions` AS t,
                  UNNEST(t.outputs) AS output
              WHERE
                  '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa' IN UNNEST(output.addresses)
              LIMIT 10;
              ```
              ```sql
              -- Calculate the total fees collected in a given month
              SELECT
                  FORMAT_TIMESTAMP('%Y-%m', block_timestamp) AS transaction_month,
                  SUM(fee) AS total_fee
              FROM
                  `bigquery-public-data.crypto_bitcoin.transactions`
              WHERE
                  block_timestamp BETWEEN '2023-01-01' AND '2023-01-31'
              GROUP BY
                  transaction_month;
              ```
              ```sql
              -- Find duplicate transactions (anomaly detection)
              SELECT
                 *
              FROM (
               SELECT
                 hash,
                 COUNT(hash) AS dup_transaction_count
               FROM
                 `bigquery-public-data.crypto_bitcoin.transactions`
               GROUP BY
                 hash)
              WHERE
               dup_transaction_count > 1
              ```
              
              # Citations
              [1] [Bitcoin Transactions](https://bigquery.googleapis.com/v2/projects/bigquery-public-data/datasets/crypto_bitcoin/tables/transactions)
              [2] [Bitcoin ETL](https://github.com/blockchain-etl/bitcoin-etl)
              [3] [Bitcoin in BigQuery: blockchain analytics on public data](https://cloud.google.com/blog/products/gcp/bitcoin-in-bigquery-blockchain-analytics-on-public-data)
              
          • index.md 297 B
            # Subdirectories
            
            * [datasets](datasets/index.md) - This BigQuery public dataset contains a complete history of the Bitcoin blockchain and updates every 10 minutes.
            * [tables](tables/index.md) - This directory contains BigQuery table details for Bitcoin blocks, transactions, inputs, and outputs.
            
        • PROVENANCE.md 1.4 KB
          # Positive parity fixture — the OKF format author's own canonical bundle
          
          `docs/` is a **verbatim, vendored copy** of an example bundle published by the authors
          of the Open Knowledge Format, used here as a positive parity test: our checker must
          accept the bundle the format's own authors ship as canonical.
          
          | Field | Value |
          |---|---|
          | Source repo | `GoogleCloudPlatform/knowledge-catalog` |
          | Source path | `okf/bundles/crypto_bitcoin/` (the 8 `.md` files; `viz.html` is omitted — no doc links to it) |
          | Ref (commit) | `d44368c15e38e7c92481c5992e4f9b5b421a801d` (branch `main`) |
          | Retrieved | 2026-06-21 |
          | Upstream license | Apache-2.0 (see `ATTRIBUTION.md`) |
          
          This is the smallest of the three upstream bundles (crypto_bitcoin / ga4 / stackoverflow);
          all three pass `living-docs check` cleanly. Only one is vendored to keep the repo small.
          
          It also documents the relationship between OKF and Living Docs: `living-docs check` enforces
          **OKF §9 conformance** (parseable frontmatter, non-empty `type`, reserved-file rules) **plus**
          the stricter Living Docs governance invariants (links resolve, index membership +
          reachability, supersede integrity). OKF's own §9 tells *consumers* to be permissive
          (they MUST NOT reject for broken links or a missing `index.md`); Living Docs is an
          *authoring* discipline that deliberately adds those stricter checks. This canonical
          bundle happens to satisfy both — which is exactly what makes it a good parity probe.
          
      • 10-mermaid-valid
        • doc.md 287 B
          # Mermaid fixture — valid diagrams
          
          A flowchart:
          
          ```mermaid
          flowchart TD
            A[Start] --> B{Decision}
            B -->|Yes| C[Do the thing]
            B -->|No| D[Skip it]
          ```
          
          An entity-relationship diagram:
          
          ```mermaid
          erDiagram
            CUSTOMER ||--o{ ORDER : places
            ORDER ||--|{ LINE_ITEM : contains
          ```
          
      • 11-mermaid-invalid
        • doc.md 141 B
          # Mermaid fixture — invalid diagram
          
          This diagram has a broken arrow chain and must fail parsing:
          
          ```mermaid
          flowchart TD
          A --> --> B
          ```
          
    • run.sh 3.7 KB
      #!/usr/bin/env bash
      #
      # run.sh — hostile/negative fixtures for the `living-docs check` CLI.
      #
      # The example corpus (examples/linkly/docs) only exercises the happy path, so it can't
      # catch regressions in the three fragile parsers (link extraction, link resolution,
      # frontmatter reading). Each fixture below asserts the CLI's exit code AND that an
      # expected violation string is present (or absent) in its output.
      #
      # Points at the `living-docs` binary rather than the retired lint-docs.sh /
      # lint-mermaid.sh shell scripts (S6). Set LIVING_DOCS_BIN to reuse an
      # already-built binary; otherwise this builds cli/ via cargo.
      #
      # Exit: 0 = all fixtures pass, 1 = at least one failed.
      
      set -uo pipefail
      
      HERE="$(cd "$(dirname "$0")" && pwd)"
      REPO_ROOT="$(cd "$HERE/../../.." && pwd)"
      FIXTURES="$HERE/fixtures"
      
      resolve_binary() {
      	if [[ -n "${LIVING_DOCS_BIN:-}" ]]; then
      		printf '%s' "$LIVING_DOCS_BIN"
      		return
      	fi
      	cargo build --quiet --manifest-path "$REPO_ROOT/cli/Cargo.toml" >&2 || exit 2
      	printf '%s' "$REPO_ROOT/cli/target/debug/living-docs"
      }
      
      LIVING_DOCS="$(resolve_binary)"
      
      fail=0
      
      assert_result() { # assert_result <name> <expected_exit> <present|absent> <substring> <actual_exit> <output>
      	local name="$1" exp="$2" mode="$3" sub="$4" rc="$5" out="$6"
      	local ok=1
      	[[ "$rc" == "$exp" ]] || ok=0
      	if [[ "$mode" == "present" ]]; then
      		grep -qF -- "$sub" <<<"$out" || ok=0
      	else
      		grep -qF -- "$sub" <<<"$out" && ok=0
      	fi
      	if ((ok == 1)); then
      		printf '  ok    %s\n' "$name"
      	else
      		printf '  FAIL  %s — exit %s (expected %s), expected %s: "%s"\n' \
      			"$name" "$rc" "$exp" "$mode" "$sub"
      		printf '%s\n' "$out" | sed 's/^/          | /'
      		fail=1
      	fi
      }
      
      run() { # run <name> <expected_exit> <present|absent> <substring>
      	local name="$1" exp="$2" mode="$3" sub="$4"
      	local out rc
      	out="$("$LIVING_DOCS" check "$FIXTURES/$name/docs" --plain 2>&1)"
      	rc=$?
      	assert_result "$name" "$exp" "$mode" "$sub" "$rc" "$out"
      }
      
      run_mermaid() { # run_mermaid <name> <expected_exit> <present|absent> <substring>
      	local name="$1" exp="$2" mode="$3" sub="$4"
      	local out rc
      	out="$("$LIVING_DOCS" check --mermaid-only --plain "$FIXTURES/$name" 2>&1)"
      	rc=$?
      	assert_result "$name" "$exp" "$mode" "$sub" "$rc" "$out"
      }
      
      echo "living-docs check hostile fixtures"
      echo
      
      # Links (delegated to lychee): fenced code blocks are skipped; titled / angle-bracket /
      # bare / reference-style links all resolve; broken links of any form are caught.
      run 01-fence-link-clean             0 absent  "broken link"
      run 02-fence-link-dirty             1 present "broken link"
      run 03-link-forms                   0 absent  "broken link"
      run 08-reference-link-broken        1 present "broken link"
      
      # Frontmatter (delegated to yq, real YAML): quotes + inline comment read fine; a block
      # scalar is a valid value; a nested key does NOT rescue a missing top-level key.
      run 04-frontmatter-quoted-commented 0 absent  "non-empty 'type'"
      run 06-block-scalar-ok              0 absent  "non-empty 'type'"
      run 05-nested-key-trap              1 present "non-empty 'type'"
      
      # Invariant-4 regression guard — broken superseded_by still fires.
      run 07-supersede-broken            1 present "has no matching record"
      
      # Positive parity — the OKF format author's own canonical bundle must pass clean
      # (vendored from GoogleCloudPlatform/knowledge-catalog; see the fixture's PROVENANCE.md).
      run 09-okf-canonical                0 present "no invariant violations"
      
      # check --mermaid-only (delegated to the real Mermaid parser via mermaid-cli): a valid
      # flowchart + erDiagram pass clean; a syntactically broken diagram fails with a file:line pointer.
      run_mermaid 10-mermaid-valid        0 absent  "FAIL"
      run_mermaid 11-mermaid-invalid      1 present "doc.md:"
      
      echo
      if ((fail == 0)); then
      	echo "All fixtures passed."
      	exit 0
      else
      	echo "Fixture failures."
      	exit 1
      fi
      
  • SKILL.md 5.9 KB
    ---
    name: living-docs
    description: Run a project's engineering decisions as a living log — MADR-lite ADRs (supersede, never delete) for decisions expensive to reverse, issues for the work (and its cheap-to-reverse choices), research artifacts, an optional PRD, a project constitution, and living Mermaid architecture views, where every record has exactly one home, indexes never drift, and a record is earned by materiality, not written per layer. Use when setting up or maintaining project docs, writing an ADR/PRD/constitution/issue/research note, drawing or updating an architecture diagram, or enforcing the no-drift maintenance rule.
    version: "0.18.0"
    metadata:
      type: skill
      layer: procedural
      tags: [documentation, adr, prd, constitution, issues, research, architecture]
    ---
    
    # Living Docs
    
    Living Docs is a **decision log with a gate**. It records the engineering decisions a future reader would pay to rediscover, traces each from its rationale to the code, and refuses to let a record exist unindexed, untyped, or silently rewritten. The spine — **every piece of knowledge has exactly one home, that home is indexed, and a material decision ships with its record** — carries a small set of record types: ADRs, issues, research, a constitution, an optional PRD, and living architecture views.
    
    This skill is stack-agnostic. It governs *how* decisions are recorded and maintained, never *what* technology a project uses.
    
    ---
    
    ## Using this skill (progressive disclosure)
    
    This SKILL.md is a **slim stub** — a trigger plus a task→topic router. The `living-docs` CLI
    holds the full, authoritative conventions and templates and discloses them progressively.
    **Before authoring anything, load the topic for your task and operate from it, not from this
    stub:**
    
    - `living-docs guide --list` — discover every topic.
    - `living-docs guide <topic>` — load that topic's full rules (+ template).
    
    Piped output is minified JSON (machine default); `--plain` for human text, `--json` to force
    JSON.
    
    Write ONLY the body below the closing ---. Frontmatter and indexes are CLI-owned: `living-docs set` / `supersede` / `index`.
    
    - The spine invariants → `living-docs guide spine`.
    - Authoring mechanics — CLI owns every deterministic step, you write only the prose →
      `living-docs guide procedure`.
    
    ## The one rule that decides whether to write a record
    
    Write an **ADR** when a future reader would pay to rediscover *why* you chose this over the
    alternatives — i.e. the decision is expensive to reverse. Otherwise put the choice in the
    **issue** that carries the work. When in doubt, it is an issue. A record is earned by
    materiality, never by the fact that a change touched structure or behavior — do not manufacture
    a record per layer.
    
    ---
    
    ## When to invoke
    
    - Standing up documentation for a project (creating `docs/` structure, the docs index, ADR/issue directories) → `living-docs guide procedure`.
    - **Adopting living-docs in an existing/brownfield project** (decisions already made but undocumented) → `living-docs guide procedure`, *Adopting living docs in an existing project*: inventory the decisions, **confirm each with the user before recording any ADR**, never back-fill by inference alone. A bundle authored under an older organization is brought current by `living-docs index` and `living-docs fmt`, then `living-docs check`.
    - Writing or editing an **ADR** (a decision expensive to reverse, with its rejected alternatives) → `living-docs guide adr` (load `guide procedure` first if not already loaded this session). A test-strategy *decision* (non-default level/technique, bar deviation) is an ADR `tags: [testing]`, not a new record type.
    - Writing or editing a **PRD** (an optional product/feature spec: who asked, what is out of scope, what success looks like) → `living-docs guide prd` (load `guide procedure` first). A PRD without who-asked/out-of-scope is just a large issue — keep it an issue.
    - Establishing or amending the **constitution** (foundational scope, non-negotiables) → `living-docs guide constitution` (load `guide procedure` first).
    - Creating or editing an **issue/ticket** (the unit of work; it carries any cheap-to-reverse decision inline) → `living-docs guide issue-workflow` (load `guide procedure` first).
    - Recording **research** (technology evaluation, external trade-offs) → load the **`research-artifacts`** skill. It owns the OKF research-note format, the source discipline, and the research → decision → issue traceable chain, and links back here for the ADR/issue artifacts. Pairs with the `deep-research` skill.
    - Drawing or updating an **architecture, data-flow, or tool-calling diagram** → `living-docs guide architecture-diagrams`.
    - A doc has grown too large or mixes concerns → **split into a semantic index** → `living-docs guide semantic-index`.
    - **Reading the corpus as an agent** (what governs X *now*) → run `living-docs read` (active records only, supersede chains collapsed; `--topic <term>` to filter, `--full` for bodies — ADR 0050), **never `index.md` directly**. A raw record whose body opens with a `SUPERSEDED` or `DEPRECATED` callout is history — follow the successor link or discard it, never plan on it.
    - Sizing a record's body (aim ~100 lines, `check` advises at 120; research exempt; never trim a load-bearing rationale) → `living-docs guide size-targets`.
    - Enforcing the **no-drift maintenance rule** after any structural change → run `living-docs check`; treat a non-zero exit as blocked; treat each advisory (`SIZE`, `LIVENESS stale-proposed`, `MOVED-SOURCE`) as work to schedule. Detail → `living-docs guide check`; the maintaining loop → `guide procedure`.
    - Authoring or checking the **OKF format** of any doc (frontmatter `type`, reserved `index.md`/`log.md`, bundle-relative links, `# References`) → `living-docs guide okf-format`.
    - Understanding the **doc trail** (constitution → PRD → ADR → issues → code) and which record type answers which question → `living-docs guide doc-trail`.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related