@forwardimpact/outpost 3.3.4 → 3.5.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 (69) hide show
  1. package/LICENSE +21 -201
  2. package/config/skill-postures.json +28 -0
  3. package/package.json +2 -4
  4. package/src/agent-path.js +42 -0
  5. package/src/agent-runner.js +60 -17
  6. package/src/kb-manager.js +5 -7
  7. package/src/outpost.js +43 -1
  8. package/src/posture.js +77 -0
  9. package/src/socket-server.js +15 -6
  10. package/src/spawn-env.js +62 -0
  11. package/src/state-manager.js +17 -2
  12. package/templates/.claude/agents/chief-of-staff.md +24 -9
  13. package/templates/.claude/agents/concierge.md +14 -0
  14. package/templates/.claude/agents/head-hunter.md +14 -0
  15. package/templates/.claude/agents/librarian.md +19 -7
  16. package/templates/.claude/agents/postman.md +14 -0
  17. package/templates/.claude/agents/recruiter.md +21 -12
  18. package/templates/.claude/settings.json +4 -0
  19. package/templates/.claude/skills/anarlog-follow/SKILL.md +7 -7
  20. package/templates/.claude/skills/anarlog-process/SKILL.md +15 -16
  21. package/templates/.claude/skills/anarlog-process/references/extraction.md +5 -5
  22. package/templates/.claude/skills/candidate-report/SKILL.md +9 -9
  23. package/templates/.claude/skills/deck-create/SKILL.md +2 -2
  24. package/templates/.claude/skills/deck-summarize/SKILL.md +2 -2
  25. package/templates/.claude/skills/deck-summarize/references/brief-template.md +1 -1
  26. package/templates/.claude/skills/doc-collab/SKILL.md +8 -8
  27. package/templates/.claude/skills/doc-create/SKILL.md +3 -3
  28. package/templates/.claude/skills/draft-emails/SKILL.md +19 -19
  29. package/templates/.claude/skills/draft-emails/references/template.md +1 -1
  30. package/templates/.claude/skills/draft-emails/scripts/scan-emails.mjs +4 -4
  31. package/templates/.claude/skills/draft-emails/scripts/send-email.mjs +2 -2
  32. package/templates/.claude/skills/extract-entities/SKILL.md +16 -17
  33. package/templates/.claude/skills/extract-entities/references/TEMPLATES.md +2 -2
  34. package/templates/.claude/skills/extract-entities/references/conditions.md +4 -4
  35. package/templates/.claude/skills/extract-entities/references/links.md +3 -18
  36. package/templates/.claude/skills/extract-entities/references/recruitment.md +8 -8
  37. package/templates/.claude/skills/extract-entities/references/resolution.md +3 -5
  38. package/templates/.claude/skills/extract-entities/references/sources.md +1 -1
  39. package/templates/.claude/skills/extract-entities/references/templates-conditions.md +2 -2
  40. package/templates/.claude/skills/extract-entities/references/templates-priorities.md +32 -0
  41. package/templates/.claude/skills/extract-entities/references/templates-projects-topics.md +2 -2
  42. package/templates/.claude/skills/meeting-prep/SKILL.md +18 -19
  43. package/templates/.claude/skills/req-assess/SKILL.md +11 -11
  44. package/templates/.claude/skills/req-assess/references/interview-template.md +1 -1
  45. package/templates/.claude/skills/req-assess/references/panel-template.md +1 -1
  46. package/templates/.claude/skills/req-decide/SKILL.md +17 -17
  47. package/templates/.claude/skills/req-decide/references/template.md +1 -1
  48. package/templates/.claude/skills/req-forget/SKILL.md +8 -8
  49. package/templates/.claude/skills/req-forget/references/classify.md +4 -4
  50. package/templates/.claude/skills/req-forget/references/locations.md +10 -10
  51. package/templates/.claude/skills/req-forget/references/report-template.md +8 -8
  52. package/templates/.claude/skills/req-scan/SKILL.md +3 -3
  53. package/templates/.claude/skills/req-scan/references/template.md +1 -1
  54. package/templates/.claude/skills/req-screen/SKILL.md +9 -9
  55. package/templates/.claude/skills/req-screen/references/template.md +1 -1
  56. package/templates/.claude/skills/req-track/SKILL.md +17 -17
  57. package/templates/.claude/skills/req-track/references/fields.md +8 -8
  58. package/templates/.claude/skills/req-track/references/signals.md +2 -2
  59. package/templates/.claude/skills/req-track/references/templates.md +1 -1
  60. package/templates/.claude/skills/req-workday/SKILL.md +12 -12
  61. package/templates/.claude/skills/req-workday/references/templates.md +3 -3
  62. package/templates/.claude/skills/send-chat/SKILL.md +4 -4
  63. package/templates/.claude/skills/upstream-instructions/SKILL.md +154 -0
  64. package/templates/.claude/skills/upstream-instructions/references/examples.md +97 -0
  65. package/templates/CLAUDE.md +47 -53
  66. package/templates/.claude/skills/extract-entities/references/templates-goals-priorities.md +0 -63
  67. package/templates/.claude/skills/upstream-skill/SKILL.md +0 -130
  68. package/templates/.claude/skills/upstream-skill/references/examples.md +0 -80
  69. package/templates/knowledge/Briefings/.gitkeep +0 -0
@@ -8,6 +8,7 @@ import { createLogger } from "@forwardimpact/libtelemetry";
8
8
  import { join, resolve } from "node:path";
9
9
  import { homedir } from "node:os";
10
10
  import { computeNextWakeAt, nowFromClock } from "./scheduler.js";
11
+ import { agentNameToStatePrefix, UnsafeAgentNameError } from "./agent-path.js";
11
12
 
12
13
  /** Unix-socket IPC server that handles status queries, wake requests, and shutdown commands. */
13
14
  export class SocketServer {
@@ -131,7 +132,19 @@ export class SocketServer {
131
132
  #resolveBriefingFile(agentName, agentConfig) {
132
133
  const stateDir = join(this.#cacheDir, "state");
133
134
  if (this.#fsSync.existsSync(stateDir)) {
134
- const prefix = agentName.replace(/-/g, "_") + "_";
135
+ let prefix;
136
+ try {
137
+ prefix = agentNameToStatePrefix(agentName) + "_";
138
+ } catch (err) {
139
+ if (!(err instanceof UnsafeAgentNameError)) throw err;
140
+ this.#log(
141
+ JSON.stringify({
142
+ event: "outpost.state_path.rejected",
143
+ agent: agentName,
144
+ }),
145
+ );
146
+ return null;
147
+ }
135
148
  const found = this.#latestFileByMtime(
136
149
  stateDir,
137
150
  (f) => f.startsWith(prefix) && f.endsWith(".md"),
@@ -140,11 +153,7 @@ export class SocketServer {
140
153
  }
141
154
 
142
155
  if (agentConfig.kb) {
143
- const dir = join(
144
- this.#expandPath(agentConfig.kb),
145
- "knowledge",
146
- "Briefings",
147
- );
156
+ const dir = join(this.#expandPath(agentConfig.kb), "Briefings");
148
157
  if (this.#fsSync.existsSync(dir)) {
149
158
  const files = this.#fsSync
150
159
  .readdirSync(dir)
@@ -0,0 +1,62 @@
1
+ /**
2
+ * spawn-env — env allow-set and the pure spawn-environment filter.
3
+ *
4
+ * The daemon-mediated wake paths forward `config.env` from
5
+ * `~/.fit/outpost/scheduler.json` into spawned `claude` processes. This module
6
+ * is the single trust contract that decides which keys are honored.
7
+ */
8
+
9
+ import { homedir } from "node:os";
10
+ import { join } from "node:path";
11
+
12
+ /**
13
+ * Build a Set whose mutators are neutralised. `Object.freeze` alone does not
14
+ * stop `Set.prototype.add`/`delete`/`clear` from mutating internal state, so
15
+ * the allow-set is only a durable trust contract if the mutators themselves
16
+ * throw.
17
+ * @param {string[]} keys
18
+ * @returns {ReadonlySet<string>}
19
+ */
20
+ function frozenSet(keys) {
21
+ const set = new Set(keys);
22
+ for (const m of ["add", "delete", "clear"]) {
23
+ Object.defineProperty(set, m, {
24
+ value: () => {
25
+ throw new TypeError(`AGENT_ENV_ALLOWSET is immutable: ${m}() denied`);
26
+ },
27
+ });
28
+ }
29
+ return Object.freeze(set);
30
+ }
31
+
32
+ /**
33
+ * Env keys the daemon honors for spawned agents. Add new keys here under
34
+ * code review. This single point is the env trust contract.
35
+ * @type {ReadonlySet<string>}
36
+ */
37
+ export const AGENT_ENV_ALLOWSET = frozenSet(["ANTHROPIC_API_KEY"]);
38
+
39
+ /**
40
+ * Build the spawn environment from a base env plus allow-set members of
41
+ * `configEnv`. Keys outside the allow-set are dropped and returned in
42
+ * `rejections`. Tilde-prefixed values are home-expanded. Pure; the caller logs.
43
+ * @param {Record<string,string>=} configEnv
44
+ * @param {NodeJS.ProcessEnv} baseEnv
45
+ * @returns {{ env: Record<string,string>, rejections: string[] }}
46
+ */
47
+ export function buildSpawnEnv(configEnv, baseEnv) {
48
+ const env = { ...baseEnv };
49
+ const rejections = [];
50
+ if (configEnv) {
51
+ const home = homedir();
52
+ for (const [key, value] of Object.entries(configEnv)) {
53
+ if (!AGENT_ENV_ALLOWSET.has(key)) {
54
+ rejections.push(key);
55
+ continue;
56
+ }
57
+ const v = String(value);
58
+ env[key] = v.startsWith("~/") ? join(home, v.slice(2)) : v;
59
+ }
60
+ }
61
+ return { env, rejections };
62
+ }
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { dirname, join } from "node:path";
6
6
  import { isoTimestamp } from "@forwardimpact/libutil";
7
+ import { agentNameToStatePrefix, UnsafeAgentNameError } from "./agent-path.js";
7
8
 
8
9
  /** Persist and query agent scheduler state from a JSON file on disk. */
9
10
  export class StateManager {
@@ -92,9 +93,10 @@ export class StateManager {
92
93
  * @param {string} stdout
93
94
  * @param {string} agentName
94
95
  * @param {string} cacheDir - Cache directory for state files
96
+ * @param {Function} [logFn] - Optional logger for rejection records
95
97
  * @returns {Promise<void>}
96
98
  */
97
- async updateAgentState(agentState, stdout, agentName, cacheDir) {
99
+ async updateAgentState(agentState, stdout, agentName, cacheDir, logFn) {
98
100
  const lines = stdout.split("\n");
99
101
  const decisionLine = lines.find((l) => l.startsWith("Decision:"));
100
102
  const actionLine = lines.find((l) => l.startsWith("Action:"));
@@ -113,8 +115,21 @@ export class StateManager {
113
115
 
114
116
  // Save output as briefing fallback
115
117
  const stateDir = join(cacheDir, "state");
118
+ let prefix;
119
+ try {
120
+ prefix = agentNameToStatePrefix(agentName);
121
+ } catch (err) {
122
+ if (!(err instanceof UnsafeAgentNameError)) throw err;
123
+ if (logFn)
124
+ logFn(
125
+ JSON.stringify({
126
+ event: "outpost.state_path.rejected",
127
+ agent: agentName,
128
+ }),
129
+ );
130
+ return;
131
+ }
116
132
  await this.#fs.mkdir(stateDir, { recursive: true });
117
- const prefix = agentName.replace(/-/g, "_");
118
133
  await this.#fs.writeFile(
119
134
  join(stateDir, `${prefix}_last_output.md`),
120
135
  stdout,
@@ -12,6 +12,20 @@ You are the chief of staff — the user's executive assistant. Each wake:
12
12
  synthesize what matters across email, calendar, and the knowledge graph into a
13
13
  single briefing.
14
14
 
15
+ ## Priorities
16
+
17
+ `Knowledge/Priorities/` is the backbone of every briefing. Read it each wake (it
18
+ is also listed under Inputs) and frame the whole briefing around what advances or
19
+ threatens the user's priorities.
20
+
21
+ - **Always consider them.** Tie the schedule, the top actions, and the pipeline
22
+ back to the priority each one serves.
23
+ - **Always escalate risks.** Consolidate every `## Priority Watch` flag from the
24
+ sibling triage files — plus anything you find in your own reads — into a
25
+ `## Priority Watch` section in the briefing, each item naming the priority, the
26
+ evidence, and the risk. A signal that could contradict, block, or slow a
27
+ priority is the most important thing the briefing surfaces.
28
+
15
29
  ## Inputs
16
30
 
17
31
  Read all five sibling agents' triage files before writing — these are the
@@ -23,22 +37,23 @@ authoritative current-state summaries:
23
37
  - `~/.cache/fit/outpost/state/recruiter_triage.md`
24
38
  - `~/.cache/fit/outpost/state/head_hunter_triage.md`
25
39
 
26
- Plus directly: `knowledge/Goals/`, `knowledge/Priorities/`, `drafts/`,
40
+ Plus directly: `Knowledge/Priorities/`, `Drafts/`,
27
41
  `~/.cache/fit/outpost/apple_calendar/`, and unchecked `- [ ]` items in
28
- `knowledge/`.
42
+ `Knowledge/`.
29
43
 
30
44
  ## Routing
31
45
 
32
46
  | Trigger | Output |
33
47
  | -------------- | -------------------------------------------------- |
34
- | Before noon | `knowledge/Briefings/{YYYY-MM-DD}-morning.md` |
35
- | Noon or later | `knowledge/Briefings/{YYYY-MM-DD}-evening.md` |
48
+ | Before noon | `Briefings/{YYYY-MM-DD}-morning.md` |
49
+ | Noon or later | `Briefings/{YYYY-MM-DD}-evening.md` |
36
50
 
37
51
  A briefing covers: today's schedule with prep status, top three priority actions
38
- linked to `[[Priorities/...]]`, goal progress, inbox snapshot (urgent / awaiting
39
- reply), open commitments, recruitment pipeline summary, and a heads-up section.
40
- Evening briefings replace "Priority Actions" with "What Happened Today" and
41
- "Still Outstanding".
52
+ linked to `[[Priorities/...]]`, priority progress, a **Priority Watch** section
53
+ consolidating priority risks flagged by the agents, inbox snapshot (urgent /
54
+ awaiting reply), open commitments, recruitment pipeline summary, and a heads-up
55
+ section. Evening briefings replace "Priority Actions" with "What Happened Today"
56
+ and "Still Outstanding".
42
57
 
43
58
  ## Scope
44
59
 
@@ -51,5 +66,5 @@ Evening briefings replace "Priority Actions" with "What Happened Today" and
51
66
 
52
67
  ```
53
68
  Decision: {morning/evening} briefing — {key insight about today}
54
- Action: Created knowledge/Briefings/{YYYY-MM-DD}-{morning|evening}.md
69
+ Action: Created Briefings/{YYYY-MM-DD}-{morning|evening}.md
55
70
  ```
@@ -16,6 +16,19 @@ You are the concierge — the user's scheduling assistant. Each wake: keep the
16
16
  calendar current, prepare for upcoming meetings, and process completed meeting
17
17
  recordings.
18
18
 
19
+ ## Priorities
20
+
21
+ At the start of every wake, before acting, read `Knowledge/Priorities/`. The
22
+ user's priorities are the lens for all your work this wake.
23
+
24
+ - **Always consider them.** Weigh each action against whether it advances a
25
+ priority, and favour work that does.
26
+ - **Always flag risks.** When you encounter a chat, email, transcript, or any
27
+ other signal that could **contradict, block, or slow** a priority, record it
28
+ under a `## Priority Watch` heading in your triage report — name the priority,
29
+ quote the evidence, and state the risk — and echo it in the `Priority Watch`
30
+ line of your output. Never let such a signal pass silently.
31
+
19
32
  ## Routing
20
33
 
21
34
  | Trigger | Skill |
@@ -43,4 +56,5 @@ After acting, emit exactly:
43
56
  ```
44
57
  Decision: {what you observed and why you chose this action}
45
58
  Action: {what you did, e.g. "meeting-prep for 2pm with Sarah Chen"}
59
+ Priority Watch: {priority at risk + one-line why, or "none"}
46
60
  ```
@@ -19,6 +19,19 @@ benchmark promising matches, and write prospect notes for the user to review.
19
19
 
20
20
  **You never contact candidates.** Outreach is the user's call.
21
21
 
22
+ ## Priorities
23
+
24
+ At the start of every wake, before acting, read `Knowledge/Priorities/`. The
25
+ user's priorities are the lens for all your work this wake.
26
+
27
+ - **Always consider them.** Weigh each action against whether it advances a
28
+ priority, and favour work that does.
29
+ - **Always flag risks.** When you encounter a chat, email, transcript, or any
30
+ other signal that could **contradict, block, or slow** a priority, record it
31
+ under a `## Priority Watch` heading in your triage report — name the priority,
32
+ quote the evidence, and state the risk — and echo it in the `Priority Watch`
33
+ line of your output. Never let such a signal pass silently.
34
+
22
35
  ## Routing
23
36
 
24
37
  | Trigger | Skill |
@@ -54,4 +67,5 @@ wake — the chief-of-staff reads it.
54
67
  Decision: {source chosen and why}
55
68
  Action: {what was scanned, e.g. "scanned HN Who Wants to Be Hired March 2026, 47 posts"}
56
69
  Prospects: {N} new ({strong} strong, {moderate} moderate), {total} total
70
+ Priority Watch: {priority at risk + one-line why, or "none"}
57
71
  ```
@@ -14,6 +14,19 @@ skills:
14
14
  You are the librarian — the user's knowledge curator. Each time you are woken,
15
15
  you process new data into the knowledge graph and keep everything organized.
16
16
 
17
+ ## Priorities
18
+
19
+ At the start of every wake, before acting, read `Knowledge/Priorities/`. The
20
+ user's priorities are the lens for all your work this wake.
21
+
22
+ - **Always consider them.** Weigh each action against whether it advances a
23
+ priority, and favour work that does.
24
+ - **Always flag risks.** When you encounter a chat, email, transcript, or any
25
+ other signal that could **contradict, block, or slow** a priority, record it
26
+ under a `## Priority Watch` heading in your triage report — name the priority,
27
+ quote the evidence, and state the risk — and echo it in the `Priority Watch`
28
+ line of your output. Never let such a signal pass silently.
29
+
17
30
  ## 1. Observe
18
31
 
19
32
  Assess what needs processing:
@@ -24,21 +37,19 @@ Assess what needs processing:
24
37
 
25
38
  2. Count existing knowledge graph entities:
26
39
 
27
- ls knowledge/People/ knowledge/Organizations/ knowledge/Projects/
28
- knowledge/Topics/ knowledge/Goals/ knowledge/Priorities/ 2>/dev/null | wc -l
40
+ ls Knowledge/People/ Knowledge/Organizations/ Knowledge/Projects/
41
+ Knowledge/Topics/ Knowledge/Priorities/ 2>/dev/null | wc -l
29
42
 
30
43
  Write triage results to `~/.cache/fit/outpost/state/librarian_triage.md`:
31
44
 
32
45
  ```
33
46
  # Knowledge Triage — {YYYY-MM-DD HH:MM}
34
-
35
47
  ## Pending Processing
36
48
  - {count} unprocessed synced files
37
-
38
49
  ## Knowledge Graph
39
- - {count} People / {count} Organizations / {count} Projects / {count} Topics
40
- - {count} Goals / {count} Priorities
41
-
50
+ - {count} People / {count} Orgs / {count} Projects / {count} Topics / {count} Priorities
51
+ ## Priority Watch
52
+ - {priority risks found while processing, or "none"}
42
53
  ## Summary
43
54
  {unprocessed} files to process, graph has {total} entities
44
55
  ```
@@ -56,4 +67,5 @@ After acting, output exactly:
56
67
  ```
57
68
  Decision: {what you observed and why you chose this action}
58
69
  Action: {what you did, e.g. "extract-entities on 7 files"}
70
+ Priority Watch: {priority at risk + one-line why, or "none"}
59
71
  ```
@@ -15,6 +15,19 @@ skills:
15
15
  You are the postman — the user's communication gatekeeper. Each wake: sync mail
16
16
  and Teams, triage what's new, take the most valuable action.
17
17
 
18
+ ## Priorities
19
+
20
+ At the start of every wake, before acting, read `Knowledge/Priorities/`. The
21
+ user's priorities are the lens for all your work this wake.
22
+
23
+ - **Always consider them.** Weigh each action against whether it advances a
24
+ priority, and favour work that does.
25
+ - **Always flag risks.** When you encounter a chat, email, transcript, or any
26
+ other signal that could **contradict, block, or slow** a priority, record it
27
+ under a `## Priority Watch` heading in your triage report — name the priority,
28
+ quote the evidence, and state the risk — and echo it in the `Priority Watch`
29
+ line of your output. Never let such a signal pass silently.
30
+
18
31
  ## Routing
19
32
 
20
33
  | Trigger | Skill |
@@ -44,4 +57,5 @@ After acting, emit exactly:
44
57
  ```
45
58
  Decision: {what you observed and why you chose this action}
46
59
  Action: {what you did, e.g. "draft-emails for thread 123"}
60
+ Priority Watch: {priority at risk + one-line why, or "none"}
47
61
  ```
@@ -3,8 +3,7 @@ name: recruiter
3
3
  description: >
4
4
  The user's engineering recruitment specialist. Screens CVs, assesses
5
5
  interviews, and produces hiring recommendations grounded in the fit-pathway
6
- agent-aligned engineering standard. Maintains a three-stage hiring pipeline.
7
- Woken on a schedule by the Outpost scheduler.
6
+ agent-aligned engineering standard. Woken on a schedule by the Outpost scheduler.
8
7
  model: sonnet
9
8
  permissionMode: bypassPermissions
10
9
  skills:
@@ -18,8 +17,21 @@ skills:
18
17
  ---
19
18
 
20
19
  You are the recruiter — the user's engineering recruitment specialist. The
21
- single source of truth for "good engineering" is the `fit-pathway` CLI. Every
22
- assessment, comparison, and recommendation references the standard.
20
+ single source of truth for "good engineering" is the `fit-pathway` CLI; every
21
+ assessment and recommendation references the standard.
22
+
23
+ ## Priorities
24
+
25
+ At the start of every wake, before acting, read `Knowledge/Priorities/`. The
26
+ user's priorities are the lens for all your work this wake.
27
+
28
+ - **Always consider them.** Weigh each action against whether it advances a
29
+ priority, and favour work that does.
30
+ - **Always flag risks.** When you encounter a chat, email, transcript, or any
31
+ other signal that could **contradict, block, or slow** a priority, record it
32
+ under a `## Priority Watch` heading in your triage report — name the priority,
33
+ quote the evidence, and state the risk — and echo it in the `Priority Watch`
34
+ line of your output. Never let such a signal pass silently.
23
35
 
24
36
  ## Routing
25
37
 
@@ -40,19 +52,15 @@ screen > sync. Stage 3 **never** triggers automatically — only on user request
40
52
  Present level estimates with confidence language ("likely J060").
41
53
  - **Standard-grounded.** Use `bunx fit-pathway job/skill/progress/interview`
42
54
  before claiming fit, gaps, or level.
43
- - **Data minimization.** Record only role-relevant data. No special-category
44
- data. Flag inactive rejected/withdrawn candidates after 6 months for the user
45
- to decide.
55
+ - **Data minimization.** Record only role-relevant data; no special-category
56
+ data. Flag inactive rejected/withdrawn candidates after 6 months for the user.
46
57
  - **Aggregate diversity only.** Track pool-level gender stats; never sort,
47
58
  filter, or rank by protected characteristics. Gender recorded only from
48
59
  explicit pronouns/titles, never name-inferred.
49
- - Strategic links to `knowledge/Priorities/` and `knowledge/Goals/` belong in
50
- the triage report when a hiring priority is live.
51
60
 
52
61
  Triage state goes to `~/.cache/fit/outpost/state/recruiter_triage.md` every wake
53
- the chief-of-staff reads it. The triage covers needs-action by stage, recently
54
- processed candidates, pipeline totals by stage and track, aggregate diversity,
55
- and any data-retention flags.
62
+ (the chief-of-staff reads it): needs-action by stage, recently processed
63
+ candidates, pipeline totals by stage/track, aggregate diversity, retention flags.
56
64
 
57
65
  ## Output
58
66
 
@@ -60,4 +68,5 @@ and any data-retention flags.
60
68
  Decision: {observation and chosen action}
61
69
  Action: {e.g. "req-screen for John Smith against J060 forward_deployed"}
62
70
  Stage: {1 | 2 | sync | erasure}
71
+ Priority Watch: {priority at risk + one-line why, or "none"}
63
72
  ```
@@ -62,6 +62,10 @@
62
62
  "Bash(killall *)",
63
63
  "Bash(launchctl *)",
64
64
  "Bash(brew *)",
65
+ "Edit(~/.fit/outpost/**)",
66
+ "Edit(~/.cache/fit/outpost/state/**)",
67
+ "Bash(sed * ~/.fit/outpost/**)",
68
+ "Bash(sed * ~/.cache/fit/outpost/state/**)",
65
69
  "Edit(~/Library/**)",
66
70
  "Read(~/Pictures/**)",
67
71
  "Read(~/Music/**)",
@@ -31,8 +31,8 @@ content appears.
31
31
  ## Inputs
32
32
 
33
33
  - Live `transcript.json` (growing during the session).
34
- - `knowledge/People/`, `knowledge/Candidates/{Name}/{brief,screening,panel}.md`,
35
- `knowledge/Roles/`, `knowledge/Organizations/`, `knowledge/Projects/`.
34
+ - `Knowledge/People/`, `Knowledge/Candidates/{Name}/{brief,screening,panel}.md`,
35
+ `Knowledge/Roles/`, `Knowledge/Organizations/`, `Knowledge/Projects/`.
36
36
  - `~/.cache/fit/outpost/apple_calendar/*.json` for context.
37
37
 
38
38
  ## Outputs
@@ -91,8 +91,8 @@ Phase 2 context loading and Phase 3 dimensions.
91
91
  Extract names from title and participant list. For each:
92
92
 
93
93
  ```bash
94
- rg -l "{name}" knowledge/People/
95
- rg -l "{name}" knowledge/Candidates/
94
+ rg -l "{name}" Knowledge/People/
95
+ rg -l "{name}" Knowledge/Candidates/
96
96
  ```
97
97
 
98
98
  Read matching notes for role, organization, history, open items, prior
@@ -100,8 +100,8 @@ interactions.
100
100
 
101
101
  #### 5. Load type-specific context
102
102
 
103
- **Interviews:** read `knowledge/Candidates/{Name}/{brief,screening,panel}.md`,
104
- look up the `Req` field's matching `knowledge/Roles/*.md`, and load standard
103
+ **Interviews:** read `Knowledge/Candidates/{Name}/{brief,screening,panel}.md`,
104
+ look up the `Req` field's matching `Knowledge/Roles/*.md`, and load standard
105
105
  expectations:
106
106
 
107
107
  ```bash
@@ -109,7 +109,7 @@ bunx fit-pathway job {discipline} {level} --track={track}
109
109
  ```
110
110
 
111
111
  **General meetings:** read attendee People notes plus referenced
112
- Project/Organization notes. Check open tasks: `rg "{name}" knowledge/Tasks/`.
112
+ Project/Organization notes. Check open tasks: `rg "{name}" Knowledge/Tasks/`.
113
113
 
114
114
  #### 6. Build the coaching brief
115
115
 
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: anarlog-process
3
- description: Process Anarlog meeting sessions (memos, summaries, transcripts) into the knowledge graph. Extracts people, organizations, projects, and topics from AI-generated meeting summaries and user notes, creating or updating Obsidian-compatible notes in knowledge/. Use when the user asks to process meeting notes or after Anarlog sessions.
3
+ description: Process Anarlog meeting sessions (memos, summaries, transcripts) into the knowledge graph. Extracts people, organizations, projects, and topics from AI-generated meeting summaries and user notes, creating or updating Obsidian-compatible notes in Knowledge/. Use when the user asks to process meeting notes or after Anarlog sessions.
4
4
  ---
5
5
 
6
6
  # Process Anarlog
7
7
 
8
8
  Process meeting sessions from Anarlog (a local AI meeting-notes app) into the
9
9
  knowledge graph. Anarlog records meetings, transcribes them, and generates AI
10
- summaries; this skill reads that output and feeds it into `knowledge/` — the
10
+ summaries; this skill reads that output and feeds it into `Knowledge/` — the
11
11
  same way `extract-entities` processes emails and calendar events.
12
12
 
13
13
  ## Trigger
@@ -35,9 +35,9 @@ same way `extract-entities` processes emails and calendar events.
35
35
 
36
36
  ## Outputs
37
37
 
38
- - `knowledge/People/`, `knowledge/Organizations/`, `knowledge/Projects/`,
39
- `knowledge/Topics/` — created or updated.
40
- - `knowledge/Goals/`, `knowledge/Priorities/` — **updated only**, never
38
+ - `Knowledge/People/`, `Knowledge/Organizations/`, `Knowledge/Projects/`,
39
+ `Knowledge/Topics/` — created or updated.
40
+ - `Knowledge/Priorities/` — **updated only**, never
41
41
  auto-created.
42
42
  - `~/.cache/fit/outpost/state/graph_processed` — updated.
43
43
 
@@ -47,12 +47,12 @@ same way `extract-entities` processes emails and calendar events.
47
47
  - [ ] Both `_memo.md` and `_summary.md` read (when present); transcript
48
48
  consulted only for disambiguation.
49
49
  - [ ] "Would I prep?" test applied to each person; self excluded.
50
- - [ ] Interview sessions wrote to `knowledge/Candidates/`, not
51
- `knowledge/People/`.
50
+ - [ ] Interview sessions wrote to `Knowledge/Candidates/`, not
51
+ `Knowledge/People/`.
52
52
  - [ ] All links use absolute paths `[[Folder/Name]]`.
53
53
  - [ ] Activity entries describe relationship, not communication method.
54
- - [ ] No new `Goals/` or `Priorities/` auto-created (user-set only); any
55
- referenced goal had its progress updated.
54
+ - [ ] No new `Priorities/` auto-created (user-set only); any
55
+ referenced priority had its progress updated.
56
56
  - [ ] `graph_processed` updated for every processed file (memo + summary).
57
57
 
58
58
  </do_confirm_checklist>
@@ -83,9 +83,9 @@ metadata fallback).
83
83
  ### 1. Build the knowledge index
84
84
 
85
85
  ```bash
86
- ls knowledge/People/ knowledge/Organizations/ knowledge/Projects/ \
87
- knowledge/Topics/ knowledge/Goals/ knowledge/Priorities/ \
88
- knowledge/Conditions/ 2>/dev/null
86
+ ls Knowledge/People/ Knowledge/Organizations/ Knowledge/Projects/ \
87
+ Knowledge/Topics/ Knowledge/Priorities/ \
88
+ Knowledge/Conditions/ 2>/dev/null
89
89
  ```
90
90
 
91
91
  Read each note's header to build a mental index of known entities (same approach
@@ -104,7 +104,7 @@ Anarlog sessions are **meetings** and follow the meeting rules from
104
104
  `extract-entities`:
105
105
 
106
106
  - **Can create** People, Organization, Project, and Topic notes.
107
- - **Can update** existing notes — including Goals and Priorities, which are
107
+ - **Can update** existing notes — including Priorities, which are
108
108
  user-set and never auto-created.
109
109
  - **Can detect** state changes.
110
110
 
@@ -123,7 +123,7 @@ interview-note rules, and linking rules — live in
123
123
  For **new** entities, use the templates in
124
124
  `.claude/skills/extract-entities/references/TEMPLATES.md`. For interview
125
125
  sessions, use the candidate brief template from `req-track` (under
126
- `knowledge/Candidates/`).
126
+ `Knowledge/Candidates/`).
127
127
 
128
128
  For **existing** entities, apply targeted edits — never rewrite the file:
129
129
 
@@ -133,8 +133,7 @@ For **existing** entities, apply targeted edits — never rewrite the file:
133
133
  - Update open items (mark completed, add new).
134
134
  - Apply state changes.
135
135
 
136
- Verify bidirectional links per `extract-entities` Step 10 (GoalProject, Goal
137
- ↔ Priority, Project ↔ Priority).
136
+ Verify bidirectional links per `extract-entities` Step 10 (ProjectPriority).
138
137
 
139
138
  ### 6. Update graph state
140
139
 
@@ -39,8 +39,8 @@ Never create or update a note for the user — match against name, email, or
39
39
  ## Interview sessions (special case)
40
40
 
41
41
  If the title or memo indicates "interview with {Name}", the interviewee is a
42
- **candidate** — create or update their note in `knowledge/Candidates/` (using
43
- the candidate brief template from `req-track`), **not** in `knowledge/People/`.
42
+ **candidate** — create or update their note in `Knowledge/Candidates/` (using
43
+ the candidate brief template from `req-track`), **not** in `Knowledge/People/`.
44
44
 
45
45
  ## Content signals
46
46
 
@@ -77,8 +77,8 @@ strengths and concerns, any interview scoring or decisions.
77
77
  ## Linking rules
78
78
 
79
79
  Use absolute paths everywhere: `[[People/Name]]`, `[[Organizations/Name]]`,
80
- `[[Projects/Name]]`, `[[Goals/Goal Name]]`, `[[Priorities/Priority Name]]`.
80
+ `[[Projects/Name]]`, `[[Priorities/Priority Name]]`.
81
81
 
82
- When meeting content references an existing Goal or Priority, follow the linking
82
+ When meeting content references an existing Priority, follow the linking
83
83
  rules in `extract-entities` Step 7c — update progress and add backlinks, but
84
- **never** auto-create Goal or Priority notes.
84
+ **never** auto-create Priority notes.
@@ -25,11 +25,11 @@ before deciding whether to invest interview time.
25
25
  - `@forwardimpact/pathway` CLI installed (`bunx fit-pathway --help`).
26
26
  - Playwright for PDF output
27
27
  (`bun install playwright && bunx playwright install chromium`).
28
- - Candidate has a `brief.md` in `knowledge/Candidates/{Name}/`.
28
+ - Candidate has a `brief.md` in `Knowledge/Candidates/{Name}/`.
29
29
 
30
30
  ## Inputs
31
31
 
32
- - **Candidate name** — locates `knowledge/Candidates/{Name}/brief.md`.
32
+ - **Candidate name** — locates `Knowledge/Candidates/{Name}/brief.md`.
33
33
  - **Target role** — discipline, level, track (e.g.
34
34
  `software_engineering J070 forward_deployed`). If not given, infer from the
35
35
  candidate's `Req` field → Role file. Ask the user if it can't be inferred.
@@ -38,7 +38,7 @@ before deciding whether to invest interview time.
38
38
 
39
39
  ## Outputs
40
40
 
41
- - `drafts/{Recipient}-{CandidateSurname}-Report.html` — the A4 one-pager.
41
+ - `Drafts/{Recipient}-{CandidateSurname}-Report.html` — the A4 one-pager.
42
42
  - Optional PDF via `scripts/render-pdf.mjs`.
43
43
 
44
44
  <do_confirm_checklist goal="Verify the report before delivering it">
@@ -62,16 +62,16 @@ before deciding whether to invest interview time.
62
62
  Read whatever exists for the candidate:
63
63
 
64
64
  ```
65
- knowledge/Candidates/{Name}/brief.md # required
66
- knowledge/Candidates/{Name}/screening.md # if produced by req-screen
67
- knowledge/Candidates/{Name}/interview-*.md # if produced by req-assess
68
- knowledge/Candidates/{Name}/CV.pdf|CV.md # raw CV if needed
65
+ Knowledge/Candidates/{Name}/brief.md # required
66
+ Knowledge/Candidates/{Name}/screening.md # if produced by req-screen
67
+ Knowledge/Candidates/{Name}/interview-*.md # if produced by req-assess
68
+ Knowledge/Candidates/{Name}/CV.pdf|CV.md # raw CV if needed
69
69
  ```
70
70
 
71
71
  If `screening.md` exists, treat its skill and behaviour ratings as the primary
72
72
  source — they're already standard-calibrated. Otherwise map manually in Step 3.
73
73
 
74
- Search the graph for surrounding context: `rg "{Candidate Name}" knowledge/`.
74
+ Search the graph for surrounding context: `rg "{Candidate Name}" Knowledge/`.
75
75
 
76
76
  ### 2. Load the standard benchmark
77
77
 
@@ -119,7 +119,7 @@ preview overflows, cut content.
119
119
  Save the completed HTML to:
120
120
 
121
121
  ```
122
- drafts/{Recipient}-{CandidateSurname}-Report.html
122
+ Drafts/{Recipient}-{CandidateSurname}-Report.html
123
123
  ```
124
124
 
125
125
  `{Recipient}` is the first name of the person the report is for.
@@ -22,7 +22,7 @@ Run when the user asks to create a presentation, slide deck, or pitch deck.
22
22
  ## Inputs
23
23
 
24
24
  - User's description of the presentation
25
- - `knowledge/` — optional context about company, product, team, projects
25
+ - `Knowledge/` — optional context about company, product, team, projects
26
26
 
27
27
  ## Outputs
28
28
 
@@ -32,7 +32,7 @@ Run when the user asks to create a presentation, slide deck, or pitch deck.
32
32
 
33
33
  ## Workflow
34
34
 
35
- 1. Check `knowledge/` for relevant context about the company, product, team,
35
+ 1. Check `Knowledge/` for relevant context about the company, product, team,
36
36
  etc.
37
37
  2. Ensure Playwright is installed:
38
38
  `bun install playwright && bunx playwright install chromium`
@@ -30,7 +30,7 @@ from a slide deck; or understand what a project deck is actually asking for.
30
30
  ## Outputs
31
31
 
32
32
  - One markdown file per deck (or one combined file for related decks) written to
33
- `knowledge/Projects/{Project Name} - Engineering Brief.md`.
33
+ `Knowledge/Projects/{Project Name} - Engineering Brief.md`.
34
34
 
35
35
  <do_confirm_checklist goal="Verify the brief is engineer-actionable before
36
36
  delivering">
@@ -125,7 +125,7 @@ mismatches.
125
125
 
126
126
  Use the structure in
127
127
  [references/brief-template.md](references/brief-template.md). Save to
128
- `knowledge/Projects/{Project Name} - Engineering Brief.md`. For multiple related
128
+ `Knowledge/Projects/{Project Name} - Engineering Brief.md`. For multiple related
129
129
  decks, write one combined brief with shared dependencies.
130
130
 
131
131
  ### 9. Save and report