Polaris boilerplate: PARA vault, AGENTS.md rulebook, eight polaris skills

This commit is contained in:
Avi 2026-09-23 18:49:57 -05:00
commit 0ca9086de5
39 changed files with 1829 additions and 0 deletions

View file

@ -0,0 +1,128 @@
---
name: polaris-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]."
---
# polaris-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?** → `polaris-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/<Area>/
_index.md ← tombstone manifest (required)
1. Projects/<Area>/... ← every Project under the Area, moved wholesale
2. Areas/<Area>/... ← the Area folder, including knowledge/
<ID>/... ← closed workstreams already here from polaris-close — merge, don't collide
```
**If only one Project is being retired and its Area stays live**, it's not an archive — close it (`polaris-close`) or pause it.
## What moves, what doesn't
| | |
|---|---|
| `1. Projects/<Area>/` and `2. Areas/<Area>/` | **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/<Area>/_index.md`
```markdown
---
type: archive
subject: <Area> — archive bundle
date: YYYY-MM-DD
tags: [archive, <area-tag>]
---
# <Area> — archived YYYY-MM-DD
**Why:** one or two sentences — what happened, no speculation.
## In this bundle
- 1. Projects/<Area>/ — <which workstreams, by ID>
- 2. Areas/<Area>/ — hub and knowledge/
## Deliberately not in this bundle
- People — <who stayed, downgraded to contact>
- Threads — <which, and their status>
- Decisions — untouched in 4. Decisions/
## Links
Repointed N inbound links; rescan: 0 dead.
## If this resumes
Run `resume <Area>` — polaris-archive, restore path.
```
---
## Restore — `resume <Area>`
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 — <Area>
Moved: 1. Projects/<Area>/ (N workstreams) · 2. Areas/<Area>/
Stayed: <research, threads, etc.>
People downgraded: <names> · Released: <names or none>
Links repointed: N — rescan 0 dead
Tombstone: 5. Archive/<Area>/_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.

View file

@ -0,0 +1,153 @@
---
name: polaris-cascade
description: "Sync an Polaris 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."
---
# polaris-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:' -- <hub>`) → 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: <what changed, in a few words>
- Projects: N open, N paused
- People: N overdue, N due soon — <names>
- <notable state changes>
```
Use `[build]` only when the session shipped something, and then add `Shipped: <what exists now that didn't>`.
## 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 `polaris-fold`, on the owner's word.
---
## Output
```
## Cascade — YYYY-MM-DD
Sends outstanding
- <Person> — <what> (<age>)
Workstreams: N open (<IDs>) · N paused (<IDs>)
People (armed: N)
Overdue: <Name> (due YYYY-MM-DD)
Due this week: <Name> (due YYYY-MM-DD[, from last contact])
Defects: <Name> — no follow_up_by
Threads: <collapsed or notable>
Log: N / 16 [— fold due]
Wiki updated: hot.md · log.md [· index.md]
Verified: <N> rendered names checked against their own files — pass / <mismatch>
```
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.**

View file

@ -0,0 +1,104 @@
---
name: polaris-close
description: "Close a finished workstream in an Polaris vault and return its deliverable to the Area that spawned it. Verifies done_when is actually met, splits the output into deliverable (→ 2. Areas/<Area>/knowledge/) and process record (→ 5. Archive/<Area>/<ID>/), updates the Area hub, releases follow-ups tied to the work, and repoints inbound links. Not reversible. Distinct from polaris-archive, which retires a whole Area. Triggers on: close workstream, close [ID], this is done, finish workstream, ship it."
---
# polaris-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/<Area>/ ──spawns──▶ 1. Projects/<Area>/<Name>/
knowledge/ ◀── deliverable ──────────────────┤
└── process ──▶ 5. Archive/<Area>/<ID>/
```
## Close or archive?
| | `polaris-close` | `polaris-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/<Area>/knowledge/` | What the Area now knows: conclusions, specs, finished documents, reusable findings |
| **Process record** | `5. Archive/<Area>/<ID>/` | 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 `<ID>` — `<Name>`, closed YYYY-MM-DD."*
## 4. Archive the process record
Move everything else, **including `<ID>_hub.md`**, to `5. Archive/<Area>/<ID>/`. 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 — <ID> · <Name>
done_when: "<sentence>" — ✅ met / ⚠ met with correction (why)
Deliverable → 2. Areas/<Area>/knowledge/
- <file> — what the Area now knows
Process → 5. Archive/<Area>/<ID>/ — N files incl. hub
Area hub: <what changed>
Links repointed: N — rescan shows N dead (was N)
Released: <Name — follow_up_by, what it was for> · 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.

View file

@ -0,0 +1,145 @@
---
name: polaris-daily
description: "Close today's daily note in an Polaris 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 polaris-ingest first, polaris-cascade after. Triggers on: daily note, tomorrow's note, close the day, weekly sweep, sweep note."
---
# polaris-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, `polaris-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 path>|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 `polaris-close`/`polaris-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.

View file

@ -0,0 +1,72 @@
---
name: polaris-fold
description: "Roll up the oldest 2^k entries of an Polaris 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."
---
# polaris-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:** `polaris-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/<ID>.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/<ID>.md`):
```yaml
---
type: fold
fold_id: <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.**

View file

@ -0,0 +1,101 @@
---
name: polaris-ingest
description: "Bring external material into an Polaris 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 polaris-cascade, which syncs wiki/ with what's already in the folders. Triggers on: ingest, process the inbox, ingest this, file this."
---
# polaris-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-<slug>.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/<Full Name>.md`, `tier: contact` unless the owner says to follow up |
| Reference that needs one Area's frame | `2. Areas/<Area>/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 `polaris-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 `polaris-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.
`polaris-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: <files or description>
Created:
- <path> — one line
Updated:
- [[Page]] — what changed
Filed in notes: N lines marked ✓
Archived: N captures → 0. Inbox/processed/YYYY-MM/
Asked / flagged: <any classification question, and the answer>
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.

View file

@ -0,0 +1,91 @@
---
name: polaris-instantiate
description: "Create a Project (workstream) or Area in an Polaris 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."
---
# polaris-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/<Area Name>/` (Title Case, spaces).
2. Hub: `<Area Name>_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: <PREFIX>-<new value>`.
⚠ **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/<Area>/<Project Name>/`. Hub: `<ID>_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, <area-tag>]`. 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/<Name>/`, rename the hub `<Name>_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 `polaris-close` step 6 for method). Log it. Cascade.
---
## Output
```
## Instantiate — <ID or Area name>
Done-when: "<sentence>" (Projects)
Created: <path>
ID: <PREFIX>-<N> — counter now <N> (Projects)
Registered: <Area hub listing · tag · knowledge/ seeded · inbound link>
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.

View file

@ -0,0 +1,134 @@
---
name: polaris-lint
description: "Health-check an Polaris 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."
---
# polaris-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 `<id>_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 `<PREFIX>-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 — `**<Question>** — 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 @ <commit>
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.**

1
.claude/skills Symbolic link
View file

@ -0,0 +1 @@
../.agents/skills

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.obsidian/workspace*.json
.DS_Store

View file

0
1. Projects/.gitkeep Normal file
View file

0
2. Areas/.gitkeep Normal file
View file

View file

View file

View file

View file

0
4. Decisions/.gitkeep Normal file
View file

0
5. Archive/.gitkeep Normal file
View file

158
6. Templates/_contracts.md Normal file
View file

@ -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/<Area>/<Area>_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, <area-tag>]
```
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/<Area>/knowledge/_index.md` — seeded at creation, stating what belongs there.
---
## Project hub — `1. Projects/<Area>/<Name>/<ID>_hub.md`
```yaml
type: project # never `hub`
id: WEB-1 # from the Area's workstream_counter
area: <Area folder name> # 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, <area-tag>]
```
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; `polaris-close` archives it whole.
**A workstream *is* a Project.** It opens when an Area needs finite work done, and closes via `polaris-close`, which returns its deliverable to the Area:
```
Area ──spawns──▶ Project (id, done_when)
▲ │ on close
└── knowledge/ ◀───┤ deliverable
└── process record ──▶ 5. Archive/<Area>/<ID>/
```
A workstream belongs to exactly one Area. A concern spanning several is a **thread**.
---
## Person — `3. Resources/People/<Full Name>.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-<slug>.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/<slug>.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/<Area>/knowledge/`
```yaml
type: reference
title:
source: # file, URL, sender, conversation — or "source unrecorded"
updated: YYYY-MM-DD
tags: [reference, <topic or area tag>]
```
**`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]`.

22
6. Templates/area-hub.md Normal file
View file

@ -0,0 +1,22 @@
---
type: area
status: standing
id_prefix:
workstream_counter: 0
parent:
updated: YYYY-MM-DD
tags:
- hub
---
# <Area>
## What this is
## Workstreams
## Open items
## Key files
## People

View file

@ -0,0 +1,52 @@
---
date: YYYY-MM-DD
tags:
- inbox
- daily-note
---
RE: <Weekday> <Month D YYYY> — [[<prior note>]]
## Focus
<What today is about. Three lines, no lists.>
## Since the last note
- <Up to five bullets. Omit the section when nothing changed.>
## <ID> · <Name> — <what is actually owed>
**Where it stands:** <one or two plain sentences.> → [[<hub>|hub]]
**Yours:**
- [ ] <task> — <asked N times since Mon D>
**Waiting on:** <Person — what, N days> · or nobody
> Notes:
## Loose
### <Item that belongs to no single workstream>
<Plain prose.>
> Notes:
## Open questions — <N> live
- [ ] <N>. **<Question>** — <one clause of context>
## People
**<N> armed · <N> overdue · <N> defects**
**Overdue**
- <Name> — <N days> (<Mon D>) — <what they are tied to>
**Due in the next 7 days**
- <Name> — <Mon D> — <what they are tied to>
## Standing
- <Holds · structural facts. Three lines max.>

24
6. Templates/decision.md Normal file
View file

@ -0,0 +1,24 @@
---
type: decision
date: YYYY-MM-DD
topic:
areas: []
status: open
updated: YYYY-MM-DD
tags:
- decision
---
# <Decision title>
## Context
## Decision
## Rationale
## Expected outcome
## Follow-up
- YYYY-MM-DD:

32
6. Templates/person.md Normal file
View file

@ -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
---
# <Full Name>
## Role & Relationship
## Background
## Context
## Open Items
- [ ]
## Contact History
- YYYY-MM-DD:

View file

@ -0,0 +1,28 @@
---
type: project
id:
area:
done_when: ""
status: open
next:
paused_because:
deadline:
threads: []
updated: YYYY-MM-DD
tags:
- hub
---
# <ID> · <Name>
## What this is
## Tasks
- [ ]
## Open items
## Key files
## People

12
6. Templates/reference.md Normal file
View file

@ -0,0 +1,12 @@
---
type: reference
title:
source:
updated: YYYY-MM-DD
tags:
- reference
---
# <Title>
*Source: <where this came from, or "source unrecorded">*

27
6. Templates/thread.md Normal file
View file

@ -0,0 +1,27 @@
---
type: thread
title:
status: open
domains: []
people: []
opened: YYYY-MM-DD
updated: YYYY-MM-DD
tags:
- thread
---
# <Thread title>
## What it is
## Why cross-cutting
## Current state
## What's needed
- [ ]
## Update log
- **YYYY-MM-DD:**

View file

@ -0,0 +1,48 @@
---
date: YYYY-MM-DD
tags:
- inbox
- weekly-sweep
---
RE: [[<prior sweep>]]
## 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
- <Up to five bullets.>
## Areas
### <Area> — <one line on what it holds> → [[<hub>]]
- [ ] **<ID> · <Name>** — <status> · <where it stands, one line>
> Notes:
## Threads
- [ ] **<slug>** — <status> · <one line>
> Notes:
## People
### Armed — <N>
- [ ] **<Name>** — <N days overdue / due Mon D> · <what they are tied to>
> Notes:
### Released — follow-ups whose work closed
- [ ] **<Name>** — <follow-up date> · was for <workstream>, closed <Mon D>
> Notes:
### Contacts — <Area>
- [ ] **<Name>** — <role, one line>
> Notes:
## Open questions — <N> live
- [ ] <N>. **<Question>** — <one clause of context>

248
AGENTS.md Normal file
View file

@ -0,0 +1,248 @@
# Polaris — Operating Manual
You are operating an **Polaris 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/<name>/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/<name>/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]` | `polaris-instantiate` |
| `ingest` · `process the inbox` | `polaris-ingest` |
| `cascade` | `polaris-cascade` |
| `daily note` · `weekly sweep` | `polaris-daily` |
| `close workstream: [id]` | `polaris-close` |
| `archive: [name]` · `resume [name]` | `polaris-archive` |
| `lint` | `polaris-lint` |
| `fold the log` | `polaris-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/<Area>/<Name>/` — finite work with a written *done-when*. Hub: `<ID>_hub.md`.
- `2. Areas/<Area>/` — ongoing responsibilities that are never done. Hub: `<Area>_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 `polaris-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 `polaris-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/<Area>/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:** `<PREFIX>-<N>` — 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 → `<ID>_hub.md`. Area → `<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. `polaris-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)
`polaris-cascade`, `polaris-lint` and `polaris-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. `polaris-ingest` and `polaris-daily` require judgment and stay in the main session.

5
CLAUDE.md Normal file
View file

@ -0,0 +1,5 @@
# Polaris
The operating manual for this vault is `AGENTS.md`, shared by every agent that drives it.
@AGENTS.md

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Avi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

70
README.md Normal file
View file

@ -0,0 +1,70 @@
# Polaris
*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: <something you're responsible for>`**. 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/<name>/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.

0
wiki/folds/.gitkeep Normal file
View file

29
wiki/hot.md Normal file
View file

@ -0,0 +1,29 @@
---
type: meta
title: "Hot — current state"
updated: YYYY-MM-DD
---
# Hot
*Rewritten by `polaris-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`.

45
wiki/index.md Normal file
View file

@ -0,0 +1,45 @@
---
type: meta
title: "Index"
updated: YYYY-MM-DD
---
# Index
*Rebuilt by `polaris-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)*

9
wiki/log.md Normal file
View file

@ -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`.*

18
wiki/meta/holds.md Normal file
View file

@ -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)*

View file

@ -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 `polaris-lint` (a finding carried two cycles) and `polaris-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**

30
wiki/meta/tags.md Normal file
View file

@ -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 `polaris-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`