Files
settled-reach/docs/discussions/decisions-restructure-tyre.md
T
jpmschweitzerandClaude Opus 4.6 1014680ebb docs(discussions): add frontmatter to all discussion rounds
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>
2026-03-13 18:55:37 +01:00

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:

  1. 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.

  2. 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} and Q-\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.

  3. 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.

  4. Inconsistent metadata. Not every decision has Raised by: or Dissent:. Some have Supersedes:, some have Superseded by:, some have Resolves:. 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:

  1. decisions-sync should 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.
  2. Add it to make setup so the DB is always current when an agent starts work.
  3. Add a make decisions-sync target that agents can call manually.
  4. Add a pre-commit hook that runs the sync and stages the DB file. This eliminates drift entirely for git-committed changes.
  5. 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.

-- 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 EXISTS to match existing schema.sql conventions
  • Composes cleanly with existing ticket schema — the existing tickets.decision_ref TEXT column already points at decisions.id without 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:

  1. Checks if any decisions/*.md file is staged
  2. If so, runs decisions-sync
  3. 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.

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.md for 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 split architecture.md into architecture-core.md and architecture-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 in perception.md if 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:

  1. Reduce domain count from 11 to 7 files (5 content domains + questions + rejected). See Section 4.3 for the taxonomy.

  2. 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.

  3. Make the sync script a pre-commit hook, not a manual step. This eliminates drift as a failure mode entirely. See Section 1.3.

  4. Add decisions-sync to make setup. Every agent session starts with a current index.

  5. Create decisions/README.md as a human-readable index regardless of DB timeline.

  6. Do NOT create new wrapper scripts for decisions queries. Use existing sqlite-query and sqlite-exec. Add common queries as make targets.

  7. 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)

  1. Create decisions/ directory
  2. Split DECISIONS.md into 7 domain files using the taxonomy in Section 4.3
  3. Restore superseded decision text from git history (D-002, D-006)
  4. Add cross-reference hyperlinks between domain files
  5. Create decisions/README.md with index table
  6. Replace root DECISIONS.md with a redirect
  7. Extend db/schema.sql with decisions tables (Section 2.4)
  8. Run sqlite-init to apply new schema
  9. Build and run db/connectors/decisions_sync.py
  10. Update all agent briefings to point to domain files
  11. Re-index domain files in Qdrant
  12. Update CLAUDE.md
  13. Commit everything in one atomic commit

Phase 2: Automation (Day 2, ~2-3 hours)

  1. Add decisions-sync target to Makefile
  2. Add decisions-coverage, decisions-active, decisions-orphan make targets
  3. Add decisions-sync to make setup
  4. Create pre-commit hook for auto-sync
  5. Add make install-hooks target
  6. Write 5-10 parser tests (test fixtures: sample decision blocks)
  7. 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:

  1. db/connectors/decisions_sync.py (~200 lines Python)

    • Reads all decisions/*.md files
    • 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 decisions and decision_refs tables
    • Validates: warns on broken references, orphaned supersessions
    • Output: JSON summary (decisions synced, refs created, warnings)
    • Idempotent: safe to run repeatedly
  2. db/connectors/decisions-sync (bash one-liner wrapper, same pattern as sqlite-init)

  3. Schema additions to db/schema.sql (the 2-table schema from Section 2.4)

  4. Makefile targets (Section 3.1)

  5. Pre-commit hook (~15 lines bash)

  6. 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.