docs(buglog): P0 defects fixed (bug-1936..bug-1955; 1936 and 1955 partial), bug-1956 cannot-reproduce
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d3da314041
commit
e5a0e42b66
22 changed files with 353 additions and 266 deletions
|
|
@ -17815,9 +17815,9 @@
|
|||
},
|
||||
{
|
||||
"id": "bug-1936",
|
||||
"status": "open",
|
||||
"status": "partial",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "exdata/cwd/home now reach the worker; still not honoured end to end: --cwd (job process spawned with cwd NULL, no cwd in job_assignment_t), exec home (no REST field), nofile_limit (not parsed), -i/-o/-e and out_dir, asked hosts and begin/end time (no submit fields), file stage-in/out (not implemented)",
|
||||
"component": "apiserver",
|
||||
"severity": "wrong-result",
|
||||
"timestamp": "2026-10-10T08:14:36Z",
|
||||
|
|
@ -17825,8 +17825,8 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "apiserver drops cwd, env, run/resource limits, file transfers and I/O paths of REST job submissions\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\n`modelJobToSubmit()` (`src/frontend/apiserver/backend/convert.go:323-375`) builds the controller's `job_startinfo_t` with only cmdline, execuser, launch_type and pre/post-exec; it never sets `exdata`, `exechome` or `execcwd`:\n```go\nsi := (*C.job_startinfo_t)(C.calloc(1, C.sizeof_job_startinfo_t))\nsi.cmdline = C.CString(job.Command)\n... // no si.exdata / si.exechome / si.execcwd\n```\nSo `--cwd`, `--env`, `--file` transfers, interactive mode, every `*_limit` flag (incl. `-W` run limit), `-i/-o/-e`, asked hosts and begin/end time are kept only in the apiserver's memory and never reach the controller or the worker.\n\n**Expected:** Every submit option the apiserver accepts reaches the worker in the job's start info (exdata, exec home, cwd), or is rejected as unsupported.\n**Impact:** Silent wrong result: jobs run without the limits, environment, working directory and I/O paths the user asked for (e.g. a `-W` run limit is never enforced).\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/frontend/apiserver/backend/convert.go, src/frontend/apiserver/controllers/jobs.go",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`modelJobToSubmit()` (`backend/convert.go`) filled only cmdline, execuser, launch_type and pre/post-exec of `job_startinfo_t`; the extended data `processJobRequest()` (`controllers/jobs.go`) builds (env, limits, transfers, interactive) and the cwd stayed in apiserver memory. Pre-existing, origin not bisected.",
|
||||
"fix": "`backend/convert_pure.go`: new pure `submitStartInfo()` sets exdata from `ExtendData`, execcwd (`ExecCWD`, else `CWD`) and exechome; `rawJobToModel` restores `ExtendData`/`CWD`; new `ValidateExdata()` rejects non-object or >16383-byte exdata (the worker would fail the job). `backend/convert.go`: copies/frees the three fields and reads exdata back for jobs and arrays. `controllers/jobs.go`: validates exdata and no longer writes `\"transfer_files\": null`. The controller passes start info through unchanged (WAL submit facts encode the whole JobStartInfo).\n\nVerification:\n- Test: `TestSubmitStartInfo_CarriesExdataCwdAndHome`, `TestSubmitStartInfo_PrefersExecCWD`, `TestRawJobArrayToModels_RestoresExdataAndCwd`, `TestValidateExdata` (`backend/convert_test.go`), `TestJobHandler_SubmitRejectsNonObjectExtendData` (`controllers/jobs_handler_test.go`): RED before (e.g. `convert_test.go:1272: exdata: got \"\", want \"{\\\"limits\\\":{\\\"run_limit\\\":60},...}\"`), GREEN after.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"apiserver",
|
||||
"submit",
|
||||
|
|
@ -17834,14 +17834,16 @@
|
|||
"limits"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"d01ced9b"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1936.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1937",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "worker",
|
||||
"severity": "wrong-result",
|
||||
"timestamp": "2026-10-10T08:14:38Z",
|
||||
|
|
@ -17849,8 +17851,8 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "apiserver writes job file transfers under 'transfer_files' but the worker parses 'transfer_file'\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\nThe apiserver serialises transfers as `extendDataMap[\"transfer_files\"]` (`src/frontend/apiserver/controllers/jobs.go:1923`) while the worker looks for:\n```c\nelse if (strcmp(key, \"transfer_file\") == 0) { /* xcecd_exdata.c:115 */\n```\n\n**Expected:** Both sides use one key, so transfers in exdata are parsed.\n**Impact:** Wrong result once exdata reaches the worker: file transfers are silently ignored.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/frontend/apiserver/controllers/jobs.go, src/worker/src/xcecd_exdata.c",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`parse_exdata()` (`src/worker/src/xcecd_exdata.c`) matched only `\"transfer_file\"`, the apiserver writes `\"transfer_files\"`. Pre-existing.",
|
||||
"fix": "`xcecd_exdata.c`: accepts `\"transfer_files\"` and still `\"transfer_file\"`; when both are present the first list is kept (no leak). Stage-in/out itself remains unimplemented (future spec).\n\nVerification:\n- Test: `test_apiserver_transfer_files_parsed` (`src/worker/testsuite/test_exdata_parse.c`): RED `test_exdata_parse.c:73: ... FAIL: Expected 2 Was 0`, GREEN after (5 tests, 0 failures).\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"apiserver",
|
||||
"worker",
|
||||
|
|
@ -17858,14 +17860,16 @@
|
|||
"file-transfer"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"b9747ad2"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1937.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1938",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "scheduler",
|
||||
"severity": "wrong-result",
|
||||
"timestamp": "2026-10-10T08:14:41Z",
|
||||
|
|
@ -17873,22 +17877,24 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "xce_scheduler dispatches jobs from closed or inactive queues (queue readiness gate is a stub)\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\nThe admin queue controls set and clear the closed/inactive flags (`src/controller/queue.c:131-152`), but the scheduler's gates always pass:\n```c\n/* FIXME this is just stub, we need to add more */\nint sched_job_is_ready(xce_sched_job_t* j) { return 1; }\n/* FIXME this is just stub, we need to add more */\nint sched_queue_is_ready(xce_sched_queue_t* q) { return 1; } /* core.c:646-649 */\n```\n\n**Expected:** Jobs of an inactive queue are not dispatched (they stay pending with a reason); a closed queue accepts no new submissions.\n**Impact:** Admin queue control silently ignored: inactivating a queue does not stop dispatch.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/scheduler/src/core.c, src/scheduler/src/plugins/builtin_fcfs.c",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`sched_queue_is_ready()` (`src/scheduler/src/core.c`) was a `return 1` stub, the only queue gate of both pickers (`builtin_fcfs_next_job`, `fcfs_elect_job`); the queue status bits did reach `xce_sched_queue_t`. Pre-existing stub.",
|
||||
"fix": "`core.c`: `sched_queue_is_ready()` returns false for `QUEUE_STAT_INACT_ADMIN` or `QUEUE_STAT_INACT_WINDOW`; `QUEUE_STAT_CLOSED` is deliberately not a dispatch gate (LSF: a closed queue still dispatches its pending jobs; closing blocks submissions). Live and sim share the core and picker. Follow-ups: the controller does not reject submissions to a closed queue and the apiserver skips the check for the default queue; no pend reason for held jobs.\n\nVerification:\n- Test: `test_inactive_queue_holds_jobs_closed_queue_dispatches` (`src/scheduler/testsuite/test_queue_admin_control.c`): RED `:208: FAIL: Expected 2 Was 3 (an inactive queue dispatches nothing)`, GREEN after on both fixture shapes.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"scheduler",
|
||||
"queue",
|
||||
"admin-control"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"f51a19d3"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1938.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1939",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "scheduler",
|
||||
"severity": "wrong-result",
|
||||
"timestamp": "2026-10-10T08:14:43Z",
|
||||
|
|
@ -17896,22 +17902,24 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "xce_scheduler dispatches jobs to hosts closed by an admin\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\nHost close sets `XCE_WORKER_CLOSED|XCE_WORKER_CLOSED_BY_ADMIN` (`src/controller/worker.c:1015-1024`), but no scheduler code checks either bit (only unavailable/reconciling hosts are skipped: `core_session.c:136`, `resource.c:704,887`); the parallel allocator's bad-host check is empty (`plugins/parjob_allocator.c:40-48`).\n\n**Expected:** A closed host gets no new jobs; running jobs are unaffected.\n**Impact:** Admin host control silently ignored: closing a host for maintenance does not stop new jobs landing on it.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/scheduler/src/resource.c, src/scheduler/src/core_session.c, src/scheduler/src/plugins/parjob_allocator.c",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`sched_host_iter_next()` (`src/scheduler/src/host_iter.c`), the candidate source of both seqjob and parjob allocators, filtered only on select and free resources, never on `XCE_WORKER_CLOSED`/`CLOSED_BY_ADMIN`; parjob's `skip_bad_worker_` is unused. Pre-existing.",
|
||||
"fix": "`host_iter.c`: a host with either closed bit is skipped before its trace scope opens, so no new placement (serial or parallel, live or sim) lands on it; running jobs and accounting are unchanged. No new pend-reason code.\n\nVerification:\n- Test: `test_admin_closed_host_gets_no_new_jobs` (`src/scheduler/testsuite/test_host_admin_close.c`): RED `:200: FAIL: Expected 0 Was 3 (the admin-closed host must get no new usage)`, GREEN after (serial and parallel, both fixture shapes).\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"scheduler",
|
||||
"host",
|
||||
"admin-control"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"1668a439"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1939.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1940",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "apiserver",
|
||||
"severity": "wrong-result",
|
||||
"timestamp": "2026-10-10T08:14:46Z",
|
||||
|
|
@ -17919,22 +17927,24 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "job control ignores the requested signal and the force-kill flag (apiserver to controller)\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\nThe control handler passes a JSON event string as content (`controllers/jobs.go:2260-2277`); `signalNumber()` looks it up as a signal name, fails and falls back to TERM/TSTP/CONT; `backend/clib.go:697-705` always sends `sig.force = 0` and `ckpt.kill = 0`, dropping ForceKill and the checkpoint kill/method options (`:746-762`).\n\n**Expected:** A kill with a user-chosen signal sends that signal; force kill and checkpoint options reach the controller.\n**Impact:** Wrong result: users cannot send a specific signal or force-kill a job.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/frontend/apiserver/controllers/jobs.go, src/frontend/apiserver/backend/clib.go",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`ControlJob` (`backend/clib.go`) treated its content (a JSON event) as a signal name, so the lookup always missed and fell back to TERM/TSTP/CONT; it also hard-coded `force = 0`, `ckpt.kill = 0` and never set the checkpoint method. Pre-existing.",
|
||||
"fix": "`backend/convert_pure.go`: new pure `jobCtrlParams()` parses the JSON event or a bare signal name/number, validates it against `JobSignalMapTable` (error instead of fallback), maps force_kill to the signal's force (kill) or the checkpoint's kill flag, and passes the method; `backend/clib.go` fills the C structs from it. Worker-side substitution of the delivered signal was a separate defect, bug-1954.\n\nVerification:\n- Test: `TestJobCtrlParams_*` (`backend/jobctrl_params_test.go`): RED `jobctrl_params_test.go:34: kill USR1 force_kill: got signo 15 force 0, want signo 10 force 1` and the checkpoint case, GREEN after (6 tests).\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"apiserver",
|
||||
"job-control",
|
||||
"signal"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"4d2e80c4"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1940.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1941",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "controller",
|
||||
"severity": "wrong-result",
|
||||
"timestamp": "2026-10-10T08:14:48Z",
|
||||
|
|
@ -17942,22 +17952,24 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "xce_controller refuses kill/stop/resume of running jobs on hosts whose status is not exactly OK\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\n```c\n/* FIXME: better method to check host status */\nif (w->ep && w->host.status == 0) { /* src/controller/job.c:2145-2156 */\n```\nAny other status bit (CLOSED_BY_ADMIN, BUSY, UNAVAIL...) makes the control request fail.\n\n**Expected:** Jobs on a closed (or otherwise flagged but connected) host can be killed, stopped and resumed; a host that is not connected gives a clear error.\n**Impact:** Users and admins cannot kill jobs on a host closed for maintenance.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/controller/job.c",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`job_ctrl()` (`src/controller/job.c`) sent control only if `w->host.status == 0` and returned `-errno` otherwise. Pre-existing FIXME.",
|
||||
"fix": "`job.c`: new `job_ctrl_to_host()` sends whenever the worker is connected (endpoint present, not UNAVAIL), so CLOSED/CLOSED_BY_ADMIN/BUSY/locked hosts work; an unknown or unconnected host fails with `-E_XCE_BAD_WORKER` and an error log naming it.\n\nVerification:\n- Test: `test_jc_connected_flagged_host_is_controllable` and `test_jc_unconnected_host_fails_with_bad_worker` (`src/controller/testsuite/test_job_ctrl_hosts.c`): RED `:239: FAIL: Expected 0 Was -2 (status 0x100000)` and `Expected -10002 Was -22`, GREEN after (asserts the decoded request in the worker send queue).\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"controller",
|
||||
"job-control",
|
||||
"host-status"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"f244661b"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1941.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1942",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "controller",
|
||||
"severity": "wrong-result",
|
||||
"timestamp": "2026-10-10T08:14:51Z",
|
||||
|
|
@ -17965,22 +17977,24 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "xce_controller sends job control of a multi-host job only to its first host\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\nJob control is routed to `allocs[0]->host` only (`src/controller/job.c:2126-2131`).\n\n**Expected:** Signals reach every host of the job (or the job's launcher is documented to fan them out and does so).\n**Impact:** Suspending or killing a multi-host job can leave its tasks on other hosts running.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/controller/job.c",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`job_ctrl()` (`src/controller/job.c`) routed control to `allocs[0]->host` only. Remote tasks (started via runtasks by the head worker or by xrun) run under their own host's worker entry, and the head worker signals only its own process group, so signals never reached other hosts.",
|
||||
"fix": "`job.c:job_ctrl`: sends the request to every allocated host through `job_ctrl_to_host` (queue-only, non-blocking); the head host decides the result; an unconnected non-head host is logged and skipped. A remaining worker-side window (signal while a remote task starts) was bug-1955.\n\nVerification:\n- Test: `test_jc_multi_host_job_reaches_every_host` and two related tests (`test_job_ctrl_hosts.c`): RED `:305: FAIL: Expected 1 Was 0 (host jch-h1 of a 3-host job must get the control)`, GREEN after.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: not run: a live `/xce-test-multihost` stop/kill check is a follow-up",
|
||||
"tags": [
|
||||
"controller",
|
||||
"job-control",
|
||||
"parallel"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"8568c8ab"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1942.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1943",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "scheduler",
|
||||
"severity": "wrong-result",
|
||||
"timestamp": "2026-10-10T08:14:54Z",
|
||||
|
|
@ -17988,8 +18002,8 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "xce_scheduler --sim does not load user and host groups, so group-scoped limits differ from live\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\nOn a config push the live scheduler loads user and host groups (`groupmgr_load_configs`, `src/scheduler/src/scheduler.c:1144-1145`); the core's config event used by the simulator applies only resources, resource values and queues (`core_events.c:846-850`).\n\n**Expected:** Live and simulated scheduling apply the same groups (scheduler-driver-equivalence.md).\n**Impact:** Replays of clusters with group-scoped limits make different decisions than the live scheduler.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/scheduler/src/core_events.c, src/scheduler/src/scheduler.c",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "Only `sched_init_config()` (`scheduler.c`, live) called `groupmgr_load_configs`; the core `CONFIG_PUSH` event (`core_events.c:xce_core_push_events`) and the replay snapshot loader (`snapshot_load.c:xce_sched_core_load_snapshot`, from which `sim_bootstrap_limit_plugin` seeds limits) never loaded groups. Pre-existing.",
|
||||
"fix": "`core.h`/`core.c`: new `xce_core_load_groups()` is the single loader, called from `sched_init_config()` (replacing its direct calls), the `CONFIG_PUSH` event (first) and `snapshot_load.c` (before the limit plugin is seeded); `snapshot.c` field-completeness note updated. Follow-up: limits are not re-seeded on a mid-replay CONFIG_PUSH.\n\nVerification:\n- Test: `test_user_group_limit_matches_in_sim_as_in_live` (`src/scheduler/testsuite/test_sim_group_limit_parity.c`): RED `:318: FAIL: Expected 1 Was 0 (sim must match the user-group-scoped limit)`, and with only the CONFIG_PUSH part reverted `:334: FAIL: CONFIG_PUSH must register the config's user groups`, GREEN after.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"scheduler",
|
||||
"sim",
|
||||
|
|
@ -17997,14 +18011,16 @@
|
|||
"limit"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"8b89a0ce"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1943.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1944",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "scheduler",
|
||||
"severity": "wrong-result",
|
||||
"timestamp": "2026-10-10T08:14:56Z",
|
||||
|
|
@ -18012,22 +18028,24 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "xce_scheduler gives a job moved to another queue the queue's priority, so it jumps ahead\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\nNew jobs get priority 0 (`schedobj.c:214`, `core_events.c:353`), but on a queue change the job's priority becomes the queue's priority (`core_events.c:1360`, `schedobj.c:684`); the picker sorts by job priority within a queue (`plugins/builtin_fcfs.c:213`).\n\n**Expected:** Moving a job does not change its job priority.\n**Impact:** Wrong ordering: moved jobs overtake jobs submitted earlier to the target queue.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/scheduler/src/core_events.c, src/scheduler/src/schedobj.c",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "On a queue change both `xce_core_push_events` (`JOB_UPDATE`, `core_events.c`) and `sched_update_existing_job` (`schedobj.c`) set `job->priority = q->priority`; new jobs and snapshot-restored jobs get 0, so moved jobs jumped ahead and live/replay disagreed. Pre-existing.",
|
||||
"fix": "Both sites now only re-point `job->queue` on a move; queue priority still orders the queues. `test_job_update.c`, which asserted the old behaviour, now expects the job's own priority.\n\nVerification:\n- Test: `test_moved_job_keeps_its_priority_and_place` (`src/scheduler/testsuite/test_job_move_priority.c`): RED `:208: FAIL: Expected 0 Was 10` (and `:214: Expected 2 Was 1` for the ordering), GREEN after; `test_update_existing_job_mutates_in_place` RED `Expected 1 Was 5` with the corrected expectation, GREEN after.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"scheduler",
|
||||
"queue",
|
||||
"priority"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"7a9d75d6"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1944.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1945",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "apiserver",
|
||||
"severity": "security",
|
||||
"timestamp": "2026-10-10T08:14:59Z",
|
||||
|
|
@ -18035,22 +18053,24 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "apiserver signs and accepts JWTs with the shipped default secret when XCE_JWT_SECRET is unset\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\n`config/app.yaml:17` ships the secret `xce-api-key`; `utils/config.go:315-320` uses `XCE_JWT_SECRET` when set and otherwise keeps the default without any warning.\n\n**Expected:** The apiserver never runs with a publicly known signing secret.\n**Impact:** Security: anyone can forge tokens for any user on a deployment that did not set the environment variable.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/frontend/apiserver/config/app.yaml, src/frontend/apiserver/utils/config.go",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`resolveJWTSecret()` (`utils/config.go`) fell back to the shipped `xce-api-key` when `XCE_JWT_SECRET` was unset.",
|
||||
"fix": "Empty or the old default secret (env or config) counts as unset: the apiserver generates a random 256-bit per-process secret and logs a warning (tokens do not survive restart; apiservers behind one endpoint must share `XCE_JWT_SECRET`); the secret is never logged; `app.yaml` ships `secretKey: \"\"`. Docs updated in 27ef5060.\n\nVerification:\n- Test: `TestResolveJWTSecret_NeverUsesKnownDefaultOrEmpty`, `TestShippedAppYAML_NoJWTSecret`, `TestInitConf_NoJWTSecretGeneratesAndWarns` (`utils/config_test.go`): RED (`... = \"xce-api-key\": must be a generated secret`), GREEN after.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"apiserver",
|
||||
"security",
|
||||
"jwt"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"19a1a6f0"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1945.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1946",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "apiserver",
|
||||
"severity": "security",
|
||||
"timestamp": "2026-10-10T08:15:01Z",
|
||||
|
|
@ -18058,22 +18078,24 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "apiserver logout does not revoke the token: it stays valid until expiry\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\nLogout deletes a token file (`controllers/auth.go:69-95`) that token validation never reads (`middleware/validatehandler.go:101-116`).\n\n**Expected:** After logout the token is rejected.\n**Impact:** Security: a leaked token keeps working for up to 24 h after logout.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/frontend/apiserver/controllers/auth.go, src/frontend/apiserver/middleware/validatehandler.go",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`AuthController.Logout` (`controllers/auth.go`) only removed a token file that token validation (`middleware/validatehandler.go`) never reads.",
|
||||
"fix": "New `controllers/token_revocation.go`: revoked token IDs kept until expiry, purged on each revocation; `generateJWT` sets a random `jti`; tokens without one are revoked by hash; new `ParseTokenClaims` (used by ValidateHandler, RequirePermission, GetUsernameFromToken) rejects revoked tokens. Per process only (not persisted or shared). Follow-up: `xcecli logout` never calls the logout API.\n\nVerification:\n- Test: `TestLogout_RevokesToken` (`middleware/validatehandler_test.go`): RED `after logout: status = 200, want 401`, GREEN after; plus `TestTokenRevocations_ExpiryAndPurge`, `TestIntegration_PostLogoutTokenRejected`.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"apiserver",
|
||||
"security",
|
||||
"jwt"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"4ce4f0b7"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1946.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1947",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "apiserver",
|
||||
"severity": "security",
|
||||
"timestamp": "2026-10-10T08:15:04Z",
|
||||
|
|
@ -18081,22 +18103,24 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "apiserver config-file auth compares plaintext passwords with != and ships admin/admin defaults\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\n`backend/auth/config_file.go:60` compares the stored plaintext password with `!=`; `config/auth.yaml:12-21` ships `admin/admin` and `user1/user1`.\n\n**Expected:** Stored passwords are hashed and compared in constant time; no default credentials are shipped active.\n**Impact:** Security: password disclosure from the config file, timing side channel, and known default credentials.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/frontend/apiserver/backend/auth/config_file.go, src/frontend/apiserver/config/auth.yaml",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`ConfigFileProvider.Authenticate` (`backend/auth/config_file.go`) compared the stored plaintext with `!=`; `auth.yaml` shipped plaintext defaults.",
|
||||
"fix": "bcrypt hashes accepted; plaintext entries still work but compare in constant time; unknown users cost the same bcrypt work; `SecurityWarnings()` + startup warnings for plaintext entries and active shipped default passwords; `auth.yaml`/`auth.yaml.example` ship bcrypt hashes of the same dev passwords (dev tooling such as `tests/regression/run.sh` keeps working); `tools/encrypt -action=hash`; `golang.org/x/crypto/bcrypt` vendored from the already pinned x/crypto v0.23.0.\n\nVerification:\n- Test: `TestConfigFileProvider_BcryptPassword`, `TestShippedAuthConfig_HashedDefaults`, `TestConfigFileProvider_SecurityWarnings` (`backend/auth/config_file_test.go`): RED (e.g. the stored hash itself was accepted as a password; `shipped password is not a bcrypt hash`), GREEN after.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"apiserver",
|
||||
"security",
|
||||
"auth"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"f91642db"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1947.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1948",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "apiserver",
|
||||
"severity": "security",
|
||||
"timestamp": "2026-10-10T08:15:06Z",
|
||||
|
|
@ -18104,22 +18128,24 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "apiserver trusts X-Forwarded-For from any client, so IP whitelist and JWT IP binding can be spoofed\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\nThe router uses `gin.Default()` (`router/routers.go:19`) and never calls `SetTrustedProxies`, so `ClientIP()` honours `X-Forwarded-For` from any peer.\n\n**Expected:** Forwarded headers are only honoured from configured trusted proxies.\n**Impact:** Security: a client can claim any IP and bypass the IP whitelist and the IP bound into its JWT.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/frontend/apiserver/router/routers.go",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`router.Router()` used `gin.Default()` without `SetTrustedProxies`, so `ClientIP()` honoured X-Forwarded-For from any peer.",
|
||||
"fix": "New `app.yaml` option `security.trusted_proxies` (IP/CIDR, default empty = none), validated at startup; `Router()` passes it to `SetTrustedProxies` (falls back to none if invalid); schema and nginx samples documented.\n\nVerification:\n- Test: `TestRouter_IgnoresForwardedForByDefault` (`router/routers_test.go`, real `Router()`): RED `non-whitelisted peer spoofing X-Forwarded-For: status = 200, want 403`, GREEN after; plus `TestRouter_HonoursForwardedForFromTrustedProxy`, `TestResolveTrustedProxies`.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"apiserver",
|
||||
"security",
|
||||
"whitelist"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"c4c63f11"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1948.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1949",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "apiserver",
|
||||
"severity": "security",
|
||||
"timestamp": "2026-10-10T08:15:09Z",
|
||||
|
|
@ -18127,22 +18153,24 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "apiserver RequirePermission and IP whitelist write an error but do not abort the request\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\nOn a bad token `RequirePermission` returns an error response without `Abort()` (`controllers/rbac_check.go:119-122`); the IP whitelist does the same for an invalid client IP (`middleware/whitelist.go:130-132`); `ReturnError` never aborts (`controllers/response.go:30-37`).\n\n**Expected:** A failed middleware check stops the request before the handler runs.\n**Impact:** Security: the handler may still run after an authorization failure.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/frontend/apiserver/controllers/rbac_check.go, src/frontend/apiserver/middleware/whitelist.go, src/frontend/apiserver/controllers/response.go",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`RequirePermission` (`controllers/rbac_check.go`) and `WhitelistIPMiddleware` (`middleware/whitelist.go`) wrote an error via `ReturnError` without `ctx.Abort()`.",
|
||||
"fix": "`ctx.Abort()` added at both sites and on ValidateHandler's request-body check; a bad token in RequirePermission now answers 401 (was 500). `ReturnError` stays non-aborting (documented): `hosts.go` relies on `ctx.IsAborted()` after a helper's error. Follow-up: `ControlHost` can still write twice if reached.\n\nVerification:\n- Test: `TestRequirePermission_AbortsOnInvalidToken` (`controllers/rbac_abort_test.go`): RED `handler ran after RequirePermission failed (status 500)`; `TestWhitelistIPMiddleware_AbortsOnFailure/unparsable_client_IP`: RED `handler ran after the IP whitelist rejected`; GREEN after.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"apiserver",
|
||||
"security",
|
||||
"middleware"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"42a402a5"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1949.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1950",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "apiserver",
|
||||
"severity": "security",
|
||||
"timestamp": "2026-10-10T08:15:11Z",
|
||||
|
|
@ -18150,22 +18178,24 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "apiserver JWT validation does not pin the signing algorithm\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\nThe middleware's parse callback returns the key without checking `token.Method` (`middleware/validatehandler.go:102-104`), unlike the other parse path (`controllers/auth.go:186`).\n\n**Expected:** Only the configured HMAC algorithm is accepted.\n**Impact:** Security hardening: algorithm-confusion class of attacks is not ruled out.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/frontend/apiserver/middleware/validatehandler.go",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`isValidToken()` (`middleware/validatehandler.go`) never checked `token.Method`; `GetUsernameFromToken` accepted any HMAC variant.",
|
||||
"fix": "`controllers/auth.go`: `JWTSigningMethod` (HS256), `JWTKeyFunc`, `JWTValidMethods()`; both parse paths use them.\n\nVerification:\n- Test: `TestIsValidToken_PinsSigningAlgorithm` (`middleware/validatehandler_test.go`): RED `isValidToken(HS384) = true, want false`; `TestGetUsernameFromToken_PinsSigningAlgorithm`: RED; GREEN after.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"apiserver",
|
||||
"security",
|
||||
"jwt"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"42dd1e7a"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1950.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1951",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "apiserver",
|
||||
"severity": "crash",
|
||||
"timestamp": "2026-10-10T08:15:14Z",
|
||||
|
|
@ -18173,8 +18203,8 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "apiserver crashes on an auth.yaml without a config_file block (nil pointer)\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\n`backend/auth/config_file.go:39` reads `cfg.ConfigFile.Users` without checking `cfg.ConfigFile` for nil.\n\n**Expected:** A missing block is a clear configuration error, not a panic.\n**Impact:** Crash at startup or login with a minimal auth.yaml.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/frontend/apiserver/backend/auth/config_file.go",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`NewConfigFileProvider` (`backend/auth/config_file.go:39`) dereferenced `cfg.ConfigFile` without a nil check.",
|
||||
"fix": "Returns a clear configuration error when the `config_file` block is missing.\n\nVerification:\n- Test: `TestNewConfigFileProvider_Errors/missing_config_file_block` (`backend/auth/config_file_test.go`): RED `panic: runtime error: invalid memory address or nil pointer dereference`, GREEN after.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"apiserver",
|
||||
"auth",
|
||||
|
|
@ -18182,14 +18212,16 @@
|
|||
"crash"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"d3ce2982"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1951.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1952",
|
||||
"status": "investigating",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "suspected from source reading; confirm with a test before fixing",
|
||||
"status_note": "",
|
||||
"component": "apiserver",
|
||||
"severity": "security",
|
||||
"timestamp": "2026-10-10T08:15:16Z",
|
||||
|
|
@ -18197,22 +18229,24 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "apiserver user role changes check a narrower rbac:control grant only against the target user\n\n**Observed:** (source reading, `.kiro/reviews/project-gap-review-2026-10-10.md` (P0); to be confirmed by a failing test before the fix)\nSuspected (needs verification): in add/delete roles for a user, a non-`all` `rbac:control` grant is only checked against \"is the target me?\" (`controllers/users.go:404-412,455-462`), so such a grant could let a user give itself `cluster_admin`. Built-in roles grant `rbac:control` only with domain `all` (`config/rbac.yaml:100-102`), so this is latent.\n\n**Expected:** A user can never grant itself a role with more rights than it already holds.\n**Impact:** Security (latent): privilege escalation through a custom role.\n**Found by:** review: `.kiro/reviews/project-gap-review-2026-10-10.md` (P0)",
|
||||
"file": "src/frontend/apiserver/controllers/users.go",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`UserController.AddRolesForUser`/`DeleteRolesForUser` (`controllers/users.go`) only checked whether the target was the caller for a non-`all` `rbac:control` grant; `self` is an accepted rbac scope (`models/roles.go:78`), so a user holding only `rbac:control` scope `self` could grant itself `cluster_admin`.",
|
||||
"fix": "`canChangeUserRoles`: changing anyone's roles (the caller's included) requires an `rbac:control` grant with scope `all`, checked over all grants before deduplication; anything else gets 403. Follow-up: any `rbac:control` scope can still create roles and add permissions to a role the caller holds (`roles.go`), the same escalation by another route.\n\nVerification:\n- Test: `TestAddRolesForUser_SelfScopeCannotGrantItselfRoles` (`controllers/users_rbac_test.go`): RED `privilege escalation: mallory (rbac:control scope self) granted itself cluster_admin (status 200)`, GREEN after; plus `TestDeleteRolesForUser_SelfScopeRejected`, `TestUserRoleChanges_AllScopeAllowed`.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"apiserver",
|
||||
"security",
|
||||
"rbac"
|
||||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"a80768f3"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1952.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1953",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "apiserver",
|
||||
"severity": "wrong-result",
|
||||
"timestamp": "2026-10-10T08:42:56Z",
|
||||
|
|
@ -18220,8 +18254,8 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "apiserver skips submit validation and limit conversion for any job submitted with a job name\n\n**Observed:** (source reading, confirmed against the code on 2026-10-10)\n`preCheckJobRequest()` (`src/frontend/apiserver/controllers/jobs.go:1308`)\nreturns from inside its job-name branch, before the rest of the checks run:\n```go\nif req.JobName != \"\" {\n if strings.ContainsAny(req.JobName, \"[]\") {\n ...\n return count, true, nil // jobs.go:1346, array name\n }\n ...\n return 1, false, nil // jobs.go:1366, plain name\n}\n```\nEverything after the branch is skipped for every named job (and every array\njob): the job-description, project-name and resreq length checks, resreq\nvalidation, the `shell_limit` → limit conversion (`jobs.go:1405-1434`), and\nthe later env / launch-type validation and transfer-file parsing. Reported by\nthe bug-1936 fix: a named job with transfer files fails with\n`failed to parse ExtendData JSON`.\n\n**Expected:** every submission gets the same validation and conversions,\nnamed or not; the name only decides array handling.\n**Impact:** wrong result and missing validation: named and array jobs bypass\nlength and resreq checks (bad input reaches the controller and scheduler),\nlose their shell limits, and fail at the worker when they carry transfers.\n**Found by:** fix of bug-1936 (submit exdata), 2026-10-10.",
|
||||
"file": "src/frontend/apiserver/controllers/jobs.go",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`preCheckJobRequest()` (`controllers/jobs.go`) returned from inside its job-name branch (`return count, true, nil` / `return 1, false, nil`), so everything after it was skipped for named and array jobs. Pre-existing.",
|
||||
"fix": "The name branch now only sets `n`/`isArray`; the function continues through every check and conversion and returns `n, isArray, nil` at the end.\n\nVerification:\n- Test: `TestPreCheckJobRequest_NamedJobsGetFullValidation` (`controllers/jobs_test.go`): RED `name \"myjob\": cpu limit not converted: got 0 s, want 60` and `an over-long project name was accepted` (same for `arr[1-3]`), GREEN after; whole controllers package ok.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"apiserver",
|
||||
"submit",
|
||||
|
|
@ -18230,14 +18264,16 @@
|
|||
"related_bugs": [
|
||||
"bug-1936"
|
||||
],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"e00526f9"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1953.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1954",
|
||||
"status": "open",
|
||||
"status": "fixed",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "",
|
||||
"component": "worker",
|
||||
"severity": "wrong-result",
|
||||
"timestamp": "2026-10-10T08:46:07Z",
|
||||
|
|
@ -18245,8 +18281,8 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "xcecd_worker sends SIGTERM for a KILL request without force and SIGSTOP for a TSTP request\n\n**Observed:** (source reading, 2026-10-10; found while fixing bug-1940)\n`worker_signal_callback()` (`src/worker/src/xcecd_worker.c:1115-1130`)\nreplaces the requested signal:\n```c\ncase SIGTERM:\ncase SIGKILL:\n if (force) { success = signal_gid_except_self(SIGKILL); }\n else { success = signal_gid_except_self(SIGTERM); }\n...\ncase SIGSTOP:\ncase SIGTSTP:\n success = signal_gid_except_self(SIGSTOP);\n```\nSince bug-1940 the requested signal reaches the worker, but an explicit\n`kill -s KILL` without force still sends SIGTERM, and an explicit TSTP is sent\nas the uncatchable SIGSTOP.\n\n**Expected:** the job receives the signal the user asked for; force kill\n(SIGKILL) stays available for a default kill.\n**Impact:** wrong result: a job that ignores SIGTERM survives an explicit\nSIGKILL request; a job that handles SIGTSTP to checkpoint or clean up cannot\ndo so.\n**Found by:** review of the bug-1940/1942 fixes, 2026-10-10.",
|
||||
"file": "src/worker/src/xcecd_worker.c",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "`worker_signal_callback()` (`src/worker/src/xcecd_worker.c`) mapped TERM/KILL to `force ? SIGKILL : SIGTERM` and STOP/TSTP to SIGSTOP; the apiserver's default stop signal was TSTP, relying on that substitution.",
|
||||
"fix": "New `job_signal_to_deliver()` (`src/worker/src/job_signal.c`, `include/job_signal.h`) delivers the requested signal; only a forced TERM escalates to SIGKILL; the callback uses it. The apiserver's default stop signal becomes SIGSTOP (`backend/convert_pure.go` `defaultActionSignal`, `models.DefaultActionSignal`), so a plain stop still suspends jobs that ignore SIGTSTP; the bug-1940 test pinning stop=20 now expects 19.\n\nVerification:\n- Test: `test_requested_signal_is_delivered` (`src/worker/testsuite/test_job_signal.c`): RED `test_job_signal.c:14: FAIL: Expected 9 Was 15` (KILL without force), GREEN after; `TestJobCtrlParams_PlainStopSendsSigstop` (`backend/jobctrl_params_test.go`): RED `DefaultActionSignal[stop] = \"TSTP\", want STOP`, GREEN after.\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"worker",
|
||||
"job-control",
|
||||
|
|
@ -18255,14 +18291,16 @@
|
|||
"related_bugs": [
|
||||
"bug-1940"
|
||||
],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"148557a5"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1954.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1955",
|
||||
"status": "open",
|
||||
"status": "partial",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "newly logged",
|
||||
"status_note": "covers a signal arriving after this host accepted the runtasks request; a control that reaches a remote host before its runtasks request arrives is still dropped there (needs a controller-side or pre-start record)",
|
||||
"component": "worker",
|
||||
"severity": "wrong-result",
|
||||
"timestamp": "2026-10-10T08:46:10Z",
|
||||
|
|
@ -18270,8 +18308,8 @@
|
|||
"occurrences": 1,
|
||||
"error_message": "xcecd drops a signal for a remote task of a multi-host job that is still starting\n\n**Observed:** (source reading, 2026-10-10; found while fixing bug-1942)\nOnly the head host's job start opens the pending-signal window\n(`pending_signal_start(d->jobid)`, `src/worker/src/controller_connector.c:1062`,\nbug-1908). The runtasks handler for remote tasks (`handle_runtasks()`, `:1147`)\nnever does, so a signal that arrives before the remote task's worker entry is\nregistered is logged and dropped:\n```c\nXCECD_LOG(XCE_LOG_ERROR, \"Failed to find worker for job ID: %s\", jobidStr);\nFREEUP(task_ctx);\nreturn -1; /* controller_connector.c:1606 */\n```\nSince bug-1942 every host of a multi-host job receives job control, so this\nwindow is now reachable.\n\n**Expected:** like the head host (bug-1908), a signal for a remote task that\nis starting is kept and delivered once the task runs.\n**Impact:** wrong result: a kill or stop sent right after a multi-host job\nstarts can miss some of its remote tasks, which keep running.\n**Found by:** review of the bug-1940/1942 fixes, 2026-10-10.",
|
||||
"file": "src/worker/src/controller_connector.c",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
"root_cause": "Only the head-host start path opened the pending-signal window (`pending_signal_start`, `controller_connector.c`, bug-1908); `handle_runtasks()` queued remote tasks without it, so a signal arriving before the task's worker entry registered hit \"Failed to find worker\" and was dropped.",
|
||||
"fix": "`handle_runtasks()` calls `pending_signal_start(jobid)` before `submit_fork_task()` and takes it back if queuing fails; the existing RUNNING transition (`xcecd_worker_utils.c`, bug-1908) delivers the kept signal to the task.\n\nVerification:\n- Test: `test_jobcontrol_signal_for_queued_remote_task_is_kept` (`src/worker/testsuite/test_controller_connector.c`): RED `:1631: FAIL: Expected 0 Was -1. the kill must not be dropped`, GREEN after (32 tests, 0 failures).\n- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok\n- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)",
|
||||
"tags": [
|
||||
"worker",
|
||||
"job-control",
|
||||
|
|
@ -18282,20 +18320,22 @@
|
|||
"bug-1942",
|
||||
"bug-1908"
|
||||
],
|
||||
"fix_commits": [],
|
||||
"fix_commits": [
|
||||
"d3da3140"
|
||||
],
|
||||
"record": ".wolf/bugs/bug-1955.md"
|
||||
},
|
||||
{
|
||||
"id": "bug-1956",
|
||||
"status": "investigating",
|
||||
"status": "cannot-reproduce",
|
||||
"status_updated": "2026-10-10",
|
||||
"status_note": "suspected: confirm whether a job without launch type decodes to NULL at the worker",
|
||||
"status_note": "no NULL path from the wire; the explicit NULL branch in job_start_local_task is unreachable through decoding",
|
||||
"component": "worker",
|
||||
"severity": "crash",
|
||||
"timestamp": "2026-10-10T08:46:13Z",
|
||||
"last_seen": "2026-10-10T08:46:13Z",
|
||||
"occurrences": 1,
|
||||
"error_message": "xcecd compares a NULL launch_type with strcmp when a job has no launch type (possible crash)\n\n**Observed:** (source reading, 2026-10-10; suspected, not reproduced)\n`job_start_local_task()` stores NULL when the start info has no launch type\nand then dereferences it:\n```c\nif (d->start_info->launch_type) {\n job_ctx->startinfo->launch_type = strdup(...);\n} else {\n job_ctx->startinfo->launch_type = NULL; /* :981-985 */\n}\n...\nif (strcmp(job_ctx->startinfo->launch_type, \"openmpi\") == 0 /* :994 */\n```\n`job_start_remote_task()` does the same without a check (`:753`). The apiserver\nsends no launch type when the user gives none (`cStringOrNil`,\n`backend/convert.go:339`). Jobs without a launch type do run in existing\ntests, so the decoder may deliver an empty string rather than NULL: not\nconfirmed either way.\n\n**Expected:** a missing launch type means a plain (non-MPI) job; no NULL\ndereference.\n**Impact:** possible worker crash at job start for jobs without a launch\ntype.\n**Found by:** review of the bug-1940/1942 fixes, 2026-10-10.",
|
||||
"error_message": "xcecd compares a NULL launch_type with strcmp when a job has no launch type (possible crash)\n\n**Observed:** (source reading, 2026-10-10; suspected, not reproduced)\n`job_start_local_task()` stores NULL when the start info has no launch type\nand then dereferences it:\n```c\nif (d->start_info->launch_type) {\n job_ctx->startinfo->launch_type = strdup(...);\n} else {\n job_ctx->startinfo->launch_type = NULL; /* :981-985 */\n}\n...\nif (strcmp(job_ctx->startinfo->launch_type, \"openmpi\") == 0 /* :994 */\n```\n`job_start_remote_task()` does the same without a check (`:753`). The apiserver\nsends no launch type when the user gives none (`cStringOrNil`,\n`backend/convert.go:339`). Jobs without a launch type do run in existing\ntests, so the decoder may deliver an empty string rather than NULL: not\nconfirmed either way.\n\n**Expected:** a missing launch type means a plain (non-MPI) job; no NULL\ndereference.\n**Impact:** possible worker crash at job start for jobs without a launch\ntype.\n**Found by:** review of the bug-1940/1942 fixes, 2026-10-10.\n\nUPDATE (2026-10-10): Not confirmed: the generated decoder reads launchType with capn_get_text(..., capn_val0) whose default is {0,\"\",0} and then STRING_DUPs (strdup) it (src/xce.build/lib/controller.capnp.c:6398), so a job start without a launch type reaches the worker as \"\" (non-NULL); strcmp at controller_connector.c:753/994 is safe. job_start_local_task's explicit NULL assignment (:985) is only reachable if start_info->launch_type is NULL, which decoding never produces.",
|
||||
"file": "src/worker/src/controller_connector.c",
|
||||
"root_cause": "TODO: required for fixed/partial",
|
||||
"fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why",
|
||||
|
|
@ -18306,7 +18346,8 @@
|
|||
],
|
||||
"related_bugs": [],
|
||||
"fix_commits": [],
|
||||
"record": ".wolf/bugs/bug-1956.md"
|
||||
"record": ".wolf/bugs/bug-1956.md",
|
||||
"repro_attempts": "decoder analysis 2026-10-10: empty launchType decodes to \"\" (capn_val0 default + strdup), never NULL"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1936"
|
||||
status: "open"
|
||||
status: "partial"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: "exdata/cwd/home now reach the worker; still not honoured end to end: --cwd (job process spawned with cwd NULL, no cwd in job_assignment_t), exec home (no REST field), nofile_limit (not parsed), -i/-o/-e and out_dir, asked hosts and begin/end time (no submit fields), file stage-in/out (not implemented)"
|
||||
component: "apiserver"
|
||||
severity: "wrong-result"
|
||||
timestamp: "2026-10-10T08:14:36Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/frontend/apiserver/backend/convert.go", "src/frontend/apiserver/controllers/jobs.go"]
|
||||
tags: ["apiserver", "submit", "exdata", "limits"]
|
||||
related: []
|
||||
fix_commits: ["d01ced9b"]
|
||||
---
|
||||
|
||||
# bug-1936: apiserver drops cwd, env, run/resource limits, file transfers and I/O paths of REST job submissions
|
||||
|
|
@ -42,15 +43,16 @@ So `--cwd`, `--env`, `--file` transfers, interactive mode, every `*_limit` flag
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`modelJobToSubmit()` (`backend/convert.go`) filled only cmdline, execuser, launch_type and pre/post-exec of `job_startinfo_t`; the extended data `processJobRequest()` (`controllers/jobs.go`) builds (env, limits, transfers, interactive) and the cwd stayed in apiserver memory. Pre-existing, origin not bisected.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
`backend/convert_pure.go`: new pure `submitStartInfo()` sets exdata from `ExtendData`, execcwd (`ExecCWD`, else `CWD`) and exechome; `rawJobToModel` restores `ExtendData`/`CWD`; new `ValidateExdata()` rejects non-object or >16383-byte exdata (the worker would fail the job). `backend/convert.go`: copies/frees the three fields and reads exdata back for jobs and arrays. `controllers/jobs.go`: validates exdata and no longer writes `"transfer_files": null`. The controller passes start info through unchanged (WAL submit facts encode the whole JobStartInfo).
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `TestSubmitStartInfo_CarriesExdataCwdAndHome`, `TestSubmitStartInfo_PrefersExecCWD`, `TestRawJobArrayToModels_RestoresExdataAndCwd`, `TestValidateExdata` (`backend/convert_test.go`), `TestJobHandler_SubmitRejectsNonObjectExtendData` (`controllers/jobs_handler_test.go`): RED before (e.g. `convert_test.go:1272: exdata: got "", want "{\"limits\":{\"run_limit\":60},...}"`), GREEN after.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `d01ced9b` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1937"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "worker"
|
||||
severity: "wrong-result"
|
||||
timestamp: "2026-10-10T08:14:38Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/frontend/apiserver/controllers/jobs.go", "src/worker/src/xcecd_exdata.c"]
|
||||
tags: ["apiserver", "worker", "exdata", "file-transfer"]
|
||||
related: []
|
||||
fix_commits: ["b9747ad2"]
|
||||
---
|
||||
|
||||
# bug-1937: apiserver writes job file transfers under 'transfer_files' but the worker parses 'transfer_file'
|
||||
|
|
@ -38,15 +39,16 @@ else if (strcmp(key, "transfer_file") == 0) { /* xcecd_exdata.c:115 */
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`parse_exdata()` (`src/worker/src/xcecd_exdata.c`) matched only `"transfer_file"`, the apiserver writes `"transfer_files"`. Pre-existing.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
`xcecd_exdata.c`: accepts `"transfer_files"` and still `"transfer_file"`; when both are present the first list is kept (no leak). Stage-in/out itself remains unimplemented (future spec).
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `test_apiserver_transfer_files_parsed` (`src/worker/testsuite/test_exdata_parse.c`): RED `test_exdata_parse.c:73: ... FAIL: Expected 2 Was 0`, GREEN after (5 tests, 0 failures).
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `b9747ad2` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1938"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "scheduler"
|
||||
severity: "wrong-result"
|
||||
timestamp: "2026-10-10T08:14:41Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/scheduler/src/core.c", "src/scheduler/src/plugins/builtin_fcfs.c"]
|
||||
tags: ["scheduler", "queue", "admin-control"]
|
||||
related: []
|
||||
fix_commits: ["f51a19d3"]
|
||||
---
|
||||
|
||||
# bug-1938: xce_scheduler dispatches jobs from closed or inactive queues (queue readiness gate is a stub)
|
||||
|
|
@ -42,15 +43,16 @@ int sched_queue_is_ready(xce_sched_queue_t* q) { return 1; } /* core.c:646-649
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`sched_queue_is_ready()` (`src/scheduler/src/core.c`) was a `return 1` stub, the only queue gate of both pickers (`builtin_fcfs_next_job`, `fcfs_elect_job`); the queue status bits did reach `xce_sched_queue_t`. Pre-existing stub.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
`core.c`: `sched_queue_is_ready()` returns false for `QUEUE_STAT_INACT_ADMIN` or `QUEUE_STAT_INACT_WINDOW`; `QUEUE_STAT_CLOSED` is deliberately not a dispatch gate (LSF: a closed queue still dispatches its pending jobs; closing blocks submissions). Live and sim share the core and picker. Follow-ups: the controller does not reject submissions to a closed queue and the apiserver skips the check for the default queue; no pend reason for held jobs.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `test_inactive_queue_holds_jobs_closed_queue_dispatches` (`src/scheduler/testsuite/test_queue_admin_control.c`): RED `:208: FAIL: Expected 2 Was 3 (an inactive queue dispatches nothing)`, GREEN after on both fixture shapes.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `f51a19d3` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1939"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "scheduler"
|
||||
severity: "wrong-result"
|
||||
timestamp: "2026-10-10T08:14:43Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/scheduler/src/resource.c", "src/scheduler/src/core_session.c", "src/scheduler/src/plugins/parjob_allocator.c"]
|
||||
tags: ["scheduler", "host", "admin-control"]
|
||||
related: []
|
||||
fix_commits: ["1668a439"]
|
||||
---
|
||||
|
||||
# bug-1939: xce_scheduler dispatches jobs to hosts closed by an admin
|
||||
|
|
@ -36,15 +37,16 @@ Host close sets `XCE_WORKER_CLOSED|XCE_WORKER_CLOSED_BY_ADMIN` (`src/controller/
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`sched_host_iter_next()` (`src/scheduler/src/host_iter.c`), the candidate source of both seqjob and parjob allocators, filtered only on select and free resources, never on `XCE_WORKER_CLOSED`/`CLOSED_BY_ADMIN`; parjob's `skip_bad_worker_` is unused. Pre-existing.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
`host_iter.c`: a host with either closed bit is skipped before its trace scope opens, so no new placement (serial or parallel, live or sim) lands on it; running jobs and accounting are unchanged. No new pend-reason code.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `test_admin_closed_host_gets_no_new_jobs` (`src/scheduler/testsuite/test_host_admin_close.c`): RED `:200: FAIL: Expected 0 Was 3 (the admin-closed host must get no new usage)`, GREEN after (serial and parallel, both fixture shapes).
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `1668a439` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1940"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "apiserver"
|
||||
severity: "wrong-result"
|
||||
timestamp: "2026-10-10T08:14:46Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/frontend/apiserver/controllers/jobs.go", "src/frontend/apiserver/backend/clib.go"]
|
||||
tags: ["apiserver", "job-control", "signal"]
|
||||
related: []
|
||||
fix_commits: ["4d2e80c4"]
|
||||
---
|
||||
|
||||
# bug-1940: job control ignores the requested signal and the force-kill flag (apiserver to controller)
|
||||
|
|
@ -36,15 +37,16 @@ The control handler passes a JSON event string as content (`controllers/jobs.go:
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`ControlJob` (`backend/clib.go`) treated its content (a JSON event) as a signal name, so the lookup always missed and fell back to TERM/TSTP/CONT; it also hard-coded `force = 0`, `ckpt.kill = 0` and never set the checkpoint method. Pre-existing.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
`backend/convert_pure.go`: new pure `jobCtrlParams()` parses the JSON event or a bare signal name/number, validates it against `JobSignalMapTable` (error instead of fallback), maps force_kill to the signal's force (kill) or the checkpoint's kill flag, and passes the method; `backend/clib.go` fills the C structs from it. Worker-side substitution of the delivered signal was a separate defect, bug-1954.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `TestJobCtrlParams_*` (`backend/jobctrl_params_test.go`): RED `jobctrl_params_test.go:34: kill USR1 force_kill: got signo 15 force 0, want signo 10 force 1` and the checkpoint case, GREEN after (6 tests).
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `4d2e80c4` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1941"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "controller"
|
||||
severity: "wrong-result"
|
||||
timestamp: "2026-10-10T08:14:48Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/controller/job.c"]
|
||||
tags: ["controller", "job-control", "host-status"]
|
||||
related: []
|
||||
fix_commits: ["f244661b"]
|
||||
---
|
||||
|
||||
# bug-1941: xce_controller refuses kill/stop/resume of running jobs on hosts whose status is not exactly OK
|
||||
|
|
@ -40,15 +41,16 @@ Any other status bit (CLOSED_BY_ADMIN, BUSY, UNAVAIL...) makes the control reque
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`job_ctrl()` (`src/controller/job.c`) sent control only if `w->host.status == 0` and returned `-errno` otherwise. Pre-existing FIXME.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
`job.c`: new `job_ctrl_to_host()` sends whenever the worker is connected (endpoint present, not UNAVAIL), so CLOSED/CLOSED_BY_ADMIN/BUSY/locked hosts work; an unknown or unconnected host fails with `-E_XCE_BAD_WORKER` and an error log naming it.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `test_jc_connected_flagged_host_is_controllable` and `test_jc_unconnected_host_fails_with_bad_worker` (`src/controller/testsuite/test_job_ctrl_hosts.c`): RED `:239: FAIL: Expected 0 Was -2 (status 0x100000)` and `Expected -10002 Was -22`, GREEN after (asserts the decoded request in the worker send queue).
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `f244661b` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1942"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "controller"
|
||||
severity: "wrong-result"
|
||||
timestamp: "2026-10-10T08:14:51Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/controller/job.c"]
|
||||
tags: ["controller", "job-control", "parallel"]
|
||||
related: []
|
||||
fix_commits: ["8568c8ab"]
|
||||
---
|
||||
|
||||
# bug-1942: xce_controller sends job control of a multi-host job only to its first host
|
||||
|
|
@ -36,15 +37,16 @@ Job control is routed to `allocs[0]->host` only (`src/controller/job.c:2126-2131
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`job_ctrl()` (`src/controller/job.c`) routed control to `allocs[0]->host` only. Remote tasks (started via runtasks by the head worker or by xrun) run under their own host's worker entry, and the head worker signals only its own process group, so signals never reached other hosts.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
`job.c:job_ctrl`: sends the request to every allocated host through `job_ctrl_to_host` (queue-only, non-blocking); the head host decides the result; an unconnected non-head host is logged and skipped. A remaining worker-side window (signal while a remote task starts) was bug-1955.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `test_jc_multi_host_job_reaches_every_host` and two related tests (`test_job_ctrl_hosts.c`): RED `:305: FAIL: Expected 1 Was 0 (host jch-h1 of a 3-host job must get the control)`, GREEN after.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: not run: a live `/xce-test-multihost` stop/kill check is a follow-up
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `8568c8ab` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1943"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "scheduler"
|
||||
severity: "wrong-result"
|
||||
timestamp: "2026-10-10T08:14:54Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/scheduler/src/core_events.c", "src/scheduler/src/scheduler.c"]
|
||||
tags: ["scheduler", "sim", "equivalence", "limit"]
|
||||
related: []
|
||||
fix_commits: ["8b89a0ce"]
|
||||
---
|
||||
|
||||
# bug-1943: xce_scheduler --sim does not load user and host groups, so group-scoped limits differ from live
|
||||
|
|
@ -36,15 +37,16 @@ On a config push the live scheduler loads user and host groups (`groupmgr_load_c
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
Only `sched_init_config()` (`scheduler.c`, live) called `groupmgr_load_configs`; the core `CONFIG_PUSH` event (`core_events.c:xce_core_push_events`) and the replay snapshot loader (`snapshot_load.c:xce_sched_core_load_snapshot`, from which `sim_bootstrap_limit_plugin` seeds limits) never loaded groups. Pre-existing.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
`core.h`/`core.c`: new `xce_core_load_groups()` is the single loader, called from `sched_init_config()` (replacing its direct calls), the `CONFIG_PUSH` event (first) and `snapshot_load.c` (before the limit plugin is seeded); `snapshot.c` field-completeness note updated. Follow-up: limits are not re-seeded on a mid-replay CONFIG_PUSH.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `test_user_group_limit_matches_in_sim_as_in_live` (`src/scheduler/testsuite/test_sim_group_limit_parity.c`): RED `:318: FAIL: Expected 1 Was 0 (sim must match the user-group-scoped limit)`, and with only the CONFIG_PUSH part reverted `:334: FAIL: CONFIG_PUSH must register the config's user groups`, GREEN after.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `8b89a0ce` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1944"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "scheduler"
|
||||
severity: "wrong-result"
|
||||
timestamp: "2026-10-10T08:14:56Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/scheduler/src/core_events.c", "src/scheduler/src/schedobj.c"]
|
||||
tags: ["scheduler", "queue", "priority"]
|
||||
related: []
|
||||
fix_commits: ["7a9d75d6"]
|
||||
---
|
||||
|
||||
# bug-1944: xce_scheduler gives a job moved to another queue the queue's priority, so it jumps ahead
|
||||
|
|
@ -36,15 +37,16 @@ New jobs get priority 0 (`schedobj.c:214`, `core_events.c:353`), but on a queue
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
On a queue change both `xce_core_push_events` (`JOB_UPDATE`, `core_events.c`) and `sched_update_existing_job` (`schedobj.c`) set `job->priority = q->priority`; new jobs and snapshot-restored jobs get 0, so moved jobs jumped ahead and live/replay disagreed. Pre-existing.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
Both sites now only re-point `job->queue` on a move; queue priority still orders the queues. `test_job_update.c`, which asserted the old behaviour, now expects the job's own priority.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `test_moved_job_keeps_its_priority_and_place` (`src/scheduler/testsuite/test_job_move_priority.c`): RED `:208: FAIL: Expected 0 Was 10` (and `:214: Expected 2 Was 1` for the ordering), GREEN after; `test_update_existing_job_mutates_in_place` RED `Expected 1 Was 5` with the corrected expectation, GREEN after.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `7a9d75d6` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1945"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "apiserver"
|
||||
severity: "security"
|
||||
timestamp: "2026-10-10T08:14:59Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/frontend/apiserver/config/app.yaml", "src/frontend/apiserver/utils/config.go"]
|
||||
tags: ["apiserver", "security", "jwt"]
|
||||
related: []
|
||||
fix_commits: ["19a1a6f0"]
|
||||
---
|
||||
|
||||
# bug-1945: apiserver signs and accepts JWTs with the shipped default secret when XCE_JWT_SECRET is unset
|
||||
|
|
@ -36,15 +37,17 @@ related: []
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`resolveJWTSecret()` (`utils/config.go`) fell back to the shipped `xce-api-key` when `XCE_JWT_SECRET` was unset.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
Empty or the old default secret (env or config) counts as unset: the apiserver generates a random 256-bit per-process secret and logs a warning (tokens do not survive restart; apiservers behind one endpoint must share `XCE_JWT_SECRET`); the secret is never logged; `app.yaml` ships `secretKey: ""`. Docs updated in 27ef5060.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `TestResolveJWTSecret_NeverUsesKnownDefaultOrEmpty`, `TestShippedAppYAML_NoJWTSecret`, `TestInitConf_NoJWTSecretGeneratesAndWarns` (`utils/config_test.go`): RED (`... = "xce-api-key": must be a generated secret`), GREEN after.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `19a1a6f0` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
- docs: 27ef5060
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1946"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "apiserver"
|
||||
severity: "security"
|
||||
timestamp: "2026-10-10T08:15:01Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/frontend/apiserver/controllers/auth.go", "src/frontend/apiserver/middleware/validatehandler.go"]
|
||||
tags: ["apiserver", "security", "jwt"]
|
||||
related: []
|
||||
fix_commits: ["4ce4f0b7"]
|
||||
---
|
||||
|
||||
# bug-1946: apiserver logout does not revoke the token: it stays valid until expiry
|
||||
|
|
@ -36,15 +37,16 @@ Logout deletes a token file (`controllers/auth.go:69-95`) that token validation
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`AuthController.Logout` (`controllers/auth.go`) only removed a token file that token validation (`middleware/validatehandler.go`) never reads.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
New `controllers/token_revocation.go`: revoked token IDs kept until expiry, purged on each revocation; `generateJWT` sets a random `jti`; tokens without one are revoked by hash; new `ParseTokenClaims` (used by ValidateHandler, RequirePermission, GetUsernameFromToken) rejects revoked tokens. Per process only (not persisted or shared). Follow-up: `xcecli logout` never calls the logout API.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `TestLogout_RevokesToken` (`middleware/validatehandler_test.go`): RED `after logout: status = 200, want 401`, GREEN after; plus `TestTokenRevocations_ExpiryAndPurge`, `TestIntegration_PostLogoutTokenRejected`.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `4ce4f0b7` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1947"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "apiserver"
|
||||
severity: "security"
|
||||
timestamp: "2026-10-10T08:15:04Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/frontend/apiserver/backend/auth/config_file.go", "src/frontend/apiserver/config/auth.yaml"]
|
||||
tags: ["apiserver", "security", "auth"]
|
||||
related: []
|
||||
fix_commits: ["f91642db"]
|
||||
---
|
||||
|
||||
# bug-1947: apiserver config-file auth compares plaintext passwords with != and ships admin/admin defaults
|
||||
|
|
@ -35,15 +36,16 @@ related: []
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`ConfigFileProvider.Authenticate` (`backend/auth/config_file.go`) compared the stored plaintext with `!=`; `auth.yaml` shipped plaintext defaults.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
bcrypt hashes accepted; plaintext entries still work but compare in constant time; unknown users cost the same bcrypt work; `SecurityWarnings()` + startup warnings for plaintext entries and active shipped default passwords; `auth.yaml`/`auth.yaml.example` ship bcrypt hashes of the same dev passwords (dev tooling such as `tests/regression/run.sh` keeps working); `tools/encrypt -action=hash`; `golang.org/x/crypto/bcrypt` vendored from the already pinned x/crypto v0.23.0.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `TestConfigFileProvider_BcryptPassword`, `TestShippedAuthConfig_HashedDefaults`, `TestConfigFileProvider_SecurityWarnings` (`backend/auth/config_file_test.go`): RED (e.g. the stored hash itself was accepted as a password; `shipped password is not a bcrypt hash`), GREEN after.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `f91642db` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1948"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "apiserver"
|
||||
severity: "security"
|
||||
timestamp: "2026-10-10T08:15:06Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/frontend/apiserver/router/routers.go"]
|
||||
tags: ["apiserver", "security", "whitelist"]
|
||||
related: []
|
||||
fix_commits: ["c4c63f11"]
|
||||
---
|
||||
|
||||
# bug-1948: apiserver trusts X-Forwarded-For from any client, so IP whitelist and JWT IP binding can be spoofed
|
||||
|
|
@ -36,15 +37,16 @@ The router uses `gin.Default()` (`router/routers.go:19`) and never calls `SetTru
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`router.Router()` used `gin.Default()` without `SetTrustedProxies`, so `ClientIP()` honoured X-Forwarded-For from any peer.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
New `app.yaml` option `security.trusted_proxies` (IP/CIDR, default empty = none), validated at startup; `Router()` passes it to `SetTrustedProxies` (falls back to none if invalid); schema and nginx samples documented.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `TestRouter_IgnoresForwardedForByDefault` (`router/routers_test.go`, real `Router()`): RED `non-whitelisted peer spoofing X-Forwarded-For: status = 200, want 403`, GREEN after; plus `TestRouter_HonoursForwardedForFromTrustedProxy`, `TestResolveTrustedProxies`.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `c4c63f11` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1949"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "apiserver"
|
||||
severity: "security"
|
||||
timestamp: "2026-10-10T08:15:09Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/frontend/apiserver/controllers/rbac_check.go", "src/frontend/apiserver/middleware/whitelist.go", "src/frontend/apiserver/controllers/response.go"]
|
||||
tags: ["apiserver", "security", "middleware"]
|
||||
related: []
|
||||
fix_commits: ["42a402a5"]
|
||||
---
|
||||
|
||||
# bug-1949: apiserver RequirePermission and IP whitelist write an error but do not abort the request
|
||||
|
|
@ -35,15 +36,16 @@ On a bad token `RequirePermission` returns an error response without `Abort()` (
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`RequirePermission` (`controllers/rbac_check.go`) and `WhitelistIPMiddleware` (`middleware/whitelist.go`) wrote an error via `ReturnError` without `ctx.Abort()`.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
`ctx.Abort()` added at both sites and on ValidateHandler's request-body check; a bad token in RequirePermission now answers 401 (was 500). `ReturnError` stays non-aborting (documented): `hosts.go` relies on `ctx.IsAborted()` after a helper's error. Follow-up: `ControlHost` can still write twice if reached.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `TestRequirePermission_AbortsOnInvalidToken` (`controllers/rbac_abort_test.go`): RED `handler ran after RequirePermission failed (status 500)`; `TestWhitelistIPMiddleware_AbortsOnFailure/unparsable_client_IP`: RED `handler ran after the IP whitelist rejected`; GREEN after.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `42a402a5` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1950"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "apiserver"
|
||||
severity: "security"
|
||||
timestamp: "2026-10-10T08:15:11Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/frontend/apiserver/middleware/validatehandler.go"]
|
||||
tags: ["apiserver", "security", "jwt"]
|
||||
related: []
|
||||
fix_commits: ["42dd1e7a"]
|
||||
---
|
||||
|
||||
# bug-1950: apiserver JWT validation does not pin the signing algorithm
|
||||
|
|
@ -35,15 +36,16 @@ The middleware's parse callback returns the key without checking `token.Method`
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`isValidToken()` (`middleware/validatehandler.go`) never checked `token.Method`; `GetUsernameFromToken` accepted any HMAC variant.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
`controllers/auth.go`: `JWTSigningMethod` (HS256), `JWTKeyFunc`, `JWTValidMethods()`; both parse paths use them.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `TestIsValidToken_PinsSigningAlgorithm` (`middleware/validatehandler_test.go`): RED `isValidToken(HS384) = true, want false`; `TestGetUsernameFromToken_PinsSigningAlgorithm`: RED; GREEN after.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `42dd1e7a` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1951"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "apiserver"
|
||||
severity: "crash"
|
||||
timestamp: "2026-10-10T08:15:14Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/frontend/apiserver/backend/auth/config_file.go"]
|
||||
tags: ["apiserver", "auth", "config", "crash"]
|
||||
related: []
|
||||
fix_commits: ["d3ce2982"]
|
||||
---
|
||||
|
||||
# bug-1951: apiserver crashes on an auth.yaml without a config_file block (nil pointer)
|
||||
|
|
@ -35,15 +36,16 @@ related: []
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`NewConfigFileProvider` (`backend/auth/config_file.go:39`) dereferenced `cfg.ConfigFile` without a nil check.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
Returns a clear configuration error when the `config_file` block is missing.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `TestNewConfigFileProvider_Errors/missing_config_file_block` (`backend/auth/config_file_test.go`): RED `panic: runtime error: invalid memory address or nil pointer dereference`, GREEN after.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `d3ce2982` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1952"
|
||||
status: "investigating"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "suspected from source reading; confirm with a test before fixing"
|
||||
status_note: ""
|
||||
component: "apiserver"
|
||||
severity: "security"
|
||||
timestamp: "2026-10-10T08:15:16Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/frontend/apiserver/controllers/users.go"]
|
||||
tags: ["apiserver", "security", "rbac"]
|
||||
related: []
|
||||
fix_commits: ["a80768f3"]
|
||||
---
|
||||
|
||||
# bug-1952: apiserver user role changes check a narrower rbac:control grant only against the target user
|
||||
|
|
@ -35,15 +36,16 @@ Suspected (needs verification): in add/delete roles for a user, a non-`all` `rba
|
|||
- Frequency: deterministic (by code reading; confirmed by the RED test of the fix)
|
||||
- Evidence: the code sites quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`UserController.AddRolesForUser`/`DeleteRolesForUser` (`controllers/users.go`) only checked whether the target was the caller for a non-`all` `rbac:control` grant; `self` is an accepted rbac scope (`models/roles.go:78`), so a user holding only `rbac:control` scope `self` could grant itself `cluster_admin`.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
`canChangeUserRoles`: changing anyone's roles (the caller's included) requires an `rbac:control` grant with scope `all`, checked over all grants before deduplication; anything else gets 403. Follow-up: any `rbac:control` scope can still create roles and add permissions to a role the caller holds (`roles.go`), the same escalation by another route.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `TestAddRolesForUser_SelfScopeCannotGrantItselfRoles` (`controllers/users_rbac_test.go`): RED `privilege escalation: mallory (rbac:control scope self) granted itself cluster_admin (status 200)`, GREEN after; plus `TestDeleteRolesForUser_SelfScopeRejected`, `TestUserRoleChanges_AllScopeAllowed`.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `a80768f3` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1953"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "apiserver"
|
||||
severity: "wrong-result"
|
||||
timestamp: "2026-10-10T08:42:56Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/frontend/apiserver/controllers/jobs.go"]
|
||||
tags: ["apiserver", "submit", "validation"]
|
||||
related: ["bug-1936"]
|
||||
fix_commits: ["e00526f9"]
|
||||
---
|
||||
|
||||
# bug-1953: apiserver skips submit validation and limit conversion for any job submitted with a job name
|
||||
|
|
@ -59,15 +60,16 @@ lose their shell limits, and fail at the worker when they carry transfers.
|
|||
- Frequency: deterministic (code path)
|
||||
- Evidence: the code quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`preCheckJobRequest()` (`controllers/jobs.go`) returned from inside its job-name branch (`return count, true, nil` / `return 1, false, nil`), so everything after it was skipped for named and array jobs. Pre-existing.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
The name branch now only sets `n`/`isArray`; the function continues through every check and conversion and returns `n, isArray, nil` at the end.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `TestPreCheckJobRequest_NamedJobsGetFullValidation` (`controllers/jobs_test.go`): RED `name "myjob": cpu limit not converted: got 0 s, want 60` and `an over-long project name was accepted` (same for `arr[1-3]`), GREEN after; whole controllers package ok.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `e00526f9` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1954"
|
||||
status: "open"
|
||||
status: "fixed"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: ""
|
||||
component: "worker"
|
||||
severity: "wrong-result"
|
||||
timestamp: "2026-10-10T08:46:07Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/worker/src/xcecd_worker.c"]
|
||||
tags: ["worker", "job-control", "signal"]
|
||||
related: ["bug-1940"]
|
||||
fix_commits: ["148557a5"]
|
||||
---
|
||||
|
||||
# bug-1954: xcecd_worker sends SIGTERM for a KILL request without force and SIGSTOP for a TSTP request
|
||||
|
|
@ -55,15 +56,16 @@ do so.
|
|||
- Frequency: deterministic by code reading (not yet run)
|
||||
- Evidence: the code quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
`worker_signal_callback()` (`src/worker/src/xcecd_worker.c`) mapped TERM/KILL to `force ? SIGKILL : SIGTERM` and STOP/TSTP to SIGSTOP; the apiserver's default stop signal was TSTP, relying on that substitution.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
New `job_signal_to_deliver()` (`src/worker/src/job_signal.c`, `include/job_signal.h`) delivers the requested signal; only a forced TERM escalates to SIGKILL; the callback uses it. The apiserver's default stop signal becomes SIGSTOP (`backend/convert_pure.go` `defaultActionSignal`, `models.DefaultActionSignal`), so a plain stop still suspends jobs that ignore SIGTSTP; the bug-1940 test pinning stop=20 now expects 19.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `test_requested_signal_is_delivered` (`src/worker/testsuite/test_job_signal.c`): RED `test_job_signal.c:14: FAIL: Expected 9 Was 15` (KILL without force), GREEN after; `TestJobCtrlParams_PlainStopSendsSigstop` (`backend/jobctrl_params_test.go`): RED `DefaultActionSignal[stop] = "TSTP", want STOP`, GREEN after.
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `148557a5` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1955"
|
||||
status: "open"
|
||||
status: "partial"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "newly logged"
|
||||
status_note: "covers a signal arriving after this host accepted the runtasks request; a control that reaches a remote host before its runtasks request arrives is still dropped there (needs a controller-side or pre-start record)"
|
||||
component: "worker"
|
||||
severity: "wrong-result"
|
||||
timestamp: "2026-10-10T08:46:10Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/worker/src/controller_connector.c"]
|
||||
tags: ["worker", "job-control", "parallel", "signal"]
|
||||
related: ["bug-1942", "bug-1908"]
|
||||
fix_commits: ["d3da3140"]
|
||||
---
|
||||
|
||||
# bug-1955: xcecd drops a signal for a remote task of a multi-host job that is still starting
|
||||
|
|
@ -51,15 +52,16 @@ starts can miss some of its remote tasks, which keep running.
|
|||
- Frequency: deterministic by code reading (not yet run)
|
||||
- Evidence: the code quoted in Description; no logs kept.
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
Only the head-host start path opened the pending-signal window (`pending_signal_start`, `controller_connector.c`, bug-1908); `handle_runtasks()` queued remote tasks without it, so a signal arriving before the task's worker entry registered hit "Failed to find worker" and was dropped.
|
||||
|
||||
## Fix
|
||||
TODO: required for fixed/partial
|
||||
`handle_runtasks()` calls `pending_signal_start(jobid)` before `submit_fork_task()` and takes it back if queuing fails; the existing RUNNING transition (`xcecd_worker_utils.c`, bug-1908) delivers the kept signal to the task.
|
||||
|
||||
## Verification
|
||||
- Test: TODO: name + file; RED before the fix, GREEN after
|
||||
- Suites: TODO: suite results and build profile
|
||||
- Live: TODO: soak/deploy run, or n/a and why
|
||||
- Test: `test_jobcontrol_signal_for_queued_remote_task_is_kept` (`src/worker/testsuite/test_controller_connector.c`): RED `:1631: FAIL: Expected 0 Was -1. the kill must not be dropped`, GREEN after (32 tests, 0 failures).
|
||||
- Suites: `xce-build.sh all asan xce.build --incremental` on the merged branch, 2026-10-10: all C suites Ok 155 / Fail 0, frontend Go unit tests ok, xceadmin tests ok; apiserver `CGO_ENABLED=0 go test ./...` (incl. middleware, router, cmd) ok
|
||||
- Live: n/a: unit/fixture-level verification only; no live deployment was run (follow-up)
|
||||
|
||||
## References
|
||||
- Related: none
|
||||
- Fix commit: `d3da3140` (on `scheduler-framework`; worker-branch original in the merge)
|
||||
- Review: `.kiro/reviews/project-gap-review-2026-10-10.md`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
id: "bug-1956"
|
||||
status: "investigating"
|
||||
status: "cannot-reproduce"
|
||||
status_updated: "2026-10-10"
|
||||
status_note: "suspected: confirm whether a job without launch type decodes to NULL at the worker"
|
||||
status_note: "no NULL path from the wire; the explicit NULL branch in job_start_local_task is unreachable through decoding"
|
||||
component: "worker"
|
||||
severity: "crash"
|
||||
timestamp: "2026-10-10T08:46:13Z"
|
||||
|
|
@ -11,6 +11,7 @@ occurrences: 1
|
|||
files: ["src/worker/src/controller_connector.c"]
|
||||
tags: ["worker", "crash", "launch-type"]
|
||||
related: []
|
||||
repro_attempts: "decoder analysis 2026-10-10: empty launchType decodes to \"\" (capn_val0 default + strdup), never NULL"
|
||||
---
|
||||
|
||||
# bug-1956: xcecd compares a NULL launch_type with strcmp when a job has no launch type (possible crash)
|
||||
|
|
@ -39,6 +40,9 @@ dereference.
|
|||
**Impact:** possible worker crash at job start for jobs without a launch
|
||||
type.
|
||||
**Found by:** review of the bug-1940/1942 fixes, 2026-10-10.
|
||||
|
||||
UPDATE (2026-10-10): Not confirmed: the generated decoder reads launchType with capn_get_text(..., capn_val0) whose default is {0,"",0} and then STRING_DUPs (strdup) it (src/xce.build/lib/controller.capnp.c:6398), so a job start without a launch type reaches the worker as "" (non-NULL); strcmp at controller_connector.c:753/994 is safe. job_start_local_task's explicit NULL assignment (:985) is only reachable if start_info->launch_type is NULL, which decoding never produces.
|
||||
|
||||
## Environment
|
||||
- OS: no /etc/os-release; Docker container; NixOS kernel; kernel Linux 6.18.33 x86_64
|
||||
- libc: glibc 2.42-47 (interpreter /nix/store/wb6rhpznjfczwlwx23zmdrrw74bayxw4-glibc-2.42-47/lib/ld-linux-x86-64.so.2)
|
||||
|
|
@ -54,6 +58,7 @@ type.
|
|||
2. Check whether `startinfo->launch_type` is NULL at `:994`.
|
||||
- Frequency: deterministic by code reading (not yet run)
|
||||
- Evidence: the code quoted in Description; no logs kept.
|
||||
|
||||
## Root cause
|
||||
TODO: required for fixed/partial
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue