# DIRECTIVE AMENDMENT 5: THE CANDIDATE SPINE AND THE DESK DATAFLOW Applies to docs/CLAUDE_CODE_BUILD_DIRECTIVE.md. Generated 27 July 2026. This amendment defines the canonical dataflow through the whole application and adds the missing half of the recruiting desk: the Candidates page, reverse matching, add to job order, and job orders that update themselves. -------------------------------------------------------------------------------- 0. HOW TO APPLY THIS AMENDMENT -------------------------------------------------------------------------------- 1. Record "amendment 5 accepted" in BUILD_STATE with the date. 2. Section 1 becomes a permanent appendix of the directive, the canonical dataflow every future feature must respect. Sections 2 through 6 amend Phase 5. Section 7 amends Gate 5. Section 8 amends the Section 11 acceptance list. 3. All directive rules apply unchanged. The candidate scoring engine stays frozen; this amendment adds entry points and lifecycle wiring, never scoring code. -------------------------------------------------------------------------------- 1. THE CANONICAL DATAFLOW, PERMANENT APPENDIX -------------------------------------------------------------------------------- One candidate spine. One linking record. Everything hangs off it. INTAKE CANDIDATE WORK apply on fg-talent.com \ / desk pipeline Import Center bulk \ / (applications) screenMATCH resume > candidates table < proposal slates quick add on the desk / one record per person \ screenings (all paths dedupe) / all tools, same spine \ pools, searches THE LINKING RECORD: application (candidate x requisition) exactly one active application per candidate per requisition requisition (job order, openings count, linked requirement) | | add to job order (from match, search, pool, or manual) v application: prescreen -> internal submittal -> client submittal -> interview -> offer -> placed or out at any stage, always with a reason code | | offer accepted v placement takes a seat under the existing FOR UPDATE seat lock | v JOB ORDER UPDATES ITSELF stage counts derive live on the order last seat placed flips status to filled in the same transaction remaining active applications become filled_by_another, notified filled unpublishes the fg-talent.com page via the expiry sweep a fall off frees the seat, reopens the order, alerts the owner, and never republishes without a human confirming | v placement end approaching -> redeployment alert -> candidate returns to the available pool -> the spine loops The two match directions use the same frozen engine: a job order ranks candidates (sourcing, slates), and a candidate ranks open job orders (marketing a person). Both read through the requisition to requirement bridge. screenMATCH is the deep evaluation of one pairing, stored on the application. slateMATCH is the proposal branch off the same spine, and a person may sit on a slate and in a desk pipeline at once, because both point at the one candidate record. -------------------------------------------------------------------------------- 2. DECISIONS RECORDED -------------------------------------------------------------------------------- 1. One candidate spine. The Candidates screen in the missionMATCH command center and the new desk page read the same records. Shared candidate profile components are extracted into a shared frontend directory and composed by both surfaces. Nothing candidate shaped is duplicated per tool. 2. recruitMATCH gains a Candidates page in its navigation, gated by the recruitmatch entitlement like every other desk screen. 3. Candidate search on the page is deterministic SQL: the existing hybrid fusion, tsvector rank with pgvector cosine joined by reciprocal rank fusion, exposed as a repository query with structured filters. The AI Ask path is untouched and remains separate. 4. Reverse matching runs the frozen engine, one candidate against the linked requirement of every open requisition. Orders without a linked requirement appear in the results as unmatchable with a fix it link to the bridge. Every computed pairing persists with score, band, engine version, and computed_at, and goes stale when the requirement or the candidate profile changes after computation. 5. Add to job order creates the application. Exactly one active application per candidate per requisition, enforced by a partial unique index over non terminal statuses. Adding a candidate whose prior application on that order ended requires an explicit reopen with a reason from the Amendment 2 taxonomy. 6. Applications record how they began: added_from in apply, import, match, search, pool, manual, screen. When added from match, the score snapshot, band, and engine version at add time are stored on the application, so why this person entered this pipeline is always answerable. 7. The default stage template gains internal_submittal and client_submittal as explicit stages, aligning the platform with the industry standard ladder. Existing stage values are never renamed and never destroyed; the template extends, historical data stands, and derive.go plus analytics read the extended set. Placement type templates from Amendment 2 build on this default. 8. Job order status is a state machine: draft, open, on_hold, filled, closed. Filling the last seat flips open to filled automatically inside the placement transaction the seat lock already governs. A fall off, meaning a placement ends early, frees the seat and flips filled back to open automatically, with an alert. Manual transitions remain available and every transition, automatic or manual, is audited with its cause. 9. filled_by_another is a distinct application outcome, not a rejection. When an order fills, remaining active applications move there in the same transaction, their candidates flagged available for other orders, and owners notified through alerts. 10. Republishing after a fall off requires a human confirm on the requisition. The page never reappears on fg-talent.com silently. -------------------------------------------------------------------------------- 3. THE CANDIDATES PAGE, IN recruitMATCH -------------------------------------------------------------------------------- 1. Roster list with columns: name, headline or current title, clearance intelligence level, top skills, location, availability, source, last activity, active pipelines count, pools. Every column sortable, list virtualized for size. 2. Filters: clearance intelligence level, skills, certifications, location and radius or remote, availability window, source, pool, has resume, last activity age. Free text box runs the fusion query. Saved searches from Amendment 2 apply here, save and rerun. 3. Bulk actions on selected rows: add to pool, add to job order, export through csvsafe. 4. Candidate detail, composed from the shared components, tabs: Profile (structured fields, clearance intelligence always labeled self reported), Resumes (version list, inline viewer for the current version, download, upload new version), Screenings (every screenMATCH result with engine version, band, and stale badges), Pipelines (every application across orders with client, order, stage, status, aging, the Submissions view of the spine), Activity and Tasks (the wired activities and tasks from Amendment 2), Pools. 5. Actions on the detail: Match to open orders, Add to job order, Screen against an order, Add to pool, Edit profile, Upload resume. -------------------------------------------------------------------------------- 4. REVERSE MATCH, CANDIDATE TO OPEN ORDERS -------------------------------------------------------------------------------- 1. Match to open orders opens a ranked list: every open requisition with a linked requirement, scored by the frozen engine, showing band chip, score, client, order title, openings remaining, response deadline or aging, and whether this candidate already has an application there. 2. Row actions: Add to pipeline, which creates the application with the match snapshot, and Screen now, which runs the full screenMATCH evaluation on the pairing and stores it. Multi select add is supported. 3. Unmatchable orders, no linked requirement, list at the bottom with a link that opens the bridge flow from Amendment 2. 4. Determinism: the same candidate and the same open orders produce the same ranking every run, decimal arithmetic, no model in the loop. Stale pairings recompute on open, and the persisted history of prior computations is never overwritten, matching the audit posture. -------------------------------------------------------------------------------- 5. ADD TO JOB ORDER, MECHANICS -------------------------------------------------------------------------------- 1. One transaction: FOR UPDATE on any existing application row for the pair, insert or reopen, write added_from and the snapshot when present, write the activity, audit through OnTx. Eight racing adds produce one application. 2. The requisition list and detail show live stage counts, in pipeline, internal submittal, client submittal, interview, offer, placed, and out, derived by indexed query, plus openings remaining from placements. Stat tiles click through to the filtered pipeline, per the platform rule. 3. Client detail shows its orders with the same counts, so the path the request described, find a candidate, match them, add them to the client's open order, is two clicks from either end and the order reflects it immediately. -------------------------------------------------------------------------------- 6. JOB ORDER SELF UPDATES -------------------------------------------------------------------------------- 1. Filling the last seat, inside the placement transaction: requisition status to filled, remaining active applications to filled_by_another with notifications, publish state to unpublished with the sitemap entry dropped by the sweep, all audited with cause placement_final. 2. Fall off: a placement ending before its scheduled end frees the seat, flips filled to open with cause fall_off, alerts the order owner and the capture owner where linked, and leaves the page unpublished pending the human republish confirm. Candidates in filled_by_another on that order can be reactivated to their prior stage manually, one click, with the reactivation audited. 3. on_hold pauses publishing and SLA timers without disturbing the pipeline. closed is terminal, requires a reason, and moves active applications to out with reason order_closed. -------------------------------------------------------------------------------- 7. GATE 5 ADDITIONS -------------------------------------------------------------------------------- 1. The Candidates page finds a planted candidate by skills filter and by free text through the fusion query, and the missionMATCH command center Candidates screen still renders from the shared components with zero regression. 2. Reverse match on a fixture candidate returns an identical ranking across repeated runs, and the engine diff against the starting commit remains empty. 3. Add to job order from the match list creates the application carrying the score snapshot and added_from match. Eight racing adds of the same pair produce exactly one application. A duplicate add through the API is rejected. 4. Stage counts on the requisition update as the application moves through prescreen, internal submittal, client submittal, interview, and offer, and each tile clicks through correctly. 5. Placing the final seat flips the order to filled, moves the remaining fixture applications to filled_by_another with alerts recorded, and the fg-talent.com detail page and sitemap entry are gone. 6. A simulated fall off frees the seat, reopens the order with an alert, does not republish, and a one click reactivation restores a filled_by_another candidate to their prior stage, audited. 7. Re adding a previously rejected candidate demands a reopen reason and records it. 8. A candidate sitting on a proposal slate and in a desk pipeline resolves to one candidate id everywhere it appears. -------------------------------------------------------------------------------- 8. ACCEPTANCE ADDITIONS TO SECTION 11 -------------------------------------------------------------------------------- 33. Exactly one active application exists per candidate per requisition, enforced by the database, proven by the race. 34. Every job order status transition, automatic or manual, carries an audited cause, and filled_by_another is distinguishable from rejection in every report. 35. Reverse match rankings are bit reproducible, persisted with engine version, and the frozen engine remains untouched.