Polaris/.agents/skills/polaris-lint/SKILL.md

8.1 KiB

name description
polaris-lint 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/.

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