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/{category}

\(\checkmark\)

2026 (worklogs)

105

/worklogs, /worklogs/{date}

\(\checkmark\)

patterns

95

/patterns, /patterns/{domain}

\(\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.