From 37ea6dfd9f472ce3b54d321e701125592053e422 Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Mon, 7 Sep 2026 07:32:25 +0000 Subject: [PATCH] chore(wolf): update buglog and anatomy/memory index Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01Hb6Edtj4KbS8CrgEWYdA2E --- .wolf/anatomy-index.json | 785 ++++++++++++++++++++++++++++++++++++--- .wolf/anatomy.md | 29 +- .wolf/buglog.json | 83 ++++- .wolf/memory.md | 25 ++ 4 files changed, 857 insertions(+), 65 deletions(-) diff --git a/.wolf/anatomy-index.json b/.wolf/anatomy-index.json index e8095849..4b2fd470 100644 --- a/.wolf/anatomy-index.json +++ b/.wolf/anatomy-index.json @@ -1,13 +1,13 @@ { "version": 1, "meta": { - "lastScanned": "2026-09-07T04:17:59.764Z", - "fileCount": 706, + "lastScanned": "2026-09-07T07:29:49.789Z", + "fileCount": 711, "hits": 0, "misses": 0, - "renderedHash": "5267c12df54187086bad0158fa11abbd2cf8e7aece3e099707e706a283693d81", - "storeUpdatedAt": "2026-09-07T04:17:59.778Z", - "rootHash": "72cd99c2241aeda8" + "renderedHash": "d14f860ae89b35a885d2e4612d53a31be29eab4028ea072b5bae6d742b2fdbf3", + "storeUpdatedAt": "2026-09-07T07:29:49.797Z", + "rootHash": "a91ff63e5c74e285" }, "files": { ".agent-shell/transcripts/2026-08-11-11-39-59.md": { @@ -2857,13 +2857,12 @@ }, ".kiro/specs/scheduler-sim-decision-parity/design.md": { "description": "Design Document", - "tokens": 8189, - "hash": "c0f10508e509eb9d", - "size": 32889, - "mtimeMs": 1787389575523.3215, - "updatedAt": "2026-08-27T19:00:00.118Z", - "source": "scan", - "importance": 0.21 + "tokens": 8526, + "hash": "84516fafffb71103", + "size": 34239, + "mtimeMs": 1788766189747.8567, + "updatedAt": "2026-09-07T07:29:49.789Z", + "source": "hook" }, ".kiro/specs/scheduler-sim-decision-parity/requirements.md": { "description": "Requirements Document, 5 reqs (accounting parity, capacity awareness, decision visibility, graceful degradation, no regression)", @@ -2917,13 +2916,12 @@ }, ".kiro/specs/scheduler-sim-eager-reconciliation/design.md": { "description": "Design Document", - "tokens": 5193, - "hash": "2f0deddaacada768", - "size": 20861, - "mtimeMs": 1787799339843.8738, - "updatedAt": "2026-08-27T19:00:00.123Z", - "source": "scan", - "importance": 0.21 + "tokens": 5580, + "hash": "aeef295f5a43e930", + "size": 22411, + "mtimeMs": 1788766157571.1833, + "updatedAt": "2026-09-07T07:29:17.608Z", + "source": "hook" }, ".kiro/specs/scheduler-sim-eager-reconciliation/requirements.md": { "description": "Requirements Document", @@ -6783,11 +6781,11 @@ }, "src/scheduler/src/repl_info.c": { "description": "include ", - "tokens": 14804, - "hash": "8f0f75bd57d478b4", - "size": 55516, - "mtimeMs": 1788754632921.189, - "updatedAt": "2026-09-07T04:17:12.962Z", + "tokens": 14934, + "hash": "2e5b08a292b497a1", + "size": 56003, + "mtimeMs": 1788764353928.2927, + "updatedAt": "2026-09-07T06:59:13.965Z", "source": "hook" }, "src/scheduler/testsuite/test_repl_breakpoints_inspection.c": { @@ -6918,11 +6916,11 @@ }, "src/scheduler/testsuite/test_sim_verify.c": { "description": "Declares mismatch", - "tokens": 15602, - "hash": "35a3398455a4cdf9", - "size": 58505, - "mtimeMs": 1788163548259.6487, - "updatedAt": "2026-08-31T08:05:48.305Z", + "tokens": 16265, + "hash": "99cce1dd74ef4c9f", + "size": 60991, + "mtimeMs": 1788766035754.3176, + "updatedAt": "2026-09-07T07:27:15.791Z", "source": "hook" }, "src/scheduler/testsuite/test_driver_session_ordering.c": { @@ -8452,20 +8450,20 @@ }, "src/scheduler/src/sim_loop.c": { "description": "include ", - "tokens": 16155, - "hash": "792856cbcc3d7889", - "size": 60578, - "mtimeMs": 1788423981951.631, - "updatedAt": "2026-09-03T08:26:21.990Z", + "tokens": 16693, + "hash": "7cfdd6f959cadb22", + "size": 62596, + "mtimeMs": 1788765932686.9917, + "updatedAt": "2026-09-07T07:25:32.735Z", "source": "hook" }, "src/scheduler/testsuite/test_sim_reconcile_unaccounted.c": { "description": "Declares documents", - "tokens": 24803, - "hash": "81419e83a82af1ab", - "size": 93010, - "mtimeMs": 1788423993650.0215, - "updatedAt": "2026-09-03T08:26:33.691Z", + "tokens": 25802, + "hash": "95b958915c9a4ba8", + "size": 96756, + "mtimeMs": 1788765957298.2698, + "updatedAt": "2026-09-07T07:25:57.332Z", "source": "hook" }, "src/scheduler/testsuite/test_repl_prompt_context.c": { @@ -8515,11 +8513,11 @@ }, "src/scheduler/testsuite/test_repl_resource_table.c": { "description": "Declares char", - "tokens": 16538, - "hash": "a50e8422cb195477", - "size": 62016, - "mtimeMs": 1788754679716.3474, - "updatedAt": "2026-09-07T04:17:59.764Z", + "tokens": 17776, + "hash": "fc0503bc86c77fb7", + "size": 66657, + "mtimeMs": 1788764346825.0894, + "updatedAt": "2026-09-07T06:59:06.872Z", "source": "hook" }, "src/scheduler/testsuite/test_repl_help.c": { @@ -8940,6 +8938,705 @@ "mtimeMs": 1788754505558.337, "updatedAt": "2026-09-07T04:15:05.605Z", "source": "hook" + }, + "src/frontend/apiserver/backend/convert_pure.go": { + "description": "Struct: rawStartInfo", + "tokens": 3703, + "hash": "4b3c499091c70690", + "size": 13905, + "mtimeMs": 1788763406172.03, + "updatedAt": "2026-09-07T06:43:26.217Z", + "source": "hook", + "symbols": [ + { + "name": "extractBits", + "kind": "fn", + "startLine": 32, + "endLine": 38, + "tokens": 65 + }, + { + "name": "extractIDTag", + "kind": "fn", + "startLine": 39, + "endLine": 47, + "tokens": 118 + }, + { + "name": "ExtractArrayBaseID", + "kind": "fn", + "startLine": 48, + "endLine": 66, + "tokens": 234 + }, + { + "name": "ExtractArrayIdx", + "kind": "fn", + "startLine": 67, + "endLine": 75, + "tokens": 83 + }, + { + "name": "IsArrayJob", + "kind": "fn", + "startLine": 76, + "endLine": 83, + "tokens": 99 + }, + { + "name": "FormatJobID", + "kind": "fn", + "startLine": 84, + "endLine": 102, + "tokens": 245 + }, + { + "name": "WorkerDefaultOutputPath", + "kind": "fn", + "startLine": 103, + "endLine": 107, + "tokens": 66 + }, + { + "name": "rawStartInfo", + "kind": "class", + "startLine": 108, + "endLine": 118, + "tokens": 69 + }, + { + "name": "rawSubmitData", + "kind": "class", + "startLine": 119, + "endLine": 137, + "tokens": 164 + }, + { + "name": "rawHostSlot", + "kind": "class", + "startLine": 138, + "endLine": 143, + "tokens": 35 + }, + { + "name": "rawJobData", + "kind": "class", + "startLine": 144, + "endLine": 156, + "tokens": 79 + }, + { + "name": "rawWorkerData", + "kind": "class", + "startLine": 157, + "endLine": 172, + "tokens": 93 + }, + { + "name": "rawQueueData", + "kind": "class", + "startLine": 173, + "endLine": 179, + "tokens": 44 + }, + { + "name": "rawResourceData", + "kind": "class", + "startLine": 180, + "endLine": 190, + "tokens": 76 + }, + { + "name": "rawJobToModel", + "kind": "fn", + "startLine": 191, + "endLine": 257, + "tokens": 690 + }, + { + "name": "rawJobArrayToModels", + "kind": "fn", + "startLine": 258, + "endLine": 277, + "tokens": 149 + }, + { + "name": "rawWorkerToModel", + "kind": "fn", + "startLine": 278, + "endLine": 297, + "tokens": 140 + }, + { + "name": "rawQueueToModel", + "kind": "fn", + "startLine": 298, + "endLine": 306, + "tokens": 70 + }, + { + "name": "rawResourceToModel", + "kind": "fn", + "startLine": 307, + "endLine": 323, + "tokens": 202 + }, + { + "name": "rawHostConfigData", + "kind": "class", + "startLine": 324, + "endLine": 332, + "tokens": 69 + }, + { + "name": "rawHostConfigToModel", + "kind": "fn", + "startLine": 333, + "endLine": 347, + "tokens": 195 + }, + { + "name": "rawResvalData", + "kind": "class", + "startLine": 348, + "endLine": 364, + "tokens": 152 + }, + { + "name": "rawResvalToDistribution", + "kind": "fn", + "startLine": 365, + "endLine": 405, + "tokens": 383 + }, + { + "name": "rawClusterData", + "kind": "class", + "startLine": 406, + "endLine": 414, + "tokens": 79 + }, + { + "name": "rawClusterToModel", + "kind": "fn", + "startLine": 415, + "endLine": 423, + "tokens": 76 + } + ] + }, + "src/frontend/apiserver/backend/convert.go": { + "description": "go:build cgo", + "tokens": 3817, + "hash": "da8348aa056731d3", + "size": 14321, + "mtimeMs": 1788763465603.1243, + "updatedAt": "2026-09-07T06:44:25.652Z", + "source": "hook", + "symbols": [ + { + "name": "goString", + "kind": "fn", + "startLine": 28, + "endLine": 43, + "tokens": 211 + }, + { + "name": "cJobArrayToModels", + "kind": "fn", + "startLine": 44, + "endLine": 78, + "tokens": 311 + }, + { + "name": "cJobToModel", + "kind": "fn", + "startLine": 79, + "endLine": 144, + "tokens": 591 + }, + { + "name": "cWorkerToModel", + "kind": "fn", + "startLine": 145, + "endLine": 176, + "tokens": 260 + }, + { + "name": "cQueueToModel", + "kind": "fn", + "startLine": 177, + "endLine": 185, + "tokens": 86 + }, + { + "name": "cResourceToModel", + "kind": "fn", + "startLine": 186, + "endLine": 197, + "tokens": 109 + }, + { + "name": "cClusterConfQueues", + "kind": "fn", + "startLine": 198, + "endLine": 213, + "tokens": 118 + }, + { + "name": "cClusterConfResources", + "kind": "fn", + "startLine": 214, + "endLine": 229, + "tokens": 128 + }, + { + "name": "cHostConfigToModel", + "kind": "fn", + "startLine": 230, + "endLine": 239, + "tokens": 95 + }, + { + "name": "cClusterConfHostConfigs", + "kind": "fn", + "startLine": 240, + "endLine": 257, + "tokens": 186 + }, + { + "name": "cClusterConfToClusterInfo", + "kind": "fn", + "startLine": 258, + "endLine": 272, + "tokens": 171 + }, + { + "name": "modelJobToSubmit", + "kind": "fn", + "startLine": 273, + "endLine": 323, + "tokens": 412 + }, + { + "name": "freeJobSubmit", + "kind": "fn", + "startLine": 324, + "endLine": 349, + "tokens": 250 + }, + { + "name": "cNameValToWorkerResval", + "kind": "fn", + "startLine": 350, + "endLine": 399, + "tokens": 495 + }, + { + "name": "cResvalToDistribution", + "kind": "fn", + "startLine": 400, + "endLine": 445, + "tokens": 470 + } + ] + }, + "src/frontend/xcecli/models/hosts.go": { + "description": "Struct: HostsResponse", + "tokens": 1435, + "hash": "830f1a678cfae5df", + "size": 5378, + "mtimeMs": 1788763620515.901, + "updatedAt": "2026-09-07T06:47:00.553Z", + "source": "hook", + "symbols": [ + { + "name": "HostsResponse", + "kind": "class", + "startLine": 66, + "endLine": 76, + "tokens": 82 + }, + { + "name": "XCEHost", + "kind": "class", + "startLine": 77, + "endLine": 110, + "tokens": 444 + }, + { + "name": "ResourceDistributionInfo", + "kind": "class", + "startLine": 111, + "endLine": 131, + "tokens": 194 + }, + { + "name": "SchedStop", + "kind": "class", + "startLine": 132, + "endLine": 138, + "tokens": 52 + }, + { + "name": "HostControlRequest", + "kind": "class", + "startLine": 139, + "endLine": 144, + "tokens": 75 + }, + { + "name": "HostControlResponse", + "kind": "class", + "startLine": 145, + "endLine": 151, + "tokens": 51 + }, + { + "name": "HostControlResponseItem", + "kind": "class", + "startLine": 152, + "endLine": 156, + "tokens": 31 + }, + { + "name": "UnmarshalJSON", + "kind": "fn", + "startLine": 157, + "endLine": 166, + "tokens": 54 + }, + { + "name": "ResReqSelectRequest", + "kind": "class", + "startLine": 167, + "endLine": 173, + "tokens": 59 + } + ] + }, + "src/frontend/xcecli/common/output/page_print_hosts.go": { + "description": "Struct: HostsPagePrinter", + "tokens": 3340, + "hash": "d94c4600da3e6bbb", + "size": 12524, + "mtimeMs": 1788763692686.0151, + "updatedAt": "2026-09-07T06:48:12.720Z", + "source": "hook", + "symbols": [ + { + "name": "formatHostResourceBytesHuman", + "kind": "fn", + "startLine": 13, + "endLine": 26, + "tokens": 138 + }, + { + "name": "hostResourceValue", + "kind": "fn", + "startLine": 27, + "endLine": 44, + "tokens": 244 + }, + { + "name": "formatHostLoadValue", + "kind": "fn", + "startLine": 45, + "endLine": 65, + "tokens": 156 + }, + { + "name": "HostsPagePrinter", + "kind": "class", + "startLine": 66, + "endLine": 70, + "tokens": 22 + }, + { + "name": "NewHostsPagePrinter", + "kind": "fn", + "startLine": 71, + "endLine": 77, + "tokens": 49 + }, + { + "name": "PrepareForPrinting", + "kind": "fn", + "startLine": 78, + "endLine": 95, + "tokens": 110 + }, + { + "name": "prepareFieldFormats", + "kind": "fn", + "startLine": 96, + "endLine": 123, + "tokens": 234 + }, + { + "name": "initColumnWidths", + "kind": "fn", + "startLine": 124, + "endLine": 167, + "tokens": 366 + }, + { + "name": "PrintPage", + "kind": "fn", + "startLine": 168, + "endLine": 198, + "tokens": 157 + }, + { + "name": "formatRows", + "kind": "fn", + "startLine": 199, + "endLine": 258, + "tokens": 625 + }, + { + "name": "printJsonPage", + "kind": "fn", + "startLine": 259, + "endLine": 269, + "tokens": 97 + }, + { + "name": "printHostsVerboseOutput", + "kind": "fn", + "startLine": 270, + "endLine": 412, + "tokens": 1284 + }, + { + "name": "max", + "kind": "fn", + "startLine": 413, + "endLine": 419, + "tokens": 18 + } + ] + }, + "src/frontend/apiserver/backend/convert_test.go": { + "description": "TestRawJobToModel_BasicFields, TestRawJobToModel_ExecHostsUsesRealPerHostSlotCount, TestRawJobToMode", + "tokens": 7765, + "hash": "58a066620aa7f6c9", + "size": 29128, + "mtimeMs": 1788763949906.6748, + "updatedAt": "2026-09-07T06:52:29.942Z", + "source": "hook", + "symbols": [ + { + "name": "TestRawJobToModel_BasicFields", + "kind": "fn", + "startLine": 9, + "endLine": 69, + "tokens": 518 + }, + { + "name": "TestRawJobToModel_ExecHostsUsesRealPerHostSlotCount", + "kind": "fn", + "startLine": 70, + "endLine": 105, + "tokens": 336 + }, + { + "name": "TestRawJobToModel_ExecHostsPreservesPerHostSlotCountsAcrossHosts", + "kind": "fn", + "startLine": 106, + "endLine": 140, + "tokens": 317 + }, + { + "name": "TestRawJobToModel_FromHost_EmptySafe", + "kind": "fn", + "startLine": 141, + "endLine": 153, + "tokens": 83 + }, + { + "name": "TestRawJobToModel_NilSubmit", + "kind": "fn", + "startLine": 154, + "endLine": 166, + "tokens": 98 + }, + { + "name": "TestRawJobToModel_Timestamps", + "kind": "fn", + "startLine": 167, + "endLine": 191, + "tokens": 181 + }, + { + "name": "TestRawWorkerToModel_BasicFields", + "kind": "fn", + "startLine": 192, + "endLine": 231, + "tokens": 280 + }, + { + "name": "TestRawWorkerToModel_NoAttrs", + "kind": "fn", + "startLine": 232, + "endLine": 247, + "tokens": 130 + }, + { + "name": "TestRawQueueToModel_BasicFields", + "kind": "fn", + "startLine": 248, + "endLine": 267, + "tokens": 131 + }, + { + "name": "TestRawResourceToModel_BasicFields", + "kind": "fn", + "startLine": 268, + "endLine": 297, + "tokens": 243 + }, + { + "name": "makeJobID", + "kind": "fn", + "startLine": 298, + "endLine": 305, + "tokens": 63 + }, + { + "name": "TestExtractBits", + "kind": "fn", + "startLine": 306, + "endLine": 313, + "tokens": 62 + }, + { + "name": "TestExtractIDTag_NonArray", + "kind": "fn", + "startLine": 314, + "endLine": 320, + "tokens": 56 + }, + { + "name": "TestExtractIDTag_Array", + "kind": "fn", + "startLine": 321, + "endLine": 327, + "tokens": 62 + }, + { + "name": "TestExtractArrayBaseID_NonArray", + "kind": "fn", + "startLine": 328, + "endLine": 340, + "tokens": 111 + }, + { + "name": "TestExtractArrayBaseID_ArrayChild", + "kind": "fn", + "startLine": 341, + "endLine": 363, + "tokens": 253 + }, + { + "name": "TestExtractArrayIdx_MaxIndex", + "kind": "fn", + "startLine": 364, + "endLine": 375, + "tokens": 105 + }, + { + "name": "TestExtractArrayBaseID_RoundTrip", + "kind": "fn", + "startLine": 376, + "endLine": 401, + "tokens": 284 + }, + { + "name": "TestRawJobToModel_NonArrayJob", + "kind": "fn", + "startLine": 402, + "endLine": 418, + "tokens": 159 + }, + { + "name": "TestRawJobToModel_ArrayChild", + "kind": "fn", + "startLine": 419, + "endLine": 440, + "tokens": 219 + }, + { + "name": "TestRawJobToModel_ArrayChildrenShareBaseID", + "kind": "fn", + "startLine": 441, + "endLine": 468, + "tokens": 337 + }, + { + "name": "TestExtractArrayBaseID_LargeTimestamp", + "kind": "fn", + "startLine": 469, + "endLine": 499, + "tokens": 352 + }, + { + "name": "TestIsArrayJob", + "kind": "fn", + "startLine": 500, + "endLine": 521, + "tokens": 208 + }, + { + "name": "TestRawHostConfigToModel", + "kind": "fn", + "startLine": 522, + "endLine": 629, + "tokens": 812 + }, + { + "name": "TestRawResvalToDistribution_FloatValue", + "kind": "fn", + "startLine": 630, + "endLine": 657, + "tokens": 223 + }, + { + "name": "TestRawResvalToDistribution_StringValue", + "kind": "fn", + "startLine": 658, + "endLine": 676, + "tokens": 150 + }, + { + "name": "TestRawResvalToDistribution_BooleanValue", + "kind": "fn", + "startLine": 677, + "endLine": 695, + "tokens": 141 + }, + { + "name": "TestRawResvalToDistribution_Int32Value", + "kind": "fn", + "startLine": 696, + "endLine": 714, + "tokens": 145 + }, + { + "name": "TestRawResvalToDistribution_Int64Value", + "kind": "fn", + "startLine": 715, + "endLine": 733, + "tokens": 175 + }, + { + "name": "TestRawResvalToDistribution_Uint32Value", + "kind": "fn", + "startLine": 734, + "endLine": 963, + "tokens": 2067 + } + ] } } } \ No newline at end of file diff --git a/.wolf/anatomy.md b/.wolf/anatomy.md index 13f778ce..050904a3 100644 --- a/.wolf/anatomy.md +++ b/.wolf/anatomy.md @@ -1,7 +1,7 @@ # anatomy.md -> Auto-maintained by OpenWolf. Last scanned: 2026-09-07T04:17:59.764Z -> Files: 706 tracked | Anatomy hits: 0 | Misses: 0 +> Auto-maintained by OpenWolf. Last scanned: 2026-09-07T07:29:49.789Z +> Files: 711 tracked | Anatomy hits: 0 | Misses: 0 ## ./ @@ -499,7 +499,7 @@ ## .kiro/specs/scheduler-sim-decision-parity/ - `brief.md` — Brief: scheduler-sim-decision-parity (~2025 tok) -- `design.md` — Design Document (~8189 tok) +- `design.md` — Design Document (~8526 tok) - `requirements.md` — Requirements Document, 5 reqs (accounting parity, capacity awareness, decision visibility, graceful degradation, no regression) (~1652 tok) - `research.md` — Research & Design Decisions (~2853 tok) - `spec.json` (~134 tok) @@ -513,7 +513,7 @@ ## .kiro/specs/scheduler-sim-eager-reconciliation/ -- `design.md` — Design Document (~5193 tok) +- `design.md` — Design Document (~5580 tok) - `requirements.md` — Requirements Document (~2312 tok) - `research.md` — Research & Design Decisions (~4657 tok) - `spec.json` (~135 tok) @@ -924,6 +924,9 @@ ## src/frontend/apiserver/backend/ +- `convert_pure.go` — Struct: rawStartInfo (~3703 tok) +- `convert_test.go` — TestRawJobToModel_BasicFields, TestRawJobToModel_ExecHostsUsesRealPerHostSlotCount, TestRawJobToMode (~7765 tok) +- `convert.go` — go:build cgo (~3817 tok) - `handler.go` — Struct: DefaultHandler (~3107 tok) ## src/frontend/apiserver/cmd/ @@ -949,6 +952,14 @@ - `main.go` (~1160 tok) +## src/frontend/xcecli/common/output/ + +- `page_print_hosts.go` — Struct: HostsPagePrinter (~3340 tok) + +## src/frontend/xcecli/models/ + +- `hosts.go` — Struct: HostsResponse (~1435 tok) + ## src/include/ - `client.h` — if !defined(_CLIENT_H_) (~2478 tok) @@ -997,7 +1008,7 @@ - `repl_bp_kind.c` — include (~979 tok) - `repl_break.c` — include (~9921 tok) - `repl_fmt.c` — include (~3971 tok) -- `repl_info.c` — include (~14804 tok) +- `repl_info.c` — include (~14934 tok) - `repl_internal.h` — if !defined(_REPL_INTERNAL_H_) (~7113 tok) - `repl_jobid_range.c` — include (~2916 tok) - `repl_params.c` — include (~4864 tok) @@ -1006,7 +1017,7 @@ - `resource.c` — include (~6852 tok) - `schedobj.c` — include (~5151 tok) - `scheduler.c` — include (~16542 tok) -- `sim_loop.c` — include (~16155 tok) +- `sim_loop.c` — include (~16693 tok) - `snapshot_load.c` — include (~5920 tok) - `snapshot.c` — include (~8498 tok) @@ -1033,7 +1044,7 @@ - `test_repl_output_compression.c` — Declares under (~3851 tok) - `test_repl_prompt_context.c` — Declares char (~6687 tok) - `test_repl_resource_formatting.c` — Declares design (~4465 tok) -- `test_repl_resource_table.c` — Declares char (~16538 tok) +- `test_repl_resource_table.c` — Declares char (~17776 tok) - `test_repl_round_rollup.c` — Declares char (~10735 tok) - `test_repl_snapshot_params.c` — Declares char (~10134 tok) - `test_repl_step_verbosity.c` — Declares unconditionally (~11316 tok) @@ -1048,12 +1059,12 @@ - `test_sim_event_loop.c` — Declares char (~9504 tok) - `test_sim_isolation.c` — Declares names (~8548 tok) - `test_sim_print_decision_gate.c` — Declares char (~7154 tok) -- `test_sim_reconcile_unaccounted.c` — Declares documents (~24803 tok) +- `test_sim_reconcile_unaccounted.c` — Declares documents (~25802 tok) - `test_sim_record_output.c` — Declares char (~6041 tok) - `test_sim_session_ordering.c` (~8267 tok) - `test_sim_snapshot_reconcile_gap.c` — Declares char (~6308 tok) - `test_sim_startup.c` — Declares char (~5708 tok) -- `test_sim_verify.c` — Declares mismatch (~15602 tok) +- `test_sim_verify.c` — Declares mismatch (~16265 tok) - `test_snapshot_save_load.c` (~28712 tok) ## src/schema/ diff --git a/.wolf/buglog.json b/.wolf/buglog.json index 2b92e227..281a546f 100644 --- a/.wolf/buglog.json +++ b/.wolf/buglog.json @@ -20703,22 +20703,24 @@ "timestamp": "2026-09-02T03:47:00Z", "error_message": "Live simulation run (xce_scheduler --sim, user-observed, not reproduced by me in this session) shows a JOBS_PUSH batch of 50 jobs where the first 22 (indices [0]-[21]) receive [sim] DISPATCH decisions, immediately followed by [sim] PEND decisions for ALL 50 jobs (indices [0]-[49]) -- including the 22 that had JUST been dispatched. Design expectation (confirmed correct, see root_cause): a job that has received a DISPATCH decision must be treated as RUN immediately, without waiting for any downstream job-start acknowledgment, and must never be reconsidered as a fresh scheduling candidate afterward -- in BOTH the live scheduler and simulation/replay mode.", "file": "src/scheduler/src/sim_loop.c, src/scheduler/src/plugins/builtin_fcfs.c, src/scheduler/src/scheduler.c", - "root_cause": "NOT YET ROOT-CAUSED -- logged from a live-observed symptom, investigated only via static code reading this session (no live repro attempted), per explicit instruction to log and defer rather than context-switch into a full debug pass. Confirmed via source read: sched_commit_decision() (scheduler.c:1435-1455) DOES set job->state = JOB_STAT_RUN synchronously at the moment a DISPATCH decision is committed, with no wait for any job-start ack -- this is shared code (sched_allocator()/sched_commit_decision()) used by BOTH the normal-mode driver and the sim driver alike (scheduler/CLAUDE.md: \"Both drive the identical core session/decision-callback protocol\"), so the intended \"dispatch implies RUN, immediately\" design IS mechanically implemented at this layer already -- this is not a missing feature. builtin_fcfs.c's on_dispatch() carries its own documented, pre-existing concurrency-hazard comment (\"this runs in the allocator thread and can race the picker thread's next_job() -- jbuf's capacity-1 handoff unblocks the picker for job N+1 before this call for job N returns\"), guarded by fcfs_plugin_data_t.lock for candidate-list mutations, but reading the code alone does not confirm whether that race (or something else -- e.g. two back-to-back sim sessions/rounds failing to preserve job->state or the picker's candidate set between them) is what produces ALL 50 jobs reappearing in one PEND batch, including the 22 already-dispatched ones. Related prior findings: bug-1567 (fixed 2026-08-17) documented that simulation mode ONCE unconditionally PENDed every candidate with no real dispatch at all, deliberately deferred to a then-not-yet-designed scheduler-allocation spec -- the pasted live log now shows genuine DISPATCH decisions in sim mode, meaning that gap has since been closed (scheduler-sim-decision-parity, referenced by bug-1623, 2026-08-22, looks like the likely spec, not yet confirmed which task/commit). bug-1623 also documents sim_loop.c's sim_reconcile_unaccounted_jobs() logic (per-round decoded-decision matching for RUN-state unaccounted jobs) as a separate, related mechanism in the same file worth checking during a real debug pass.", - "fix": "NOT FIXED -- deliberately deferred per explicit instruction (log and continue other work, do not context-switch into a full debug pass now). Needs a dedicated investigation (e.g. /kiro-debug) scoped to sim_loop.c's session/round-driving loop to determine: (a) whether this is one scheduling session emitting a genuine duplicate/second decision for already-dispatched jobs (a real bug in the shared allocator/picker pipeline or in sim_loop.c's own session driving), or two distinct back-to-back sessions where job->state / the picker's candidate set was not correctly carried over between them; (b) whether the identical scenario is reproducible against the NORMAL-mode driver (scheduler.c/driver.c), which would point at the shared sched_allocator/builtin_fcfs code rather than anything sim-specific, or whether it only reproduces in --sim, which would point at sim_loop.c's own session/round handling (possibly interacting with bug-1623's sim_reconcile_unaccounted_jobs()). A live, controlled repro (fixed job count, fixed resource limits, single JOBS_PUSH batch, --sim-verify or a new targeted unit test) should be built first rather than relying on the user's own live-run log.", + "root_cause": "ROOT-CAUSED FOR REAL (2026-09-07), and turns out to be a SPEC CONFLICT, not a logic bug -- a patch was attempted and REVERTED after it broke a pre-existing, passing regression test. Confirmed mechanism: sim mode's REAL DISPATCH decisions come entirely from sim_reconcile_unaccounted_jobs() (sim_loop.c), which reconstructs a job's dispatch PURELY from replay data (populating job->allocs/job->accounts, reporting a synthesized DISPATCH decision) but never calls picker->picker_iface->on_dispatch() -- unlike the real/live allocator path (sched_allocator(), scheduler.c line 507-510), which ALWAYS calls on_dispatch() to retire the job from the picker's own candidate list (fcfs_queue_t.pendJobs) before building the decision. Because reconciliation skips this, the job stays a live candidate in the picker's bookkeeping. sim_picker_thread_fn() (sim_loop.c) -- a SEPARATE, always-running thread that walks next_job() every round and unconditionally PENDs whatever it is still offered, since it has no real resource-matching allocation of its own -- keeps re-offering and re-PENDing that job every subsequent round until an explicit JOB_STATE_CHANGE-to-RUN event (also replayed from the original recording, can legitimately arrive several rounds later) removes it from pendJobs via builtin_fcfs_on_job_state_change(). CRITICAL DISCOVERY: this exact behavior is NOT accidental -- it is DOCUMENTED, INTENTIONAL, and covered by an existing passing test, test_sim_verify_no_false_mismatch_across_round_separated_dispatch (test_sim_verify.c, scheduler-sim-eager-reconciliation spec task 3.2), whose own header comment states verbatim: 'sim_reconcile_unaccounted_jobs() captures job->accounts but never calls picker_iface->on_dispatch() to retire the job from the picker's own internal pendJobs (design.md's Non-Goals/Revalidation Triggers explicitly leave live-picker DISPATCH emission to a future scheduler-allocation spec)'. That spec's own design.md (.kiro/specs/scheduler-sim-eager-reconciliation/design.md, Non-Goals section) explicitly lists 'Any change to simulation mode's live picker (still PEND-only for freshly-arriving jobs, per scheduler-allocation)' as OUT OF SCOPE. A fix attempt (calling on_dispatch() from the reconciliation FOUND branch, mirroring sched_allocator()'s exact ordering) was implemented with a new TDD test, confirmed the bug reproduces deterministically (RED), and confirmed the fix resolves it (GREEN) -- but broke test_sim_verify_no_false_mismatch_across_round_separated_dispatch, whose fixture explicitly bakes in 'PEND(jobid) recorded in the SAME round as its own DISPATCH, and again for every round until the RUN confirmation arrives' as the CORRECT, expected --sim-verify-clean shape. The fix was REVERTED (both the sim_loop.c change and its new test) rather than kept, since it silently violates an already-agreed, tested design contract from a sibling spec.", + "fix": "FIXED FOR REAL (2026-09-07), after a first fix attempt was correctly reverted (see prior root_cause note) upon discovering it broke test_sim_verify_no_false_mismatch_across_round_separated_dispatch. That test's OWN fixture turned out to be baking in the bug's exact symptom as 'expected' -- but its parent spec's own design.md ('Integration with --sim-verify') already documented the CORRECT assumption ('the picker never re-decides an already-resolved job'), which the implementation had silently drifted from. This was a genuine implementation/test drift from an already-agreed design intent, not a live spec conflict requiring a product decision -- confirmed by re-reading both scheduler-sim-decision-parity's and scheduler-sim-eager-reconciliation's own design.md files (both updated in place with 2026-09-07 correction notes explaining this). Fix: sim_reconcile_unaccounted_jobs() (sim_loop.c) now resolves the job picker and calls picker_iface->on_dispatch() immediately after reconstructing job->allocs/job->accounts in its FOUND branch, mirroring sched_allocator()'s own live-dispatch ordering (scheduler.c line 507-515) exactly. This retires the reconciled job from the picker's own pendJobs bookkeeping the moment its dispatch is reconstructed, so sim_picker_thread_fn()'s unconditional-PEND thread never re-offers/re-PENDs it on a later round. TDD: new test test_reconcile_removes_reconciled_job_from_picker_candidates (test_sim_reconcile_unaccounted.c) directly proves a job is no longer offered by next_job() after reconciliation, using sim_bootstrap_picker() to register a real, resolvable builtin_fcfs instance -- confirmed RED before the fix, GREEN after. test_sim_verify_no_false_mismatch_across_round_separated_dispatch (test_sim_verify.c) was updated to match the corrected behavior: round 1 now records DISPATCH-only (new helper append_replay_session_with_dispatch(), no accompanying PEND), and rounds 2-3 are now empty ReplaySessions (matching round 4's own existing pattern) instead of baking in a stale re-PEND echo as expected. Full scheduler suite: 76/77 pass (same pre-existing unrelated test_core_events.c failure, bug-1762, untouched by this fix).", "tags": [ + "builtin_fcfs", + "discovered-live", + "dispatch", + "dispatch-implies-run", + "fixed", + "job-state", + "needs-debug", + "pend", + "race-condition-suspected", "scheduler", + "scheduler-allocation", "sim-mode", "sim_loop-c", - "builtin_fcfs", - "dispatch", - "pend", - "job-state", - "dispatch-implies-run", - "race-condition-suspected", - "needs-debug", - "discovered-live", - "user-reported", - "not-fixed" + "spec-conflict", + "user-reported" ], "related_bugs": [ "bug-1567", @@ -21124,6 +21126,63 @@ ], "occurrences": 1, "last_seen": "2026-09-06T21:10:00Z" + }, + { + "id": "bug-1778", + "timestamp": "2026-09-07T06:50:00Z", + "error_message": "Live-observed (interactive sim session=29, replaying a real captured trace): three plain (non-array) jobs already at JOB_STAT_DONE (0-14-1788751409-0, 0-14-1788751435-0, 0-14-1788751504-0) still appear in `info worker pc13v`'s 'assigned jobs' listing (each annotated '*2' via bug-1776's slot-count fix), alongside the genuinely-running array job elements. User: 'The finished job(exit/done) should be de-assign from worker.'", + "file": "src/scheduler/src/repl_info.c", + "root_cause": "PARTIALLY CONFIRMED, NOT FULLY ROOT-CAUSED this session (user asked to record, not fix). Confirmed facts: (1) repl_info_worker_one()'s assigned-jobs loop (repl_info.c, ~line 686) gates solely on `job->allocs != NULL`, with no independent job->state check -- if allocs is non-NULL for a terminal job, it will always display, by design (mirrors the exact structural gap bug-1764 already documented for this same function). (2) The worker's ACTUAL resource accounting is NOT confused by this: the same session's 'resource slots: value=22.00 used=20.00' correctly reflects only the 5 genuinely-running 4-slot array elements (5*4=20), excluding the 3 DONE jobs entirely -- proving core.resmgr/resInUse (the real admission-control state) is fine; only the assigned-jobs DISPLAY loop (which walks job->allocs directly, a separate field) is stale for these 3 jobs. (3) This is NOT a regression of bug-1764's fix: verified sim_loop.c:713-714 still correctly excludes JOB_IS_DONE(job->state)||JOB_IS_EXIT(job->state) from sim_reconcile_unaccounted_jobs()'s resurrection path, so that specific documented mechanism is not what's reintroducing these allocs. (4) core_events.c's XCE_CORE_EVENT_JOB_STATE_CHANGE (line ~1155-1163) and XCE_CORE_EVENT_JOB_UPDATE (line ~1207-1215) handlers both correctly free_JobAlloc_ptr()+null job->allocs atomically alongside the state write whenever `!JOB_IS_RUN(new_state)` -- so if either of THESE handlers was what drove these 3 jobs to DONE, allocs should already be NULL; something else must be true. Leading unconfirmed hypothesis: snapshot_load.c:490-493 deep-copies wj->allocs from the .replay snapshot's wire payload UNCONDITIONALLY whenever wj->allocs != NULL, with no check against the snapshot's own wj->state -- if the live production recording's snapshot-capture moment (snapshot_wire.c's save side) captured these 3 jobs' allocs and state in a mutually inconsistent way (e.g. a save-time field-read ordering gap, or the snapshot genuinely predates their JOB_STATE_CHANGE/JOB_UPDATE terminal cleanup while a separately-recorded later event updated state to DONE without a matching allocs-clearing event reaching this replay stream), the replay would faithfully reproduce that inconsistency verbatim. NOT verified with a live trace/gdb this session -- flagged per this project's own persistence.md field-completeness concern (a state that 'recovers correctly' while an unrelated field goes stale is the exact class of bug that steering calls out), not asserted as confirmed.", + "fix": "INTERIM DISPLAY-LAYER MITIGATION APPLIED (2026-09-07, per user request). repl_info_worker_one()'s assigned-jobs loop (repl_info.c) now also excludes JOB_IS_DONE(job->state) || JOB_IS_EXIT(job->state), in addition to the existing job->allocs != NULL check -- mirrors the same 'terminal is permanent' guard job_state_regresses_terminal()/sim_reconcile_unaccounted_jobs() already apply elsewhere. TDD: new test test_info_worker_assigned_job_listing_excludes_terminal_job_despite_stale_allocs (test_repl_resource_table.c) directly assigns the SAME allocs struct to a DONE job and a RUN job on the same worker, forcing the DONE job's state after assigning allocs (reproducing the exact state/allocs inconsistency without needing to root-cause how it arises live) -- confirms the DONE job is excluded while the RUN job still shows. Full scheduler suite: 76/77 pass (same pre-existing unrelated test_core_events.c failure as before, bug-1762). NOTE: this masks the symptom at the display layer only -- the underlying question of WHY job->allocs stays non-NULL for a terminal job (suspected snapshot save/load inconsistency) remains unresolved; a real fix should also prevent/clear the stale allocs at its source.", + "tags": [ + "job-lifecycle", + "stale-state", + "repl", + "snapshot", + "scheduler", + "related-to-bug-1776", + "assigned-jobs", + "persistence", + "needs-live-repro", + "related-to-bug-1764", + "interim-fix", + "sim", + "fixed" + ], + "related_bugs": [ + "bug-1764", + "bug-1776" + ], + "occurrences": 1, + "last_seen": "2026-09-07T06:50:00Z" + }, + { + "id": "bug-1779", + "timestamp": "2026-09-07T06:58:00Z", + "error_message": "Live-observed (interactive sim session=19, replaying a real captured trace, 'step 9'): within the SAME batch of scheduler decisions, jobs 0-12-1788762745-0[0..4] receive a DISPATCH decision, then immediately ALSO receive a PEND decision in the same step's output -- and `info jobs` afterward shows all 10 array elements (0-12-1788762745-0[0..9]) as PEND, including the 5 that were just dispatched. User: 'when a job has been dispatched (in scheduler), we should treat it as RUN, so it should be excluded from PEND ... we need to remove 0-12-1788762745-0[0-4] from PEND but show in RUN.'", + "file": "src/scheduler/src/sim_loop.c", + "root_cause": "ROOT-CAUSED FOR REAL (2026-09-07), and turns out to be a SPEC CONFLICT, not a logic bug -- a patch was attempted and REVERTED after it broke a pre-existing, passing regression test. Confirmed mechanism: sim mode's REAL DISPATCH decisions come entirely from sim_reconcile_unaccounted_jobs() (sim_loop.c), which reconstructs a job's dispatch PURELY from replay data (populating job->allocs/job->accounts, reporting a synthesized DISPATCH decision) but never calls picker->picker_iface->on_dispatch() -- unlike the real/live allocator path (sched_allocator(), scheduler.c line 507-510), which ALWAYS calls on_dispatch() to retire the job from the picker's own candidate list (fcfs_queue_t.pendJobs) before building the decision. Because reconciliation skips this, the job stays a live candidate in the picker's bookkeeping. sim_picker_thread_fn() (sim_loop.c) -- a SEPARATE, always-running thread that walks next_job() every round and unconditionally PENDs whatever it is still offered, since it has no real resource-matching allocation of its own -- keeps re-offering and re-PENDing that job every subsequent round until an explicit JOB_STATE_CHANGE-to-RUN event (also replayed from the original recording, can legitimately arrive several rounds later) removes it from pendJobs via builtin_fcfs_on_job_state_change(). CRITICAL DISCOVERY: this exact behavior is NOT accidental -- it is DOCUMENTED, INTENTIONAL, and covered by an existing passing test, test_sim_verify_no_false_mismatch_across_round_separated_dispatch (test_sim_verify.c, scheduler-sim-eager-reconciliation spec task 3.2), whose own header comment states verbatim: 'sim_reconcile_unaccounted_jobs() captures job->accounts but never calls picker_iface->on_dispatch() to retire the job from the picker's own internal pendJobs (design.md's Non-Goals/Revalidation Triggers explicitly leave live-picker DISPATCH emission to a future scheduler-allocation spec)'. That spec's own design.md (.kiro/specs/scheduler-sim-eager-reconciliation/design.md, Non-Goals section) explicitly lists 'Any change to simulation mode's live picker (still PEND-only for freshly-arriving jobs, per scheduler-allocation)' as OUT OF SCOPE. A fix attempt (calling on_dispatch() from the reconciliation FOUND branch, mirroring sched_allocator()'s exact ordering) was implemented with a new TDD test, confirmed the bug reproduces deterministically (RED), and confirmed the fix resolves it (GREEN) -- but broke test_sim_verify_no_false_mismatch_across_round_separated_dispatch, whose fixture explicitly bakes in 'PEND(jobid) recorded in the SAME round as its own DISPATCH, and again for every round until the RUN confirmation arrives' as the CORRECT, expected --sim-verify-clean shape. The fix was REVERTED (both the sim_loop.c change and its new test) rather than kept, since it silently violates an already-agreed, tested design contract from a sibling spec.", + "fix": "FIXED FOR REAL (2026-09-07), after a first fix attempt was correctly reverted (see prior root_cause note) upon discovering it broke test_sim_verify_no_false_mismatch_across_round_separated_dispatch. That test's OWN fixture turned out to be baking in the bug's exact symptom as 'expected' -- but its parent spec's own design.md ('Integration with --sim-verify') already documented the CORRECT assumption ('the picker never re-decides an already-resolved job'), which the implementation had silently drifted from. This was a genuine implementation/test drift from an already-agreed design intent, not a live spec conflict requiring a product decision -- confirmed by re-reading both scheduler-sim-decision-parity's and scheduler-sim-eager-reconciliation's own design.md files (both updated in place with 2026-09-07 correction notes explaining this). Fix: sim_reconcile_unaccounted_jobs() (sim_loop.c) now resolves the job picker and calls picker_iface->on_dispatch() immediately after reconstructing job->allocs/job->accounts in its FOUND branch, mirroring sched_allocator()'s own live-dispatch ordering (scheduler.c line 507-515) exactly. This retires the reconciled job from the picker's own pendJobs bookkeeping the moment its dispatch is reconstructed, so sim_picker_thread_fn()'s unconditional-PEND thread never re-offers/re-PENDs it on a later round. TDD: new test test_reconcile_removes_reconciled_job_from_picker_candidates (test_sim_reconcile_unaccounted.c) directly proves a job is no longer offered by next_job() after reconciliation, using sim_bootstrap_picker() to register a real, resolvable builtin_fcfs instance -- confirmed RED before the fix, GREEN after. test_sim_verify_no_false_mismatch_across_round_separated_dispatch (test_sim_verify.c) was updated to match the corrected behavior: round 1 now records DISPATCH-only (new helper append_replay_session_with_dispatch(), no accompanying PEND), and rounds 2-3 are now empty ReplaySessions (matching round 4's own existing pattern) instead of baking in a stale re-PEND echo as expected. Full scheduler suite: 76/77 pass (same pre-existing unrelated test_core_events.c failure, bug-1762, untouched by this fix).", + "tags": [ + "array-job", + "builtin_fcfs", + "decision", + "dispatch", + "fixed", + "job-lifecycle", + "needs-live-repro", + "pend", + "picker", + "scheduler", + "scheduler-allocation", + "sim", + "spec-conflict" + ], + "related_bugs": [ + "bug-1778" + ], + "occurrences": 1, + "last_seen": "2026-09-07T06:58:00Z" } ] } diff --git a/.wolf/memory.md b/.wolf/memory.md index b9ba5077..f5cdc6b1 100644 --- a/.wolf/memory.md +++ b/.wolf/memory.md @@ -4282,3 +4282,28 @@ | 21:17 | Edited src/scheduler/src/repl_info.c | added 3 condition(s) | ~1126 | | 21:17 | Edited src/scheduler/testsuite/test_repl_resource_table.c | modified request() | ~2292 | | 21:17 | Edited src/scheduler/testsuite/test_repl_resource_table.c | 2→4 lines | ~94 | +| 23:43 | Edited src/frontend/apiserver/backend/convert_pure.go | expanded (+10 lines) | ~172 | +| 23:43 | Edited src/frontend/apiserver/backend/convert_pure.go | 4→4 lines | ~39 | +| 23:44 | Edited src/frontend/apiserver/backend/convert.go | modified job_alloc_host() | ~114 | +| 23:44 | Edited src/frontend/apiserver/backend/convert.go | expanded (+15 lines) | ~211 | +| 23:47 | Edited src/frontend/xcecli/models/hosts.go | expanded (+18 lines) | ~250 | +| 23:47 | Edited src/frontend/xcecli/common/output/page_print_hosts.go | modified formatHostResourceBytesHuman() | ~567 | +| 23:48 | Edited src/frontend/xcecli/common/output/page_print_hosts.go | expanded (+17 lines) | ~312 | +| 23:52 | Edited src/frontend/apiserver/backend/convert_test.go | modified TestRawJobToModel_ExecHostsUsesRealPerHostSlotCount() | ~667 | +| 23:52 | Edited src/frontend/apiserver/backend/convert_test.go | 4→5 lines | ~16 | +| 23:59 | Edited src/scheduler/testsuite/test_repl_resource_table.c | modified 1778() | ~1232 | +| 23:59 | Edited src/scheduler/testsuite/test_repl_resource_table.c | 2→3 lines | ~72 | +| 23:59 | Edited src/scheduler/src/repl_info.c | modified for() | ~166 | +| 00:12 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | modified test_reconcile_removes_reconciled_job_from_picker_candidates() | ~988 | +| 00:12 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 3→4 lines | ~54 | +| 00:14 | Edited src/scheduler/src/sim_loop.c | modified sim_reconcile_unaccounted_jobs() | ~450 | +| 00:14 | Edited src/scheduler/src/sim_loop.c | added 1 condition(s) | ~198 | +| 00:25 | Edited src/scheduler/src/sim_loop.c | modified sim_reconcile_unaccounted_jobs() | ~527 | +| 00:25 | Edited src/scheduler/src/sim_loop.c | added 1 condition(s) | ~198 | +| 00:25 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | modified test_reconcile_removes_reconciled_job_from_picker_candidates() | ~988 | +| 00:25 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 3→4 lines | ~54 | +| 00:26 | Edited src/scheduler/testsuite/test_sim_verify.c | modified correction() | ~459 | +| 00:26 | Edited src/scheduler/testsuite/test_sim_verify.c | expanded (+9 lines) | ~293 | +| 00:27 | Edited src/scheduler/testsuite/test_sim_verify.c | modified Correction() | ~824 | +| 00:29 | Edited .kiro/specs/scheduler-sim-eager-reconciliation/design.md | modified Correction() | ~527 | +| 00:29 | Edited .kiro/specs/scheduler-sim-decision-parity/design.md | modified Correction() | ~624 |