# AITP Topic Folder Architecture

Status: canonical

## Purpose

This document defines the file-system layout for AITP topic data.

All topic-local files live under one parent directory per topic. The
legacy split-root layout (separate `runtime/topics/`, `source-layer/topics/`,
`intake/topics/`, `feedback/topics/`, `validation/topics/`, `consultation/topics/`)
has been fully migrated away and must not be reintroduced.

## Layout

```
knowledge-hub/
├── topics/                              ← single parent for all topics
│   ├── <slug-1>/
│   │   ├── topic_manifest.md            ← auto-generated folder contract
│   │   ├── L0/                          ← source intake (papers, notes)
│   │   ├── L1/                          ← distillation, vault
│   │   ├── L2/                          ← staging placeholder only
│   │   ├── L3/                          ← candidate formation
│   │   │   └── runs/<run_id>/           ← per-run artifacts
│   │   ├── L4/                          ← validation / adjudication
│   │   │   └── runs/<run_id>/           ← per-run artifacts
│   │   ├── runtime/                     ← topic state, decisions, profile
│   │   ├── consultation/                ← L2 consultations
│   │   └── logs/                        ← run logs
│   └── <slug-2>/
│       └── ...
├── runtime/                             ← workspace-level (not topic-owned)
│   ├── active_topics.json               ← authoritative topic registry
│   ├── current_topic.md                 ← current-topic memory
│   └── topic_index.jsonl                ← topic index
├── canonical/                           ← global reusable L2
│   ├── compiled/                        ← Obsidian-facing mirror
│   ├── staging/                         ← promotion candidates
│   └── ...                              ← typed canonical families
└── knowledge_hub/                       ← Python package code
```

## Rules

### R1. One folder per topic

Every topic has exactly one truth root at `topics/<slug>/`. No topic data may
live outside this root except for workspace-level artifacts in `runtime/` and
global reusable knowledge in `canonical/`.

### R2. Layers are sub-directories

`L0`, `L1`, `L2`, `L3`, `L4`, `runtime`, `consultation`, and `logs` are
sub-directories inside the topic root. They are not separate top-level trees.

### R3. L2 is global, not topic-owned

Canonical reusable knowledge lives in `canonical/` at the workspace level.
The `L2/` sub-directory inside a topic folder is only a staging placeholder
for promotion candidates, not a second copy of global L2.

### R4. Topic registry is authoritative

`runtime/active_topics.json` is the single source of truth for which topics
exist, their status, lane, and resume stage. Every topic entry must have
`runtime_root` pointing to `topics/<slug>/runtime`.

### R5. Code must go through helpers

All path construction for topic data must use helpers from
`topic_truth_root_support.py`:

- `topic_root()` for the topic folder
- `runtime_root()` for the runtime sub-folder
- `layer_root()` for L0-L4 sub-directories
- `consultation_root()` for the consultation sub-folder
- `logs_root()` for the logs sub-folder
- `ensure_topic_truth_root()` to create the full structure

Do not construct topic paths by string concatenation or by referencing
legacy split-root prefixes.

### R6. Legacy paths are deprecated

The legacy split-root layout (`runtime/topics/`, `source-layer/topics/`, etc.)
must not be used in new code. Legacy helper methods in `aitp_service.py`
(`_legacy_runtime_root`, `_legacy_l0_root`, etc.) are deprecated and emit
`DeprecationWarning`. They will be removed in a future cleanup.

### R7. Topic manifest is auto-generated

`topic_manifest.md` is generated by `ensure_topic_truth_root()`. It records
the folder structure contract. Do not hand-edit it as the authoritative
source.

## Layer quick reference

| Layer | Purpose | Location |
|-------|---------|----------|
| L0    | Source intake (papers, notes, code) | `topics/<slug>/L0/` |
| L1    | Distillation, vault, provisional units | `topics/<slug>/L1/` |
| L2    | Staging placeholder; canonical L2 is global | `topics/<slug>/L2/` |
| L3    | Candidate formation, idea packets, plans | `topics/<slug>/L3/runs/<id>/` |
| L4    | Validation, adjudication, promotion gates | `topics/<slug>/L4/runs/<id>/` |
| runtime | Topic state, decisions, profiles | `topics/<slug>/runtime/` |
| consultation | L2 consultations | `topics/<slug>/consultation/` |
| logs  | Run logs | `topics/<slug>/logs/` |

## Enforced by

- `topic_truth_root_support.py` — path helpers and deprecation warnings
- `aitp_service.py` — `_legacy_*_root()` methods marked deprecated
- `active_topics.json` — all entries must use `topics/<slug>/runtime` format

## Migration history

The migration from split-root to unified layout was completed in a single pass.
All 38 active topics were moved, `active_topics.json` was updated, and the 6
legacy `*/topics/` directories were cleaned up. No rollback path is needed
because the legacy directories no longer exist.
