Commit graph

384 commits

Author SHA1 Message Date
lei.chen
b38ef6de63 fix(testsuite): resize crr_build_config caller arrays -- bug-1977
The external-license-resources E2 fixture builder crr_build_config
registers five resources and four distributions, writing resources[4],
dists[3] and vals[4]. All four caller test functions declared only
resources[4]/dists[3]/vals[4], so every build_config call wrote past
the caller's stack arrays -- deterministic ASAN stack-buffer-overflow,
the whole controller suite (137 fixtures) red since 2fcacac2.

Resize the four caller arrays to match the builder's sizing
(resources[5]/dists[4]/vals[5]) with a bug-1977 comment on the sizing
contract. No production code touched.

Verified: src/tools/xce-build.sh controller (asan) 6/6 OK, controller
suite 91s green; buglog record .wolf/bugs/bug-1977.md.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-28 11:58:19 +00:00
lei.chen
13a28a387a wolf: log bug-1976 fixed (controller dispatch commit dropped allocs_shared)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-28 05:40:03 +00:00
lei.chen
3eb1b9716d wolf: mark bug-1973/1974/1975 fixed (commit 2fcacac2)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-27 03:45:49 +00:00
lei.chen
2fcacac2cb E2 Phase 1: external-license-resources — xceesd daemon, extres role, EXTERNAL admission
Implements Phase 1 of .kiro/specs/external-license-resources/ (design.md):
externally-reported license pools pushed by a dedicated daemon through the
existing resval pipeline, with EXTERNAL-aware admission arithmetic.

Wire & controller:
- controller.capnp HostRole.extres (@5, appended); xce_join_req accepts it
- extres.c: HostRole_extres join table (endpoint+name, no workermgr slot),
  leave cleanup; join.c/cluster.c dispatch
- opupd.c do_update_resvals: extres branch runs the resource hooks and
  update_resval_list(c, NULL, ...) — host=="" entries route through
  update_val_res' SHARED branch into c->sharedinst; per-entry -EPERM for
  non-shared targets is logged, never fails the list
- worker.c update_val_res: NULL worker only writes SHARED resources
- cluster.c cluster_build_resources: rebuilt on resourceApplyDef (bug-1854)
  — EEXIST-tolerant so definitions added by an activation register on a
  RUNNING controller (bug-1973), and RES_APPLY_CHANGED updates definition
  fields (valtype/ordtype/flags/interval) in place so a corrected config
  heals a stale registration (bug-1974); seed_sharedinst_from_config skips
  EXTERNAL pools (daemon-reported free counts only; seeding would fabricate
  capacity while the daemon is down)

Scheduler:
- core_events.c RESVALS_DELTA: NULL/"" host marks a SHARED value and lands
  in core->sharedInst via dup_val (bug-1585 ownership rule), mirroring
  snapshot_load's host=="" precedent — previously WARN-skipped as unknown
  worker
- resource.c unsatisfy_: EXTERNAL skips the inuse term
  (F >= uncomit + wanted; F is already net of our checkouts)

xceesd (src/esd, new component):
- script collectors polled per source, debounce on unchanged values,
  fail-open stale policy; pushes host=="" shared resvals over xcecli
- reconnect gap fix (bug-1975): with a stable value the debounce pushed
  nothing and reconnects only fire inside a push — after a controller
  restart the daemon sat on a dead connection forever; the main loop now
  forces a full re-push when xcecli_is_connection_broken() (bug-1760
  predicate) latches

Config/mapping:
- resources.yaml: extlic sample (location: [external])
- mapping.py: RESOURCE_FLAG_EXTERNAL (0x10) + location:["external"] mapping;
  xceadmin tests

Tests (TDD, red->green per fix): test_extres_resvals.c (join+resval
pipeline), test_config_resource_reconcile.c +2 (register past EEXIST /
hot-apply changed definition), test_core_events.c +131 lines (shared DELTA
landing), mapping tests. Suites: controller 1358/0, scheduler 100/0,
esd 7/0, lib 1/0; check-no-fork covers src/esd.

Live t1 E2E: config gen=15 push -> xceesd push extlic=4 lands in
sharedinst -> rusage[extlic=3] job RUN; second job PENDs at free=1;
release re-admits it; controller restart -> forced re-push restores the
value and admission resumes. Full precommit job verification passed.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-27 03:45:28 +00:00
lei.chen
ba42fdd82e wolf: mark bug-1972 fixed (commit f780a166)
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-26 14:03:05 +00:00
lei.chen
f780a1660a A-batch admin-plane fixes: rusage unit name, XCE_JOBID identity, select WARN, CLI env, docs
rusage collection (merge cb0c7fe9 regression, root cause of 0 counters):
- collect_job_rusages builds the systemd unit name with
  make_job_sd_unit_name (four-segment fmt_jobid_ex form) instead of a bare
  %lu of the packed uint64, so the D-Bus property lookups hit the real
  per-job unit again. E2E on t1: DONE job reports max_mem/avg_mem/cpu_time
  non-zero (previously all 0).

XCE_JOBID written identity:
- exdata sets XCE_JOBID via fmt_jobid (four-segment
  cluster-apiserver-timestamp-seq) instead of a bare packed decimal;
  XCE_JOBINDEX handling unchanged.
- xrun parses XCE_JOBID with parse_jobid (accepts the four-segment form);
  a bare decimal no longer round-trips through the written identity.
- E2E on t1: job sees XCE_JOBID=<submit id>; xrun remote-start round-trip
  to another host matches the job.

select WARN (silent degradation):
- parse_resreq_primary WARNs when a select references an unregistered
  resource ("...references an unregistered resource -- dropping the select
  and skipping any rusage[] clause of this primary") instead of failing
  silently; scheduler log shows the WARN on t1 and the job schedules
  without the constraint.

CLI env handling (unit-tested; subEnvVars is not flag-bound so this is
not reachable from the production CLI):
- getEnvironmentVariables keeps B=b=c (split at first '=') and warns +
  drops a bare key or an '=value' fragment instead of silently mis-parsing.

Docs:
- src/docs/xce.md: document the dead-clause semantics (select/rusage
  primary drop behavior) matching the WARN.

bug-1972 (test-only UAF): test_job_live_gc asserted job destruction by
reading refcount from the freed job; rewrite the assertion to observe
destruction without touching freed memory. controller_unit_test is green
again (1354 tests).

Regenerate 3 repl_trace_baseline fixtures whose baselines shifted with the
select-WARN logging; replay tests green.

Spec naming: external-license-resources design.md/brief.md fix the
self-referential daemon-name note (old drafts said xceextresd/extresd).

Verified on t1: rusage_burn job (counters non-zero in DONE), echo_env job
(four-segment XCE_JOBID), select[nosuchres] job (WARN + schedules),
xrun t2 remote-start round-trip, CLI env unit tests, xcelib 762 /
controller 1354 / worker exdata 8+11 / sched repl_trace 4+14+4+10+17
tests green.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-26 14:02:53 +00:00
lei.chen
993daa8f95 bug-1971: fix_commits field via buglog.py status
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-22 08:08:44 +00:00
lei.chen
d8f738b08a bug-1971: mark fixed, record fix commit 68c3ccd7
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-22 08:08:15 +00:00
lei.chen
68c3ccd773 bug-1971: preserve flaky test-failure evidence across xce-build.sh runs
A failed test run's evidence (meson-logs/testlog.txt + the mkdtemp sweep's
FAILED-case /tmp/xce_* fixture dirs) was destroyed by the next build:
setup_build rm -rf's the build dir, and any subsequent meson test overwrites
testlog.* in place. t2 2026-10-22: a controller case failed at ~05:46, the
make clean + rerun at ~05:52 left 134/134 OK and zero trace of what failed.

Two chokes in xce-build.sh:
- finalize_failure_evidence (EXIT trap): on rc!=0 with RUN_TESTS=1, copy
  meson-logs to testlogs.archive/<BUILD_DIR>/this-<stamp>-rc<N>/ and drop
  the .meson_test_failed_rc marker; also releases the build lock (the old
  lock-release trap folded in).
- archive_previous_failure (run start, pre-wipe): if the marker exists,
  move the previous run's meson-logs to prev-<stamp>-rc<N>/ -- outside the
  build dir, unreachable by the wipe; sweep aged (>5 min) /tmp/xce_*
  FAILED-case fixture dirs into prev-<stamp>-fixtures/ so they sit with the
  testlog that explains them; cap the archive at newest 10 per build dir.

Also -type d on BOTH /tmp/xce_* sweeps (this one and bug-924's
prune_stale_tmp_fixtures): mkdtemp fixtures are always directories, but
the bare name also matches regular files -- the untyped find live-moved
daemon debug logs (xce_scheduler.log, xce_strace*.log) into the archive,
and the bug-924 variant rm -rf's its matches.

Test: src/tools/test-failure-evidence-archive.sh, 6 scenarios / 11
assertions exercising the real function bodies (sourced with surgical
stubbing) -- all green.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-22 08:08:01 +00:00
lei.chen
3b6f53bb65 merge: sync Rongsong's scheduler-framework (122 commits, 070c7869..f01ae353)
Introduces WAL replay field-completeness fixes (bug-1687..1697, 1731), scheduler snapshot job-allocation restore, heap UAF fixes (vtask_enq, xcealloc, builtin_fcfs, limit), HA fixes (bug-1694/1695/1696), xceadmin retry, worker signal-exit severity, and their test suites.

Conflicts resolved keeping both sides (drop-audit passed):
- worker.c: mark_worker_jobs_exit (bug-1509 B1) + fetchfile_signal_worker_disconnect (bug-1693)
- handler.go: DefaultBroker.Publish (EventJobFinished) + bug-1731 logging
- config_repl.c / test_config_repl.c: our ns-resolution comment / unique-tmpdir
- test_dispatch_commit.c: both B3-UNKWN and bug-1697 start_time assertions

Excluded Rongsong's bookkeeping per policy: .wolf/, .kiro/, CHANGES.md, reports/;
.claude/ + CLAUDE.md kept ours (his settings.json has machine-absolute paths).
2026-08-31 14:24:17 +00:00
f01ae353ef
docs: sync OpenWolf state
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QxaSzHRB7pmYFp4cVnwkA
2026-08-30 16:04:52 +00:00
1c4a1ba24a
docs: sync OpenWolf state
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QxaSzHRB7pmYFp4cVnwkA
2026-08-30 15:32:16 +00:00
ccd7fc2184
docs: sync OpenWolf state
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QxaSzHRB7pmYFp4cVnwkA
2026-08-30 15:08:15 +00:00
22aa16bf06
docs: sync OpenWolf state
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QxaSzHRB7pmYFp4cVnwkA
2026-08-30 03:55:59 +00:00
a02d47772b
fix(bug-1561): fix flaky test_conf_trim_keeps_only_n_versions/test_conf_get_saved_tag_no_config
Two root causes, confirmed by direct code reading (previously misattributed
to an overlayfs sandbox fdatasync artifact):

conf_trim_old_versions() sorted config-version files by st_mtime (second
resolution). The test writes 3 versions 15ms apart -- well within one
second, so ties are the expected outcome, not a rare edge case. qsort()
isn't stable, so a tied ordering could push the protected current-pointer
file (skipped on deletion, never compensated) past keep_n, leaving one
extra file on disk ("Expected 2 Was 3"). Fixed by sorting on st_mtim
(nanosecond-resolution struct timespec) instead of st_mtime.

cr_setup() keyed its tmpdir on getpid()+time(NULL) (second resolution),
risking collision with a stale directory left by an earlier interrupted
run (ASAN abort, timeout, SIGKILL -- none reach cr_teardown()'s rm -rf)
reusing the same PID within the same second -- test_conf_get_saved_tag_
no_config then observed that directory as "not actually empty" and read
a leftover tag instead of the expected 0. Fixed with a monotonic counter
guaranteeing a unique directory per cr_setup() call.

TDD: RED reproduced on the first attempt (both tests failed with the
exact historical signature). GREEN confirmed across 16+ repeat runs
after the fix, zero other regressions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QxaSzHRB7pmYFp4cVnwkA
2026-08-30 03:55:45 +00:00
9e11bb9e0b
docs: sync OpenWolf state
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QxaSzHRB7pmYFp4cVnwkA
2026-08-30 03:01:28 +00:00
38437e570e
fix(scheduler): don't hand an orphaned duplicate job to the picker
Found while chasing bug-1714's crash (root cause still open -- see that
entry): two related, independently-confirmed defects, not proven to be
bug-1714's own cause but real bugs on their own merits.

xce_core_push_events()'s JOBS_PUSH case never checked sched_add_job()'s
return value -- if key_add() failed (duplicate jobid), the freshly-built
xce_sched_job_t was handed to picker_iface->on_job_push() anyway, even
though it was never registered in core->jobs. An orphaned job the
picker knows about but sched_get_job() can never find again. Now checks
the return, frees the orphan (at core_build_job()'s own established
cleanup granularity -- xce_sched_job_t has no complete destructor
anywhere in this codebase, kill_sched_job() only frees ->rusages, so
this intentionally doesn't invent a more thorough one), and skips the
picker call.

This makes it safe to fix (not the other way around): sched_on_job_array()'s
per-element dedup check (handler.c) has a TOCTOU race -- a job is only
added to core->jobs later, by the driver thread, so a redelivered array
push arriving on the request thread before the driver catches up isn't
caught. Documented as a best-effort optimization, not a correctness
boundary -- the actual authoritative uniqueness check is sched_add_job()'s
key_add(), which the JOBS_PUSH fix above now handles correctly.

TDD: new test reproduces the duplicate-jobid path (RED: on_job_push
fired twice, Expected 1 Was 2), GREEN after the fix. Full scheduler
regression: 54/55, only the known bug-1561-adjacent flake.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QxaSzHRB7pmYFp4cVnwkA
2026-08-30 03:01:14 +00:00
898586737b
docs: sync OpenWolf state
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QxaSzHRB7pmYFp4cVnwkA
2026-08-29 12:13:15 +00:00
670098150d
fix(bug-1731): fire HOOK_DETAIL_JOB_FAIL on WAL_JOB_FAIL apply
Follow-up to ebe691c3 (HOOK_DETAIL_JOB_START/JOB_EXIT), same gap for job
failures: apply_committed_entry()'s WAL_JOB_FAIL case only ever fired
the generic HOOK_DETAIL_JOB_UPDATE, leaving sched_job_fail_fun (sched.c)
and apiserver_job_fail_fun (apiserver.c) dead -- the apiserver's
OnJobFinished was starved of data for job failures specifically (the
prior fix only closed this for clean finishes).

Fires HOOK_DETAIL_JOB_FAIL only for the WAL_JOB_FAIL_STAGE_FLAG branch,
which already constructs a real job_failinfo_t -- the legacy _pad==0
absolute-overwrite branch has no fail-specific data and must not
fabricate one, mirroring how the WAL_JOB_START fix only fires when
pidinfo was genuinely decoded. Unlike WAL_JOB_START, no gate-widening
was needed: apply_job_fail_transition() always returns
JOB_TRANSITION_APPLIED for a genuine new fail transition (confirmed by
reading it), so the existing result-gated early return already covers
this correctly.

TDD: RED confirmed (fix reverted, test failed "Expected 2 Was 1"),
GREEN after restoring it. Full regression: 1220 tests, only the known
bug-1561 flake.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QxaSzHRB7pmYFp4cVnwkA
2026-08-29 12:13:01 +00:00
83cb660b44
fix(bug-1732): build xcecd_virtual in xce-build.sh's worker target
The `worker)` case's meson compile target list omitted xcecd_virtual --
the no-root worker binary deploy-ha.sh/the xce-deploy-ha skill needs
whenever no real systemd manager is present (the common sandbox case).
/xce-build worker alone left it unbuilt, so deploy-ha.sh silently
soft-skipped generating start-worker.sh. Verified: xcecd_virtual now
builds with a fresh mtime, full worker suite still 5/5.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QxaSzHRB7pmYFp4cVnwkA
2026-08-29 11:35:10 +00:00
25778ee8a2
docs: sync OpenWolf state for bug-1730/1733/1731 investigation
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019QxaSzHRB7pmYFp4cVnwkA
2026-08-29 11:29:23 +00:00
f0a3729f24
ignore daemon.log token-ledger 2026-08-28 14:33:03 +08:00
b64682dce9
docs: save scheduler-snapshot-job-allocation and xce-test-cli-ux spec docs, sync OpenWolf state
Adds the previously-uncommitted spec.json/requirements.md/design.md/research.md
for scheduler-snapshot-job-allocation (feature now fully implemented across
tasks 1.1-4.5) and the in-progress xce-test-cli-ux spec's requirements.md/
spec.json. Updates brief.md, a security.md note on an unrelated deferred RBAC
persistence gap found during this feature's cross-component survey, and syncs
OpenWolf's anatomy/memory/token-ledger/daemon-log bookkeeping.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SSuXfK6nD1Nue5EjjdhjNZ
2026-08-28 06:30:37 +00:00
lei.chen
05ac57b183 fix(worker): restore getpwnam execuser-existence check (bug-1507 merge regression)
The scheduler-framework merge (4e894d21) reverted the bug-1507 fix from
c091a8da: job_start_local_task fell back to nobody only when execuser was
EMPTY, not when it does not exist on the worker host — a submit-user missing
from /etc/passwd makes systemd fail the worker unit with EXIT_USER (217) and
every job dies. Restored the getpwnam() existence check (+ #include <pwd.h>).
All 21 worker tests pass; fallback log message verified in the built xcecd.

Also records the merge-overwrite lesson in cerebrum Do-Not-Repeat: after any
branch-sync merge, re-verify each previously-fixed bug's marker symbol
survived (git show <merge>:<file> | grep -c <symbol> vs <merge>^).
2026-08-27 13:11:09 +00:00
097e33ae34
feat(scheduler-snapshot-job-allocation): add dup_job_alloc deep-copy primitive
Task 1.1: new deep-copy for xce_job_alloc_t composed from existing
make_alloc/make_host_alloc/make_job_alloc, explicitly preserving each
allocation's original from/duration rather than accepting make_alloc's
own time(NULL) stamp. TDD: 6 new unit tests (single-host, multi-host,
multi-resource-per-host, shared-resource-pool, independence-after-free,
from/duration fidelity), all passing under ASAN.

Also logs bug-1723 (pre-existing, unrelated leak in two bug-1722 test
fixtures, confirmed via git-stash A/B rebuild to be byte-for-byte
identical before and after this change) -- documentation only, not fixed
here.

Requirements: 1.1, 1.4
2026-08-27 12:07:27 +00:00
c0ad576838
chore(wolf): log bug-1722 (make_job_account heap overflow)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AgYRU3zDTqNGV5Jk8aiKLg
2026-08-27 08:43:33 +00:00
d8bf8fb2e1
chore(wolf): checkpoint buglog.json (1062 bugs)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AgYRU3zDTqNGV5Jk8aiKLg
2026-08-27 08:27:43 +00:00
b3c462ede4
chore(wolf): checkpoint buglog.json (1057 bugs) 2026-08-26 14:30:13 +00:00
f9e8d97eac
chore(wolf): checkpoint buglog.json (1056 bugs) 2026-08-26 13:40:07 +00:00
lei.chen
10865a4e63 chore(wolf): record clean deployment + AppImage runtime fix 2026-08-26 11:52:06 +00:00
eca25271fd
chore(wolf): checkpoint buglog.json (1056 bugs) 2026-08-26 11:41:25 +00:00
1cb57791af
chore(wolf): checkpoint buglog.json (1056 bugs) 2026-08-26 11:19:11 +00:00
lei.chen
77616435c2 chore(wolf): record merge verification + bug-1490 regression + p2-hang fix lessons 2026-08-26 10:54:52 +00:00
b5da7825e2
chore(wolf): checkpoint buglog.json (1056 bugs) 2026-08-26 10:38:45 +00:00
a50b7ff4f9
chore(wolf): checkpoint buglog.json (1055 bugs) 2026-08-26 10:29:51 +00:00
e8b863875a
chore(wolf): checkpoint buglog.json (1055 bugs) 2026-08-26 10:23:07 +00:00
8b92f9c30a
chore(wolf): checkpoint buglog.json (1054 bugs) 2026-08-26 10:10:04 +00:00
35863d0ed4
chore(wolf): checkpoint buglog.json (1053 bugs) 2026-08-26 09:58:14 +00:00
0a5ce1e2b7
chore(wolf): checkpoint buglog.json (1053 bugs) 2026-08-26 09:33:35 +00:00
c7290344d5
chore(wolf): checkpoint buglog.json (1042 bugs) 2026-08-26 09:14:21 +00:00
3b81f8df8f
chore(wolf): checkpoint buglog.json (1041 bugs) 2026-08-26 08:36:57 +00:00
2cb9ffc423
chore(wolf): checkpoint buglog.json (1040 bugs) 2026-08-26 08:21:00 +00:00
473fa8d8cd
chore(wolf): checkpoint buglog.json (1040 bugs) 2026-08-26 07:58:30 +00:00
54ea98fb35
chore(wolf): checkpoint buglog.json (1040 bugs) 2026-08-26 07:52:43 +00:00
e34e9fec23
chore(wolf): checkpoint buglog.json (1039 bugs) 2026-08-26 07:33:53 +00:00
980e35316e
chore(wolf): checkpoint buglog.json (1038 bugs) 2026-08-26 04:49:40 +00:00
f5e105ea9f
chore(wolf): checkpoint buglog.json (1038 bugs) 2026-08-26 04:17:52 +00:00
14cbc8dad3
chore(wolf): checkpoint buglog.json (1038 bugs) 2026-08-26 03:27:17 +00:00
2d3b47820b
chore(wolf): checkpoint buglog.json (1037 bugs) 2026-08-26 02:28:01 +00:00
a91275be16
chore(wolf): checkpoint buglog.json (1037 bugs) 2026-08-25 16:31:48 +00:00