# Frozen Semantic Audit — EM-TEC-10 (single pass, closed) ## 1. Verdict **REVISE.** The identity split is sound and I do not disturb the fixed decision. The artifacts, however, assert a large body of invariants that their own object definitions cannot carry: the emergency path is unsatisfiable as specified, rollback is re-collapsed inside `ChangeExecution.lifecycle`, Freeze Period survives as a label with no enforcement (and silently becomes an executable window in the reconciled scenario), `DutyRoster` owns shifts, substitutions and handovers while defining no object for any of them, and `profile-candidate.json` specifies no fields at all. These are artifact defects, not registry holds. ## 2. Material defects **D1 — The emergency fixture is unsatisfiable against the required field set.** `fixtures.json` (ChangeExecution): `{"id":"emergency-change","kind":"positive","input":"An emergency execution relaxes one control under named authority.","expect":"The relaxation, reason and retrospective obligation are explicit."}`. But `allocation-candidate.json` has `"required":["approvedRequestRevisionRef","authorityRef","targetScope","startedAt","status"]` and the invariant *"Every execution pins exactly one approved request revision and its conditions."* claude-study states the opposite ordering: *"retrospective authorisation is a new decision bound to the same request, not an edit."* An emergency execution runs before that decision exists, so no approved revision can be pinned at start. No `emergency`, `relaxedControls`, `relaxationReason`, `relaxationAuthorityRef`, `retrospectiveDueAt` or `retrospectiveDecisionRef` field exists, and no lifecycle state marks an undischarged retrospective obligation — `closed` is reachable with it open. The invariant *"Emergency execution records relaxed controls, authority, reason and retrospective obligations."* has no carrier. **D2 — "and its conditions" is unenforceable.** local-evidence: *"Authorization freezes an approved proposal revision plus conditions and effectivity."* The object carries `approvedRequestRevisionRef` and `authorityRef` only. There is no `conditionsRef`, no `effectivityFrom/To`, and therefore no way to test an execution against the conditions it was authorized under. **D3 — No version component or digest on any pin.** grok invariant 14: *"A later plan version does not rewrite the version cited by a past execution."* local-evidence invariant 12: *"Approved revisions, plans, windows, rosters and rules are immutable and superseded explicitly."* Yet `approvedRequestRevisionRef`, `windowRef`, `rollbackPlanRef`, `authorityRef` are scalar references with no revision or digest component, and `ChangeExecution` has no `contentDigest` (unlike `RosterRevision`). `RosterRevision.contentDigest` itself declares no algorithm or canonicalization, so it is unverifiable. **D4 — The lifecycle re-collapses rollback into the reverted execution.** `"lifecycle":["scheduled","started","partially-completed","completed","failed","rollback-started","rolled-back","aborted","closed"]` puts rollback states on the occurrence being reverted, contradicting *"Rollback intent, plan, execution and verified restored state remain distinct."*, *"Retries and continuations receive distinct linked execution identities."* and claude-study's *"a ChangeExecution occurrence with kind=rollback and a typed link to the reverted occurrence"*. There is no `kind` discriminator in `objects.ChangeExecution` at all, and `rollbackExecutionRef` is undirected — E1→E2 and E2→E1 are indistinguishable. **D5 — `rolled-back` and `closed` are reachable without verification, and the verification master is undeclared.** `verificationRefs` is in `optional`, against the invariant *"Rolled back never means restored without verification evidence."* claude-study anchors verified state in WM-SFT-015 (*"referenced from WM-SFT-015, never restated"*), but WM-SFT-015 appears nowhere in local-evidence, `references`, or `bases`. `verificationRefs` has no declared target type. (The base's publication state is a hold; its absence from the reconciled reference set is the defect.) **D6 — `startedAt` is required while `scheduled` is a lifecycle state.** A scheduled occurrence has no start instant, so every scheduled record violates the required set. Symmetrically, `endedAt` is optional with no obligation in `completed`, `failed`, `aborted`, `rolled-back` or `closed`. **D7 — Per-target recording is optional while `partially-completed` exists.** `perTargetOutcomes` is in `optional`; the invariant says *"Partial rollout records per-target actions and outcomes."* and claude-study adds *"no aggregate success is inferred"*. Nothing requires outcomes to cover the required `targetScope`, so a partial execution may claim an aggregate result over an uncovered scope. **D8 — Freeze Period is unenforceable, and the reconciled scenario converts a freeze into an available window.** grok: *"citing EU window W-EU (open) and US freeze W-US"*, *"Freeze is a prohibition interval, not a denied decision."* local-evidence instead reads *"binds EU and US windows with distinct zones"* and *"the unused US window remains bound"*; the fixture `multiple-windows` repeats *"binds EU and US windows"*. claude-study's derogation machinery (*"derogable only by recorded, bounded derogation"*, *"registered derogation with granting authority, bounded validity, compensating obligation"*) was dropped entirely: local-evidence's twelve invariants and the twelve `ChangeExecution` invariants contain no freeze or derogation clause, and `profile-candidate.json` names Freeze Period only as one of *"immutable schedule or plan releases."* A later executor reading the reconciled artifact sees a bound, unexecuted US **window** where grok recorded a **prohibition**. **D9 — Two bound windows cannot be represented; the window check is optional.** Fixture expectation: *"The execution records the EU window while the unused US window remains unchanged."* claude-study: *"a change binding two windows holds two pinned window references, each with its own tz identifier."* `windowRef` is singular and optional on `ChangeExecution`, and `profile-candidate.json` defines no field on the WM-ACT-032 profile to hold the bound set. An execution may also run with neither `windowRef` nor a recorded exemption. **D10 — The profile candidate specifies nothing.** `profile-candidate.json` contains `bases` plus six prose `constraints` — no objects, no fields, no identity statements, no lifecycle, no fixtures, and no `validation-policy.json`. Against this, local-evidence asserts *"Change Window has identity, recurrence, exclusions, overrides, disclosure class, timezone identifier, tzdb release and version."* Every profiled thing (Operational Change, Change Window, Freeze Period, Rollback Plan, Escalation Rule and its condition) is unspecified and untested, while both new roots have full specs and policies. **D11 — The decision triad is missing from the profile bases and from the execution's references; `authorityRef` is untyped.** local-evidence: *"Decision rationale, approval act and issued instrument stay in WM-KNW-010, WM-ACT-024 and WM-REC-010."* `bases` lists WM-ACT-032, WM-ACT-008, WM-KNW-012, WM-KNW-013, WM-SFT-008, WM-SFT-009, WM-ORG-016, WM-ACT-006 — none of the triad. `ChangeExecution.references` includes only WM-REC-010 of the three. With no target typing on any reference field, invariant *"A window permits disturbance within an envelope but never authorizes execution."* cannot be enforced: `authorityRef` may legally point at a WM-ACT-008 window instance. **D12 — WM-SFT-009 is asserted as a specialization of an unallocated root.** `references`: `{"target":"WM-SFT-009","purpose":"Software deployment specialization"}`; local-evidence: *"WM-SFT-009 is the software-deployment specialization"*; claude-study: *"WM-SFT-009 becomes a software specialisation of it"*. This contradicts the same file's `excludes` (*"release, build or deployment identity"*), grok (*"Deployment (WM-SFT-009) may be caused by execution; it is not the change"*) and grok's blocker (*"Profiling is valid only as association, not as subtype collapse."*). A published registry model is being re-parented under a root with `modelId: null`. **D13 — Duty Roster owns shifts, substitutions, overrides and handovers but defines no object for any of them.** `owns` includes *"shift occurrences"*, *"substitution and override records"*, *"handover, acknowledgment and retirement history"*. `objects` contains only `DutyRoster{serviceScope, ownerRef, status}` and `RosterRevision{shifts, timezoneId, tzdbRelease, validFrom, contentDigest, …}`, with `shifts` structurally undefined. Eight invariants have no carrier, including *"Every shift references an eligible standing assignment."*, *"Handover records outgoing and incoming parties, instant, open work and incoming acknowledgment."*, *"Substitution and override append attributable records with authorizer and effective instant."* and *"Missing acknowledgment remains an explicit gap and never becomes acceptance."* Fixture `authorized-substitution` expects *"changes the effective shift without rewriting the roster"* while `shifts` sits inside the digested immutable revision — the overlay it requires does not exist. **D14 — As-of resolution is non-deterministic.** `validFrom` is required, `validTo` optional, and no invariant forbids overlapping effective revisions, so two revisions may cover one instant. claude-study's *"DST gaps and overlaps require a declared resolution policy per window"* was dropped and no `dstPolicy` field exists. Fixture `cross-zone-shifts` therefore cannot meet its own expectation, *"Each occurrence resolves deterministically with offset and revision."*, and the invariant *"Escalation resolves its target through the roster as of event time."* has no unique answer. **D15 — No assertion time, no bitemporal separation, no declared instant format.** claude-study: *"event, observation and ingestion times are separate fields"*; local-evidence reduces this to *"Every instant carries offset"*. Neither object has `assertedAt`/`recordedAt`, so `supersedesRef` chains (*"Corrections append successor assertions for the same occurrence"*) have no ordering key and two competing successors cannot be ranked. The RFC 3339 / explicit-offset requirement exists only in claude-study prose; no field in either JSON declares it. **D16 — Roster root lifecycle contradicts revision-level immutability.** `DutyRoster.lifecycle` includes `amended` and `superseded` with `optional:["successorRef","retiredAt"]`, while the invariant is *"Roster revisions are immutable and superseded explicitly."* and the identity test says the roster *"remains identifiable across shift occurrences, substitutions and handovers while its schedule revisions evolve"*. Root-level supersession with a `successorRef` migrates identity and defeats the stability claim. `retiredAt` is not required in `retired`, and nothing carries open-work carryover despite *"Roster retirement never closes employment, assignment, incidents or in-flight changes."* **D17 — Handover is non-blocking in the reconciled text, and the execution side records no shift.** grok: *"Handover requires acknowledgment before the receiving shift may act under that change. Unacknowledged shift end is not a handover."* local-evidence weakens this to *"Missing acknowledgment is a gap."* `ChangeExecution` has `operatorRefs` in `optional`, no `actingShiftRef`, and no `handoverRefs`, so in the acceptance scenario (*"During E2, duty passes from A to B with explicit acknowledgment."*) the acting party across the handover instant is unrecoverable from the execution record. **D18 — The privileged-access invariant has no carrier.** *"Privileged on-call access requires a separate time-bounded authorized audited grant."* / *"Any privileged access for on-call work is a separate time-bounded authorized and audited grant with expiry."* Both roots `exclude` IAM grant identity, `operatorRefs` is optional and carries no grant reference, and no field records expiry or audit. The invariant is stated where it cannot be evaluated. (The absent access-grant base is a hold; the unanchored invariant and the missing `operatorRefs` grant slot are the defects.) **D19 — Roster→escalation reference direction is inverted, the WM-ACT-008 roster profile is undeclared, and the escalation target may be a frozen shift.** `DutyRoster.references` includes WM-KNW-012 *"Escalation rule"* and WM-KNW-013 *"Escalation condition"* while `excludes` lists *"incident, escalation or change-execution identity"* — the resolver is made to depend on the rule that resolves through it. The same list has WM-ACT-008 *"Schedule profile"*, a fourth WM-ACT-008 profile that `profile-candidate.json` never defines (it names only *"Change Window, Freeze Period and Rollback Plan"*). grok also permits *"a roster role or shift as the notify target"* and *"Escalation names S-US"*; naming a shift occurrence pins the target at authoring time and bypasses as-of-event-time resolution. **D20 — Latent authorization: no effectivity end and no closure precondition.** *"One authorization may govern multiple executions without rewriting the approved revision."* plus *"the unused US window remains bound"* and no effectivity end, no bar on executing after request disposition or closure, and no closure precondition asserting that no latent or in-flight execution remains. local-evidence assigns WM-ACT-032 *"closure references"* while grok holds *"Partial failure does not auto-close the request or the decision."* — the reconciled artifact specifies neither direction, leaving an indefinitely executable approval. **D21 — Every negative fixture asserts a rejection no artifact mechanism can produce.** `window-is-authorization`, `rollback-is-restored`, `release-is-deployment`, `roster-grants-admin`, `silence-is-ack`, `assignment-is-shift` all expect a bare *"The inference is rejected."* with no rejection code, no rule reference and no typed field to reject against; `validation-policy.json` requires only `"requiresPositiveAndNegativeFixtures":true`. The negative suite is currently decorative. ## 3. Required bounded fixes 1. **Emergency path (D1, D20).** Make `approvedRequestRevisionRef` conditionally required: required unless `authorizationKind = emergency`. Add required-on-emergency `relaxedControls`, `relaxationReason`, `relaxationAuthorityRef`, `retrospectiveDueAt`, and `retrospectiveDecisionRef`; add lifecycle state `pending-retrospective-authorization` and bar `closed` while it is open. 2. **Authorization pin (D2, D3, D11, D20).** Add required `conditionsRef`, `effectivityFrom`, `effectivityTo`. Give every reference an explicit `{model, id, revision, digest}` shape and a declared target-model whitelist; add WM-ACT-024, WM-KNW-010, WM-REC-010 (and the verification base once published) to `bases` and to `ChangeExecution.references`; constrain `authorityRef` to the decision triad only. Add invariants: execution start within effectivity; no execution after recorded closure; closure asserts no latent or in-flight execution. 3. **Rollback (D4, D5).** Remove `rollback-started` and `rolled-back` from the lifecycle. Add required `kind ∈ {normal, standard, emergency, rollback, retry, continuation}` and directed `revertsExecutionRef` (required when `kind = rollback`). Add `restoredStateAsserted` gated on non-empty `verificationRefs`, and declare the verification target model (hold until published). 4. **Lifecycle/field coherence (D6, D7).** `startedAt` required for all states except `scheduled`; `endedAt` required in every terminal state; `perTargetOutcomes` required in `partially-completed`, `completed` and `failed`, with a coverage rule against `targetScope`. 5. **Freeze and windows (D8, D9).** Add `boundWindowRefs[]` (set, each with zone + tzdb pin) on the WM-ACT-032 profile and `executedWindowRef` on `ChangeExecution`. Add required `intervalRole ∈ {window, freeze, rollback-plan}` to the WM-ACT-008 profile. Add invariants: execution start inside a `freeze` interval requires a recorded derogation (`grantingAuthorityRef`, bounded validity, compensating obligation); a freeze interval is never a bindable executable window. Correct the reconciled scenario to carry grok's US freeze, or state explicitly that W-US is a window and that grok's freeze case is separately covered. 6. **Profile specification (D10, D21).** Replace the prose-only `profile-candidate.json` with object and field definitions for Operational Change, Change Window, Freeze Period, Rollback Plan, Escalation Rule and condition — including the attributes local-evidence already claims (recurrence, exclusions, overrides, `disclosureClass`, `timezoneId`, `tzdbRelease`, `version`, `dstPolicy`) — plus a `fixtures.json` and a `validation-policy.json` for the profile, and an `expectedCode` on every negative case across all three suites. 7. **Deployment relation (D12).** Replace *"Software deployment specialization"* with association: `causedDeploymentRefs` on `ChangeExecution`, purpose *"Software deployment caused by this execution"*. State explicitly that no existing registry model is re-parented under an unallocated root. 8. **Duty Roster objects (D13, D16, D17).** Define `RosterShift{rosterShiftId; rosterRevisionRef, standingAssignmentRef, serviceScope, startAt, endAt, timezoneId}`, `ShiftOverride{overrideId; supersededShiftRef, substituteRef, substitutedForRef, authorizerRef, effectiveAt, kind}` as an overlay outside the revision digest, and `DutyHandover{handoverId; outgoingShiftRef, incomingShiftRef, atInstant, openIncidentRefs, inFlightExecutionRefs, acknowledgment{by, atInstant} | gapRecorded}`. Remove `amended`/`superseded`/`successorRef` from the root lifecycle (supersession is revision-level); require `retiredAt` in `retired` and require that retirement enumerate uncovered open work. Add `actingShiftRef[]` with intervals and `handoverRefs` on `ChangeExecution`, and the rule that an incoming party may not act under an in-flight execution before acknowledgment. 9. **Time and provenance (D14, D15).** Declare the instant type once (RFC 3339, seconds, explicit offset). Add `assertedAt` (and `observedAt` where distinct) to both roots as the ordering key for `supersedesRef`. Require non-overlapping `[validFrom, validTo)` per roster, add required `dstPolicy` per window and per roster revision, and specify the `contentDigest` algorithm and canonicalization. 10. **Escalation and access (D18, D19).** Remove WM-KNW-012/013 from `DutyRoster.references` (keep the dependency one-way: rule → roster); add the WM-ACT-008 roster-schedule profile to the profile candidate or drop the reference. Constrain the escalation target to a role/service plus a roster reference, never a shift occurrence. Add optional `accessGrantRefs` with expiry on `operatorRefs` entries, restate the privileged-access invariant as a prohibition the artifacts can enforce (no permission attribute on roster, shift, override or handover), and record a gap when a privileged action has no grant reference. ## 4. Additional fixtures ```json [ {"target":"ChangeExecution","id":"d01-emergency-execution-without-prior-approval","kind":"positive","input":"Execution E9 starts with authorizationKind=emergency, no approvedRequestRevisionRef, and relaxedControls, relaxationReason, relaxationAuthorityRef and retrospectiveDueAt populated; status=pending-retrospective-authorization.","expect":"Accepted; the revision pin is waived only under the emergency kind and the relaxation record is mandatory."}, {"target":"ChangeExecution","id":"d01b-emergency-closed-with-open-retrospective","kind":"negative","input":"E9 is moved to closed while retrospectiveDecisionRef is absent and retrospectiveDueAt has passed.","expect":"Closure is rejected and the undischarged retrospective obligation is reported.","expectedCode":"E-CE-RETROSPECTIVE-OPEN"}, {"target":"ChangeExecution","id":"d02-execution-without-pinned-conditions","kind":"negative","input":"E1 pins approvedRequestRevisionRef=R1 but carries no conditionsRef and no effectivity bounds.","expect":"Rejected; the invariant requiring the revision and its conditions cannot be satisfied.","expectedCode":"E-CE-CONDITIONS-UNPINNED"}, {"target":"ChangeExecution","id":"d02b-start-outside-authorization-effectivity","kind":"negative","input":"E4 starts after effectivityTo of the authorization that governs R1.","expect":"Rejected; execution must start within the pinned effectivity.","expectedCode":"E-CE-EFFECTIVITY-EXPIRED"}, {"target":"ChangeExecution","id":"d03-plan-superseded-after-execution","kind":"positive","input":"Rollback plan P1 is superseded by P2 after E2 has closed; E2 is re-read.","expect":"E2 still reports P1 with its revision and digest unchanged; no retroactive rewrite occurs."}, {"target":"ChangeExecution","id":"d03b-reference-without-revision-component","kind":"negative","input":"windowRef and rollbackPlanRef are supplied as bare identifiers with no revision or digest.","expect":"Rejected; every pin requires model, id, revision and digest.","expectedCode":"E-CE-REF-UNVERSIONED"}, {"target":"ChangeExecution","id":"d04-rollback-as-separate-occurrence","kind":"positive","input":"E2 is created with kind=rollback, revertsExecutionRef=E1 and rollbackPlanRef=P1 pinned; E1 remains partially-completed.","expect":"Accepted; E1 and E2 hold distinct identities and the revert link is directed E2 to E1."}, {"target":"ChangeExecution","id":"d04b-rollback-state-on-reverted-execution","kind":"negative","input":"E1 is transitioned to rollback-started and then rolled-back instead of creating E2.","expect":"Rejected; rollback states may not exist on the reverted occurrence.","expectedCode":"E-CE-ROLLBACK-STATE-COLLAPSE"}, {"target":"ChangeExecution","id":"d04c-untyped-rollback-link","kind":"negative","input":"rollbackExecutionRef is set on both E1 and E2 with no kind discriminator.","expect":"Rejected; the revert direction and execution kind must be explicit.","expectedCode":"E-CE-KIND-MISSING"}, {"target":"ChangeExecution","id":"d05-restored-claimed-without-verification","kind":"negative","input":"E2 asserts restored state and closes with verificationRefs empty.","expect":"Rejected; rolled back never implies restored without verification evidence.","expectedCode":"E-CE-RESTORED-UNVERIFIED"}, {"target":"ChangeExecution","id":"d05b-verification-target-undeclared","kind":"negative","input":"verificationRefs points at a model that is not in the declared reference whitelist.","expect":"Rejected; the verification master must be a declared reference target.","expectedCode":"E-CE-REF-TARGET-UNDECLARED"}, {"target":"ChangeExecution","id":"d06-scheduled-without-start-instant","kind":"positive","input":"E5 exists with status=scheduled, windowRef pinned and no startedAt.","expect":"Accepted; startedAt is required only from started onward."}, {"target":"ChangeExecution","id":"d06b-terminal-without-end-instant","kind":"negative","input":"E5 is set to completed with endedAt absent.","expect":"Rejected; every terminal state requires endedAt.","expectedCode":"E-CE-TERMINAL-NO-END"}, {"target":"ChangeExecution","id":"d07-partial-without-per-target-coverage","kind":"negative","input":"E1 is partially-completed with perTargetOutcomes absent, then with outcomes covering two of five targets in targetScope.","expect":"Both forms are rejected; partial outcomes must cover the declared scope and no aggregate result is inferred.","expectedCode":"E-CE-PARTIAL-NO-OUTCOMES"}, {"target":"ChangeExecution","id":"d08-start-inside-freeze-without-derogation","kind":"negative","input":"E6 starts inside freeze interval F-US with no derogation recorded.","expect":"Rejected; a freeze prohibition blocks execution start absent a bounded derogation.","expectedCode":"E-CE-FREEZE-VIOLATION"}, {"target":"ChangeExecution","id":"d08b-freeze-derogation-recorded","kind":"positive","input":"E6 starts inside F-US under a registered derogation with grantingAuthorityRef, bounded validity and a compensating obligation.","expect":"Accepted; the derogation, its authority, bounds and obligation are recorded on the execution."}, {"target":"EM-TEC-10-profile","id":"d08c-freeze-bound-as-executable-window","kind":"negative","input":"W-US is mastered with intervalRole=freeze but is bound to the authorization as an executable window and described as remaining available.","expect":"Rejected; a freeze interval is never a bindable executable window.","expectedCode":"E-PROF-FREEZE-AS-WINDOW"}, {"target":"EM-TEC-10-profile","id":"d09-two-bound-windows-one-executed","kind":"positive","input":"The approved revision carries boundWindowRefs=[W-EU, W-US], each pinned with timezoneId and tzdbRelease; execution records executedWindowRef=W-EU.","expect":"Accepted; the bound set and the single executed window are separately representable and W-US is untouched."}, {"target":"ChangeExecution","id":"d09b-execution-without-window-binding","kind":"negative","input":"E7 reaches started with no executedWindowRef and no recorded exemption.","expect":"Rejected; execution start must cite a window or a recorded exemption.","expectedCode":"E-CE-WINDOW-UNBOUND"}, {"target":"EM-TEC-10-profile","id":"d10-profile-declares-field-set","kind":"positive","input":"The Change Window profile declares identity, recurrence, exclusions, overrides, disclosureClass, timezoneId, tzdbRelease, version, dstPolicy and intervalRole as named fields.","expect":"Accepted; the attributes claimed in the synthesis are backed by declared fields."}, {"target":"EM-TEC-10-profile","id":"d10b-profile-asserts-unspecified-attributes","kind":"negative","input":"The profile candidate carries only prose constraints while the synthesis claims window recurrence, overrides, disclosure class, timezone and version attributes.","expect":"Rejected; profiled objects require declared fields, fixtures and a validation policy.","expectedCode":"E-PROF-UNSPECIFIED-FIELDS"}, {"target":"ChangeExecution","id":"d11-authority-must-be-decision-triad","kind":"negative","input":"authorityRef points at a WM-ACT-008 window instance.","expect":"Rejected; authority resolves only to the decision triad and a window is never authorization.","expectedCode":"E-CE-AUTHORITY-NOT-DECISION"}, {"target":"EM-TEC-10-profile","id":"d11b-decision-triad-present-in-bases","kind":"positive","input":"bases include WM-ACT-024, WM-KNW-010 and WM-REC-010 and the execution references list all three.","expect":"Accepted; the authorization chain is reachable from the execution."}, {"target":"EM-TEC-10-profile","id":"d12-deployment-declared-as-subtype","kind":"negative","input":"WM-SFT-009 is declared a specialization or subtype of the unallocated Change Execution root.","expect":"Rejected; the relation is association only and no published model is re-parented under an unallocated root.","expectedCode":"E-PROF-SUBTYPE-COLLAPSE"}, {"target":"ChangeExecution","id":"d12b-deployment-as-caused-association","kind":"positive","input":"E1 records causedDeploymentRefs=[D1] where D1 is a WM-SFT-009 deployment.","expect":"Accepted; deployment, release and execution identities remain separate and the link is causal association."}, {"target":"DutyRoster","id":"d13-shift-override-handover-objects-defined","kind":"positive","input":"RosterShift, ShiftOverride and DutyHandover objects are defined with their own identities and required fields, each shift citing a standingAssignmentRef.","expect":"Accepted; the owned facts have carriers and the eligibility, substitution and handover invariants become testable."}, {"target":"DutyRoster","id":"d13b-handover-without-acknowledgment","kind":"negative","input":"A DutyHandover from A to B is recorded with atInstant and open work but no acknowledgment and no gapRecorded.","expect":"Rejected; silence is neither acceptance nor an implicit gap and must be recorded explicitly.","expectedCode":"E-DR-ACK-MISSING"}, {"target":"DutyRoster","id":"d13c-substitution-outside-revision-digest","kind":"positive","input":"C substitutes for B via a ShiftOverride with authorizerRef and effectiveAt while the roster revision digest is unchanged.","expect":"Accepted; the effective shift changes through an overlay and the immutable revision is not rewritten."}, {"target":"DutyRoster","id":"d14-overlapping-effective-revisions","kind":"negative","input":"Revisions 3 and 4 of one roster both cover the instant used to resolve an escalation target.","expect":"Rejected; effective revision intervals must not overlap for as-of resolution.","expectedCode":"E-DR-REVISION-OVERLAP"}, {"target":"DutyRoster","id":"d14b-dst-overlap-without-policy","kind":"negative","input":"A shift boundary falls in a repeated local hour and the revision declares no dstPolicy.","expect":"Rejected; DST gaps and overlaps require a declared per-schedule resolution policy.","expectedCode":"E-DR-DST-POLICY-MISSING"}, {"target":"ChangeExecution","id":"d15-successor-assertions-unordered","kind":"negative","input":"Two correction records cite supersedesRef=E1 with no assertedAt on either.","expect":"Rejected; successor assertions require an assertion instant as ordering key.","expectedCode":"E-CE-ASSERTION-UNORDERED"}, {"target":"ChangeExecution","id":"d15b-instant-without-offset","kind":"negative","input":"startedAt is supplied as a local date-time with no explicit offset.","expect":"Rejected; every instant is RFC 3339 with seconds and an explicit offset.","expectedCode":"E-CE-INSTANT-NO-OFFSET"}, {"target":"DutyRoster","id":"d16-root-level-supersession","kind":"negative","input":"The roster root is set to superseded with successorRef to a second roster identity while its revisions are unchanged.","expect":"Rejected; supersession is revision-level and the root identity remains stable.","expectedCode":"E-DR-ROOT-SUPERSESSION"}, {"target":"DutyRoster","id":"d16b-retired-with-uncovered-open-work","kind":"negative","input":"The roster is set to retired with no retiredAt and with in-flight executions and open incidents unenumerated.","expect":"Rejected; retirement requires its instant and an explicit statement of uncovered open work.","expectedCode":"E-DR-RETIREMENT-STRANDS-WORK"}, {"target":"DutyRoster","id":"d17-incoming-acts-before-acknowledgment","kind":"negative","input":"B records an action under in-flight execution E2 before the handover acknowledgment instant.","expect":"Rejected; the incoming party may not act under an in-flight change before acknowledgment.","expectedCode":"E-DR-ACT-BEFORE-ACK"}, {"target":"ChangeExecution","id":"d17b-acting-shift-intervals-across-handover","kind":"positive","input":"E2 records actingShiftRef intervals for S-EU and S-US and handoverRefs for the A-to-B handover.","expect":"Accepted; the acting party at every instant of E2 is recoverable from the execution record."}, {"target":"ChangeExecution","id":"d18-privileged-action-without-grant","kind":"negative","input":"An operator performs a privileged step with operatorRefs empty, or present with no accessGrantRef and no expiry.","expect":"Rejected or recorded as an explicit gap; roster membership confers no permission and the grant is a separate audited object.","expectedCode":"E-CE-GRANT-MISSING"}, {"target":"DutyRoster","id":"d19-roster-references-escalation-rule","kind":"negative","input":"DutyRoster.references retains WM-KNW-012 and WM-KNW-013 while excluding escalation identity.","expect":"Rejected; the dependency is one-way from rule to roster.","expectedCode":"E-DR-DIRECTION-INVERTED"}, {"target":"EM-TEC-10-profile","id":"d19b-escalation-names-shift-occurrence","kind":"negative","input":"An escalation rule pins S-US, a shift occurrence, as its notify target.","expect":"Rejected; the target is a role or service resolved through the roster as of event time.","expectedCode":"E-PROF-TARGET-PINNED-SHIFT"}, {"target":"EM-TEC-10-profile","id":"d19c-undeclared-wm-act-008-roster-profile","kind":"negative","input":"DutyRoster references WM-ACT-008 as a schedule profile that the profile candidate does not define.","expect":"Rejected; every WM-ACT-008 profile in use must be declared with an intervalRole and field set.","expectedCode":"E-PROF-UNDECLARED-PROFILE"}, {"target":"ChangeExecution","id":"d20-execution-after-request-closure","kind":"negative","input":"E8 starts against R1 after the operational change request has been recorded as closed.","expect":"Rejected; closure asserts no latent or in-flight execution remains.","expectedCode":"E-CE-POST-CLOSURE-EXECUTION"}, {"target":"EM-TEC-10-profile","id":"d20b-partial-failure-does-not-close-request","kind":"positive","input":"E1 reaches partially-completed and E2 fails; the request and the decision are re-read.","expect":"Accepted; neither record is auto-closed or rewritten by execution outcome."}, {"target":"EM-TEC-10-profile","id":"d21-negative-fixture-without-code","kind":"negative","input":"A negative fixture states only that the inference is rejected, with no expectedCode and no rule or typed field to reject against.","expect":"Rejected; every negative case carries an expectedCode bound to an enforceable rule.","expectedCode":"E-PROF-FIXTURE-NO-CODE"} ] ``` ## 5. Identifier decision No identifier is allocated, reserved, inferred or implied by this audit. - **Change Execution** and **Duty Roster** remain `modelId: null`, `registryId: null`, `allocationState: "unassigned"`, `canonicalPublishable: false`. Registry allocation stays a hold. - No catalogue identifier, no runtime identifier (`newRuntimeId: false` stands), no WM-* range reuse or neighbour-derived guess for either root. - Existing WM-* identifiers are cited only as profile bases or association targets: WM-ACT-032 (request-side Operational Change), WM-ACT-008 (Change Window, Freeze Period, Rollback Plan — and, once declared, the roster schedule), WM-KNW-012/013 (Escalation Rule and condition), WM-SFT-008, WM-SFT-009, WM-ORG-016, WM-ACT-006, plus WM-ACT-024, WM-KNW-010 and WM-REC-010 to be added to `bases`. WM-SFT-009 is an association target, not a subtype (D12). - WM-SFT-010 and the verification master referenced only in claude-study (WM-SFT-015) are not adopted here; declaring the verification target is a required fix, its publication a hold. - Proposed names and scenario labels — `Change Execution`, `Duty Roster`, `R1`, `E1`, `E2`, `P1`, `P0`, `V1`, `W-EU`, `W-US`, `S-EU`, `S-US` — are labels, never identifiers. The "names, dates and window labels are never identifiers" invariant present in claude-study was dropped in reconciliation and should be restored. ## 6. Freeze decision **Closed. No rerun.** This single frozen audit is complete and will not be repeated; its findings are final as of 2026-10-01 against the artifacts quoted above. The fixed identity decision was not revisited, declared registry and base publication gaps were treated as holds, and no identifier, standards claim or publication-readiness claim was made. Remediation proceeds through the bounded fixes and the fixture set in §4 under ordinary reconciliation, not through a second audit pass.