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:
The domain model parses, renders, builds, and compares idxs.
Document adapters expose structural sites and free comment occurrences.
YAML configuration independently chooses participation, index notation, and header presentation.
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:
observedinserts at structural depths already represented in the enrolled file;nevervalidates existing addresses without insertion;allcovers 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.
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/headersprojects 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.
5Comments 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.