Chain · Hiring — the first application, not the product
Parent: requirements-to-design
L0 · Vision
boundaries — hiring is an application on the foundation, explicitly NOT the product. transaction-needs-difference — a transaction needs difference; the résumé is lossy compression into an HR-parseable format; StandMeet's job is to put the difference back. dont-repeat-myself — the job story told 5–15 times across 30–50 interviews.
L1 · Promise
In the hiring transaction, the owner's specific, provable, opinionated detail reaches the recruiter — via QR on the résumé into a role-framed conversation, and via an owner-side outbound loop.
L2 · Requirements (journeys & features)
The owner's job/resume/application journeys and the cross-actor closed loop: recruiter scans the QR → lands /<handle>?code=… → the code is absorbed and held (defer-issue: the session is only issued after the visitor picks a name — deliberately not auto-start). Feature surfaces: the Jobs tools (jobs.fetch_new, 18 source kinds — backend/internal/owner/jobs/fetch/jobfetch.go:36-63, asserted by e2e/test/admin-sources.spec.ts:26-30; six more on 2026-09-02 (7dd19527b) incl. a generic schema.org JSON-LD ingester, a generic RSS adapter + seeded default aggregators on 2026-09-04 (d235f9817)), Resume (resume.draft/update_draft/discard_draft; since 2026-09-07 a visual Puck composer on /admin/edit-resume/[id] — 756c0eb1d, app/src/components/admin/composer/PuckResumeEditor.tsx — and the PDF drawn from the same Puck config through gotenberg's Chromium at /print/application/<id> — 1b1ebed2b, backend/cmd/server/boot_pdf.go), applications.commit; each code carries its own landing path /c/<slug> (c6c54ce88, 2026-09-06, app/src/app/c/[slug]/page.tsx, access/entity/access_code.go:85) and its string can be rotated for leak recovery (codes.rotate, 505b3fc4f, access/repo/codes_rotate.go; admin modal 6ed1759bb); admin Applications (searchable by company / role / status — af263d4eb, 2026-09-05) + Sources + Listings.
L3 · Design decisions
The job-loop design (built; docs/design/job-loop.md is the record): the state/reasoning split (StandMeet = state holder, Claude = reasoning via Playwright MCP — an MCP server on the owner's Claude side, neither of our two planes, confusables); AccessCode = invitation, unified; mandatory staging (draft → preview → owner nod → commit — never "Claude sends directly"); QR top-right pointing at <public_url>/?code=<code> (jobsuc/applications.go:317-322), no /gate interstitial; history.replaceState strips ?code (app/src/lib/gate/use-absorb-code.ts); an invalid code lands on /gate (230a17025); the draft snapshots the job row. One renderer: a Typst renderer with owner-selectable templates was added 2026-09-01 (340ffabf9) and removed 2026-09-07 (1b1ebed2b) — Puck draws both the editor canvas and the PDF, so preview and print cannot diverge. IDEAS.md backlog: resume=git model (git vocabulary dropped from UI, 2026-05-28), application bundles, bullet↔wiki backlinks.
L4 · Engineering artifacts
backend/internal/owner/jobs/ — a domain module (fetch / dedup / cache / jobsuc / jobsmcp / jobsadmin / printsess), tables job_sources / job_fingerprints / resume_drafts / applications (code_bookings is gone — the booker owns per-code booking quota, b73c932bb, 2026-07-25); printsess + gotenberg (PDF, boot_pdf.go); mock-stack job-board fake upstream.
L5 · Verification
E2e [✓ applications-commit, -qr-works, -playwright-hint], [✓ qr-code-absorb], coded-landing-slug, applications-search, job-fetch-rss, the resume-composer-* / resume-pdf-render / resume-look / composer-pdf-fidelity estate (e2e/test/); booking regression suite.
Status & gaps
The job-loop phases are built (jobs / resume / applications / QR → coded landing live; no calendar hook exists — next_event_at appears nowhere in the backend at 36789537d); the mandatory-staging discipline is the chain's own safe-recursion gate — owner nod before anything leaves. Boundary risk to watch: this is the easiest chain to over-invest in against boundaries' own warning.