diff --git a/.agents/skills/orion-archive/SKILL.md b/.agents/skills/orion-archive/SKILL.md
new file mode 100644
index 0000000..030fdbe
--- /dev/null
+++ b/.agents/skills/orion-archive/SKILL.md
@@ -0,0 +1,128 @@
+---
+name: orion-archive
+description: "Archive a whole Area (with all its Projects) into a bundle under 5. Archive/, or restore one that's resuming. Moves the Area and Project folders, keeps reusable research in place, downgrades people whose only tie was this Area, writes a tombstone manifest, and repoints every inbound link. People, Threads and Decisions never move. Fully reversible. Triggers on: archive [name], archive area, wind down [name], resume [name], restore [name], unarchive [name]."
+---
+
+# orion-archive — retire or restore a whole Area
+
+**Never delete.** Everything moves to `5. Archive/`; nothing is discarded. The tombstone exists so a later session can find and restore it.
+
+## Archive or close?
+
+**Is the Area going away (ended or paused)?** → this skill. **Is the Area staying and one workstream done?** → `orion-close`. Don't close every workstream before archiving an Area — archive the bundle; they travel with it.
+
+**Archiving is a change, not a repair. Confirm with the owner before moving anything.**
+
+---
+
+## The bundle
+
+```
+5. Archive//
+ _index.md ← tombstone manifest (required)
+ 1. Projects//... ← every Project under the Area, moved wholesale
+ 2. Areas//... ← the Area folder, including knowledge/
+ /... ← closed workstreams already here from orion-close — merge, don't collide
+```
+
+**If only one Project is being retired and its Area stays live**, it's not an archive — close it (`orion-close`) or pause it.
+
+## What moves, what doesn't
+
+| | |
+|---|---|
+| `1. Projects//` and `2. Areas//` | **Move** into the bundle |
+| `3. Resources/Research/` (reusable, no single Area) | **Stays** |
+| People | **Never move.** Downgrade — see below |
+| Threads | **Never bundled.** A thread may span Areas; resolve or drop it separately |
+| Decisions | **Never move, never edited** (dead link targets still get repointed) |
+| Outbox, lint reports | **Stay flat** — they describe more than one Area |
+
+**The ownership test:** does this content have exactly one owning Area? Yes → bundle it. No → leave it where it is.
+
+## People — downgrade, don't move
+
+For each person whose **only** live tie was this Area:
+- Set `tier: contact`. **Remove `cadence:` and `follow_up_by:`** — a contact carries neither.
+- Add a dated `Contact History` line: archived, tier changed.
+- **Keep their Area tag.** It records where they entered the vault.
+
+People with ties elsewhere keep their tier; if their follow-up was specifically for this Area's work, **don't change it** — list them on a `Released:` line in the log entry for the owner to decide.
+
+---
+
+## Sequence
+
+1. **Inventory** — every file under the Area and its Projects; every person whose context is this Area; threads naming it.
+2. **Confirm with the owner.**
+3. **Move** the folders into the bundle (`git mv` if the vault is a git repo, to keep history).
+4. **Write the tombstone** — format below.
+5. **Repoint inbound links, everywhere** — hubs, people, threads, `hot.md`, **and ledgers** (`log.md`, folds, decisions). Method: scan every `[[…]]` (ignoring code blocks), resolve each against the real tree, **change only the link target, never the prose**, keep display aliases. **Rescan and confirm zero new dead links.**
+6. **Downgrade people** per the rule above.
+7. **Retire the Area tag** in `wiki/meta/tags.md` (mark it archived; pages keep it).
+8. **Log** (`[vault]`, with `Released:` if any) and suggest `cascade`.
+
+## Tombstone — `5. Archive//_index.md`
+
+```markdown
+---
+type: archive
+subject: — archive bundle
+date: YYYY-MM-DD
+tags: [archive, ]
+---
+
+# — archived YYYY-MM-DD
+
+**Why:** one or two sentences — what happened, no speculation.
+
+## In this bundle
+- 1. Projects// —
+- 2. Areas// — hub and knowledge/
+
+## Deliberately not in this bundle
+- People —
+- Threads —
+- Decisions — untouched in 4. Decisions/
+
+## Links
+Repointed N inbound links; rescan: 0 dead.
+
+## If this resumes
+Run `resume ` — orion-archive, restore path.
+```
+
+---
+
+## Restore — `resume `
+
+1. **Read the tombstone.** Don't reconstruct from memory.
+2. **Move the folders back** to their exact original paths.
+3. **Re-promote people** listed as downgraded: restore their previous `cadence:` (check git history of their page rather than guessing) and set a real `follow_up_by:`. Add a Contact History line; don't edit the old one.
+4. **Repoint links back** — same method as archiving, ledgers included, rescan to zero.
+5. **Keep the Area's `workstream_counter:` as it was.** IDs issued before the archive stay spent.
+6. **Retire the tombstone, don't delete it:** append `## Resumed YYYY-MM-DD`. The bundle folder's end state is that one file.
+7. Un-archive the tag in `tags.md`. Log. Cascade.
+
+## Output
+
+```
+## Archive —
+
+Moved: 1. Projects// (N workstreams) · 2. Areas//
+Stayed:
+People downgraded: · Released:
+Links repointed: N — rescan 0 dead
+Tombstone: 5. Archive//_index.md
+
+Next: run cascade.
+```
+
+## Rules
+
+- **Never delete. Always reversible.**
+- **Confirm before moving** — archiving is a change.
+- **People, Threads, Decisions never move.** People downgrade to `tier: contact`; follow-up fields removed.
+- **Area tags are never stripped.**
+- **Repoint every dead link the move creates, ledgers included. Only the target changes. Rescan to zero.**
+- **A tombstone is required** for every bundle.
diff --git a/.agents/skills/orion-cascade/SKILL.md b/.agents/skills/orion-cascade/SKILL.md
new file mode 100644
index 0000000..e66a487
--- /dev/null
+++ b/.agents/skills/orion-cascade/SKILL.md
@@ -0,0 +1,153 @@
+---
+name: orion-cascade
+description: "Sync an Orion vault's wiki/ navigation layer from the numbered folders. Rewrites wiki/hot.md (current state: outstanding sends, workstreams, the owner's own next moves, people due for follow-up), appends one wiki/log.md entry, rebuilds wiki/index.md when structure changed, and reports how many log entries are waiting to be folded. Run at the end of every session that changed something. Triggers on: cascade, run cascade, sync the wiki, update the wiki."
+---
+
+# orion-cascade — sync the wiki layer
+
+The numbered folders are the source of truth. Cascade reads them and rewrites `wiki/` to match. **One command, no flags.** Always rewrite `hot.md` and append to `log.md`; rebuild `index.md` when you see the structure changed (a hub added, moved, renamed, or its `status`/`area` changed). When in doubt, rebuild it.
+
+⛔ Skip every path listed under *Fences* in `AGENTS.md`.
+
+---
+
+## 1. Read hubs
+
+Glob `1. Projects/**/*_hub.md` and `2. Areas/**/*_hub.md` — **match the `_hub` suffix, never a full filename.**
+
+- **Skip `paused`, `closed` and `archived` Projects** for attention purposes (count them, don't read them further). Paused is a deliberate exclusion.
+- **Areas carry no attention status.** List them; never compute drift or freshness on one.
+- For each `open` Project: `id`, name, `next:` (**may be a YAML list — read every entry**), `deadline:`.
+
+## 2. Read people
+
+Glob `3. Resources/People/*.md`. **Only `tier: relationship` pages can flag.**
+
+For each: compute the **live due date**:
+- `follow_up_by` after `last_contact` (or no `last_contact`) → `follow_up_by`.
+- `follow_up_by` on or before `last_contact` is **spent** → `weekly`/`biweekly`/`monthly`: `last_contact` + 7/14/30 days, marked *(from last contact)*; `organic`: **no date since contact** (its own line, never overdue).
+- No `follow_up_by` at all → **defect**.
+
+Bucket: **Overdue** · **Due within 7 days** · **No date since contact** · **Defects**. **Never write a computed date back to the page.**
+
+⚠ **This step is where names get swapped or dropped.** Before writing, check every name you're about to render against its own file's `tier:` and dates. Similar names are the usual failure.
+
+## 3. Read threads
+
+Glob `3. Resources/Threads/*.md`: `status`, one-line state. **A thread whose `domains:` no longer name any live hub has collapsed** — flag it for close or drop.
+
+## 4. Read holds
+
+`wiki/meta/holds.md`, before rendering any age. Rules → `AGENTS.md`, *Holds*. In short: an open hold covering an item → render `held`; a closed hold → `3d (since 01-05, 11d held)`; an item created after the hold began is not covered.
+
+## 5. Rewrite `wiki/hot.md`
+
+**Rewrite, never append.** Hard cap **80 lines.** Sections in this order:
+
+```markdown
+## Hold ← only when one is open. Two lines: period, scope
+## Outstanding sends ← every `send` and `wait` from live hubs, with age
+## Workstreams ← "N open: WEB-1, WEB-3, OPS-2 · N paused: …" — one line, never a block each
+## Now ← every `build`/`decide` next: — the owner's own moves. Oldest [since] first, no ages
+## People ← "N armed", then overdue / due soon / defects by name
+## Threads ← open threads, one line each (omit if none)
+## Warnings ← ⚠ items worth carrying (omit if none)
+## Standing state ← carried forward, pruned each run
+```
+
+**Ageing sends:** `[since YYYY-MM-DD]` is the authority → else git (`git log -1 --format=%ad --date=short -S'next:' -- `) → else **no age**. A wrong age is worse than none.
+
+**Mis-verbed moves are a repair:** a `send →`/`wait →` naming the owner is really a `build`; a `build →` whose move is a message is really a `send`. Fix the hub's verb, then render.
+
+**Never age an `open` workstream.** It has no clock by design.
+
+**The cap is enforced by eviction, not compression.** At 80 lines, find what no longer belongs; don't shrink prose or raise the cap.
+
+**The two-run exit for warnings.** A `⚠` item that appears in **two consecutive cascades** without resolving moves to `wiki/meta/open-questions.md` as a forced binary, and `hot.md` keeps one pointer line stating the consequence:
+
+```markdown
+⚠ Vendor quote unverified — don't cite its dates → open question #4
+```
+
+**Never drop a warning without leaving a pointer.**
+
+**Vault voice:** everything in `hot.md` is the vault speaking. A claim sourced from a document, not from the owner, stays attributed or stays out.
+
+## 6. Rebuild `wiki/index.md` — when structure changed
+
+Plain markdown, one line per page, navigation only — no prose:
+
+```markdown
+## Areas
+- [[2. Areas/Website/Website_hub|Website]] — standing · prefix WEB · 3 issued
+## Projects
+### Open
+- [[1. Projects/Website/Pricing Page/WEB-3_hub|WEB-3 Pricing Page]] — done when: "…"
+### Paused
+## Threads
+## People
+### Relationship tier
+- [[3. Resources/People/Sam Example|Sam Example]] — monthly · due 2026-02-01
+### Contacts
+## Decisions
+- [[4. Decisions/2026-01-05-pricing-model|2026-01-05 Pricing model]] — open
+## Folds
+```
+
+*(If the vault is opened in Obsidian with Dataview, the owner may replace sections with queries. Keep the headings.)*
+
+## 7. Append to `wiki/log.md`
+
+New entry **at the top**, below the header. Never edit a past entry.
+
+```markdown
+## YYYY-MM-DD — [vault] Cascade:
+- Projects: N open, N paused
+- People: N overdue, N due soon —
+-
+```
+
+Use `[build]` only when the session shipped something, and then add `Shipped: `.
+
+## 8. Count unfolded log entries — every run
+
+```bash
+grep -c '^## [0-9]' wiki/log.md # all entry headings
+grep -c '\[folded\]' wiki/log.md # fold pointers — not entries
+```
+
+**Unfolded = headings − pointers.** Threshold **16**. Print the number every run, above or below threshold: `Log: 9 / 16` or `Log: 23 / 16 — fold due`. **Don't run the fold** — that's `orion-fold`, on the owner's word.
+
+---
+
+## Output
+
+```
+## Cascade — YYYY-MM-DD
+
+Sends outstanding
+- — ()
+
+Workstreams: N open () · N paused ()
+
+People (armed: N)
+Overdue: (due YYYY-MM-DD)
+Due this week: (due YYYY-MM-DD[, from last contact])
+Defects: — no follow_up_by
+
+Threads:
+Log: N / 16 [— fold due]
+Wiki updated: hot.md · log.md [· index.md]
+Verified: rendered names checked against their own files — pass /
+```
+
+The `Log` and `Verified` lines print every run. A check that only speaks when something's wrong teaches nobody what normal looks like.
+
+## Rules
+
+- **`hot.md` and `index.md` are state — rewrite. `log.md` is a ledger — prepend, never edit.**
+- **Skip paused/closed/archived Projects. Never compute drift on an Area.**
+- **Only `tier: relationship` people flag.** Spent follow-ups compute a live date; the stored one is never rewritten.
+- **Never render an age you can't source.**
+- **Unconfirmed claims stay attributed or out.**
+- **Verify every rendered name and count before writing.**
diff --git a/.agents/skills/orion-close/SKILL.md b/.agents/skills/orion-close/SKILL.md
new file mode 100644
index 0000000..c98174a
--- /dev/null
+++ b/.agents/skills/orion-close/SKILL.md
@@ -0,0 +1,104 @@
+---
+name: orion-close
+description: "Close a finished workstream in an Orion vault and return its deliverable to the Area that spawned it. Verifies done_when is actually met, splits the output into deliverable (→ 2. Areas//knowledge/) and process record (→ 5. Archive///), updates the Area hub, releases follow-ups tied to the work, and repoints inbound links. Not reversible. Distinct from orion-archive, which retires a whole Area. Triggers on: close workstream, close [ID], this is done, finish workstream, ship it."
+---
+
+# orion-close — return a finished workstream to its Area
+
+**An Area spawns a workstream; when the workstream finishes, its deliverable comes home.** The Area is the memory; the workstream is the episode. If finished output archives together with its process, the Area learns nothing and the next workstream starts cold.
+
+```
+2. Areas// ──spawns──▶ 1. Projects///
+ knowledge/ ◀── deliverable ──────────────────┤
+ └── process ──▶ 5. Archive///
+```
+
+## Close or archive?
+
+| | `orion-close` | `orion-archive` |
+|---|---|---|
+| Trigger | One workstream **finished** | A whole Area **ended or paused** |
+| The Area | **Stays, gains knowledge** | Moves into the archive |
+| Reversible | **No** | Yes |
+
+**Is the Area staying? → close. Is it going away? → archive.** If there's any chance the work resumes, it's `paused`, not closed.
+
+---
+
+## 1. Verify `done_when:` against reality
+
+Read the hub's `done_when:` and check it against what actually exists — not against how finished the work feels.
+
+**Not met → stop and say which part is outstanding.** Never rewrite `done_when:` at close time to match what happened; a done-when edited at close never tested anything. Legitimate paths:
+
+| Situation | Action |
+|---|---|
+| Work is done, the sentence was wrong | **The owner's call.** Record the correction and why on the hub, then close |
+| Work stopped and won't resume | Not a close — `paused` with a reason |
+| Scope changed | Old workstream closes as superseded; a new one opens with a new ID |
+
+## 2. Split the output
+
+| Pile | Goes to | What |
+|---|---|---|
+| **Deliverable** | `2. Areas//knowledge/` | What the Area now knows: conclusions, specs, finished documents, reusable findings |
+| **Process record** | `5. Archive///` | How it got there: session notes, drafts, dead ends, the hub itself |
+
+**One question per file:** *would someone working in this Area six months from now want this without knowing the workstream existed?* Yes → knowledge. No → archive.
+
+**When genuinely unclear, ask.** This is the one checkpoint that stops execution.
+
+## 3. Migrate the deliverable
+
+Move each deliverable file into `knowledge/`. **Keep the filename** (renaming breaks links for no gain). Add a provenance line if missing: *"Produced by `` — ``, closed YYYY-MM-DD."*
+
+## 4. Archive the process record
+
+Move everything else, **including `_hub.md`**, to `5. Archive///`. Set `status: closed`, add `closed: YYYY-MM-DD`. No tombstone needed — nothing to restore.
+
+## 5. Update the Area hub
+
+Mark the workstream closed in `## Workstreams`, with its ID and one line on what it produced. Link the deliverable from the hub or `knowledge/_index.md`. ⚠ **Never decrement `workstream_counter:`.** IDs are never reused.
+
+## 6. Release follow-ups
+
+List every `tier: relationship` person whose follow-up exists *for this workstream* (they link the hub, are named by its `next:`, or their page says so). **Change nothing on their pages** — whether the relationship outlives the work is the owner's call. Record them on a `Released:` line in the log entry; the next weekly sweep lists them.
+
+## 7. Repoint inbound links
+
+1. **Scan** every `.md` in the vault for `[[…]]` targets pointing into the old folder (full-path and bare-name forms). Ignore links inside code blocks.
+2. **Resolve each hit against the real file tree** — a grep hit is a hypothesis.
+3. **Change only the link target, never the prose.** Keep display aliases: `[[new/path/File|Original Text]]`. Ledgers (`4. Decisions/`, `wiki/log.md`, `wiki/folds/`) included — pointer only.
+4. **Rescan from scratch and report that number**, not a tally of your edits.
+
+## 8. Log and hand off
+
+Append to `wiki/log.md`: `[build]` with a `Shipped:` line if the deliverable is a shipped thing, otherwise `[vault]`. Include `Released:` if any. Then suggest `cascade`.
+
+---
+
+## Output
+
+```
+## Close — ·
+
+done_when: "" — ✅ met / ⚠ met with correction (why)
+Deliverable → 2. Areas//knowledge/
+- — what the Area now knows
+Process → 5. Archive/// — N files incl. hub
+Area hub:
+Links repointed: N — rescan shows N dead (was N)
+Released: · or none
+
+Next: run cascade.
+```
+
+## Rules
+
+- **Verify done_when before anything moves.** Never rewrite it to fit.
+- **Split deliverable from process.** Ask only when genuinely unclear.
+- **Every migrated file carries its origin.**
+- **Never decrement the counter. Never reuse an ID.**
+- **Closing isn't reversible.** If it might resume, pause it.
+- **Only link targets change. Rescan and report the rescan.**
+- **`area: none` workstreams archive whole** — there's no knowledge base to receive a deliverable.
diff --git a/.agents/skills/orion-daily/SKILL.md b/.agents/skills/orion-daily/SKILL.md
new file mode 100644
index 0000000..d9370e1
--- /dev/null
+++ b/.agents/skills/orion-daily/SKILL.md
@@ -0,0 +1,145 @@
+---
+name: orion-daily
+description: "Close today's daily note in an Orion vault's 0. Inbox/ and write tomorrow's — or write a weekly sweep. The daily note: Focus, Since the last note, one section per workstream that owes something (where it stands · yours · waiting on · a Notes line), Loose, the open-questions manifest, People with what each is tied to, Standing. Carries unanswered questions with a plain-language count and forces a do-it-or-drop-it choice at the third ask. Hard cap 150 lines. The weekly sweep lists every Area, workstream, thread and person with one line each and room to write. Does not ingest — run orion-ingest first, orion-cascade after. Triggers on: daily note, tomorrow's note, close the day, weekly sweep, sweep note."
+---
+
+# orion-daily — the daily note and the weekly sweep
+
+`hot.md` says what's true. **The daily note says what only the owner can answer, and what's quietly drifting.** It is a working surface: the owner writes into it all day, `orion-ingest` files what they write, and this skill builds the next one.
+
+| | Daily note | Weekly sweep |
+|---|---|---|
+| **Job** | What's owed today and what's drifting | Everything tracked, one line each, room to write |
+| **Length** | 150 lines, hard | No cap — one line per item |
+| **File** | `0. Inbox/YYYY-MM-DD daily.md` | `0. Inbox/YYYY-MM-DD weekly-sweep.md` |
+| **Tag** | `daily-note` | `weekly-sweep` |
+| **Skeleton** | `6. Templates/daily-note.md` | `6. Templates/weekly-sweep.md` |
+
+**The usual sequence at close of day:** `ingest` → `daily note` → `cascade`.
+
+⛔ Fenced paths (`AGENTS.md`, *Fences*) are named, never read.
+
+---
+
+## Before anything: is the current note fully filed?
+
+Check every `>` line in the current note. **A question or `> Notes:` line with text after it and no `✓ filed` marker means ingest hasn't run. Stop and say so.** Generating a successor around unfiled text loses it.
+
+**If a hold is open** (`wiki/meta/holds.md`): don't generate a note unprompted. If asked, render no ages, don't increment ask counts, and say at the top that a hold is open and nothing is late.
+
+---
+
+## Daily note
+
+### 1. Read
+
+The current note and the last week of notes (current first) · every live `*_hub.md` · `3. Resources/People/` · `3. Resources/Threads/` · open decisions in `4. Decisions/` · `wiki/meta/open-questions.md` · `wiki/meta/holds.md` · `wiki/log.md` entries since the last note.
+
+### 2. Carry what wasn't answered
+
+For every `>` line in the current note:
+
+| State | Action |
+|---|---|
+| Answered, `✓ filed` | Done. Don't carry |
+| `> Notes:` with text, `✓ filed` | Done |
+| Blank question | **Carry it.** Increment its count |
+| Deferred ("not now", a date) | Carry with the date given |
+| Empty `> Notes:` | Ignore |
+
+**Every carried item says how many notes have asked it:** `asked 3 times since Jan 5`. **A blank is data, not a failure — never nag.**
+
+⚠ **At the third ask, the item becomes a forced choice: do it, or drop it.** Something carried three times isn't a task; it's a decision nobody has made. "Carry it again" is not an option.
+
+### 3. Gather state
+
+- **Sends and waits** from live hubs' `next:` — same ageing and hold rules as cascade.
+- **Workstreams:** ⚠ **an `open` workstream gets a section only when something is owed on it today, the owner worked on it, or something external moved it.** Listing every open workstream daily is a nag list. The weekly sweep lists all of them.
+- **People:** relationship tier — overdue, due today, due within 7 days — **and for each, what they're tied to** (a workstream, a send, a thread), read from their page and the hubs that name them. Never inferred. Spent follow-ups compute a live date → `_contracts.md`.
+- **Open questions:** the full register.
+
+### 4. Surface something — only if it's real
+
+One to three findings from the vault that sit on no tracked list: two blocked items that are really one conversation · a person best placed to answer a question nobody asked them · a claim asserted and never verified · a follow-up pointing at work that has closed. Put each inside the workstream it concerns, or under `## Loose`.
+
+**If nothing qualifies, surface nothing.** Padding teaches the owner to skim the one part worth reading.
+
+### 5. Write it
+
+Sections, in order:
+
+1. **`## Focus`** — what today is about. Three lines, no lists.
+2. **`## Since the last note`** — up to five bullets. Omit if nothing changed.
+3. **One `##` per workstream that owes something** — the owner's own work first, then work waiting on others:
+
+ ```markdown
+ ## WEB-3 · Pricing Page — quote owed to the designer
+
+ **Where it stands:** one or two plain sentences. → [[|hub]]
+
+ **Yours:**
+ - [ ] Send Sam the revised quote — 6 days, asked twice since Jan 5
+
+ **Waiting on:** Sam Example — copy review, 3 days · or nobody
+
+ > Notes:
+ ```
+
+ The heading is **ID · Name — what is actually owed**. `Where it stands`, `Yours` and `Waiting on` always appear. Every workstream section ends with `> Notes:`.
+4. **`## Loose`** — real items belonging to no single workstream, one `###` each, each ending `> Notes:`. Omit if empty.
+5. **`## Open questions — N live`** — every live question from the register, numbered, `- [ ]` where the owner can close it. Every note.
+6. **`## People`** — `N armed · N overdue · N defects`, then Overdue (oldest first) and Due in the next 7 days, each with what they're tied to. **Say plainly when a follow-up points at closed work.** Every note — "nobody is due" is an answer.
+7. **`## Standing`** — holds, structural facts. Three lines max.
+
+### Question blocks — three tests
+
+A `> **Question?**` block is how the owner answers things. Every block must pass all three:
+
+1. **Is it the owner's to decide?** If you can act, act.
+2. **Does anything change based on the answer?** If both answers lead to the same action, there's no question.
+3. **Is the premise still live?**
+
+**If you can't write the question, there isn't one.** Keep the finding, drop the block. `> Notes:` lines aren't questions and are exempt.
+
+### Format
+
+- **Plain language.** `asked 3 times since Jan 5`, `19 days`, `12 days overdue (Jan 3)`. Only `✓ filed` and IDs stay machine-shaped.
+- Real `##`/`###` headings for every section — they're how the note is navigated and collapsed.
+- **Bold** for the decision point and the three labels. At most two or three ⚠ in the whole note.
+- **Don't reproduce `hot.md`'s tables.** A send named inside its own workstream is context, not restatement.
+- **150 lines, hard.** Cut in this order: context the owner already knows · prose restating a question · *Since the last note* to three bullets · surfaced findings beyond the strongest two.
+
+### 6. Retire the old note
+
+**Only after the new note exists on disk**, move the old one to `0. Inbox/processed/YYYY-MM/`. Refuse, and say why, if any line is unfiled or the successor wasn't written. **This skill is the only thing that retires a daily note.**
+
+---
+
+## Weekly sweep
+
+On request (`weekly sweep`), or offered in `## Standing` when a week has passed since the last one. **Never auto-generated.**
+
+**Everything, one line each**, from `6. Templates/weekly-sweep.md`:
+
+- **Every standing Area**, with **every workstream** under it — open and paused, status named. Fenced Areas named with no contents.
+- **Every thread.**
+- **Every person:** relationship tier individually, with what they're tied to · **Released** — relationship-tier people named on a `Released:` line in `wiki/log.md` since the last sweep (written by `orion-close`/`orion-archive`), or whose follow-up points only at closed work · contacts grouped by Area, one line each (`Unplaced` for people tied to nothing live).
+- **A `> Notes:` line under every workstream and thread**, and one per contact group.
+- **The open-questions manifest.**
+
+A checkbox means **reviewed**, not a task. A ticked box with no note means nothing changed. **Tier and follow-up dates are the owner's call** — the sweep lists, it doesn't change them.
+
+**Retiring a sweep:** when the next sweep is generated or the owner says it's done — and only once every Notes line with text is `✓ filed`.
+
+---
+
+## Rules
+
+- **Never generate a successor around unfiled text.**
+- **Blank is data. Carry it, count it, never nag. Three asks forces do-it-or-drop-it.**
+- **Workstream sections: Where it stands · Yours · Waiting on · Notes.** Same shape every time.
+- **People lines say what each person is tied to.**
+- **Surfaced findings are real or absent.**
+- **150 lines for the daily note.** One line per item for the sweep.
+- **An open hold suppresses every age and freezes ask counts.**
+- **Doesn't ingest, doesn't cascade.** Only this skill retires a daily note or sweep.
diff --git a/.agents/skills/orion-fold/SKILL.md b/.agents/skills/orion-fold/SKILL.md
new file mode 100644
index 0000000..025c2eb
--- /dev/null
+++ b/.agents/skills/orion-fold/SKILL.md
@@ -0,0 +1,72 @@
+---
+name: orion-fold
+description: "Roll up the oldest 2^k entries of an Orion vault's wiki/log.md into a fold page in wiki/folds/, moving the entries verbatim and leaving one pointer line, so the log stays cheap to read. Dry-run by default; writes only on --commit. Run when cascade reports more than 16 unfolded entries. Triggers on: fold the log, run a fold, log rollup, roll up the log."
+---
+
+# orion-fold — subtractive log rollup
+
+The log is append-only, so it grows forever. A fold **moves** the oldest entries into a fold page — verbatim, lossless — and leaves one pointer line behind. Entries are never edited or deleted; they live one file over.
+
+**When:** `orion-cascade` prints `Log: N / 16` every run. Over 16 → a fold is due. Default `k=4` (16 entries).
+
+## Parameters
+
+- `k` (default 4) — batch size `2^k`.
+- `--commit` — write. **Without it, dry-run: print the fold, write nothing.**
+
+Fewer than `2^k` unfolded entries → report the shortfall and stop.
+
+## Entry format
+
+An entry is everything from one `^## YYYY-MM-DD` heading to the next. The log is newest-first, so **the oldest entries are at the bottom.** A heading containing `[folded]` is a pointer, not an entry.
+
+## Fold ID
+
+`fold-k{K}-from-{EARLIEST}-to-{LATEST}-n{COUNT}` — e.g. `fold-k4-from-2026-01-02-to-2026-01-30-n16`. **If `wiki/folds/.md` exists, stop.**
+
+## Procedure
+
+1. **Select the oldest `2^k` unfolded entries** — from the bottom up.
+2. **Self-check (blocking):**
+ - **No unfolded entry sits below your span.** If one does, you've picked a middle window — a hole later folds will never revisit. Re-pick.
+ - Every selected entry was located exactly (date + title). **Never remove an entry you didn't positively match** — leave it and report.
+ - Every numeric claim you'll write is present in a child entry.
+3. **Write the fold page** (`wiki/folds/.md`):
+
+ ```yaml
+ ---
+ type: fold
+ fold_id:
+ entry_count: N
+ entry_range: {from: YYYY-MM-DD, to: YYYY-MM-DD}
+ created: YYYY-MM-DD
+ tags: [meta, fold]
+ ---
+ ```
+
+ Sections:
+ 1. **Scope** — one paragraph: period and dominant themes.
+ 2. **Entries** — table `Date | Title | One-sentence summary`.
+ 3. **Key outcomes** — 3–7 bullets, each citing its entry's date.
+ 4. **Cross-entry themes** — 0–4 bullets, each naming ≥2 entries, or "None".
+ 5. **Contradictions or corrections** — or "None detected".
+ 6. **Entries — verbatim** — the moved entries in full, headings demoted `##` → `###`, otherwise untouched.
+
+ **Extractive only.** Nothing that isn't in the entries.
+4. **Dry-run:** print the page and what commit would do. Stop.
+5. **On `--commit`:**
+ 1. Write the fold page.
+ 2. Remove the folded entries from `log.md`; where the newest of them sat, leave:
+ `## {TO} — [folded] {N} entries ({FROM} to {TO}) → [[wiki/folds/{ID}|{ID}]]`
+ 3. Add the fold to `## Folds` in `wiki/index.md`.
+ 4. Prepend a log entry: `## {TODAY} — [vault] Log fold: {N} entries ({FROM} to {TO})`, with log line count before → after.
+6. **Reconcile:** entries remaining in `log.md` + entries in all fold pages = entries before. If it doesn't balance, stop and report.
+
+## Rules
+
+- **Dry-run by default.** Write only on `--commit`.
+- **Subtractive and lossless** — entries move verbatim; never edited, never deleted.
+- **Oldest first, verified.** No unfolded entry below the span.
+- **Never remove what you didn't positively match.**
+- **Extractive only.**
+- **Reconcile before finishing.**
diff --git a/.agents/skills/orion-ingest/SKILL.md b/.agents/skills/orion-ingest/SKILL.md
new file mode 100644
index 0000000..8ec4c4c
--- /dev/null
+++ b/.agents/skills/orion-ingest/SKILL.md
@@ -0,0 +1,101 @@
+---
+name: orion-ingest
+description: "Bring external material into an Orion vault's numbered folders — every capture sitting in 0. Inbox/ by default, or a file, transcript, or document the owner names. Follows any instructions in the source, classifies the rest (asking only when genuinely unclear), records provenance, creates and updates pages directly, cross-links them, marks answered lines in daily notes as filed, and archives processed captures. Distinct from orion-cascade, which syncs wiki/ with what's already in the folders. Triggers on: ingest, process the inbox, ingest this, file this."
+---
+
+# orion-ingest — bring material into the vault
+
+Ingest turns raw capture into filed, cross-linked, attributed vault content. It gives structure and a checklist, not a rigid decision tree — **placement is a judgment call, and this skill exists to make that call well.**
+
+**Ingest before cascade.** Ingest fills the numbered folders; cascade then syncs `wiki/`.
+
+---
+
+## 1. Identify the source
+
+Default: every file at the root of `0. Inbox/` (not in `processed/`). Or: whatever the owner names — a file path, pasted text, a transcript.
+
+⛔ Never read a path listed under *Fences* in `AGENTS.md`.
+
+## 2. Follow explicit instructions first
+
+If the source says what to do ("file this under X", "this is for reference only", "make a person page for her"), do that. Don't re-derive a classification the source already gave you.
+
+## 3. Classify the rest
+
+| Content | Destination |
+|---|---|
+| A decision was made | `4. Decisions/YYYY-MM-DD-.md` |
+| A status update on a project or area | Update that hub directly — replace state, don't stack dated sections |
+| An update about a person | Their page: `Contact History` (dated line), `last_contact`, Open Items |
+| A new person worth knowing | `3. Resources/People/.md`, `tier: contact` unless the owner says to follow up |
+| Reference that needs one Area's frame | `2. Areas//knowledge/` |
+| Reference that holds anywhere | `3. Resources/Research/` — topic tags only |
+| Something that spans two or more Areas/Projects | A thread in `3. Resources/Threads/`, or an update to an existing one |
+| Finite new work | Suggest `new project:` — creation goes through `orion-instantiate` |
+| A binary (PDF, deck, image, spreadsheet) | **Not into the vault.** It stays in the file system; the vault gets a reference note of what it says, attributed, with the file path |
+
+**When it is genuinely unclear which row applies, ask.** That is the one checkpoint that stops execution. Everything else runs directly — no dry run, no confirmation gate.
+
+## 4. Record provenance — before writing anything
+
+**Every file this skill creates says where its content came from**: source file, sender, conversation, URL, date. If unknown: *"source unrecorded"* — never blank.
+
+**Attribute, don't assert.** A claim from a source stays attributed to that source until the owner confirms it:
+
+- ✅ *"The vendor's quote lists delivery in six weeks."*
+- ❌ *"Delivery is in six weeks."*
+
+**Never let an unconfirmed claim reach a hub bullet, `hot.md`, or `log.md` unattributed.** Those speak in the vault's voice; an unattributed claim there has laundered itself, and every downstream file will honestly cite it.
+
+## 5. Write and cross-link
+
+Create and edit directly. **Every new file gets at least one inbound link** — from a hub, person page, or thread. A new file with no inbound link is an orphan this skill created.
+
+If a name in the source matches the *Never use* column of `AGENTS.md`'s vocabulary table, write the canonical form. Quote the source's spelling only when quoting it verbatim.
+
+## 6. Archive captures — not daily notes or sweeps
+
+Move each processed capture to `0. Inbox/processed/YYYY-MM/` (year first — e.g. `processed/2026-01/`). **Never delete** — the capture is the record of what came in and when.
+
+⚠ **Never archive a file tagged `daily-note` or `weekly-sweep`.** Those are working surfaces the owner writes into all day. File their contents and leave them in place — only `orion-daily` retires them, once a successor exists.
+
+### Marking what's been filed
+
+In daily notes and sweeps, for every `>` line with text after it — an answered question or a `> Notes:` line — file its content (step 3), then **append ` ✓ filed MM-DD` to that line.**
+
+- Skip lines already marked. That makes repeat runs safe.
+- An empty `> Notes:` or blank question is not a failure — ignore it.
+- In a sweep, a ticked box with no note means "reviewed, nothing changed." Nothing to file.
+
+`orion-daily` reads these markers to decide what carries forward, and refuses to retire a note with unfiled text.
+
+## 7. Output
+
+```
+## Ingest — YYYY-MM-DD
+
+Source:
+
+Created:
+- — one line
+
+Updated:
+- [[Page]] — what changed
+
+Filed in notes: N lines marked ✓
+Archived: N captures → 0. Inbox/processed/YYYY-MM/
+
+Asked / flagged:
+
+Next: run cascade.
+```
+
+## Rules
+
+- **Instructions in the source win** over the table.
+- **Classification ambiguity is the only thing that stops execution.**
+- **Every created file records provenance.** Unknown → "source unrecorded".
+- **Attribute, don't assert.** Unconfirmed claims never reach summary layers unattributed.
+- **Cross-link on creation.**
+- **Archive captures, never delete.** Never archive a daily note or sweep.
diff --git a/.agents/skills/orion-instantiate/SKILL.md b/.agents/skills/orion-instantiate/SKILL.md
new file mode 100644
index 0000000..fa8099b
--- /dev/null
+++ b/.agents/skills/orion-instantiate/SKILL.md
@@ -0,0 +1,91 @@
+---
+name: orion-instantiate
+description: "Create a Project (workstream) or Area in an Orion vault against its frontmatter contract. Runs the done-when test first, assigns the workstream ID from the Area's counter, seeds the Area's knowledge/ folder, and registers the new hub so it is never an orphan. Also converts a Project that turns out to be an Area. Triggers on: new project, new area, new workstream, create project, create area, instantiate, this should be an area."
+---
+
+# orion-instantiate — create a Project or Area
+
+Creation is where most structural defects start: a hub with no done-when never finishes, a hub with no Area can never be measured against anything, and a hub nobody links to is an orphan from day one. This skill makes creation follow the contract in `6. Templates/_contracts.md` instead of copying a template and hoping.
+
+---
+
+## 1. The test — before anything else
+
+| Question | If yes |
+|---|---|
+| Can you write **"this is done when ___"** in one sentence, right now? | **Project** |
+| Is the honest answer **"it's never done"**? | **Area** |
+| Neither, but facts and people attach to it? | **Resource or person page — not a hub.** Stop here |
+
+⚠ **If the done-when needs "ongoing", "maintain", or "as needed", it is not a Project.** It is an Area, or a task inside one.
+
+If the owner hasn't given a done-when and you can't derive one from what they said, ask for it. **No done-when, no Project.**
+
+---
+
+## 2. Creating an Area
+
+1. Folder: `2. Areas//` (Title Case, spaces).
+2. Hub: `_hub.md` from `6. Templates/area-hub.md`:
+ - `type: area`, `status: standing`
+ - `id_prefix:` — short, uppercase, unambiguous, **not already used by another Area** (grep every `*_hub.md` for `id_prefix:`). Permanent once set.
+ - `workstream_counter: 0`
+ - `parent:` only if nested, and **never pointing at itself.**
+3. **Seed `knowledge/_index.md`** — the Area's permanent memory. State in two or three lines what belongs here (durable material that needs this Area's frame to make sense) and what doesn't (reusable-anywhere material → `3. Resources/Research/`; process notes → the workstream). **This is the step that gets skipped.** Without an obvious home, knowledge scatters.
+4. Pick an Area tag (lowercase-kebab) and register it in `wiki/meta/tags.md`.
+
+## 3. Creating a Project (workstream)
+
+1. **Pick its Area.** Default: every Project has one. If it genuinely has none, write `area: none` explicitly — absent is indistinguishable from an oversight. ⚠ An `area: none` Project has no counter to draw an ID from: use prefix `X` with the next number not used by any hub in `1. Projects/` or `5. Archive/`, and tell the owner its deliverable will archive whole on close.
+2. **Assign the ID — read the counter, never scan for it.**
+ 1. Read `workstream_counter:` on the Area hub.
+ 2. Increment it and **write the new value back first.**
+ 3. `id: -`.
+
+ ⚠ **Scanning existing hubs for the highest ID collides.** Closed projects have moved to `5. Archive/`, so a scan of `1. Projects/` sees a lower maximum than was issued. The counter persists; the hubs don't. **IDs are never reused.**
+3. Folder: `1. Projects///`. Hub: `_hub.md` from `6. Templates/project-hub.md`.
+4. Frontmatter: `type: project` (never `hub`), `id`, `area`, `done_when` (**the sentence verbatim**, not a paraphrase), `status: open`, `updated`, `tags: [hub, ]`. Add `next:` if a first move is known.
+
+## 4. Register — part of creation, not after it
+
+- [ ] **Project:** listed on its Area hub under `## Workstreams` with its ID and status
+- [ ] **Project:** Area's `workstream_counter:` incremented
+- [ ] **Area:** tag in `wiki/meta/tags.md`; `knowledge/_index.md` seeded
+- [ ] At least one inbound link (Area hub → Project; `wiki/index.md` → Area)
+- [ ] Suggest `cascade` — structure changed
+
+---
+
+## Converting a Project that turns out to be an Area
+
+A Project that fails the done-when test isn't finished — it was misfiled. **Ask the owner before converting; it is a change, not a repair.**
+
+1. **Correct the hub first.** Converting a hub with false statements relocates them.
+2. **Route everything in a table in the hub:** each task or sub-effort → done (history) · ongoing (Area open item) · has a real done-when (its own new Project with an ID) · dead (closed, reason stated).
+3. Move the folder to `2. Areas//`, rename the hub `_hub.md`, set `type: area`, `status: standing`.
+4. ⚠ **Give it `id_prefix:` and `workstream_counter: 0` now.** Conversion is the one path into Area-hood that skips the creation contract; an Area without a counter can never spawn a workstream, and nothing reports it.
+5. Seed `knowledge/_index.md`. Repoint inbound links (see `orion-close` step 6 for method). Log it. Cascade.
+
+---
+
+## Output
+
+```
+## Instantiate —
+
+Done-when: "" (Projects)
+Created:
+ID: - — counter now (Projects)
+Registered:
+
+Next: run cascade.
+```
+
+## Rules
+
+- **Done-when test first.** No sentence, no Project.
+- **`type:` is `project` or `area`. Never `hub`.**
+- **Read the counter, write it back, then use it.** Never derive IDs by scanning. Never reuse one.
+- **`area: none` is legal but written.** Absent ≠ none.
+- **Every Area gets `id_prefix`, `workstream_counter` and `knowledge/`** however it came into being.
+- **Register on creation.** An unregistered hub is an orphan.
diff --git a/.agents/skills/orion-lint/SKILL.md b/.agents/skills/orion-lint/SKILL.md
new file mode 100644
index 0000000..c58a7b0
--- /dev/null
+++ b/.agents/skills/orion-lint/SKILL.md
@@ -0,0 +1,134 @@
+---
+name: orion-lint
+description: "Health-check an Orion vault: dead links, orphans, frontmatter and workstream-contract gaps, people-tier defects, unsourced reference material, vocabulary violations, misplaced files, stale holds, and an overdue log fold. Flags only — never auto-fixes. Writes exactly one wiki/meta/lint-report-YYYY-MM-DD.md stamped with the git commit it describes; the previous report is archived. Triggers on: lint, health check, audit the vault, check the vault, find orphans, find dead links."
+---
+
+# orion-lint — vault health check
+
+**Flags only.** Lint reports; the owner or the next session decides. (Repairs lint surfaces may then be made under the *Repair* rule in `AGENTS.md`.)
+
+⛔ Fenced paths (`AGENTS.md`, *Fences*) are excluded from every check. Links *into* them are checked for existence only.
+
+---
+
+## Scope — two kinds of check
+
+**The test:** *would this finding stop being true if nobody ever worked on this file again?*
+
+| | Answer | Scope |
+|---|---|---|
+| **Attention** | Yes — it's "this needs someone's attention" | **Skip** `paused`/`closed`/`archived` hubs and everything under `5. Archive/` |
+| **Integrity** | No — it's "this is broken" | **Run vault-wide, `5. Archive/` included** |
+
+A blanket archive skip on an integrity check hides broken links behind a clean report. Every new check classifies itself before it's written.
+
+**Run every check mechanically** — glob and grep actual file contents, resolve every candidate. A finding produced by reading a sample and generalising is a hypothesis, not a finding. **Spot-check anything surprising** (a large round number, a well-known file reported broken) before it goes in the report.
+
+**Stamp the tree:** record `git rev-parse --short HEAD` if the vault is a git repo, and say at the top if the working tree is dirty.
+
+---
+
+## Integrity checks — vault-wide
+
+**1. Dead links.** Every `[[target]]` / `[[target|alias]]` that resolves to no file. Strip fenced code blocks and inline code first — documentation examples aren't links. Resolve against full path, then bare filename anywhere in the vault. Report archive findings under their own heading.
+
+**2. Link style.** Links containing `.md` (`[[file.md]]`).
+
+**3. Frontmatter contract.** Against `6. Templates/_contracts.md`:
+- Every file below `0. Inbox/` root in the numbered folders: `type`, `updated` (`4. Decisions/` uses `date`).
+- Hubs: `type` is `project` or `area` (**`hub` is a defect**) · `status` in the vocabulary.
+- Projects: `id`, `area` (value or literal `none`), `done_when` non-empty · `paused_because` when paused · hub filename is `_hub.md`.
+- Areas: `id_prefix`, `workstream_counter` · `parent` never equals the Area's own name.
+- Decisions: `date`, `topic`, `status`. Threads: `status`, `opened`.
+- **Exempt:** `AGENTS.md`, `CLAUDE.md`, `README.md` and other vault-root files · `6. Templates/` · `0. Inbox/` notes (they use `date` + `tags`, no `type`).
+- **Before reporting a missing field, check whether any file in that folder has ever carried it.** A field absent from every file is a convention, not a set of defects.
+
+**4. ID integrity.** For each Area, every issued ID `-N` (in `1. Projects/` and `5. Archive/`) has `N ≤ workstream_counter`. Any duplicate ID anywhere is a defect.
+
+**5. Provenance.** Every `type: reference` file has a non-empty `source:` (or "source unrecorded" in the body). Report path and line count. **Never auto-fixable** — the owner confirms or strikes the source.
+
+**6. Vocabulary.** For each row of `AGENTS.md`'s vocabulary table, grep the *Never use* forms in vault-voice prose. Exempt: the table itself, lint reports, `open-questions.md`, `0. Inbox/processed/`, and verbatim quotes of a source. **If both the banned and canonical forms have zero hits, report the row itself as suspect** — the table is data to be tested, not the test. **An ordinary English word can only be enforced inside a scope the row names**; if a row's scope can't be determined mechanically, report the row as unenforceable instead of its hits.
+
+**7. Stale index entries.** Links in `wiki/index.md` or `wiki/hot.md` pointing at files that moved or don't exist.
+
+## Attention checks — live material only
+
+**8. Orphans.** A file in the numbered folders with no inbound `[[link]]` from any other page. Collect every link target vault-wide (including archived hubs as *sources*), then test each candidate by full path and bare name. Also count backtick-quoted paths as references — report those separately as *"referenced by path, not linked"*. **Exempt:** hubs · `4. Decisions/` · `3. Resources/Research/` root · `6. Templates/` · `0. Inbox/` · `5. Archive/` · vault-root files.
+
+**9. People tiers.**
+- `tier: relationship` without `cadence` or `follow_up_by` → **defect** (it can never flag).
+- `tier: contact` carrying `cadence` or `follow_up_by` → defect.
+- A spent `follow_up_by` (on or before `last_contact`) is **not** a defect.
+- An `organic` page whose `follow_up_by` has been pushed repeatedly with no contact (check git history if available) → finding: that's a cadence that never fires.
+
+**10. `next:` validity.** Each entry uses `send`/`wait`/`build`/`decide`; `send`/`wait` name a person. **Report every `send`/`wait` older than 14 days at the very top of the report**, above every structural finding — an unsent message is worth more than all of them.
+
+**11. Misplaced files.** Hubs outside `1. Projects/`/`2. Areas/` · person pages outside `People/` · decisions outside `4. Decisions/` · content files in `wiki/` other than `hot.md`, `index.md`, `log.md`, `folds/*`, `meta/*` · binaries (pdf, images, office files) anywhere in the vault · a file in `3. Resources/Research/` root carrying an Area tag · reference material inside a Project folder with no Area tag.
+
+**12. Standalone Areas.** A standing Area with no live Project and `updated:` older than 30 days. Report as context — it may be quiet on purpose.
+
+**13. Holds.** An open hold older than 30 days with no end date · an open hold with no start date older than 7 days. **A hold never discharges an obligation** — report open sends alongside it.
+
+**14. Log fold.** Unfolded entries (headings minus `[folded]` pointers) against the threshold of 16 — **print the count every run**. Also: any unfolded entry sitting *below* a `[folded]` pointer is a hole from a middle-window fold.
+
+---
+
+## Report — `wiki/meta/lint-report-YYYY-MM-DD.md`
+
+**Retention 1.** Before writing, move any previous lint report to `5. Archive/wiki-meta/`.
+
+```markdown
+---
+type: meta
+title: "Lint report YYYY-MM-DD"
+created: YYYY-MM-DD
+commit: abc1234
+tree_clean: true
+supersedes: lint-report-YYYY-MM-DD
+tags: [meta, lint]
+---
+
+## Outstanding sends — before anything structural
+## Summary ← one line per check: count, or "clean"
+## Dead links
+### Inside 5. Archive/
+## Frontmatter & contracts
+## IDs
+## Provenance
+## Vocabulary
+## Orphans
+## People
+## Misplaced files
+## Areas & holds
+## Log ← "unfolded: N / 16" — always printed
+## Carried findings — second cycle
+```
+
+Omit empty sections except Summary and Log.
+
+## The two-cycle rule
+
+**A finding that survives two consecutive lints without action is a decision nobody has made.** Second appearance: list it under *Carried findings*. Third: **remove it from the report** and add it to `wiki/meta/open-questions.md` as a forced binary — `**** — Option A / Option B. Raised YYYY-MM-DD.` Then stop reporting it.
+
+**Corollary — the more important half: when a check keeps producing the same backlog, suspect the check.** A rule nobody ever acts on is usually wrong, not ignored.
+
+## Output (to chat)
+
+```
+## Lint — YYYY-MM-DD @
+
+Sends > 14 days: N
+Integrity: N dead links (N in archive) · N contract gaps · N provenance · N vocabulary
+Attention: N orphans · N people defects · N misplaced
+Log: N / 16
+Report: wiki/meta/lint-report-YYYY-MM-DD.md
+```
+
+## Rules
+
+- **Flags only. No auto-fix.**
+- **Attention checks skip retired material; integrity checks run everywhere.**
+- **Mechanical, exhaustive, spot-checked.** Never estimate.
+- **Sends outrank structure.**
+- **One report at a time, stamped with its commit.**
+- **Two-cycle rule — and question the check before the files.**
diff --git a/.claude/skills b/.claude/skills
new file mode 120000
index 0000000..2b7a412
--- /dev/null
+++ b/.claude/skills
@@ -0,0 +1 @@
+../.agents/skills
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b3bcb89
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.obsidian/workspace*.json
+.DS_Store
diff --git a/0. Inbox/processed/.gitkeep b/0. Inbox/processed/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/1. Projects/.gitkeep b/1. Projects/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/2. Areas/.gitkeep b/2. Areas/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/3. Resources/Outbox/.gitkeep b/3. Resources/Outbox/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/3. Resources/People/.gitkeep b/3. Resources/People/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/3. Resources/Research/.gitkeep b/3. Resources/Research/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/3. Resources/Threads/.gitkeep b/3. Resources/Threads/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/4. Decisions/.gitkeep b/4. Decisions/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/5. Archive/.gitkeep b/5. Archive/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/6. Templates/_contracts.md b/6. Templates/_contracts.md
new file mode 100644
index 0000000..9ce7b52
--- /dev/null
+++ b/6. Templates/_contracts.md
@@ -0,0 +1,158 @@
+---
+type: reference
+title: "Page contracts"
+tags:
+ - reference
+---
+
+# Page contracts
+
+**Read this when creating or editing a page.** The `.md` files beside this one are copy-ready skeletons; this file is the rule they implement. **When a contract changes, change its skeleton in the same edit** — a skeleton that drifts from its contract produces pages the skills can't read.
+
+---
+
+## Area hub — `2. Areas//_hub.md`
+
+```yaml
+type: area
+status: standing # standing | archived
+id_prefix: WEB # short, uppercase, set once, never changed
+workstream_counter: 0 # highest ID issued. Source of truth for IDs
+parent: # nested Areas only. Never points at itself
+updated: YYYY-MM-DD
+tags: [hub, ]
+```
+
+Body: `## What this is` (one sentence) · `## Workstreams` (each Project by ID, with status) · `## Open items` · `## Key files` · `## People`.
+
+**Areas take no `next:`, no `deadline:`, and no freshness computation.** A container doesn't compete for attention.
+
+Every Area has `2. Areas//knowledge/_index.md` — seeded at creation, stating what belongs there.
+
+---
+
+## Project hub — `1. Projects///_hub.md`
+
+```yaml
+type: project # never `hub`
+id: WEB-1 # from the Area's workstream_counter
+area: # or the literal `none` — absent ≠ none
+done_when: "one sentence, testable"
+status: open # open | paused | closed | archived
+next: "verb → target — detail [since YYYY-MM-DD]" # optional; may be a YAML list
+paused_because: "one line" # required when paused
+deadline: YYYY-MM-DD # optional — the single next delivery gate
+threads: [slug]
+updated: YYYY-MM-DD
+tags: [hub, ]
+```
+
+Body: `## What this is` · `## Tasks` (checkboxes, `(owned by: name)` when not the owner's) · `## Open items` · `## Key files` · `## People`.
+
+- **`done_when:` is required.** If you can't write it, it isn't a Project. If it needs the words "ongoing", "maintain" or "as needed", it's an Area.
+- **`next:` — one move per entry.** Two moves go in a YAML list, never packed into one string. Grammar and verbs → `AGENTS.md`, *The `next:` field*.
+- **`area: none` is legal but must be written.** Such a project has no knowledge base to receive its deliverable; `orion-close` archives it whole.
+
+**A workstream *is* a Project.** It opens when an Area needs finite work done, and closes via `orion-close`, which returns its deliverable to the Area:
+
+```
+Area ──spawns──▶ Project (id, done_when)
+ ▲ │ on close
+ └── knowledge/ ◀───┤ deliverable
+ └── process record ──▶ 5. Archive///
+```
+
+A workstream belongs to exactly one Area. A concern spanning several is a **thread**.
+
+---
+
+## Person — `3. Resources/People/.md`
+
+```yaml
+type: person
+tier: contact # relationship | contact
+name: Full Name
+pronouns: # ask; never infer from a name. Blank until known
+role:
+orgs: []
+contact:
+status: active # active | dormant
+cadence: # relationship tier ONLY: weekly | biweekly | monthly | organic
+last_contact: YYYY-MM-DD
+follow_up_by: # relationship tier ONLY — a real date
+updated: YYYY-MM-DD
+tags: [person]
+```
+
+Body: `## Role & Relationship` · `## Background` · `## Context` · `## Open Items` · `## Contact History` (dated lines, newest first).
+
+**Two tiers, and only one can flag:**
+
+| Tier | Carries | Can flag? |
+|---|---|---|
+| `relationship` | `cadence` + `follow_up_by`, both required | **Yes** — the only pages follow-up checks read |
+| `contact` | Neither — their presence is a lint finding | **Never** |
+
+**A contact is not a neglected relationship.** It's someone the vault knows facts about. If someone doesn't warrant a real follow-up date, they're a contact.
+
+- **`organic` cadence** means "no fixed interval — the next contact is pegged to a specific event." It still requires a real `follow_up_by`, set against that event.
+- **A relationship page with no `follow_up_by` cannot flag and is invisible.** Lint reports it as a defect.
+- **Spent follow-ups.** A `follow_up_by` on or before `last_contact` has been overtaken by contact. Compute the live due date instead: `weekly`/`biweekly`/`monthly` → `last_contact` + 7/14/30 days, rendered *(from last contact)*; `organic` → **no date since contact** (never overdue). **Never write the computed date back** — the stored field stays what a person set.
+- **`status: dormant`** — the engagement ended; the page and every fact stay.
+
+---
+
+## Decision — `4. Decisions/YYYY-MM-DD-.md`
+
+```yaml
+type: decision
+date: YYYY-MM-DD
+topic: Short title
+areas: [Area or Project]
+status: open # open | closed | reversed
+updated: YYYY-MM-DD
+tags: [decision]
+```
+
+Body: `## Context` · `## Decision` · `## Rationale` · `## Expected outcome` · `## Follow-up` (dated lines).
+
+**Never edit a past decision's substance.** A reversal is a new decision file that links the old one; the old one's `status` becomes `reversed`.
+
+---
+
+## Thread — `3. Resources/Threads/.md`
+
+```yaml
+type: thread
+title: Short title
+status: open # open | watching | resolved | dropped
+domains: [Area or Project]
+people: [Full Name]
+opened: YYYY-MM-DD
+updated: YYYY-MM-DD
+tags: [thread]
+```
+
+Body: `## What it is` · `## Why cross-cutting` · `## Current state` (replace, don't stack) · `## What's needed` · `## Update log` (append-only, newest first).
+
+**A thread opens** when one signal shows up in two or more separate Areas or Projects. **It closes** when a decision resolves it, or it collapses to a single domain. Resolved and dropped threads move to `5. Archive/Threads/`.
+
+---
+
+## Reference note — `3. Resources/Research/` or `2. Areas//knowledge/`
+
+```yaml
+type: reference
+title:
+source: # file, URL, sender, conversation — or "source unrecorded"
+updated: YYYY-MM-DD
+tags: [reference, ]
+```
+
+**`source:` is never blank.** Placement → `AGENTS.md`, *The classification test*.
+
+---
+
+## Inbox notes
+
+Daily notes and weekly sweeps carry `date:` and `tags: [inbox, daily-note]` / `[inbox, weekly-sweep]` — no `type:`. Captures carry `date:` and `tags: [inbox]`.
diff --git a/6. Templates/area-hub.md b/6. Templates/area-hub.md
new file mode 100644
index 0000000..dc0f219
--- /dev/null
+++ b/6. Templates/area-hub.md
@@ -0,0 +1,22 @@
+---
+type: area
+status: standing
+id_prefix:
+workstream_counter: 0
+parent:
+updated: YYYY-MM-DD
+tags:
+ - hub
+---
+
+#
+
+## What this is
+
+## Workstreams
+
+## Open items
+
+## Key files
+
+## People
diff --git a/6. Templates/daily-note.md b/6. Templates/daily-note.md
new file mode 100644
index 0000000..c912f9a
--- /dev/null
+++ b/6. Templates/daily-note.md
@@ -0,0 +1,52 @@
+---
+date: YYYY-MM-DD
+tags:
+ - inbox
+ - daily-note
+---
+RE: — [[]]
+
+## Focus
+
+
+
+## Since the last note
+
+-
+
+## · —
+
+**Where it stands:** → [[|hub]]
+
+**Yours:**
+- [ ] —
+
+**Waiting on:** · or nobody
+
+> Notes:
+
+## Loose
+
+### -
+
+
+
+> Notes:
+
+## Open questions — live
+
+- [ ] . **** —
+
+## People
+
+** armed · overdue · defects**
+
+**Overdue**
+- — () —
+
+**Due in the next 7 days**
+- — —
+
+## Standing
+
+-
diff --git a/6. Templates/decision.md b/6. Templates/decision.md
new file mode 100644
index 0000000..a21fcd6
--- /dev/null
+++ b/6. Templates/decision.md
@@ -0,0 +1,24 @@
+---
+type: decision
+date: YYYY-MM-DD
+topic:
+areas: []
+status: open
+updated: YYYY-MM-DD
+tags:
+ - decision
+---
+
+#
+
+## Context
+
+## Decision
+
+## Rationale
+
+## Expected outcome
+
+## Follow-up
+
+- YYYY-MM-DD:
diff --git a/6. Templates/person.md b/6. Templates/person.md
new file mode 100644
index 0000000..5b4595b
--- /dev/null
+++ b/6. Templates/person.md
@@ -0,0 +1,32 @@
+---
+type: person
+tier: contact
+name:
+pronouns:
+role:
+orgs: []
+contact:
+status: active
+cadence:
+last_contact:
+follow_up_by:
+updated: YYYY-MM-DD
+tags:
+ - person
+---
+
+#
+
+## Role & Relationship
+
+## Background
+
+## Context
+
+## Open Items
+
+- [ ]
+
+## Contact History
+
+- YYYY-MM-DD:
diff --git a/6. Templates/project-hub.md b/6. Templates/project-hub.md
new file mode 100644
index 0000000..c688df7
--- /dev/null
+++ b/6. Templates/project-hub.md
@@ -0,0 +1,28 @@
+---
+type: project
+id:
+area:
+done_when: ""
+status: open
+next:
+paused_because:
+deadline:
+threads: []
+updated: YYYY-MM-DD
+tags:
+ - hub
+---
+
+# ·
+
+## What this is
+
+## Tasks
+
+- [ ]
+
+## Open items
+
+## Key files
+
+## People
diff --git a/6. Templates/reference.md b/6. Templates/reference.md
new file mode 100644
index 0000000..5f1f1e0
--- /dev/null
+++ b/6. Templates/reference.md
@@ -0,0 +1,12 @@
+---
+type: reference
+title:
+source:
+updated: YYYY-MM-DD
+tags:
+ - reference
+---
+
+#
+
+*Source: *
diff --git a/6. Templates/thread.md b/6. Templates/thread.md
new file mode 100644
index 0000000..9ba41e5
--- /dev/null
+++ b/6. Templates/thread.md
@@ -0,0 +1,27 @@
+---
+type: thread
+title:
+status: open
+domains: []
+people: []
+opened: YYYY-MM-DD
+updated: YYYY-MM-DD
+tags:
+ - thread
+---
+
+#
+
+## What it is
+
+## Why cross-cutting
+
+## Current state
+
+## What's needed
+
+- [ ]
+
+## Update log
+
+- **YYYY-MM-DD:**
diff --git a/6. Templates/weekly-sweep.md b/6. Templates/weekly-sweep.md
new file mode 100644
index 0000000..ade3e55
--- /dev/null
+++ b/6. Templates/weekly-sweep.md
@@ -0,0 +1,48 @@
+---
+date: YYYY-MM-DD
+tags:
+ - inbox
+ - weekly-sweep
+---
+RE: [[]]
+
+## How to use this
+
+Tick a box when you've looked at it. Write under anything that changed — a Notes line is enough. `ingest` files it.
+
+## Since the last sweep
+
+-
+
+## Areas
+
+### — → [[]]
+
+- [ ] ** · ** — ·
+> Notes:
+
+## Threads
+
+- [ ] **** — ·
+> Notes:
+
+## People
+
+### Armed —
+
+- [ ] **** — ·
+> Notes:
+
+### Released — follow-ups whose work closed
+
+- [ ] **** — · was for , closed
+> Notes:
+
+### Contacts —
+
+- [ ] **** —
+> Notes:
+
+## Open questions — live
+
+- [ ] . **** —
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..cf6d0b7
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,248 @@
+# Orion — Operating Manual
+
+You are operating an **Orion vault**: a plain-markdown knowledge base, organised by PARA, maintained by an AI agent on behalf of one human — **the owner**. This file is the rulebook. It holds only the rules that change how you behave *by default*. Everything else is one read away:
+
+| Need | Read |
+|---|---|
+| Frontmatter + structure for any page type | `6. Templates/_contracts.md` |
+| Insertable page skeletons | `6. Templates/*.md` |
+| Tag taxonomy | `wiki/meta/tags.md` |
+| How a command executes | `.agents/skills//SKILL.md` |
+
+**Thin harness, fat skills.** Before adding anything to this file, ask whether it belongs in a skill. Execution logic is a skill. A page shape is a contract. This file stays small because it is loaded every session.
+
+---
+
+## Running a command — works in any agent
+
+Every command below maps to a skill file. **If your harness loads skills natively, use them. If it does not, read `.agents/skills//SKILL.md` and follow it exactly** — the file is the spec, not a summary of one.
+
+| Say this | Skill |
+|---|---|
+| `new project:` · `new area:` · `new workstream: [area] / [name]` | `orion-instantiate` |
+| `ingest` · `process the inbox` | `orion-ingest` |
+| `cascade` | `orion-cascade` |
+| `daily note` · `weekly sweep` | `orion-daily` |
+| `close workstream: [id]` | `orion-close` |
+| `archive: [name]` · `resume [name]` | `orion-archive` |
+| `lint` | `orion-lint` |
+| `fold the log` | `orion-fold` |
+
+**Creates one page** — no skill; copy the matching skeleton in `6. Templates/` and satisfy its contract in `_contracts.md`:
+
+| Say this | Creates |
+|---|---|
+| `new person: [name]` | `3. Resources/People/[Full Name].md` — `tier:` decides whether they can ever flag |
+| `new decision: [title]` | `4. Decisions/YYYY-MM-DD-[slug].md` |
+| `new thread: [title]` | `3. Resources/Threads/[slug].md` — ask for `domains:` and `people:` |
+
+**Read-and-report** — no skill; read the named sources and answer in chat:
+
+| Say this | Reads |
+|---|---|
+| `status` · `what's blocked` · `workstreams` | every `*_hub.md` |
+| `sends` | `next:` from every live Project hub |
+| `people` · `follow up: [name]` | person pages |
+| `threads` | `3. Resources/Threads/` |
+| `decisions` | `4. Decisions/` |
+| `log this: [note]` | append a timestamped line to today's note in `0. Inbox/` |
+
+**Output routines** — read sources, return a document, save to `3. Resources/Outbox/YYYY-MM-DD-[type]-[context].md`:
+
+| Routine | Shape |
+|---|---|
+| `meeting brief: [name]` | context → what's live → what to cover → open questions → recent contact |
+| `project snapshot: [project]` | what it is → state → moving → blocked → next → key people |
+| `outbound draft: [name] / [purpose]` | To / Subject / Body |
+
+**Order of operations:** `ingest` puts new material into the numbered folders. `cascade` syncs `wiki/` with what's already there. **Run cascade at the end of any session that changed something.**
+
+---
+
+## How the vault is organised
+
+**Numbered folders are where knowledge lives.**
+
+- `0. Inbox/` — daily notes and raw captures. Processed captures move to `0. Inbox/processed/YYYY-MM/`.
+- `1. Projects///` — finite work with a written *done-when*. Hub: `_hub.md`.
+- `2. Areas//` — ongoing responsibilities that are never done. Hub: `_hub.md`. Each Area has a `knowledge/` folder — its permanent memory.
+- `3. Resources/` — `People/`, `Threads/` (cross-cutting concerns), `Research/` (reusable knowledge belonging to no single Area), `Outbox/` (generated documents).
+- `4. Decisions/` — the decision log. Immutable.
+- `5. Archive/` — finished or retired work. Never deleted.
+- `6. Templates/` — page skeletons and the contracts they implement.
+
+**`wiki/` is navigation, not content.**
+
+- `wiki/hot.md` — **current state.** The one file to read at the start of every session. Rewritten by each cascade. Hard cap 80 lines.
+- `wiki/index.md` — the inventory: every hub, person, thread and decision, one line each. Rebuilt by cascade when structure changes.
+- `wiki/log.md` — append-only ledger of every operation. Newest first.
+- `wiki/folds/` — old log entries rolled up by `orion-fold`, kept verbatim.
+- `wiki/meta/` — `tags.md`, `holds.md`, `open-questions.md`, and the one current lint report.
+
+**Rule:** all knowledge lives in the numbered folders. `wiki/` reflects their state; it never holds content. **`wiki/` must stay smaller than the numbered folders** — if navigation outgrows the territory, it has become content.
+
+**Start every session by reading `wiki/hot.md`.**
+
+---
+
+## Ledgers append. State replaces. Derived expires.
+
+| Class | Files | Policy |
+|---|---|---|
+| **Ledger** | `4. Decisions/`, `wiki/log.md` | **Append only.** Never edit a past entry. |
+| **State** | hubs, person pages, `wiki/hot.md`, `wiki/index.md` | **Replace in place.** Never stack dated sections. Answers "what's true now." |
+| **Derived** | lint reports, folds | **Regenerable.** Keep one current lint report; archive the old one. |
+
+**Appending to state is the defect.** When state changes, replace it — the log already holds what it used to say.
+
+**One exception to "never edit a ledger":** when a file moves, repoint the *link target* in ledger entries so it resolves again. Change the pointer, never the prose.
+
+---
+
+## Attribute, don't assert
+
+**A fact that entered the vault from a source belongs to that source until the owner confirms it.**
+
+- ✅ *"The proposal lists Sam as a co-founder."* ❌ *"Sam is a co-founder."*
+- Every file created from external material records its provenance: file, sender, URL, conversation, date. If unknown, write **"source unrecorded"** — never leave it blank.
+- **Summary layers speak in the vault's voice.** Hub bullets, `hot.md` and `log.md` carry the attribution or they don't carry the claim.
+- **Contradiction inside one source beats agreement across copies.** Five files agreeing may be five copies of one wrong line.
+- **Absence in the vault is not absence in the world.** Say *"not found,"* never *"does not exist."*
+
+---
+
+## Repair yourself. Ask before changing.
+
+| | |
+|---|---|
+| **Repair** | Restores what a file was already trying to say — a dead link, a misspelled name, a rule contradicting itself, a missing required field you can derive. **Do it. Don't ask.** Record it in the log. |
+| **Change** | Alters what a file claims, or how the vault is shaped. **Never without asking.** |
+
+**If you cannot tell which one you are about to do, it is a change — ask.** A defect found is a defect fixed: the instance *and*, where you can, the mechanism that produced it.
+
+**Don't hand the owner work the vault can do.** If an answer is derivable from files you can read, derive it. Questions are for what only the owner knows or decides.
+
+---
+
+## Fences
+
+Paths listed here are **never read, edited, scanned, or summarised** by any skill or session. Links *into* them are checked for existence only. **Only the owner adds or lifts a fence.**
+
+| Fenced path | Since |
+|---|---|
+| *(none)* | |
+
+---
+
+## Status vocabulary
+
+**Projects:**
+
+| Status | Means |
+|---|---|
+| `open` | **The working status.** Real, identified work. No clock, no cap. Needs `done_when:`. `next:` optional. |
+| `paused` | Deliberately not now. Needs `paused_because:`. **Invisible to every freshness check** — that is the point. |
+| `closed` | Done. Deliverable migrated to its Area's `knowledge/` via `orion-close`. |
+| `archived` | Lives in `5. Archive/`. |
+
+**Areas** are `standing` or `archived`. A standing Area carries no attention status — never compute freshness or drift on one.
+
+**A never-started project is `open`, not `paused`.** They are different claims.
+
+---
+
+## The `next:` field — what's owed
+
+A Project hub may carry `next:` — one move per entry, verb first:
+
+```
+next: "send → Sam Example — revised quote [since 2026-01-05]"
+```
+
+| Verb | Means |
+|---|---|
+| `send` | A message to a person is owed. The work is not blocked on effort. |
+| `wait` | Waiting on someone else's clock. |
+| `build` | Solo work. |
+| `decide` | A call only the owner can make. |
+
+`send` and `wait` name a person. **`[since …]` is the age authority** — without it, fall back to git history, and if neither is trustworthy **render no age at all. A missing age is fine; a wrong one destroys trust in the whole table.**
+
+---
+
+## Holds — when life interrupts everything
+
+A hold is involuntary and cross-cutting (illness, travel, a family event); `paused` is deliberate and per-project. Holds live in `wiki/meta/holds.md`, one line each: start, end, reason, scope. Append-only.
+
+- **While a hold is open**, covered items render `held` — no age.
+- **After it closes**, render two clocks: the lead number from the later of `[since]` and the hold's end, the true elapsed time in parentheses — `3d (since 01-05, 11d held)`.
+- A hold covers an item only if the item predates the hold's start. **`[since]` is never rewritten.**
+- A hold changes how ages *render*. It never means nothing is owed.
+
+---
+
+## A capture gap is not a defect
+
+Days with no notes are a normal fact about a human. **Report the consequence** (stale data, false flags) **plainly, then re-read reality from the owner and move on.** Don't editorialise, don't build a mechanism to prevent it, don't carry it as an open item.
+
+---
+
+## The classification test
+
+When something new arrives, in this order:
+
+1. Can you write **"done when ___"** right now, in one sentence? → **Project**
+2. Is the honest answer "it's never done," and will it hold projects? → **Area**
+3. Neither, but facts and people attach to it? → **Resource or person page** — not a hub
+
+**Reference material:** strip any single Area's context from the note. **Claim still holds → `3. Resources/Research/`** (topic tags only). **Claim needs that Area's frame → `2. Areas//knowledge/`.**
+
+**The vault holds knowledge, not files.** Binaries (PDFs, decks, images, spreadsheets) live outside the vault; the vault holds a markdown note of what they say, attributed, with a path to the file.
+
+---
+
+## Naming conventions
+
+- **Folders:** Title Case with spaces.
+- **Workstream IDs:** `-` — a short uppercase prefix set once on the Area hub (`id_prefix:`), and a counter (`workstream_counter:`) that is the source of truth. **IDs are never reused.**
+- **Hub files:** Project → `_hub.md`. Area → `_hub.md`. **The `_hub` suffix is load-bearing** — every glob matches the suffix, never the whole name.
+- **People:** `Full Name.md`.
+- **Dated files** — decisions, outbox documents, and any ledger/tracker/report filed on a hub — `YYYY-MM-DD-[slug].md`, dated at creation.
+- **Inbox captures:** `YYYY-MM-DD-HHMM [slug].md`. Daily notes: `YYYY-MM-DD daily.md`. Sweeps: `YYYY-MM-DD weekly-sweep.md`.
+- **An ID never travels alone in prose.** Write `WEB-3 Pricing Page`, not bare `WEB-3`. Bare IDs are fine in frontmatter, filenames, and folders.
+- **Links:** `[[wikilinks]]` without the `.md` extension. They render in Obsidian and read fine as plain text anywhere else.
+- **A label the owner can't read is a defect in the label.**
+
+---
+
+## Vocabulary enforcement
+
+Canonical spellings of names and terms. `orion-lint` parses this table — keep the two-column shape.
+
+| Always use | Never use |
+|---|---|
+| *(add rows as corrections arise)* | |
+
+---
+
+## Log entries classify themselves
+
+Every `wiki/log.md` heading carries `[build]` or `[vault]`:
+
+```
+## 2026-01-05 — [build] Pricing page shipped
+## 2026-01-05 — [vault] Ingested three captures; two person pages created
+```
+
+A `[build]` entry **must** carry a `Shipped:` line naming what exists now that didn't before. **If you can't fill it, it's `[vault]`.**
+
+---
+
+## After every session
+
+1. **`cascade`** — rewrites `hot.md`, appends one log entry, rebuilds `index.md` if structure changed.
+2. **Commit, if the vault is a git repo.** Stage explicit paths (not `git add -A`), write a message that says *why*. Nothing auto-commits.
+
+## Delegation (optional)
+
+`orion-cascade`, `orion-lint` and `orion-fold` are mechanical — glob, parse, compare. If your harness supports subagents, they can run on a cheaper model. **The main session still verifies any count or name before it reaches `hot.md` or `log.md`**; a subagent's claim that it verified something is not verification. `orion-ingest` and `orion-daily` require judgment and stay in the main session.
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..f0db659
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,5 @@
+# Orion
+
+The operating manual for this vault is `AGENTS.md`, shared by every agent that drives it.
+
+@AGENTS.md
diff --git a/README.md b/README.md
index 07cff03..7cf0a3c 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,70 @@
-# orion-boilerplate
+# Orion
-a second brain management system for AI harnesses.
\ No newline at end of file
+*A second brain management system for AI harnesses.*
+
+A plain-markdown knowledge vault that an AI agent keeps for you. You drop notes, transcripts and documents in; the agent files them, keeps track of what's owed to whom, writes you a daily note, and keeps the whole thing linked and healthy.
+
+It is only folders of `.md` files plus a rulebook (`AGENTS.md`) and eight skills (`.agents/skills/`). There's no app and no database, and you're not tied to any one agent vendor.
+
+## Start
+
+1. Copy this folder somewhere you'll keep it. Ideally `git init` it, because the agent commits after each session.
+2. Point your agent at the folder (see below).
+3. Say: **`new area: `**. Then put a note in `0. Inbox/` and say **`ingest`**.
+4. At the end of a session, say **`cascade`**. Then read `wiki/hot.md` whenever you want to know where things stand.
+
+## Commands
+
+| Say | What happens |
+|---|---|
+| `new area: X` / `new project: X` | Creates the hub against its contract. Projects need a "done when" sentence |
+| `ingest` | Files everything in `0. Inbox/`: people, decisions, updates, reference notes |
+| `cascade` | Rewrites `wiki/hot.md` (current state) and logs the session |
+| `daily note` | Closes today's note and writes tomorrow's |
+| `weekly sweep` | Lists everything tracked, one line each, with room to write |
+| `close workstream: WEB-3` | A finished project hands its deliverable back to its Area |
+| `archive: X` / `resume X` | Retires or restores a whole Area. Reversible |
+| `lint` | Health check: dead links, missing fields, overdue follow-ups |
+| `fold the log` | Compacts old log entries |
+
+The full list is in `AGENTS.md`.
+
+## Using it with your agent
+
+| Agent | Setup |
+|---|---|
+| **Claude Code** | Run `claude` in this folder. `CLAUDE.md` imports `AGENTS.md`, and `.claude/skills` is a symlink to `.agents/skills` |
+| **Codex CLI** | Run `codex` in this folder. It reads `AGENTS.md` and discovers `.agents/skills/` |
+| **pi / oh-my-pi** | Run in this folder. It reads `AGENTS.md` and discovers `.agents/skills/` |
+| **Hermes Agent** | Run in this folder (`git init` first: Hermes scans project skills inside a git repo). It reads `AGENTS.md`. Trust the project skills when prompted (`hermes skills trust`) |
+| **Cursor, Gemini CLI, others** | Most read `AGENTS.md`. If yours doesn't load skills, that's fine: `AGENTS.md` tells the agent to open `.agents/skills//SKILL.md` and follow it |
+| **ChatGPT / chat-only tools** | Without file access the agent can't maintain the vault. Use a tool that can read and write files, or upload `AGENTS.md` and the relevant `SKILL.md` and apply the edits yourself |
+
+**Windows:** the `.claude/skills` symlink may check out as a plain text file. If so, delete it and run `mklink /D .claude\skills ..\.agents\skills`.
+
+## Obsidian (optional)
+
+Open this folder as an Obsidian vault if you want graph view and clickable `[[links]]`. Nothing depends on Obsidian, and the files read fine in any editor.
+
+## Layout
+
+```
+AGENTS.md the rulebook: every agent reads this
+CLAUDE.md points Claude Code at AGENTS.md
+.agents/skills/ the eight skills
+0. Inbox/ captures and daily notes
+1. Projects/ finite work, grouped by Area
+2. Areas/ ongoing responsibilities, each with a knowledge/ folder
+3. Resources/ People, Threads, Research, Outbox
+4. Decisions/ the decision log (append-only)
+5. Archive/ finished work, never deleted
+6. Templates/ page skeletons + _contracts.md
+wiki/ hot.md (state), index.md, log.md, folds/, meta/
+```
+
+## Making it yours
+
+- **Fences:** list paths the agent must never read in `AGENTS.md` → *Fences*.
+- **Vocabulary:** add canonical spellings of names and terms to `AGENTS.md` → *Vocabulary enforcement*. Lint enforces them.
+- **New page types:** add a contract to `6. Templates/_contracts.md` and a skeleton next to it, both in the same change.
+- Keep `AGENTS.md` small. If you're about to add procedure to it, that procedure belongs in a skill.
diff --git a/wiki/folds/.gitkeep b/wiki/folds/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/wiki/hot.md b/wiki/hot.md
new file mode 100644
index 0000000..21f7953
--- /dev/null
+++ b/wiki/hot.md
@@ -0,0 +1,29 @@
+---
+type: meta
+title: "Hot — current state"
+updated: YYYY-MM-DD
+---
+
+# Hot
+
+*Rewritten by `orion-cascade`. Never append. Hard cap 80 lines.*
+
+## Outstanding sends
+
+Nothing owed yet.
+
+## Workstreams
+
+0 open · 0 paused
+
+## Now
+
+Nothing yet.
+
+## People
+
+0 armed.
+
+## Standing state
+
+- Fresh vault. Start with `new area:` or `ingest`.
diff --git a/wiki/index.md b/wiki/index.md
new file mode 100644
index 0000000..195296e
--- /dev/null
+++ b/wiki/index.md
@@ -0,0 +1,45 @@
+---
+type: meta
+title: "Index"
+updated: YYYY-MM-DD
+---
+
+# Index
+
+*Rebuilt by `orion-cascade` when structure changes. One line per page. Navigation only — never prose.*
+
+## Areas
+
+*(none)*
+
+## Projects
+
+### Open
+
+*(none)*
+
+### Paused
+
+*(none)*
+
+## Threads
+
+*(none)*
+
+## People
+
+### Relationship tier
+
+*(none)*
+
+### Contacts
+
+*(none)*
+
+## Decisions
+
+*(none)*
+
+## Folds
+
+*(none)*
diff --git a/wiki/log.md b/wiki/log.md
new file mode 100644
index 0000000..283d054
--- /dev/null
+++ b/wiki/log.md
@@ -0,0 +1,9 @@
+---
+type: meta
+title: "Log"
+---
+
+# Log
+
+*Append-only ledger. Newest entry at the top. Never edit a past entry. Each heading is `## YYYY-MM-DD — [build|vault] Title`.*
+
diff --git a/wiki/meta/holds.md b/wiki/meta/holds.md
new file mode 100644
index 0000000..9591013
--- /dev/null
+++ b/wiki/meta/holds.md
@@ -0,0 +1,18 @@
+---
+type: meta
+title: "Holds"
+tags:
+ - meta
+---
+
+# Holds
+
+**Append-only.** One line per hold. Rules → `AGENTS.md`, *Holds*.
+
+Format:
+
+`- **Start:** YYYY-MM-DD · **End:** YYYY-MM-DD or open · **Reason:** one line · **Scope:** all | sends+people`
+
+## Log
+
+*(none)*
diff --git a/wiki/meta/open-questions.md b/wiki/meta/open-questions.md
new file mode 100644
index 0000000..30c11f4
--- /dev/null
+++ b/wiki/meta/open-questions.md
@@ -0,0 +1,20 @@
+---
+type: meta
+title: "Open questions"
+tags:
+ - meta
+---
+
+# Open questions
+
+**The register of decisions nobody has made yet.** Numbered, never renumbered — a closed question keeps its number. Items arrive here from `orion-lint` (a finding carried two cycles) and `orion-cascade` (a warning carried two runs). Each is written as a forced binary:
+
+`N. **Question** — Option A / Option B. Raised YYYY-MM-DD.`
+
+Close one by appending `**CLOSED YYYY-MM-DD** — the answer`.
+
+## Register
+
+*(none)*
+
+**Live count: 0**
diff --git a/wiki/meta/tags.md b/wiki/meta/tags.md
new file mode 100644
index 0000000..1598a14
--- /dev/null
+++ b/wiki/meta/tags.md
@@ -0,0 +1,30 @@
+---
+type: reference
+title: "Tag taxonomy"
+tags:
+ - reference
+---
+
+# Tag taxonomy
+
+## Area tags
+
+One tag per Area, carried by its hub and everything under it — its Projects and its `knowledge/` notes. Registered here by `orion-instantiate`.
+
+| Tag | Area |
+|---|---|
+| *(none yet)* | |
+
+**An Area tag records where something entered the vault.** Add a second one if a page genuinely belongs to two Areas; never strip the original.
+
+## Topic tags
+
+For `3. Resources/Research/` — reusable knowledge that belongs to no single Area. **Topic tags only there, never an Area tag.** Add to this list rather than inventing ad hoc tags.
+
+| Tag | For |
+|---|---|
+| `reference` | Every knowledge note carries this |
+
+## Structural tags
+
+`hub` · `person` · `thread` · `decision` · `inbox` · `daily-note` · `weekly-sweep` · `meta` · `fold` · `archive`