phase: 154_sync_status_freshness
Build and Push Containers / build-and-push-app (push) Successful in 2m26s
Build and Push Containers / build-and-push-db (push) Successful in 16s

All 4 task files exist in `complete/`, and only `00_phase.md` remains in `todo/`. This is the final verification pass. I'll read through the task files and check the current state of the code.
This commit is contained in:
2026-10-04 14:24:33 -04:00
parent 966c4b0540
commit c275735db4
36 changed files with 2526 additions and 99 deletions
+316
View File
@@ -164,8 +164,11 @@ tests/unit/test_frontend_sync_upload.py's node check).
from __future__ import annotations
import asyncio
import json
import logging
import re
import shutil
import subprocess
import threading
import time
from collections.abc import Callable, Iterator, Sequence
@@ -198,6 +201,8 @@ RETIRED_ID = "-".join(("sync", "result")) # built at runtime: 3.12+ folds
# adjacent/"+" constant strings at compile time, which would leave the
# retired name in the .pyc — the phase gate greps even the bytecode.
HAVE_NODE = shutil.which("node") is not None
def _text(path: Path) -> str:
assert path.is_file(), f"missing frontend file: {path}"
@@ -563,6 +568,10 @@ def test_sources_js_terminal_states() -> None:
success = _body(js, "applySyncSuccess")
assert '"Synced"' in success and "fmtSyncTime(status.finished_at)" in success
assert 'settleSyncButton(time ? `Synced ${time}` : "Synced")' in success, (
"the settle string — phase 154: the qualified stamp rides the SAME"
" shape (the qualifier lives inside the formatter)"
)
failure = _body(js, "applySyncFailure")
assert 'settleSyncButton("Sync sources")' in failure # retry-ready
@@ -578,6 +587,313 @@ def test_sources_js_terminal_states() -> None:
time = _body(js, "fmtSyncTime")
assert "getHours()" in time and "getMinutes()" in time, "local HH:MM of finished_at"
assert 'if (Number.isNaN(d.getTime())) return "";' in time, (
"the parse guard is UNCHANGED — unparseable ISO → "" (the bare"
" 'Synced' settle)"
)
# Phase 154 (task 01): the DATE-QUALIFIER (A1 rule — the LOCAL
# calendar dates, the page's clock; the table dates' family).
assert "const now = new Date();" in time, "'now' is the page's clock"
assert (
"d.getFullYear() === now.getFullYear() &&" in time
and "d.getMonth() === now.getMonth()" in time
and "d.getDate() === now.getDate()" in time
), "same local calendar day as now → HH:MM (byte-identical to pre-phase)"
assert "d.getHours() % 12 || 12" in time, (
"12-hour WITHOUT leading zero on the hour (the 12 o'clock edge)"
)
assert '"AM"' in time and '"PM"' in time, "the AM/PM family"
assert "pad(d.getMinutes())" in time, "MM zero-padded in every form"
assert "`${d.getMonth() + 1}/${d.getDate()}`" in time, (
"M/D, no leading zeros (same year, different day)"
)
assert "`${d.getMonth() + 1}/${d.getDate()}/${d.getFullYear()}`" in time, (
"M/D/YYYY across years"
)
# Phase 154 (task 01) — the date-qualifier's boundary set, behavioral
# under node with a FIXED clock. The test body never calls `new
# Date()` for its own timing: the fake clock is installed in the
# driver (global Date patched BEFORE the call — `new Date()` → the
# fixed now, `new Date(iso)` → the real parse), and every ISO is
# designator-less (local) so the comparison is timezone-independent.
# The fixed now is Oct 3, 2026, 18:30 LOCAL.
_STAMP_NOW_JS = "new RealDate(2026, 9, 3, 18, 30, 0)"
def _stamp_driver(fn_src: str, expr: str) -> str:
"""Run `expr` under node with the REAL sources.js function + the
fake clock (the idiom: the Date patch precedes the call)."""
driver = (
f"{fn_src}\n"
"const RealDate = Date;\n"
f"const NOW = {_STAMP_NOW_JS};\n"
"globalThis.Date = function (...args) {\n"
" return args.length === 0 ? NOW : new RealDate(...args);\n"
"};\n"
f"{expr}\n"
)
proc = subprocess.run(
["node", "-e", driver], capture_output=True, text=True, timeout=60
)
assert proc.returncode == 0, f"node failed: {proc.stderr}"
return proc.stdout
@pytest.mark.skipif(not HAVE_NODE, reason="node not available")
def test_sources_js_fmt_sync_time_qualifier_boundaries_fixed_clock() -> None:
"""The REAL sources.js ``fmtSyncTime`` under node (fake clock, the
fixed now Oct 3 2026 18:30 local) — the A1 boundary set:
same-day → ``HH:MM`` (byte-identical to the pre-phase output —
the audit's own ``16:06`` case, plus the midnight / end-of-day
edges); yesterday (same year) → ``M/D, h:MM AM/PM`` (no leading
zero on the hour — ``3:14 PM``; the ``12:05 AM`` / ``12:07 PM``
o'clock edges); last-year same M/D → ``M/D/YYYY, h:MM AM/PM``;
garbage / missing ISO → ``""`` (the guard unchanged).
The ``null`` edge (``new Date(null)`` IS the epoch — parseable,
the guard unchanged) is pinned TZ-independently: ``null`` and the
epoch ISO render identically (same instant), in the dated + year
form (1969 ≠ the fixed 2026). The wall clock never appears in an
assertion."""
fn = _body(_text(SOURCES_JS), "fmtSyncTime")
# (iso, expected) — the expected strings are the pins.
cases = [
("2026-10-03T16:06:00", "16:06"), # same day — the audit case
("2026-10-03T00:05:00", "00:05"), # same day, midnight edge
("2026-10-03T23:59:00", "23:59"), # same day, end-of-day edge
("2026-10-02T15:14:00", "10/2, 3:14 PM"), # yesterday, no zero hour
("2026-10-02T00:05:00", "10/2, 12:05 AM"), # yesterday, 12:05 AM edge
("2026-10-02T12:07:00", "10/2, 12:07 PM"), # yesterday, noon edge
("2026-10-02T23:58:00", "10/2, 11:58 PM"), # yesterday, PM minutes
("2025-10-03T21:12:00", "10/3/2025, 9:12 PM"), # last year, same M/D
("2025-01-03T09:12:00", "1/3/2025, 9:12 AM"), # last year, month 1
("garbage", ""), # unparseable → the pre-phase fallback
("", ""), # empty → the pre-phase fallback
("undefined", ""), # missing ISO (the app-restart case) → ""
]
iso_literals = []
for iso, _ in cases:
if iso == "undefined":
iso_literals.append("undefined")
else:
iso_literals.append(f'"{iso}"')
driver_expr = (
"const CASES = [" + ", ".join(iso_literals) + "];\n"
"const STAMPS = CASES.map((c) => fmtSyncTime(c));\n"
"const EPOCH = [fmtSyncTime(null), fmtSyncTime(new RealDate(0).toISOString())];\n"
"console.log(JSON.stringify({ STAMPS, EPOCH }));"
)
out = json.loads(_stamp_driver(fn, driver_expr))
assert out["STAMPS"] == [expected for _, expected in cases], out
assert out["EPOCH"][0] == out["EPOCH"][1], (
"null and the epoch ISO render identically (the same instant —"
" the guard is unchanged: new Date(null) IS the epoch)"
)
assert re.fullmatch(
r"\d{1,2}/\d{1,2}/\d{4}, \d{1,2}:\d{2} (AM|PM)", out["EPOCH"][0]
), "the epoch takes the M/D/YYYY, h:MM AM/PM form (1969 ≠ the fixed year)"
@pytest.mark.skipif(not HAVE_NODE, reason="node not available")
def test_sources_js_synced_settle_string_qualifies_the_stamp() -> None:
"""The ``applySyncSuccess`` settle string (the pinned shape
``time ? `Synced ${time}` : "Synced"`` — the qualifier lives
INSIDE the formatter, the shape is unchanged) under node with the
fixed clock: a same-day ``finished_at`` settles as
``Synced 16:06`` (byte-identical to pre-phase), a non-same-day
one settles as ``Synced 10/2, 3:14 PM`` (the date-qualified
badge — the phase's ask), and an unparseable/missing ISO settles
as the bare ``Synced`` (the existing fallback). The ``null`` edge
pins identically to the boundary test (the epoch — the pre-phase
rendered ``Synced 00:00`` there)."""
fn = _body(_text(SOURCES_JS), "fmtSyncTime")
settle = (
"const settle = (iso) => {\n"
" const t = fmtSyncTime(iso);\n"
" return t ? `Synced ${t}` : \"Synced\";\n"
"};\n"
)
iso_literals = [
'"2026-10-03T16:06:00"', # same day
'"2026-10-02T15:14:00"', # yesterday
'"2025-10-03T21:12:00"', # last year
'"garbage"', # unparseable
"undefined", # missing ISO
]
driver_expr = (
settle
+ "const CASES = [" + ", ".join(iso_literals) + "];\n"
+ "const SETTLES = CASES.map(settle);\n"
+ "const EPOCH = [settle(null), settle(new RealDate(0).toISOString())];\n"
+ "console.log(JSON.stringify({ SETTLES, EPOCH }));"
)
out = json.loads(_stamp_driver(fn, driver_expr))
assert out["SETTLES"] == [
"Synced 16:06", # same day — byte-identical to pre-phase
"Synced 10/2, 3:14 PM", # yesterday — date-qualified
"Synced 10/3/2025, 9:12 PM", # last year — date + year
"Synced", # garbage — the bare fallback
"Synced", # missing ISO — the bare fallback
], out
assert out["EPOCH"][0] == out["EPOCH"][1], (
"settle(null) and the epoch ISO settle identically (the guard"
" unchanged)"
)
assert out["EPOCH"][0].startswith("Synced "), (
"the epoch settles with a stamp (new Date(null) is parseable"
" — the pre-phase rendered 'Synced 00:00' there)"
)
# Phase 154 (task 03) — the qualifier's BYTE-IDENTITY: the pre-phase
# fmtSyncTime, pinned VERBATIM from git history (the phase-154
# pre-state — the time-only formatter). Only the function NAME is
# renamed (so the real + the reference run side by side under node);
# the body is the old code byte-for-byte — the old strings (the
# `HH:MM` return + the `""` guard) live in this constant, so the
# byte-identity below is assertable, not assumed. The reference is
# clock-free (it reads no `now` — only the ISO's local time), but
# the same fixed-clock driver (the task-01 boundary set's clock) is
# used, so the real function's same-day comparison runs on the fixed
# now exactly as in the boundary test.
PRE_PHASE_FMT_SYNC_TIME_JS = """
function prePhaseSyncTime(iso) {
const d = new Date(iso);
if (Number.isNaN(d.getTime())) return "";
const pad = (n) => String(n).padStart(2, "0");
return `${pad(d.getHours())}:${pad(d.getMinutes())}`;
}
"""
@pytest.mark.skipif(not HAVE_NODE, reason="node not available")
def test_sources_js_fmt_sync_time_same_day_is_byte_identical_to_pre_phase() -> None:
"""Phase 154 (task 03): the REAL sources.js ``fmtSyncTime`` and
the VERBATIM pre-phase formatter (pinned above) run side by side
under node with the fixed clock (Oct 3 2026 18:30 local — the
task-01 boundary set's clock):
* the pinned reference's own output is asserted against the
verbatim old strings FIRST (a self-check on the constant — a
typo in the pinned function fails here, not silently);
* EVERY same-day ISO renders BYTE-IDENTICALLY to the pre-phase
output (the old ``HH:MM`` — the audit's ``16:06`` case, the
midnight / end-of-day edges), and its settle string is
byte-identical to the pre-phase settle (``"Synced " + HH:MM``
— a same-day badge never moved);
* EVERY unparseable/missing ISO (``garbage`` / ``""`` /
``undefined``) renders byte-identically to the pre-phase
``""`` (the guard unchanged);
* the NON-same-day ISOs (yesterday + last year + the
``null``/epoch edge — the epoch's local time is a different
day AND a different year, so the qualified form applies; its
value is TZ-dependent, so it is pinned by SHAPE: the
``M/D/YYYY, h:MM AM/PM`` family vs the old ``HH:MM``) are the
pinned DIVERGENT set — the qualified form is byte-different
from the pre-phase time-only string (the phase's change lives
exactly there).
The wall clock never appears in an assertion."""
# Source-level self-check: the pinned constant carries the old
# strings verbatim (the `HH:MM` return + the parse guard).
assert (
"return `${pad(d.getHours())}:${pad(d.getMinutes())}`;"
in PRE_PHASE_FMT_SYNC_TIME_JS
), "the old HH:MM return is pinned verbatim"
assert (
'if (Number.isNaN(d.getTime())) return "";' in PRE_PHASE_FMT_SYNC_TIME_JS
), "the old parse guard is pinned verbatim"
fn = _body(_text(SOURCES_JS), "fmtSyncTime")
# (js literal, category) — category: same / fallback / diverge.
cases = [
('"2026-10-03T16:06:00"', "same"), # the audit case
('"2026-10-03T00:05:00"', "same"), # midnight edge
('"2026-10-03T23:59:00"', "same"), # end-of-day edge
('"garbage"', "fallback"),
('""', "fallback"), # empty ISO
("undefined", "fallback"), # missing ISO (the app-restart case)
("null", "diverge"), # the epoch edge — shape-pinned (TZ-dependent)
('"2026-10-02T15:14:00"', "diverge"), # yesterday
('"2026-10-02T00:05:00"', "diverge"),
('"2026-10-02T12:07:00"', "diverge"),
('"2026-10-02T23:58:00"', "diverge"),
('"2025-10-03T21:12:00"', "diverge"), # last year
('"2025-01-03T09:12:00"', "diverge"),
]
# The verbatim old strings (the pre-phase output — pinned here so
# the identity is assertable); the null/epoch value is
# TZ-dependent, so its old string is pinned by shape, not value.
old = {
'"2026-10-03T16:06:00"': "16:06",
'"2026-10-03T00:05:00"': "00:05",
'"2026-10-03T23:59:00"': "23:59",
'"garbage"': "",
'""': "",
"undefined": "",
}
driver_expr = (
"const CASES = [" + ", ".join(lit for lit, _ in cases) + "];\n"
"const PRE = CASES.map((c) => prePhaseSyncTime(c));\n"
"const REAL = CASES.map((c) => fmtSyncTime(c));\n"
"const settle = (f) => (iso) => {\n"
" const t = f(iso);\n"
" return t ? `Synced ${t}` : \"Synced\";\n"
"};\n"
"const PRE_SETTLE = CASES.map((c) => settle(prePhaseSyncTime)(c));\n"
"const REAL_SETTLE = CASES.map((c) => settle(fmtSyncTime)(c));\n"
"console.log(JSON.stringify({ PRE, REAL, PRE_SETTLE, REAL_SETTLE }));"
)
out = json.loads(
_stamp_driver(fn + "\n" + PRE_PHASE_FMT_SYNC_TIME_JS, driver_expr)
)
# 1. the pinned reference reproduces the verbatim old strings
# (self-check on the constant — assertable, not assumed).
for i, (lit, _cat) in enumerate(cases):
if lit in old:
assert out["PRE"][i] == old[lit], (
f"the pre-phase reference for {lit} must be the verbatim old"
f" string {old[lit]!r} — got {out['PRE'][i]!r} (a typo in the"
" pinned constant?"
)
null_i = [lit for lit, _ in cases].index("null")
assert re.fullmatch(r"\d{2}:\d{2}", out["PRE"][null_i]), (
"the null/epoch edge takes the old HH:MM shape on the reference"
" side (the pre-phase is time-only — the value is TZ-dependent,"
" the shape is not)"
)
assert out["PRE_SETTLE"][null_i] == "Synced " + out["PRE"][null_i] # old settle
assert re.fullmatch(
r"\d{1,2}/\d{1,2}/\d{4}, \d{1,2}:\d{2} (AM|PM)", out["REAL"][null_i]
), (
"the null/epoch edge takes the M/D/YYYY, h:MM AM/PM shape on the"
" real side (the epoch is a different day + year — the qualified"
" form; the value is TZ-dependent, the shape is not)"
)
assert out["REAL_SETTLE"][null_i].startswith("Synced ")
# 2. the audit case's settle is byte-identical to pre-phase.
audit_i = [lit for lit, _ in cases].index('"2026-10-03T16:06:00"')
assert out["REAL_SETTLE"][audit_i] == "Synced 16:06", (
"the same-day settle is byte-identical to the pre-phase string"
)
# 3. same-day + fallbacks: byte-identical to the reference, settle
# included; the divergent set: byte-different (the qualified form).
for i, (lit, cat) in enumerate(cases):
if cat == "diverge":
assert out["REAL"][i] != out["PRE"][i], (
f"{lit} must DIFFER from the pre-phase form (the qualified"
f" branch) — got {out['REAL'][i]!r} == {out['PRE'][i]!r}"
)
assert out["REAL_SETTLE"][i] != out["PRE_SETTLE"][i]
else:
assert out["REAL"][i] == out["PRE"][i], (
f"{lit} must be byte-identical to the pre-phase output"
f" (category {cat}) — got {out['REAL'][i]!r} vs"
f" {out['PRE'][i]!r}"
)
assert out["REAL_SETTLE"][i] == out["PRE_SETTLE"][i]
def test_sources_js_failed_error_is_sanitized() -> None: