# Single Frozen Semantic Audit — EM-OPS-02 ## 1. Verdict **REVISE.** The identity decision itself is sound and is not reopened: two identifier-unassigned candidates (Procurement Request, Sourcing Event), four profiles over WM-ECO-021 / WM-ACT-034 ×2 / WM-KNW-010, downstream WM-ECO-006 and WM-ECO-019 untouched. The defect is that the candidate artifacts do not carry the structure their own invariants and fixtures assert. Most invariants in both `allocation-candidate.json` files are unenforceable against the declared `objects`, and the profile candidate is prose with no objects, no fixtures and no validation policy. ## 2. Material defects **D1 — Event lifecycle conflates event state with round state; the agreed multi-round scenario is unrepresentable.** `SourcingEvent.lifecycle` = `["planned","published","open","sealed","opened","evaluating","awarded","cancelled","closed"]` while `SourcingRound.lifecycle` = `["draft","published","open","sealed","opened","finalized","superseded"]`. Invariant *"A material post-publication change creates an addendum, equal notification and a successor round"* plus fixture `criterion-addendum` (*"a successor round while the v1 round remains readable"*) require round 1 `finalized` and round 2 `open` at the same instant. A single event-level `sealed`/`opened`/`evaluating` state cannot hold both. **D2 — No witnessed-opening record and no per-bid seal or time fields; two invariants and one negative fixture are undecidable.** Invariants *"Receipt time, sealing time and opening time remain distinct"* and *"Sealed content is not exposed before the authorized witnessed opening"*; fixture `open-before-witness` expects *"The disclosure is rejected."* The only related fields are `contentDigest` (required, round-level, subject undefined) and `openingRule` (optional). There is no `openedAt`, no `openingWitnessRef`, no `sealedAt`, no `receivedAt`, and no per-bid digest — though grok-study's accepted scenario is *"Bids B1, B2 and B3 are submitted, hashed and sealed"*, i.e. per-bid. **D3 — No receipt/admissibility object, though the event claims to own it.** `owns` lists *"submission window and receipt rules"* and *"bid admissibility and evaluation-round bindings"*; local-evidence says *"the buyer owns only receipt and procedure bindings"*; claude-study adds *"disposition of late or non-compliant submissions"*. No object exists for any of it. Without it, buyer-side receipt has nowhere to live that does not re-mint supplier bid identity — a latent violation of the agreed invariant *"Supplier bid identity and immutable submitted versions remain supplier-owned."* **D4 — Temporal layer absent.** The only instant in either candidate is `closedAt` (optional). `submissionWindow` is required but untyped; criteria releases have no `effectiveFrom`, contradicting local-evidence *"Every criterion set has a version and effective time"* and the `identityTest` claim of *"immutable event releases and rounds"*. No format constraint is stated, although claude-study requires *"RFC 3339 with seconds and explicit offset throughout"* and separation of event, observation and ingestion time. **D5 — No evaluator roster, conflict declaration, independent determination or recusal structure anywhere.** Invariant *"Conflicts are declared before determination and recusals remain in history"* and fixture `conflicted-evaluator` have no backing fields. claude-study states the base gap explicitly — WM-ACT-034 *"records no function that assigns assessors or captures impartiality before determination begins — the BidEvaluation profile must add that as a required extension"* — and `profile-candidate.json` adds nothing beyond the sentence *"Conflicts, recusals, exclusions, waivers and superseded rounds remain append-only and explainable."* The declarant≠determiner rule and grok invariant 10 (*"A conflicted evaluator does not score the affected comparison"*) are therefore unenforceable. **D6 — Round-creation and remediation rules are mutually contradictory (three parts).** (a) Trigger: invariant 6 makes a successor round the consequence of a *criteria change*, but fixture `conflicted-evaluator` expects *"a replacement round is attributable"* from a *recusal* — a round with no criteria change and no defined criteria binding. (b) Bias adjustment vs immutability: local-evidence permits outcomes to be *"excluded, replaced or bias-adjusted according to a declared method"* while the invariant states *"Finalized rounds are append-only and never recomputed in place"*; bias adjustment of a finalized outcome is a recomputation unless it is defined as a new marked result. (c) Bid carry-over: grok-study holds *"Round-1 bids are not re-scored on V2. Suppliers may submit round-2 responses"*; claude-study has *"round 2 is opened and scored under v2"* and *"excluded with re-scoring in round 3"*. The artifacts resolve neither, so `rewrite-finalized-round` only forbids in-place mutation and still permits scoring a round-1 bid version under v2 without resubmission. **D7 — Notification scope is indeterminate and unrecorded.** local-evidence: *"equal notification to affected participants"*; claude-study: *"must be notified to all participants"*; `profile-candidate.json`: *"equal participant notification"*. No notification record exists and `participantScope` is `optional`, so "equal" has no referent set and no evidence. **D8 — `procedureKind` is unenumerated and single-source obligations are inconsistent.** Invariant 1 requires a `procedureKind` but no value set is declared, so the conditional single-source rules cannot bind. No field holds justification ground, deciding authority, mandate scope or baseline. Fixture `single-source` expects *"A real one-alternative set, justification and waiver are recorded"* — making a waiver mandatory — while the invariant requires only *"a real one-alternative set and justification"* and local-evidence says *"and any waiver"* (optional). **D9 — `evaluating` and `awarded` are states with no anchoring field, and `awarded` leaks award into the event.** `excludes` lists *"assessment or award-decision identity"*, yet `owns` lists *"award linkage and closure history"* and the lifecycle contains `awarded`. `objects.SourcingEvent` has no `evaluationRefs` and no `awardDecisionRef`, so both states are unverifiable, and grok invariant 12 (*"AwardDecision does not create, sign or imply WM-ECO-006 or WM-ECO-019"*) has no counterpart constraint keeping `awarded` purely referential. **D10 — Procurement Request declares version identity it cannot express.** `versionIdentity`: *"Changes to requested scope, quantity, delivery constraints, authority or funding references create immutable request versions"*; invariants *"Scope, quantity and delivery changes create traceable request revisions"* and *"Historical request versions remain resolvable after fulfilment or closure."* `identity` is `["procurementRequestId"]` only — no revision identifier, no supersession chain, no effective time. `successorRef` is overloaded: `versionIdentity` also says *"a materially distinct need creates a new request"*, so the same field would denote both revision succession and new-request succession. **D11 — No approval record, and `authorityRef` is optional.** `owns` includes *"approval, rejection and withdrawal history"*; lifecycle includes `approved`; invariant *"Approval authorizes sourcing activity only within the recorded scope"*. No approver, no authority binding at approval, no decision instant, no pinned scope revision — and `authorityRef` sits under `optional`, so an `approved` request with no authority at all validates. **D12 — Trace links are claimed but absent, and the request↔event direction is contradictory.** `owns` includes *"sourcing-event and downstream trace links"* and fixture `split-fulfilment` expects *"The request retains one identity and references both orders without merging them"* — yet `ProcurementRequest` has no `sourcingEventRefs`, `agreementRefs` or `orderRefs`. On the event side `requestRefs` is `optional` and plural, contradicting grok-study's accepted boundary *"An event cites one authorizing request"* and leaving the invariant *"A rejected request cannot silently enter a sourcing event"* with no enforcement point on either side. Compounding this, the reference entry `{"target":"WM-KNW-010","purpose":"Approval or award decision"}` fuses the request's *owned* internal approval with the award decision its own `excludes` disclaims. **D13 — The profile candidate carries no testable obligation, and is misfiled.** `profile-candidate.json` has `bases` and six prose `constraints`; it declares no objects, no required fields, no fixtures file and no validation policy — so SupplierBid, BidEvaluation, SupplierQualification and AwardDecision, which carry most of the fairness load, are entirely unverified. The seam rule *"references evaluation results without copying them"* has no field-level prohibition and no stated behaviour when no BidEvaluation exists; AwardDecision is nowhere required to cite the criteria version, the relied-upon round, the considered bid set or the selected bid, although both studies make those mandatory. It is also stored inside `candidate-allocation-offline-procurement-request/`, whose `excludes` list disclaims *"supplier qualification or bid evaluation"* and *"award decision, agreement or purchase order"*. **D14 — Validity windows are never checked at the moments that matter.** claude-study: *"bid validity windows can lapse before award"* and qualification is *"a precondition or screening input to bid admissibility"* with *"its own validity window"*. No invariant, field or fixture requires bid validity to hold at the award instant or qualification standing to be pinned as of receipt, so a lapsed bid can be awarded and an expired qualification can gate admissibility silently. **D15 — Fixtures are not mechanically checkable, and one bundles two assertions.** All twelve cases state `expect` in prose with no code; `validation-policy.json` requires `minimumFixtures`, `requiresPositiveAndNegativeFixtures` and similar counts but nothing tying fixtures to invariants, so 24 invariants are covered by 12 prose cases. `winner-is-contract` expects *"Both transitions are rejected"* — contract formation and order issuance in one undiscriminated assertion. Separately, both candidates write `"canonicalPublishable":false` while the hold text in both studies names the field `publishableCanonical`; one of the two spellings will not validate. ## 3. Required bounded fixes 1. **D1** — Reduce `SourcingEvent.lifecycle` to round-agnostic states `["planned","published","active","evaluating","awarded","cancelled","closed"]`. Keep `sealed`/`opened`/`finalized`/`superseded` only on `SourcingRound`. Add `SourcingRound.roundNumber` (serial, append-only). 2. **D2** — Add required `SourcingRound.openedAt` and `SourcingRound.openingWitnessRef` as a conditional pair on state `opened`; rename round `contentDigest` to `criteriaSnapshotDigest` with a stated subject; move seal evidence to the receipt object (below). 3. **D3** — Add object `BidReceipt`, identity `["sourcingEventId","roundId","bidRef","bidVersion"]`, required `receivedAt`, `contentDigest`, `sealState` (`sealed|opened`), `admissibility` (`admitted|late-admitted|rejected|withdrawn`), optional `latenessDisposition`, `waiverRef`, `qualificationStandingRef`. State explicitly that `bidRef`/`bidVersion` are supplier-issued and never re-minted. 4. **D4** — Require RFC 3339 with seconds and explicit offset for every instant; add `publishedAt`, `submissionWindow.{opensAt,closesAt}`, `criteriaEffectiveFrom`, `finalizedAt`, `awardedAt`; keep event time separate from record/ingestion time. 5. **D5** — In the BidEvaluation profile add required `evaluatorRoster[]` with `{evaluatorRef, mandateRef, assignedAt, declaredInterests[]}`, and `conflictDetermination[]` with `{interestRef, determinedBy, determinedAt, outcome, recusalEffectiveAt}`. Constrain `determinedBy != declarant` and `determinedAt < first outcome instant for the affected comparison`. 6. **D6** — (a) Add `SourcingRound.roundKind` ∈ `{solicitation, remediation}`; `remediation` must pin the same `criteriaSetRef` and the same bid versions, and may not reopen submission. (b) Define bias adjustment and exclusion as **new marked results in a successor round**, never edits to a finalized outcome; add `resultMarker` ∈ `{active, excluded, bias-adjusted, contested, superseded}` with `supersedesResultRef`. (c) State the rule once: a bid version scored under criteria vN may never be scored under vN+1; a new criteria version requires a solicitation round with new or re-affirmed submissions. 7. **D7** — Make `participantScope` required on any `published` round. Add `Addendum` with required `notifiedParticipantRefs[]`, `notifiedAt`, `criteriaSetRef`, and a rule that the notified set equals the round's participant scope. Fix the wording to **all participants in scope** and align `profile-candidate.json` to it. 8. **D8** — Enumerate `procedureKind` ∈ `{open, restricted, negotiated, single-source}`. When `single-source`, require `justificationGround`, `decidingAuthorityRef`, `mandateScope`, optional `baselineComparisonRef`, optional `waiverRef`. Correct the `single-source` fixture: waiver optional, justification and authority mandatory. 9. **D9** — Add optional `evaluationRefs[]` and `awardDecisionRef`, required when status is `evaluating`/`awarded`. State that these are referential only and create no agreement or order. 10. **D10** — Add `ProcurementRequest.revisionId` to identity, plus required `revisionEffectiveFrom` and `supersedesRevisionRef`; rename `successorRef` to `replacementRequestRef` for the distinct-need case. 11. **D11** — Add required `approvals[]` `{approverRef, authorityRef, decidedAt, decision, approvedScopeRevisionRef}`; move `authorityRef` to required once status reaches `submitted`. 12. **D12** — Add `sourcingEventRefs[]`, `agreementRefs[]`, `orderRefs[]` to `ProcurementRequest`. Make `SourcingEvent.authorizingRequestRef` required with a single value, or an explicit `noRequestGround` from a closed list. Add the invariant that a request in `rejected`/`withdrawn` cannot be an `authorizingRequestRef`. Split the WM-KNW-010 reference into two purposes: *internal procurement approval* (owned) and *award decision* (referenced only). 13. **D13** — Give the profile candidate objects and required fields for SupplierBid, BidEvaluation, SupplierQualification and AwardDecision; add `fixtures.json` and `validation-policy.json` alongside it; relocate it out of the Procurement Request directory into a shared `profile-em-ops-02/`. Require on AwardDecision: `criteriaSetRef` (versioned), `reliedUponRoundRef`, `consideredBidRefs[]`, `selectedBidRef`, `authorityRef`, `divergenceFromRanking`, `conflictRecordRefs[]`; prohibit `criterionOutcomes` whenever a BidEvaluation exists, and require an explicit `noEvaluationGround` when none does. 14. **D14** — Add invariants and fields: award requires `selectedBid.validUntil >= awardedAt` or a recorded extension; `BidReceipt.qualificationStandingRef` must be valid at `receivedAt`; a bid score never writes back to qualification standing. 15. **D15** — Add `expectedCode` to every fixture; split `winner-is-contract` into separate contract and order cases; add `requiresInvariantCoverage: true` and `requiresExpectedCode: true` to both `validation-policy.json` files; settle on one spelling of the publishability field across all artifacts. ## 4. Additional fixtures `expectedCode` values below are fixture-local assertion labels. They are not registry identifiers, model identifiers or runtime codes. ```json [ {"target":"candidate-allocation-offline-sourcing-event/SourcingEvent","id":"round-states-are-round-scoped","kind":"positive","input":"Round 1 is finalized under criteria v1 while round 2 is open under criteria v2 in the same sourcing event.","expect":"Both round states coexist and the event status is 'evaluating'; no event-level seal or opening state is asserted.","expectedCode":"EMOPS02-ROUND-STATE-SCOPED-OK"}, {"target":"candidate-allocation-offline-sourcing-event/SourcingEvent","id":"event-seal-state-blocks-second-round","kind":"negative","input":"The event is set to status 'sealed' while round 2 must be 'open', using the event lifecycle to represent round state.","expect":"Rejected: seal and opening states belong to SourcingRound, not SourcingEvent.","expectedCode":"EMOPS02-EVENT-STATE-CONFLATION"}, {"target":"candidate-allocation-offline-sourcing-event/SourcingRound","id":"opening-requires-witness-and-instant","kind":"negative","input":"A round transitions to 'opened' with no openedAt and no openingWitnessRef.","expect":"Rejected: a witnessed opening record with an explicit instant is mandatory for the 'opened' state.","expectedCode":"EMOPS02-OPENING-WITNESS-MISSING"}, {"target":"candidate-allocation-offline-sourcing-event/BidReceipt","id":"receipt-seal-opening-instants-distinct","kind":"positive","input":"A bid is received at 2026-10-01T09:14:00+02:00, sealed on receipt, and opened at 2026-10-08T10:00:00+02:00 under a named witness.","expect":"Receipt, seal and opening instants are stored separately and all three remain resolvable.","expectedCode":"EMOPS02-TIME-TRIAD-OK"}, {"target":"candidate-allocation-offline-sourcing-event/BidReceipt","id":"evaluation-read-before-opening","kind":"negative","input":"A BidEvaluation outcome is recorded for a bid whose receipt sealState is still 'sealed'.","expect":"Rejected: sealed content is unreadable for evaluation until a witnessed opening is recorded against that round.","expectedCode":"EMOPS02-SEAL-READ-VIOLATION"}, {"target":"candidate-allocation-offline-sourcing-event/BidReceipt","id":"receipt-without-content-digest","kind":"negative","input":"A sealed bid receipt is recorded with no per-bid contentDigest, relying on the round-level digest instead.","expect":"Rejected: each sealed submission carries its own content digest; a round digest cannot evidence per-bid integrity.","expectedCode":"EMOPS02-BID-DIGEST-MISSING"}, {"target":"candidate-allocation-offline-sourcing-event/BidReceipt","id":"late-submission-disposition-recorded","kind":"positive","input":"A bid arrives after submissionWindow.closesAt and is admitted under a recorded waiver.","expect":"Admissibility is 'late-admitted' with a waiving role, rule waived and reason retained; the original receipt instant is unchanged.","expectedCode":"EMOPS02-LATE-DISPOSITION-OK"}, {"target":"candidate-allocation-offline-sourcing-event/BidReceipt","id":"buyer-reminted-bid-identity","kind":"negative","input":"The buyer assigns its own bid identifier on receipt and stores it as the bid's identity.","expect":"Rejected: bid identity is supplier-issued; the buyer may hold only a receipt binding to bidRef and bidVersion.","expectedCode":"EMOPS02-BID-IDENTITY-REMINT"}, {"target":"candidate-allocation-offline-sourcing-event/SourcingRound","id":"timestamp-without-offset","kind":"negative","input":"submissionWindow.closesAt is recorded as '2026-10-08 17:00' with no seconds and no UTC offset.","expect":"Rejected: every instant is RFC 3339 with seconds and an explicit offset.","expectedCode":"EMOPS02-TIME-FORMAT-INVALID"}, {"target":"candidate-allocation-offline-sourcing-event/SourcingRound","id":"criteria-release-without-effective-from","kind":"negative","input":"A criteria set version is published with a version label but no criteriaEffectiveFrom.","expect":"Rejected: every criteria release carries a version and an effective time that outcomes can pin.","expectedCode":"EMOPS02-CRITERIA-EFFECTIVE-FROM-MISSING"}, {"target":"profile-em-ops-02/BidEvaluation","id":"evaluator-scores-without-roster-entry","kind":"negative","input":"A criterion outcome is recorded by an actor who has no evaluatorRoster entry, mandate reference or impartiality declaration assigned before determination began.","expect":"Rejected: assessors are assigned and impartiality is declared before any determination is recorded.","expectedCode":"EMOPS02-ROSTER-ENTRY-MISSING"}, {"target":"profile-em-ops-02/BidEvaluation","id":"declarant-determines-own-interest","kind":"negative","input":"Evaluator X declares an interest in bid B2 and records the determination of that interest personally.","expect":"Rejected: each declared interest is determined by a party other than the declarant.","expectedCode":"EMOPS02-SELF-DETERMINED-CONFLICT"}, {"target":"profile-em-ops-02/BidEvaluation","id":"conflicted-evaluator-scores-dependent-comparison","kind":"negative","input":"After recusal on bid B2, evaluator X records a pairwise comparison whose result depends on B2.","expect":"Rejected: a recused evaluator scores neither the affected bid nor any comparison depending on it.","expectedCode":"EMOPS02-RECUSAL-SCOPE-VIOLATION"}, {"target":"profile-em-ops-02/BidEvaluation","id":"recusal-history-retained","kind":"positive","input":"X is recused with an effective instant; X's earlier round-2 outcomes are marked 'excluded' and a remediation round restates participation figures.","expect":"Original outcomes, the determination and the recusal instant all remain resolvable; nothing is deleted.","expectedCode":"EMOPS02-RECUSAL-HISTORY-OK"}, {"target":"candidate-allocation-offline-sourcing-event/SourcingRound","id":"remediation-round-pins-same-criteria","kind":"positive","input":"A recusal triggers a round with roundKind 'remediation' that pins criteria v2 and the identical bid versions, with no new submission window.","expect":"Accepted: the remediation round is attributable, binds the same criteria version, and reopens no submissions.","expectedCode":"EMOPS02-REMEDIATION-ROUND-OK"}, {"target":"profile-em-ops-02/BidEvaluation","id":"bias-adjustment-in-place","kind":"negative","input":"A finalized round-2 criterion outcome is overwritten with a bias-adjusted value.","expect":"Rejected: bias adjustment and exclusion create new marked results in a successor round; finalized outcomes are never edited.","expectedCode":"EMOPS02-FINALIZED-OUTCOME-MUTATION"}, {"target":"profile-em-ops-02/BidEvaluation","id":"prior-bid-scored-on-new-criteria","kind":"negative","input":"Round-1 bid versions are scored under criteria v2 in round 2 without any new or re-affirmed submission.","expect":"Rejected: a bid version scored under criteria vN is never scored under vN+1; a new criteria version requires a solicitation round with new or re-affirmed submissions.","expectedCode":"EMOPS02-CROSS-VERSION-RESCORE"}, {"target":"candidate-allocation-offline-sourcing-event/Addendum","id":"addendum-notifies-full-participant-scope","kind":"positive","input":"A material criterion change issues an addendum notified at one instant to every participant in the round's participant scope.","expect":"Accepted: notifiedParticipantRefs equals the round participant scope; criteria v2 and a successor round are created.","expectedCode":"EMOPS02-EQUAL-NOTIFICATION-OK"}, {"target":"candidate-allocation-offline-sourcing-event/Addendum","id":"addendum-notifies-subset","kind":"negative","input":"An addendum changing a criterion is notified only to the two participants the buyer deems affected, out of five in scope.","expect":"Rejected: post-publication changes are notified to all participants in the round's participant scope.","expectedCode":"EMOPS02-NOTIFICATION-SUBSET"}, {"target":"candidate-allocation-offline-sourcing-event/SourcingEvent","id":"procedure-kind-outside-enum","kind":"negative","input":"procedureKind is recorded as the free-text value 'expedited sourcing exercise'.","expect":"Rejected: procedureKind is one of open, restricted, negotiated, single-source.","expectedCode":"EMOPS02-PROCEDURE-KIND-INVALID"}, {"target":"candidate-allocation-offline-sourcing-event/SourcingEvent","id":"single-source-without-ground-or-authority","kind":"negative","input":"procedureKind is 'single-source' with a one-alternative set but no justificationGround and no decidingAuthorityRef.","expect":"Rejected: single-source requires a justification ground, a competent deciding authority and a mandate scope.","expectedCode":"EMOPS02-SINGLE-SOURCE-JUSTIFICATION-MISSING"}, {"target":"candidate-allocation-offline-sourcing-event/SourcingEvent","id":"single-source-valid-without-waiver","kind":"positive","input":"A single-source event records one real alternative, a justification ground, deciding authority and mandate scope, and no waiver.","expect":"Accepted: the waiver is optional; no dummy bid or simulated competitive round is created.","expectedCode":"EMOPS02-SINGLE-SOURCE-OK"}, {"target":"candidate-allocation-offline-sourcing-event/SourcingEvent","id":"awarded-state-without-award-reference","kind":"negative","input":"The event status is set to 'awarded' with no awardDecisionRef.","expect":"Rejected: the 'awarded' state requires a referential award decision link and asserts no agreement or order.","expectedCode":"EMOPS02-AWARDED-STATE-UNANCHORED"}, {"target":"candidate-allocation-offline-procurement-request/ProcurementRequest","id":"scope-change-creates-pinned-revision","kind":"positive","input":"Requested quantity changes after approval; a new revision is created with revisionEffectiveFrom and supersedesRevisionRef.","expect":"Both revisions remain resolvable and the prior approval stays pinned to the scope revision it authorized.","expectedCode":"EMOPS02-REQUEST-REVISION-OK"}, {"target":"candidate-allocation-offline-procurement-request/ProcurementRequest","id":"successor-ref-used-for-revision","kind":"negative","input":"A scope revision is recorded by setting replacementRequestRef to a new request identifier instead of creating a revision.","expect":"Rejected: revision succession and distinct-need replacement are separate fields with separate meanings.","expectedCode":"EMOPS02-SUCCESSION-OVERLOAD"}, {"target":"candidate-allocation-offline-procurement-request/ProcurementRequest","id":"approved-without-authority-record","kind":"negative","input":"A request reaches status 'approved' with no approvals entry and no authorityRef.","expect":"Rejected: approval requires an approver, authority binding, decision instant and the approved scope revision.","expectedCode":"EMOPS02-APPROVAL-RECORD-MISSING"}, {"target":"candidate-allocation-offline-procurement-request/ProcurementRequest","id":"split-fulfilment-references-both-orders","kind":"positive","input":"One approved request is fulfilled by two independently issued purchase orders.","expect":"orderRefs holds both order references under one request identity; the orders are not merged and no contract is implied.","expectedCode":"EMOPS02-SPLIT-FULFILMENT-OK"}, {"target":"candidate-allocation-offline-sourcing-event/SourcingEvent","id":"event-without-authorizing-request","kind":"negative","input":"A sourcing event is published with neither an authorizingRequestRef nor a declared noRequestGround.","expect":"Rejected: an event cites exactly one authorizing request or an explicit enumerated ground for having none.","expectedCode":"EMOPS02-AUTHORIZING-REQUEST-MISSING"}, {"target":"candidate-allocation-offline-sourcing-event/SourcingEvent","id":"rejected-request-authorizes-event","kind":"negative","input":"A request in status 'rejected' is used as the authorizingRequestRef of a published event.","expect":"Rejected: a rejected or withdrawn request cannot authorize a sourcing event.","expectedCode":"EMOPS02-REJECTED-REQUEST-AUTHORIZATION"}, {"target":"candidate-allocation-offline-procurement-request/boundary","id":"internal-approval-vs-award-reference","kind":"negative","input":"The request's internal approval is recorded as the award decision it references under the single purpose 'Approval or award decision'.","expect":"Rejected: internal procurement approval is owned by the request; the award decision is a separate referenced record with its own purpose.","expectedCode":"EMOPS02-APPROVAL-AWARD-CONFLATION"}, {"target":"profile-em-ops-02/AwardDecision","id":"award-without-criteria-and-round-citation","kind":"negative","input":"An award names the selected bid but cites no criteria version, no relied-upon round and not all considered bids.","expect":"Rejected: the award cites the criteria version, the relied-upon evaluation round, every considered bid and the selected bid.","expectedCode":"EMOPS02-AWARD-CITATION-MISSING"}, {"target":"profile-em-ops-02/AwardDecision","id":"award-restates-criterion-outcomes","kind":"negative","input":"An award copies per-criterion scores from the evaluation round into its own evaluation-results area while that BidEvaluation record exists.","expect":"Rejected: where a BidEvaluation exists the award references the round and aggregation relied upon and restates no criterion outcome.","expectedCode":"EMOPS02-SEAM-OUTCOME-RESTATEMENT"}, {"target":"profile-em-ops-02/AwardDecision","id":"single-source-award-without-evaluation","kind":"positive","input":"A single-source award exists with no BidEvaluation record and a declared noEvaluationGround.","expect":"Accepted: the absence of an evaluation is explicit and grounded; no outcomes are fabricated.","expectedCode":"EMOPS02-NO-EVALUATION-GROUND-OK"}, {"target":"profile-em-ops-02/AwardDecision","id":"award-creates-agreement-or-order","kind":"negative","input":"Recording the award automatically instantiates a concluded agreement record.","expect":"Rejected: the award creates, signs and implies no agreement; conclusion, signature evidence and conditions precedent are separately evidenced.","expectedCode":"EMOPS02-AWARD-IMPLIES-AGREEMENT"}, {"target":"profile-em-ops-02/AwardDecision","id":"award-creates-purchase-order","kind":"negative","input":"Recording the award automatically issues and marks accepted a purchase order.","expect":"Rejected: order issuance and acceptance are separate later acts, and issuance alone never proves contract formation.","expectedCode":"EMOPS02-AWARD-IMPLIES-ORDER"}, {"target":"profile-em-ops-02/SupplierQualification","id":"qualification-scored-inside-bid-evaluation","kind":"negative","input":"A supplier's qualification standing is entered as a scored criterion inside the bid evaluation, and the bid score then revises that standing.","expect":"Rejected: qualification and bid evaluation have different subjects and validity; neither writes into the other.","expectedCode":"EMOPS02-QUALIFICATION-SCOPE-VIOLATION"}, {"target":"profile-em-ops-02/SupplierQualification","id":"expired-qualification-gates-admissibility","kind":"negative","input":"Admissibility cites a qualification standing whose validity window ended before the bid receipt instant.","expect":"Rejected: admissibility pins a qualification standing valid as of receivedAt.","expectedCode":"EMOPS02-QUALIFICATION-LAPSED"}, {"target":"profile-em-ops-02/AwardDecision","id":"lapsed-bid-awarded","kind":"negative","input":"The selected bid's validity window ended before awardedAt and no extension is recorded.","expect":"Rejected: award requires the selected bid to be valid at the award instant or a recorded extension.","expectedCode":"EMOPS02-BID-VALIDITY-LAPSED"}, {"target":"candidate-allocation-offline-procurement-request/validation-policy.json","id":"fixture-without-expected-code","kind":"negative","input":"A fixture is submitted with prose 'expect' and no expectedCode under requiresExpectedCode.","expect":"Rejected: every fixture carries a machine-checkable expectedCode.","expectedCode":"EMOPS02-FIXTURE-CODE-MISSING"}, {"target":"candidate-allocation-offline-sourcing-event/validation-policy.json","id":"invariant-without-fixture-coverage","kind":"negative","input":"An invariant set of twelve entries is submitted with fixtures covering nine of them under requiresInvariantCoverage.","expect":"Rejected: every invariant maps to at least one fixture.","expectedCode":"EMOPS02-INVARIANT-COVERAGE-GAP"}, {"target":"candidate-allocation-offline-procurement-request/allocation-candidate.json","id":"publishability-field-name-divergence","kind":"negative","input":"One artifact uses 'canonicalPublishable' while the reconciled hold text names 'publishableCanonical'.","expect":"Rejected: a single spelling of the publishability field is used across all EM-OPS-02 artifacts.","expectedCode":"EMOPS02-FIELD-NAME-DIVERGENCE"}, {"target":"profile-em-ops-02/profile-candidate.json","id":"profile-candidate-without-objects-or-fixtures","kind":"negative","input":"The profile candidate declares bases and prose constraints with no objects, no required fields, no fixtures file and no validation policy.","expect":"Rejected: a profile candidate declares testable objects and required fields and ships fixtures and a validation policy.","expectedCode":"EMOPS02-PROFILE-UNTESTABLE"}, {"target":"profile-em-ops-02/profile-candidate.json","id":"profile-filed-under-excluded-candidate","kind":"negative","input":"The shared profile candidate covering bid, evaluation, qualification and award is stored inside the Procurement Request candidate directory whose boundary excludes those subjects.","expect":"Rejected: the profile candidate lives in its own shared location, not inside a candidate that disclaims its subjects.","expectedCode":"EMOPS02-ARTIFACT-MISFILED"} ] ``` ## 5. Identifier decision No identifier is allocated, inferred, reserved or implied by this audit. Procurement Request and Sourcing Event remain `modelId: null`, `registryId: null`, `allocationState: "unassigned"`, `canonicalPublishable/publishableCanonical: false`; registry allocation is the registry's act, not this audit's. The four profiles create no new identity and no runtime identifier (`newRuntimeId: false` stands). WM-ECO-021, WM-ACT-034, WM-KNW-010, WM-ECO-006, WM-ECO-019, WM-ORG-001 and WM-XCT-016 are referenced only as named in the submitted inputs; no crosswalk, publication status or relation ratification is asserted. All field names and `expectedCode` strings proposed above are artifact-local and fixture-local labels; none is a registry, model or runtime identifier, and none may be promoted to one without registry action. ## 6. Freeze decision This audit is **closed**. It was the single independent frozen semantic audit for EM-OPS-02 and must not be rerun, re-requested, re-scoped or supplemented by another frozen audit pass. The verdict is REVISE; the fifteen defects and their bounded fixes in §3, together with the fixtures in §4, constitute the complete and final output of the frozen review. Applying the fixes is ordinary revision work verified against the fixtures, not a new audit, and no result above may be reopened by re-executing this review.