Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / docs/PHASE2_DOCUMENT_TRIAL.md |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | docs/PHASE2_DOCUMENT_TRIAL.md |
| Original SHA-256 | 4cd9d7ead43aef67d55662ce69de70587729d89a88fffc80e1e2a4ba5e0f71a9 |
| Git blob SHA | 95dac11f773ee9689ef41bff4b0b4b479a8f8dc2 |
| Reading-copy SHA-256 | 4cd9d7ead43aef67d55662ce69de70587729d89a88fffc80e1e2a4ba5e0f71a9 |
Recovered source transcript
Download complete source text ↓166 lines · 9.4 KB
# PHASE 2 REAL DOCUMENT TRIAL: A READY TO EXECUTE CHECKLIST
Written 28 July 2026. Phase 2 Gate A is OPEN pending exactly ONE blocker: a real
solicitation package from Joseph.
THIS FILE EXISTS SO THE PACKAGE ARRIVING IS THE ONLY REMAINING INPUT for the
steps that can run today.
REHEARSED END TO END AGAINST A SYNTHETIC PACKAGE, 28 July 2026, and it FAILED IN
FOUR PLACES. That is why the rehearsal happened: a checklist nobody has ever
executed is a plan, not a procedure, and it is cheaper to break it now than in
front of the owner. Full record at
docs/evidence/phase2/functional/document-trial-rehearsal.txt. The corrections are
folded in below and the two that change the plan are stated here:
BOTH OF THOSE WERE FIXED ON 28 JULY and the checklist is updated accordingly.
The upload handler, cmd/opportunity-extract, cmd/opportunity-amendment-diff and
cmd/sam-attachment-sync all exist and are proven on staging. The PDF reader was
chosen by measured bake off (ledongthuc/pdf, 25 of 29 real federal PDFs usable,
zero panics) and real attachments now yield genuine text. STEPS 1, 2 AND 6 RUN.
WHAT IS STILL TRUE: step 3 composes notice METADATA, about 250 bytes of header
fields, when it runs from a tracked notice. Running it against EXTRACTED
DOCUMENT CHUNKS is the remaining wiring, and the trial is where that gets
exercised on real text for the first time.
## WHERE THE PACKAGE GOES
/home/user/missionmatch/inbox/ ON MEGAMIND-AGI
NOT on Bubbles. Topology rule, owner decision 29 July 2026: Bubbles carries only
hosted site content and deployed production artifacts. Every fixture, inbox, and
work directory lives on megamind-agi. Verify SHA256SUMS on the remote side before
running anything below.
## WHAT IS NEEDED, precisely
An RFP or combined synopsis containing:
a PWS, SOW, or SOO
AT LEAST ONE amendment, because amendment handling is half of what is proven
ideally an attachment list, which exercises the deferred Phase 1 items
Drop it anywhere and say where. No format work is needed first.
## THE ORDER OF OPERATIONS, and why it is this order
Section 5.1 of the directive is explicit: DETERMINISTIC EXTRACTION FIRST, before
any model call. That ordering was already violated once and corrected in 0da4c7c,
so it is written down here rather than trusted to memory.
STEP 1 RUNS. POST /api/opportunities/{id}/documents, multipart, gated on
opportunity.manage. Upload through the real intake path, never a
database insert: an insert would skip the allowlist, the size cap, the
malware hook, and the sha256 dedupe, which are the four things this
step exists to prove.
Proves: sha256 duplicate detection, the file type allowlist, the size
cap, extraction_status pending, and that the malware scan hook sits
between upload and pending.
Expect: opportunity_documents row, provenance BORN tenant_upload by
migration 0081, which nothing in the app can override.
ALREADY PROVEN by the rehearsal, directly against the table: an insert
DECLARING public_cache was born tenant_upload regardless. The provenance
half of this step needs no document at all.
The column is file_name, not filename.
STEP 2 RUNS. cmd/opportunity-extract -dsn <dsn> -storage-root <root>.
DETERMINISTIC only, no model.
Proves: headings, numbered clauses, tables, dates, deadlines, dollar
values, labor categories, quantities, clearance terms, certifications,
locations, travel percentages, period of performance, deliverables, and
evaluation factors land in opportunity_document_chunks WITH provenance:
page, section label, content hash, extraction method, confidence.
ASSERT: every chunk carries its provenance. A chunk that cannot say
where it came from cannot support a cited scope item later.
STEP 3 cmd/opportunity-scope-normalize, the model pass, LOCAL plane only.
RUNS TODAY, on notice METADATA. It composes nine header fields, about
250 bytes. It will consume a PWS only once steps 1 and 2 exist, and
until then the scope items restate the notice header.
ASSERT FIRST, before running: the payload composer must refuse. The
document is provenance tenant_upload, and AllowEgress refuses any
payload whose element set contains it. THIS IS THE TEST THAT MATTERS
on a real document: the external lane must be structurally unreachable
for a customer's own package, not merely unused.
Then run it against the LOCAL model and confirm cited scope items.
Invocation, proven in the rehearsal:
go run ./cmd/opportunity-scope-normalize -dsn <migrator> \
-megamind http://100.94.8.94:8091 -token <gateway token> \
-limit 1 -dry-run
The staging gateway token is in the staging secrets file, NOT the
production api.env. The production token returns 401 here.
ASSERT: ck_scope_items_cited refuses any uncited machine produced item.
ASSERT: a fabricated citation, a quote not present in the source text,
is rejected by ValidateScopeCandidates.
STEP 4 Scope review queue, screen 4, as a recruiter and as a manager.
Accept, edit and accept, reject, split, merge, add manually.
ASSERT: every item shows its document name, page or section, extraction
method, and confidence. A reviewer who cannot see the provenance is
approving a claim rather than checking one.
STEP 5 Requirement drafts, screen 5, then PROMOTION.
ASSERT: promotion records the NAMED HUMAN. TWO constraints do this and
they fire in a FIXED ORDER, so testing only one proves only one:
ck_drafts_approved_has_requirement fires FIRST, an approved draft
must carry approved_requirement_id
ck_drafts_decided_has_reviewer fires only once the first is satisfied
Assert BOTH, and follow them with a plain draft insert as the positive
control, because a table that refused everything would look identical.
review_status is draft, in_review, approved, rejected. There is no
"pending". The label column is labor_category, there is no "title".
ASSERT: the promoted requirement links only skills the EXISTING ontology
knows. A solicitation names skills the ontology lacks; those stay
unlinked, because writing the global ontology is operator curation and
never a side effect of approving one requirement.
STEP 6 AMENDMENT. Ingest the amendment.
ASSERT: a NEW immutable opportunity_versions row, its predecessor
retired in the SAME transaction, the ingest manifest cited.
ASSERT: the diff flags deadlines, labor categories, quantities, security
requirements, and evaluation criteria.
ASSERT: affected APPROVED requirements are FLAGGED for a named human and
NOT rewritten. This is acceptance item 11 and the whole safety promise.
The synthetic proof already passed: an approved requirement survived 20
ingest rounds byte for byte. The real package proves it on real text.
STEP 7 The two DEFERRED PHASE 1 ITEMS, BOTH NOW BUILT as of 28 July. The
upload screen handler exists and cmd/sam-attachment-sync pulls the
public attachment package. What the trial adds is the first exercise of
both against documents nobody here authored.
intake screen 3, uploads, with drag and drop, progress, extraction
status, retryable errors, and duplicate detection by sha256
cmd/sam-attachment-sync, downloading queued public attachments
CORRECTED 28 July 2026: the earlier line here said both were deferred
on documents existing and never on engineering. The upload screen has
no handler behind it and there is no extraction binary at all, so that
claim was wrong for the upload half and is withdrawn. The attachment
sync genuinely does wait on public attachments existing.
## THE GATES THIS CLOSES
GATE 1 remainder: uploads validated, hashed, versioned, traceable. NOT closable
by the package alone, see steps 1 and 2.
GATE 2 remainder: every extracted scope item carries a source citation, on a
REAL document rather than a fixture. The synthetic halves are already proven
and filed under docs/evidence/phase2/. The REAL document half waits on the
same engineering, because nothing today puts a document in front of the
extractor.
## WHAT IS ALREADY PROVEN AND DOES NOT NEED REDOING
Uncited model output rejected, by test AND by a live insert refusal.
Eight racing promotions elect exactly one requirement, and thirty two also.
Ingest during promotion corrupts nothing; approved requirements survive it.
The external boundary refuses candidate rows and tenant documents by
provenance bound at origin, with the binding sites enumerated by test.
Schema constraints proven against a live database by six refusal tests.
## THE ONE JUDGEMENT CALL TO EXPECT
A real PWS will name skills the ontology does not carry. That is NORMAL and the
correct behaviour is to leave them unlinked and surface them, NOT to write the
global ontology. If the trial produces a long list of unlinked skills, that is a
curation backlog for an operator, not a defect. Recording this in advance so it
is not mistaken for a failure on the day.