From 1c4a1ba24acbed4344e7545cc1037e1a7e848410 Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Sun, 30 Aug 2026 15:32:16 +0000 Subject: [PATCH] docs: sync OpenWolf state Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_019QxaSzHRB7pmYFp4cVnwkA --- .wolf/anatomy-index.json | 67 ++++++++++++++++++++++++++++------------ .wolf/anatomy.md | 19 +++++++++--- .wolf/buglog.json | 26 +++++++++------- .wolf/memory.md | 12 +++++++ 4 files changed, 88 insertions(+), 36 deletions(-) diff --git a/.wolf/anatomy-index.json b/.wolf/anatomy-index.json index 1cf5b33c..f95ae568 100644 --- a/.wolf/anatomy-index.json +++ b/.wolf/anatomy-index.json @@ -1,13 +1,13 @@ { "version": 1, "meta": { - "lastScanned": "2026-08-30T15:06:40.281Z", - "fileCount": 555, + "lastScanned": "2026-08-30T15:25:28.278Z", + "fileCount": 558, "hits": 0, "misses": 0, - "renderedHash": "ee44fa75780c1935939977f8ffaaa77b305dd8dfb1d92273e53e281cb38bb834", - "storeUpdatedAt": "2026-08-30T15:06:40.289Z", - "rootHash": "91d2c295883b912b" + "renderedHash": "6515a885c8768e4276e975dcc3d90f08f7d92107ca44a3203ea7e560af9be4dc", + "storeUpdatedAt": "2026-08-30T15:25:28.287Z", + "rootHash": "24fb14ecfae59ce8" }, "files": { ".agent-shell/transcripts/2026-08-11-11-39-59.md": { @@ -6272,11 +6272,11 @@ }, "src/controller/job.c": { "description": "include ", - "tokens": 39347, - "hash": "b584def6c8be4e0b", - "size": 147700, - "mtimeMs": 1788094063748.4392, - "updatedAt": "2026-08-30T12:47:43.792Z", + "tokens": 39387, + "hash": "7346df3ab0f4cf61", + "size": 147851, + "mtimeMs": 1788103367463.4827, + "updatedAt": "2026-08-30T15:22:47.506Z", "source": "hook" }, "src/controller/sched.c": { @@ -6577,11 +6577,11 @@ }, "src/controller/testsuite/test_host_runusage.c": { "description": "Declares char", - "tokens": 2404, - "hash": "5c993a7a53ccfcf0", - "size": 9015, - "mtimeMs": 1788096408980.8794, - "updatedAt": "2026-08-30T13:26:49.043Z", + "tokens": 3442, + "hash": "5612eb8b26d20d3f", + "size": 12906, + "mtimeMs": 1788103528243.6794, + "updatedAt": "2026-08-30T15:25:28.278Z", "source": "hook" }, "src/controller/meson.build": { @@ -6595,11 +6595,11 @@ }, "src/controller/misc.c": { "description": "include ", - "tokens": 1756, - "hash": "a6472812879cd1a8", - "size": 6582, - "mtimeMs": 1788094049916.7393, - "updatedAt": "2026-08-30T12:47:29.955Z", + "tokens": 2257, + "hash": "f5cd4707a7a6cc05", + "size": 8462, + "mtimeMs": 1788103316495.1594, + "updatedAt": "2026-08-30T15:21:56.703Z", "source": "hook" }, "src/controller/testsuite/test.c": { @@ -6637,6 +6637,33 @@ "mtimeMs": 1788098337067.5034, "updatedAt": "2026-08-30T13:58:57.394Z", "source": "hook" + }, + "src/scheduler/testsuite/test_admin_request.c": { + "description": "Declares level", + "tokens": 13020, + "hash": "0aca61e7462c9340", + "size": 48824, + "mtimeMs": 1788103082342.1372, + "updatedAt": "2026-08-30T15:18:02.611Z", + "source": "hook" + }, + "src/include/xce/types.h": { + "description": "< NULL.", + "tokens": 5452, + "hash": "a70960eb96ae7bda", + "size": 20456, + "mtimeMs": 1788103228846.1067, + "updatedAt": "2026-08-30T15:20:29.310Z", + "source": "hook" + }, + "src/schema/controller.capnp": { + "description": "Declares OPCode", + "tokens": 15126, + "hash": "db582a215ce32ffa", + "size": 57419, + "mtimeMs": 1788103256851.4102, + "updatedAt": "2026-08-30T15:20:56.894Z", + "source": "hook" } } } \ No newline at end of file diff --git a/.wolf/anatomy.md b/.wolf/anatomy.md index 855c5eb7..1940a352 100644 --- a/.wolf/anatomy.md +++ b/.wolf/anatomy.md @@ -1,7 +1,7 @@ # anatomy.md -> Auto-maintained by OpenWolf. Last scanned: 2026-08-30T15:06:40.281Z -> Files: 555 tracked | Anatomy hits: 0 | Misses: 0 +> Auto-maintained by OpenWolf. Last scanned: 2026-08-30T15:25:28.278Z +> Files: 558 tracked | Anatomy hits: 0 | Misses: 0 ## ./ @@ -809,10 +809,10 @@ ## src/controller/ - `config_repl.c` — define _GNU_SOURCE (~35341 tok) -- `job.c` — include (~39347 tok) +- `job.c` — include (~39387 tok) - `main.c` — include (~5489 tok) - `meson.build` (~3852 tok) -- `misc.c` — include (~1756 tok) +- `misc.c` — include (~2257 tok) - `persist.c` — define _GNU_SOURCE (~109226 tok) - `sched.c` — include (~6721 tok) @@ -826,7 +826,7 @@ - `test_apply_reapply_idempotency.c` — Declares xce_job_t (~4115 tok) - `test_commit_barrier_reply.c` — Declares uint8_t (~45642 tok) - `test_config_repl.c` — define _GNU_SOURCE (~87218 tok) -- `test_host_runusage.c` — Declares char (~2404 tok) +- `test_host_runusage.c` — Declares char (~3442 tok) - `test_wal_job_finish_fact.c` — Declares as (~8980 tok) - `test_wal_job_start_fact.c` — Declares as (~12368 tok) - `test.c` — include (~40634 tok) @@ -835,6 +835,10 @@ - `handler.go` — Struct: DefaultHandler (~3107 tok) +## src/include/xce/ + +- `types.h` — < NULL. (~5452 tok) + ## src/lib/ - `controller.capnp.c` — include "controller.capnp.h" (~167125 tok) @@ -863,6 +867,7 @@ ## src/scheduler/testsuite/ +- `test_admin_request.c` — Declares level (~13020 tok) - `test_core_events.c` — Declares and (~11084 tok) - `test_sim_contention_parity.c` — Declares calls (~18713 tok) - `test_sim_e2e_original_motivation.c` (~17120 tok) @@ -870,6 +875,10 @@ - `test_sim_startup.c` — Declares char (~5708 tok) - `test_snapshot_save_load.c` (~28712 tok) +## src/schema/ + +- `controller.capnp` — Declares OPCode (~15126 tok) + ## src/tools/ - `xce-build.sh` (~4220 tok) diff --git a/.wolf/buglog.json b/.wolf/buglog.json index 7953ffd3..11d70007 100644 --- a/.wolf/buglog.json +++ b/.wolf/buglog.json @@ -16201,23 +16201,25 @@ "timestamp": "2026-08-15T22:54:35Z", "error_message": "test_recordstart_symlink_escape_replies_error (src/scheduler/testsuite/test_admin_request.c:850) FAILED: Expected 'invalid record file name' Was 'permission denied accessing record file'. Surfaced only now because bug-1559's fix made xce-build.sh's scheduler case run the full `meson test --suite scheduler` for the first time -- this test was never reached by the old sched_test-only invocation.", "file": "src/scheduler/testsuite/test_admin_request.c, src/scheduler/src/recording.c", - "root_cause": "Not yet investigated. Test plants a symlink inside record_dir whose target resolves outside record_dir, then issues a recordStart admin request expecting rejection with error string 'invalid record file name' (the canonical-path containment check). Instead the admin path is returning a 'permission denied accessing record file' error, implying some permission-check code path is being hit and short-circuiting before (or instead of) the containment check in this sandbox environment (uid 1000, non-root) -- ordering between the two checks in recording.c not yet confirmed by direct read. Unrelated to component-failover-adoption / bug-1548/1549/1558/1559 -- discovered purely as a side effect of bug-1559's coverage-gap fix making this test reachable.", - "fix": "NOT FIXED -- out of scope for the component-failover-adoption remediation that surfaced it. Needs its own investigation of recording.c's record-file validation check ordering. NEW NUANCE (2026-08-20, build-time-versioning task 6.1): because xce-build.sh has `set -euo pipefail` and its scheduler case's RUN_TESTS block runs the FULL `meson test --suite scheduler` unconditionally (asan profile only), this one persistently-failing test makes the WHOLE `xce-build.sh scheduler asan ...` invocation exit non-zero EVEN THOUGH `meson compile` (all 430/430 targets) already succeeded and the real xce_scheduler binary was produced correctly -- any downstream script/wrapper that treats a non-zero xce-build.sh exit as \"build failed\" will incorrectly abort/skip real post-build verification (e.g. checking --version output) on the asan profile specifically. src/tools/test-build-version-regression.sh (task 6.1's new regression check) works around this deliberately: it captures xce-build.sh's exit code via `cmd || rc=$?` (NOT a bare unguarded call, which would trigger its own set -e), prints a WARNING distinguishing \"compile succeeded, only the bundled test run failed\" from a genuine build failure, and continues to check the binary/--version output regardless -- the binary-existence check right after is what still catches a REAL compile failure. Root cause of the underlying test failure itself remains unfixed/uninvestigated.\n\nRe-observed a 5th time 2026-08-23 during the scheduler-dispatch-commit feature's final GO/NO-GO release-gate verification run (`xce-build.sh scheduler asan build-asan --incremental`, tree fully committed, zero uncommitted diff in src/scheduler/). meson compile succeeded (467/467 targets, zero compiler errors/warnings-as-errors), xce_scheduler and all testsuite binaries linked cleanly; the bundled `meson test --suite scheduler` run's only failure was this same test (Expected 'invalid record file name' Was 'permission denied accessing record file'), still unrelated to job.c/handler.c dispatch-commit work. Confirmed the feature's own targets separately, both green: `scheduler dispatch commit test` (5 Tests 0 Failures) and `scheduler handlers test` (7 Tests 0 Failures, including the new test_handle_notify_job_dispatch_fail_enqueues_pend case).", + "root_cause": "Not yet investigated. Test plants a symlink inside record_dir whose target resolves outside record_dir, then issues a recordStart admin request expecting rejection with error string 'invalid record file name' (the canonical-path containment check). Instead the admin path is returning a 'permission denied accessing record file' error, implying some permission-check code path is being hit and short-circuiting before (or instead of) the containment check in this sandbox environment (uid 1000, non-root) -- ordering between the two checks in recording.c not yet confirmed by direct read. Unrelated to component-failover-adoption / bug-1548/1549/1558/1559 -- discovered purely as a side effect of bug-1559's coverage-gap fix making this test reachable.\n\n[UPDATE 2026-08-30] ROOT-CAUSED, confirmed by direct code reading and cross-checked against a sibling unit test. sched_validate_record_filename() (recording.c)'s canonical-path containment check (path_is_contained() branch, hit when a pre-existing symlink inside record_dir resolves outside it) deliberately returns -EACCES, not -EINVAL -- -EINVAL is reserved for Step 1's malformed-filename check (bare '/' or '..' in the filename itself, rejected before any filesystem access). This is NOT environment-dependent (not a uid-1000-vs-root permission-check ordering issue as originally suspected) -- test_recording_path_validation.c's own direct unit test for the identical scenario (test_symlink_inside_record_dir_escaping_outside_is_rejected) already asserts TEST_ASSERT_EQUAL_INT(-EACCES, rc) and has always passed. The bug was purely in test_admin_request.c's test_recordstart_symlink_escape_replies_error, which asserted the wrong expected error string (\"invalid record file name\", the -EINVAL string) against production code that has always, correctly, returned -EACCES (\"permission denied accessing record file\") for this exact scenario.", + "fix": "FIXED (2026-08-30). Corrected test_recordstart_symlink_escape_replies_error's expected error string in src/scheduler/testsuite/test_admin_request.c from \"invalid record file name\" to \"permission denied accessing record file\", matching the already-correct, already-independently-verified production behavior. No production code changed -- this was purely a wrong test assertion, not a real product bug (the symlink-escape IS correctly rejected; only the test's expectation of WHICH rejection string was wrong). Verified: full `meson test --suite scheduler` run clean, Ok:55 Fail:0, all 55 test binaries pass including sched_admin_request_test (16/16 cases in test_admin_request.c PASS).", "tags": [ "scheduler", "recording", "symlink", "test-failure", "coverage-gap-discovery", - "unresolved", "xce-build.sh", - "set-e-propagation" + "set-e-propagation", + "fixed", + "test-only-bug", + "not-environment-dependent" ], "related_bugs": [ "bug-1559" ], "occurrences": 5, - "last_seen": "2026-08-23T21:53:00Z" + "last_seen": "2026-08-30T08:25:00" }, { "id": "bug-1652", @@ -20056,7 +20058,7 @@ "error_message": "PRIORITY: LOW -- display/reporting only, not consumed by any scheduling logic. Split 2026-08-30 from bug-1735 at user request: the 'statistics-only' half of that finding -- resource usage fields with no scheduling relevance, purely for operator-facing job accounting/reporting (bjobs -l/bhist-style views), as opposed to bug-1735's memory+CPU-time core, which is a prerequisite for future scheduling decisions. Worker (collect_job_rusages(), xcecd_cgroups.c) already measures and sends 'memory_swap' and 'tasks_current' per job, but the controller has NO field to receive them at all (xce_host_runusage_t only has cpu_time/mem_usage -- no swap or task-count field exists) -- these two are silently dropped entirely, not just misnamed. Separately, xce_job_runusage_t's peak/efficiency fields (peak_cpu_time, peak_cpu_duration, mem_efficiency, avg_cpu_efficiency, peak_cpu_efficiency) have no computation logic anywhere in the codebase (grepped) -- nothing populates them, ever, regardless of bug-1735's fix.", "file": "src/worker/src/xcecd_cgroups.c (collect_job_rusages -- already sends memory_swap/tasks_current, no controller-side field to receive them), src/include/xce/types.h (xce_host_runusage_t -- would need new fields for swap/task-count; xce_job_runusage_t -- the peak/efficiency fields with no producer), src/controller/misc.c (update_host_runusage -- would need new parse branches), src/controller/job.c (update_job_rusages -- same open FIXME as bug-1735, this is the other half of what it would need to cover)", "root_cause": "See bug-1735's root_cause for the full original investigation (resname-mismatch mechanism, environment-limitation note re: this session's sandbox having no real cgroup-backed worker to live-verify against) -- this entry covers only the subset of that finding split out as lower-priority. Unlike bug-1735's memory/cpu_time (which have existing-but-mismatched fields), memory_swap/tasks_current have NO receiving field in xce_host_runusage_t at all -- the worker's measurement is a complete dead end on the controller side, not a naming mismatch. The peak/efficiency fields (xce_job_runusage_t's own top-level fields) are simply never computed by anything, anywhere -- confirmed via grep, no partial implementation exists to build on.", - "fix": "NOT FIXED -- low priority, no scheduling impact identified, logged for whenever operator-facing job-accounting/reporting detail becomes a priority. RECOMMENDED SCOPE if picked up: (1) extend xce_host_runusage_t with swap/task-count fields and wire update_host_runusage() to parse 'memory_swap'/'tasks_current' alongside bug-1735's mem/cputime fix; (2) design and implement the peak/efficiency computations (peak_cpu_time/peak_cpu_duration would need tracking the running max across reports, not just the latest value; mem_efficiency/avg_cpu_efficiency/peak_cpu_efficiency need a defined formula against requested resources that doesn't exist yet -- this is closer to a small design task than a bug fix, unlike bug-1735's two clean, well-scoped corrections).", + "fix": "PARTIALLY FIXED (2026-08-30). Of the two gaps this entry covers:\n\n(1) memory_swap/tasks_current -- FIXED. Added mem_swap (double)/tasks_current (int) fields to xce_host_runusage_t (types.h), matching capnp fields (memSwap @3/tasksCurrent @4) appended to the HostRunusage schema (controller.capnp) for WAL field-completeness, parsing in update_host_runusage() (misc.c) for the worker's 'memory_swap'/'tasks_current' resnames, and per-host copy in merge_job_runusage()'s (job.c) existing-host branch (the new fields would otherwise have been silently dropped on WAL replay/catchup for a host already seen).\n\n(2) peak_cpu_time -- FIXED. aggregate_job_runusage() (misc.c) now tracks it as the running MAX of the per-call cpu_time sum across every report a job has ever received (not just the latest), guarding against a later report reducing it (e.g. an out-of-order merge/replay).\n\nSTILL NOT FIXED, DELIBERATELY (documented scope decision, not an oversight -- see aggregate_job_runusage()'s own doc comment in misc.c): peak_cpu_duration and the three efficiency fields (mem_efficiency/avg_cpu_efficiency/peak_cpu_efficiency). These need a 'used vs. requested' ratio against a job's resource request (a resreq expression tree, not a plain core/slot count) and/or an unspecified duration semantic -- genuine product/design decisions, not a formula that can be safely guessed. Left at their existing zero value rather than populated with an invented number that could mislead an operator.\n\nVerified: full `meson test --suite controller` clean, Ok:6 Fail:0, 1220/1220 individual controller_unit_test cases pass (zero regression from touching the shared xce_host_runusage_t struct + its capnp schema), plus 2 new regression tests in test_host_runusage.c (7/7 cases pass).", "tags": [ "worker", "controller", @@ -20067,17 +20069,19 @@ "priority-low", "split-2026-08-30", "no-scheduling-impact", - "unfixed", "static-analysis-only", "unreproduced-in-sandbox", - "needs-owner", - "needs-design-not-just-fix" + "needs-design-not-just-fix", + "partially-fixed", + "peak-cpu-time-fixed", + "swap-taskcount-fixed", + "efficiency-fields-remain-scope-decision" ], "related_bugs": [ "bug-1735" ], "occurrences": 1, - "last_seen": "2026-08-30T10:45:00Z" + "last_seen": "2026-08-30T08:35:00" } ] -} \ No newline at end of file +} diff --git a/.wolf/memory.md b/.wolf/memory.md index da033a48..6ac0fd8c 100644 --- a/.wolf/memory.md +++ b/.wolf/memory.md @@ -3177,3 +3177,15 @@ | 08:03 | Edited src/tools/xce-build.sh | modified 924() | ~444 | | 08:04 | Edited src/tools/xce-build.sh | 3→5 lines | ~23 | | 08:06 | Edited .kiro/specs/scheduler-snapshot-job-allocation/spec.json | 3→3 lines | ~28 | +| 08:17 | Edited src/scheduler/testsuite/test_admin_request.c | expanded (+18 lines) | ~463 | +| 08:18 | Edited src/scheduler/testsuite/test_admin_request.c | 10→11 lines | ~134 | +| 08:20 | Edited src/include/xce/types.h | modified struct() | ~41 | +| 08:20 | Edited src/schema/controller.capnp | modified mapname() | ~85 | +| 08:21 | Edited src/controller/misc.c | added 2 condition(s) | ~216 | +| 08:21 | Edited src/controller/misc.c | added 1 condition(s) | ~740 | +| 08:22 | Edited src/controller/job.c | modified if() | ~128 | +| 08:24 | Edited src/controller/testsuite/test_host_runusage.c | modified 1736() | ~664 | +| 08:24 | Edited src/controller/testsuite/test_host_runusage.c | modified free_usages() | ~264 | +| 08:24 | Edited src/controller/testsuite/test_host_runusage.c | modified test_update_host_runusage_parses_swap_and_task_count() | ~356 | +| 08:25 | Edited src/controller/testsuite/test_host_runusage.c | modified test_aggregate_job_runusage_peak_cpu_time_is_running_max() | ~351 | +| 08:25 | Edited src/controller/testsuite/test_host_runusage.c | 5→7 lines | ~126 |