DESIGN — ID-429 Bundle index: format, axis, and one index per subdirectory
DESIGN — ID-429 Bundle index
Section titled “DESIGN — ID-429 Bundle index”Artefact: {429.1} · Status: design ruled, not implemented · Satisfies: id-429 AC-1 (the design written down before implementation) Author’s stance: the theme machinery is a strip, not a replacement; the axis is the directory, not a taxonomy; and the one change that looks cosmetic (the separator) is the only one with no consumer cost, while the one that looks structural (per-subdir indexes) carries a measured producer defect that must be fixed in the same subtask.
Section numbers are OKF v0.2 throughout (§8 index, §9 log, §12 versioning, §6.1 bundle-absolute links, §3.1 reserved filenames, §11 conformance). The vendored copy in the repo is still v0.1 and numbers these §6/§7/§11/§5.1/§3.1/§9 — id-426 re-vendors.
0. Why this task exists — stated in the only terms that survive a reader’s check
Section titled “0. Why this task exists — stated in the only terms that survive a reader’s check”This is a design decision the owner has taken, not a conformance fix (DR-141
Consequences bullet 6; id-429 status_note). §8 says an index.md MAY appear in any
directory; §11 forbids rejecting a bundle for missing ones. Any justification of this work
by conformance cites a document that says the opposite.
The requirement each surface serves is named in §1. Where I could not name a requirement
and its current source, the verdict is UNDECIDABLE and it is carried verbatim in §7.
1. Requirement-first: what each index surface is for
Section titled “1. Requirement-first: what each index surface is for”| Surface | Requirement it serves | Current source of that requirement |
|---|---|---|
Root index.md | A reader (human or agent) landing on the bundle must learn what groups of knowledge exist before opening anything — §8’s stated purpose, progressive disclosure. Post-id-427 the bundle becomes corpus-complete by construction (DR-141), so the root must not be a flat enumeration: the thing it enumerates is about to become the whole corpus. | OKF §8 (purpose); DR-141 Decision (corpus-completeness makes a flat root index unusable) |
Per-subdirectory index.md | A reader who has navigated into a group must get the group’s own contents, on the axis they just navigated by. Today they get nothing: opening /certifications/ shows a bare file list with no titles and no descriptions. | Owner ruling S545 verbatim: “Index format, design, and including one per-subdir is required”; DR-141 Consequences bullet 6 (the axis mismatch) |
okf_version stamp | A generic consumer must be able to learn which spec revision the bundle targets, from the one place the spec permits frontmatter in an index. | §12 + §8 (“with one exception: a bundle-root index.md MAY carry an okf_version key”) |
Bullet form (* [Title](url) - description) | A generic OKF consumer that was written against the spec’s shown form must parse our bundle without special-casing us. We ship the first generic consumer ourselves (id-439); the second one will not be ours. | §8 shown form, read verbatim from upstream main this session (§2, row 7) |
| ~17 themes | UNDECIDABLE — see §7 Q1. No requirement with a current source could be named. | — |
2. Measured ground (what I executed, against canonical main d1e6e14ad)
Section titled “2. Measured ground (what I executed, against canonical main d1e6e14ad)”Everything below was executed this session unless the row says otherwise. file:line
cites are from the read, not carried.
- One emission site.
write_bundlebuildsthemes = build_index_themes(theme_config, written)and declares exactly one file —bundle_dir / INDEX_FILENAME(bundle_writer.py:1366-1368). No otherindex.mdis ever written. writtenis keyed by the PHYSICAL path.ConceptWriteResult.rel_path = bundle_write_path(draft)(bundle_writer.py:330-331,:351,:369), so the won-bid redirect (case-studies/won-bid/<slug>.md) is already what the index links to. No latent broken-link bug; groupingwrittenby dirname is sound.- The theme axis has no supplier.
theme_configdefaults()at both call sites (bundle_writer.py:1149,producer/flow_def.py:414; pass-through at:555). Repo-wide there is no non-test supplier. The sibling config file its own docstring names as the feeding convention —index-themes.json(bundle_writer.py:993) — does not exist anywhere in the repo: one docstring hit, zero files, not in_RESERVED_BUNDLE_FILENAMES. - The measured defect that per-subdir indexes would trip.
_existing_concept_paths(bundle_writer.py:1114-1120) compares the full bundle-relative path against_RESERVED_BUNDLE_FILENAMES(a set of bare basenames). Socertifications/index.mdis not reserved: it is counted as a previous-run concept, never appears inwritten, and therefore lands inRunSummary.removedon every run, forever — pollutinglog.mdand the human-edit reconcile set. §3.1 is explicit that the reserved filenames hold “at any level of the hierarchy”, so this is a real deviation today, latent only because we emit no nested index. - The TS side already gets §3.1 right.
bundle-graph.ts:417skips by basename (basename === INDEX_NAME || basename === LOG_NAME), so a nested index is already excluded from the concept graph — no change needed there.RESERVED_ROOT_DOCS(:84, README/CONFORMANCE) is deliberately root-only and stays so. - The separator needs no consumer change.
CONCEPT_BULLET_RE(parse-index.ts:27-28) is/^[*-]\s*\[(.+?)\]\(([^)\s]+\.md)\)(?:\s*[-—]\s*(.*))?$/— the class[-—]already accepts both glyphs, and the writer’s own S451 rider docstring says so (bundle_writer.py:25-27: “both-/—are accepted, so a hyphen would ALSO round-trip”). This corrects the dispatch brief:parse-index.tsdoes not have to move in step with the separator. The only artefact that must move is the byte-exact round-trip fixture__tests__/fixtures/okf/bundle-writer-index.md, which is prettier-excluded by design (.prettierignore:65-70, S451 rider; re-affirmed ind1e6e14ad’s message) so the formatter will not silently undo it. - The spec’s shown form, read from upstream
main(WebFetch ofGoogleCloudPlatform/knowledge-catalogokf/SPEC.md, this session):* [Title 1](relative-url-1) - short description of item 1— asterisk marker, ASCII hyphen separator — and, in the same fenced block,* [Subdirectory](subdir/) - short description of the subdirectory. The vendored copy renders these with a-marker (lib/okf/.claude/skills/okf/reference/SPEC.md:280-289); that is the prettier-style drift S546 already found in the vendored file (list-marker normalisation, alongside the reflow and*emphasis*→_emphasis_), not an upstream difference. id-426’s re-vendor must land upstream bytes, or this AC will be checked against a formatted copy and read as already-conformant. - Heading contract.
HEADING_RE(parse-index.ts:26) matches##/###only;IndexTheme.levelis validated∈ {2,3}(bundle_writer.py:394-417); the root H1 is the literal# OKF Concept Bundle(:460); theokf_versionstamp is at:456-459. - Nav paths are matched against graph node ids.
bundle-nav.tsx:157,171doesrow.path === selectedConceptId, androw.pathisstripMdSuffix(link)from the bullet, while node ids are bundle-root-relative-without-extension (bundle-graph.ts:424-427). So the link form in an index is load-bearing for selection, and a leading/(§6.1 house form) would break it today. descriptionis required and non-empty (validator.py:336,check_required_keys:386-404), so every concept bullet always carries one.- Directory layout today (from
ConceptKey.rel_path,sources/l_records.py):topics/,products/,company/,certifications/,case-studies/+case-studies/won-bid/(bundle_writer.py:224-284),references/(web_pass.py:683) — and the config-gated feeder grain already mintsf"{concept_type}/{slug}.md"from a raw, unpluralised type (l_records.py:815). The fixed grains are hand-written plurals. That inconsistency is id-427’s to resolve; §5 states what this design needs from it. git_syncis index-agnostic. Onlylog.mdis special-cased (git_sync.py:685-710, by exact root path); itsINDEX_FILENAMEconstant (:146) is defined and never used. Nested indexes flow through the managed set as ordinary paths, so a human-edited generated index raises the normalHumanEditConflict— the desired behaviour, no change needed.
Carried, not re-measured: the published showcase index being one ## Other bucket over
19 concepts (S546 producer audit §3). The only bundle in this repo is
okf-prototype-bundle/ (7 files, dirs navigation/ + tool/), which is not the
producer’s output.
3. Decisions
Section titled “3. Decisions”D1 — The axis of every index is the directory it sits in
Section titled “D1 — The axis of every index is the directory it sits in”Each index.md enumerates its own directory’s immediate members: the concept files in
it, and its immediate child directories. Nothing else. No taxonomy, no cross-cut, no
config.
Rationale. It is the only axis that is (a) definitionally the same as the thing the
reader just navigated by — which is precisely what DR-141 says the current index is not;
(b) total over an open type vocabulary (id-427/DR-141) with no registry to maintain;
(c) derivable from data the writer already holds (written, §2 row 2), so it has a
supplier by construction — the failure mode that killed the theme axis cannot recur;
(d) invariant under whatever type→directory mapping id-427 chooses, including a
many-to-one one, because the index never reads type.
Rejected. Grouping a directory’s concepts by type within the index: post-id-427 a
directory may hold one type (making the grouping a no-op) or several (making it a second
axis inside the first). Either way it re-introduces a vocabulary read where D1 needs none.
D2 — The root index becomes a directory listing, not a concept listing
Section titled “D2 — The root index becomes a directory listing, not a concept listing”The root index.md emits an entry per immediate child directory, plus a section for
bundle-root concept files if any exist. It stops enumerating every concept.
Rationale. §8’s purpose is to see what is available before opening documents; under
DR-141’s corpus-complete enumeration the concept count becomes the corpus size, and a flat
root listing stops being disclosure and becomes the dump it was meant to replace. §8’s own
example shows a * [Subdirectory](subdir/) - … entry, so this is the shown form, not an
invention.
Consequence, and it is not free. parseBundleNav ignores any bullet whose target is not
.md (§2 row 6), so a root index of directory entries yields themes with zero
concepts — and because the array is non-empty, <BundleNav>’s absent-index fallback does
not fire: the nav rail renders empty headings. This makes id-439 a co-requisite, not
a nicety — see §6. Sequencing is in PLAN.md {429.6}.
Rejected. Keeping a full flat concept list at the root “for the viewer”: it preserves exactly the defect DR-141 names, and it does so by letting a consumer’s current parser dictate the bundle’s shape — the bundle is the client’s asset (DR-016), not our viewer’s backing store.
D3 — The ~17-theme capability is retired, not replaced
Section titled “D3 — The ~17-theme capability is retired, not replaced”Strip build_index_themes, the theme_config parameter at both call sites
(bundle_writer.write_bundle, flow_def run entry), and the unthemed_heading fallback.
Rename IndexTheme → IndexSection and keep it as the renderer’s structural node
(heading + level + entries + children); keep regenerate_indexes’ renderer core.
Rationale. Requirement-first, the theme axis fails at the second half of the test: I can
name its origin (the first client’s own ~17-theme “BID RESPONSE TOPIC INDEX”,
bundle_writer.py:471-486) but not a current source — no supplier, and the sibling
config file its own docstring names does not exist (§2 row 3). What actually ships is a
single ## Other bucket. This is the owner’s standing strip case: machinery with no
supplier, whose one live behaviour is its fallback. DR-130 already rules subject taxonomy
is display metadata and not a driving axis; §3.1 rules the same way for the closest
thing the spec discusses — “OKF does not specify a separate file format for aggregating
documents by tag; a consumer that wants a tag-browsing view can synthesize one at
consumption time by scanning frontmatter.” A cross-cut is a consumption-time synthesis.
The re-entry path, if the requirement is later shown live (§7 Q1): a theme becomes a
concept — a document with links, in its own directory — which post-DR-141’s open
vocabulary needs no machinery at all; or a viewer-side facet over tags. Neither is a
producer index axis. Do not re-add theme_config.
Rejected. Keeping the machinery “in case a client supplies a theme map”: that is the argument that produced a capability with no supplier the first time. DR-139 is directly on point — a production consumer is not a reason to keep something incorrect, and here there is not even a consumer.
D4 — House style: # document title, ## section headings, ### for nesting
Section titled “D4 — House style: # document title, ## section headings, ### for nesting”Each index opens with a single # title, then ## section headings; ### is reserved for
a future nested grouping and is not emitted by this design.
Rationale. The spec states no heading-level constraint (S546 correctly reclassified
this AC from “reconcile with the spec” to a house-style call; §8’s # group headings are
an example). Three reasons pick this one: (i) the spec’s own §9 log.md example uses
exactly this shape — # Directory Update Log title with ## date groups — so the
title-H1/groups-H2 pattern is the specification document’s own house style; (ii) it keeps
one H1 per rendered document, which is what the file render pane and any markdown reader
expect; (iii) it costs zero consumer change (§2 row 8), whereas # group headings would
make parseBundleNav return [] and silently degrade the nav — a real regression bought
for nothing. AC-4 is answered as “reconciled by ruling, not by moving”: we keep our
levels, on stated grounds, because there is nothing to reconcile against.
D5 — Entry links are relative to the index’s own directory
Section titled “D5 — Entry links are relative to the index’s own directory”certifications/index.md links iso-27001.md; case-studies/index.md links
won-bid/; the root index links certifications/. No leading slash anywhere.
Rationale. §8’s shown form is relative-url, and §6.1’s bundle-absolute recommendation
is scoped to concept-to-concept links, where it buys stability under moves. An index is
regenerated in full on every run (D6), so move-stability buys nothing here — the entry is
re-derived, not repaired. Relative links additionally make a subdirectory self-contained: a
directory lifted out of the bundle still has a working index. For the root index,
directory-relative and bundle-root-relative coincide, so today’s emitted form is unchanged
and <BundleNav> selection keeps working (§2 row 9).
Consumer consequence, handed to id-439: for a nested index the parsed
BundleNavConcept.path must be joined against the index’s own directory to remain
comparable to a graph node id. parseBundleNav takes a base-dir argument; the root call
passes '' and is unchanged. See §6.
Rejected. Bundle-absolute (/certifications/iso-27001.md) for uniformity: it breaks
row.path === selectedConceptId at the root today (§2 row 9) for a stability property the
regeneration already provides, and it departs from the shown form the AC pins.
D6 — Bullet form, descriptions, ordering, titles
Section titled “D6 — Bullet form, descriptions, ordering, titles”- Concept entry:
* [<frontmatter title>](<relative path>.md) - <frontmatter description>. Asterisk marker (already ours), ASCII hyphen-minus separator (the drift AC). Description is the concept’s frontmatterdescription, verbatim — §8’s SHOULD, and it is validator-guaranteed present and non-empty (§2 row 10). Defensive: if a description is ever empty, emit the bullet with no trailing separator rather than a dangling-. - Directory entry:
* [<Sentence-cased basename>](<basename>/) - <N> concept(s)[, <M> subdirector(y|ies)]. The count is of immediate members, so it predicts the page the reader is about to open. Where §8 says entries SHOULD carry the linked concept’s frontmatter description, a directory has no frontmatter, so the SHOULD does not reach it; a derived count is honest and needs no supplier. Rejected: client-authored directory descriptions — that istheme_configagain, wearing a different name. - Heading/label text: basename →
-/_to spaces → sentence case (case-studies→ “Case studies”). No lookup table and no title-case stop-word list: the function must be total over directory names id-427 has not minted yet. - Section headings: the literals
## Concepts(emitted first, when the directory holds concept files) then## Directories(when it holds child directories). Structural headings are the honest label once there is no theme axis to name. - Ordering: ASCII-ascending by link target, within each section. Determinism is not cosmetic — the bundle is a client-owned git repo (DR-016) and a non-deterministic index produces a diff on every run.
D7 — Regeneration: same declare_file pass, one index per directory with members
Section titled “D7 — Regeneration: same declare_file pass, one index per directory with members”After the concept loop and before log.md, group written (physical paths, §2 row 2) by
directory; for each directory on the path from the root to every concept, declare
<dir>/index.md. Rules:
- Membership is
written— this run’s validated set — not the on-disk tree. A tree read would include concepts that cocoindex’s reconciliation is about to orphan-delete. - A re-affirmed failed concept (
_reaffirm_failed_concepts) is absent from its index for that run, though its file survives. Stated as a decided consequence: including it would require re-parsing frontmatter off disk to recover title/description, and the index is defined as a projection of what the run validated. It remains reachable via the file tree and the graph, and it is named inlog.md’sfailed. - Intermediate directories are always declared, even when they hold no concepts of
their own (e.g. a
case-studies/that only containswon-bid/), so the root→leaf chain is never broken. - The root index is always declared, even for an empty bundle — it carries the
okf_versionstamp (§12), which must not disappear when the corpus is empty. - Empty/vanished directories need no special case: an index simply is not declared, and
cocoindex’s own orphan-delete reconciliation removes the stale file on the next run
(
bundle_writer.pymodule docstring, EXECUTOR-VERIFY). New directories need no special case either —create_parent_dirs=True. - Unchanged directories cost nothing: identical content re-declared is a fingerprint no-op in the engine, so a directory nobody touched produces no write and no commit.
- Frontmatter: the root index alone opens with
okf_version: "0.2"(post-id-426; §12 + §8’s single exception). Nested indexes carry none — the renderer takes the stamp as a parameter, so “nested index acquires frontmatter” becomes structurally impossible rather than conventionally avoided. (id-429 AC-5.) - Prerequisite in the same subtask:
_existing_concept_pathsmust reserveindex.md/log.mdby basename at any depth (§2 row 4, §3.1). Without it, per-subdir indexes are reportedremovedon every run. This is the one place the feature would otherwise ship a defect.
D8 — log.md stays root-only
Section titled “D8 — log.md stays root-only”§9 permits a log.md at any level; this design emits one, at the root, unchanged.
Rationale. The requirement log.md serves is “what did the producer do this run”, and a
run is bundle-scoped: RunSummary is a bundle-wide diff (bundle_writer.py:528-570), and
<BundleLog> reads the root only (graph/route.ts:37-38). Per-directory logs would need
per-directory run diffs nothing asks for, and would multiply append-only files in a
client-owned repo. The only change this task makes to the log surface is defensive: the
basename reservation in D7 means a client-hand-authored nested log.md (which §9
permits and DR-016 makes plausible) is never miscounted as a concept. It is never
producer-declared, so it is never orphan-deleted.
D9 — Out-of-scope cleanups this design names but does not claim
Section titled “D9 — Out-of-scope cleanups this design names but does not claim”git_sync.INDEX_FILENAME is dead (§2 row 12) — delete it with {429.4} or leave it; either
way it is not a behaviour change. The bundle_writer module docstring’s “~17 client
themes” narrative and its v0.1 §-cites are swept by {429.9} alongside id-426’s
renumbering.
4. The emitted shapes
Section titled “4. The emitted shapes”Root (index.md), post-id-426 stamp:
---okf_version: "0.2"---# OKF Concept Bundle
## Directories
* [Case studies](case-studies/) - 3 concepts, 1 subdirectory* [Certifications](certifications/) - 4 concepts* [Company](company/) - 1 concept* [Products](products/) - 3 concepts* [References](references/) - 2 concepts* [Topics](topics/) - 12 conceptsA subdirectory with both members (case-studies/index.md), no frontmatter:
# Case studies
## Concepts
* [Acme Council rollout](acme-council-rollout.md) - How the 2025 rollout was delivered.
## Directories
* [Won bid](won-bid/) - 3 conceptsA leaf (certifications/index.md):
# Certifications
## Concepts
* [ISO 27001](iso-27001.md) - Information security management certification.5. Interface assumptions on id-427’s directory scheme (the Coordinator reconciles)
Section titled “5. Interface assumptions on id-427’s directory scheme (the Coordinator reconciles)”D1 deliberately reads no type, so most of id-427’s freedom is unconstrained. What this design does require of id-427’s scheme, stated so it can be satisfied or refused:
- IA-1 — Every concept has a directory. Each concept’s physical bundle path is
<dir>/<slug>.mdwith at least one directory component, decided at draft time and stable across runs for an unchanged concept. Why: a concept at the bundle root lands in the root index’s## Conceptssection, and if the residual grain routes there, D2’s root listing degrades back into the flat dump it exists to prevent. - IA-2 — The residual grain gets a named directory of its own. Corollary of IA-1, and the one most likely to be missed: the residual grain is where an unrouted record lands, so it is the grain most likely to be given no home.
- IA-3 —
indexandlogare refused as concept slugs. §3.1 makesindex.md/log.mdreserved at any level and MUST NOT be used for concept documents. Under a closed vocabulary this was unreachable; opening the vocabulary makes it reachable — a concept whose title slugifies toindexin any directory would silently overwrite that directory’s index and then be deleted by the next run’s reconciliation. The slug function must refuse or suffix both names. This is a net-new requirement created by id-427, not by id-429. - IA-4 — Directory names are filesystem-safe slugs, and many-to-one is fine. Two types
may share a directory; the index never reads
type. What must not happen is a directory name that varies run-to-run for the same type (the count and ordering would churn the client’s git history). - IA-5 — Nesting is arbitrary but finite, and every intermediate directory is a real directory (D7 declares an index at each level).
Not required by this design, and explicitly left to id-427: pluralisation
(certifications/ vs certification/) and whether the existing hand-written plurals are
regularised against the feeder’s raw-type form (§2 row 11). D6’s sentence-casing works on
either.
6. Consumer coupling — the id-439 hand-off
Section titled “6. Consumer coupling — the id-439 hand-off”id-439 owns the parser surfaces; this design specifies what it must accept, not how.
- Directory entries (blocking, D2).
parseBundleNavcurrently drops any bullet whose target is not.md, and a root index of directory entries therefore renders an empty nav rather than triggering the absent-index fallback. The nav model needs a directory entry kind (target ending/, no concept id). {429.6} must not merge before this. - Base-dir resolution (D5). For a nested index,
BundleNavConcept.pathmust be joined against the index’s directory to stay comparable to a graph node id (bundle-nav.tsx:157). Root behaviour is unchanged (''base). - Separator: no change required.
[-—]already accepts both (§2 row 6). This corrects the dispatch brief’s premise; the round-trip fixture is the only artefact that moves. okf_version: "0.2"acceptance is already id-439’s AC-1.
Nothing else on the consumer side changes: bundle-graph.ts already skips nested indexes
by basename (§2 row 5), walk-bundle-tree.ts lists them as ordinary renderable files, and
file-explorer.tsx:55-58 deliberately looks for the root index.md only as the default
selection — still correct.
7. UNDECIDABLE (carried verbatim)
Section titled “7. UNDECIDABLE (carried verbatim)”Q1. “What requirement does the ~17-theme axis serve, and is that requirement still
live?” — Origin is nameable: the first client’s own ~17-theme “BID RESPONSE TOPIC INDEX”,
recorded as PRODUCT BI-5’s owner’s-call in bundle_writer.py:471-486. Its current source
is not. No file in the repo supplies a theme map; index-themes.json, the sibling-file
convention the code’s own docstring names as the feed, does not exist (§2 row 3). Whether
that client still navigates their bid content by that index is an owner/client fact not
decidable from the codebase, and it was not asked this session. D3 retires the machinery
either way — a live client artefact would still not be a directory’s own axis — and names
the re-entry path that needs no machinery.
Q2. “For a directory whose name is an opaque slug minted by id-427’s residual grain, is a sentence-cased basename an adequate heading, or does the reader need a human label the producer does not currently hold?” — Not decidable until id-427 names the residual directory (IA-2). D6 ships sentence-casing; if the answer is “needs a label”, the label belongs to id-427’s grain definition, not to a config file here.
Q3. “Does the client’s own editing workflow want a per-directory log.md?” — §9
permits it; nothing in the platform requires it; the bundle is a client-owned git repo
(DR-016), so the people who would read a per-directory history are outside this codebase.
D8 rules root-only and makes the defensive reservation that keeps a hand-authored nested
log safe.
8. What this design did not cover
Section titled “8. What this design did not cover”- No producer run, no bundle regenerated. Every shape in §4 is specified, not observed.
The published showcase bundle lives in an external client repo (
OKF_BUNDLE_ROOT, DR-016) and was not read; the “19 concepts in one## Otherbucket” fact is carried from the S546 audit, not re-measured. The only in-repo bundle isokf-prototype-bundle/, which is not the producer’s output. - No test bodies read.
scripts/tests/test_producer_bundle_writer.pywas located by name and line (:297-393, five index tests) but its assertions were not read; PLAN.md’s per-subtask test strategy is therefore written as what must be proven, not as a diff against what is currently asserted. - Formatter risk in the client repo is unmeasured. Our fixture is prettier-excluded
(§2 row 6), but if the client’s bundle repo runs a markdown formatter on commit, a
*list marker will be normalised to-there and the AC will read as violated in the artefact a reader actually opens. Not checkable from this repo. parse-log.ts,<BundleLog>,file-render-pane.tsxwere greppd, not read..claude/worktrees/copies were excluded from every sweep.- No database queried; no repo file edited.
- id-427’s directory scheme is not settled here — §5 states assumptions; it does not pre-empt them.
CONFORMANCE.md/ontology.jsoninteractions (id-430, id-431) are untouched: this design adds no superset and removes none.
S546 owner rulings, post-authoring
Section titled “S546 owner rulings, post-authoring”- §7’s theme-axis UNDECIDABLE is RULED (owner, S546): the requirement is not live. D3’s retirement is fully ratified; supplier task id-323 closed with the supersession note (its 2026-07-15/16 config-home/filename/type-grouped-default ratifications answered the pre-DR-141 question).