ADR-0035 — walkable architecture nav-derive (graph から index/cluster-nav を生成、 golden 型 commit-in-place、 generated-view を interpretive-gap で授権)

Status: accepted · Date: 2026-06-01 · folio v0.5.0-draft · architecture/ を「歩ける website」に: top-level index + cluster 横断 nav を folio build が graph (head metadata + @id path-prefix + objectGraph の JOIN) から生成し commit、 marker + regen-drift gate で hand-authored と区別、 P-7/P-13 の空間排除は HOW+verification を名指すゆえ派生 view は憲法改訂なしに ADR で授権。 companion = ADR-0036 (glossary)。 ADR-0024 init + ADR-0025 materialize + ADR-0020 validate を拡張、 ADR-0023 の gitignore-projection を新 artifact class に限り反転

§1. Context

folio が consumer に約束する architecture/ design-intent 空間は 「歩けない」。 検証済の現状 (grep 2026-06-01):

正確に言えば欠陥は「cluster が孤立している」ことではない (decisions/spec は body prose に rich xref を持つ — これは ADR-0034 の成果で、 nav が置換すべきものではない)。 narrower な実体は (1) 鮮度ある top-level 集約 index の不在 (folio 自身は pin が古化、 生成物は皆無)、 (2) research/README の dead-end、 (3) 生成物の cluster 横断 nav 欠如である。 手で index を維持してきた事実 (folio 自身) が、 「歩ける website を手で維持すると必ず drift する」ことの証拠になっている。

user grill (2026-06-01) で 6 つの根の決定が確定した: (1) 歩ける website を normative 化 (folio 自身も init 生成物も同一規約・機械検証)、 (2) nav は graph から derive する派生 view (drift-proof)、 (3) folio-用語 glossary を folio が上流で author→ship・consumer は derive (companion ADR-0036)、 (4) これは pre-1.0.0 の主作業、 (5) golden 型 commit-in-place (build が生成物を architecture/ に in-place 再生成し commit、 marker + regen-drift gate で hand-authored と区別)、 (6) 置き場所 = architecture/ 内 + ADR のみ (憲法改訂なし、 interpretive-gap 論拠、 §2.6)。 貫く 3 層原則: 人間 = 意味を author / 機械 = 純構造を derive (nav・index・xref 配線) / 意味の人間向けレンダリングだけ co-author+enforce (prose essence、 ADR-0033)

本 feature は ADR-0030/ADR-0032 の criterion(c)「実用に耐える」判断への INPUT である (user が歩行性を実用性の要件と判断 = criterion(c) を行使している)。 criterion(c) は ADR-0032 §3 で 明示的に user の主観判断と定義されており機械 gate ではない — 本 ADR は (c) を「検査可能 gate に変える」ものではなく、 user の (c) 判断に資する証拠を作る。 criteria A〜G + criterion H (ADR-0031 実装 = task #84 完了 + greenfield walk PASS) は既に充足済。 status = accepted (S5 統合検証 PASS 後 user 承認)。 設計は grill 6 問 + 4軸 design workflow + 敵対的 critique (blocker 3 解消) で確定。

§2. Decision

§2.1 walkable architecture を normative 化 (範囲 = architecture/ 内に限定)

top-level architecture/index.html + 全 cluster 横断 nav を folio 自身・folio init 生成物・consumer 生成物すべてで必須とし機械検証する。 mandate 範囲は architecture/ 配下 = folio が P-7 で既に govern する design-intent 空間に限定し、 consumer の test 配置・実装 dir・自由 documentation (docs/steering) には一切及ばない (P-13(b) 不変、 test dir は引続き scaffold しない)。 nav は consumer に新 dir を強いず既存 architecture/ 内で完結するため、 P-13(a) spec 適合性 (framework 提供・普遍・dir 非 mandate と同型) の新 gate として位置づける。

§2.2 nav の SoT = graph の JOIN (「graph 1 つ」ではない)

nav の SoT は新 data 源を作らず既存 graph から導く。 ただし正確には単一 edge 集合ではなく JOIN である:

すなわち実 SoT = {head metadata + @id path-prefix 規約 + objectGraph (+ 将来 curation field)} であり、 nav はこの JOIN の派生 view で SSoT を持たない。

§2.3 生成器 = folio build (新 subcommand)、 fix と責務分離

新 subcommand folio build を新設し、 §2.2 の JOIN から architecture/index.html (+ companion ADR-0036glossary.html) を生成する。 cluster README の cross-cluster nav は build の生成対象外とし、 init scaffold が静的に materialize する (責務帰属は §2.7 が確定)。 README nav region の build-derive 化 (index.html と同型の drift-proof 派生) は post-1.0.0 の follow-up とし、 それまでの static nav の href link-rot は cluster-reachability gate の link-rot 検査 (#128 で追加、 README body 相対 href を realpath 正規化 + [[ -e ]] 実在検査) が interim に受け持つ (link-integrity は JSON-LD relation のみ・nav-dead-link は生成 index のみで README body href を未被覆ゆえ本 gate が担う)。 deterministic・idempotent・timestamp 非含有・LC_ALL=C sort で golden 安定を保つ。 入力は inventory.json (無ければ内部で folio inventory を呼ぶ、 prime と同じ auto-regen) + 各 file の <head> JSON-LD。 既存 helper (folio_build_relations / folio_resolve_relpath / folio_reverse_relid / folio_extract_head_jsonld) を再利用する。 build ロジックは .claude-plugin/bin/folio に隔離維持し、 生成 HTML には platform 固有値 (絶対 path / env var) を埋め込まず相対リンクのみとする (P-11)。

責務分離: folio fix = in-band relation/xref/glossary-tooltip を spec 自身に materialize する「graph を整える」器folio build = 整った graph から index/nav という「派生 view を出す」器。 別 subcommand とし CI/golden を独立させる (build-drift.yaml と fix-bidirectional.yaml が別 scenario)。 SoT が空 (relation 無し) なら nav も空で clean (additive/keystone、 既存 validate-clean を壊さない)。

§2.4 golden 型 commit-in-place = 三重 marker + curated region 隔離

生成物は architecture/ に in-place commit するが、 hand-authored と機械可読・人間可読の両面で区別する:

§2.5 enforcement = folio validate に 3 gate 追加 (ADR-0020 scope 拡張) + drift モデル

ADR-0020 の validate scope を拡張し deterministic floor として追加する:

drift モデル (正確化): inventory.json / prime digest は各 file の <head> JSON-LD + objectGraph から derive され、 architecture/index.html は inventory に走査されない。 ゆえに nav-body の編集は inventory/prime golden を汚さない。 新たな drift 面は nav-body ↔ graph であり、 これを regen-drift gate が所有する。 inventory/prime golden の再生成義務は <head> の relation/status を変える slice のみに適用する (例: §2.7 の reverse-materialize、 status flip — ADR-0025 broken-reverse の系譜)。

§2.6 generated-view の architecture/ 同居を ADR で授権 (interpretive-gap、 constitution 不変)

決定 5/6 の commit-in-place は hand-authored design-intent 空間に機械生成物を同居させる。 これと Always-tier 原則の関係を以下に確定する:

ADR-0023 の明示的反転: ADR-0023 §alternatives は「inventoryarchitecture/ に配置」を却下し走査 base と出力先を decouple した。 本 ADR の決定は、 committed generated-view という新 artifact class に限り、 その却下方向を反転する。 これは frictionless extension ではなく意図的な reversal である。 reconcile: AI 向け projection (inventory.json/prime) は disposable・gitignore・repo-root のまま (ADR-0023 保存)、 human 向け view (index.html/glossary.html) は committed・architecture/ 内 (本 ADR)。 これは「2 種の派生物に 2 policy」という意図的な split であり、 根拠は用途の差 (AI は build して捨てる / human は github.com 素閲覧・Pages で build なしに歩く)。

§2.7 ADR-0024 init 拡張 + folio-self dogfood + self-spec layout 追記

ADR-0024 init 出力に cluster README への cross-cluster nav region (静的 heredoc) を加え、 init pipeline 末尾で folio build を 1 回走らせ top-level index.html を生成し即 folio validate clean (regen-drift 含む) を満たす (lazy materialize 維持 = 実在 cluster README のみ列挙、 空 placeholder を作らない、 0-part でも valid な index)。 folio 自身の index.html は build 出力へ移行し手動 pin drift を恒久解消する (dogfood)。

Slice 2 feasibility 注記: 現 architecture/index.html<head> JSON-LD を持たず architecture/ 直下 (3 scan dir の外) にある。 folio fix の index↔cluster reverse-materialize は、 先に index に JSON-LD head を与え scan-target に含めるのが前提となる (Slice 1)。 frozen ADR <head> への dc:isReferencedBy reverse-link materialize は既存 broken-reverse gate で既に corpus clean な established practice (metadata であり prose 本文に触れない、 CLAUDE.md §2 の link-integrity 維持に該当)。

folio-self-spec.html §2 / rules.html §2 の layout 記述に generated-view category (index.html) を追記する (assets/ と同じ「非 domain support」の拡張として明記)。 この spec 編集は caller-marker hook で gate され、 index.html の commit と同 slice で sequence し live layout と spec layout が乖離しないようにする。 実装上の責務帰属 (§2.3 と整合): folio buildindex.html のみ derive し cluster README には触れない / cross-cluster nav は init scaffold が静的 heredoc で materialize / check-readme-index.sh の §2 inventory-table 鮮度は従来どおり hook が担う (build と別概念)。 README nav の build-derive 化は §2.3 のとおり post-1.0.0 follow-up とする (ADR-0003 の hook+skill mutate 構想との関係は reverse-link + prose で trace = mechanism 置換であり単なる narrowing ではない)。

§3. Consequences

Positive

Negative

Neutral / TODO

§4. Alternatives Considered

採否
architecture/ 内 commit-in-place + ADR 授権 (interpretive-gap、 採用)採用 — user 決定 6。 P-7/P-13 の空間排除は HOW+verification を名指し派生 view を名指さないゆえ憲法改訂不要。 marker + regen-drift gate で hand-authored と区別。 github.com 素閲覧でも Pages でも build 不要で歩ける core 目的を満たす
architecture/ の外に置く (repo-root / Pages source、 ADR-0023 原則を守る)却下 — build 不要で歩ける website には index/nav が architecture/ 内に commit される必要 (外置き + gitignore では素閲覧で nav が存在しない)。 また cluster README 内の横断 nav が成立せず in-cluster nav が手書き drift か top-level index 経由のみに弱まる。 user が in-place を確定済
architecture/ 内 commit + P-10 憲法改訂却下 (fallback として保持) — P-7/P-13 に generated-view category を user 承認で明文追加すれば曖昧さゼロだが、 不変資産の constitution を触る重い操作。 §2.6 の interpretive-gap で十分と判断。 解釈が challenge された場合の fallback に retain
nav を check-only に留める (生成せず staleness を notify、 現 check-readme-index.sh の延長)不採用 — 現 index の pin drift と research/README dead-end が示す通り check-only は drift を検出しても直さない。 決定 2「nav は派生 view・drift-proof」は SoT から再生成する mutate を要求 (ADR-0003 完成形目標も README index 自動更新)
SoT を「graph 1 つ (hasPart edge のみ)」とする不採用 — individual ADR/spec は hasPart edge を持たず title も objectGraph に無い。 cluster 分類は @id path-prefix、 title/doc-type は specs[] head から JOIN する必要 (§2.2)。 「graph 1 つ」は不正確と確定
nav+glossary を 1 ADR に束ねる (split しない)不採用 — supersede risk が glossary 側のみ集中・依存 cluster が別・hard-to-reverse 軸が別 (ADR-0031 §10.3「1 決定 = 1 ADR」)。 ADR-0033ADR-0034 の split 先例に整合。 本 ADR (nav) + ADR-0036 (glossary、 本 ADR に depends) に分離

§5. Trace