@forwardimpact/outpost 3.12.1 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/package.json +3 -2
  2. package/src/kb-manager.js +58 -5
  3. package/src/kb-validator.js +762 -0
  4. package/src/outpost.js +73 -8
  5. package/templates/.claude/agents/chief-of-staff.md +14 -6
  6. package/templates/.claude/agents/concierge.md +9 -2
  7. package/templates/.claude/agents/head-hunter.md +9 -2
  8. package/templates/.claude/agents/librarian.md +11 -4
  9. package/templates/.claude/agents/postman.md +9 -2
  10. package/templates/.claude/agents/recruiter.md +9 -2
  11. package/templates/.claude/skills/anarlog-follow/SKILL.md +53 -29
  12. package/templates/.claude/skills/anarlog-follow/references/sessions.md +52 -0
  13. package/templates/.claude/skills/anarlog-process/SKILL.md +88 -45
  14. package/templates/.claude/skills/anarlog-process/references/extraction.md +19 -11
  15. package/templates/.claude/skills/anarlog-process/references/sessions.md +92 -58
  16. package/templates/.claude/skills/anarlog-process/scripts/scan.mjs +404 -163
  17. package/templates/.claude/skills/candidate-report/SKILL.md +12 -9
  18. package/templates/.claude/skills/changelog/SKILL.md +106 -56
  19. package/templates/.claude/skills/deck-create/SKILL.md +60 -2
  20. package/templates/.claude/skills/deck-review/SKILL.md +4 -1
  21. package/templates/.claude/skills/deck-summarize/SKILL.md +6 -2
  22. package/templates/.claude/skills/deck-summarize/references/brief-template.md +1 -1
  23. package/templates/.claude/skills/doc-collab/SKILL.md +16 -11
  24. package/templates/.claude/skills/doc-create/SKILL.md +6 -3
  25. package/templates/.claude/skills/draft-emails/SKILL.md +31 -25
  26. package/templates/.claude/skills/draft-emails/references/template.md +1 -1
  27. package/templates/.claude/skills/draft-emails/scripts/scan-emails.mjs +14 -8
  28. package/templates/.claude/skills/draft-emails/scripts/send-email.mjs +9 -3
  29. package/templates/.claude/skills/extract-entities/SKILL.md +17 -16
  30. package/templates/.claude/skills/extract-entities/references/TEMPLATES.md +2 -1
  31. package/templates/.claude/skills/extract-entities/references/conditions.md +6 -5
  32. package/templates/.claude/skills/extract-entities/references/links.md +34 -10
  33. package/templates/.claude/skills/extract-entities/references/recruitment.md +15 -10
  34. package/templates/.claude/skills/extract-entities/references/resolution.md +1 -1
  35. package/templates/.claude/skills/extract-entities/references/sources.md +1 -1
  36. package/templates/.claude/skills/extract-entities/references/templates-conditions.md +10 -4
  37. package/templates/.claude/skills/extract-entities/references/templates-people-orgs.md +29 -10
  38. package/templates/.claude/skills/extract-entities/references/templates-priorities.md +8 -2
  39. package/templates/.claude/skills/extract-entities/references/templates-projects-topics.md +19 -7
  40. package/templates/.claude/skills/meeting-prep/SKILL.md +23 -18
  41. package/templates/.claude/skills/organize-files/SKILL.md +3 -0
  42. package/templates/.claude/skills/person-identify/SKILL.md +58 -10
  43. package/templates/.claude/skills/person-identify/scripts/identify.sh +110 -11
  44. package/templates/.claude/skills/person-lookup/SKILL.md +8 -3
  45. package/templates/.claude/skills/person-lookup/scripts/lookup.sh +27 -1
  46. package/templates/.claude/skills/req-assess/SKILL.md +19 -11
  47. package/templates/.claude/skills/req-assess/references/interview-template.md +6 -1
  48. package/templates/.claude/skills/req-assess/references/panel-template.md +5 -1
  49. package/templates/.claude/skills/req-bundle/SKILL.md +164 -0
  50. package/templates/.claude/skills/req-bundle/references/matching.md +70 -0
  51. package/templates/.claude/skills/req-bundle/references/pdf-structure.md +74 -0
  52. package/templates/.claude/skills/req-bundle/scripts/split-bundle.mjs +377 -0
  53. package/templates/.claude/skills/req-decide/SKILL.md +26 -18
  54. package/templates/.claude/skills/req-decide/references/template.md +2 -2
  55. package/templates/.claude/skills/req-forget/SKILL.md +39 -22
  56. package/templates/.claude/skills/req-forget/references/classify.md +12 -10
  57. package/templates/.claude/skills/req-forget/references/locations.md +27 -22
  58. package/templates/.claude/skills/req-forget/references/report-template.md +23 -15
  59. package/templates/.claude/skills/req-scan/SKILL.md +6 -3
  60. package/templates/.claude/skills/req-scan/references/template.md +11 -1
  61. package/templates/.claude/skills/req-screen/SKILL.md +78 -34
  62. package/templates/.claude/skills/req-screen/references/rubric.md +38 -42
  63. package/templates/.claude/skills/req-screen/references/scoring.md +79 -0
  64. package/templates/.claude/skills/req-screen/references/template.md +26 -14
  65. package/templates/.claude/skills/req-track/SKILL.md +44 -44
  66. package/templates/.claude/skills/req-track/references/fields.md +18 -15
  67. package/templates/.claude/skills/req-track/references/overlays.md +42 -0
  68. package/templates/.claude/skills/req-track/references/signals.md +2 -2
  69. package/templates/.claude/skills/req-track/references/templates.md +28 -27
  70. package/templates/.claude/skills/req-workday/SKILL.md +49 -20
  71. package/templates/.claude/skills/req-workday/references/brief.md +81 -0
  72. package/templates/.claude/skills/req-workday/references/templates.md +6 -73
  73. package/templates/.claude/skills/req-workday/references/xlsx-format.md +19 -0
  74. package/templates/.claude/skills/req-workday/scripts/parse-workday.mjs +96 -20
  75. package/templates/.claude/skills/send-chat/SKILL.md +11 -11
  76. package/templates/.claude/skills/sync-apple-calendar/SKILL.md +3 -0
  77. package/templates/.claude/skills/sync-apple-mail/SKILL.md +3 -0
  78. package/templates/.claude/skills/sync-teams/SKILL.md +3 -0
  79. package/templates/.claude/skills/upstream-instructions/SKILL.md +8 -5
  80. package/templates/.claude/skills/upstream-instructions/references/examples.md +3 -3
  81. package/templates/CLAUDE.md +96 -87
  82. package/templates/MIGRATION.md +359 -0
  83. package/templates/registry.yaml +25 -0
  84. package/templates/.claude/skills/anarlog-follow/scripts/follow.mjs +0 -243
  85. package/templates/.claude/skills/anarlog-trim/SKILL.md +0 -186
@@ -5,6 +5,9 @@ description: Draft and send email responses with context from the knowledge base
5
5
 
6
6
  # Draft Emails
7
7
 
8
+ Write tier: `0-Draft`
9
+ Frontmatter: none
10
+
8
11
  Draft and send email responses. Use the knowledge base and calendar for full
9
12
  context on every person and conversation. Every draft needs explicit user
10
13
  approval before you send it.
@@ -20,24 +23,26 @@ The user asks to draft, reply to, respond to, or send an email.
20
23
 
21
24
  ## Data locations
22
25
 
23
- | Data | Location |
24
- | --------------- | -------------------------------------------- |
25
- | People | `Knowledge/People/*.md` |
26
- | Organizations | `Knowledge/Organizations/*.md` |
27
- | Email threads | `~/.cache/fit/outpost/apple_mail/*.md` |
28
- | Calendar events | `~/.cache/fit/outpost/apple_calendar/*.json` |
29
- | Handled IDs | `Drafts/handled` (one ID per line) |
30
- | Ignored IDs | `Drafts/ignored` (one ID per line) |
31
- | Draft files | `Drafts/{email_id}_draft.md` |
26
+ | Data | Location |
27
+ | --------------- | --------------------------------------------------- |
28
+ | People | `3-Team/People/*.md` |
29
+ | Organizations | `3-Team/Organizations/*.md` |
30
+ | Email threads | `~/.cache/fit/outpost/apple_mail/*.md` |
31
+ | Calendar events | `~/.cache/fit/outpost/apple_calendar/*.json` |
32
+ | Handled IDs | `~/.cache/fit/outpost/drafts/handled` (one ID/line) |
33
+ | Ignored IDs | `~/.cache/fit/outpost/drafts/ignored` (one ID/line) |
34
+ | Draft files | `0-Draft/{email_id}_draft.md` |
32
35
 
33
36
  `handled` and `ignored` both exclude threads from `scan-emails.mjs`. Use
34
37
  `handled` for resolved threads (sent here, replied manually, resolved through a
35
38
  DM). Use `ignored` for threads that need no response (newsletters, spam,
36
- outbound with no reply).
39
+ outbound with no reply). The ledgers are agent state, not knowledge. They live
40
+ in the cache `drafts/` directory, never in `state/` (a daemon-owned trust
41
+ root).
37
42
 
38
43
  <do_confirm_checklist goal="Verify a draft is safe and ready before sending">
39
44
 
40
- - [ ] You looked up the sender and the organization in `Knowledge/` before you
45
+ - [ ] You looked up the sender and the organization in `3-Team/` before you
41
46
  drafted.
42
47
  - [ ] The draft is a single email (not multiple variants). It matches the
43
48
  incoming tone.
@@ -47,7 +52,7 @@ outbound with no reply).
47
52
  recipients. Any direct-to-candidate draft carries `⚠️ RECRUITER ONLY`.
48
53
  - [ ] The draft includes no sensitive personal data (health, politics, etc.).
49
54
  - [ ] The user explicitly approved the draft before any send.
50
- - [ ] Send used `--draft <path>` so cleanup and `Drafts/handled` happen
55
+ - [ ] Send used `--draft <path>` so cleanup and the `handled` ledger happen
51
56
  automatically.
52
57
 
53
58
  </do_confirm_checklist>
@@ -61,12 +66,12 @@ node scripts/scan-emails.mjs
61
66
  ```
62
67
 
63
68
  The script outputs `email_id<TAB>subject` for unprocessed emails (those not in
64
- `Drafts/handled` or `Drafts/ignored`).
69
+ the `handled` or `ignored` ledger).
65
70
 
66
71
  ### 2. Classify
67
72
 
68
- **Ignore** (append ID to `Drafts/ignored`): newsletters, marketing, automated
69
- notifications, spam, outbound with no reply.
73
+ **Ignore** (append the ID to `~/.cache/fit/outpost/drafts/ignored`):
74
+ newsletters, marketing, automated notifications, spam, outbound with no reply.
70
75
 
71
76
  **Draft a response**: meeting requests, personal mail from known contacts,
72
77
  business inquiries or follow-ups, requests for information or action.
@@ -75,12 +80,12 @@ Be conservative with ignore. When in doubt, draft.
75
80
 
76
81
  ### 3. Gather context
77
82
 
78
- Before you draft, look up the sender and the organization in `Knowledge/`:
83
+ Before you draft, look up the sender and the organization in the graph:
79
84
 
80
85
  ```bash
81
- rg -l "sender_name" Knowledge/
82
- cat "Knowledge/People/Sender Name.md"
83
- cat "Knowledge/Organizations/Company Name.md"
86
+ rg -l "sender_name" [0-9]-*/
87
+ cat "3-Team/People/Sender Name.md"
88
+ cat "3-Team/Organizations/Company Name.md"
84
89
  ```
85
90
 
86
91
  For an email that arranges a meeting time, also read the relevant calendar
@@ -96,7 +101,7 @@ is unclear or the person has multiple contexts, **ask** rather than guess.
96
101
 
97
102
  ### 4. Write the draft
98
103
 
99
- Save to `Drafts/{email_id}_draft.md` with the template in
104
+ Save to `0-Draft/{email_id}_draft.md` with the template in
100
105
  [references/template.md](references/template.md). Reference past interactions
101
106
  naturally. To arrange a meeting, propose specific times from the calendar
102
107
  availability.
@@ -105,7 +110,7 @@ availability.
105
110
 
106
111
  You **must never** copy candidates on internal threads about them.
107
112
 
108
- - Identify the candidate from the thread and `Knowledge/Candidates/`.
113
+ - Identify the candidate from the thread and `2-Confidential/Candidates/`.
109
114
  - Strip the candidate from To/CC. Draft to internal stakeholders only.
110
115
  - Direct-to-candidate emails carry the warning header
111
116
  `⚠️ RECRUITER ONLY — This email goes directly to the candidate.`
@@ -128,18 +133,19 @@ node scripts/send-email.mjs \
128
133
  --cc "other@example.com" \
129
134
  --subject "Re: Subject" \
130
135
  --body "Plain text body" \
131
- --draft "Drafts/12345_draft.md"
136
+ --draft "0-Draft/12345_draft.md"
132
137
  ```
133
138
 
134
139
  Required: `--to`, `--subject`, `--body` (plain text). Optional: `--cc`, `--bcc`,
135
140
  `--draft`. With `--draft`, the script deletes the draft file. It also appends
136
- the email ID to `Drafts/handled` automatically.
141
+ the email ID to the `handled` ledger automatically.
137
142
 
138
143
  ### 8. Mark handled and do not send
139
144
 
140
145
  When other channels resolve a thread:
141
146
 
142
147
  ```bash
143
- echo "$EMAIL_ID" >> Drafts/handled
144
- rm -f "Drafts/${EMAIL_ID}_draft.md"
148
+ mkdir -p ~/.cache/fit/outpost/drafts
149
+ echo "$EMAIL_ID" >> ~/.cache/fit/outpost/drafts/handled
150
+ rm -f "0-Draft/${EMAIL_ID}_draft.md"
145
151
  ```
@@ -1,6 +1,6 @@
1
1
  # Draft File Template
2
2
 
3
- Save each draft to `Drafts/{email_id}_draft.md` with this layout:
3
+ Save each draft to `0-Draft/{email_id}_draft.md` with this layout:
4
4
 
5
5
  ```markdown
6
6
  # Draft Response
@@ -3,13 +3,16 @@
3
3
  * Scan for unprocessed emails and output their IDs and subjects.
4
4
  *
5
5
  * The script checks ~/.cache/fit/outpost/apple_mail/ for email thread markdown
6
- * files. It skips a file that Drafts/handled or Drafts/ignored already lists.
7
- * It outputs one tab-separated line per unprocessed thread:
8
- * email_id<TAB>subject. The draft-emails skill uses this script to find
9
- * threads that need a reply.
6
+ * files. It skips a file that the ~/.cache/fit/outpost/drafts/handled or
7
+ * ~/.cache/fit/outpost/drafts/ignored ledger already lists. It outputs one
8
+ * tab-separated line per unprocessed thread: email_id<TAB>subject. The
9
+ * draft-emails skill uses this script to find threads that need a reply.
10
+ *
11
+ * The ledgers live in the cache drafts/ directory. Never move them into
12
+ * ~/.cache/fit/outpost/state/ — that directory is a daemon-owned trust root.
10
13
  */
11
14
 
12
- import { existsSync, readdirSync, readFileSync } from "node:fs";
15
+ import { existsSync, mkdirSync, readdirSync, readFileSync } from "node:fs";
13
16
  import { basename, join } from "node:path";
14
17
  import { homedir } from "node:os";
15
18
 
@@ -18,7 +21,8 @@ const HELP = `scan-emails — list unprocessed email threads
18
21
  Usage: node scripts/scan-emails.mjs [-h|--help]
19
22
 
20
23
  Scans ~/.cache/fit/outpost/apple_mail/ for .md thread files not yet
21
- recorded in Drafts/handled or Drafts/ignored. Outputs one line per
24
+ recorded in ~/.cache/fit/outpost/drafts/handled or
25
+ ~/.cache/fit/outpost/drafts/ignored. Outputs one line per
22
26
  unprocessed thread as: email_id<TAB>subject`;
23
27
 
24
28
  if (process.argv.includes("-h") || process.argv.includes("--help")) {
@@ -28,6 +32,7 @@ if (process.argv.includes("-h") || process.argv.includes("--help")) {
28
32
 
29
33
  const HOME = homedir();
30
34
  const MAIL_DIR = join(HOME, ".cache/fit/outpost/apple_mail");
35
+ const DRAFTS_DIR = join(HOME, ".cache/fit/outpost/drafts");
31
36
 
32
37
  /** Load a file of IDs (one per line) into a Set. */
33
38
  function loadIdSet(path) {
@@ -50,8 +55,9 @@ function extractSubject(filePath) {
50
55
  function main() {
51
56
  if (!existsSync(MAIL_DIR)) return;
52
57
 
53
- const handled = loadIdSet("Drafts/handled");
54
- const ignored = loadIdSet("Drafts/ignored");
58
+ mkdirSync(DRAFTS_DIR, { recursive: true });
59
+ const handled = loadIdSet(join(DRAFTS_DIR, "handled"));
60
+ const ignored = loadIdSet(join(DRAFTS_DIR, "ignored"));
55
61
 
56
62
  for (const name of readdirSync(MAIL_DIR).sort()) {
57
63
  if (!name.endsWith(".md")) continue;
@@ -15,12 +15,13 @@
15
15
  import { execFileSync } from "node:child_process";
16
16
  import {
17
17
  appendFileSync,
18
+ mkdirSync,
18
19
  mkdtempSync,
19
20
  writeFileSync,
20
21
  unlinkSync,
21
22
  } from "node:fs";
22
23
  import { basename, join } from "node:path";
23
- import { tmpdir } from "node:os";
24
+ import { homedir, tmpdir } from "node:os";
24
25
 
25
26
  const HELP = `send-email — send an email through Apple Mail
26
27
 
@@ -32,7 +33,7 @@ Options:
32
33
  --bcc <addrs> Comma-separated BCC recipients
33
34
  --subject <subj> Email subject line (required)
34
35
  --body <text> Plain-text email body (required)
35
- --draft <path> Draft file. The script deletes it after send and appends the ID to Drafts/handled
36
+ --draft <path> Draft file. The script deletes it after send and appends the ID to ~/.cache/fit/outpost/drafts/handled
36
37
  -h, --help Show this help message and exit
37
38
 
38
39
  Mail.app must run. You need no signature or sign-off. Apple Mail appends it.`;
@@ -104,6 +105,10 @@ function buildAppleScript({ to, cc, bcc, subject, body }) {
104
105
  .join("\n");
105
106
  }
106
107
 
108
+ // The handled ledger lives in the cache drafts/ directory. Never move it into
109
+ // ~/.cache/fit/outpost/state/ — that directory is a daemon-owned trust root.
110
+ const DRAFTS_DIR = join(homedir(), ".cache/fit/outpost/drafts");
111
+
107
112
  function handleDraftCleanup(draft) {
108
113
  if (!draft) return;
109
114
  try {
@@ -115,7 +120,8 @@ function handleDraftCleanup(draft) {
115
120
  const draftBasename = basename(draft, ".md");
116
121
  const emailId = draftBasename.replace(/_draft$/, "");
117
122
  if (emailId) {
118
- appendFileSync("Drafts/handled", emailId + "\n");
123
+ mkdirSync(DRAFTS_DIR, { recursive: true });
124
+ appendFileSync(join(DRAFTS_DIR, "handled"), emailId + "\n");
119
125
  console.log(`Marked as handled: ${emailId}`);
120
126
  }
121
127
  }
@@ -1,13 +1,16 @@
1
1
  ---
2
2
  name: extract-entities
3
- description: Process synced email/calendar files from ~/.cache/fit/outpost/ and ad-hoc document files (e.g. from ~/Desktop/ or ~/Downloads/). Extract structured knowledge into Knowledge/ as Obsidian-compatible markdown notes. Use on a schedule, when the user asks to process/extract entities, or when another skill invokes it (e.g. organize-files). Builds the core knowledge graph from raw data.
3
+ description: Process synced email/calendar files from ~/.cache/fit/outpost/ and ad-hoc document files (e.g. from ~/Desktop/ or ~/Downloads/). Extract structured knowledge into the tier directories as Obsidian-compatible markdown notes. Use on a schedule, when the user asks to process/extract entities, or when another skill invokes it (e.g. organize-files). Builds the core knowledge graph from raw data.
4
4
  ---
5
5
 
6
6
  # Extract Entities
7
7
 
8
+ Write tier: `3-Team` (general); `2-Confidential` (recruitment entities)
9
+ Frontmatter: person, organization, project, topic, priority, condition
10
+
8
11
  Process synced email and calendar files from `~/.cache/fit/outpost/`, plus
9
12
  ad-hoc documents from other skills, into Obsidian-compatible markdown notes
10
- under `Knowledge/`. This skill builds the core knowledge graph.
13
+ in the tier directories. This skill builds the core knowledge graph.
11
14
 
12
15
  ## Trigger
13
16
 
@@ -35,15 +38,14 @@ under `Knowledge/`. This skill builds the core knowledge graph.
35
38
 
36
39
  ## Outputs
37
40
 
38
- - `Knowledge/People/`, `Knowledge/Organizations/`, `Knowledge/Projects/`,
39
- `Knowledge/Topics/` — created or updated.
40
- - `Knowledge/Priorities/` — **updated only**, never
41
- auto-created.
42
- - `Knowledge/Conditions/` — created when you detect cross-cutting patterns, or
41
+ - `3-Team/People/`, `3-Team/Organizations/`, `3-Team/Projects/`,
42
+ `3-Team/Topics/` — created or updated.
43
+ - `3-Team/Priorities/` — **updated only**, never auto-created.
44
+ - `3-Team/Conditions/` — created when you detect cross-cutting patterns, or
43
45
  updated.
44
- - `Knowledge/Roles/*.md`, `Knowledge/Candidates/*/brief.md` — enriched with
45
- inferred metadata. Create new role stubs with `**Status:** open`. Update to
46
- `**Status:** closed` when a role closes.
46
+ - `2-Confidential/Roles/*.md`, `2-Confidential/Candidates/*/brief.md` — enriched
47
+ with inferred metadata. Create new role stubs with `**Status:** open`. Update
48
+ to `**Status:** closed` when a role closes.
47
49
  - `~/.cache/fit/outpost/state/graph_processed` — updated.
48
50
 
49
51
  <do_confirm_checklist goal="Verify the batch produced clean, linked,
@@ -55,8 +57,8 @@ well-grounded notes">
55
57
  - [ ] Apply the "Would I prep?" test. Write no stub profiles. Give every new
56
58
  People note a substantive `## Summary`. Route calendar-only attendees to
57
59
  the Organization `## Contacts` section.
58
- - [ ] Use absolute paths `[[Folder/Name]]` for all links. Keep bidirectional
59
- links consistent (incl. Project ↔ Priority).
60
+ - [ ] Use tier-prefixed absolute paths (`[[3-Team/People/Name]]`) for all
61
+ links. Keep bidirectional links consistent (incl. Project ↔ Priority).
60
62
  - [ ] Describe the relationship in each summary. Omit the communication
61
63
  method. Make key facts substantive. Make open items commitments.
62
64
  - [ ] Log state changes with `[Field → value]`. Never auto-create a Priority
@@ -91,9 +93,8 @@ directly. Do not scan `~/.cache/fit/outpost/`. Still check each path against
91
93
  ### 1. Build the knowledge index
92
94
 
93
95
  ```bash
94
- find Knowledge/People Knowledge/Organizations Knowledge/Projects \
95
- Knowledge/Topics Knowledge/Priorities \
96
- Knowledge/Conditions -name "*.md" 2>/dev/null
96
+ find 3-Team/People 3-Team/Organizations 3-Team/Projects 3-Team/Topics \
97
+ 3-Team/Priorities 3-Team/Conditions -name "*.md" 2>/dev/null
97
98
  ```
98
99
 
99
100
  Run `head -20` on each note to capture the key fields. Build a mental index of
@@ -174,7 +175,7 @@ For **existing** entities, never rewrite the file. Apply targeted edits:
174
175
 
175
176
  - Add the new activity entry at the **top** of `## Activity` (reverse
176
177
  chronological).
177
- - Update `Last seen`.
178
+ - Update `Last seen`, and stamp frontmatter `updated` in the same edit.
178
179
  - Add new key facts (skip duplicates).
179
180
  - Update open items (mark completed, add new).
180
181
  - Apply state changes to fields.
@@ -2,7 +2,8 @@
2
2
 
3
3
  Use these templates for new knowledge-base notes. One file holds each entity
4
4
  family. This keeps each file under the L5 cap. `anarlog-process` references
5
- this file as the index.
5
+ this file as the index. Every template opens with its YAML frontmatter block
6
+ (core keys plus the type's conditional keys from `registry.yaml`).
6
7
 
7
8
  - [templates-people-orgs.md](templates-people-orgs.md) — People, Organizations.
8
9
  - [templates-projects-topics.md](templates-projects-topics.md) — Projects,
@@ -20,7 +20,7 @@ same constraint or state, suspect a Condition.
20
20
 
21
21
  ## Create a Condition
22
22
 
23
- 1. Check existing: `ls Knowledge/Conditions/ 2>/dev/null`.
23
+ 1. Check existing: `ls 3-Team/Conditions/ 2>/dev/null`.
24
24
  2. **No match:** create a new Condition note with
25
25
  [templates-conditions.md](templates-conditions.md). Give it a descriptive
26
26
  name ("Hiring Freeze Q2", "Division Reorg").
@@ -31,13 +31,13 @@ same constraint or state, suspect a Condition.
31
31
 
32
32
  When you create or update a Condition:
33
33
 
34
- 1. Add `[[Conditions/{Condition}]]` to the `## Affects` section of affected
35
- Priorities.
34
+ 1. Add `[[3-Team/Conditions/{Condition}]]` to the `## Affects` section of
35
+ affected Priorities.
36
36
  2. Add `[Status → on hold]` state changes to affected Projects where
37
37
  appropriate.
38
38
  3. Add a `## Blockers` entry to affected Role files if recruitment is frozen.
39
39
  4. Log the Condition reference in activity entries:
40
- `- **YYYY-MM-DD** ({source}): {update}. See [[Conditions/{Condition}]]`.
40
+ `- **YYYY-MM-DD** ({source}): {update}. See [[3-Team/Conditions/{Condition}]]`.
41
41
 
42
42
  ## Resolve Conditions
43
43
 
@@ -45,7 +45,8 @@ Source content indicates the Condition ended: "approved", "freeze lifted",
45
45
  "reorg complete", "back on track".
46
46
 
47
47
  - Set `**Status:** resolved`, `**Resolved:** {date}`.
48
- - Remove `[[Conditions/{Condition}]]` from affected Priority `## Affects`.
48
+ - Remove `[[3-Team/Conditions/{Condition}]]` from affected Priority
49
+ `## Affects`.
49
50
  - Log with `[Status → resolved]`.
50
51
 
51
52
  ## Conservatism
@@ -1,10 +1,34 @@
1
- # Bidirectional Links
2
-
3
- Reference for `extract-entities` Step 10 and Step 7c (Priorities).
1
+ # Links
2
+
3
+ Reference for `extract-entities` Step 10 and Step 7c (Priorities). Every
4
+ skill that writes wiki links follows the format and overlay rules here.
5
+
6
+ ## Link format
7
+
8
+ - In shared tiers (ranks 1 and up), write every wiki link tier-prefixed and
9
+ vault-absolute: `[[3-Team/People/Sarah Chen]]`,
10
+ `[[2-Confidential/Candidates/Jane Doe/brief]]`. A bare basename
11
+ (`[[Sarah Chen]]`) is a validation finding there, because overlays
12
+ duplicate basenames across tiers.
13
+ - Exemption: relative links between files inside one entity subdirectory (a
14
+ per-candidate folder, an asset collection) stay relative, so the folder
15
+ moves as one unit.
16
+ - Tier-0 notes may use bare basenames.
17
+ - Link legality (own tier or wider only) lives in CLAUDE.md § Placement and
18
+ Links; the validator flags the rest.
19
+
20
+ ## Overlay links
21
+
22
+ A sensitive facet of an entity lives as an **overlay** note in a narrower
23
+ tier. The overlay declares itself through its frontmatter `canonical`
24
+ property: a double-quoted, tier-prefixed, vault-absolute link to the
25
+ canonical note (`canonical: "[[3-Team/People/Jane Doe]]"`). The canonical
26
+ note **never links back**. Backlinks stay symmetric within one tier only; a
27
+ cross-tier reference is one-way, from the narrower note up.
4
28
 
5
29
  ## Bidirectional link rules
6
30
 
7
- After you write, verify each link goes both ways.
31
+ After you write, verify each link goes both ways **within the same tier**.
8
32
 
9
33
  | If you add... | Then also add... |
10
34
  | ---------------------- | -------------------------------------------- |
@@ -13,18 +37,18 @@ After you write, verify each link goes both ways.
13
37
  | Project → Organization | Organization → Project (in Projects section) |
14
38
  | Project → Priority | Priority → Project (in Projects section) |
15
39
  | Condition → Project | Project → Condition (in Related section) |
16
- | ConditionRole | Role Condition (notes or status field) |
40
+ | RoleCondition | nothing the pair crosses tiers |
17
41
 
18
- Use absolute paths everywhere: `[[People/Sarah Chen]]`,
19
- `[[Organizations/Acme Corp]]`, `[[Projects/Acme Integration]]`,
20
- `[[Priorities/Priority Name]]`, `[[Conditions/Condition Name]]`.
42
+ The Role Condition pair crosses tiers (rank 2 → rank 3), so only the
43
+ narrower side links: the Role file may name the Condition, and the Condition
44
+ never names the Role.
21
45
 
22
46
  ## Priorities (Step 7c)
23
47
 
24
48
  Match source themes against priority names and descriptions.
25
49
 
26
- - Add `[[Priorities/{Priority}]]` to a Project or Topic `## Related` section if
27
- it is not already present.
50
+ - Add `[[3-Team/Priorities/{Priority}]]` to a Project or Topic `## Related`
51
+ section if it is not already present.
28
52
  - Update the Priority's `## Projects` section when a new project emerges that
29
53
  serves it.
30
54
 
@@ -1,9 +1,14 @@
1
1
  # Recruitment Inference
2
2
 
3
- Reference for `extract-entities` Step 7b. Enrich `Knowledge/Roles/` and
4
- `Knowledge/Candidates/` with metadata that no single source carries.
3
+ Reference for `extract-entities` Step 7b. Enrich `2-Confidential/Roles/` and
4
+ `2-Confidential/Candidates/` with metadata that no single source carries.
5
5
 
6
- All Role files are flat in `Knowledge/Roles/`. The `**Status:**` field
6
+ Recruitment entities live in tier 2: route Candidates, Prospects, Roles, and
7
+ Erasure records to `2-Confidential/`. A recruitment fact about a `3-Team`
8
+ person lands in the person's `2-Confidential` overlay (a note with a
9
+ `canonical` link up to the `3-Team` note), never in the canonical team note.
10
+
11
+ All Role files are flat in `2-Confidential/Roles/`. The `**Status:**` field
7
12
  distinguishes:
8
13
 
9
14
  - **`Status: open`** — active openings (use for new candidates and table
@@ -15,10 +20,10 @@ distinguishes:
15
20
  Scan email subjects and bodies for requisition numbers (e.g. 7-digit Workday
16
21
  IDs).
17
22
 
18
- 1. `ls Knowledge/Roles/ | grep "{req_number}"` — find out whether a Role file
19
- exists.
23
+ 1. `ls 2-Confidential/Roles/ | grep "{req_number}"` — find out whether a Role
24
+ file exists.
20
25
  2. **No file:** create a stub with the Role-stub template in `req-track` Step
21
- 0b, and set `**Status:** open`. Search `rg "{req_number}" Knowledge/` for
26
+ 0b, and set `**Status:** open`. Search `rg "{req_number}" [0-9]-*/` for
22
27
  context to enrich it.
23
28
  3. **File exists:** check the `**Status:**` field. If `open`, check whether the
24
29
  email provides new metadata (hiring manager, recruiter, locations). Then
@@ -31,11 +36,11 @@ A calendar event title can match an interview pattern ("Interview", "Screening",
31
36
  "Screen", "Decomposition", "Panel", "Technical Assessment", "Candidate") and
32
37
  also carry a person name. When it does:
33
38
 
34
- 1. Cross-reference the candidate against `Knowledge/Candidates/`.
39
+ 1. Cross-reference the candidate against `2-Confidential/Candidates/`.
35
40
  2. Extract the **organizer**. If the organizer isn't the user (per
36
41
  `~/.cache/fit/outpost/state/identity.md`),
37
42
  they are likely the hiring manager.
38
- 3. Confirm the hiring manager. Look up the organizer in `Knowledge/People/` for
43
+ 3. Confirm the hiring manager. Look up the organizer in `3-Team/People/` for
39
44
  an indication of a manager or HM role.
40
45
  4. Check the candidate's `brief.md` for a `Req` field. If you know the req, set
41
46
  the matching Role file's `Hiring manager` (only if it is currently `—`).
@@ -44,9 +49,9 @@ also carry a person name. When it does:
44
49
  ## Recruiter — email-thread inference
45
50
 
46
51
  When a thread references candidates (name match against
47
- `Knowledge/Candidates/`):
52
+ `2-Confidential/Candidates/`):
48
53
 
49
- 1. Cross-reference To/CC against `Knowledge/People/`.
54
+ 1. Cross-reference To/CC against `3-Team/People/`.
50
55
  2. If a CC'd person's note mentions "recruiter", "talent acquisition", or a
51
56
  similar role, they are likely the internal recruiter.
52
57
  3. Update the candidate's `brief.md` recruiter field and the matching Role file
@@ -12,7 +12,7 @@ Extract every way a source refers to each entity.
12
12
  - **Projects:** explicit names, descriptive references ("the pilot", "the
13
13
  deal").
14
14
  - **Priorities:** references to strategic directions, time-bound targets, or
15
- measurable outcomes that match `Knowledge/Priorities/` entries.
15
+ measurable outcomes that match `3-Team/Priorities/` entries.
16
16
 
17
17
  ## Matching
18
18
 
@@ -40,7 +40,7 @@ Never write a placeholder profile. See the
40
40
 
41
41
  ## Process — update existing notes only
42
42
 
43
- - Emails from people already in `Knowledge/People/`.
43
+ - Emails from people already in `3-Team/People/`.
44
44
  - Emails referencing existing projects or organizations.
45
45
 
46
46
  ## Process — can create new notes
@@ -5,6 +5,12 @@ The librarian agent can **auto-create** them when it detects cross-cutting
5
5
  patterns. The user can also create them manually. Lifecycle: active → resolved.
6
6
 
7
7
  ```markdown
8
+ ---
9
+ type: condition
10
+ created: {YYYY-MM-DD}
11
+ updated: {YYYY-MM-DD}
12
+ ---
13
+
8
14
  # {Condition Name}
9
15
 
10
16
  ## Info
@@ -16,10 +22,10 @@ patterns. The user can also create them manually. Lifecycle: active → resolved
16
22
  **Resolution signal:** {What would indicate this condition has ended}
17
23
 
18
24
  ## Affects
19
- {Priorities, Projects, Roles, and People impacted by this condition}
20
- - [[Priorities/{Priority}]]{how it's affected}
21
- - [[Projects/{Project}]] — {how it's affected}
22
- - [[Roles/{Role}]] — {how it's affected}
25
+ {Priorities, Projects, and People impacted by this condition. A Role file
26
+ links here instead a Condition never links into a narrower tier.}
27
+ - [[3-Team/Priorities/{Priority}]] — {how it's affected}
28
+ - [[3-Team/Projects/{Project}]] — {how it's affected}
23
29
 
24
30
  ## Agent implications
25
31
  {How agents should modify their behavior while this condition is active}
@@ -1,16 +1,28 @@
1
1
  # People and Organization Templates
2
2
 
3
+ Every template opens with the YAML frontmatter block: the core keys (`type`,
4
+ `created`, `updated`) plus the type's conditional keys from `registry.yaml`.
5
+ A key lifted into frontmatter (`aliases` here) leaves the body; unmatched
6
+ bold keys stay body prose.
7
+
3
8
  ## People
4
9
 
5
10
  ```markdown
11
+ ---
12
+ type: person
13
+ created: {YYYY-MM-DD}
14
+ updated: {YYYY-MM-DD}
15
+ aliases:
16
+ - "{name variant}"
17
+ ---
18
+
6
19
  # {Full Name}
7
20
 
8
21
  ## Info
9
22
  **Role:** {role or inferred role with qualifier}
10
- **Organization:** [[Organizations/{organization}]]
11
- **Reports to:** [[People/{{Person}}]]
23
+ **Organization:** [[3-Team/Organizations/{organization}]]
24
+ **Reports to:** [[3-Team/People/{{Person}}]]
12
25
  **Email:** {email}
13
- **Aliases:** {comma-separated variants}
14
26
  **First met:** {YYYY-MM-DD}
15
27
  **Last seen:** {YYYY-MM-DD}
16
28
 
@@ -18,12 +30,12 @@
18
30
  {2-3 sentences: who they are, why you know them, what you're working on}
19
31
 
20
32
  ## Connected to
21
- - [[Organizations/{Org}]] — works at
22
- - [[People/{Person}]] — {relationship}
23
- - [[Projects/{Project}]] — {role}
33
+ - [[3-Team/Organizations/{Org}]] — works at
34
+ - [[3-Team/People/{Person}]] — {relationship}
35
+ - [[3-Team/Projects/{Project}]] — {role}
24
36
 
25
37
  ## Activity
26
- - **{YYYY-MM-DD}** ({meeting|email|voice memo}): {Summary with [[Folder/Name]] links}
38
+ - **{YYYY-MM-DD}** ({meeting|email|voice memo}): {Summary with [[3-Team/Folder/Name]] links}
27
39
 
28
40
  ## Key facts
29
41
  {substantive facts only — leave empty if none}
@@ -35,6 +47,14 @@
35
47
  ## Organizations
36
48
 
37
49
  ```markdown
50
+ ---
51
+ type: organization
52
+ created: {YYYY-MM-DD}
53
+ updated: {YYYY-MM-DD}
54
+ aliases:
55
+ - "{name variant}"
56
+ ---
57
+
38
58
  # {Organization Name}
39
59
 
40
60
  ## Info
@@ -42,7 +62,6 @@
42
62
  **Industry:** {industry}
43
63
  **Relationship:** {customer|prospect|partner|vendor}
44
64
  **Domain:** {primary email domain}
45
- **Aliases:** {comma-separated}
46
65
  **First met:** {YYYY-MM-DD}
47
66
  **Last seen:** {YYYY-MM-DD}
48
67
 
@@ -50,13 +69,13 @@
50
69
  {2-3 sentences}
51
70
 
52
71
  ## People
53
- - [[People/{Person}]] — {role}
72
+ - [[3-Team/People/{Person}]] — {role}
54
73
 
55
74
  ## Contacts
56
75
  {for transactional contacts who don't get their own notes}
57
76
 
58
77
  ## Projects
59
- - [[Projects/{Project}]] — {relationship}
78
+ - [[3-Team/Projects/{Project}]] — {relationship}
60
79
 
61
80
  ## Activity
62
81
  - **{YYYY-MM-DD}** ({type}): {Summary}
@@ -8,13 +8,19 @@ on** existing notes.
8
8
  ## Priorities
9
9
 
10
10
  ```markdown
11
+ ---
12
+ type: priority
13
+ created: {YYYY-MM-DD}
14
+ updated: {YYYY-MM-DD}
15
+ ---
16
+
11
17
  # {Priority Name}
12
18
 
13
19
  ## About
14
20
  {2-3 sentences: what this strategic direction means and why it matters}
15
21
 
16
22
  **Status:** {active|paused|retired}
17
- **Owner:** [[People/{Person}]]
23
+ **Owner:** [[3-Team/People/{Person}]]
18
24
  **Set:** {YYYY-MM-DD}
19
25
 
20
26
  ## What this means
@@ -25,7 +31,7 @@ on** existing notes.
25
31
  here — there is no separate Goals entity.}
26
32
 
27
33
  ## Projects
28
- - [[Projects/{Project}]] — {relationship}
34
+ - [[3-Team/Projects/{Project}]] — {relationship}
29
35
 
30
36
  ## Key facts
31
37
  {substantive facts only — leave empty if none}