@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.
- package/package.json +3 -2
- package/src/kb-manager.js +58 -5
- package/src/kb-validator.js +762 -0
- package/src/outpost.js +73 -8
- package/templates/.claude/agents/chief-of-staff.md +14 -6
- package/templates/.claude/agents/concierge.md +9 -2
- package/templates/.claude/agents/head-hunter.md +9 -2
- package/templates/.claude/agents/librarian.md +11 -4
- package/templates/.claude/agents/postman.md +9 -2
- package/templates/.claude/agents/recruiter.md +9 -2
- package/templates/.claude/skills/anarlog-follow/SKILL.md +53 -29
- package/templates/.claude/skills/anarlog-follow/references/sessions.md +52 -0
- package/templates/.claude/skills/anarlog-process/SKILL.md +88 -45
- package/templates/.claude/skills/anarlog-process/references/extraction.md +19 -11
- package/templates/.claude/skills/anarlog-process/references/sessions.md +92 -58
- package/templates/.claude/skills/anarlog-process/scripts/scan.mjs +404 -163
- package/templates/.claude/skills/candidate-report/SKILL.md +12 -9
- package/templates/.claude/skills/changelog/SKILL.md +106 -56
- package/templates/.claude/skills/deck-create/SKILL.md +60 -2
- package/templates/.claude/skills/deck-review/SKILL.md +4 -1
- package/templates/.claude/skills/deck-summarize/SKILL.md +6 -2
- package/templates/.claude/skills/deck-summarize/references/brief-template.md +1 -1
- package/templates/.claude/skills/doc-collab/SKILL.md +16 -11
- package/templates/.claude/skills/doc-create/SKILL.md +6 -3
- package/templates/.claude/skills/draft-emails/SKILL.md +31 -25
- package/templates/.claude/skills/draft-emails/references/template.md +1 -1
- package/templates/.claude/skills/draft-emails/scripts/scan-emails.mjs +14 -8
- package/templates/.claude/skills/draft-emails/scripts/send-email.mjs +9 -3
- package/templates/.claude/skills/extract-entities/SKILL.md +17 -16
- package/templates/.claude/skills/extract-entities/references/TEMPLATES.md +2 -1
- package/templates/.claude/skills/extract-entities/references/conditions.md +6 -5
- package/templates/.claude/skills/extract-entities/references/links.md +34 -10
- package/templates/.claude/skills/extract-entities/references/recruitment.md +15 -10
- package/templates/.claude/skills/extract-entities/references/resolution.md +1 -1
- package/templates/.claude/skills/extract-entities/references/sources.md +1 -1
- package/templates/.claude/skills/extract-entities/references/templates-conditions.md +10 -4
- package/templates/.claude/skills/extract-entities/references/templates-people-orgs.md +29 -10
- package/templates/.claude/skills/extract-entities/references/templates-priorities.md +8 -2
- package/templates/.claude/skills/extract-entities/references/templates-projects-topics.md +19 -7
- package/templates/.claude/skills/meeting-prep/SKILL.md +23 -18
- package/templates/.claude/skills/organize-files/SKILL.md +3 -0
- package/templates/.claude/skills/person-identify/SKILL.md +58 -10
- package/templates/.claude/skills/person-identify/scripts/identify.sh +110 -11
- package/templates/.claude/skills/person-lookup/SKILL.md +8 -3
- package/templates/.claude/skills/person-lookup/scripts/lookup.sh +27 -1
- package/templates/.claude/skills/req-assess/SKILL.md +19 -11
- package/templates/.claude/skills/req-assess/references/interview-template.md +6 -1
- package/templates/.claude/skills/req-assess/references/panel-template.md +5 -1
- package/templates/.claude/skills/req-bundle/SKILL.md +164 -0
- package/templates/.claude/skills/req-bundle/references/matching.md +70 -0
- package/templates/.claude/skills/req-bundle/references/pdf-structure.md +74 -0
- package/templates/.claude/skills/req-bundle/scripts/split-bundle.mjs +377 -0
- package/templates/.claude/skills/req-decide/SKILL.md +26 -18
- package/templates/.claude/skills/req-decide/references/template.md +2 -2
- package/templates/.claude/skills/req-forget/SKILL.md +39 -22
- package/templates/.claude/skills/req-forget/references/classify.md +12 -10
- package/templates/.claude/skills/req-forget/references/locations.md +27 -22
- package/templates/.claude/skills/req-forget/references/report-template.md +23 -15
- package/templates/.claude/skills/req-scan/SKILL.md +6 -3
- package/templates/.claude/skills/req-scan/references/template.md +11 -1
- package/templates/.claude/skills/req-screen/SKILL.md +78 -34
- package/templates/.claude/skills/req-screen/references/rubric.md +38 -42
- package/templates/.claude/skills/req-screen/references/scoring.md +79 -0
- package/templates/.claude/skills/req-screen/references/template.md +26 -14
- package/templates/.claude/skills/req-track/SKILL.md +44 -44
- package/templates/.claude/skills/req-track/references/fields.md +18 -15
- package/templates/.claude/skills/req-track/references/overlays.md +42 -0
- package/templates/.claude/skills/req-track/references/signals.md +2 -2
- package/templates/.claude/skills/req-track/references/templates.md +28 -27
- package/templates/.claude/skills/req-workday/SKILL.md +49 -20
- package/templates/.claude/skills/req-workday/references/brief.md +81 -0
- package/templates/.claude/skills/req-workday/references/templates.md +6 -73
- package/templates/.claude/skills/req-workday/references/xlsx-format.md +19 -0
- package/templates/.claude/skills/req-workday/scripts/parse-workday.mjs +96 -20
- package/templates/.claude/skills/send-chat/SKILL.md +11 -11
- package/templates/.claude/skills/sync-apple-calendar/SKILL.md +3 -0
- package/templates/.claude/skills/sync-apple-mail/SKILL.md +3 -0
- package/templates/.claude/skills/sync-teams/SKILL.md +3 -0
- package/templates/.claude/skills/upstream-instructions/SKILL.md +8 -5
- package/templates/.claude/skills/upstream-instructions/references/examples.md +3 -3
- package/templates/CLAUDE.md +96 -87
- package/templates/MIGRATION.md +359 -0
- package/templates/registry.yaml +25 -0
- package/templates/.claude/skills/anarlog-follow/scripts/follow.mjs +0 -243
- 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 | `
|
|
26
|
-
| Organizations | `
|
|
27
|
-
| Email threads | `~/.cache/fit/outpost/apple_mail/*.md`
|
|
28
|
-
| Calendar events | `~/.cache/fit/outpost/apple_calendar/*.json`
|
|
29
|
-
| Handled IDs |
|
|
30
|
-
| Ignored IDs |
|
|
31
|
-
| Draft files | `
|
|
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 `
|
|
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 `
|
|
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
|
-
`
|
|
69
|
+
the `handled` or `ignored` ledger).
|
|
65
70
|
|
|
66
71
|
### 2. Classify
|
|
67
72
|
|
|
68
|
-
**Ignore** (append ID to
|
|
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
|
|
83
|
+
Before you draft, look up the sender and the organization in the graph:
|
|
79
84
|
|
|
80
85
|
```bash
|
|
81
|
-
rg -l "sender_name"
|
|
82
|
-
cat "
|
|
83
|
-
cat "
|
|
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 `
|
|
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 `
|
|
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 "
|
|
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 `
|
|
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
|
-
|
|
144
|
-
|
|
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
|
```
|
|
@@ -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
|
|
7
|
-
*
|
|
8
|
-
* email_id<TAB>subject. The
|
|
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
|
|
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
|
-
|
|
54
|
-
const
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
- `
|
|
39
|
-
`
|
|
40
|
-
- `
|
|
41
|
-
|
|
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
|
-
- `
|
|
45
|
-
inferred metadata. Create new role stubs with `**Status:** open`. Update
|
|
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 `[[
|
|
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
|
|
95
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
#
|
|
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
|
-
|
|
|
40
|
+
| Role → Condition | nothing — the pair crosses tiers |
|
|
17
41
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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`
|
|
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 `
|
|
4
|
-
`
|
|
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
|
-
|
|
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
|
|
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}"
|
|
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 `
|
|
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 `
|
|
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
|
-
`
|
|
52
|
+
`2-Confidential/Candidates/`):
|
|
48
53
|
|
|
49
|
-
1. Cross-reference To/CC against `
|
|
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 `
|
|
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 `
|
|
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,
|
|
20
|
-
|
|
21
|
-
- [[
|
|
22
|
-
- [[
|
|
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}
|