ThatAIguyA world of ideas

THE CONSCIOUSNESS ATLAS
Read. Experiment. Follow the evidence.

ConsciousnessLearn · Explore · Joseph Anady

Janady13/missionmatch / docs/CLAUDE_CODE_BUILD_DIRECTIVE.md

Source identity, revision, and recovered contents.

GitHub sourceSource text recovered

Source identity

FieldRecorded value
Source typeGitHub source
Original recordJanady13/missionmatch / docs/CLAUDE_CODE_BUILD_DIRECTIVE.md
DateNot specified in source
RepositoryJanady13/missionmatch
Revision720d47fae476b0d38477ae4401697d372b1ea2bc
Branchfeature/opportunity-to-outcome
Path or archive memberdocs/CLAUDE_CODE_BUILD_DIRECTIVE.md
Original SHA-25699b67fd52e6728ebf8fcaf8853474ea7172aad5b7cfd954f76a224204b3ba890
Git blob SHAa3087ba3fc9935d5b9de04ecf00276a21a271a48
Reading-copy SHA-25699b67fd52e6728ebf8fcaf8853474ea7172aad5b7cfd954f76a224204b3ba890

Original source ↗

Recovered source transcript

Download complete source text ↓1,000 lines · 55.2 KB
# CLAUDE CODE BUILD DIRECTIVE: OPPORTUNITY TO OUTCOME missionMATCH complete update. Generated 27 July 2026. This is the single source of truth for the build. It absorbs and supersedes INTELLIGENCE_EXPANSION_SPEC.md, whose content now lives in Phases 0, 2, and 4. Move that file to docs/archive in Phase 0 so exactly one work order exists. The mission: an opportunity may enter through the SAM.gov API, manual entry, uploaded solicitation documents, a customer or teaming partner scope, a spreadsheet import, or a future agency forecast feed. Every intake path converges into one canonical workflow: Opportunity -> Source Documents -> Scope Extraction -> Human Review -> Approved Requirements -> Staffing Slates -> Proposal Workspace -> Submission -> Outcome This UPDATES missionMATCH. Nothing is built beside it. -------------------------------------------------------------------------------- 0. SESSION PROTOCOL, HOW CLAUDE CODE RUNS THIS BUILD -------------------------------------------------------------------------------- 1. Read order at the start of every session: CLAUDE.md, this directive, docs/BUILD_STATE.md, then only the files needed for the current item. 2. Phase lock. Work exclusively on the lowest incomplete phase. Never start phase N+1 until every item in the phase N gate is verified and recorded. 3. Ledger. docs/BUILD_STATE.md is append only in practice: one line per completed gate item recording phase, item number, verification evidence (the command run, the rows observed, the screen checked), commit hash, and date. Only verified items enter. Aspirations never enter. 4. Commit convention: "phaseN itemM: short description". One logical change per commit. 5. Frozen and untouchable: internal/modules/matching/engine (the candidate scoring engine), db/migrations_eeo, every existing migration file, generated sqlc output (regenerate, never hand edit), and the append only audit semantics. 6. Extend, never build beside (Section 1). If a change appears to require a parallel structure, stop, record the conflict in BUILD_STATE, and wait for Joseph rather than forking. 7. Verification method, unchanged from how this system was built: reproduce the defect or behavior against the live database first, implement, verify against the same database, verify end to end through the live authenticated API, then look at the rendered screen. Concurrency is proven by racing it, not by reasoning about it. 8. Inherited non negotiable rules: No Python anywhere, Go backend, TypeScript frontend, bash scripts. No dashes in written output, commas or rewrite, hyphens only inside code identifiers, protocol headers such as User-Agent, and official designations. Every API key stays on the server, root owned 0600, never in the repo, never in the browser bundle. Clearance is clearance intelligence, never verified. Fail closed everywhere. 9. Environment rule, AMENDMENT 1, reinstated 28 July 2026 by the consolidated amendments (docs/DIRECTIVE_AMENDMENTS_CONSOLIDATED.md). This supersedes the 27 July decision to build directly against production, which is now void for all work from 28 July forward. Every migration, every live database verification, and every end to end check through Phase 5 runs against missionmatch_staging. The production tenant database is touched only at Gate 6, and only after the backup and restore test passes. If any task appears to require production before Gate 6, stop and record the conflict in BUILD_STATE instead of proceeding. RESOLVED LOCATION. The amendment names staging as missionmatch_staging on megamind-agi port 5433. Verified on 28 July: that database exists but is an EMPTY SHELL, 0 organizations, 0 candidates, and its goose table is not even readable by the app role. The working staging is missionmatch_staging on M4 port 5432: 76 tables, 2766 organizations, 8872 candidates, and it is the database the live mm-api-staging service on 127.0.0.1:8097 actually serves. Gate verification requires an end to end check through a live authenticated API and a rendered screen, which only the M4 database supports. Per Section 0 item 5 of the amendments, the smallest change satisfying both is to honor the amendment's database NAME and its staging only rule while using the host where that database actually functions. Staging therefore means missionmatch_staging on 100.94.8.94 port 5432. Safety rails on every schema change, unchanged: assert the connected database name before any write, pg_dump the target before a migration batch, keep migrations additive and transactional, and keep down migrations refusing to destroy application authored rows. -------------------------------------------------------------------------------- 1. EXTEND, NEVER BUILD BESIDE (THE ANTI DRIFT MAP) -------------------------------------------------------------------------------- EXTEND these existing components. Do not duplicate their function anywhere: cmd/sam-sync upgraded in Section 4, never replaced cmd/opp-sync unified opportunity ingestion cmd/awards-sync gains task order depth in Phase 4 internal/modules/opportunities gains the tenant tracked layer internal/modules/opportunity_intelligence internal/modules/awards internal/modules/bidoutcomes outcomes write through here internal/modules/alerts notifications ride here, with alert-sweep internal/modules/slatematch the proposal workspace lives here internal/modules/commandcenter readiness tiles read from here internal/modules/recruitmatch completed in Phase 5 internal/modules/governance evidence pack export lands here internal/platform/docextract and internal/platform/extraction internal/platform/storage document bytes, keyed by hash internal/platform/secrets the only home for keys internal/platform/inference circuit breaker, bounded retries internal/platform/scrub extended with egress payload classes internal/platform/audit OnTx coverage for every material action internal/platform/tenant, tenantpool, database, config, csvsafe, obs frontend/src/tools/slatematch new screens mount here frontend/src/App.tsx routes and ToolGuard, existing pattern db/migrations numbering continues from the current max NEW things allowed, and this list is exhaustive: Tables named in Section 3. Binaries named in Section 8. Package internal/modules/proposals with pure subpackage engine. Frontend screens named in Section 6. docs/BUILD_STATE.md and docs/archive/. FORBIDDEN, full stop: A new repository, a new API binary, or a second candidate scoring engine. A fifth product entitlement. Renaming or restructuring existing tables. Schema changes outside numbered migrations. Ingestion paths that edit approved requirements or tenant authored data. Secrets anywhere except the secrets store. NL to SQL, model authored SQL, or model authored parameters. Web scraping of candidate data of any kind. -------------------------------------------------------------------------------- 2. DECISIONS RECORDED, DO NOT REOPEN -------------------------------------------------------------------------------- 1. The proposal workspace ships inside the slatematch entitlement. A proposal is the continuation of a slate. Routes mount in the slatematch route group with flat aliases registered per the existing pattern. Record this in STACK_DECISIONS. 2. Tenant tracked opportunities live inside internal/modules/opportunities as a tenant owned layer above the shared public cache. No new capture module. 3. The readiness engine is a new pure package internal/modules/proposals/engine: shopspring/decimal, no database, no I/O, a versioned READINESS_ALGO_VERSION constant. It never touches or resembles the candidate scoring engine. 4. Proposal outcomes write through the existing bidoutcomes module, closing the loop that AIOE already expects. 5. Deadline and amendment notifications use the existing alerts module. 6. External inference: OpenAI becomes a third gateway backend under the rules in Section 5.3. The key exposed in chat on 27 July 2026 is revoked and replaced before the enabled flag ever turns true. 7. Capabilities: map new actions onto the existing 19 first. If none fits, add exactly these, at these role thresholds, and update the exhaustively tested capability matrix: opportunity.manage at recruiter and above, scope.review at recruiter and above, requirement.approve at manager and above, proposal.manage at recruiter and above, proposal.submit at manager and above. Superuser holds all by rule, never by matrix row. 8. Migration numbers continue from the current maximum in db/migrations. Never renumber, never reuse, never touch the EEO set. 9. ingest_manifest lives wherever the public opportunity cache lives today. Inspect the sam-sync write target and follow that exact pattern: if the cache is per tenant, the manifest carries organization_id like every tenant table; if the cache is shared reference data, the manifest is shared reference data. Tenant rows reference manifest rows by id. -------------------------------------------------------------------------------- 3. DATA MODEL -------------------------------------------------------------------------------- Invariants for every new tenant table, no exceptions: organization_id, forced row level security, a composite index leading with organization_id, composite foreign keys, ON DELETE SET NULL only in the column list form (migration 0053 exists because the bare form is a trap), audit coverage through OnTx, and down migrations that refuse with a count rather than destroy application authored rows. 3.1 tracked_opportunities organization_id, id, public_opportunity_id, source_type, source_record_id, sam_notice_id, title, solicitation_number, agency_name, office_name, notice_type, set_aside_code, naics_code, psc_code, place_of_performance, posted_at, response_deadline, estimated_value_min, estimated_value_max, ceiling_value, period_of_performance_start, period_of_performance_end, incumbent_name, prime_or_sub, capture_owner_user_id, status, source_url, source_manifest_id, created_by_user_id, created_at, updated_at source_type enum: sam_gov, agency_forecast, customer, partner, internal, spreadsheet, manual. status enum: identified, qualifying, qualified, pursuing, no_bid, submitted, won, lost, cancelled, archived. Unique partial index on (organization_id, public_opportunity_id) where public_opportunity_id is not null, so a tenant cannot track one public notice twice. 3.2 opportunity_versions, immutable snapshots organization_id, id, opportunity_id, version_number, amendment_number, source_version_label, source_payload_hash, normalized_payload, fetched_at, effective_at, supersedes_version_id, ingest_manifest_id, is_current, created_by_user_id Unique on (organization_id, opportunity_id, version_number). is_current flips inside the same transaction that inserts the successor. Rows are never updated after insert except that flag, enforce with a trigger in the audit style. 3.3 opportunity_documents organization_id, id, opportunity_id, opportunity_version_id, document_type, file_name, media_type, storage_key, size_bytes, sha256, source_url, source_type, uploaded_by_user_id, extraction_status, extraction_error_code, supersedes_document_id, is_current, created_at document_type enum: solicitation, amendment, sow, pws, soo, labor_categories, pricing_template, evaluation_criteria, security, q_and_a, past_performance, subcontract_scope, customer_scope, attachment, other. extraction_status enum: pending, running, done, failed. Failed is retryable. Duplicate detection by sha256 within the opportunity. Bytes go through internal/platform/storage; the malware scan integration point sits between upload and extraction_status pending. 3.4 opportunity_document_chunks, exact extraction provenance organization_id, id, document_id, page_number, section_label, text_content, content_hash, extraction_method, confidence, created_at 3.5 opportunity_scope_items organization_id, id, opportunity_id, scope_type, title, description, source_document_id, source_page_number, source_section_label, source_quote_hash, extraction_method, extraction_confidence, review_status, reviewed_by_user_id, reviewed_at, parent_scope_item_id, display_order, created_at, updated_at scope_type enum: objective, task, deliverable, labor_category, staffing_quantity, skill, certification, clearance, customer_experience, location, travel, schedule, security_control, reporting, transition, key_personnel, pricing_instruction, evaluation_factor, compliance_clause, assumption, dependency, risk, other. review_status enum: extracted, accepted, edited, rejected, merged, manual. 3.6 requirement_drafts, the safety boundary before live scoring organization_id, id, opportunity_id, source_scope_item_id, labor_category, quantity, clearance_level, polygraph, compartments, required_skills, mandatory_skill_flags, required_certifications, minimum_years_experience, required_customer_experience, work_location, remote_allowed, travel_percent, availability_date, employment_type, pay_band_min, pay_band_max, bill_rate_min, bill_rate_max, derivation_method, derivation_confidence, review_status, reviewed_by_user_id, reviewed_at, approved_requirement_id, created_at, updated_at review_status enum: draft, in_review, approved, rejected. Promotion to the existing requirement table happens in one audited transaction that takes FOR UPDATE on the draft row, so racing approvals elect exactly one winner, matching the nine existing lock patterns. 3.7 Proposal tables proposals: organization_id, id, opportunity_id, title, stage, status, proposal_owner_user_id, capture_owner_user_id, customer_deadline, internal_deadline, submitted_at, outcome_recorded_at, created_at, updated_at. proposal_sections and proposal_section_versions: section_code, title, owner_user_id, required, page_or_word_limit, due_at, draft_status, review_status, approved_by_user_id, version_number, content reference. proposal_compliance_items: source requirement text, source_document_id, page or section, response_location, owner_user_id, due_at, status, evidence reference, reviewer_user_id. proposal_milestones: kind enum covering question_deadline, pink_team, red_team, gold_team, final_review, upload, submission, plus due_at and completed_at. proposal_risks: likelihood, impact, owner_user_id, mitigation, trigger, status, related_scope_item_id. proposal_team_members, proposal_staffing_links (requirement_id, slate_id, required_quantity, approved_count), proposal_attachments, proposal_readiness_snapshots (overall decimal, one decimal column per component, blockers, drivers, algorithm_version, calculated_at). 3.8 ingest_manifest source, url, license, fetched_at, record_count, content_hash, and organization_id if the Section 2 item 9 inspection says per tenant. Every synced row and every knowledge card traces to a manifest row. -------------------------------------------------------------------------------- 4. SAM.GOV INGESTION UPGRADE, INSIDE cmd/sam-sync -------------------------------------------------------------------------------- The complete flow, in order: 1. Retrieve official notice metadata. 2. Write or refresh the shared public opportunity cache. 3. Record provenance in ingest_manifest. 4. Retrieve the full description where permitted. The description field returns a URL that costs a second authenticated call, so the call budget is double the notice count. Opportunity pages cap at one thousand records. Personal keys allow roughly ten calls a day, role backed roughly one thousand, federal system accounts roughly ten thousand. Explicit pagination and caching, always. 5. Retrieve attachment metadata. 6. Compare the current source hash to the last stored source hash. 7. On change, create an immutable opportunity_versions row for every tenant tracking the notice. 8. Queue approved public attachments for cmd/sam-attachment-sync. 9. Extract document text through the existing extraction packages. 10. Generate draft scope items, Section 5 rules. 11. Notify tracking tenants through the alerts module when an amendment lands or a deadline changes. 12. Never touch tenant authored data. Refresh writes only to the public cache and to versions. A test asserts that every tenant owned column on tracked_opportunities survives a refresh byte for byte. Amendment handling, always: a new amendment creates a new version, retains the original, diffs deadlines, labor categories, quantities, security requirements, and evaluation criteria, flags affected approved requirements, and requires a named human to accept operational changes. Nothing silently rewrites an approved requirement. -------------------------------------------------------------------------------- 5. EXTRACTION, NORMALIZATION, AND THE EXTERNAL BOUNDARY -------------------------------------------------------------------------------- 5.1 Deterministic extraction first, before any model call, in the existing extraction packages: headings, numbered clauses, tables, dates, deadlines, dollar values, labor categories, quantities, clearance terms, certifications, locations, travel percentages, period of performance, deliverables, evaluation factors. Output lands in opportunity_document_chunks with provenance. 5.2 Model normalization second, through the existing inference router: 1. The model returns typed JSON matching a declared schema. 2. Every item carries document provenance: document id, page, section, quote hash. 3. Uncited output is rejected. 4. Invalid enum values, dates, lengths, and quantities are rejected. 5. Model output creates scope item drafts and requirement drafts only. 6. Only a named, authorized human promotes a draft into anything the scoring engine can see. Extract, draft, review, approve, promote. 5.3 The external boundary. megamind-gateway gains a third backend: backend openai, endpoint https://api.openai.com/v1/chat/completions, bearer from the secrets resolver, model as a config value validated non empty at boot, enabled flag default false. Enabled without the secret fails the boot closed. internal/platform/scrub gains egress payload classes. Only these may leave the machine: PUBLIC_KNOWLEDGE, PUBLIC_DATA_SUMMARY, ONTOLOGY_SUGGEST, and REQUIREMENT_NORMALIZE. Public SAM.gov notice text may use the external backend under REQUIREMENT_NORMALIZE. Tenant uploaded documents and every private scope stay on the local plane, always. Never external, enforced by the gate and by tests: candidate rows, resume text, names, emails, phone numbers, tenant identifiers, anything from the eeo schema, RouteRAG and RouteGraph over tenant data, scoring inputs, scoring outputs, and slate contents. The gate fails closed to the local plane. Every external call audits backend name, payload class, byte count, and content hash, never content. The verifier gates all returned prose exactly as it does for local models. Record the backend in the model registry and AEDT inventory as outside the FIPS boundary, restricted to non regulated tasks. -------------------------------------------------------------------------------- 6. FRONTEND, INSIDE frontend/src/tools/slatematch -------------------------------------------------------------------------------- Intake screens: 1. Create opportunity: title, source type, agency or customer, solicitation or reference number, response deadline, prime or subcontract, capture owner, status. Minimum eight fields, nothing else required. 2. Opportunity intelligence: NAICS, PSC, set aside, place of performance, estimated value, period of performance, incumbent, source URL, notes, known partners. All optional. 3. Upload documents: drag and drop plus file picker, required document classification, file type allowlist, file size limit, sha256 duplicate detection, upload progress, extraction status, retryable extraction errors, malware scan hook. 4. Review scope: for every extracted item show the text, document name, page or section, extraction method, and confidence, with accept, edit and accept, reject, split, merge, and add manually. 5. Build requirements: generate drafts from accepted staffing scope, show missing required fields, allow manual completion, require named approval, promote, preserve lineage. Proposal workspace tabs: Overview (opportunity summary, customer deadline, internal deadline, owners, stage, readiness, hard blockers, scope changes, staffing coverage, compliance completion, section completion, review milestones, risks, recent activity), Scope, Requirements, Compliance Matrix (source requirement, document, page or section, response location, owner, due date, status, evidence, reviewer), Sections (code, title, owner, required, page or word limit, due date, draft status, review status, approval, version), Staffing (requirement, required quantity, linked slate, approved candidates, remaining gap, last scoring date, stale score warning), Milestones, Risks, Attachments, and Activity fed from the append only audit trail. Every new tile is clickable through to its filtered list. Reuse AppShell, ToolGuard, lib/queries, and the existing screen patterns. -------------------------------------------------------------------------------- 7. READINESS ENGINE, internal/modules/proposals/engine -------------------------------------------------------------------------------- Pure Go, shopspring/decimal, no database, no I/O, injected inputs, a READINESS_ALGO_VERSION constant. Weights: Staffing coverage 0.30 Compliance matrix 0.25 Required sections 0.20 Review and approval 0.10 Schedule health 0.10 Risk posture 0.05 Hard blockers cap readiness regardless of total, mirroring the band cap philosophy of the candidate engine without sharing a line of code with it: customer deadline passed, required compliance item open, required section missing, required staffing quantity uncovered, final approval missing, unreviewed amendment affecting scope, required attachment missing, submission validation failed. Every result returns overall score, component scores, driver explanations, hard blockers, calculation timestamp, and algorithm version. Submission is blocked server side while any hard blocker exists. Snapshots persist to proposal_readiness_snapshots. This makes the command center distinction concrete: low proposal readiness can be a documentation problem, not a people problem. -------------------------------------------------------------------------------- 8. BINARIES, EXHAUSTIVE LIST OF NEW COMMANDS -------------------------------------------------------------------------------- cmd/sam-attachment-sync download queued public attachments cmd/opportunity-extract run extraction over pending documents cmd/opportunity-scope-normalize model normalization pass, Section 5 cmd/opportunity-amendment-diff version diffing and impact flags cmd/proposal-readiness-snapshot scheduled readiness persistence cmd/proposal-deadline-alerts deadline sweeps into alerts cmd/stale-requirement-scan flag requirements older than policy cmd/oews-metro-sync Phase 4, BLS OEWS at MSA level, API v2 cmd/sca-wd-sync Phase 4, SAM.gov wage determinations cmd/usajobs-sync Phase 4, USAJOBS with the three headers Authorization-Key, User-Agent set to the registered email, Host data.usajobs.gov Task order depth extends cmd/awards-sync using USASpending File D1 through api.usaspending.gov bulk_download. Every binary follows the sam-sync pattern: idempotent, bounded, observable, audited, provenance aware, safe to rerun. -------------------------------------------------------------------------------- 9. API ROUTES -------------------------------------------------------------------------------- POST /api/opportunities GET /api/opportunities/{id} PATCH /api/opportunities/{id} POST /api/opportunities/{id}/documents GET /api/opportunities/{id}/documents POST /api/opportunities/{id}/extract GET /api/opportunities/{id}/scope POST /api/opportunities/{id}/scope/items PATCH /api/opportunities/{id}/scope/items/{item_id} POST /api/opportunities/{id}/requirement-drafts POST /api/requirement-drafts/{id}/approve POST /api/requirement-drafts/{id}/reject POST /api/proposals GET /api/proposals/{id} PATCH /api/proposals/{id} GET /api/proposals/{id}/readiness POST /api/proposals/{id}/readiness/snapshot POST /api/proposals/{id}/submit POST /api/proposals/{id}/outcome Plus normal CRUD for proposal sections, compliance items, milestones, risks, attachments, and staffing links. Every route follows the existing change discipline: thin handler, service layer logic, RunInTenantTx, capability check, tool entitlement gate answering 404 never 403, the same gate on flat alias paths, and an endpoint catalogue update. -------------------------------------------------------------------------------- 10. PHASES AND GATES -------------------------------------------------------------------------------- PHASE 0: SECURITY AND PREFLIGHT 1. HUMAN STEP, Joseph and Tom: revoke the exposed OpenAI key in the OpenAI dashboard. Claude Code verifies no key material exists anywhere in the repo or in any file it authors. 2. HUMAN STEP: create a fresh project scoped key under a Mission Workforce Technologies organization with a monthly usage cap and budget alerts. It enters internal/platform/secrets as openai_api_key, root owned 0600 on M4, and nowhere else. 3. HUMAN STEP: begin the SAM.gov system account application. Approval can take weeks, so it starts now even though Phase 4 consumes it. 4. Implement the scrub gate egress classes and external call audit rows with the backend flag still false. 5. Move INTELLIGENCE_EXPANSION_SPEC.md to docs/archive. 6. Create docs/BUILD_STATE.md with the ledger format from Section 0. GATE 0: gateway with openai enabled and no secret refuses to boot, proven against the live gateway. Scrub tests pass. BUILD_STATE exists. The archive move is committed. PHASE 1: OPPORTUNITY FOUNDATIONS 1. Migrations for tracked_opportunities, opportunity_versions, opportunity_documents, opportunity_document_chunks, and ingest_manifest per Section 2 item 9. 2. Intake screens 1 through 3 with create, intelligence, and upload flows. 3. sam-sync upgrade steps 1 through 8 of Section 4, including hash comparison, versioning, and attachment queuing. 4. cmd/sam-attachment-sync. 5. Amendment detection wiring into the alerts module. GATE 1: a SAM.gov opportunity ingests twice without duplication. A manual opportunity is created with only the eight minimum fields and supports every downstream capability a SAM.gov opportunity supports. Versions are immutable, proven by attempted update failing. Tenant authored fields survive a source refresh byte for byte, proven by test. Uploads are validated, hashed, versioned, and traceable. All touched screens render with zero 5xx and zero page errors. PHASE 2: SCOPE AND REQUIREMENTS 1. Deterministic extraction into chunks, Section 5.1. 2. Local model normalization producing cited scope item drafts. 3. External REQUIREMENT_NORMALIZE for public SAM.gov notice text only, behind the scrub gate. Backend may be enabled only if Phase 0 items 1 and 2 are recorded in BUILD_STATE. 4. Screen 4 scope review queue with accept, edit, reject, split, merge, and manual add. 5. requirement_drafts, screen 5, and the single transaction promotion path. 6. cmd/opportunity-extract, cmd/opportunity-scope-normalize, cmd/opportunity-amendment-diff. 7. Amendment impact analysis flagging affected approved requirements for named human acceptance. GATE 2: every extracted scope item carries a source citation. Uncited model output is rejected, proven by test. A fixture containing a candidate row and a fixture of tenant uploaded document text each fail the scrub suite when placed anywhere in an external bound payload. Eight racing promotions of one draft elect exactly one approved requirement. An ingest run during promotion corrupts nothing. Approved requirements are never rewritten by any ingest path, proven by test. PHASE 3: PROPOSAL OPERATIONS 1. Proposal migrations from Section 3.7. 2. The workspace tabs from Section 6. 3. The readiness engine from Section 7 with snapshots and cmd/proposal-readiness-snapshot. 4. cmd/proposal-deadline-alerts and cmd/stale-requirement-scan. 5. Submission workflow with server side hard blocker enforcement. 6. Outcome recording through bidoutcomes. 7. SLATE APPROVAL LIFECYCLE, merged from consolidated amendment 2.3. The slate member record gains status in proposed, approved, withdrawn, plus approved_by_user_id, approved_at, withdrawn_by_user_id, withdrawn_at, and withdrawal_reason, which is REQUIRED on every withdrawal and stored. Approve is one transaction taking FOR UPDATE on the member row: set status and stamps, and where the slate links to a proposal increment proposal_staffing_links.approved_count, audited through OnTx. The approval shows in the proposal Staffing tab, readiness inputs, and slate exports with who and when. Withdraw uses the same transaction discipline: requires the reason, sets status and stamps, decrements approved_count, audits, and flags the latest readiness snapshot stale. Withdrawal never deletes anything. Re approval after withdrawal is allowed and the audit trail carries the full sequence. Both actions use the existing slate decision capability and notify the capture owner and proposal owner through the alerts module. UI: approve and withdraw buttons on the member row, withdraw opens a reason modal, the row shows current status with the latest stamp. GATE 3: a proposal with any hard blocker cannot be submitted through the API, not merely the UI. The same inputs produce bit identical readiness scores across runs. Every readiness result includes component scores, driver explanations, blockers, timestamp, and algorithm version. All workspace tabs render with zero 5xx. An outcome lands in bidoutcomes. GATE 3 ADDITIONS, merged from consolidated amendment 2.3: approve, withdraw, and re approve leave approved_count exactly correct under an EIGHT WAY RACE, proven by racing it. A withdrawal without a reason is rejected by the API, not just the form. A withdrawal flips readiness staleness and the next snapshot reflects the reduced coverage. The full sequence is visible in the audit trail. PHASE 4: INTELLIGENCE TIER A 1. cmd/oews-metro-sync, cmd/sca-wd-sync (roughly ninety thousand wage determination records, current revision flagged, no bulk download, so page and cache), cmd/usajobs-sync including the unauthenticated code list API, and task order depth in cmd/awards-sync. 2. ontology-sync bump to O*NET 30.3 now and 31.0 when it lands late August 2026, CC BY 4.0 attribution recorded in the manifest, Career Exploration Tools excluded because their license is no derivatives. 3. Verify whether CALC+ under buy.gsa.gov exposes a usable bulk path before building on it. If not, ceiling rates load manually and are versioned. 4. Eleven compliance knowledge cards through curation.curate, each cited to primary sources: NYC Local Law 144, Illinois HB 3773 with the AI Video Interview Act, California FEHA automated decision rules, California CCPA ADMT rules, Colorado SB 26-189 and its stay, Texas TRAIGA, New Jersey LAD guidance, Mobley v. Workday through the 22 June 2026 order, the Kistler v. Eightfold FCRA theory and why missionMATCH is first party only, OFCCP after EO 11246 with the 5.1 percent VEVRAA benchmark and the ESDS listing duty, and the EU AI Act with Digital Omnibus timing. 5. Five new closed TAG intents, read only, parameterized, the model selects the name only: wage_benchmark_by_msa(soc_code, msa), sca_wd_lookup(state, county), recompete_radar(agency, naics, months_ahead), vevraa_benchmark_status(), and clearance_runway(clearance_level). 6. The AEDT evidence pack export stub in governance: scoring inputs, engine version, weights, band caps applied, model registry entry, exportable per decision. GATE 4: every sync writes ingest_manifest rows and reruns without duplicates. All eleven cards render with citations and appear in GET /knowledge/cards. All five intents live in the registry with tests. PHASE 5: recruitMATCH DESK COMPLETION 1. Expand the New Client form until a real client can be recorded: contacts, addresses, billing terms, status, notes. 2. Fix the stale hardcoded copy at internal/modules/recruitmatch/derive.go:73 so the dashboard reflects what is actually tracked. 3. Make dashboard stat cards clickable through to their filtered lists, platform wide. 4. Wire the existing time to fill migration to a real service. 5. Add revenue and bill rate tracking on placements, and candidate source on candidates, with reporting. 6. Add the redeployment metric with an assignment end date alert through the alerts module, plus submissions per job and fill rate analytics. MERGED FROM THE CONSOLIDATED AMENDMENTS. The full text of each item is in docs/DIRECTIVE_AMENDMENTS_CONSOLIDATED.md at the section cited; the summary here is the work order. 7. DESK INTEGRATION, amendment 2.4. (A) Requisition to requirement bridge: requisitions gain requirement_id, creating a job order either links an existing requirement or creates and links one using the structured fields the platform already scores against. The FROZEN engine is reached ONLY through this bridge. Editing a linked requirement after screenings exist marks those results stale, never silently. (B) Resume pipeline: upload on the candidate record and through apply intake, sha256, versioned, current flag, priors retained, bytes through internal/platform/storage; parsing through docextract and extraction into DRAFT profile suggestions accepted or edited by a recruiter, never silently applied; clearance always labeled clearance intelligence, self reported; duplicate detection on email and phone prompts open or merge. (C) Screen from the desk: a Screen action on an application runs screenMATCH against the requisition's linked requirement, storing score, band, caps applied, engine version, and timestamp on the application, with re screening history and a stale badge. 8. PUBLISHING TO THE TENANT WEBSITE, amendment 2.5. Requisition visibility internal_only or published with public label open, on_hold, filled, closed, behind a publish checklist. The mm_api public jobs handler renders SERVER SIDE HTML from Go templates: a careers index, one canonical detail page per published open job, and the apply endpoint. Exactly one JobPosting JSON-LD block per detail page mirroring visible content, none on the list page. nginx on Bubbles proxies fg-talent.com/careers/ to the mm_api upstream with the tenant slug fixed server side, and /careers/apply with its own limit_req zone. JOSEPH REVIEWS BOTH LOCATION BLOCKS BEFORE THEY TOUCH THE LIVE VHOST. Apply intake is same origin, creating or dedupe matching a candidate and an application in the applied stage, source career_site, consent event stored with notice version, honeypot plus rate limiting. Nothing is ever posted to Google: indexing is the careers sitemap section regenerated on publish and unpublish, internal links, GSC Request Indexing, and the URL Inspection API. Expiry discipline through cmd/jobs-expiry-sweep. FG TALENT CONTENT RULE, enforced in template AND in test: only Patricia Cox and Brian Atwood may appear on the public site or in schema; Tom and Glennette appear nowhere. hiringOrganization is FG Talent Partners. Tenant mapping is configuration: tenant_slug, public_base_url, brand template, consent notice reference; a mapped tenant's jobs path on the missionMATCH domain issues a 301. 9. DESK WORKFLOW ADDITIONS 1 through 11, amendment 2.6: structured intake brief (role context, candidate profile, submission logistics), pipelines per placement type, client submittal records with feedback reason codes and an aging SLA timer, a reason taxonomy on every rejection and backward stage move, days in stage aging, activities and tasks wired into every record surface, talent pools and saved searches, status triggered alerts with human send, offers completed with decline reasons flowing into placements, an optional per client requisition approval chain, and client specific submittal requirements. 10. THE IMPORT CENTER AND UPLOADS, amendment 4. ONE upload subsystem, three entry points (candidate record, recruitMATCH Import Center, screenMATCH screen from resume), and apply intake uses the same path. Every bulk import is STAGED, never direct: import_batches, import_rows, import_mappings, then validate, preview, and a HUMAN COMMIT with a first party attestation. Protected class columns are REJECTED at validation by name pattern and content sniffing; EEO data never enters through an import. cmd/import-process is asynchronous, bounded, observable, audited, and idempotent by row action. Archive safety on every zip: list entries first, per entry allowlist and size cap, entry count cap, reject nested archives and path traversal. 11. THE CANDIDATE SPINE AND THE CANDIDATES PAGE, amendment 5. ONE candidate spine shared by every surface, with shared frontend profile components composed by both the command center and the new recruitMATCH Candidates page. Candidate search is DETERMINISTIC SQL through the existing hybrid fusion exposed as a repository query; the AI Ask path is untouched. Reverse match runs the frozen engine, one candidate against every open requisition's linked requirement, persisting score, band, engine version, and computed_at, going stale on change. Add to job order creates the application under FOR UPDATE with exactly ONE active application per candidate per requisition enforced by a partial unique index over non terminal statuses. Applications record added_from and, when added from a match, the score snapshot at add time. Job order status is a state machine (draft, open, on_hold, filled, closed) that UPDATES ITSELF: filling the last seat flips to filled inside the placement transaction the seat lock governs, moves remaining active applications to filled_by_another (a distinct outcome, never a rejection) with notifications, and unpublishes the public page; a fall off frees the seat, reopens the order, alerts, and NEVER republishes without a human confirm. GATE 5: a real client is created through the UI. The full pipeline, contacted to interview to offer to hire or no hire, is exercised end to end with data. Time to fill, fill rate, submissions per job, redeployment rate, revenue, bill rate, and source all render with real numbers. Zero 5xx. GATE 5 ADDITIONS, merged from consolidated amendments 2.8, 4.6, and 5.7. Publishing and desk (2.8): publish a job order and load it at https://fg-talent.com/careers/ and its detail URL, with curl showing full job content in the INITIAL HTML response, no JS required. Exactly one JobPosting JSON-LD block mirroring visible content, passing Rich Results. Apply from fg-talent.com creates a candidate and an application, stage applied, source career_site, consent event stored with notice version, duplicate check firing on a repeat email. Filling the order removes the detail page, the index entry, the sitemap entry, and the markup. The missionMATCH domain path for the FG Talent slug issues a 301. Page and schema contain Patricia Cox and Brian Atwood only, with a TEST asserting Tom and Glennette appear nowhere in rendered output or JSON-LD. Unknown slug returns 404 leaking nothing, and the apply rate limit answers 429 under a race. The careers sitemap regenerates on publish and unpublish, GSC Request Indexing is exercised once and recorded, and the feed renders on a test page. Screen from an application stores a banded result that goes stale when the requirement changes; resume parse produces suggestions and never overwrites; duplicate detection fires. An intake brief saves with all three blocks, a client submittal records feedback with a reason code whose SLA timer ages, a rejection carries a taxonomy reason, and an accepted offer flows into a placement carrying rates forward. Imports (4.6): a three file resume bundle commits to three candidates with parsed suggestions and batch and row lineage. A planted duplicate triggers the dedupe prompt and a merge produces ONE candidate. A spreadsheet with a protected class column is REJECTED at validation with the column named and nothing reaches a live table. A five hundred row spreadsheet commits with correct counts and a clean error export. KILL cmd/import-process MID COMMIT and rerun: the batch completes with no duplicates, proven by counts. Screen from resume produces a banded result and the dedupe prompt fires. A bulk screen fills the queue and lists a corrupt file as failed. A zip with path traversal and a zip with a nested archive are both rejected AT LISTING. Every commit stores the attestation with user and timestamp. An uncommitted batch is invisible to candidates, search, matching, and slates, proven by query. Candidates and dataflow (5.7): the Candidates page finds a planted candidate by skills filter and by free text through the fusion query, and the command center Candidates screen still renders from shared components with ZERO regression. Reverse match returns an IDENTICAL ranking across repeated runs and the engine diff remains empty. Add to job order from the match list creates the application with 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. Stage counts update through every stage and each tile clicks through. Placing the final seat flips the order to filled, moves remaining applications to filled_by_another with alerts, and removes the fg-talent.com page and sitemap entry. A simulated fall off frees the seat, reopens the order, does NOT republish, and a one click reactivation restores a filled_by_another candidate to their prior stage, audited. Re adding a previously rejected candidate demands a reopen reason. A candidate on a proposal slate and in a desk pipeline resolves to ONE candidate id everywhere. PHASE 5A: IDENTITY AND ACCESS Inserted between Phase 5 and Phase 6 by docs/DIRECTIVE_AMENDMENT_6.md, triggered by live FG Talent feedback. Full text in that file, section 4. 1. MATRIX REBUILD. Capabilities become entity action pairs carrying an OWNERSHIP SCOPE of own, team, or organization, plus feature capabilities for export, bulk edit, import commit, publish, and the existing approvals. The nineteen current capability keys REMAIN AS ALIASES mapped forward, never renamed destructively. Role defaults, tenant scoped, each row building on the one before it: viewer reads only with no export and no rates and no EEO ever; member adds notes, tasks, and activities; recruiter adds full desk work, imports including commit with attestation, pools and saved searches, pay rate visible, export limited to own and team; manager adds orders create and edit, publish and unpublish, requirement approval and proposal submission, bill rate and margin visible, organization wide export and bulk edit, fall off reactivations; admin adds user management, tenant settings, stage templates, notice templates, import mappings, and integration configuration; owner adds billing and plan, retention settings, and full data export; superuser is owner plus everything else BY RULE, WITHIN ITS TENANT ONLY; operator is everything everywhere including platform surfaces, always audited, MFA always. 2. OWNERSHIP SCOPES as an attribute of each entity action capability, with team defined by the light teams model (an optional team assignment per tenant). 3. FIELD SENSITIVITY CLASSES, first class rates: pay rate visible to recruiter and above; bill rate and margin visible to manager and above and INVISIBLE below that everywhere. Wired through render, export, feed, and API layers so a hidden class is ABSENT FROM THE PAYLOAD, not blanked in the UI. The mechanism is generic so future sensitive fields reuse it. 4. IMPERSONATION, operator only: view as a user with a persistent on screen banner, read only by default, write only through explicit escalation, auto expiry within the hour, every impersonated request audited with BOTH identities. 5. ORGANIZATIONS PROVISIONING, operator console: create a tenant, set product entitlements per tool, configure the site mapping, and invite the first superuser by email. The productized path for onboarding the next client. 6. The exhaustive capability matrix tests are REGENERATED for the new shape and pass in full, including the alias mapping from the nineteen legacy keys. GATE 5A: the regenerated matrix tests pass for every role, every tool, every scope. A recruiter cannot obtain bill rate or margin through ANY surface, screen, export file, feed, or raw API response, proven by fixture inspection of the payloads. The grant ceiling holds at every rung, proven by attempting each violation. Impersonation shows the banner, expires on schedule, defaults read only, and writes both identities to every audit row it touches. Provisioning on staging creates a tenant, entitles products, configures a site mapping, and delivers a working superuser invitation end to end. A tenant superuser requesting any platform route receives 404, and the operator with MFA reaches all of them. PHASE 6: PRODUCTION HARDENING AND GO LIVE 1. Enable MFA. Set MM_ENV to production and validate the MM_ALLOW_SELF_HOSTED_PRODUCTION path so every production gate is live. 2. Queue and sync metrics through obs. 3. Backup and restore test, large document tests, and a rerun of the full concurrency suite including the original sixteen racing stage transitions. 4. Documentation sweep: Owner's Manual, MODEL_CARD, STACK_DECISIONS, endpoint index, table index, runbooks, and the honest work queue, which must match BUILD_STATE exactly. GATE 6: the final acceptance list in Section 11 passes in full. POST GO LIVE FAST FOLLOW, not gated for launch: agency forecast ingestion, VEVRAA state job bank posting starting with design partner states, the SkillBridge authorized organizations directory (organizations, never people), SBA socioeconomic data through SAM.gov entity extracts, the hand curated quarterly clearance runway reference table from GAO and performance.gov, and licensed compensation benchmarks, never scraped. Merged from consolidated amendment 2.7: the client portal rendering the submittal and feedback model, read only, per client contact authentication; automated candidate engagement sequences on status triggers once a sending policy is decided; VEVRAA ESDS posting reusing the publish pipeline as its source of truth; knockout questions and reference check records on applications; a placement start onboarding checklist; and requisition and placement history import. -------------------------------------------------------------------------------- TASK T1: MARKETING SITE LOGIN BUTTON, STANDALONE -------------------------------------------------------------------------------- Registered from consolidated amendment 2.2. This is standalone work OUTSIDE the phase gates and OUTSIDE the missionMATCH repo, executed on the Bubbles vhosts. 1. Enumerate the nginx vhosts on Bubbles and identify where missionMATCH is marketed publicly. The application itself lives at https://missionmatch.thatwebhostingguy.com, so the button belongs on the marketing surface, not inside the app. 2. If the target is ambiguous, list the candidate vhosts for Joseph in ONE message and WAIT for his pick. Never guess on a production website. 3. Add a prominent Log in button in the site header and hero linking to https://missionmatch.thatwebhostingguy.com. Static HTML, CSS, and vanilla JS, brand consistent, no framework, no Python. 4. If no marketing page exists, say so and build a single branded page with a hero, a product line summary, and Log in, at the vhost Joseph names. 5. Verify rendered in a browser over HTTPS before recording done. -------------------------------------------------------------------------------- 11. FINAL ACCEPTANCE, ALL MUST PASS -------------------------------------------------------------------------------- 1. A SAM.gov opportunity is ingested without duplication. 2. A manual opportunity is created with minimum information. 3. Manual and SAM.gov opportunities have full feature parity. 4. Amendments create immutable versions. 5. Tenant capture data survives source refreshes. 6. Uploaded files are validated, hashed, versioned, and traceable. 7. Every extracted scope item has a source citation. 8. Uncited model output is rejected. 9. Private scopes never use external inference, proven by the scrub suite. 10. Requirement drafts cannot enter candidate scoring without named human approval. 11. Amendments never silently rewrite approved requirements. 12. Proposals cannot be submitted with hard blockers, enforced server side. 13. Readiness calculations are bit reproducible. 14. Every readiness result includes explanations and an algorithm version. 15. Every new tenant table has organization_id, forced RLS, and the composite index. 16. Cross tenant queries return zero rows. 17. All jobs are idempotent and rerun safe. 18. Every external source writes provenance to ingest_manifest. 19. The gateway with openai enabled and no secret refuses to boot. 20. No new Python exists anywhere, confirmed by rg. 21. No dashes exist in written docs, confirmed by rg. 22. Audit records remain append only, update and delete still revoked. 23. The candidate scoring engine diff against the starting commit is empty. 24. BUILD_STATE, the honest work queue, and reality agree. Merged from the consolidated amendments, sections 2.9, 4.7, and 5.8. 25. Slate approval and withdrawal maintain correct counts under race, and every withdrawal carries a stored reason. 26. Public jobs surfaces expose only published data, resolve tenants by slug only, and pass Rich Results validation on every live posting. 27. Expired or filled postings drop their markup immediately, verified by the sweep job's test. 28. Apply intake stores a consent event with notice version for every submission. 29. Desk screenings reach the engine only through the requisition to requirement bridge, and the engine diff remains empty. 30. No import writes a live record except through a committed batch, and every imported record carries batch and row lineage. 31. Protected class data cannot enter through any import path, proven by the rejection tests. 32. Import batches are idempotent under rerun and partial failure, with counts that always reconcile to rows. 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. Merged from docs/DIRECTIVE_AMENDMENT_6.md section 5. 36. Every role can edit its own profile, and identity changes are audited and propagate everywhere the identity renders. 37. The role grant ceiling is enforced at the API for every rung of the ladder. 38. Rates above pay are invisible below manager on every surface, including exports, feeds, and raw API payloads. 39. Operator requires MFA without exception, platform surfaces answer 404 to everyone else, and every impersonated action carries both identities in the audit trail. 40. User accounts are never deleted; deactivation blocks login while preserving ownership, activity, and audit history. DEFINITION OF DONE A company can discover an opportunity from SAM.gov or enter one manually, upload and version its solicitation package, extract and review the scope, approve workforce requirements, generate staffing slates, manage proposal compliance and content, measure explainable readiness, submit the proposal, record the outcome, and trace every material decision back to its original source, all inside missionMATCH, with nothing built beside it. ================================================================================ APPENDIX A. THE CANONICAL DATAFLOW, PERMANENT ================================================================================ Merged from consolidated amendment 5.1 as a permanent part of this directive. 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 Both match directions use the SAME FROZEN ENGINE: a job order ranks candidates, and a candidate ranks open job orders, both reading 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 one candidate record.

Search equations, builds, manuscript text, and recovered sources.