Commit graph

61 commits

Author SHA1 Message Date
lei.chen
0c8607345e merge: sync Rongsong's scheduler-framework (c5b172c7..3442a57d, 781 commits)
Merge origin/scheduler-framework into merge-sf-20260903 (97 commits on
ours: bug-1490/1494/1498/1509/1513/1521/1522 fixes, PEND-reason P1,
scheduler-agent Phase 2, bug-924 owner-pid shim).

Bookkeeping excluded per policy: .kiro/, .wolf/, CHANGES.md, reports/
(92 files dropped); .claude/ + CLAUDE.md keep ours.

Key theirs-side changes absorbed:
- bug-1938/1960: QUEUE_STAT_CLOSED no longer gates dispatch (closed
  queue refuses new submissions only; pending jobs still run) --
  supersedes our QUEUE_CLOSED preason on the dispatch path;
  sched_queue_status_reason drops that branch
- bug-1846: config push now stashes and applies between scheduling
  rounds (sched_stash_config/sched_apply_pending_config), applied at
  the same main-thread round boundary that preserves bug-1513
  serialization
- bug-1760: sched_check_pending_rejoin exposed +
  xcecli_is_connection_broken public predicate
- bug-1936: execuser/exechome/execcwd/exdata carried on submission
  (superset of our bug-1500 execuser fallback; our job-typed
  resolveExecUser removed as dead code)
- bug-1945~1962: apiserver auth hardening (HS256 pinning, default-
  secret rejection, logout revocation, bcrypt, RBAC) -- our API-key
  branch folded into controllers.ParseTokenClaims so both coexist
- bug-1736: rawRunUsage job run-usage fields in the Go model
- xce_test relocated src/controller/testsuite/test.c ->
  src/harness/test.c; controller suite split into
  controller_test.c + fixtures; their clitest fixtures spawn xce_test
  mid-suite under `meson test -j`

Ours preserved across the merge:
- PEND-reason P1 (codes 1-9, preason.h, job_preason machinery) --
  gate re-ported into their relocated allocator (sched_election.c)
  after plugin_job_election, with attach on the allocator thread
  only (bug-1521 race discipline)
- PEND-reason P0 main_reason semantics RECONCILED to theirs: the
  merge initially re-carried our first-detail-add-promotes-main_reason
  fallback in add_job_preason (4e2ac86), but their whole trace/verify
  stack treats "detail-only => main_reason 0" as a contract --
  sched_trace_capture counts main_reason as its own occurrence
  ("Expected 2 Was 3" in test_trace_capture), the outcome renderer
  prints "main reason: none" for detail-only PENDs (test_repl_trace_e2e),
  and the committed .replay/.sim_verify baselines encode main_reason=0
  (test_repl_trace_baseline byte compare, test_trace_equivalence
  off-vs-traced). The fallback is dropped from the shared lib;
  the user-visible "overall reason" survives as an API-layer view:
  rawJobToModel (convert_pure.go) promotes the first detail row to
  main_reason_name when main_reason is 0 (main_reason VALUE marshals
  unchanged). add_job_preason keeps only the NULL-reasons guard
- bug-1498: sched_job_is_ready rejects non-PEND/suspended jobs
- bug-1490/1781: xce_jobctrl_t.action as capnp union discriminant
  (their jobCtrlUnionDiscriminant, same semantics)
- xcecli typed PendingReason field (53c00834), bug-1522 reconnect
  resend, xcecli_force_reconnect + their is_connection_broken both
  exported in client.h/libclient
- t1/t2/t3 test-node hostconfig in src/configs/hosts.yaml (bug-1494),
  /xce/v1/events + /xce/v1/apikeys whitelist routes (agent Phase 2)
- lib ASAN_OPTIONS=detect_leaks=0 test env + their oom-test block
- drop-audit: our bug-1504 fix covered by their bug-1680 (no action)

bug-924 follow-up (replaces the 67f3f6ad scratch-dir wipe): the
take-theirs audit's one "drop" was re-evaluated and REVERTED instead of
re-applied -- a global `find /tmp -name 'xce_*' -exec rm -rf` at suite
start/exit races the LIVE /tmp/xce_* fixtures of sibling suites under
`meson test -j` (harness_unit_test's clitest fixtures spawn xce_test as
a child mid-suite; the wipe destroyed the parent's fixtures ->
test_test_cli failures). Coverage instead:
- mkdtemp_clean shim gains mkdtemp_clean_mark/sweep_since
  (testsuite_support/mkdtemp_clean.[ch])
- new case_scratch_sweep.[ch]: aggregate runners (controller_test.c,
  harness_test.c -- hundreds of cases per process) call
  case_scratch_sweep_begin/_end_ok from setUp/tearDown; a PASSED case's
  dirs are swept immediately in tearDown (after engine reaping), FAILED
  cases keep their dirs for post-mortem; XCE_MKDTEMP_KEEP_ALL=1
  disables. One full controller_unit_test run was observed to leak 12G+
  to ENOSPC without this, cascading into unrelated "Expected Non-NULL"
  failures
- harness_unit_test_deps links the shim library as well

Test reconciliations on adopt:
- core-ready-gates: sched_queue_is_ready now gates only
  INACT_ADMIN|INACT_WINDOW (bug-1938/1960); CLOSED queues elect --
  covered end-to-end by test_queue_admin_control.c
- test_worker_resync: the 4 restart-replay RUN assertions predate the
  bug-1509 B3 marking (8858afed) landing on the same lineage; replayed
  RUN jobs now assert RUN|UNKWN|TRANSIENT (TWR_ASSERT_REPLAYED_RUN);
  terminal DONE/EXIT assertions unchanged
- convert_pure.go: our job-typed resolveExecUser deleted (superseded
  by their bug-1780/1936 two-arg version)
- test_preason: the 3 P0-promotion assertions reverted to the
  detail-keeps-main-0 contract; new tests cover limit-code detail
  rows and explicit-main-wins-over-later-details; apiserver
  convert_test.go gains the detail-only name-promotion cases

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 05:17:03 +00:00
954c96cf5b
feat(xcecli): jobs kill --signal and --force
The control API already takes `signal` (kill only: that signal once,
instead of the graceful INT, TERM, KILL sequence) and `force_kill`
(SIGKILL at once); xcecli could not send either. `jobs kill` now has
-s/--signal <name|number> (names in any case, SIG prefix optional, sent
upper case without it) and --force, in both the job-ID and the filter
request; using both at once, or an empty signal, is refused before any
request. stop and resume get neither (the server rejects a signal there).
Kill help and docs/xce.md "Killing and stopping jobs" document the flags.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 10:25:23 +00:00
d84a793578
docs: document graceful job kill/stop and job.terminate_interval (bug-1957)
- src/docs/xce.md: explicit signal and force kill are REST-only (signal,
  force_kill); xcecli has no signal option yet.
- src/docs/deployment.md: app.yaml row lists the job block
  (max_array_size, terminate_interval) and trusted proxies.
- xcecli jobs kill/stop/resume help describes the signal sequences.
- REST: control endpoint annotations and the signal/force_kill model fields
  describe the behaviour (swagger output not regenerated: swag fails on an
  unrelated annotation).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 10:07:42 +00:00
97f7c800f1
fix(apiserver): validate, default and document job.terminate_interval (bug-1957)
The loader now stores the effective interval (10 s when unset or 0, LSF's
JOB_TERMINATE_INTERVAL default) and refuses a negative one; app_schema.json
describes the setting; src/docs/xce.md documents kill/stop behaviour and
the interval.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 10:04:47 +00:00
27ef506058
docs(apiserver): document security defaults changed by bug-1945..1952
deployment.md: auth.yaml now holds bcrypt hashes of the (still public)
dev credentials with startup warnings; JWT secret from XCE_JWT_SECRET or a
random per-process secret; logout revocation is per process;
security.trusted_proxies for reverse proxies.
security.md steering: JWT parsing, revocation, secret resolution,
trusted proxies, middleware abort rule, bcrypt and role-change rule.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 08:58:20 +00:00
c15580a7f3
fix(frontend): peek and restart take <array-id>[k] and written job IDs
- apiserver peek (parseJobIDParam): <array-id>[k] now resolves to the
  element; it used to drop [k] and look up the array identity itself
  (and panicked in parseArrayName on some inputs). A job number still
  names that job exactly (an element by its own XCE_JOBID); ranges and
  invalid selections are rejected.
- apiserver restart: the decimal-only pre-check (isValidJobId, now
  unused and removed) rejected the written form c-a-ts-seq[k];
  ParseIdentitySelection, already used for the lookup, validates it.
- xcecli jobs restart converts its argument with ToAPIJobID like the
  control commands, so written IDs work and invalid ones fail locally.
- docs: the peek/restart caveat in the Job arrays section.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 09:42:27 +00:00
6439e5852f
docs(job-array-one-based-index): document the supported array syntax (task 9.3)
src/docs/xce.md gains a 'Job arrays' section: name[1-N] and name[1],
numbering from 1, the API-server limit (default 1000, at most 32767),
<array-id>[k] and <array-id>[a-b] selection (with the peek/restart
caveat), XCE_JOBINDEX, the harness jobsub -a N / $jobid[k], and every
LSF array feature this release does not support. The superseded
statements in job-array-single-wal-record and xce-test-e2e-primitives
are annotated (history kept), the controller-job-cleanup and
job-dependency briefs describe 1-based numbering, and the roadmap gains
an entry.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 13:46:07 +00:00
66435d100d
docs(scheduler-sim-discrete-clock): deployment guide describes the event-driven sim clock and deprecated --sim-speed (task 4.1)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 05:21:11 +00:00
f5fbc6bcac
feat(eliminate-frontend-makefile): task 3.3 - update live documentation (11 files)
Removes every live current-fact reference to src/frontend/Makefile
targets or Makefile-specific fixed paths across 11 docs (steering,
frontend/CLAUDE.md, root CLAUDE.md, deployment docs, and two skill
docs), replacing with the Meson-based equivalents established by
tasks 1-3.2: /xce-build apiserver, meson test --suite apiserver,
direct tests/regression/run.sh invocation.

Round-1 review rejected the first pass: xce-deploy-ha/SKILL.md had
over-corrected by deleting all mention of deploy-ha.sh's still-real
/tmp/apiserver legacy fallback (that script's discovery logic is
unchanged, unlike run-resource-verify.sh's, which genuinely lost its
fallback in task 3.1 -- xce-test-resources/SKILL.md's identical-
looking edit was correct for that reason). Fixed by restoring an
accurate, Makefile-free description of the real fallback at all four
touched sites. Re-reviewed and approved.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XYdtrEWWZfKRRGED7raEYg
2026-09-03 14:22:54 +00:00
lei.chen
4e894d2184 merge: sync Rongsong's scheduler-framework into chatbot
Full merge of origin/scheduler-framework (scheduler-core restructure,
failover-adoption, WAL_JOB_DISPATCH, apiserver backend health/heartbeat,
build-time versioning, bug-1673/1676/1678/1679/1680).

Conflict resolution:
- scheduler: adopt Rongsong's scheduler-core architecture (driver loop,
  queue project/picker fields, resource bug-1569 fix)
- worker/controller_connector.c: keep Rongsong's reconnect/rejoin
  structure, PORT our bug-1509 resend_job_status onto the rejoin success
  path (his reconnect didn't re-report job state)
- apiserver backend: take Rongsong's health/heartbeat (supersedes our
  e505066 circuit breaker)
- group.c: keep our bug-1513 comment
- misc: take theirs for additive fixes (go_build versioning,
  test_group.c, persist.c RUSAGE_UPDATE, FilterRows bug-1680)

NOTE: our scheduler fixes (bug-1494 family dispatch-fail requeue,
PEND-reason classification) are NOT in Rongsong's branch — needs
verification/porting onto scheduler-core (separate follow-up).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-25 12:33:16 +00:00
lei.chen
06887985b4 fix(schedulerclient): node memory_bytes_total no longer ×1e6 (bug-1514)
The apiserver's host max_mem is already in bytes (the worker reads
sysinfo().totalram × mem_unit → bytes and passes it through unchanged via
controller.capnp), but ListNodes treated it as MB and multiplied by
mbToBytes, inflating each node's reported memory to ~8.2e15 (~7.3 PiB).
Now reports the raw bytes (~7.7 GiB per node).

- httpclient.go: drop ×mbToBytes for node max_mem; clarify mbToBytes is
  job-submit-path only (job max_mem is never populated → stays 0)
- ordermap_test.go: correct assertion that had encoded the buggy value
- httpclient_test.go: regression test TestListNodeMemoryBytesKeepsByteUnit
- buglog.json: bug-1514 + close-tags for the bug-1494 family (prior session)

Also add MCP demo deliverables:
- docs/claude-code-demo-guide.md: live Claude Code demo guide (7 scenes)
- docs/mcp-demo-design.md: leadership demo design
- docs/mcp-demo-run.py: add --slow/--color flags for screen recording

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-22 14:58:56 +00:00
d70bf6a402 update documents 2026-08-10 17:51:51 +08:00
c705cadadc
feat(scheduler): working default record-dir, improved REPL output, job ID formatting
- Change default record_dir from /var/log/xce/ to /tmp (always exists)
- Add mkdir(record_dir, 0755) at startup for custom --record-dir paths
- Split validation_error_text into 6 distinct per-errno messages
- Accept human-readable job IDs in 'info job' via parse_jobid()
- Add 'info jobs' command to list all jobs in sim REPL
- Format job IDs with fmt_jobid() for xce_test-consistent output
- Replace printf with fprintf(stdout, ...) in all REPL files
  to bypass -Wl,--wrap=printf linker interception
2026-08-10 09:48:10 +00:00
d9d0613598
docs: add scheduler recording/simulation/REPL to deployment guide
The "Deploying the Scheduler" section predated scheduler-core and only
covered normal-mode startup. Adds session recording (--record-dir,
xceadmin scheduler record start|stop|status, filename validation),
xceadmin scheduler dump for offline .replay inspection, and simulation
mode (--sim, --sim-speed, --sim-verify, --sim-alt-events, --sim-output,
--interactive REPL) — all verified against the actual argp help output
and xceadmin cli.py source, not assumed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-08 03:21:57 +00:00
lei.chen
62dee0edc1 fix(configs): add worker-builtin load indices missing from resources.yaml
worker/src/resource_sync.c init_builtin_load_indices registers 11 load
indices (r15s/r1m/r15m/ut/pg/ls/it/swp/mem/tmp/io) but resources.yaml only
defined r1m/r15s/mem/tmp. The 7 missing ones (r15m/ut/pg/ls/it/swp/io) caused
controller "update_resval: Success" ERRORs and scheduler "unknown resource in
per-worker resvals update" warnings, leaving the worker resource view
incomplete. Add the 7 definitions matching the existing r1m/r15s pattern.

Docs: log bug-1494 (all jobs PEND, scheduler never dispatches; after this
config fix jobs still PEND — remaining suspect is the scheduler→controller
join path after restart), update design doc + verification manual known-issue
tables and root CLAUDE.md cluster-verification status.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-02 07:36:03 +00:00
lei.chen
4a4ae16725 docs(scheduler-agent): add Claude Code integration guide to verification manual
New §5 in src/docs/chatbot-verification.md: how to connect Claude Code to
the scheduler-agent MCP server. Covers building the mcp-server binary,
`claude mcp add` CLI registration (verified against installed CLI
v2.1.220), the .mcp.json project config schema, the three scopes
(local/user/project), the first-run approval gate, verification commands,
and stdio/env gotchas. Original §5-§7 renumbered to §6-§8.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-02 04:26:23 +00:00
lei.chen
56da673b22 docs(scheduler-agent): add cluster deployment + chatbot verification manual
New src/docs/chatbot-verification.md: reproducible steps to deploy the
scheduler-agent stack on the t1/t2/t3 test cluster (AppImage build, store
sync, controller/apiserver/scheduler/worker startup) and verify Phase 0-1
(login, mcp_operator API key, read ops, submit). Documents the vcpus quirk,
setsid launch pattern, conf/current pointer mechanism, and known bugs
(job-control HTTP 500 = bug-1490, HA election deadlock).

Also add the manual to the design doc's related-documents index.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-01 09:57:44 +00:00
0ca96359f5 docs(deployment): note WAL/snapshot retention is automatic
trim_wal_segments + rotate_snapshots run on every checkpoint --
operators don't need to manually purge data/. Documents the
snap_keep_n=2 default and that it's a cluster-config field, not a CLI
flag.
2026-07-31 08:48:41 +00:00
9ed80c4a7c docs(deployment): explain why the built xceadmin venv needs nix develop
--system-site-packages means pip skips vendoring click/pycapnp/pyyaml/
jsonschema since nix already provides them -- deliberate, to keep
pycapnp's ABI-sensitive build pinned to the exact capnproto C library
nix built it against. Activating the venv outside nix develop (or the
AppImage) hits ModuleNotFoundError immediately; not a packaging bug.
2026-07-31 08:40:28 +00:00
4835cf2b30 fix(security): replace exposed admin credential with placeholder
rshen/Letmein was a live, checked-in cluster_admin credential in
auth.yaml. Renamed to a non-identifying username with a clearly-marked
placeholder password.

docs: add full ops deployment guide (src/docs/deployment.md)

Covers building and running all four daemons plus xceadmin, based on
direct source verification (CLI flags, config file shapes, TLS posture)
and a live single-node deploy. Documents real production gaps (no
process supervision, plaintext non-controller traffic, exposed dev
creds) rather than treating the repo as a finished runbook.
2026-07-31 03:31:23 +00:00
Lei Chen
3a2094a461 Merge branch 'working' into job_peek_lchen
job_peek_lchen: Add fetchfile feature (job output/error peek proxy)
working: HA/Raft infrastructure (consensus, replication, config mgmt)

Conflict resolution summary:
- controller.capnp: fetchfile @41, fetchfilereply @18, fetchfilemsg @30
- cluster.c: bifurcated OPCode_reply for fetchfile + config-push ACK
- job.c: kept full fetchfile pending-request subsystem (~183 lines)
- request.c: kept both xce_fetchfile_req() and XCE_RETRY_DEFAULTS
- helper.c: added missing preVoteRequest/preVoteReply mappings
- All 15 new test registrations (test_cbuf.c + 14 HA tests)
2026-07-22 13:57:25 +08:00
dbc631664d docs(ha-single-leader-role): sync steering + contributor docs to three-state model + own-term gate (task 6.1) 2026-06-13 14:58:55 +00:00
06135954ff chore: baseline snapshot — prior-session work + ha-consistency-invariants spec family
Pre-existing uncommitted work: ha-repl-hardening payload data plane (7.x),
heartbeat liveness fix (Req 1.3), connection-reuse ASAN fixes, doc cleanup.
New: ha-consistency-invariants umbrella (requirements/design/research) and
its four implementation sub-specs (specs generated via batch, cross-spec
review applied), steering roadmap + product.md Raft+CP decision.
2026-06-11 13:21:50 +00:00
fa66d1ba9c finalize configuration replication 2026-06-09 16:40:13 +08:00
9bbff7b016 claude skills 2026-05-29 15:00:06 +08:00
7a922cf184 docs(config-repl): update impl-status — Phase 1 wire protocol complete
- Mark Phase 1 as WIRE PROTOCOL COMPLETE (was: ACTIVE with stubs)
- Add commits 2ed7e34-5053c8d to component table
- Remove resolved limitations (do_one_config_fetch stub, push no-op)
- Update test count: 18 → 24 tests, total 84 passing
- Update Phase 2 table: handle_upgrade_config wired, push timeout enforced
- Update files changed to include request.c shims and new test additions
2026-05-22 09:20:29 +00:00
f3babec5bc feat(config-repl): implement wait_all_with_timeout() for push fan-out
Replaces blocking pthread_join() per thread with a CLOCK_MONOTONIC
deadline + 5ms poll loop. CONF_PUSH_TIMEOUT_MS (500ms) now enforced.
Matches design §6.3 aggregate timeout guarantee.

- Add done field to push_ctx_t; push_thread sets it on exit
- Add static wait_all_with_timeout() before push_config_to_standbys()
- Wire push_config_to_standbys() to use wait_all_with_timeout()
- Add #include <stdatomic.h> to config_repl.c
- Guard push_ctx_t local typedef with #ifndef XCE_TESTING
- Expose push_ctx_t and wait_all_with_timeout_for_test() in header
  under XCE_TESTING for unit test access
- Add test_wait_all_with_timeout_slow_threads (timeout fires, acked=0)
- Add test_wait_all_with_timeout_fast_threads (all complete, acked=3)
- Update design doc §6.3 with actual implementation signature and
  5ms poll interval note
2026-05-21 08:30:43 +00:00
2ed7e34e25 fix(config-repl): conf_save_config() must use workdir/name not workdir
load_primary_config() reads from workdir/name/conf — conf_save_config()
was writing to workdir/conf. Latent bug: would have corrupted upgrade
restart cycle once Task 11 wired the upgrade path.

Update all conf_read_current_filename, conf_get_saved_tag, and
conf_check_stale calls in the test suite to use the corrected
effective_dir (workdir/name) path structure. Add new test
test_conf_save_config_path_consistency that explicitly verifies the
written path matches what load_primary_config() reads.
2026-05-21 08:09:02 +00:00
609314efa4 docs: update impl-status — create_lost_and_found done, API guard done, fix malformed row 2026-05-14 03:26:21 +00:00
e4c1bfb17f docs: update design doc status; add config-replication-impl-status.md with full implementation summary 2026-05-14 03:01:38 +00:00
40c7a93951 docs: add future work items 6-8 and clarify design doc safety gate
- Future Work §6: validate_host() implementation plan (CN allowlist,
  admin-cn flag, reject/log unauthorised OP_upgradeConfig requests)
- Future Work §7: OP_replConfig access control hardening (peer
  validation, rate-limiting, minimum_role check)
- Future Work §8: lost_and_found reserved-name validation in admin
  config tool, with migration path for pre-existing clusters
- config-replication-design.md: expand CONF_ENABLE_UPGRADE_CONFIG
  safety gate section with gating prerequisites
2026-05-13 18:21:44 +00:00
6a47ef5c39 save document 2026-05-13 11:05:04 +00:00
Lei Chen
d2b47e3985 Init commit of jobs output/error message peek project. 2026-05-09 16:57:54 +08:00
59597e105e feat: add --peers to controller for HA peer list and priority election
- myconf_t gains peers_cfg (xce_cluster_config_t) populated from --peers
- controller/main.c: parse --peers host:port,... via argp; ca_cert_path
  auto-derived from workdir/certs/xce.crt (no --ca-cert flag needed)
- cluster_init: derive my_priority from position in peers list (index 0 =
  primary); fall back to 0 when --peers not given (single-node mode)
2026-05-08 04:40:27 +00:00
9da6bbb260 Merge branch 'merge_api_server' into persistent_ha 2026-05-07 04:41:14 +00:00
177cf45af5 docs: mark Phase 6 complete in phase6-scheduler-integration-plan 2026-04-30 07:17:32 +00:00
9b0e9571d1 docs: mark Phase 6 complete in resreq-ast-cse-impl-plan 2026-04-30 07:06:36 +00:00
9ed38d4bad fix: address fifth-round adversarial review findings for persistence-and-ha-design
P1 fixes:
- A5-008: Change `in_catch_up` from plain `int` to `_Atomic int` with
  documented access patterns and memory ordering
- A5-002: Add missing opcodes to Part 5.10 capnp schema (heartbeat,
  steppingDown, replSnapshot, replCatchUpDone)
- A5-004: Add hook list synchronization spec for demotion (RCU-style
  removal with disabled flag and deferred memory reclamation)
- A5-005: Change xce_connect_cluster return type from int to SSL*,
  add xce_disconnect_cluster(SSL*), update xce_reconnect to SSL**
- A5-006: Add GC use-after-free mitigation section (per-operation READ
  lock hold for P0, epoch-based reclamation as P3)
- A5-010: Add OP_steppingDown handler spec to P1-2 milestone
- A5-001: Clarify P0-3 checkpoint timer vs dedicated pthread timers
- A5-003: Clarify WAL_CRC_NONE handling in replication CRC validation
- A5-013: Add repl_remove_standby slot cleanup requirement
- A5-012: Add primary_ep lifecycle documentation (iomgr-owned borrow,
  NULL-before-free under mutex)
- A5-014: Add async hook error handling convention
- A5-015: Add aggregate memory budget analysis for concurrent snapshots
- A5-016: Fix ha_check_heartbeat plain role read to use atomic_load_explicit
- A5-017: Fix Appendix A.4 in_catch_up type consistency (_Atomic int)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 05:17:56 +00:00
bb4a95ce37 chore: phase 6 pre-audit — allocator single-threaded confirmed, stub at resource.c:127 2026-04-30 03:28:41 +00:00
c623e37b84 fix: address fourth-round adversarial review findings for persistence-and-ha-design
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 14:01:26 +00:00
454b4aa355 fix: address third-round adversarial review findings for persistence-and-ha-design
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 13:36:43 +00:00
f1641b1fbf docs: fix 9 P0 and 6 P1 issues from second adversarial review
P0 fixes (9):
- R-22: COW vstore find-slot-and-write not atomic
- R-23: vput grow path without mutex during COW
- R-24: Post-growth slot double-claimed by concurrent threads
- R-25: Missing key_snapshot field for checkpoint serialization
- R-26: malloc(0) for WAL_CHECKPOINT entries
- R-27: Fallback to older snapshot with trimmed WAL
- R-28: hdr.term > ha->term + 1 too restrictive
- R-29: _Atomic on enum type (implementation-defined)
- R-30: handle_jobsubmit() ignores hook return value
- R-31: malloc NULL check missing in standby receiver

P1 fixes (5):
- R-32: No heartbeat during persist_recover() on new primary
- R-33: Catch-up from dead primary removed from promotion
- R-34: Added total_wal_bytes field to persist_t

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 12:55:47 +00:00
54bbfa5865 docs: fix 6 additional P0/P1 review findings for persistence-and-ha-design
P0 fixes (3):
- R-16: vstore COW growth re-check used OOB a->data[old_caps].inuse
- R-17: Standby WAL write return value unchecked before sending ACK
- R-18: Chained CRC validation absent from replication stream

P1 fixes (3):
- R-19: Replicated entry LSN handling unspecified
- R-20: seg_offset in-memory and lost on crash
- R-21: WAL segment rotation prev_crc handling at recovery

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 12:28:39 +00:00
bb66b9766d docs: fix remaining P0/P1 review findings for persistence-and-ha-design
- P0: Fix concurrent vstore race under READ lock during COW mode
  (add xzarray mutex serialization around grow-and-assign section)
- P0: Array job sync replication latency bound (batch mode for
  array submits to avoid O(array_size × sync_timeout_ms) blocking)
- P1: rtti library ABI break documented with two-repo dependency note
2026-04-29 12:02:53 +00:00
8bab418c61 docs: address multi-perspective review findings for persistence-and-ha-design
Fixes 15 P0/P1 issues identified by coherence, feasibility, scope, and
security reviewers:

- P0: traversalLimitInWords fixed to constant bound (not file_size / 8)
- P0: Job ID allocator reset added to recovery sequence
- P0: acked_lsn declared _Atomic uint64_t in struct definition
- P0: ha.role declared _Atomic ctrl_role_t with acquire/release semantics
- P0: hooks_registered idempotency guard added to ha_state_t
- P0: MAX_HA_CANDIDATES reduced from 16 to 4 (speculative generality)
- P0: checkpoint_mutex (pthread_mutex_t) added to persist_t
- P1: Split-brain detection condition explicitly specified
- P1: Heartbeat interval minimum standardized to 2000ms
- P1: Degraded-mode restricted state removed from scope
- P1: Config version hash in heartbeat deferred to P3
- P1: WALEntry Cap'n Proto schema clarified as replication-only
- P1: Snapshot backward compatibility path documented
- P1: Snapshot total_size validated BEFORE malloc
- P1: WAL_QUEUE_CTRL/WAL_WORKER_CTRL replay made idempotent
- P1: mTLS gate enforced before replication code (P1-1)
- P1: PENDING reason ambiguity logged at DEBUG during replay

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 11:54:11 +00:00
607f9519e1 docs: address 30 adversarial review findings for persistence-and-ha-design
Three rounds of adversarial review plus a regression review identified
30 findings across CRITICAL/HIGH/MODERATE/LOW severities. Key fixes:

CRITICAL/HIGH:
- C11 atomics for COW inuse fields (vget, vput, vstore scan + growth)
- kvtab_gc must run inside same write-lock section as thaw
- WAL growth safeguard during in-progress checkpoint
- pthread_mutex_t checkpoint_mutex (not mylock_t) for cond var
- atomic_store_explicit(release) for ha.role demotion write

MODERATE:
- LSN strictly-increasing check (not consecutive) for WAL_CHECKPOINT gaps
- Hook unregistration on demotion + idempotent registration guard
- CLOCK_MONOTONIC recommendation for retention time comparisons
- Cross-kvmgr freeze ordering documented (WAL replay restores consistency)
- pthread_once + rand_r() replacing unsafe rng_seed_once/rand()
- should_retain lock requirement and merge-walk iterator lock doc
- Standby catch-up receive ordering (snapshot-first, then live WAL)
- applied_lsn==0 gap validation clarification

LOW:
- Demotion failure handling (fail-forward as STANDBY, no rollback)
- WAL_CRC_NONE (0xFFFFFFFF) sentinel replacing collision-prone 0
2026-04-29 10:43:02 +00:00
b38babb7d6 feat: implement Phase 4d const-fold transform for select AST
Adds sel_const_fold_pass() — a single-pass bottom-up const-fold that
runs after the Phase 4c flatten loop in parse_select():

  4d-1  EQ/NE with either operand SEL_ANY → SEL_TRUE / SEL_FALSE
        (checks both child slots — commutativity sort makes SEL_ANY
        position non-deterministic after makeSelectNode interning)
  4d-2  Identity laws: TRUE&&X→X, X&&TRUE→X, FALSE||X→X, X||FALSE→X
  4d-3  Annihilation laws: FALSE&&X→FALSE, TRUE||X→TRUE (symmetric)
  4d-4  Complement laws: !TRUE→FALSE, !FALSE→TRUE

Memory semantics:
  level==0 (API server): frees orphaned nodes via free_select_node /
    sel_free_tree; OOM from makeSelectNode returns original node safely
  level>0  (CSE/scheduler): never manually frees; annihilation folds
    return the already-interned left/right singleton directly (no
    redundant makeSelectNode call); OOM guard unconditional so CSE
    mode also degrades gracefully instead of returning NULL

9 new TDD tests added to test_select.c (RED→GREEN verified).
All 166 tests pass (157 prior + 9 Phase 4d).
2026-04-29 08:24:04 +00:00
c2ad96a5e0 docs: incorporate review feedback for resreq-ast-cse-design
- Rename grammar rules: or_expr→select_or, and_expr→select_and,
  not_expr→select_not, atom_expr→select_primary
- Eliminate SEL_BOOL_LITERAL: parse true/false directly as
  SEL_TRUE/SEL_FALSE; boolean resources used standalone (gpu,
  not gpu==true)
- Remove 'true'|'false' from value production in grammar
- Use LSF-style unquoted strings in examples (type==linux,
  not type=="linux")
- Document n-ary vs binary tree decision in §6.2
- Add §8.5 Evaluation Memoization: per-host select_eval_ctx_t
  with node_id-indexed bool_bits bitmap, num_vals, str_vals
  arrays; memoized eval_select with cache check; session lifecycle
  (pre-session capacity, per-host alloc/discard, post-session
  GC + node ID recompaction)
- Add node_id field to xce_select_node_t for eval context indexing
- Clarify §9 two-level sharing: select CSE is global, resreq
  sharing is scoped to (user, queue, project)
- Clarify §10 select vs rusage boundary: select evaluates against
  host snapshot, rusage checks host.available (total - booked)
2026-04-22 02:25:30 +00:00
19898a198a docs: address deep document-review findings for resreq-ast-cse-design
Review by adversarial, feasibility, and product-lens reviewers.
Key changes:

- Add host_eval_ctx_t struct to carry both numeric and string host
  resource values; xvec_idval_t is for job allocation, not host eval
- Fix SEL_FALSE case in eval_select (was returning -1 instead of 0)
- Add bval field to appendix xce_select_node_t struct
- Fix makeSelectNode key_add race (EEXIST now re-finds existing entry)
- Specify two-phase GC sweep to avoid iterator corruption in kvtab
- Add EDA cluster justification for CSE memory savings
- Use %.17g instead of %g for number-to-string coercion (full precision)
- Add #include "kv.h" dependency note for Phase 4
- Add runtime goroutine assertion requirement for CGO bridge safety
- Add gc_sweep_select_nodes() CGO call in Phase 6 session boundary
- Clarify job cleanup happens at session boundaries (no mid-session kill)
- Clarify sel_key_hash/sel_key_cmp must hash fields individually (padding)
2026-04-21 07:05:49 +00:00
98911a2154 docs: add controller code consistency findings to persistence design
Incorporates investigation of vtaskmgr.c, netio.c, cluster.c, job.c,
join.c, and worker.c into the persistence-and-ha-design document:

- Part 2.7: Controller connection context (workers/scheduler/API servers only)
- Part 3.8: COW lock hierarchy (kvmgr rwlock -> xzarray mutex)
- Part 3.9: Checkpoint timer uses delaymgr, not raw pthread
- Part 4.9: Endpoint deferred cleanup (close fd/SSL, defer slot cleanup)
- Part 4.10: mark_worker_unavail() already exists, only needs extending
- Part 6.5: Replication uses endpoint/iomgr/vtask SSL pipeline
- Part 8.3: Lock safety analysis for reply-after-hooks change
- P0-2a, P0-8a, P2-5a: New implementation steps
- Appendix A.3/A.4: standby_conn_t and ha_state_t use endpoint_t*
2026-04-21 04:46:20 +00:00