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:
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:
This is not abstract. Every number below comes from two concrete measurements:
-
Filesystem enumeration:
find docs/modules/ROOT/{pages,partials,examples} -type f | wc -l -
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:
| Content Type | \(|F|\) | \(|F_A|\) | \(R\) |
|---|---|---|---|
Pages ( |
1,855 |
1,855 |
1.000 |
Partials ( |
1,135 |
1,135 |
1.000 |
Examples (all files under |
496 |
496 |
1.000 |
Total |
3,486 |
3,486 |
1.000 |
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.
| Category | Files | Dedicated Route | Status |
|---|---|---|---|
education |
808 |
|
\(\checkmark\) |
projects |
369 |
|
\(\checkmark\) |
codex |
114 |
|
\(\checkmark\) |
2026 (worklogs) |
105 |
|
\(\checkmark\) |
patterns |
95 |
|
\(\checkmark\) |
case-studies |
80 |
|
\(\checkmark\) |
portfolio |
77 |
|
\(\checkmark\) |
reference |
52 |
|
\(\checkmark\) |
standards |
27 |
|
\(\checkmark\) |
templates |
20 |
|
\(\checkmark\) |
api |
18 |
|
\(\checkmark\) |
sessions |
16 |
|
\(\checkmark\) |
drafts |
14 |
|
\(\checkmark\) |
runbooks |
13 |
|
\(\checkmark\) |
2025 (old worklogs) |
13 |
— |
\(\times\) |
trackers |
10 |
|
\(\checkmark\) |
objectives |
9 |
|
\(\checkmark\) |
meta |
6 |
|
\(\checkmark\) |
discoveries |
4 |
|
\(\checkmark\) |
operations |
3 |
— |
\(\times\) |
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.
| Document Type | Standard | POST Endpoint | Status |
|---|---|---|---|
Incident reports |
STD-011 |
|
\(\checkmark\) |
Change requests |
STD-005 |
|
\(\checkmark\) |
Root cause analyses |
STD-010 |
|
\(\checkmark\) |
Projects |
STD-001 |
|
\(\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\) |
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:
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 |
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:
| 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 |
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 |
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 |
|
\(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:
-
Re-run the acquisition commands above
-
Update the dimension tables with new counts
-
Recompute \(\kappa\) using the Python one-liner
-
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.