48 lines
7.3 KiB
Markdown
48 lines
7.3 KiB
Markdown
# P7-08 — Operation and notification UTC transport
|
||
|
||
**SQLite/direct-controller and bounded available-field HTTP scope: CONDITIONAL GO; hygiene PASS, separate repair commit and normal push verified.** Full hosted date coverage and manual/production acceptance remain unverified. This bounded compatibility repair precedes the two [P7-08 presentation boundaries](README.md). [Portable UTC results](evidence/utc-results.json) retain exact commands, reports, source observations and qualifications; the later native observation is bounded below.
|
||
|
||
## 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.
|
||
|
||
The four-case/73-consumer 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. The separate hosted observation below supplements this gate; it does not replace the all-seven-field deterministic precision proof. MariaDB, external provider/model execution, human/device/output and production release remain unverified.
|
||
|
||
## Bounded actual HTTP observation
|
||
|
||
Six actual Program/local-Identity-cookie native cases pass **21:00:34.683928–21:01:16.758533 UTC**, zero skipped/unexpected/flaky cases and retries 0. `.artifacts/phase7/p7-08/recent-native-verified/results.json` retains that execution, SHA256 `10ecebb46c208aa4241ad656bcb7ca03f417220f8cf008563896f2ccdda58659`. An inert test-only queued operation is seeded; existing real cancel/retry/read/dismiss endpoints own the subsequent persisted transitions, without worker/provider/model activation.
|
||
|
||
The actual lifecycle attachment records UTC-`Z` operation `createdAtUtc`/`completedAtUtc` and notification `createdAtUtc`/`readAtUtc` over HTTP. All available non-null `*AtUtc` fields are asserted as ISO UTC. Started/deadline/cancellation-request dates are null in that hosted fixture, and dismissed time is not a public notification field: **no all-seven-field hosted or deterministic tick-precision claim follows**. Controlled long-text/internal-link GET projections qualify their UI behavior only; actual notices retain `linkPath=null`. This supplies bounded transport evidence, not complete presentation, human/device or production acceptance.
|
||
|
||
## 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](evidence/utc-static-checks.json) pass: secret scan, working/staged/phase whitespace, local documentation links, all 57 preservation groups and 33 current routes. Repair commit **`9dfea1226f57ba12b944e05e0e83fb2fea846131`** is separately committed and normally pushed at **21:00:51.343381–21:00:53.589287**, together with the previously blocked Documents implementation/documentation. The [publication recovery](../p7-07/evidence/ui-publication.json) preserves failed attempts and the immutable raw recovery receipt/hash. At **21:01:11.788733**, HEAD/origin/live development all equal `9dfea1226f57ba12b944e05e0e83fb2fea846131`; local/origin/live main remain `27657f31131cd95d42f0e1290853ec9c9b3959a4`. Known notification presentation/tests/native helpers remain unstaged WIP, so no clean-worktree or publication of that work is claimed. **Production: NO-GO; no main push or deployment. Phase 8: no implementation.**
|