Commit graph

2203 commits

Author SHA1 Message Date
aa4c43c897
feat(scheduler-sim-decision-trace): parse the trace command and manage trace settings
Task 4.3: trace on all|job SEL... [level] [lines N] [file PATH], off and
status, parsed from the raw line; invalid arguments are named and leave
the settings unchanged; refcounted next/current settings; status shows
the settings in effect or pending, whole arrays as <base>[*], and stored
trace memory against its bound.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 14:05:36 +00:00
73416e3e91
feat(scheduler-sim-decision-trace): store the latest trace per job and serve info trace
Task 4.2: a new trace replaces a job's earlier one; above 64 MiB the
oldest traces are evicted (never the newest) and marked discarded until
a newer capture; info trace renders a job's or an array's stored traces
in the current units mode, or reports discarded / no trace with the
job's state / unknown job.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 13:50:02 +00:00
fe445e9453
feat(scheduler-sim-decision-trace): render trace records to text
Task 4.1: hierarchy, summary-level position summaries, truncation marker
with the fixed totals block, 50-host outcome cap with aggregates and
separate limit charges, no-decision and reconstructed records, amounts
in the REPL units mode, identical bytes to one or two sinks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 13:30:06 +00:00
16f40fa9dc
feat(scheduler-sim-decision-trace): hook the allocator runner
Task 3.4: the runner records no-plan reasons, the cluster-wide check,
plans (tried, discarded, not tried) and their ends, positions, claimed
skips and per-host candidate verdicts, rollbacks, commit or finalize
failure, and search end. A declined or generator-failed requirement now
counts once as 'no plan generated'. Runner results are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 12:04:16 +00:00
d4bee4b5d0
feat(scheduler-sim-decision-trace): hook the host pre-filter, host scan and satisfaction check
Task 3.3: the pre-filter records selection mismatches and internal
errors as host verdicts, a scan stopped by an error marks the position
as a scan error, and unsatisfy_() hands every checked row to the current
record. Iterator and check results are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 11:42:19 +00:00
542c6e602a
feat(scheduler-sim-decision-trace): hook resource-requirement branching
Task 3.2: single requirements, top-level compounds, alternatives and
members push their path level and record one begin and one end; member
failures record the members not tried, merge failures and skipped
alternatives are separate entries, the chosen alternative or all-failed
is recorded, and each compound attempt's reasons are captured before the
job's stored reason is replaced. Scheduling results are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 11:23:16 +00:00
ed7b889bb7
feat(scheduler-sim-decision-trace): hook the allocator loop
Task 3.1: when the sim publishes trace settings, sched_allocator() counts
job positions, starts a record for wanted jobs with their selection and
cluster-wide limits, pushes no-decision kinds as trace-only decisions,
and attaches the captured outcome to built decisions; every handoff
clears core->trace_rec. Live (trace_ctl NULL) is unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 11:10:28 +00:00
144a01982e
refactor(scheduler-sim-decision-trace): split trace sources under the 800-line cap
Task 2.4: outcome capture moves to sched_trace_outcome.c and the
position/host/summary/rollback half of the model to sched_trace_scan.c;
shared helpers go behind sched_trace_internal.h (sti_ prefix). Code is
moved unchanged; every target that compiles the trace sources gets all
four, and the core isolation scan covers the new files.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 10:16:46 +00:00
eacb1fa599
docs(scheduler): list the decision-trace sources in the component guide
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 10:10:36 +00:00
f5a38b5a48
docs(buglog): record Gitea sync for bug-1924 (#349 closed)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 10:00:35 +00:00
0ee3bc50f5
docs(spec): scheduler-sim-decision-trace task 2.4, split trace sources under the 800-line cap
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 09:58:41 +00:00
8efe142bad
feat(scheduler-sim-decision-trace): capture decision outcomes and reconstructed dispatches
Task 2.3: dispatch rows with limit charges listed separately and
resolved through the job's matched limits (raw-number fallback), pend
reason set deep-copied, 50 hosts in detail with the rest aggregated,
and RECONSTRUCTED records holding the dispatch outcome.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 09:58:21 +00:00
79c5a0cbda
docs(buglog): bug-1924 fixed (e56f27f9)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 09:51:13 +00:00
e56f27f997
test(scheduler): check only the timestamp field in the frozen tlog format test (bug-1924)
test_tlog_format_shows_frozen_virtual_time_not_infotime asserted that
"1999" (info->time's year) appears nowhere in the formatted line, but
the line also carries getpid(), so the test failed whenever its PID
contained 1999. It now asserts the exact frozen timestamp field.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 09:50:36 +00:00
9b0284fab5
docs(buglog): record Gitea sync for bug-1924
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 09:38:00 +00:00
258267fa48
feat(scheduler-sim-decision-trace): capture shortfall and limit rows from the satisfaction check
Task 2.2: each checked row carries name, flags, value type, total,
in-use, reserved, requested and met (same comparison as unsatisfy_());
limit rows resolve through the scope's matched limits and never count as
shortfalls; the cluster-wide check keeps every row, a host only unmet
rows, which set its shortfall/limit verdict.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 09:35:00 +00:00
90d417bb1b
docs(buglog): bug-1924 clock test fails when the test PID contains 1999
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 09:31:10 +00:00
54f9139e77
feat(scheduler-sim-decision-trace): capture selection facts, cluster-wide limits and attempt reasons
Task 2.1: policy, queue and priority/queue-time ordering keys, each
matched cluster-wide limit as (name, scope), and per-code attempt
failure reasons with the hosts and resources they name, all copied into
the record arena.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 09:08:23 +00:00
a801aff46f
feat(scheduler-sim-decision-trace): core trace gate and SCHED_TRACE hook macro
Task 1.8: the core gains trace_ctl/trace_rec (NULL unless the sim REPL
sets them) and SCHED_TRACE evaluates its call only while a record is
being built.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 08:53:40 +00:00
29b6734649
feat(scheduler-sim-decision-trace): trace attachment and trace-only op on decisions
Task 1.7: xce_decision_t gains a trace pointer (NULL from every existing
constructor) and XCE_DECISION_TRACE with make_trace_decision(); the live
driver skips trace-only decisions and frees any attached trace.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 08:40:37 +00:00
320f88a432
feat(scheduler-sim-decision-trace): compile trace sources into white-box tests of hooked files
Task 1.6: the 27 tests that #include a hooked scheduler source now also
include sched_trace.c and sched_trace_capture.c.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 08:29:56 +00:00
4ae68998ce
test(scheduler): silence snprintf truncation warning in repl trace baseline cleanup
remove_workdir() now checks snprintf's result and skips a truncated path
instead of unlinking whatever it happens to name.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 08:28:22 +00:00
d277bfb657
feat(scheduler-sim-decision-trace): plan/verdict counters, search-end, summary tallies, rollback merging
Task 1.5: per-requirement plan counts and search-end statements,
decision-wide counters exact past truncation, summary-level position
tallies (per verdict kind and per limit), merged rollback entries.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 08:21:57 +00:00
e06bdc290b
docs(buglog): bug-1923 fixed (16616d96), synced to Gitea #348
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 08:11:37 +00:00
16616d9688
fix(scheduler): load shared resource values from the snapshot (bug-1923)
xce_scheduler --sim started with no shared resource pool when the shared
values came only from the recording's SnapshotEntry (license value=(none)),
so jobs needing a shared resource pended instead of dispatching. Two
defects caused it:

- Load side (snapshot_load.c): a resval was treated as shared only when
  rv->host == NULL. The capnp round trip (write_snapshot_entry ->
  decode_SnapshotEntry) reads a NULL host back as "", so every shared
  resval in a .replay file was skipped. A NULL or empty host now means
  the shared pool; only a named host marks per-worker data.
- Save side (snapshot.c, snapshot_wire.c): core->sharedInst and each
  worker's resvals were walked with i < .count. zarray_t.count is the
  number of filled slots, not the highest idx + 1, and both arrays are
  sparse by resource idx, so higher-index values were dropped from the
  snapshot. Both loops are now bounded by .caps, as repl_info.c already is.

New test test_snapshot_sparse_resvals.c covers the in-memory save/load,
the empty-host load, and the real sched_record_start() -> .replay ->
sched_sim_driver_start() round trip.

Regenerated fixtures/repl_trace_baseline/set_output.replay: its mid-run
snapshot now carries license, limit=cluster_slots and each worker's
limit=host_slots, which the old writer dropped (all other fixtures
unchanged).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 08:10:00 +00:00
4f951f2b52
feat(scheduler-sim-decision-trace): trace entry sequence and line budget
Task 1.4: requirement path push/pop with balanced begin/end entries
carrying the full nesting path, one entry per traced event kind, and a
line budget that stops storing at the bound and counts omitted lines.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 08:05:44 +00:00
383e2a90e4
docs(wolf): cerebrum learnings (bug-1923 snapshot resvals, build dir) and memory log
Also carries earlier uncommitted cerebrum entries (gitea milestones filter,
standalone ASAN sim leaks, bug-1883 ctx vectors, gofmt vendor rule) and the
hook-maintained memory.md log.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 07:51:14 +00:00
7d3c71fc34
feat(scheduler-sim-decision-trace): trace record model foundation
Task 1.3: trace types and constants, per-record arena, job selection
matching, no-decision record finishing; empty capture module; both
sources scanned by the core isolation test with a no-stdio check.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 07:49:09 +00:00
7f40ff27dc
feat(scheduler-sim-decision-trace): move units and value formatting helpers into repl_fmt.c
Task 1.2: translate_units_mode, repl_format_numeric_resource_value,
repl_format_consumable_value_and_used and repl_current_units_mode move
unchanged from repl_info.c and are declared in repl_internal.h so the
trace renderer can reuse them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 07:30:42 +00:00
ce757eaaa1
docs(buglog): record Gitea sync for bug-1923 (#348)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 07:24:40 +00:00
e2d5662d28
feat(scheduler-sim-decision-trace): capture the trace-off REPL transcript baseline
Task 1.1: scripted REPL session over a contention replay (license, cluster
and host limits, parallel and alternative jobs); transcript, recordings and
--sim-verify result committed as fixtures and compared byte for byte.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 07:21:38 +00:00
bf1e4b7245
docs(buglog): bug-1923 sim drops shared resource values from the recording snapshot
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 07:18:37 +00:00
ed201686b6
docs(spec): scheduler-sim-decision-trace design, research and tasks
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 06:48:57 +00:00
33437a392e
docs(wolf): STATUS.md -- PR #347 open into develop
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 03:10:41 +00:00
99f479082a
docs(wolf): STATUS.md -- bug-1736 exposure, bug-1914..1922, soak gates; merge pending
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 03:08:20 +00:00
145e41d8e0
docs(buglog): record Gitea sync for bug-1917/1919/1920/1922
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 03:04:11 +00:00
8dab1f2065
docs(buglog): bug-1922 fixed; bug-1917 follow-up; soak coverage for bug-1919/1920
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 03:03:27 +00:00
5cf923350c
test(soak): WAL segment-layout gate and --truncated-fence scenario
- wal-layout-check.py: every WAL segment must hold one contiguous LSN run
  starting at the LSN in its name (bug-1920 signature); the sequential,
  chaotic and truncated-fence modes fail on a misfiled segment.
- --truncated-fence: breaks ctrl-1's WAL tail CRC so it boots
  RECOVER_TRUNCATED, makes it win an election (promotion REFUSED), then
  requires the fence to be healed and released after catch-up and the
  node to lead with zero job loss (bug-1919 lifecycle, proven from logs).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 03:03:09 +00:00
c06798b2fa
fix(harness): xce_test fake worker answers the controller's job-state query (bug-1922)
The worker-rejoin-resync query sent when a worker with live jobs re-joins
had no handler in xce_test's worker context, so the controller resolved
every such round by its 15 s timeout, withholding dispatch meanwhile.
New fake_resync.{c,h} reassembles the paginated query and builds the
report like xcecd (queried jobs in order, running or unrecognized, then
unqueried running jobs); the handler sends it with a non-blocking request.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 03:03:09 +00:00
f26a2d4586
fix(lib): reconnect from an endpoint's own task neither waits nor leaks old replies (bug-1917)
A reconnect made from inside a task of the endpoint it re-establishes (a
request handler that failed over) waited out the full 2 s quiesce bound:
its own reference cannot drain, and the old connection's queued tasks are
serialised behind it -- and those then ran after the owner was re-armed,
reaching the new session.

Each VTASK_IO task now records the endpoint's reconnect_gen when queued and
vtask_entry drops a task whose generation is stale; the vtask manager
tracks the endpoint whose task the current thread runs
(vtask_current_io_ep), and xce_ctx_quiesce_ep skips the wait in that case.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 03:03:09 +00:00
6a42631b2a
docs(buglog): record Gitea sync for bug-1921
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 14:43:22 +00:00
77ca96ab63
docs(buglog): bug-1921 fixed
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 14:42:28 +00:00
70d56a5df6
fix(harness): xce_test fake worker defers handler notifications and re-joins after a reconnect (bug-1921)
Worker-context handlers (startjob, runtasks, jobcontrol) run as tasks of
the worker's own connection, so their synchronous notify RPCs waited for
a reply queued behind themselves, timed out (-110) and failed the client
over; the session never joined again, so the controller rejected every
later worker request ("is not a worker") and job usage stayed zero.

Handlers now queue the notification (new worker_notify.{c,h} FIFO) and a
one-shot delay-manager task sends it; housekeeping retries anything left.
A recorded worker join is repeated with the saved attributes once the
connection's reconnect_gen changes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 14:42:28 +00:00
12f5eb2a76
docs(buglog): record Gitea issues for bug-1736/1917/1921
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 13:55:45 +00:00
07d81fc5bc
docs(buglog): bug-1736 exposed to apiserver/xcecli; log bug-1921
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 13:54:53 +00:00
1cedd7f791
fix(controller,apiserver,xcecli): expose job CPU peak and efficiency to the apiserver and xcecli (bug-1736)
The controller computed run usage (CPU time, memory, CPU peak and
efficiency, LSF bjobs -l definitions) but the capnp Job struct had no
field for it, so the job pushed to the apiserver never carried it, and
snapshots (the same struct) dropped it: a job restored from a checkpoint
lost its accumulated usage.

- controller.capnp: Job.runUsage @13 (JobRunusage); old entries decode
  with no run usage.
- apiserver: map run_usage into JobInfo; max_mem, avg_mem, used_mem,
  cpu_time, peak_cpu, peak_cpu_time, peak_cpu_duration, mem_efficiency,
  avg_cpu_efficiency, peak_cpu_efficiency become queryable columns.
- xcecli: -o fields MAX_MEM, AVG_MEM, MEM_EFFICIENCY, CPU_PEAK,
  CPU_PEAK_DURATION, CPU_EFFICIENCY, CPU_PEAK_EFFICIENCY (CPU_TIME now
  renders too), and a MEMORY USAGE / CPU USAGE block in jobs list -l.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 13:54:43 +00:00
e2472aa73c
docs(buglog): record Gitea issues for bug-1914/1917/1918
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 00:00:25 +00:00
8e66d463ea
docs(buglog): bug-1914, bug-1917, bug-1918 fixed; refresh STATUS.md
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-04 23:59:29 +00:00
06e99b9081
fix(controller): size the config-push barrier for loaded hosts and admit its wait (bug-1914)
The configAck byte-delivery barrier waited 500 ms, below scheduling
delay on an oversubscribed host, so a push to a healthy majority was
rejected with -110 while its already-appended marker still committed.
CONF_PUSH_TIMEOUT_MS is now 2000 ms, the wait holds a commit-wait
admission slot (new commit_blocking_admit/release; a full budget fails
fast with not-ready), and the timeout reply no longer claims the change
was not committed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-04 23:59:29 +00:00
431a6d709e
fix(lib): quiesce the old endpoint before xce_ctx_reconnect re-inits it (bug-1917)
Work dispatched for the old connection (the io_worker's epoll batch,
queued VTASK_IO reply tasks) could still run while the reconnect tore
down and re-armed ctx->ep; a queued reply of the old connection then
reached the new session. The reconnect now unmonitors the old fd,
clears ep->owner (stale tasks are dropped) and waits for the endpoint's
references to drain, bounded at 2 s so a caller that is itself one of
those tasks cannot deadlock. vtask_entry reads ep->owner under ep->lock.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-04 23:59:29 +00:00