Standardized YAML frontmatter on all 26 docs/discussions/ files with title, description, type, status, round number, and created date. All marked as archived. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
29 KiB
title, description, type, status, round, created
| title | description | type | status | round | created |
|---|---|---|---|---|---|
| Decisions Restructure — Tyre Technical Review | Tyre's technical feasibility review endorsing hybrid domain-split markdown + SQLite index with schema and sync modifications | discussion | archived | 0 | 2026-02-11 |
Decision Architecture Restructure — Technical Feasibility Review
Author: Tyre (Technical Architect)
Date: 2026-02-11
Status: Technical review of Si and Qatux proposals
Inputs reviewed: docs/discussions/decisions-restructure-si.md, docs/discussions/decisions-restructure-qatux.md, db/schema.sql, DECISIONS.md, Makefile, db/connectors/sqlite_connector.py
0. Summary Verdict
Both proposals independently converge on Option C / 2.4: hybrid domain-split markdown + SQLite index. I endorse the hybrid approach. It is feasible, the sync script is tractable, and the architecture is sound. I have specific modifications to the schema, the domain taxonomy, and the sync strategy that reduce maintenance burden and eliminate the primary failure mode (drift).
Let me be honest about what this means technically: this is a documentation infrastructure project, not a game systems project. The engineering is straightforward. The hard part is taxonomy discipline and workflow adoption. I will focus my review on what breaks, what is harder than it sounds, and where we can simplify.
1. Feasibility Assessment — Sync Script and Parsing
1.1 Is the markdown format machine-parseable enough?
Yes, with caveats. Looking at the actual structure of DECISIONS.md, every decision follows a consistent pattern:
### D-NNN: Title text
- **Date:** YYYY-MM-DD
- **Decision:** Free text (may span multiple lines, contain sub-lists, tables, code blocks)
- **Rationale:** Free text
- **Raised by:** Agent names
- **Dissent:** Free text or "None"
This is parseable. The heading line (### D-NNN: Title) is the anchor — reliable, unique, machine-extractable with a simple regex: ^### (D|Q|R)-(\d+):?\s*(.*)$. The metadata fields (Date:, Raised by:, Supersedes:) use bold-prefixed list items, also regex-extractable.
The caveats:
-
Decision body boundaries. The body of a decision runs from the heading to the next heading of equal or higher level. This is standard markdown section parsing — not trivial to hand-roll, but well-solved by libraries. Python's
mistletoe,markdown-it-py, or even a simple state machine splitting on^###lines will work. No need for a full AST parser. -
Freeform cross-references. Decisions reference others in prose: "Supersedes: D-002", "Same principle as D-010", "See D-024", "Ties to D-010 principle 2". Extracting these is a regex scan for
D-\d{3}andQ-\d{3}patterns in the body text. This catches 95% of references. The 5% it misses (oblique references like "the four architectural principles") are not worth chasing — that is what Qdrant semantic search is for. -
Superseded decisions are currently tombstones. D-002 is just
### D-002: SUPERSEDED by D-005. The original text is in git history. During migration, Qatux will need to restore the original text from git for archival completeness. This is a one-time editorial task, not a parsing challenge. -
Inconsistent metadata. Not every decision has
Raised by:orDissent:. Some haveSupersedes:, some haveSuperseded by:, some haveResolves:. The parser must treat all metadata fields as optional. This is easy.
1.2 Is the sync script realistic?
Feasible. Straightforward, in fact. cracks knuckles
Scope-wise, this means: a Python script of ~150-250 lines that reads markdown files, extracts decision blocks using heading-level splitting, parses metadata fields with regex, extracts cross-references with a D-\d{3}|Q-\d{3}|R-\d{3} scan, and upserts into SQLite. The existing sqlite_connector.py already handles connection management, WAL mode, and foreign keys. The sync script can import from it or use the same patterns.
Difficulty tier: Low. The parsing is deterministic, the input format is controlled by us, and we can add a ## Parsing Contract section to the decisions README that specifies exactly what the parser expects. If someone writes a decision that breaks the parser, the parser fails loudly (missing ID, unparseable heading) rather than silently (wrong data).
Time estimate: 3-4 hours for the initial script with tests. 1-2 hours for edge case polish after the first real run.
1.3 What breaks when someone forgets to run the sync script?
This is the critical question. Both proposals identify sync drift as the primary risk.
Si's mitigation: Pre-commit hook runs sync automatically. Qatux's mitigation: Linter script checks markdown IDs match DB IDs.
Both are right, but I want to reframe the risk. The markdown files are the source of truth. The SQLite index is a derived view. If the index drifts, the consequences are:
- Agents querying the DB get stale metadata (wrong status, missing new decisions)
- Cross-reference queries return incomplete results
- Ticket-to-decision coverage reports are inaccurate
These are annoying but not catastrophic. No agent makes architectural decisions based solely on a DB query — they read the markdown file. The DB is a convenience layer for discovery and reporting. If it drifts for a day, nobody ships broken code.
My recommendation: Make the sync script idempotent and cheap, then run it aggressively. Specifically:
decisions-syncshould take <2 seconds for our current 52 entries. At 200 entries, still under 5 seconds. SQLite is fast. There is no reason not to run it on every relevant commit.- Add it to
make setupso the DB is always current when an agent starts work. - Add a
make decisions-synctarget that agents can call manually. - Add a pre-commit hook that runs the sync and stages the DB file. This eliminates drift entirely for git-committed changes.
- Do NOT require agents to manually run sync. The pre-commit hook handles it. If Qatux edits a markdown file and commits, the hook runs, the DB updates, both get committed together.
The pre-commit hook is the key. It turns "two operations that must stay in sync" into "one operation that automatically does both." This is the difference between "manageable maintenance" and "inevitable drift."
2. Schema Review
2.1 Si's Proposed Schema
Si proposes three tables: decisions, decision_refs, decision_tags. The decisions table stores id, type, domain, title, status, supersedes, superseded_by, date, raised_by, file_path, line_start, line_end, synced_at.
2.2 Qatux's Proposed Schema
Qatux proposes two tables: decision_index, decision_refs. Similar to Si but uses decision_index as the table name, adds round INTEGER, tags TEXT (JSON array), and omits raised_by from the index (keeping it in markdown only).
2.3 My Assessment
Both schemas are reasonable. The differences are minor. Here is what I would change:
Table naming: Use decisions, not decision_index. The table IS the decisions metadata. "Index" implies it is secondary, which creates confusion about source of truth. Call it what it is. The markdown is the authoritative content; the DB table is the authoritative metadata and relationship store.
Drop line_start / line_end from Si's schema. These are fragile — they break every time someone edits the file above a decision. The file_path column is sufficient for directing agents to the right file. If you need to jump to a specific decision within a file, use the heading anchor (architecture.md#d-010). Markdown anchors are stable; line numbers are not.
Drop raised_by from the DB. It is in the markdown. It does not drive any query we care about ("show me all decisions raised by Tyre" is not a useful planning query). Keep the DB lean — only store what you actually query.
Keep round INTEGER. Qatux is right — this enables "what changed in Round 17?" queries, which are useful for sprint planning. Si's schema implicitly supports this through date, but round number is more natural for our workflow.
Drop decision_tags as a separate table (for now). Si proposes a tags table. Qatux proposes a JSON array column. Neither has a compelling query use case today. Tags are a future enhancement — add them when we have a query that needs them. YAGNI.
Keep decision_refs with Si's ref_type enum. Both proposals agree on this. The enum (supersedes, references, resolves, depends_on) is the right set. Qatux adds a note TEXT column — that is a nice touch for context, low cost, include it.
Add ON DELETE CASCADE to decision_refs. If a decision is removed from the markdown (rare but possible), the refs should clean up automatically.
2.4 Recommended Schema
-- Decision metadata (synced from decisions/*.md files)
CREATE TABLE IF NOT EXISTS decisions (
id TEXT PRIMARY KEY, -- 'D-031', 'Q-009', 'R-010'
type TEXT NOT NULL CHECK(type IN ('confirmed', 'question', 'rejected')),
domain TEXT NOT NULL, -- derived from source filename
title TEXT NOT NULL,
status TEXT DEFAULT 'active'
CHECK(status IN ('active', 'superseded', 'resolved', 'open')),
round INTEGER, -- discussion round number
date TEXT, -- YYYY-MM-DD
file_path TEXT NOT NULL, -- 'decisions/architecture.md'
synced_at TEXT DEFAULT (datetime('now'))
);
-- Cross-references between decisions (parsed from markdown content)
CREATE TABLE IF NOT EXISTS decision_refs (
source_id TEXT NOT NULL REFERENCES decisions(id) ON DELETE CASCADE,
target_id TEXT NOT NULL REFERENCES decisions(id) ON DELETE CASCADE,
ref_type TEXT NOT NULL
CHECK(ref_type IN ('supersedes', 'references', 'resolves', 'depends_on')),
note TEXT, -- optional context
PRIMARY KEY (source_id, target_id, ref_type)
);
CREATE INDEX IF NOT EXISTS idx_decisions_domain ON decisions(domain);
CREATE INDEX IF NOT EXISTS idx_decisions_status ON decisions(status);
CREATE INDEX IF NOT EXISTS idx_decisions_type ON decisions(type);
CREATE INDEX IF NOT EXISTS idx_drefs_target ON decision_refs(target_id);
Why this is better:
- 2 tables, not 3 (dropped tags — add later if needed)
- No fragile line numbers
- No metadata that duplicates markdown content without query value
- CASCADE cleanup on refs
- Uses
IF NOT EXISTSto match existing schema.sql conventions - Composes cleanly with existing ticket schema — the existing
tickets.decision_ref TEXTcolumn already points atdecisions.idwithout requiring a foreign key constraint (which is correct, since some tickets predate the decisions table)
2.5 Composition with Existing Schema
The existing tickets table has decision_ref TEXT (line 17 of db/schema.sql) with an index on it (idx_tickets_decision). This is already the join key. No migration needed on the ticket side.
The key query both proposals want:
SELECT d.id, d.title, d.domain, COUNT(t.id) as ticket_count
FROM decisions d
LEFT JOIN tickets t ON d.id = t.decision_ref
WHERE d.status = 'active' AND d.type = 'confirmed'
GROUP BY d.id
ORDER BY d.domain, d.id;
This works today with the existing ticket schema, zero changes. That is elegant — the decisions table slots into the existing data model without any schema migration on the ticket side.
3. Tooling Implications
3.1 Makefile Changes
Add these targets:
# --- Decisions ---
decisions-sync:
@python3 db/connectors/decisions_sync.py
@echo "Decisions index synced."
decisions-coverage:
@db/connectors/sqlite-query "SELECT d.domain, COUNT(DISTINCT d.id) as decisions, COUNT(DISTINCT t.decision_ref) as with_tickets FROM decisions d LEFT JOIN tickets t ON d.id = t.decision_ref WHERE d.status='active' AND d.type='confirmed' GROUP BY d.domain"
decisions-active:
@db/connectors/sqlite-query "SELECT id, domain, title FROM decisions WHERE status='active' AND type='confirmed' ORDER BY domain, id"
decisions-orphan:
@db/connectors/sqlite-query "SELECT id, title FROM decisions WHERE type='confirmed' AND id NOT IN (SELECT DISTINCT decision_ref FROM tickets WHERE decision_ref IS NOT NULL)"
Difficulty tier: Trivial. Copy-paste into Makefile, done.
3.2 Connector Scripts
Add one new wrapper script: db/connectors/decisions-sync (bash one-liner, same pattern as sqlite-init).
The sync script itself (db/connectors/decisions_sync.py) is the main new artifact. It follows the same conventions as sqlite_connector.py — uses the same config.json for DB path, same connection patterns, JSON output.
Do NOT create a separate decisions-query wrapper. The existing sqlite-query and sqlite-exec wrappers already work for decisions queries. Adding another wrapper creates confusion about which to use. Just document the common queries in the decisions README and as make targets.
3.3 make setup Changes
Add decisions-sync to the setup target so the DB is current when an agent starts a session:
setup: setup-rust setup-godot setup-tooling decisions-sync
This is important. It means every make setup run ensures the decisions index is current. Agents who follow the CLAUDE.md workflow ("run make setup") automatically get a fresh index.
3.4 Pre-commit Hook
Add a git pre-commit hook that:
- Checks if any
decisions/*.mdfile is staged - If so, runs
decisions-sync - Stages the updated
db/commonwealth.db
This is ~10 lines of bash. It eliminates drift for any change that goes through git commit.
Important: The hook must be installed manually (git hooks are not tracked in the repo). Add a make install-hooks target and document it in CLAUDE.md. Or use the core.hooksPath git config to point at a tracked hooks directory.
3.5 CLAUDE.md Changes
Update the "Agent Instructions / Before starting work" section:
### Before starting work
1. Read your briefing at `docs/briefings/{your-name}.md` for current project context
2. Read the relevant `decisions/*.md` domain file(s) listed in your briefing
3. Check `docs/discussions/` for recent discussion rounds if needed
Update the "File conventions" section:
- Decision files: `decisions/*.md` (domain-split, source of truth)
- Decision IDs: `D-NNN` (confirmed), `Q-NNN` (open questions), `R-NNN` (rejected)
3.6 Agent Workflow Changes
Difficulty tier: Low. The change for agents is: instead of reading one 474-line file, read one or two 80-150 line files that your briefing points you to. This is strictly less work for agents. Adoption friction is near zero.
The only agent whose workflow changes materially is Qatux, who now writes to domain files instead of DECISIONS.md and must run make decisions-sync (or rely on the pre-commit hook). This is a modest workflow change with a net time savings (fewer briefing updates, faster Qdrant re-indexing).
4. Domain Taxonomy
4.1 The Proposals
Si proposes 6 content domains + questions + rejected = 8 files. Qatux proposes 9 content domains + questions + rejected = 11 files.
The difference: Qatux splits out world.md, combat.md, multiplayer.md, and meta.md as separate domains. Si groups these into broader buckets.
4.2 My Assessment: Too Many Domains is Worse Than Too Few
The point of domain splitting is that an agent knows which file to read. If there are 11 files, an agent starting a session asks "which of these 11 files do I need?" and we are back to a discovery problem — just at the file level instead of the decision level.
Qatux's combat.md currently has ONE decision (D-008). meta.md has TWO (D-004, D-021). multiplayer.md has ONE (D-009). process.md has ONE (D-022). Four files with 1-2 decisions each is over-engineering. These files will sit at 15-30 lines for months. That is not a domain, that is a stub.
The right heuristic: a domain file should be 60-200 lines today and projected to grow to 150-400 lines over 12 months. Below 60 lines, the file is overhead. Above 400 lines, the file needs splitting.
4.3 Recommended Taxonomy: 5 Content Domains + 2 Reference Files
| Domain | File | Current Decisions | Notes |
|---|---|---|---|
| architecture | decisions/architecture.md |
D-008, D-009, D-010, D-012, D-020, D-026, D-030, D-031 | Technical foundation. Includes combat design principles (D-008, which is about z-levels, LOD, procgen patterns), multiplayer architecture (D-009), simulation tiers (D-026), time system (D-031). ~8 decisions, ~160 lines. |
| perception | decisions/perception.md |
D-011, D-015, D-016, D-017, D-018, D-019 | Everything the player sees and hears. Camera, fog, sound, monologue, perception modes. ~6 decisions, ~120 lines. |
| content | decisions/content.md |
D-023, D-024, D-025, D-028, D-029 | NPC generation, templates, dialogue, population ratios. Will grow fastest. ~5 decisions now, projected 20-30. ~100 lines now. |
| scope | decisions/scope.md |
D-001, D-003, D-005, D-006, D-007, D-013, D-014, D-027 | What we are building, the core concept, design pillars, prototype definition, map specs, POI system. ~8 decisions, ~180 lines. |
| process | decisions/process.md |
D-004, D-021, D-022 | Team, title, workflow. Small now, grows slowly. ~3 decisions, ~40 lines. Acceptable as a thin file because process decisions are rarely consulted. |
| -- | decisions/questions.md |
Q-001 through Q-011 | Reference file. |
| -- | decisions/rejected.md |
R-001 through R-010 | Reference file. |
Total: 7 files. Down from Qatux's 11, up from a monolith.
Why this works:
- Tyre reads:
architecture.md(primary) +perception.md(secondary). Two files, ~280 lines total. Down from 474. - Paula reads:
content.md(primary). One file, ~100 lines. Down from 474. - Gestalt reads:
scope.md+content.md. Two files, ~280 lines. Down from 474. - Si reads:
scope.md(primary) + queries DB for cross-domain planning. - Miri reads:
scope.md+content.mdfor lore-relevant decisions.
Every agent reads 1-2 files. No agent reads all 7. The briefing tells them which files to read. Discovery problem solved.
4.4 Where the Edge Cases Go
- D-008 (action pillar): Goes in
architecture.md. It is about z-levels, LOD, procgen, combat system architecture. Tyre needs it. When the combat system grows, we can splitarchitecture.mdintoarchitecture-core.mdandarchitecture-combat.md. Not yet. - D-009 (multiplayer): Goes in
architecture.md. It is an architectural constraint, not a game design domain. The "design for multiplayer" principle affects every system Tyre builds. - D-013 (diegetic insert/POI): Goes in
scope.md. It is part of the game concept — how navigation works. Cross-reference inperception.mdif needed. - D-026 (simulation tiers): Goes in
architecture.md. It is a performance budget and ECS architecture decision. Content implications are noted via cross-reference. - D-031 (time system): Goes in
architecture.md. It is a simulation infrastructure decision with gameplay implications.
The principle: if Tyre has to validate the technical feasibility, it goes in architecture. If Paula has to write content for it, it goes in content. If Gestalt has to design systems around it, it goes in scope or content depending on whether it is a "what" decision (scope) or a "how" decision (content).
4.5 When to Split
Set a threshold: when any domain file exceeds 350 lines (~25 decisions), review whether it should split. content.md will hit this first. Split into content-npcs.md and content-dialogue.md when it happens. The DB makes this painless — update file_path column, move the text. Git diff shows the reorganization clearly.
5. Alternative Considerations
5.1 Can We Get 80% of the Benefit With 20% of the Work?
Yes. The domain split alone (Option A / Si's Phase 1) delivers the vast majority of the value:
- 70-80% context reduction: agents read domain files, not the monolith
- Cleaner git diffs: domain-scoped changes
- Faster Qdrant re-indexing: per-domain-file
- Better discovery: agents know which file to read
The DB index adds:
- Cross-reference queries (nice but agents can grep markdown)
- Ticket-decision linkage reports (useful for Si's sprint planning)
- Structured supersession tracking (nice but rare — 2 superseded decisions in 31)
- "Decisions without tickets" audit (genuinely useful)
If time is tight: do the domain split now, defer the DB index. The domain split is a 2-3 hour editorial pass with zero new tooling. The DB index is another 4-6 hours of scripting and testing. Both are cheap, but the split delivers immediate value to every agent while the DB index primarily benefits Si's planning workflow.
However: Since both Si and Qatux have already designed the DB schema and sync approach in detail, and the engineering is straightforward, I see no reason to defer. Do both. The total effort is under a day. The sync script is a weekend build, same as D-028's line previewer CLI.
5.2 What About Just Using Qdrant?
One approach neither proposal explored: instead of SQLite, use Qdrant's metadata filtering capabilities. Index the domain files with metadata (domain, decision_id, status) and let agents search with filters.
I would reject this. Qdrant is a semantic search engine, not a relational database. It does not support JOINs (decisions-to-tickets), aggregations (coverage reports), or precise equality queries (get D-010 exactly). It complements the DB, it does not replace it.
5.3 What About a Single README Index File Instead of SQLite?
A decisions/README.md with a manually maintained table of all decisions (ID, domain, title, status) would give agents a lightweight discovery mechanism without any new tooling.
This is actually worth doing regardless of whether we build the DB index. It is a 20-minute manual creation during the split. It serves as the human-readable entry point to the domain files. The DB index can then be validated against it.
I recommend: create decisions/README.md as part of the migration. Whether we build the DB sync script immediately or defer it, the README has standalone value.
6. My Recommendation
6.1 Endorse Hybrid Approach With Modifications
I endorse the hybrid domain-split + SQLite index approach. Both proposals are well-reasoned. My modifications:
-
Reduce domain count from 11 to 7 files (5 content domains + questions + rejected). See Section 4.3 for the taxonomy.
-
Simplify the schema to 2 tables (decisions + decision_refs). Drop decision_tags, drop line numbers, drop raised_by from DB. See Section 2.4 for the schema.
-
Make the sync script a pre-commit hook, not a manual step. This eliminates drift as a failure mode entirely. See Section 1.3.
-
Add
decisions-synctomake setup. Every agent session starts with a current index. -
Create
decisions/README.mdas a human-readable index regardless of DB timeline. -
Do NOT create new wrapper scripts for decisions queries. Use existing
sqlite-queryandsqlite-exec. Add common queries as make targets. -
Phase the migration in 2 phases, not 5. Si's 5-week phased rollout is too slow for the scope of work. This is a day of focused effort, not a multi-week project.
6.2 Revised Migration Plan
Phase 1: Split + Index (Day 1, ~4-5 hours)
- Create
decisions/directory - Split DECISIONS.md into 7 domain files using the taxonomy in Section 4.3
- Restore superseded decision text from git history (D-002, D-006)
- Add cross-reference hyperlinks between domain files
- Create
decisions/README.mdwith index table - Replace root
DECISIONS.mdwith a redirect - Extend
db/schema.sqlwith decisions tables (Section 2.4) - Run
sqlite-initto apply new schema - Build and run
db/connectors/decisions_sync.py - Update all agent briefings to point to domain files
- Re-index domain files in Qdrant
- Update
CLAUDE.md - Commit everything in one atomic commit
Phase 2: Automation (Day 2, ~2-3 hours)
- Add
decisions-synctarget to Makefile - Add
decisions-coverage,decisions-active,decisions-orphanmake targets - Add
decisions-synctomake setup - Create pre-commit hook for auto-sync
- Add
make install-hookstarget - Write 5-10 parser tests (test fixtures: sample decision blocks)
- Commit
Total effort: ~7-8 hours across 2 focused sessions. Not 5 weeks.
6.3 What I Would Build
If assigned the technical implementation (which Si's proposal assigns to me), here is what I would deliver:
-
db/connectors/decisions_sync.py(~200 lines Python)- Reads all
decisions/*.mdfiles - Parses decision blocks using
^### (D|Q|R)-\d+heading splits - Extracts: id, type, title, status, date, round (from metadata fields)
- Derives: domain (from filename), file_path
- Scans body for
(D|Q|R)-\d{3}references, infers ref_type from context - Upserts into
decisionsanddecision_refstables - Validates: warns on broken references, orphaned supersessions
- Output: JSON summary (decisions synced, refs created, warnings)
- Idempotent: safe to run repeatedly
- Reads all
-
db/connectors/decisions-sync(bash one-liner wrapper, same pattern assqlite-init) -
Schema additions to
db/schema.sql(the 2-table schema from Section 2.4) -
Makefile targets (Section 3.1)
-
Pre-commit hook (~15 lines bash)
-
Parser test fixtures (3-4 sample decision blocks + expected parse output)
Difficulty tier: Low-to-medium. Challenging only in the "doing it carefully" sense, not the "might not work" sense. The parsing is deterministic, the schema is simple, the tooling patterns are established. This is a confidence build, not a research spike.
7. Risks I Want to Flag
7.1 Binary DB File in Git
Both proposals commit commonwealth.db to git. Binary files in git are not diffable. Qatux acknowledges this; Si does not address it.
My position: this is acceptable. The DB is a derived artifact (synced from markdown). Its git history is the markdown file history. If you need to see "what changed in the decisions index," look at the markdown diff. The DB file is committed for convenience (agents have a current index without running sync), not for auditability.
Mitigation: If the DB grows large (unlikely — decisions metadata is tiny), we can .gitignore it and require make setup to regenerate it. But at <100KB for hundreds of decisions, this is a non-issue.
7.2 Taxonomy Disputes
When D-032 arrives, someone must decide which domain file it goes in. If the taxonomy is unclear, this becomes a recurring friction point.
Mitigation: The decisions/README.md must include a clear one-sentence definition of each domain's scope and a "when in doubt" rule. My proposed rule: if a decision constrains how we build, it is architecture. If it defines what we build, it is scope. If it defines what the player experiences, it is content or perception. If it defines how the team works, it is process.
7.3 Cross-Domain Decisions
D-026 (simulation tiers) touches architecture AND content. D-013 (POI system) touches scope AND perception.
My position: single-homing with cross-reference notes. Every decision lives in exactly one file. The other file gets a one-line cross-reference: > See also: [D-026: Simulation tiers](architecture.md#d-026) — performance budgets affect content density. This is cleaner than duplication and keeps the DB simple (one file_path per decision).
7.4 The "Nobody Reads the README" Problem
We are creating a decisions/README.md that explains the taxonomy. If agents skip it and go straight to the wrong domain file, they miss decisions.
Mitigation: Briefings are the primary routing mechanism, not the README. Agents do not discover which file to read — their briefing tells them. The README is for humans and for agents who need cross-domain context. This is already how it works (briefings tell agents which decisions to read); we are just making the pointer more granular (domain file vs monolith).
8. Conclusion
This is a good idea proposed by two agents who thought about it carefully. The technical execution is straightforward. The main value — context window reduction for agents — is immediate and significant. The secondary value — structured queries for sprint planning — is real but can be phased.
I endorse the hybrid approach with the modifications described above: fewer domains (7 not 11), leaner schema (2 tables not 3), automated sync (pre-commit hook, not manual), and compressed timeline (2 days not 5 weeks).
Assign me the sync script, schema additions, and Makefile targets. I can have Phase 1 and 2 deliverables ready in two focused sessions.
File locations referenced:
- This review:
/var/mnt/data/projects/commonwealth/docs/discussions/decisions-restructure-tyre.md - Si's analysis:
/var/mnt/data/projects/commonwealth/docs/discussions/decisions-restructure-si.md - Qatux's analysis:
/var/mnt/data/projects/commonwealth/docs/discussions/decisions-restructure-qatux.md - Current schema:
/var/mnt/data/projects/commonwealth/db/schema.sql - Current decisions:
/var/mnt/data/projects/commonwealth/DECISIONS.md - Makefile:
/var/mnt/data/projects/commonwealth/Makefile - SQLite connector:
/var/mnt/data/projects/commonwealth/db/connectors/sqlite_connector.py
End of technical review.