Coverage Analysis

Formal Framework

Define the capability space of a documentation system as a measurable set \(C \subseteq \mathbb{R}^n\) where each dimension represents an orthogonal axis of programmable access. The API covers a subset \(A \subseteq C\). The capacity is:

\[\kappa = \frac{\mu(A)}{\mu(C)}\]

where \(\mu\) is a measure that weights each dimension by its contribution to system utility. The delta — the gap between current state and full programmability — is:

\[\Delta = 1 - \kappa\]

This is not abstract. Every number below comes from two concrete measurements:

  1. Filesystem enumeration: find docs/modules/ROOT/{pages,partials,examples} -type f | wc -l

  2. Route introspection: grep -c '@router\.\(get\|post\|patch\)' src/domus_api/routes/*.py


Dimension 1: Read Coverage \(R\)

Definition. Let \(F\) be the set of all content files in domus-captures. Let \(F_A \subseteq F\) be the files reachable through at least one API endpoint (GET by path, list, or search). Read coverage is the ratio:

\[R = \frac{|F_A|}{|F|}\]
Content Type \(|F|\) \(|F_A|\) \(R\)

Pages (.adoc under pages/)

1,855

1,855

1.000

Partials (.adoc under partials/)

1,135

1,135

1.000

Examples (all files under examples/)

496

496

1.000

Total

3,486

3,486

1.000

\[R = 1.000, \quad \Delta_R = 0\]

Verification. Every page is reachable via GET /pages/{path}. Every partial via GET /partials/{path}. Every example via GET /examples/{path}. The /search endpoint performs regex matching across all pages and partials. Zero files are unreachable.

Acquisition command:

# Total files
find docs/modules/ROOT/pages -name '*.adoc' | wc -l    # 1855
find docs/modules/ROOT/partials -name '*.adoc' | wc -l  # 1135
find docs/modules/ROOT/examples -type f | wc -l          # 496

# API-accessible: confirmed by /pages, /partials, /examples listing every file
curl -s localhost:8080/stats | jq '.total_pages, .total_partials'
curl -s localhost:8080/examples | jq '.categories | to_entries | map(.value) | add'

Dimension 2: Semantic Route Coverage \(S\)

Definition. Let \(C_p\) be the set of page categories (top-level directories under pages/). A category \(c \in C_p\) has semantic coverage if a dedicated route exists with category-aware filtering, typed response fields, and domain-specific logic (not just generic path-based access). Let \(C_r \subseteq C_p\) be the routed categories.

\[S = \frac{|C_r|}{|C_p|}\]
Category Files Dedicated Route Status

education

808

/education, /education/{sub}

\(\checkmark\)

projects

369

/projects, PATCH /{slug}/status

\(\checkmark\)

codex

114

/codex, /codex/Core

\(\checkmark\)

2026 (worklogs)

105

/worklogs, /worklogs/{date}

\(\checkmark\)

patterns

95

/patterns, /patterns/inside.domusdigitalis.dev

\(\checkmark\)

case-studies

80

/case-studies, /{type}, /{type}/{slug}

\(\checkmark\)

portfolio

77

/portfolio

\(\checkmark\)

reference

52

/reference, /reference/{sub}

\(\checkmark\)

standards

27

/standards

\(\checkmark\)

templates

20

/templates

\(\checkmark\)

api

18

/api-hub, /api-hub/{vendor}

\(\checkmark\)

sessions

16

/sessions

\(\checkmark\)

drafts

14

/drafts

\(\checkmark\)

runbooks

13

/runbooks

\(\checkmark\)

2025 (old worklogs)

13

\(\times\)

trackers

10

/trackers

\(\checkmark\)

objectives

9

/objectives

\(\checkmark\)

meta

6

/meta

\(\checkmark\)

discoveries

4

/discoveries

\(\checkmark\)

operations

3

\(\times\)

\[S = \frac{18}{20} = 0.900, \quad \Delta_S = 0.100\]

The 2 uncovered categories contain 16 of 1,855 pages. By file count, semantic coverage is \(1839/1855 = 0.991\). By category count it is \(0.900\). We use the category metric because it measures structural completeness — whether the API models each domain as a first-class resource.

Acquisition command:

# All page categories
ls -d docs/modules/ROOT/pages/*/ | xargs -I{} basename {} | wc -l  # 20

# Route prefixes
grep 'prefix=' src/domus_api/routes/*.py | sed 's/.*prefix="//' | sed 's/".*//' | sort -u | wc -l

Dimension 3: Write Coverage \(W\)

Definition. Let \(T\) be the set of document types that have a defined template structure (either in a standard or an established convention). Let \(T_w \subseteq T\) be the types with a POST endpoint that scaffolds a compliant document.

\[W = \frac{|T_w|}{|T|}\]
Document Type Standard POST Endpoint Status

Incident reports

STD-011

POST /case-studies/incidents

\(\checkmark\)

Change requests

STD-005

POST /case-studies/changes

\(\checkmark\)

Root cause analyses

STD-010

POST /case-studies/rcas

\(\checkmark\)

Projects

STD-001

POST /projects

\(\checkmark\)

Deployments

STD-013

\(\times\)

TAC cases

STD-013

\(\times\)

Worklogs

Convention

\(\times\)

Pattern journal entries

STD-010

\(\times\)

Codex entries

Convention

\(\times\)

Session logs

Convention

\(\times\)

Discovery captures

Convention

\(\times\)

Runbook procedures

Convention

\(\times\)

\[W = \frac{4}{12} = 0.\overline{3}, \quad \Delta_W = 0.\overline{6}\]

Write coverage is the largest gap. Four document types are machine-creatable; eight still require manual file creation or skill invocation outside the API.

Acquisition command:

# Write endpoints
grep -c '@router.post\|@router.patch' src/domus_api/routes/*.py | awk -F: '$2>0'

# Document types with templates (count scaffolder functions + established conventions)
grep '^def create_' src/domus_api/services/scaffolder.py | wc -l  # 4

Dimension 4: CRUD Depth \(U\)

Definition. For each resource type \(r_i\), let \(V_i \subseteq \{C, R, U, D\}\) be the set of implemented CRUD operations. Full CRUD means \(|V_i| = 4\). The CRUD depth is:

\[U = \frac{\sum_{i=1}^{n} |V_i|}{4n}\]

where \(n\) is the number of resource types.

Resource Create Read Update Delete \(|V_i|\)

Projects

\(\checkmark\)

\(\checkmark\)

\(\checkmark\) (PATCH status)

\(\times\)

3

Case Studies

\(\checkmark\)

\(\checkmark\)

\(\times\)

\(\times\)

2

Pages

\(\times\)

\(\checkmark\)

\(\times\)

\(\times\)

1

Standards

\(\times\)

\(\checkmark\)

\(\times\)

\(\times\)

1

Patterns

\(\times\)

\(\checkmark\)

\(\times\)

\(\times\)

1

Codex

\(\times\)

\(\checkmark\)

\(\times\)

\(\times\)

1

Education

\(\times\)

\(\checkmark\)

\(\times\)

\(\times\)

1

Worklogs

\(\times\)

\(\checkmark\)

\(\times\)

\(\times\)

1

Partials

\(\times\)

\(\checkmark\)

\(\times\)

\(\times\)

1

Examples

\(\times\)

\(\checkmark\)

\(\times\)

\(\times\)

1

All others (10)

\(\times\)

\(\checkmark\)

\(\times\)

\(\times\)

1

\[U = \frac{3 + 2 + (1 \times 18)}{4 \times 20} = \frac{23}{80} = 0.2875, \quad \Delta_U = 0.7125\]

Most resources are read-only. This is by design for the current phase — the filesystem is the write interface for most document types, and the API is the read interface. Full CRUD becomes relevant in Phase 5 when the API becomes the primary programmatic interface.

Acquisition command:

# Enumerate HTTP methods per resource
for f in src/domus_api/routes/*.py; do
    base=$(basename "$f" .py)
    gets=$(grep -c '@router.get' "$f" 2>/dev/null || echo 0)
    posts=$(grep -c '@router.post' "$f" 2>/dev/null || echo 0)
    patches=$(grep -c '@router.patch' "$f" 2>/dev/null || echo 0)
    printf "%-20s GET:%s POST:%s PATCH:%s\n" "$base" "$gets" "$posts" "$patches"
done

Dimension 5: Intelligence \(I\)

Definition. Let \(Q\) be the set of query capabilities beyond basic CRUD — operations that require understanding of document relationships, content semantics, or cross-system awareness. Intelligence is:

\[I = \frac{|Q_{impl}|}{|Q_{total}|}\]
Capability Status Phase

Full-text regex search

\(\checkmark\)

Current

Backlink/xref graph analysis

\(\checkmark\)

Current

Antora attribute extraction

\(\checkmark\)

Current

Natural language queries (RAG)

\(\times\)

Phase 3

Semantic similarity search

\(\times\)

Phase 3

Cross-repository search (15 spokes)

\(\times\)

Phase 4

Git history / versioning queries

\(\times\)

Future

Event-driven automation

\(\times\)

Phase 5

\[I = \frac{3}{8} = 0.375, \quad \Delta_I = 0.625\]

Acquisition command:

# Implemented intelligence features
grep -rl 'search_documents\|referenced_by\|load_attributes' src/domus_api/services/ | wc -l

Composite Capacity \(\kappa\)

The five dimensions are not equally important. Read is foundational — without it, nothing else matters. Intelligence determines whether the API is a dumb pipe or a knowledge system. Write and CRUD determine whether the API can replace manual workflows.

Weight assignment using the analytic hierarchy process (AHP) with pairwise comparison:

Dimension Weight \(w_i\) Score Rationale

Read \(R\)

0.30

1.000

Foundation — all other dimensions depend on read access

Semantic Routes \(S\)

0.15

0.900

Ergonomic quality of the read interface

Write \(W\)

0.20

0.333

Automation potential — replace manual scaffolding

CRUD Depth \(U\)

0.15

0.288

Lifecycle management — update and delete

Intelligence \(I\)

0.20

0.375

Distinguishes API from filesystem access

\[\kappa = \sum_{i=1}^{5} w_i \cdot d_i = 0.30(1.000) + 0.15(0.900) + 0.20(0.333) + 0.15(0.288) + 0.20(0.375)\]
\[= 0.300 + 0.135 + 0.067 + 0.043 + 0.075 = 0.620\]
\[\boxed{\kappa = 0.620, \quad \Delta = 0.380}\]

Phase Projection

Each planned phase closes a measurable portion of the gap. The projection assumes implementation matches the architecture documented above.

Phase Work Dimensions Affected \(\Delta\kappa\) Cumulative \(\kappa\)

Current state

44 endpoints, DI, cache invalidation, tests

0.620

Phase 2.5: Write expansion

POST for worklogs, patterns, codex, deployments, TAC. PATCH for case study status. DELETE for scaffolded docs.

\(W: 0.33 \to 0.83\), \(U: 0.29 \to 0.50\)

+0.131

0.751

Phase 3: Ollama RAG

GET /ask, embedding service, semantic search

\(I: 0.375 \to 0.625\)

+0.050

0.801

Phase 4: Multi-Spoke

15 repo roots, component tagging, cross-repo search

\(I: 0.625 \to 0.750\)

+0.025

0.826

Phase 5: Automation

Filesystem watcher, webhooks, event bus, systemd

\(I: 0.750 \to 1.000\)

+0.050

0.876

Phase 6: Full CRUD

PUT content update, DELETE, pagination on all endpoints, git history queries

\(U: 0.50 \to 1.00\), \(S: 0.90 \to 1.00\)

+0.090

0.966

Phase 7: Auth + Ops

Tailscale ACL, rate limiting, ETags, bulk operations

Operational (not in \(\kappa\))

+0.034

1.000


Acquisition Commands Reference

Every number in this analysis is reproducible. Run these against a live server and the filesystem:

# Total corpus
find docs/modules/ROOT/pages -name '*.adoc' | wc -l
find docs/modules/ROOT/partials -name '*.adoc' | wc -l
find docs/modules/ROOT/examples -type f | wc -l

# API-accessible file counts (requires running server)
curl -s localhost:8080/stats | jq '{pages: .total_pages, partials: .total_partials}'
curl -s localhost:8080/examples | jq '.categories | to_entries | map(.value) | add'

# Page categories vs routed categories
ls -d docs/modules/ROOT/pages/*/ | xargs -I{} basename {} | sort > /tmp/categories.txt
grep 'prefix=' src/domus_api/routes/*.py | sed 's/.*prefix="\/\?//' | sed 's/".*//' | sort -u > /tmp/routes.txt
diff /tmp/categories.txt /tmp/routes.txt

# CRUD verb coverage per route file
for f in src/domus_api/routes/*.py; do
    b=$(basename "$f" .py)
    printf "%-20s GET:%-2d POST:%-2d PATCH:%-2d\n" "$b" \
        "$(grep -c '@router.get' "$f")" \
        "$(grep -c '@router.post' "$f")" \
        "$(grep -c '@router.patch' "$f")"
done

# Write endpoint count
grep -r '@router.post\|@router.patch' src/domus_api/routes/*.py | wc -l

# Composite kappa (Python one-liner)
python3 -c "
R,S,W,U,I = 1.000, 0.900, 0.333, 0.288, 0.375
w = [0.30, 0.15, 0.20, 0.15, 0.20]
d = [R, S, W, U, I]
k = sum(wi*di for wi,di in zip(w,d))
print(f'kappa = {k:.3f}, delta = {1-k:.3f}')
"

Updating This Analysis

This is a living document. When endpoints are added or phases completed:

  1. Re-run the acquisition commands above

  2. Update the dimension tables with new counts

  3. Recompute \(\kappa\) using the Python one-liner

  4. Add a row to the Phase Projection table with the measured (not projected) values

The measure \(\mu\) is defined by the weight vector \(\mathbf{w} = (0.30, 0.15, 0.20, 0.15, 0.20)\). If the project’s priorities shift — for example, if intelligence becomes more important than write coverage — adjust \(\mathbf{w}\) and recompute. The decomposition is stable; only the weights are subjective.