@skarmy/hiring-agent
v0.2.1
Published
Skarmy's Hiring Lead — plans the earliest hires, drafts listings and exports, publishes the careers-page spec, and screens applicants (recommend-only). Prompt-runtime agent.
Readme
@skarmy/hiring-agent
Skarmy's Hiring Lead — plans the earliest hires, drafts job listings, publishes a careers-page spec, and screens applicants. Joins the team when the team-selection judge matches its inclusion criterion: "Making this real clearly needs people beyond the founder — skills or capacity one person can't cover."
A prompt-runtime agent: the hub's prompt engine runs onTurn in-process every founder turn. See SPEC.md for the full behavioral spec.
What it does
- Plan roles — the 1–4 earliest hires from the venture brief, biased toward not hiring. Comp is always a labeled estimate (
isEstimate: trueis hard-coded; no fabricated market data). When the hub grantsweb_search, cited comp datapoints are attached to the plan deterministically after the model call — the planning model never sees search results, so it can't launder them into invented "sourced" numbers. - Draft listings — a full listing per role plus a deterministic screening scorecard derived from it (mustHave → weight 3, niceToHave → 1, plus standard shipping/communication criteria).
- Export — copy-paste variants for HN "Who is hiring", LinkedIn, and Wellfound; full text always fenced in the reply.
- Publish a careers page — only on explicit founder opt-in. Writes
/hiring/careers-page.md(markerskarmy:careers-page/v1, fenced JSON contract) and hands the founder to the Engineering Lead, which builds/careerswith an apply form POSTing to the hub's public/api/intake. - Screen + escalate — applications land as venture files via the intake route; every turn screens new ones against the scorecards, maintains a ranked shortlist, surfaces escalations, and drafts (never sends) replies.
- Track founder decisions — "I hired Ada" / "passed on Bob" is recorded verbatim in
/hiring/applicants/decisions.json; the shortlist becomes a live pipeline (decided escalations stop being action items). The agent records decisions, never makes them; ambiguity gets a clarifying question, never a guess. Chat is grounded in the live shortlist, so "who should I talk to?" gets a real answer.
Non-negotiables
- Recommend-only. No "reject" arm exists in the schema; rogue model rejects are clamped to "review"; the no-model heuristic may only say "review". The founder decides.
- Bias constraints live in the screening prompt: role-relevant evidence only; never name, inferred demographics, prestige, gaps, or location beyond a stated hard requirement; missing evidence is "probe", not a strike. The per-applicant rationale is persisted as the audit record.
- Graceful degradation. No model key → deterministic fallbacks; no file capability → content inlined in the reply; no intake endpoint → careers page ships with a disabled form.
The venture-file contract
Everything flows through /hiring/** (latest-only overwrites; schemas in src/types.ts):
| Path | Writer |
|---|---|
| /hiring/plan.json + /hiring/plan.md | hiring |
| /hiring/roles/<slug>/{listing.md, scorecard.json, interview-kit.md, exports/*} | hiring |
| /hiring/careers-page.md | hiring (→ builder consumes) |
| /hiring/applicants/inbox/<stem>.json | hub intake route only |
| /hiring/applicants/screened/<stem>.json + shortlist.md | hiring |
| /hiring/applicants/decisions.json (founder-stated only) | hiring |
The inbox filename stem is the idempotency key: an applicant is screened iff a matching screened/ record exists.
Exports
export const hiringManifest: AgentManifest; // key "hiring", tools ["files","intake","web_search"]
export const hiringDefinition: AgentDefinition; // onTurn owns every turn; never completes
export { onHiringTurn, loadHiringState }; // for hub tests/toolingManifest key/name/criterion stay in lockstep with the hub roster (src/lib/discovery/team.ts) — pinned by the hub's registry tests.
Develop
Prereqs: Node 22+ (@skarmy/agent-sdk resolves from npm).
npm install
npm run typecheck
npm test # 76 tests: contract, state, router, features, screening, decisions, comp, turnTests run against src/testing/stub-ctx.ts — an in-memory PromptTurnContext with a scriptable callModel, file map, and recorders. No network, no keys.
Publish & pin
npx pnpm@9 publish --access public --no-git-checkspnpm (not npm) so publishConfig rewrites main/exports from src/ to dist/ (built by prepack). The hub then pins "@skarmy/hiring-agent": "^0.2.0" and registers hiringManifest / hiringDefinition in src/lib/agents/registry.ts + prompt-engine.ts.
License
MIT
