myxce/.wolf/bugs/bug-1584.md
Rongsong Shen d26ff8870d
feat(buglog): one Markdown record per bug, checked against a record standard
The buglog was one 27K-line JSON file whose fields covered only symptom,
root cause and fix, as free text: 2% of entries named the code version a
bug was found on, 12% the build profile, 36% a way to reproduce, and 58% of
the file was OpenWolf hook auto-detections ("Missing guard clause",
"Function not marked async" on .md files).

- .claude/skills/buglog/bug-record.md: the record standard. Eight
  sections (Summary as the title, Description, Environment, Reproduction;
  Root cause, Fix, Verification, References once fixed), each with the
  content it must contain -- e.g. Environment needs the OS, the libc the
  failing binary loads (from its ELF interpreter: glibc 2.42 in the nix
  shell vs 2.40 on the host), toolchain, build profile and commit.
- .wolf/bugs/<id>.md: 500 records migrated from buglog.json; every field
  verified to round-trip. They carry legacy: true and an explicit "not
  recorded" where the old log had no such field; component derived from
  file paths, severity from keywords (else unknown), fix_commits from
  hashes in status_note/fix that git resolves (91 of 463 fixed).
- .wolf/buglog-archive.json: the 710 hook auto-detections, verbatim.
- .wolf/buglog.json is now an index generated from the records, keeping
  the fields OpenWolf's hooks and `openwolf bug search` read.
- scripts/buglog.py rewritten: new (template + Environment collected from
  the machine and --binary), check, status (refuses a status the record
  doesn't support; fixed needs Root cause, Fix, Verification and
  --commit hashes git resolves), note, recur, set, show, list, triage,
  env, index. 29 unittest cases in scripts/tests/test_buglog.py.
- scripts/git-hooks/pre-commit runs `check --staged`: incomplete staged
  records, a legacy record hand-changed to fixed without the fix-time
  sections, a new record claiming legacy: true, or a stale index refuse
  the commit.
- scripts/gitea-sync.py reads the records: issue body = the record's
  sections plus linked fix commits (origin remote, GITEA_COMMIT_REPO to
  override), and a body hash so an issue's text is refreshed when the
  record changes.
- bug-1866 rewritten to the full standard as the worked example.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 03:40:11 +00:00

4.5 KiB

id status status_updated status_note component severity timestamp last_seen occurrences files tags related legacy
bug-1584 fixed 2026-09-24 scheduler unknown 2026-08-19T02:47:00Z 2026-09-19T09:00:00Z 1
src/scheduler/src/core_clock.c
src/scheduler/include/core.h
src/scheduler/src/core.c
src/scheduler/src/scheduler.c
src/scheduler/testsuite/test_clock.c
scheduler
clock
xce_core_now
recording
xceadmin
wall-clock
epoch-time
monotonic-clock
core-clock
user-reported
true

bug-1584: User-reported: xceadmin scheduler record start/status/stop always shows 'started at:' near…

Description

User-reported: xceadmin scheduler record start/status/stop always shows 'started at:' near 1970-01-01 (e.g. '1970-01-04T20:11:26') instead of the real start time, even though 'file'/'events'/'recording' fields are correct.

Environment

Not recorded (migrated from buglog.json).

Reproduction

Not recorded (migrated from buglog.json).

Root cause

xce_sched_core_init() (core.c) seeds the scheduler-core's clock anchors to a neutral (virtual_clock_base=0, real_clock_base=0, speed_num=1, speed_den=1) default. The existing doc comments in core.c/core.h (task 4.5, scheduler-core spec) claimed this 'degrades to real wall-clock time' -- that claim is simply wrong: with both anchors at 0, xce_core_now()'s elapsed computation (wall_ns - real_clock_base) collapses to the raw CLOCK_MONOTONIC reading itself, i.e. nanoseconds since an arbitrary reference point (typically system boot), NOT nanoseconds since the Unix epoch. Only the simulation driver (sim.c's sim_set_virtual_clock(), called from sched_sim_driver_start()) ever seeds a genuine epoch anchor -- the normal-mode driver (scheduler.c's sched_init()) never did. recording.c's sched_record_start()/sched_record_stop() stamp record_start_ts and every ReplayEvent/SnapshotEntry ts via xce_core_now(), and controller.capnp's SchedAdminReply.startedAt is explicitly documented as 'nanoseconds since epoch' (which xceadmin's cli.py _format_timestamp_ns() renders via datetime.fromtimestamp(ns/1e9, tz=utc)) -- so a normal-mode scheduler's uptime-since-boot value gets rendered as a date near 1970. Independently confirmed already known and documented as a latent issue for a DIFFERENT symptom (tlog logging integration, design.md line ~793 / scheduler-core tasks.md Implementation Notes item #6) but nobody had connected it to the recording subsystem's user-facing 'started at' field before this report.

Fix

Added xce_core_set_wallclock_anchor(xce_sched_core_t*) to core_clock.c -- the normal-mode counterpart to sim.c's sim_set_virtual_clock() -- which reads CLOCK_REALTIME (the epoch anchor for virtual_clock_base) and CLOCK_MONOTONIC (the matching real_clock_base xce_core_now()'s own elapsed computation is defined against) back-to-back and stores them as a group (speed_num=speed_den=1). Declared in core.h. Wired into scheduler.c's sched_init(), called once immediately after xce_sched_core_init() succeeds, before anything can observe xce_core_now(). Corrected the misleading 'degrades to real wall-clock time' doc comments in core.c and core.h to state the actual (monotonic-since-boot) behavior of the neutral default and point to the new function. Simulation mode and every core.c-including test fixture that constructs a bare core directly are unaffected (they never call the new function, so they keep the (0,0,1,1) neutral default or sim_set_virtual_clock()'s own anchors exactly as before). TDD: added test_xce_core_set_wallclock_anchor_seeds_real_epoch_time (brackets xce_core_now() immediately after the call between two back-to-back CLOCK_REALTIME reads -- fails loudly pre-fix since the bracketed value would be a small monotonic-since-boot number, not a real ~1.7e18ns epoch value) and test_xce_core_set_wallclock_anchor_null_core_is_a_safe_noop to test_clock.c. Verified via /xce-build scheduler asan --incremental: build clean, test_clock 100% green (17/17 including both new tests). One pre-existing, unrelated failure in the same suite run (test_admin_request's test_recordstart_symlink_escape_replies_error, bug-1560, a sandbox uid-permission-ordering issue) confirmed unaffected -- git status confirms test_admin_request.c was not touched by this fix. Not yet live-validated against a real xceadmin CLI run end-to-end (xceadmin scheduler record start/status) -- recommend a live /xce-deploy-ha smoke check before considering this fully closed.

Verification

Not recorded (migrated from buglog.json).

References

Not recorded (migrated from buglog.json).