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:
Rongsong Shen 2026-10-10 09:15:15 +00:00
parent d3da314041
commit e5a0e42b66
Signed by untrusted user: rshen
GPG key ID: 80533536B0EB651C
22 changed files with 353 additions and 266 deletions

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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`

View file

@ -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