5.7 KiB
P7-08 — Operation and notification UTC transport
Local SQLite/direct-controller scope: CONDITIONAL GO; hygiene PASS. Hosted HTTP/native acceptance, separate commit and normal push follow. This bounded compatibility repair precedes the two P7-08 presentation boundaries. Portable UTC results retain exact commands, reports, source observations and qualifications.
Demonstrated defect and minimal correction
Fresh SQLite materialization drops DateTime.Kind from stored UTC fields. The ordinary regression observes Web JSON createdAtUtc as 2026-10-16T08:09:10.1234567, missing the required Z. A browser can therefore interpret the recorded UTC instant as local wall time.
The sole product change is in JobTrackerApi/Controllers/OperationsController.cs: seven DTO projections use DateTime.SpecifyKind(value, DateTimeKind.Utc), preserving nullable values. The fields are five operation dates (createdAtUtc, startedAtUtc, completedAtUtc, deadlineAtUtc, cancellationRequestedAtUtc) and two notification dates (createdAtUtc, readAtUtc).
This labels the existing stored UTC ticks; it does not call ToUniversalTime, adjust instants or write rows. Routes, the exact 14-operation/8-notification public fields, ownership, authorization, queue/retry/cancel behavior and schema remain unchanged. No client-side timezone suffix is invented, and no new producer, handler, provider or model capability is enabled.
Executed regression evidence
All times are UTC on 2026-10-16. Raw command.json, career.trx and career.log files remain under .artifacts/phase7/current/backend-career/.
| Observation | Actual result |
|---|---|
| Ordinary UTC RED | 3 pass / 1 fail of 4, 16:34:10.428105–16:34:31.629894, p708-utc-red-20261016T163410Z. The new case fails on missing Z after fresh SQLite reload; four captured inputs match before/after |
| UTC GREEN | 4/4 PASS, 16:35:47.955889–16:35:57.322108, p708-utc-green-20261016T163547Z, fresh Release compilation with --no-restore; zero failed/not-executed cases |
| Related consumers | 73/73 PASS, 16:36:14.129488–16:36:18.762446, p708-utc-consumers-20261016T163614Z, --no-build against the compiled repair; zero failed/not-executed cases |
The new ordinary Fact uses distinct deterministic seven-digit fractional ticks for all seven dates, disposes the seeding context, then proves SQLite's materialized values have Unspecified kind. It invokes the actual controllers directly and serializes their DTOs with JsonSerializerDefaults.Web: Get/List agree, public field sets remain exact, every date has Z/zero offset/original ticks, and fresh persisted rows remain identical after reads.
The original three controller cases remain. Added persisted readback assertions strengthen cancel/retry and notification cases: the same operation ID/conflict rules and lifecycle resets persist; repeated notification read/dismiss retain timestamps and leave the associated operation unchanged. The 73 consumer cases cover operation stores, queue, StrategySnapshot, CV processing, ProfileCv, authorization posture and session middleware. These are affected subsets, not additional full-suite cases or deployed-service qualification.
Source, binary and execution qualifications
utc-green-post.json, observed 16:39:08.852884, confirms five backend source inputs held across the four contract and 73 consumer cases. Controller source SHA256 is a2a38aee1d23c36f3cec617f1537f73d35639542087d4c1e5e7fb65f227440e2; test source SHA256 is 06d6f91b70af4e1e98fe67246a76a9084d22a4050667295349a14c4d520c8e75.
The API DLL SHA256 e1d2c1bfc7ba4d9816d5d7b80503e79d2a647ad0ae2f4777e2703508fd32681c and test DLL SHA256 425d098903732802b5b304072c6f2e2f4479d74a56cf292d8c152544592dd99a are actual post-build/run observations. They do not prove binary equality across a compilation that changes the product. Frontend work is outside these backend source holds. Resumption at 20:52 UTC confirms the controller/test sources remain held; no execution is inferred during the usage pause.
This gate uses real disk-backed SQLite and direct-controller Web JSON serialization. It hosts no HTTP server or cookie middleware. Test names containing “API” do not change that boundary. Actual Program/local-cookie native journeys must still verify available UTC fields over HTTP and existing consumers; no hosted all-five-operation-date fixture is claimed. MariaDB, external provider/model execution, human/device/output and production release remain unverified.
Preservation and publication
One new ordinary case derives backend inventory 1,054 from 1,053; the existing three cases are strengthened and no case is skipped or removed. The last full backend run of 1,033 remains inherited until P7-12's integrated regression. Frontend/browser counts are reconciled separately from the presentation work.
All 57 PRES groups remain 56 PARTIAL / C11 DEFERRED, and the original 32 routes plus Documents remain 33. P5-13 stays withheld with zero model qualification calls; followMode is deferred. This correction does not establish full notification/operation UX acceptance or F20 recovery.
The repair static checks pass: secret scan, working/staged/phase whitespace, local documentation links, all 57 preservation groups and 33 current route patterns. Commit this compatibility change separately before presentation commits. P7-07 publication and normal development push remain blocked by the recorded port-443 connection failures; the fresh 20:53 UTC fetch also failed, so no current live remote equality is claimed. Actual commit/push outcomes will be recorded after execution. Production: NO-GO; main unchanged. Phase 8: no implementation.