---
schema_version: 1
id: RAC-KV2QQPHY9SZ1
type: roadmap
---
# RAC v0.13.6 — OKF Bundle Export

## Status

Planned

## Context

ADR-048 adopts Google's Open Knowledge Format (OKF v0.1 Draft) as an informative
carrier profile and a **derived export target**, and `rac-okf-carrier-profile`
scopes the work. This milestone delivers the export half: a new `rac export
--okf` view that projects the corpus as a conformant OKF bundle, parallel to the
existing JSON and Portal exports (ADR-007, ADR-014).

The corpus is already OKF-shaped, so the export is additive and reuses the
existing machinery. `build_corpus_export()` already walks the corpus once,
classifies artifacts, renders bodies, and resolves relationships — and already
**excludes Unknown-type files**, exactly the set OKF would have no `type` for.
The git-derived recency service (ADR-045) and the repository index service supply
the `log.md` and `index.md` conventions the profile recommends. No validation
behaviour changes; the bundle is a derived output, never a source format.

This milestone deliberately excludes making `type` mandatory at the source and
the CI conformance gate (`rac-okf-carrier-profile` REQ-001). That tightens
validation and revises ADR-025, so it is a separately recorded decision and a
later fence. Export degrades gracefully without it: untyped documents are simply
absent from the bundle, as they already are from the JSON export.

## Outcomes

- `rac export <dir> --okf` writes a conformant OKF v0.1 bundle: one Markdown file
  per typed artifact carrying a projected OKF `type`, plus generated `index.md`
  and `log.md`.
- The OKF `type` mirrors the RAC `type` per the ADR-048 mapping
  (`decision`→`ADR`, `requirement`→`Requirement`, `roadmap`→`Roadmap`,
  `prompt`→`Prompt`, `design`→`Design`); the RAC `type` stays authoritative.
- Every relationship that resolves under `rac relationships --validate` appears
  in the bundle as a body link, so links survive for permissive OKF consumers
  while the typed front matter remains the source of truth.
- The existing JSON and HTML exports, and all validation, are byte-for-byte
  unchanged.

## Initiatives

### Initiative 1 — OKF Bundle Renderer

Add `src/rac/output/okf.py` that turns a `CorpusExport` into an in-memory bundle:
a mapping of relative bundle paths to file contents. Each artifact becomes a
Markdown file with OKF front matter (`type` projected via the ADR-048 mapping,
`id` preserved) and its original body, with a derived `# Citations` / body-link
block for resolved relationships. The renderer is pure and deterministic
(artifacts ordered by path, links by target), mirroring `render_export_json`.

### Initiative 2 — Generated index.md and log.md

Generate `index.md` (progressive disclosure: overview, then artifacts grouped by
type) from the repository index, and `log.md` (date-grouped, newest-first) from
the git-recency service (ADR-045). Outside a git repository, recency is unknown
and `log.md` degrades to a stable placeholder rather than failing — no exception
crosses the boundary, consistent with the recency service's contract.

### Initiative 3 — CLI Surface

Add `--okf` to the `export` mutually-exclusive mode group and `--out` handling so
`rac export <dir> --okf --out <bundle-dir>` writes the bundle to a directory
(default `okf-bundle/`). `--json` remains the default; `--okf` and `--html` stay
mutually exclusive. Exit codes follow the existing export command (`0` success,
`2` usage/IO error).

### Initiative 4 — Coverage and Documentation

Service-level unit tests for the renderer (type projection, link rendering,
determinism, Unknown-type exclusion, empty corpus) and a golden bundle over a
fixture corpus. Update `docs/okf-profile.md` to point at the live command, add a
CHANGELOG entry, and mark `rac-okf-carrier-profile` REQ-002/003 (and the REQ-005
conventions) as delivered by this milestone.

## Constraints

- Additive only (ADR-007): no existing export output, CLI flag, JSON field, or
  validation behaviour changes. `--okf` is a new mode.
- The bundle is a derived output (ADR-016, ADR-048): RAC front matter and
  `## Related <Type>` sections stay authoritative; the bundle never becomes a
  source RAC reads back.
- No code, package, or network dependency on OKF or Google tooling; the profile
  stays pinned to OKF v0.1 (ADR-048).
- Determinism (REQ-Trust-Transparency): same corpus state yields a byte-identical
  bundle; all ordering is explicit.

## Non-Goals

- Making `type` mandatory at the source or adding a CI OKF-conformance gate
  (`rac-okf-carrier-profile` REQ-001) — a separate ADR and fence.
- A round-trip importer that reads an OKF bundle back into RAC; export is one-way.
- Promoting the OKF bundle to a frozen contract alongside the JSON export — a
  future ADR if and when it is warranted (ADR-048).
- Reading or validating bundles produced by other OKF tools.

## Implementation Contract

The following decisions are pinned for v0.13.6.

### CLI

- `rac export <dir> --okf [--out <bundle-dir>]` writes a bundle directory
  (default `okf-bundle/`). `--okf` joins the existing `--json` / `--html`
  mutually-exclusive group; `--out` applies to `--html` and `--okf`.
- An existing `--out` directory is overwritten (exports are build artifacts),
  matching the `--html` contract.

### Bundle layout

- One file per typed artifact at a path derived from its source path under the
  bundle root; Unknown-type files are excluded (as in the JSON export).
- `index.md` at the bundle root; `log.md` at the bundle root.
- Each artifact file: OKF front matter with the projected `type` and preserved
  `id`, the original Markdown body, and a derived body-link block for resolved
  relationships.

### Behaviour

- The OKF `type` is derived from the RAC `type`; an artifact whose RAC `type`
  has no mapping is not emitted (cannot occur for the five enumerated types).
- `log.md` uses ISO `YYYY-MM-DD` date grouping, newest-first, from git recency;
  unknown recency degrades to a placeholder, never an error.
- JSON/HTML export, `rac validate`, and `rac relationships --validate` are
  unchanged.

## Success Measures

- `rac export rac/ --okf --out okf-bundle/` produces a bundle whose every
  artifact file carries a non-empty OKF `type` matching the mapping, plus
  `index.md` and `log.md`.
- Each relationship that `rac relationships rac/ --validate` resolves has a
  corresponding body link in the bundle.
- Re-running the export on the same corpus state yields a byte-identical bundle
  (golden test).
- `rac validate rac/` and `rac relationships rac/ --validate` exit codes and
  output are unchanged from before the milestone.

## Risks

- Bundle file-path derivation could collide for two artifacts. Mitigated: derive
  paths from the already-unique source paths and assert uniqueness in the
  renderer.
- `log.md` depends on git; in a non-git checkout it would be empty. Mitigated:
  degrade to a stable placeholder, matching the recency service's no-exception
  contract.
- Scope creep toward a frozen contract or a round-trip importer. Mitigated:
  explicit Non-Goals; the bundle stays a derived, one-way output.

## Assumptions

- `build_corpus_export()` remains the single corpus walk feeding exports; the OKF
  renderer consumes its `CorpusExport`, adding no second classification path.
- The git-recency (ADR-045) and index services remain the source of recency and
  inventory; the OKF generators consume them rather than re-deriving.

## Related Decisions

- adr-048
- adr-007
- adr-016
- adr-045
- adr-014

## Related Requirements

- rac-okf-carrier-profile

## Related Roadmaps

- v0.13.5-self-type-relationships
