TS — TFW-26 / Phase A: Compilable Contract + Infrastructure¶
Date: 2026-04-05 Author: Coordinator Status: 🟡 TS_DRAFT — Awaiting approval Parent HL: HL-TFW-26
1. Objective¶
Define the compilable contract — a formal specification of what structure TFW artifacts MUST have for deterministic compilation into a navigable knowledge graph. This includes: - Source manifest (what files are compiled) - Reference format (how agents cite sources — text references that a script resolves into hyperlinks) - Output structure (how the docs site is organized) - Template/workflow amendments (where current artifacts need tighter conventions for the contract to work)
After this phase, every agent and every utility knows: what goes in, what comes out, and how references connect.
2. Scope¶
In Scope¶
- Write §16 Compilable Contract in
.tfw/conventions.md(source manifest, reference format, resolution rules, output structure) - Audit and amend templates where Source/reference columns need standardized format
- Create
docs/mkdocs.ymlwith MkDocs Material configuration - Create
docs/scripts/gen_docs.pyskeleton (imports, manifest, function signatures, reference resolver pattern) - Create
docs/requirements.txt - Create
.github/workflows/docs.ymlfor GitHub Actions deployment - Update
.gitignorewithsite/
Out of Scope¶
- gen_docs.py implementation logic (Phase B)
- Curated docs/index.md landing page (Phase C)
- GitLab CI/CD wrapper (Phase C)
- MCP server implementation (future task)
- Coordinator fact capture in HL template (future task, ref S9)
3. Affected Files¶
| File | Action | Description |
|---|---|---|
.tfw/conventions.md |
MODIFY | Add §16: Compilable Contract |
.tfw/templates/KNOWLEDGE.md |
MODIFY | Source column: standardize reference format |
.tfw/templates/TOPIC_FILE.md |
MODIFY | Source column: add reference format note |
.tfw/templates/RF.md |
MODIFY | FC Source + Observations: reference format note |
.tfw/templates/REVIEW.md |
MODIFY | FC Source + Tech Debt: reference format note |
.tfw/templates/RES.md |
MODIFY | FC Source + HL Recommendations: reference format note |
.tfw/glossary.md |
MODIFY | Add: Compilable Contract, Reference Format, Source Manifest terms |
docs/mkdocs.yml |
CREATE | MkDocs + Material config |
docs/scripts/gen_docs.py |
CREATE | Skeleton with manifest, resolver pattern, function signatures |
docs/requirements.txt |
CREATE | Python dependencies |
.github/workflows/docs.yml |
CREATE | GitHub Actions build + deploy |
.gitignore |
MODIFY | Add site/ |
Budget: 4 new files, 8 modifications = 12 total. Defaults: max 14 files, max 8 new, max 1200 LOC.
4. Detailed Steps¶
Step 1: Define §16 Compilable Contract in conventions.md¶
Add after §15 (Role Lock Protocol).
§16.1 Source Manifest¶
All .md files in the project are compilable. The utility walks these paths:
| # | Source Path | Output Path | Behavior |
|---|---|---|---|
| 1 | README.md |
index.md |
Full copy. If docs/index.md exists, use it as override |
| 2 | .tfw/README.md |
concepts/philosophy.md |
Copy + frontmatter |
| 3 | .tfw/init.md |
getting-started.md |
Copy + frontmatter |
| 4 | .tfw/conventions.md |
reference/conventions.md |
Copy + frontmatter |
| 5 | .tfw/glossary.md |
reference/glossary.md |
Copy + frontmatter |
| 6 | .tfw/CHANGELOG.md |
reference/changelog.md |
Copy + frontmatter |
| 7 | KNOWLEDGE.md |
knowledge-index.md |
Copy + frontmatter (whole file, no split) |
| 8 | knowledge/*.md |
knowledge/{filename}.md |
Copy each + frontmatter |
| 9 | TECH_DEBT.md |
reference/tech-debt.md |
Copy + frontmatter |
| 10 | RELEASE.md |
reference/release.md |
Copy + frontmatter. Optional — skip if absent |
| 11 | tasks/**/*.md |
tasks/{same relative path} |
Copy + frontmatter. Preserve folder structure |
| 12 | .tfw/workflows/**/*.md |
reference/workflows/{path} |
Copy + frontmatter |
| 13 | .tfw/templates/**/*.md |
reference/templates/{path} |
Copy + frontmatter |
Principle:
tasks/preserve their folder structure in output so that all relative links between artifacts (HL→TS, RF→HL, REVIEW→RF) work without rewriting.
File existence rules:
| Source | Required? | On Missing |
|---|---|---|
README.md |
Required | ERROR |
.tfw/README.md, conventions.md, glossary.md, CHANGELOG.md, init.md |
Required | ERROR |
KNOWLEDGE.md |
Optional | WARNING, skip page |
knowledge/ |
Optional | WARNING, skip section |
TECH_DEBT.md |
Optional | WARNING, skip page |
RELEASE.md |
Optional | Skip silently |
tasks/ |
Optional | Skip silently |
docs/index.md |
Optional | Falls back to README.md |
§16.2 Reference Format¶
Agents write text references to other artifacts. A build-time resolver converts these into hyperlinks. Agents do NOT write full markdown links for cross-artifact references (saves tokens, reduces errors).
Standard reference patterns:
| Pattern | Example | Resolves to |
|---|---|---|
{TYPE} {PREFIX}-{N} |
[RF TFW-18](../../TFW-18__knowledge_consolidation/RF__PhaseB__knowledge_quality.md) |
tasks/[TFW-18](../../TFW-18__knowledge_consolidation/HL-TFW-18__knowledge_consolidation.md)*/RF__*.md (glob) |
{TYPE} {PREFIX}-{N} §{section} |
[RF TFW-18](../../TFW-18__knowledge_consolidation/RF__PhaseB__knowledge_quality.md) §6 |
Same file, anchor to section |
{TYPE} {PREFIX}-{N}/{PHASE} |
[RF TFW-18](../../TFW-18__knowledge_consolidation/RF__PhaseB__knowledge_quality.md)/A |
tasks/[TFW-18](../../TFW-18__knowledge_consolidation/HL-TFW-18__knowledge_consolidation.md)*/PhaseA/RF__PhaseA*.md or tasks/[TFW-18](../../TFW-18__knowledge_consolidation/HL-TFW-18__knowledge_consolidation.md)*/RF__PhaseA*.md |
HL-{PREFIX}-{N} |
[HL-TFW-19](../../TFW-19__config_propagation/HL-TFW-19__config_propagation.md) |
tasks/[TFW-19](../../TFW-19__config_propagation/HL-TFW-19__config_propagation.md)*/[HL-TFW-19](../../TFW-19__config_propagation/HL-TFW-19__config_propagation.md)*.md |
D{N} |
D24 |
KNOWLEDGE.md §1 Architecture Decisions row |
P{N} |
P7 |
KNOWLEDGE.md §0 Philosophy row |
F{N} in knowledge context |
F4 |
knowledge/{category}.md row |
TD-{N} |
[TD-59](../../../reference/tech-debt.md) |
TECH_DEBT.md row |
S{N} |
S9 |
HL §11 Strategic Insights row (task-local) |
Where references appear:
- KNOWLEDGE.md §0 Source column, §1 Source column, §2 Key Artifact column, §3 Source column
- knowledge/*.md Source(s) column
- TECH_DEBT.md Source column
- RF.md §2 Key Decisions (rationale text), §6 FC Source column
- REVIEW.md §3 Tech Debt Source column, §5 FC Source column
- RES.md Decisions Rationale column, HL Recommendations Source column, FC Source column
- Any inline mention in artifact prose
Resolution rules:
- Resolver uses tfw.task_prefix from PROJECT_CONFIG.yaml to know the prefix
- Glob-based: {TYPE} [TFW-18](../../TFW-18__knowledge_consolidation/HL-TFW-18__knowledge_consolidation.md) → find tasks/[TFW-18](../../TFW-18__knowledge_consolidation/HL-TFW-18__knowledge_consolidation.md)*/{TYPE}__*.md
- If glob returns multiple matches → use first alphabetically, emit WARNING
- If glob returns zero matches → leave as text, emit WARNING
- Phase references: [RF TFW-18](../../TFW-18__knowledge_consolidation/RF__PhaseB__knowledge_quality.md)/A → search in tasks/[TFW-18](../../TFW-18__knowledge_consolidation/HL-TFW-18__knowledge_consolidation.md)*/PhaseA/ first, then task root
- D{N}, P{N}, F{N}, TD-{N} → anchor links within the appropriate index page
- Resolver runs as a post-processing step on generated pages (regex scan + replacement)
§16.3 Frontmatter Convention¶
Every output page gets YAML frontmatter:
---
title: "{from first # heading or filename}"
source: "{relative path to source file}"
---
§16.4 Output Navigation Structure¶
Home ← README.md (full, with Task Board)
Getting Started ← .tfw/init.md
Concepts/
Philosophy ← .tfw/README.md
Architecture/
Knowledge Index ← KNOWLEDGE.md (whole file)
Knowledge/
{topic files} ← knowledge/*.md
Reference/
Conventions ← .tfw/conventions.md
Glossary ← .tfw/glossary.md
Tech Debt ← TECH_DEBT.md
Changelog ← .tfw/CHANGELOG.md
Release ← RELEASE.md
Workflows/ ← .tfw/workflows/**/*.md
Templates/ ← .tfw/templates/**/*.md
Tasks/
{task folders with all artifacts} ← tasks/**/*.md (preserved structure)
Step 2: Amend templates — Reference Format¶
For each template, add a short note to Source column instructions specifying the reference format.
KNOWLEDGE.md template (.tfw/templates/KNOWLEDGE.md)¶
Change §0 Source column example from backtick-path to reference format:
-| P1 | _Describe your first principle_ | `tasks/{ID}/HL-...md` |
+| P1 | _Describe your first principle_ | HL-{PREFIX}-{N} |
Change §1 Architecture Decisions Source column:
-| # | Decision | Rationale | Source RF |
-|---|----------|-----------|-----------
-| [D1](../../../knowledge-index.md#architecture-decisions) | _e.g., Chose PostgreSQL_ | _ACID needed_ | `tasks/{ID}/RF-...md` |
+| # | Decision | Rationale | Source |
+|---|----------|-----------|--------|
+| [D1](../../../knowledge-index.md#architecture-decisions) | _e.g., Chose PostgreSQL_ | _ACID needed_ | RF {PREFIX}-{N} |
Change §2 Key Artifacts:
-| _PROJ-1_ | _Initial setup_ | `tasks/PROJ-1.../RF-...md` | _Foundation decisions_ |
+| _PROJ-1_ | _Initial setup_ | RF {PREFIX}-1 | _Foundation decisions_ |
Change §3 Legacy Source column:
-| _e.g., Old auth module_ | Deprecated | _2026-01_ | _OAuth2 flow_ | `tasks/{ID}/RF-...md` |
+| _e.g., Old auth module_ | Deprecated | _2026-01_ | _OAuth2 flow_ | RF {PREFIX}-{N} |
Also fix stale §5 reference on L4 → §4:
-> See KNOWLEDGE.md §5 for the index.
+> See KNOWLEDGE.md §4 for the index.
This is TOPIC_FILE.md L4, not KNOWLEDGE.md.
TOPIC_FILE.md template (.tfw/templates/TOPIC_FILE.md)¶
Add reference format note to the table header area:
+> **Source format**: Use reference patterns (e.g., `[RF TFW-18](../../TFW-18__knowledge_consolidation/RF__PhaseB__knowledge_quality.md) §6`, `[REVIEW TFW-22](../../TFW-22__coordinator_research_enrichment/REVIEW__TFW-22__coordinator_research_enrichment.md)`).
+> Build-time resolver converts these to hyperlinks. See conventions.md §16.2.
+
| # | Fact | Verified | Source(s) | Added |
|---|------|----------|-----------|-------|
Fix stale §5 reference:
-> See KNOWLEDGE.md §5 for the index.
+> See KNOWLEDGE.md §4 for the index.
RF.md template (.tfw/templates/RF.md)¶
Add reference format note before FC table:
+> **Source format**: Use reference patterns (e.g., `[RF TFW-18](../../TFW-18__knowledge_consolidation/RF__PhaseB__knowledge_quality.md)`, `D24`). See conventions.md §16.2.
+
| # | Category | Candidate | Source | Confidence |
REVIEW.md template (.tfw/templates/REVIEW.md)¶
Add reference format note before FC table and Tech Debt table:
## 3. Tech Debt Collected
+> **Source format**: Use reference patterns (conventions.md §16.2).
| # | Source | Severity | File | Description | Action |
+> **Source format**: Use reference patterns (e.g., `[RF TFW-18](../../TFW-18__knowledge_consolidation/RF__PhaseB__knowledge_quality.md)`, `D24`). See conventions.md §16.2.
+
| # | Category | Candidate | Source | Confidence |
RES.md template (.tfw/templates/RES.md)¶
Add reference format note before FC table:
+> **Source format**: Use reference patterns (e.g., `[HL-TFW-19](../../TFW-19__config_propagation/HL-TFW-19__config_propagation.md)`, `D24`). See conventions.md §16.2.
+
| # | Category | Candidate | Source | Confidence |
Step 3: Add glossary terms¶
Add to glossary.md before ## Project-Specific Terms:
## Compilable Contract
Formal specification (conventions.md §16) of what structure TFW artifacts must have for deterministic compilation into documentation, MCP endpoints, or other output formats. Defines: source manifest (what files), reference format (how agents cite), resolution rules (how scripts resolve), output structure (where pages go). The contract is the interface between Layer 1 (agents) and Layer 2 (utilities).
## Reference Format
Standard text pattern for cross-artifact citations (conventions.md §16.2). Agents write structured text (e.g., `[RF TFW-18](../../TFW-18__knowledge_consolidation/RF__PhaseB__knowledge_quality.md) §6`, `D24`) instead of full markdown links. Build-time resolver converts these to hyperlinks. Saves tokens, reduces link-rot, enables multi-target output (web, MCP, archive).
## Source Manifest
Ordered list of project files that compilation utilities read (conventions.md §16.1). Includes: root artifacts, .tfw/ core, knowledge/ facts, tasks/ history. Each entry has a source path, output path, and transformation type.
Step 4: Create docs/mkdocs.yml¶
site_name: "My Project Docs"
site_url: ""
repo_url: ""
theme:
name: material
features:
- navigation.sections
- navigation.expand
- navigation.indexes
- search.suggest
- search.highlight
- content.code.copy
palette:
- scheme: default
primary: indigo
accent: indigo
toggle:
icon: material/brightness-7
name: Switch to dark mode
- scheme: slate
primary: indigo
accent: indigo
toggle:
icon: material/brightness-4
name: Switch to light mode
plugins:
- search
- gen-files:
scripts:
- scripts/gen_docs.py
nav:
- Home: index.md
- Getting Started: getting-started.md
- Concepts:
- Philosophy: concepts/philosophy.md
- Architecture:
- Knowledge Index: knowledge-index.md
- Knowledge: knowledge/
- Reference:
- Conventions: reference/conventions.md
- Glossary: reference/glossary.md
- Tech Debt: reference/tech-debt.md
- Changelog: reference/changelog.md
- Release: reference/release.md
- Workflows: reference/workflows/
- Templates: reference/templates/
- Tasks: tasks/
markdown_extensions:
- tables
- admonition
- pymdownx.details
- pymdownx.superfences
- toc:
permalink: true
Note:
navstructure fortasks/will be auto-generated by gen_docs.py from Task Board in README.md. This config is a skeleton.
Step 5: Create docs/scripts/gen_docs.py¶
"""TFW Documentation Generator — mkdocs-gen-files script.
Reads TFW project artifacts and generates virtual MkDocs pages.
Runs at build time via the mkdocs-gen-files plugin.
Contract: .tfw/conventions.md §16 (Compilable Contract)
"""
import re
from pathlib import Path
import mkdocs_gen_files
# --- §16.1 Source Manifest ---
# Static sources: (source_path, output_path, required)
STATIC_SOURCES = [
("README.md", "index.md", True),
(".tfw/README.md", "concepts/philosophy.md", True),
(".tfw/init.md", "getting-started.md", True),
(".tfw/conventions.md", "reference/conventions.md", True),
(".tfw/glossary.md", "reference/glossary.md", True),
(".tfw/CHANGELOG.md", "reference/changelog.md", True),
("KNOWLEDGE.md", "knowledge-index.md", False),
("TECH_DEBT.md", "reference/tech-debt.md", False),
("RELEASE.md", "reference/release.md", False),
]
# Glob sources: (glob_pattern, output_prefix, required)
GLOB_SOURCES = [
("knowledge/*.md", "knowledge/", False),
("tasks/**/*.md", "tasks/", False),
(".tfw/workflows/**/*.md", "reference/workflows/", False),
(".tfw/templates/**/*.md", "reference/templates/", False),
]
# Curated override
INDEX_OVERRIDE = "docs/index.md"
# --- §16.2 Reference Patterns ---
# Compiled at build time from PROJECT_CONFIG.yaml tfw.task_prefix
TASK_PREFIX = "TFW" # TODO: Phase B — read from config
REFERENCE_PATTERNS = [
# {TYPE} {PREFIX}-{N} — e.g., "[RF TFW-18](../../TFW-18__knowledge_consolidation/RF__PhaseB__knowledge_quality.md)", "[HL-TFW-19](../../TFW-19__config_propagation/HL-TFW-19__config_propagation.md)"
(r'\b(HL|TS|RF|ONB|RES|REVIEW)[- ](' + TASK_PREFIX + r'-\d+)\b', '_resolve_artifact_ref'),
# {TYPE} {PREFIX}-{N}/{PHASE} — e.g., "[RF TFW-18](../../TFW-18__knowledge_consolidation/RF__PhaseB__knowledge_quality.md)/A"
(r'\b(HL|TS|RF|ONB|RES|REVIEW)[- ](' + TASK_PREFIX + r'-\d+)/([A-Z])\b', '_resolve_phase_ref'),
# D{N}, P{N}, TD-{N} — decision/principle/tech-debt references
(r'\bD(\d+)\b', '_resolve_decision_ref'),
(r'\bP(\d+)\b', '_resolve_principle_ref'),
(r'\bTD-(\d+)\b', '_resolve_techdebt_ref'),
]
# --- Transformation Functions ---
def add_frontmatter(content: str, title: str, source: str) -> str:
"""Inject YAML frontmatter (§16.3)."""
# TODO: Phase B
pass
def extract_title(content: str, filename: str) -> str:
"""Derive title from first # heading, fallback to filename."""
# TODO: Phase B
pass
def copy_with_frontmatter(source_path: str, output_path: str) -> None:
"""Read source, add frontmatter, write virtual page."""
# TODO: Phase B
pass
def copy_glob(pattern: str, output_prefix: str) -> None:
"""Glob source files, copy each with frontmatter to output prefix."""
# TODO: Phase B
pass
def validate_sources() -> list[str]:
"""Check required sources exist, warn on missing optional (§16.1)."""
# TODO: Phase B
pass
# --- §16.2 Reference Resolver ---
def resolve_references(content: str) -> str:
"""Scan content for reference patterns, resolve to hyperlinks.
Uses glob to find actual file paths for artifact references.
Leaves unresolvable references as plain text with WARNING.
"""
# TODO: Phase B — implement pattern matching + glob resolution
pass
def _resolve_artifact_ref(match: re.Match) -> str:
"""Resolve '{TYPE} {PREFIX}-{N}' to file path."""
# TODO: Phase B
pass
def _resolve_phase_ref(match: re.Match) -> str:
"""Resolve '{TYPE} {PREFIX}-{N}/{PHASE}' to file path."""
# TODO: Phase B
pass
def _resolve_decision_ref(match: re.Match) -> str:
"""Resolve 'D{N}' to KNOWLEDGE.md anchor."""
# TODO: Phase B
pass
def _resolve_principle_ref(match: re.Match) -> str:
"""Resolve 'P{N}' to KNOWLEDGE.md anchor."""
# TODO: Phase B
pass
def _resolve_techdebt_ref(match: re.Match) -> str:
"""Resolve 'TD-{N}' to TECH_DEBT.md anchor."""
# TODO: Phase B
pass
# --- Main ---
def main():
"""Entry point for mkdocs-gen-files plugin."""
warnings = validate_sources()
for w in warnings:
print(f"WARNING [gen_docs]: {w}")
# TODO: Phase B
# 1. Process static sources
# 2. Process glob sources
# 3. Apply reference resolver to all generated pages
if __name__ == "__main__":
main()
Step 6: Create docs/requirements.txt¶
mkdocs>=1.6
mkdocs-material>=9.5
mkdocs-gen-files>=0.5
Step 7: Create .github/workflows/docs.yml¶
name: Deploy Documentation
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install -r docs/requirements.txt
- name: Build docs
run: mkdocs build --config-file docs/mkdocs.yml --strict
- uses: actions/upload-pages-artifact@v3
with:
path: site/
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
Step 8: Update .gitignore¶
Add site/ if not present.
5. Acceptance Criteria¶
- [ ]
.tfw/conventions.md§16 exists with: Source Manifest (13 entries), Reference Format (9 patterns), Resolution Rules, Frontmatter Convention, Output Navigation Structure - [ ] KNOWLEDGE.md template Source columns use reference format (
RF {PREFIX}-{N}) instead of backtick paths - [ ] TOPIC_FILE.md template has reference format note before table
- [ ] RF.md, REVIEW.md, RES.md templates have reference format note before FC tables
- [ ]
glossary.mdhas 3 new terms: Compilable Contract, Reference Format, Source Manifest - [ ]
docs/mkdocs.ymlexists with MkDocs Material config, gen-files plugin, tasks/ in nav - [ ]
docs/scripts/gen_docs.pyskeleton has: static manifest, glob manifest, reference patterns list, resolver function signatures - [ ]
docs/requirements.txtlists 3 dependencies - [ ]
.github/workflows/docs.ymlexists with build + deploy jobs - [ ]
.gitignoreincludessite/ - [ ] All reference patterns in §16.2 are unambiguous — each pattern maps to exactly one resolution rule
6. Phase Risks¶
| Risk | Mitigation |
|---|---|
Reference resolver regex has false positives (e.g., P3 matching prose "P3 protocol") |
Resolver only processes content within Source columns and known table formats. Or: use word boundary \b + context check. Phase B will tune |
| tasks/ contains 100+ files — nav becomes unwieldy | MkDocs Material collapsible sections. Tasks grouped by folder. Task Board in index provides navigation |
| KNOWLEDGE.md as single page is long (140 lines) | Acceptable — page has TOC with anchors. Split is a future optimization if needed |
| Template changes require adapter sync | Phase A RF will list adapter files to sync. Standard procedure per convention F5 |
TS — TFW-26 / Phase A: Compilable Contract + Infrastructure | 2026-04-05