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>
45 lines
7 KiB
Markdown
45 lines
7 KiB
Markdown
---
|
|
id: "bug-1590"
|
|
status: "fixed"
|
|
status_updated: "2026-09-24"
|
|
status_note: ""
|
|
component: "scheduler"
|
|
severity: "unknown"
|
|
timestamp: "2026-08-19T03:40:00Z"
|
|
last_seen: "2026-09-19T09:00:00Z"
|
|
occurrences: 2
|
|
files: ["src/scheduler/src/repl_info.c (repl_info_worker_one ~287-335", "repl_info_resource_one ~410-496); src/scheduler/src/core_events.c (~838-861", "TRACE 'resval applied'); src/controller/worker.c (~107-119); src/controller/dataex.c (~86-90)"]
|
|
tags: ["scheduler", "repl", "resource-value", "type-dispatch", "display-bug", "logging", "not-yet-fixed"]
|
|
related: ["bug-1568", "bug-1573"]
|
|
legacy: true
|
|
---
|
|
|
|
# bug-1590: User-reported: `(sim) info worker all` in the scheduler's interactive REPL shows `resource type…
|
|
|
|
## Description
|
|
User-reported: `(sim) info worker all` in the scheduler's interactive REPL shows `resource type: total=0.00 available=0.00` and `resource model: total=0.00 available=0.00` -- but `type`/`model` are STRING-valued resources (e.g. OS type, hardware model name), not numeric, so 0.00 is meaningless. User also notes boolean-typed resources exist and asked to verify resource-value type-correct formatting broadly, across both REPL output and log lines, not just this one command.
|
|
|
|
## Environment
|
|
_Not recorded (migrated from buglog.json)._
|
|
|
|
## Reproduction
|
|
_Not recorded (migrated from buglog.json)._
|
|
|
|
## Root cause
|
|
CONFIRMED via source read across the whole stack (C scheduler/controller/worker + Go apiserver/xcecli), several distinct severities under one theme -- 'resource values are not type-dispatched when formatted for display/log, several call sites assume every resource is numeric (Value_u_fvalue)':
|
|
|
|
(1) MOST SEVERE, matches the exact user report -- `repl_info_worker_one()` (repl_info.c:329-334): `avail = (avail_v->which == Value_u_fvalue) ? avail_v->u.fvalue : 0.0;` then unconditionally `fprintf(..., "total=%.2f available=%.2f", ...)` -- ANY resource whose wire value is Value_u_svalue (string, e.g. `type`/`model`) or Value_u_bvalue (boolean) silently renders as `0.00`, indistinguishable from a genuinely-zero numeric resource. Comment at line 324-328 references bug-1568 (a DIFFERENT, already-fixed bug about comparing against the wrong enum) but bug-1568's fix never added string/bool handling -- it only made the numeric case correct.
|
|
(2) Same defect, `repl_info_resource_one()` (repl_info.c:436-444, `info resource <name>`): the total/available aggregation loop only accumulates when `->which == Value_u_fvalue` (correctly guarded, no UB) -- but silently EXCLUDES string/bool resources from the sum entirely, so `info resource type`/`info resource model` would also show `total=0.00 available=0.00` despite `valtype=string` being correctly labeled two lines below it (line 489-495) -- an internally inconsistent-looking display (correct type label, wrong/misleading value).
|
|
(3) Related, narrower gap in scheduler logging -- `core_events.c`'s bug-1573 fix (~838-861, the 'resval applied host=... resource=... value=...' TRACE line) DOES correctly branch Value_u_svalue -> '%s' vs Value_u_fvalue -> '%f', but its own comment self-documents that Value_u_bvalue (boolean) is 'silently skipped here rather than guessed at' -- confirmed still true as of this reading: no case handles Value_u_bvalue, so a boolean resource update produces NO trace line at all (silent omission, not a wrong value, but incomplete visibility for exactly the resource kind the user flagged).
|
|
(4) Minor/lower severity, controller-side -- `worker.c` (~107-119) has an `else` branch for non-fvalue that logs `which=%d (non-numeric)` (informative about the presence of a non-numeric update, but never decodes/prints the actual string or boolean value); `dataex.c` (~86-90) has NO else branch at all -- silently skips the TRACE entirely for any non-fvalue resource, weakest visibility of the four sites but least user-facing (debug-level TRACE only).
|
|
|
|
POSITIVE finding, scoped this from being a systemic whole-stack issue: the Go apiserver's `cNameValToWorkerResval()` (`src/frontend/apiserver/backend/convert.go:325-370`) is a CORRECT, COMPLETE reference implementation -- it switches on all 7 `Value_u_which` wire tags (ivalue32/ivalue64/uvalue32/uvalue64/fvalue all -> NUMERIC/`NumericValue`, svalue -> STRING/`StringValue`, bvalue -> BOOLEAN/`BooleanValue`, matching `models.ResourceDistributionInfo`'s already-correctly-typed fields, `src/frontend/apiserver/models/resources.go:118-126`), plus a `default:` WARN log for any unrecognized tag. `src/frontend/xcecli/models/resource.go`'s `ResourceValue.UnmarshalJSON()` (client-side) also correctly handles string/bool/numeric JSON values. So the production REST API (apiserver) and `xcecli` CLI resource-value display path are NOT affected -- this bug is confined to the scheduler's own C-side simulation-debugging REPL (`repl_info.c`, the user-facing symptom) and a handful of C-side TRACE/debug log call sites in the scheduler/controller (lower severity, debug-visibility-only gaps).
|
|
|
|
## Fix
|
|
Fixed. src/scheduler/src/repl_info.c: repl_info_worker_one() (`info worker <name>|all`) now switches on the resval's real Value_u_which wire tag -- Value_u_svalue prints `resource <name>: value=<string>`, Value_u_bvalue prints `resource <name>: value=true|false`, Value_u_fvalue keeps the existing `total=%.2f available=%.2f` numeric display unchanged. repl_info_resource_one() (`info resource <name>`) got the analogous fix one layer up: the per-worker aggregation loop now tracks the first-seen string/boolean value (in addition to the existing numeric total/available sum), and the final print branches on the resource DEFINITION's authoritative `r->valtype` (XCE_VAL_STRING/XCE_VAL_BOOLEAN/XCE_VAL_NUMERIC, xce/types.h) to decide which of `value=<v>` (with a 'reported by N worker(s)' count) vs. the numeric total/available pair to print -- total/available is a consumable-quantity concept that is only meaningful for a numeric resource, so a string/boolean resource no longer gets a fabricated total=0.00/available=0.00 pair at all. TDD: added test_info_worker_reports_string_and_boolean_resource_values and test_info_resource_reports_string_value to test_repl_breakpoints_inspection.c, both constructing a real WORKERS_PUSH event with a string- and boolean-valued resource through the actual xce_core_push_events() path (same fixture idiom the existing bug-1568 numeric-resource test already established), asserting the new `value=` lines appear and no `total=` line is ever emitted for a non-numeric resource. Verified via a full non-incremental /xce-build scheduler asan run (fresh wipe+reconfigure, not reusing any cached object): zero compiler errors, both new tests confirmed PASS in testlog.txt, full suite Ok:41/Fail:1 out of 42 -- the sole failure is the pre-existing unrelated bug-1560 (test_admin_request's symlink-escape test). core_events.c's separately-noted boolean-TRACE gap (item 3 in this entry's root_cause) and worker.c/dataex.c's non-numeric TRACE decode gaps (item 4) were NOT touched -- left as documented, lower-priority follow-ups, not part of this fix's scope.
|
|
|
|
## Verification
|
|
_Not recorded (migrated from buglog.json)._
|
|
|
|
## References
|
|
- Related: bug-1568, bug-1573
|