--- numbering: title: true --- # Idxs as Mappings, Not Decoration An idx looks like text: `1.2`, `a.i.`, `+`, or `` `1.a.` ``. Its useful identity is not that text, however. It is a mapping between a visible document site and a place in a hierarchy. Rendering is only one representation of that relation. This is why `arch.idx` stores zero-based ordinals separately from style. The first child is place zero whether it renders as `1`, `a`, `i`, or `.`. A style can change without changing what the idx addresses, and `matches()` therefore compares places while `render()` owns notation. ## `1` Policy is not mechanism Four layers have separate responsibilities: 1. The domain model parses, renders, builds, and compares idxs. 2. Document adapters expose structural sites and free comment occurrences. 3. YAML configuration independently chooses participation, index notation, and header presentation. 4. The engine derives diagnostics and edits, then applies a content-hash-guarded plan. The CLI and TUI are projections of layer four. Neither is allowed to invent its own mutation semantics. This makes JSON, a unified diff, and a highlighted terminal pane mutually checkable views of one object. ## `2` Two idx domains, one clear boundary `arch.Quad` is the preferred name for the original architectonic address. `arch.Idx` remains its compatibility name. A Quad has at most four concrete places, may be the empty root, and can name an abstract `a` or `b` half between its concrete branches. It is also a persisted SQL model value. `arch.idx.Idx` is instead a non-empty, arbitrary-depth sequence of zero-based document ordinals whose numeral styles, separators, markers, and wrappers are presentation policy. They therefore must not be joined by a subtype relationship. Subtyping would promise shared construction, ancestry, emptiness, and persistence invariants that neither model actually has. An explicit adapter can be introduced later for a concrete use case. Today, imports name the domain directly, which is the safer and more legible boundary. ## `3` Positive enrollment precedes observation Indexing a document is an authorship decision: it changes the document's conceptual model, often on every heading. A numeral already present in a file is not evidence of consent. It may be prose, a fixture, foreign numbering, or residue from an earlier tool run. Repository discovery therefore requires a positive `indexing.paths` rule before it creates a plan. An explicit `--spec` override or direct Python planner call is also an explicit selection. Diagnostic callers can pass `enrolled=False`. Observation only narrows an authorized operation: - `observed` inserts at structural depths already represented in the enrolled file; - `never` validates existing addresses without insertion; - `all` covers the entire intended hierarchy, but is legal only on an explicit path rule or command override. This is deliberately stricter than "the tool can infer a tree." Capability does not constitute permission, and an incompatible numeric-looking token is reported without being rewritten. ## `4` Selection authorities stay independent Participation, address notation, and visible header formatting answer different questions. The configuration assigns each authority separately: - `indexing.paths` selects a named `IdxSpec`. - `header_paths` selects a named `HeaderProfile`. - Document-family defaults choose safe presentation without enrolling indexing. The internal configuration model exposes both resolutions separately, and `arch config show --path FILE` reports each authority and its source. A shared name cannot accidentally couple the decisions. Markdown and source are also separate structural families. The Markdown default is non-case-changing, leaves H1 unindexed, and displays H2+ addresses as dotted backtick tags. Source retains its established code-header dialect. Typst, reStructuredText, and unknown suffixes fail closed until they have dedicated adapters. ## `5` Comments are real document surfaces Source comments carry headings, doctrine, runbooks, and local tables of contents. Ignoring them would make an idx linter language-biased. Treating every comment as a heading would be worse: ordinary prose would become hierarchy. The adapters therefore separate *structural sites* from *free occurrences*. A decorated comment heading can generate an expected hierarchical address. A plain comment idx is still parsed, validated, canonicalized, and removable, but it does not acquire children or reorder its neighbors. ## `6` Plans make change legible A mutation is represented by: - the original content digest; - decoded text facts such as BOM and newline style; - occurrences and structured diagnostics; - non-overlapping source spans and replacements. Application is intentionally boring. It rechecks the digest, applies spans in reverse order, encodes with the original UTF-8 mode, flushes a same-directory temporary file, preserves permissions, and atomically replaces the target. Once replacement succeeds, an unavailable parent directory sync cannot turn that completed write into a reported failure. Refusal is a first-class outcome, not a recovery path hidden behind retries. Configured depth is also a semantic boundary, not a formatting hint. A structural site beyond `max_depth` receives an explicit diagnostic and no proposed address. Truncating it would silently map two different sites onto the same visible place. ## `7` Frontier - **Keystone: semantic adapters beyond line syntax** - Tree-sitter-backed comment recognition could distinguish comments from string literals. - Language-specific heading conventions could be configured without weakening generic safety. - A measured corpus should establish whether those gains justify the dependency and complexity. - Alternative plans - The TUI could offer per-occurrence alternatives rather than only per-file systematic modes. - Saved plan manifests could support reviewed, later application across agent handoffs. - Wider notation - Tagged and bespoke wrappers from historical `subl/headers` projects can be added as explicit specs if real files demonstrate demand. - Unicode symbol alphabets need width and normalization tests before adoption. - Terminus - No daemon, language server, or automatic whole-repository rewrite is implied. - The current terminus is a local, inspectable, run-to-completion linter with an optional terminal skin.