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>
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 |
|
|
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).