@forwardimpact/outpost 3.0.3
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/LICENSE +201 -0
- package/README.md +15 -0
- package/bin/fit-outpost.js +3 -0
- package/config/scheduler.json +34 -0
- package/package.json +63 -0
- package/src/agent-runner.js +189 -0
- package/src/index.js +5 -0
- package/src/kb-manager.js +228 -0
- package/src/outpost.js +417 -0
- package/src/scheduler.js +195 -0
- package/src/socket-server.js +336 -0
- package/src/state-manager.js +126 -0
- package/templates/.claude/agents/chief-of-staff.md +58 -0
- package/templates/.claude/agents/concierge.md +46 -0
- package/templates/.claude/agents/head-hunter.md +57 -0
- package/templates/.claude/agents/librarian.md +60 -0
- package/templates/.claude/agents/postman.md +47 -0
- package/templates/.claude/agents/recruiter.md +63 -0
- package/templates/.claude/settings.json +88 -0
- package/templates/.claude/skills/candidate-report/SKILL.md +139 -0
- package/templates/.claude/skills/candidate-report/references/report-template.html +203 -0
- package/templates/.claude/skills/candidate-report/references/report.css +438 -0
- package/templates/.claude/skills/candidate-report/references/rubric.md +76 -0
- package/templates/.claude/skills/candidate-report/scripts/render-pdf.mjs +48 -0
- package/templates/.claude/skills/deck-create/SKILL.md +75 -0
- package/templates/.claude/skills/deck-create/references/slide.css +35 -0
- package/templates/.claude/skills/deck-create/scripts/convert-to-pdf.mjs +47 -0
- package/templates/.claude/skills/deck-summarize/SKILL.md +139 -0
- package/templates/.claude/skills/deck-summarize/references/brief-template.md +85 -0
- package/templates/.claude/skills/deck-summarize/scripts/extract-pptx.mjs +210 -0
- package/templates/.claude/skills/doc-collab/SKILL.md +112 -0
- package/templates/.claude/skills/doc-create/SKILL.md +105 -0
- package/templates/.claude/skills/doc-create/scripts/convert-to-pdf.mjs +50 -0
- package/templates/.claude/skills/draft-emails/SKILL.md +141 -0
- package/templates/.claude/skills/draft-emails/references/template.md +26 -0
- package/templates/.claude/skills/draft-emails/scripts/scan-emails.mjs +66 -0
- package/templates/.claude/skills/draft-emails/scripts/send-email.mjs +139 -0
- package/templates/.claude/skills/extract-entities/SKILL.md +187 -0
- package/templates/.claude/skills/extract-entities/references/TEMPLATES.md +14 -0
- package/templates/.claude/skills/extract-entities/references/conditions.md +55 -0
- package/templates/.claude/skills/extract-entities/references/content.md +104 -0
- package/templates/.claude/skills/extract-entities/references/links.md +48 -0
- package/templates/.claude/skills/extract-entities/references/recruitment.md +57 -0
- package/templates/.claude/skills/extract-entities/references/resolution.md +71 -0
- package/templates/.claude/skills/extract-entities/references/sources.md +70 -0
- package/templates/.claude/skills/extract-entities/references/templates-conditions.md +36 -0
- package/templates/.claude/skills/extract-entities/references/templates-goals-priorities.md +63 -0
- package/templates/.claude/skills/extract-entities/references/templates-people-orgs.md +67 -0
- package/templates/.claude/skills/extract-entities/references/templates-projects-topics.md +68 -0
- package/templates/.claude/skills/extract-entities/scripts/state.mjs +131 -0
- package/templates/.claude/skills/hyprnote-follow/SKILL.md +174 -0
- package/templates/.claude/skills/hyprnote-follow/references/coaching.md +118 -0
- package/templates/.claude/skills/hyprnote-follow/references/debrief.md +59 -0
- package/templates/.claude/skills/hyprnote-follow/references/meeting-types.md +14 -0
- package/templates/.claude/skills/hyprnote-follow/scripts/follow.mjs +243 -0
- package/templates/.claude/skills/hyprnote-process/SKILL.md +147 -0
- package/templates/.claude/skills/hyprnote-process/references/extraction.md +84 -0
- package/templates/.claude/skills/hyprnote-process/references/sessions.md +81 -0
- package/templates/.claude/skills/hyprnote-process/scripts/scan.mjs +246 -0
- package/templates/.claude/skills/hyprnote-trim/SKILL.md +177 -0
- package/templates/.claude/skills/manage-tasks/SKILL.md +152 -0
- package/templates/.claude/skills/manage-tasks/references/format.md +73 -0
- package/templates/.claude/skills/meeting-prep/SKILL.md +180 -0
- package/templates/.claude/skills/organize-files/SKILL.md +146 -0
- package/templates/.claude/skills/organize-files/scripts/organize-by-type.mjs +105 -0
- package/templates/.claude/skills/organize-files/scripts/summarize.mjs +91 -0
- package/templates/.claude/skills/req-assess/SKILL.md +137 -0
- package/templates/.claude/skills/req-assess/references/interview-template.md +62 -0
- package/templates/.claude/skills/req-assess/references/panel-template.md +117 -0
- package/templates/.claude/skills/req-assess/references/rubric.md +65 -0
- package/templates/.claude/skills/req-decide/SKILL.md +163 -0
- package/templates/.claude/skills/req-decide/references/rubric.md +63 -0
- package/templates/.claude/skills/req-decide/references/template.md +118 -0
- package/templates/.claude/skills/req-forget/SKILL.md +154 -0
- package/templates/.claude/skills/req-forget/references/classify.md +23 -0
- package/templates/.claude/skills/req-forget/references/locations.md +59 -0
- package/templates/.claude/skills/req-forget/references/report-template.md +67 -0
- package/templates/.claude/skills/req-scan/SKILL.md +145 -0
- package/templates/.claude/skills/req-scan/references/fallbacks.md +76 -0
- package/templates/.claude/skills/req-scan/references/filters.md +83 -0
- package/templates/.claude/skills/req-scan/references/sources.md +76 -0
- package/templates/.claude/skills/req-scan/references/state.md +54 -0
- package/templates/.claude/skills/req-scan/references/template.md +36 -0
- package/templates/.claude/skills/req-scan/scripts/state.mjs +396 -0
- package/templates/.claude/skills/req-screen/SKILL.md +151 -0
- package/templates/.claude/skills/req-screen/references/rubric.md +94 -0
- package/templates/.claude/skills/req-screen/references/template.md +91 -0
- package/templates/.claude/skills/req-track/SKILL.md +189 -0
- package/templates/.claude/skills/req-track/references/fields.md +114 -0
- package/templates/.claude/skills/req-track/references/signals.md +42 -0
- package/templates/.claude/skills/req-track/references/statuses.md +32 -0
- package/templates/.claude/skills/req-track/references/templates.md +127 -0
- package/templates/.claude/skills/req-workday/SKILL.md +162 -0
- package/templates/.claude/skills/req-workday/references/field-mapping.md +40 -0
- package/templates/.claude/skills/req-workday/references/status-mapping.md +38 -0
- package/templates/.claude/skills/req-workday/references/templates.md +126 -0
- package/templates/.claude/skills/req-workday/references/xlsx-format.md +56 -0
- package/templates/.claude/skills/req-workday/scripts/parse-workday.mjs +313 -0
- package/templates/.claude/skills/send-chat/SKILL.md +170 -0
- package/templates/.claude/skills/sync-apple-calendar/SKILL.md +145 -0
- package/templates/.claude/skills/sync-apple-calendar/references/SCHEMA.md +80 -0
- package/templates/.claude/skills/sync-apple-calendar/scripts/query.mjs +307 -0
- package/templates/.claude/skills/sync-apple-calendar/scripts/sync.mjs +332 -0
- package/templates/.claude/skills/sync-apple-mail/SKILL.md +151 -0
- package/templates/.claude/skills/sync-apple-mail/references/SCHEMA.md +115 -0
- package/templates/.claude/skills/sync-apple-mail/scripts/parse-emlx.mjs +389 -0
- package/templates/.claude/skills/sync-apple-mail/scripts/sync-helpers.mjs +372 -0
- package/templates/.claude/skills/sync-apple-mail/scripts/sync.mjs +239 -0
- package/templates/.claude/skills/sync-teams/SKILL.md +177 -0
- package/templates/.claude/skills/sync-teams/scripts/idb-reader.mjs +147 -0
- package/templates/.claude/skills/sync-teams/scripts/leveldb-reader.mjs +288 -0
- package/templates/.claude/skills/sync-teams/scripts/sync.mjs +381 -0
- package/templates/.claude/skills/upstream-skill/SKILL.md +130 -0
- package/templates/.claude/skills/upstream-skill/references/examples.md +80 -0
- package/templates/.claude/skills/weekly-update/SKILL.md +141 -0
- package/templates/.claude/skills/weekly-update/references/template.md +55 -0
- package/templates/CLAUDE.md +134 -0
- package/templates/USER.md +3 -0
- package/templates/apm.yml +5 -0
- package/templates/knowledge/Briefings/.gitkeep +0 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Screening Rubric
|
|
2
|
+
|
|
3
|
+
Reference data for `req-screen` Steps 1, 3, 4, 5, and 6 (recommendation).
|
|
4
|
+
|
|
5
|
+
## What to extract from the CV
|
|
6
|
+
|
|
7
|
+
| Field | What to look for |
|
|
8
|
+
| ----------------------- | -------------------------------------------------------------- |
|
|
9
|
+
| **Current role** | Most recent job title |
|
|
10
|
+
| **Years of experience** | Total and per-role tenure |
|
|
11
|
+
| **Technical skills** | Languages, platforms, agent-aligned standards, tools mentioned |
|
|
12
|
+
| **Domain experience** | Industries, business domains, customer-facing work |
|
|
13
|
+
| **Education** | Degrees, certifications, relevant courses |
|
|
14
|
+
| **Leadership signals** | Team size, mentoring, cross-team work, architecture |
|
|
15
|
+
| **Scope signals** | Scale of systems, user base, revenue impact |
|
|
16
|
+
| **Communication** | Publications, talks, open source, documentation |
|
|
17
|
+
| **Gender** | Pronouns or gendered titles only — never inferred from names |
|
|
18
|
+
|
|
19
|
+
## Level estimation heuristics
|
|
20
|
+
|
|
21
|
+
| CV signal | Likely level |
|
|
22
|
+
| -------------------------------------------- | ---------------- |
|
|
23
|
+
| 0–2 years, junior titles, learning signals | J040 (Level I) |
|
|
24
|
+
| 2–5 years, mid-level titles, independent | J060 (Level II) |
|
|
25
|
+
| 5–8 years, senior titles, mentoring signals | J070 (Level III) |
|
|
26
|
+
| 8–12 years, staff/lead titles, area scope | J090 (Staff) |
|
|
27
|
+
| 12+ years, principal titles, org-wide impact | J100 (Principal) |
|
|
28
|
+
|
|
29
|
+
## Track-fit signals
|
|
30
|
+
|
|
31
|
+
| Forward Deployed signals | Platform signals |
|
|
32
|
+
| ------------------------------------ | --------------------------------------- |
|
|
33
|
+
| Customer-facing projects | Internal tooling / shared services |
|
|
34
|
+
| Business domain immersion | Infrastructure / platform-as-product |
|
|
35
|
+
| Rapid prototyping, MVPs | Architecture, system design |
|
|
36
|
+
| Data integration, analytics | CI/CD, DevOps, reliability |
|
|
37
|
+
| Stakeholder management | Code quality, technical-debt management |
|
|
38
|
+
| Cross-functional work | Scalability, performance engineering |
|
|
39
|
+
| Multiple industries / domain breadth | Deep platform ownership |
|
|
40
|
+
|
|
41
|
+
## Proficiency mapping
|
|
42
|
+
|
|
43
|
+
| Proficiency | CV evidence |
|
|
44
|
+
| -------------- | ------------------------------------------------------- |
|
|
45
|
+
| `awareness` | Mentioned but no project evidence |
|
|
46
|
+
| `foundational` | Used in projects, basic application |
|
|
47
|
+
| `working` | Primary tool/skill in multiple roles, independent usage |
|
|
48
|
+
| `practitioner` | Led teams using this skill, mentored others, deep work |
|
|
49
|
+
| `expert` | Published, shaped org practice, industry recognition |
|
|
50
|
+
|
|
51
|
+
### Scepticism rule
|
|
52
|
+
|
|
53
|
+
CVs inflate. Default **two levels below** what the CV implies unless the
|
|
54
|
+
candidate provides concrete, quantified evidence (metrics, named systems, team
|
|
55
|
+
sizes, user/revenue scale). Vague phrases like "improved performance" or "led
|
|
56
|
+
initiatives" do not count. A skill listed only in a "Skills" section with no
|
|
57
|
+
project context is `awareness` at most.
|
|
58
|
+
|
|
59
|
+
## Behaviour signals
|
|
60
|
+
|
|
61
|
+
| Behaviour | CV evidence |
|
|
62
|
+
| -------------------------- | -------------------------------------------------- |
|
|
63
|
+
| Own the Outcome | End-to-end ownership, P&L impact, delivery metrics |
|
|
64
|
+
| Think in Systems | Architecture decisions, system-wide reasoning |
|
|
65
|
+
| Communicate with Precision | Technical writing, documentation, talks |
|
|
66
|
+
| Be Polymath Oriented | Cross-domain work, diverse tech stack |
|
|
67
|
+
| Don't Lose Your Curiosity | Side projects, continuous learning, certifications |
|
|
68
|
+
|
|
69
|
+
## Skill alignment classification
|
|
70
|
+
|
|
71
|
+
- **Strong match** — meets or exceeds expected proficiency **and** evidence is
|
|
72
|
+
concrete (metrics, project specifics, scope indicators).
|
|
73
|
+
- **Adequate** — exactly one level below expected with clear project evidence,
|
|
74
|
+
**or** at level but evidence thin.
|
|
75
|
+
- **Gap** — two or more levels below expected.
|
|
76
|
+
- **Not evidenced** — CV doesn't mention this skill area. **Treat as a gap**:
|
|
77
|
+
absence of evidence is not evidence of skill.
|
|
78
|
+
|
|
79
|
+
## Recommendation decision rules
|
|
80
|
+
|
|
81
|
+
| Recommendation | Criteria |
|
|
82
|
+
| ------------------------------ | ------------------------------------------------------------------------ |
|
|
83
|
+
| **Interview** | ≥ 70 % Strong match, no core-skill gaps, strong behaviour signals |
|
|
84
|
+
| **Interview with focus areas** | ≥ 50 % Strong match, ≤ 2 gaps in non-core skills, no behaviour red flags |
|
|
85
|
+
| **Pass** | Everything else — including thin evidence |
|
|
86
|
+
|
|
87
|
+
**Threshold rule:** if more than **one third** of the target job's skills are
|
|
88
|
+
Gap or Not evidenced, the candidate cannot receive "Interview." If more than
|
|
89
|
+
**half** are Gap or Not evidenced, the candidate cannot receive "Interview with
|
|
90
|
+
focus areas."
|
|
91
|
+
|
|
92
|
+
When in doubt, choose the stricter recommendation. "Interview with focus areas"
|
|
93
|
+
should be rare — strong candidate with a specific, named concern, not a marginal
|
|
94
|
+
candidate.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Screening Output Template
|
|
2
|
+
|
|
3
|
+
Reference template for `req-screen` Step 6. Save to
|
|
4
|
+
`knowledge/Candidates/{Name}/screening.md`. Filename **must** be `screening.md`
|
|
5
|
+
— not `assessment.md`, `cv-screening.md`, or any variant. If a misnamed
|
|
6
|
+
screening file exists in the folder (look for `# CV Screening` in the header),
|
|
7
|
+
delete it after writing.
|
|
8
|
+
|
|
9
|
+
```markdown
|
|
10
|
+
# CV Screening — {Full Name}
|
|
11
|
+
|
|
12
|
+
**Assessed against:** {Discipline} {Level} — {Track}
|
|
13
|
+
**Req:** {Req number and title, or "—"}
|
|
14
|
+
**Hiring manager:** {Name from Role file, or "—"}
|
|
15
|
+
**Domain lead:** {Name from Role file, or "—"}
|
|
16
|
+
**Date:** {YYYY-MM-DD}
|
|
17
|
+
**CV source:** [{filename}](./{filename})
|
|
18
|
+
|
|
19
|
+
## Summary
|
|
20
|
+
|
|
21
|
+
{2–3 sentences: overall fit, key strengths, primary concerns. Frame
|
|
22
|
+
around the screening question — is this worth an interview?}
|
|
23
|
+
|
|
24
|
+
## Estimated Profile
|
|
25
|
+
|
|
26
|
+
| Dimension | Assessment |
|
|
27
|
+
| -------------- | -------------------------------------- |
|
|
28
|
+
| **Level** | {estimated level and confidence} |
|
|
29
|
+
| **Track fit** | {forward_deployed / platform / either} |
|
|
30
|
+
| **Discipline** | {best discipline match} |
|
|
31
|
+
| **Gender** | {Woman / Man / —} |
|
|
32
|
+
|
|
33
|
+
## Skill Alignment
|
|
34
|
+
|
|
35
|
+
Standard reference: `{discipline} {level} --track={track}`
|
|
36
|
+
|
|
37
|
+
| Skill | Expected | Estimated | Status |
|
|
38
|
+
| --- | --- | --- | --- |
|
|
39
|
+
| {skill} | {standard level} | {CV-based estimate} | {✅ Strong / 🟡 Adequate / ❌ Gap / ⬜ Not evidenced} |
|
|
40
|
+
|
|
41
|
+
### Key Strengths
|
|
42
|
+
- {Strength 1 — with CV evidence}
|
|
43
|
+
- {Strength 2 — with CV evidence}
|
|
44
|
+
|
|
45
|
+
### Key Gaps
|
|
46
|
+
- {Gap 1 — what's missing and why it matters}
|
|
47
|
+
- {Gap 2 — what's missing and why it matters}
|
|
48
|
+
|
|
49
|
+
## Behaviour Indicators
|
|
50
|
+
|
|
51
|
+
| Behaviour | Expected Maturity | CV Evidence | Signal |
|
|
52
|
+
| --- | --- | --- | --- |
|
|
53
|
+
| {behaviour} | {maturity} | {evidence or "—"} | {Strong / Weak / None} |
|
|
54
|
+
|
|
55
|
+
## Track Fit Analysis
|
|
56
|
+
|
|
57
|
+
{Paragraph explaining why the candidate fits forward_deployed,
|
|
58
|
+
platform, or either. Reference specific CV evidence.}
|
|
59
|
+
|
|
60
|
+
## Screening Recommendation
|
|
61
|
+
|
|
62
|
+
**⚠️ Advisory only — human decision required.**
|
|
63
|
+
|
|
64
|
+
**Recommendation:** {Interview / Interview with focus areas / Pass}
|
|
65
|
+
|
|
66
|
+
**Rationale:** {3–5 sentences grounded in standard data. Cite specific
|
|
67
|
+
gaps or strengths, the skill match percentage, and the gap count.}
|
|
68
|
+
|
|
69
|
+
## Interview Focus Areas
|
|
70
|
+
|
|
71
|
+
{Only when the recommendation is Interview or Interview with focus
|
|
72
|
+
areas. These are uncertainties the interviews must resolve.}
|
|
73
|
+
|
|
74
|
+
- **{Area 1}:** {What to probe and why — link to a specific gap or thin
|
|
75
|
+
evidence}
|
|
76
|
+
- **{Area 2}:** {What to probe and why}
|
|
77
|
+
|
|
78
|
+
### Suggested Interview Questions
|
|
79
|
+
|
|
80
|
+
Generate with `bunx fit-pathway interview {discipline} {level}
|
|
81
|
+
--track={track}`. Pick 3–5 questions most relevant to the gaps and
|
|
82
|
+
focus areas; note which gap each targets.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Brief link
|
|
86
|
+
|
|
87
|
+
In `brief.md`, link the screening with this exact text:
|
|
88
|
+
|
|
89
|
+
```markdown
|
|
90
|
+
- [CV Screening](./screening.md)
|
|
91
|
+
```
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: req-track
|
|
3
|
+
description: Scan synced email threads for recruitment candidates, extract structured profiles, and create/update notes in knowledge/Candidates/. Use when the user asks to track candidates, process recruitment emails, or update the hiring pipeline.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Track Candidates
|
|
7
|
+
|
|
8
|
+
Scan synced email threads from `~/.cache/fit/outpost/apple_mail/` for
|
|
9
|
+
recruitment candidates. Extract structured candidate profiles and create or
|
|
10
|
+
update notes in `knowledge/Candidates/`. Builds a local, searchable recruitment
|
|
11
|
+
pipeline from scattered email threads.
|
|
12
|
+
|
|
13
|
+
## Trigger
|
|
14
|
+
|
|
15
|
+
- The user asks to track, process, or update candidates.
|
|
16
|
+
- The user asks about recruitment pipeline status.
|
|
17
|
+
- After `sync-apple-mail` has pulled new threads.
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
- Synced email data in `~/.cache/fit/outpost/apple_mail/` (from
|
|
22
|
+
`sync-apple-mail`).
|
|
23
|
+
- User identity configured in `USER.md`.
|
|
24
|
+
|
|
25
|
+
## Inputs
|
|
26
|
+
|
|
27
|
+
- `~/.cache/fit/outpost/apple_mail/*.md` — synced email threads.
|
|
28
|
+
- `~/.cache/fit/outpost/apple_mail/attachments/` — CV/resume attachments.
|
|
29
|
+
- `~/.cache/fit/outpost/apple_calendar/*.json` — calendar events (for
|
|
30
|
+
cross-source inference).
|
|
31
|
+
- `knowledge/Roles/*.md` — open role/requisition files (metadata inheritance).
|
|
32
|
+
- `~/.cache/fit/outpost/state/graph_processed` — processed-file index (shared
|
|
33
|
+
with `extract-entities`).
|
|
34
|
+
- `USER.md` — user identity for self-exclusion.
|
|
35
|
+
|
|
36
|
+
## Outputs
|
|
37
|
+
|
|
38
|
+
- `knowledge/Candidates/{Full Name}/brief.md` — candidate profile note.
|
|
39
|
+
- `knowledge/Candidates/{Full Name}/CV.pdf` (or `CV.docx`) — local CV copy.
|
|
40
|
+
- `knowledge/Candidates/{Full Name}/headshot.jpeg` — candidate photo.
|
|
41
|
+
- `knowledge/Roles/*.md` — created/updated role files (Candidates tables
|
|
42
|
+
rebuilt).
|
|
43
|
+
- `~/.cache/fit/outpost/state/graph_processed` — updated with processed threads.
|
|
44
|
+
|
|
45
|
+
<do_confirm_checklist goal="Verify candidate processing batch is complete and
|
|
46
|
+
correct">
|
|
47
|
+
|
|
48
|
+
- [ ] Required Info fields present on every brief (Title, Source, Status, First
|
|
49
|
+
seen, Last activity, Channel).
|
|
50
|
+
- [ ] Pipeline status reflects latest thread activity; timeline in chronological
|
|
51
|
+
order.
|
|
52
|
+
- [ ] Bidirectional links present (Candidate ↔ Org / Recruiter / Role /
|
|
53
|
+
Project).
|
|
54
|
+
- [ ] Role files synced — Candidates tables rebuilt, stubs created for any
|
|
55
|
+
unknown reqs.
|
|
56
|
+
- [ ] CV and headshot copied into the candidate directory when available.
|
|
57
|
+
- [ ] Skills tagged with agent-aligned engineering standard IDs from
|
|
58
|
+
`bunx fit-pathway skill --list`.
|
|
59
|
+
- [ ] Gender field populated only from explicit pronouns or titles.
|
|
60
|
+
- [ ] No duplicate candidate notes; all processed threads marked in the state
|
|
61
|
+
file.
|
|
62
|
+
|
|
63
|
+
</do_confirm_checklist>
|
|
64
|
+
|
|
65
|
+
## Procedure
|
|
66
|
+
|
|
67
|
+
Process **10 files per run**.
|
|
68
|
+
|
|
69
|
+
### 1. Load context and pick the batch
|
|
70
|
+
|
|
71
|
+
Read `USER.md` for the user's name, email, and domain. List new or changed
|
|
72
|
+
source files:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
node .claude/skills/extract-entities/scripts/state.mjs check
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Filter the output to `apple_mail/*.md` only — calendar files are not relevant
|
|
79
|
+
here.
|
|
80
|
+
|
|
81
|
+
### 2. Build candidate, people, and org indexes
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
ls -d knowledge/Candidates/*/
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Read each existing brief's header (Name, Role, Source, Status) to build a mental
|
|
88
|
+
index. Also scan `knowledge/People/`, `knowledge/Organizations/`, and
|
|
89
|
+
`knowledge/Projects/` to resolve recruiter names, agency orgs, and project
|
|
90
|
+
links.
|
|
91
|
+
|
|
92
|
+
### 3. Sync `knowledge/Roles/`
|
|
93
|
+
|
|
94
|
+
This keeps role metadata current and enables inheritance.
|
|
95
|
+
|
|
96
|
+
1. Read each Role file's Info block to map Req → Role file path, Hiring manager,
|
|
97
|
+
Domain lead, recruiter, Channel.
|
|
98
|
+
2. Find Reqs referenced by candidate briefs but missing a Role file:
|
|
99
|
+
`rg "^\*\*Req:\*\*" knowledge/Candidates/*/brief.md`. For each missing Req,
|
|
100
|
+
create a stub using the **Role file stub** in
|
|
101
|
+
[references/templates.md](references/templates.md), then enrich by searching
|
|
102
|
+
the graph: `rg "{req_number}" knowledge/`.
|
|
103
|
+
3. Rebuild each Role file's `## Candidates` table by scanning briefs:
|
|
104
|
+
`rg -l "Req:.*{req_number}" knowledge/Candidates/*/brief.md`. Use the **Role
|
|
105
|
+
Candidates table** format from `references/templates.md`. Sort by First seen,
|
|
106
|
+
newest first.
|
|
107
|
+
4. If a Role file has a hiring manager but no domain lead, walk the
|
|
108
|
+
`**Reports to:**` chain in `knowledge/People/` to a VP or senior leader.
|
|
109
|
+
|
|
110
|
+
### 4. Identify recruitment threads
|
|
111
|
+
|
|
112
|
+
For each thread in the batch, decide whether it contains recruitment content
|
|
113
|
+
using the signals in [references/signals.md](references/signals.md). Skip
|
|
114
|
+
threads that match no signal.
|
|
115
|
+
|
|
116
|
+
### 5. Extract candidate data
|
|
117
|
+
|
|
118
|
+
For each candidate found, populate the field map from
|
|
119
|
+
[references/fields.md](references/fields.md). That reference covers field
|
|
120
|
+
sources, the `Channel` rule, the hiring-manager / domain-lead resolution chain,
|
|
121
|
+
gender rules, source/recruiter resolution, CV copying, and headshot discovery.
|
|
122
|
+
|
|
123
|
+
### 6. Determine pipeline status
|
|
124
|
+
|
|
125
|
+
Assign a status using the table and advancement signals in
|
|
126
|
+
[references/statuses.md](references/statuses.md). Default to `new`. Read the
|
|
127
|
+
full thread chronologically; the most recent signal wins.
|
|
128
|
+
|
|
129
|
+
### 7. Build the pipeline timeline
|
|
130
|
+
|
|
131
|
+
Extract a chronological timeline — one `**{date}**: {event}` line per meaningful
|
|
132
|
+
event, capturing who did what. Skip noise (signature blocks, disclaimers,
|
|
133
|
+
forwarded headers).
|
|
134
|
+
|
|
135
|
+
### 8. Write or update the candidate note
|
|
136
|
+
|
|
137
|
+
For **new** candidates, create `knowledge/Candidates/{Full Name}/brief.md` from
|
|
138
|
+
the **Candidate brief** template in
|
|
139
|
+
[references/templates.md](references/templates.md). Place the **Extra Info
|
|
140
|
+
fields** after `Last activity` in the order shown there. Add the **Optional
|
|
141
|
+
sections** when data warrants. Omit `## CV` if no attachment.
|
|
142
|
+
|
|
143
|
+
For **existing** candidates, apply targeted edits — do not rewrite the file:
|
|
144
|
+
update `Status` and `Last activity`, append Pipeline entries, fill in newly
|
|
145
|
+
known Info fields, and add new Skills.
|
|
146
|
+
|
|
147
|
+
### 9. Capture cross-candidate insights
|
|
148
|
+
|
|
149
|
+
Update `knowledge/Candidates/Insights.md` only when an observation is
|
|
150
|
+
high-signal: candidate may suit a **different role**, is a **strong match** for
|
|
151
|
+
a specific team or leader, a meaningful **comparison between candidates**, or a
|
|
152
|
+
hiring trade-off needs to be **remembered across sessions**.
|
|
153
|
+
|
|
154
|
+
Skip per-candidate status and generic strengths/weaknesses — those belong on
|
|
155
|
+
`brief.md`. Format: one bullet under `## Placement Notes` with
|
|
156
|
+
`[[Candidates/Name/brief|Name]]` and relevant people/org backlinks.
|
|
157
|
+
|
|
158
|
+
### 10. Ensure bidirectional links
|
|
159
|
+
|
|
160
|
+
| If you add... | Then also add... |
|
|
161
|
+
| ------------------------ | ---------------------------------------------------------- |
|
|
162
|
+
| Candidate → Organization | Organization → Candidate |
|
|
163
|
+
| Candidate → Recruiter | Recruiter → Candidate (in Activity) |
|
|
164
|
+
| Candidate → Project | Project → Candidate (in People section) |
|
|
165
|
+
| Candidate → Role | Role → Candidate (in Candidates table — rebuilt by Step 3) |
|
|
166
|
+
|
|
167
|
+
Use absolute paths: `[[Candidates/Name/brief|Name]]`,
|
|
168
|
+
`[[Organizations/Agency]]`, `[[People/Recruiter]]`. Only add a backlink when the
|
|
169
|
+
target note doesn't already reference the candidate.
|
|
170
|
+
|
|
171
|
+
### 11. Mark each thread processed
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
node .claude/skills/extract-entities/scripts/state.mjs update "{file_path}"
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Shares state with `extract-entities`, so the thread won't be re-scanned by
|
|
178
|
+
either skill until it changes.
|
|
179
|
+
|
|
180
|
+
### 12. Tag skills against the standard
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
bunx fit-pathway skill --list
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Use agent-aligned engineering standard IDs (e.g. `data_integration`,
|
|
187
|
+
`full_stack_development`, `architecture_and_design`) in the `## Skills` section
|
|
188
|
+
instead of free-form tags. Flag any candidate with a CV attachment for
|
|
189
|
+
`req-screen`.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Candidate Field Extraction
|
|
2
|
+
|
|
3
|
+
Field map and resolution rules for Step 2 of `req-track`.
|
|
4
|
+
|
|
5
|
+
## Fields
|
|
6
|
+
|
|
7
|
+
| Field | Source | Required |
|
|
8
|
+
| ----------------- | ------------------------------------------------------------ | ------------------- |
|
|
9
|
+
| Name | Filename, email body, CV | Yes |
|
|
10
|
+
| Title | Email body, CV — the candidate's professional title/function | Yes |
|
|
11
|
+
| Rate | Email body (e.g. "$120/hr", "€80/h") | If available |
|
|
12
|
+
| Availability | Email body (e.g. "1 month notice", "immediately") | If available |
|
|
13
|
+
| English | Email body (e.g. "B2", "Upper-intermediate") | If available |
|
|
14
|
+
| Location | Email body, CV | If available |
|
|
15
|
+
| Source agency | Sender domain → Organization | Yes |
|
|
16
|
+
| Recruiter | Email sender or CC'd recruiter | Yes |
|
|
17
|
+
| CV path | Attachment directory | If available |
|
|
18
|
+
| Skills | Email body, CV | If available |
|
|
19
|
+
| Gender | Pronouns or gendered titles only | If identifiable |
|
|
20
|
+
| Summary | Email body, CV | Yes — 2-3 sentences |
|
|
21
|
+
| Role | Internal requisition profile being hired against | If available |
|
|
22
|
+
| Req | Requisition ID from hiring system | If available |
|
|
23
|
+
| Channel | `hr` or `vendor` — see below | Yes |
|
|
24
|
+
| Hiring manager | Cross-source inference — see below | If determinable |
|
|
25
|
+
| Domain lead | Resolved from hiring manager's reporting chain | If determinable |
|
|
26
|
+
| Internal/External | Whether candidate is internal or external | If available |
|
|
27
|
+
| Model | Engagement model (B2B, Direct Hire, etc.) | If available |
|
|
28
|
+
| Current title | CV or email body | If available |
|
|
29
|
+
| Email | Email body, CV, signature | If available |
|
|
30
|
+
| Phone | Email body, CV, signature | If available |
|
|
31
|
+
| LinkedIn | Email body, CV | If available |
|
|
32
|
+
| Also known as | Alternate name spellings or transliterations | If available |
|
|
33
|
+
|
|
34
|
+
## Channel
|
|
35
|
+
|
|
36
|
+
- `vendor` — Source links to an `[[Organizations/...]]` flagged as
|
|
37
|
+
vendor/partner (keywords: supplier, recruitment partner, contractor,
|
|
38
|
+
staffing), or Req contains "via {vendor name}" rather than a system ID.
|
|
39
|
+
- `hr` — candidate came through a hiring system (numeric Req), applied
|
|
40
|
+
internally, or was submitted by an internal recruiter.
|
|
41
|
+
|
|
42
|
+
## Hiring manager and domain lead — resolution chain
|
|
43
|
+
|
|
44
|
+
Stop at the first match:
|
|
45
|
+
|
|
46
|
+
1. **Req-first inheritance** — look up `knowledge/Roles/*.md` for the matching
|
|
47
|
+
Req; inherit Hiring manager and Domain lead from the Role file.
|
|
48
|
+
2. **Calendar inference** —
|
|
49
|
+
`rg -l "{Candidate Name}" ~/.cache/fit/outpost/apple_calendar/`. The non-user
|
|
50
|
+
organizer of an interview event is likely the hiring manager.
|
|
51
|
+
3. **Email inference** — internal To/CC recipients (besides the user)
|
|
52
|
+
cross-checked against `knowledge/People/`.
|
|
53
|
+
4. **Reporting chain** — read the hiring manager's `**Reports to:**` field; walk
|
|
54
|
+
up to a VP / senior leader for the domain lead.
|
|
55
|
+
5. **Staffing project timeline** — search staffing notes for the candidate or
|
|
56
|
+
vendor; surrounding context often names the manager.
|
|
57
|
+
|
|
58
|
+
If none resolve, set `—` and revisit on the next cycle.
|
|
59
|
+
|
|
60
|
+
## Gender
|
|
61
|
+
|
|
62
|
+
Record only when **explicitly stated**:
|
|
63
|
+
|
|
64
|
+
- Pronouns from the recruiter ("she is available", "her CV attached")
|
|
65
|
+
- Gendered titles ("Ms.", "Mrs.", "Mr.")
|
|
66
|
+
|
|
67
|
+
Record as `Woman`, `Man`, or `—` (unknown). When uncertain, use `—`. **Never
|
|
68
|
+
infer gender from names** — name-based inference is unreliable and culturally
|
|
69
|
+
biased. The field supports aggregate diversity tracking; it has no bearing on
|
|
70
|
+
hiring decisions, assessment criteria, or candidate visibility.
|
|
71
|
+
|
|
72
|
+
## Source and recruiter
|
|
73
|
+
|
|
74
|
+
- Map sender email domain to an organization in `knowledge/Organizations/`.
|
|
75
|
+
- The person who sent or forwarded the profile is the recruiter — link with
|
|
76
|
+
`[[People/Name]]`.
|
|
77
|
+
- Create the organization or recruiter notes if missing.
|
|
78
|
+
|
|
79
|
+
## CV attachment
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
ls ~/.cache/fit/outpost/apple_mail/attachments/{thread_id}/
|
|
83
|
+
mkdir -p "knowledge/Candidates/{Full Name}"
|
|
84
|
+
cp "~/.cache/fit/outpost/apple_mail/attachments/{thread_id}/{file}" \
|
|
85
|
+
"knowledge/Candidates/{Full Name}/CV.pdf"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Use `CV.pdf` (PDF) or `CV.docx` (Word). The `## CV` link is `./CV.pdf`.
|
|
89
|
+
|
|
90
|
+
## Headshot discovery
|
|
91
|
+
|
|
92
|
+
Search both locations:
|
|
93
|
+
|
|
94
|
+
1. **Email attachments** —
|
|
95
|
+
`~/.cache/fit/outpost/apple_mail/attachments/{thread_id}/`. Filter to
|
|
96
|
+
portrait images (skip logos, signatures, `image001.png`).
|
|
97
|
+
2. **Downloads** —
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
find ~/Downloads -maxdepth 3 -type f \
|
|
101
|
+
\( -iname "*.jpg" -o -iname "*.jpeg" \
|
|
102
|
+
-o -iname "*.png" -o -iname "*.heic" \) 2>/dev/null
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Match by name fragment (case-insensitive). Prefer the Downloads match. Always
|
|
106
|
+
write `headshot.jpeg`:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
cp "{src}" "knowledge/Candidates/{Full Name}/headshot.jpeg"
|
|
110
|
+
# PNG → JPEG
|
|
111
|
+
magick "{src}.png" "knowledge/Candidates/{Full Name}/headshot.jpeg"
|
|
112
|
+
# HEIC → JPEG
|
|
113
|
+
magick "{src}.heic" "knowledge/Candidates/{Full Name}/headshot.jpeg"
|
|
114
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Recruitment Signals
|
|
2
|
+
|
|
3
|
+
Decide whether an email thread is recruitment-related. Skip threads that match
|
|
4
|
+
no signal — most email is not.
|
|
5
|
+
|
|
6
|
+
## CV/resume attachments
|
|
7
|
+
|
|
8
|
+
`~/.cache/fit/outpost/apple_mail/attachments/{thread_id}/` contains `.pdf` or
|
|
9
|
+
`.docx` files with candidate names in the filename.
|
|
10
|
+
|
|
11
|
+
## Recruiter sender domains
|
|
12
|
+
|
|
13
|
+
Sender domain maps to an organization in `knowledge/Organizations/` tagged as a
|
|
14
|
+
recruitment agency. When no agencies are catalogued yet, treat these patterns as
|
|
15
|
+
hints:
|
|
16
|
+
|
|
17
|
+
- Multiple candidates presented by the same sender
|
|
18
|
+
- Structured profile formatting (rate, availability, skills)
|
|
19
|
+
- Forwarding candidate CVs on behalf of others
|
|
20
|
+
|
|
21
|
+
## Profile presentation patterns
|
|
22
|
+
|
|
23
|
+
Structured candidate descriptions containing:
|
|
24
|
+
|
|
25
|
+
- "Rate:" or rate/cost information
|
|
26
|
+
- "Availability:" or notice period
|
|
27
|
+
- "English:" or language level
|
|
28
|
+
- "Location:" or country/city
|
|
29
|
+
- Candidate name + role formatting (e.g. "Staff Software Engineer")
|
|
30
|
+
- "years of experience" / "YoE"
|
|
31
|
+
- Skills/tech stack listings
|
|
32
|
+
|
|
33
|
+
## Interview scheduling
|
|
34
|
+
|
|
35
|
+
- "schedule a call", "schedule an interview"
|
|
36
|
+
- "first interview", "second interview", "technical interview"
|
|
37
|
+
- "interview slot", "available for a call"
|
|
38
|
+
|
|
39
|
+
## Follow-up on existing candidates
|
|
40
|
+
|
|
41
|
+
A thread mentions a candidate already in `knowledge/Candidates/` by name —
|
|
42
|
+
process it to update pipeline status.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Pipeline Statuses
|
|
2
|
+
|
|
3
|
+
Used by Step 3 of `req-track`. Default to `new` if no advancement signals are
|
|
4
|
+
found. Read the full thread chronologically; the most recent signal wins.
|
|
5
|
+
|
|
6
|
+
## Statuses
|
|
7
|
+
|
|
8
|
+
| Status | Signal |
|
|
9
|
+
| ------------------ | ----------------------------------------------------- |
|
|
10
|
+
| `new` | CV/profile received, no response yet |
|
|
11
|
+
| `screening` | Under review, questions asked about the candidate |
|
|
12
|
+
| `first-interview` | First interview scheduled or completed |
|
|
13
|
+
| `second-interview` | Second interview scheduled or completed |
|
|
14
|
+
| `work-trial` | Paid work trial or assessment project in progress |
|
|
15
|
+
| `offer` | Offer extended |
|
|
16
|
+
| `hired` | Accepted and onboarding |
|
|
17
|
+
| `rejected` | Explicitly passed on ("not a fit", "pass", "decline") |
|
|
18
|
+
| `withdrawn` | Candidate withdrew from the process |
|
|
19
|
+
| `on-hold` | Paused, waiting on notice period, or deferred |
|
|
20
|
+
|
|
21
|
+
## Advancement signals (hiring-manager replies)
|
|
22
|
+
|
|
23
|
+
- "let's schedule" / "set up an interview" → `first-interview`
|
|
24
|
+
- "second round" / "follow-up interview" → `second-interview`
|
|
25
|
+
- "work trial" / "assessment project" / "paid trial" → `work-trial`
|
|
26
|
+
- "not what we're looking for" / "pass" → `rejected`
|
|
27
|
+
- "candidate withdrew" / "no longer interested" / "accepted another offer" →
|
|
28
|
+
`withdrawn`
|
|
29
|
+
- "extend an offer" / "make an offer" → `offer`
|
|
30
|
+
- "they've accepted" / "start date" → `hired`
|
|
31
|
+
- "put on hold" / "come back to later" → `on-hold`
|
|
32
|
+
- No response to profile → remains `new`
|