Commit graph

2479 commits

Author SHA1 Message Date
lei.chen
66a1d1e680 attach jobs end with their command: relay watcher, once-only start banner, worker-side ttyd cleanup
Three attach-mode (-I) fixes, verified end-to-end on the t1 cluster:

1. Session hang on job finish (job_attach.go): the relay's client->worker
   pump blocked forever in ReadMessage after the worker hop closed, so the
   old wg.Wait()-before-Close teardown never ran and the client hung, then
   died with an abnormal 1006. A broker watcher now subscribes to
   EventJobFinished and on job end sends the 4001 policy close and closes
   both hops, unblocking the pumps; the teardown follows normally. The
   client (attach.go) treats 4001/1000/1001 -- and 1006-after-output as a
   final safety net -- as a clean session end.

2. "<<Starting on t1 >>" printed repeatedly (submit.go): the status poll
   printed the banner on every transition; now gated on a reportedStart
   flag. The URL is also no longer printed in attach mode -- it only makes
   sense for browse (-I --tty --browse) and DISPLAY jobs.

3. ttyd left behind after an attach job exits (xcecd_worker.c): a new
   tty_stop_attach_session(), called from process_exit_callback for TTY
   jobs, kills the per-job ttyd right away. This is insurance -- the sh -c
   exec means uv_proc monitors ttyd's own pid, so ttyd is normally gone
   before the callback fires -- but it guarantees no orphan when the
   timing lines up badly. Web-viewed sessions are untouched: they keep
   ttyd and output alive for later browsing, per design.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-15 08:32:21 +00:00
lei.chen
601f04dc00 feat(xcecli): bare -I maps to TTY attach interactive mode
-I without --xjob now means -I --tty: the submit attaches the interactive
session right in the calling terminal through the apiserver relay. The
previous bare -I mapping (interactive=3, readonly DISPLAY web view) had no
interactive input and gave the user no hint; --browse still opens the web
URL for TTY jobs and --xjob keeps the VNC path. The API's interactive=3
semantics are unchanged -- only this CLI's default remaps.

Help text updated: -I/--tty/--xjob descriptions and the long-help examples.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-15 03:40:32 +00:00
lei.chen
6d5281daf1 fix(worker): VNC start failure reports JOB_FAILED instead of killing the worker; fix generate_url snprintf overflow
xjob_start_vnc's four failure points (XCE_SERVER_DIR unset, pre-exec spawn
failure, DISPLAY export failure, port-wait timeout) called exit(1), taking
down the whole per-job worker with no user-visible reason and leaving the
job RUNNING forever (the master never learned of the death until its
instance reap path). It now returns int; the worker_job_callback call site
reports the standard failed-start pattern -- JOB_FAILED + status_message
"Failed to start VNC server (check worker log)" + worker_exit_flag so the
master reaps the instance and starts a fresh one for the next job.

xjob_stop_vnc is cleanup-only: its failures now log and return instead of
exit(1) -- a failed stop must not kill the worker or clobber the job's
exit code.

generate_url sized its snprintf with CMD_MAX_LENGTH (4096) while the url
buffer is URL_MAX_LENGTH (256). Latent since import: the old build's
non-fortified snprintf silently truncated, but any _FORTIFY_SOURCE build
aborts with SIGABRT (__chk_fail) on the FIRST interactive job -- found via
core dump after t1 bare -I jobs died ~1s after start ("*** buffer overflow
detected ***" in generate_url). Size both snprintfs with URL_MAX_LENGTH.

Verified on t1: -I --xjob on a host without vncserver fails in ~1s with
the reason in worker/master logs, worker exits cleanly, next batch job
completes; bare -I submits, dispatches, attaches via the relay and runs
until killed; daemons healthy.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-15 03:40:29 +00:00
lei.chen
a8c3e91b59 feat(interactive): attach TTY sessions through the apiserver websocket relay
Step 2 of the interactive-job UX work: `-I --tty` now attaches the session
to the submitting terminal by default instead of opening a browser.

Producer/consumer shape (user clusters cannot reach worker ttyd ports):

  xcecli (-I --tty, raw terminal)
    <-> GET /xce/v1/jobs/:id/attach (JWT auth + job:control ownership)
      <-> ws://worker:ttyd-port/ws (ttyd)

apiserver (controllers/job_attach.go):
- new websocket relay endpoint, route gated by RequirePermission("job:control");
  owner may always attach, others need a job:control scope covering the owner
- JWT accepted from the Authorization header or ?token= query param
  (browser WebSocket API cannot set headers)
- bidirectional frame pump with policy close codes: 4000 = cannot reach the
  session on the worker, 4001 = session ended
- the worker hop dials with the "tty" websocket subprotocol: ttyd 1.7.7
  completes the handshake without it but then stays silent (verified against
  the deployed binary)

xcecli (cmd/jobs/attach.go):
- attach client: dials the relay, raw mode via golang.org/x/term, ttyd
  wire format (TEXT hello {"AuthToken",columns,rows}; binary frames
  '0'+input, '1'+resize JSON, output '0' to stdout), SIGWINCH resize
  forwarding, terminal restored on every exit path
- submit.go: --browse flag opens the web URL instead of attaching (TTY jobs
  attach by default; XJOB/VNC keeps the browser path); the URL line is
  always printed as a record
- waitForInteractiveURL no longer fails when the job is RUN but the worker's
  start report (carrying the URL) has not landed yet -- poll and retry

Verified on t1: raw-client and real-xcecli attach round trips through the
relay (echo both ways), kill -> EXIT with URL retained, batch jobs unaffected,
all daemons healthy. Suites: meson 'apiserver backend' 1/1, CGO_ENABLED=0
controllers/router and xcecli tests green.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 13:24:09 +00:00
lei.chen
74121eb72e fix(apiserver): map pidinfo from job start into the job model (interactive_job_url)
The worker packs the interactive session URL (ttyd/XJOB) into the start
report's exdata as {"url": ...}; the controller stores it on
job->job.pidinfo->exdata and the capnp Job wire carries pidinfo (pidinfo@9,
JobPIDInfo.exdata@3) — but apiserver's cJobToModel never mapped pidinfo, so
models.JobInfo.InteractiveJobURL (declared only in the query-field whitelist
JobAdditionalFields) had no producer and interactive_job_url was permanently
empty in API responses. xcecli's waitForInteractiveURL/openBrowser flow could
never fire.

- models.JobInfo: add InteractiveJobURL (json interactive_job_url, matching
  the JobAdditionalFields whitelist name).
- convert_pure.go: rawPidInfo (pids/pgids/exdata) + interactiveURLFromExdata;
  rawJobToModel marshals pids/pgids into PIDInfo (pid_info is a JSONBJFields
  entry, parsed by processJobData) and promotes the exdata URL to
  InteractiveJobURL.
- convert.go: cJobToModel extracts job.pidinfo via pidinfo_pid/pidinfo_pgid
  cgo helpers (CGO cannot index the C arrays directly).

Cluster-verified end to end on t1 (fresh apiserver deployed): tty job
(xcecli -I --tty equivalent, exdata {"interactive":1}) now returns
interactive_job_url=http://<worker>:9000 and a populated pid_info; non-tty
jobs return ""/no pid_info. All daemons healthy, zero errors in window.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 09:20:27 +00:00
lei.chen
f661987a60 fix(scheduler-test): unlink the reconcile stdout-capture scratch files (bug-924 tail)
test_sim_reconcile_unaccounted.c captures stdout through mkstemp() files in
/tmp/xce_simreconcile_*, but only the shared capture_stdout_around() helper
unlinked its file after reading it back -- the 4 inlined capture sites left
theirs behind on every passing run (the mkdtemp shim does not intercept
mkstemp, so nothing else removed them). Add the same close(fd); unlink(tmp)
the file family's other capture helpers use to each of the 4 sites.

Verified: scheduler sim reconcile unaccounted test passes and leaves no
/tmp/xce_simreconcile_* files behind.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-14 07:27:45 +00:00
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
3442a57dd9
docs(spec): project-config: a built-in default project always exists
A job without a project and without a group default goes to the cluster
default project, the built-in `default` (members all) unless configured
otherwise; it is never rejected for lacking a project.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 07:17:22 +00:00
d769b746fa
docs(spec): host state never changes pools or shares; the scheduler skips unusable hosts
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 07:16:53 +00:00
d1be84cd66
docs(spec): project shares at a location; pool capacity, defaults, visibility
A share may be owned at a location (host group) as well as anywhere.
Per resource, located host groups and the rest of the cluster form
disjoint pools; usage is charged to the host's pool and every pool follows
the share rules on its own, so located ownership is real. Pool capacity
counts registered hosts including down and closed ones. No-default
submits list the user's projects; a per-user default project is a
client-side xcecli setting; members see their ancestors' usage, not
siblings' details.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 07:09:03 +00:00
e02310c02d
docs(spec): project open items: jobs count, inner projects, aliases, accounting
- `jobs` is a built-in resource for shares and member quotas: the job
  limits per project and user; pending caps go to pending-job-limits.
- Jobs may be charged to inner projects, with a warning and pend reason
  when their unassigned part is empty.
- Project aliases keep jobs through renames; running jobs follow them.
- Changing a pending job's project is part of job-modify.
- New project-accounting brief: durable finished-job records, outside the
  WAL, before controller-job-cleanup drops a job.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 07:03:20 +00:00
c6a938476b
docs(spec): project-fairshare: proposals agreed by the user
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 06:59:10 +00:00
16b9059116
docs(spec): fairshare belongs to projects; add project-fairshare brief
Fairshare weights and usage history live on the project tree; queues keep
priority between queues and only choose fairshare or FCFS ordering. The
per-queue `fairshare:` user lists in queues.yaml go away.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 06:50:34 +00:00
f3d4dba970
docs(spec): projects own shares of their parent's resources; project-guarantee becomes project-borrowing
A project's `share` (absolute or a percentage of its parent's) is carved
from the parent; siblings never add up to more than the parent. v1 is
strict: a project holds at most its share. A project's own jobs and its
children without a share draw from its unassigned part. Borrowing idle
shares above a project's own (`max`) and reclaim are future work, in the
renamed project-borrowing brief.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 06:38:39 +00:00
136e4a0132
docs(spec): peer-authentication-hardening: decide SSH-style ed25519 keys with temporary keys and revocation
Revocation and expiry close live connections authenticated with the key,
since authentication happens only at join. Lists the design questions:
where the trusted list is changed, keeping revoked keys revoked, bootstrap
keys, token registration for elastic hosts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 04:32:20 +00:00
497148a732
docs(roadmap): peer-authentication-hardening lists the ed25519 option
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 04:28:37 +00:00
274eddfb55
docs(spec): peer-authentication-hardening: option D, SSH-style ed25519 key pairs
Per-host identity without a CA; only public keys move, and the trusted
list can ride on the replicated cluster config. Recommended over the
phased per-role-keys/PKI plan; decision still deferred.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 04:28:23 +00:00
20ebef6d28
docs(spec): peer-authentication-hardening: secret type and key distribution deferred for later discussion
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 04:26:27 +00:00
a2bf160cc3
docs(spec): peer-authentication-hardening brief; production mode accepts user requests only from the apiserver
Promotes the roadmap item to a brief: production/test mode on the
controller, authenticated roles at join, per-role request allowlist with
user requests only from the apiserver, an admin role for xceadmin. Lays
out the open decisions on secret type (cluster key / per-role keys / PKI)
and key distribution (files / token enrolment), with a phased
recommendation. project-config Req 3.13 applies to test mode only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 04:25:17 +00:00
33edbeeaf0
docs(spec): project-config: apiserver is the only project authorization point
Production submits always go through the apiserver; harness and direct
client-library submits are test tools. The apiserver resolves the project
and checks project:submit; the controller records the project and the
authorization basis it is given. Direct submits are recorded as given
with basis `direct`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 04:17:04 +00:00
88ca983f43
docs(spec): project-config: project:submit RBAC implied by membership; project admins
Submitting under a project becomes the RBAC permission project:submit,
implied by membership (that project only) and grantable by roles (scope
covers the subtree). A project's admins get every job permission and
project:view over its subtree; they cannot edit the project, which only
the cluster admin changes through config in this stage.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 04:13:35 +00:00
332f86eaa1
docs(spec): resource control under the project tree; retire limits.yaml
The project tree is the only place concurrent use is capped: quotas are
written on the project (quota, member_quota over the subtree) and compiled
into the limit plugin, which becomes internal. Queues keep per-job
ceilings only; host slot caps are supply. Project path is the identity
and the only submit form; members are users and user groups, never
sub-projects. Adds the limits-to-owners backlog item.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 04:07:00 +00:00
df486a01c0
docs(spec): application-profile: Future Discussion section (design questions, deferred features, housekeeping)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 03:47:12 +00:00
7382e94d24
docs(spec): presets have no access control of their own
Preset routes need no RBAC permission; a submit made from a preset is
checked like any other submit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 03:33:25 +00:00
e48d36054d
docs(spec): defer per-profile access control to app-access-control
- v1: any queue:submit user may use any profile; listing reuses cluster:view
- app:use / app:view design kept in the brief and moved to the new backlog
  item app-access-control (depends on rbac-persistence for API grants)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 03:31:00 +00:00
863ba98ac8
docs(spec): application-profile hooks and starters; kill-path requirement; proposals 2-5
- worker-run hooks: pre/post_job_exec (once, first host) and
  pre/post_host_exec (once per host); no per-task hooks
- task starter reaches MPI ranks through the mpirun line XCE builds
  (correction); XCE_JOB_HOST_DIR, XCE_HOST_NTASKS, XCE_HOST_TASK_INDEX
- hook failure: job EXIT with a reason naming the hook; post hooks still run
- post hooks must survive every way a job ends: run limit is systemd
  RuntimeMaxUSec stopping the unit (worker included) and post-exec is only
  bounded by the unset TimeoutStopUSec; requirement for an explicit stop
  timeout and OOM survival (not logged as a bug: post-exec does run today)
- default profile always usable with queue:submit; service profile
  rejected for batch jobs; warning when no host matches the profile select

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 03:28:10 +00:00
f2406caaa7
docs(spec): application-profile: job starter wraps the full job, task starter wraps every task startup
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 03:15:43 +00:00
a50c0e236b
docs(spec): application-profile params and annotations; 0-valued rusage dropped; app-submit-hook backlog
- params: declared application settings XCE carries but never interprets;
  exported as XCE_APP_PARAM_*; job overrides with --app-param; undeclared
  names rejected; stored in exdata app_params
- annotations: metadata for tools, also exported as XCE_APP_ANN_* (name
  conversion, collision check, size limits, no secrets)
- merge drops 0-valued rusage terms so the scheduler sees no term (today a
  0 term still rejects hosts where the resource is over-committed)
- app-submit-hook (esub-style) recorded as a roadmap backlog item only

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 03:04:32 +00:00
f658b0a4b0
docs(spec): application-profile review fixes
Gaps closed:
- profile env travels separately from the job env (needed for the clean
  outer-layer environment; remote tasks get both)
- merge library parses and rewrites exdata (env, limits; keeps meta);
  added to job-config-merge scope
- new start_info fields listed (job starter, profile env)
- empty profile name = no profile, never resolved to default_application
- a file profile named default replaces the built-in one
- restart copies the profile name; array jobs carry one name
- multi-host outer pre/post-exec and job starter placement as open design
  questions; rusage=0 and declined-dispatch counting to confirm
- scheduler-side field completeness (frozen dispatched jobs, Conf4Sched
  profiles in snapshot/replay)
- no secrets in profiles; xceadmin warns on secret-looking env names

Stale text fixed: job-modify reference, exdata wording, rusage defaults
exception, I/O directories (moved to job-sandbox-execution), sandbox in the
sketch, job starter and job_pre_post_exec in the table, dispatch record
contents, misplaced rationale paragraph, versioning reference, scope and
touchpoints, task range (min/max) in job-config-layering.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 02:55:23 +00:00
1f9aaae050
docs(spec): structured profile resreq; per: optional (default task); merge rules at a glance
- profile resreq split into select / rusage entries / span / same / order;
  rusage entries carry optional per: (default task, today's PER_DEFAULT
  behaviour) and optional default
- job's rusage term wins whole for a resource in both; unit must match;
  no modifier inheritance
- compound/alternative: only the profile select applies; any profile
  rusage default or span/same/order rejects until PR-15
- job-config-layering: merge rules at a glance table; profile = essentials
  plus default reservations

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 02:49:53 +00:00
8f3a811a43
docs(spec): rusage merge: union, job value wins, profile per-type; compound rule
- rusage: union of profile and job resources; for a resource in both the
  job's value wins (either direction); the profile's per-type applies and an
  explicitly different per-type is rejected; omitted modifiers inherited;
  name=0 means none
- rusage is the one profile section that is a per-resource default;
  shared-resource protection via limits.yaml/quotas, later a counted marker
- side effects recorded for requirements (lowering warnings, redundant
  preset values, origin labels, ceiling errors, hash churn)
- compound/alternative: profile select ANDed into every part, per-task
  rusage merged per part, other profile resreq sections reject until PR-15

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 14:49:10 +00:00
a68d2fc965
docs(spec): presets record themselves in exdata.meta; job-labels backlog item
- no preset field on the server: the client puts preset name + hash into
  the job's exdata JSON under 'meta', passed through uninterpreted; the
  worker skips 'meta' silently; 'preset report' filters jobs client-side
- drop the local submission log idea
- job-labels: independent backlog item (general server-side labels)
- bug-1970: note the dropped REST 'tags' field

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 13:26:09 +00:00
5cfe64218c
docs(roadmap): config-history-audit backlog item; profile versioning/audit deferred from application-profile
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 13:12:39 +00:00
67002b2a25
docs(spec): application-profile v1 attributes: job starter added, others ship with their features
- v1 profile attributes: mode (direct), launch type, env + pre/post-exec,
  essential resreq and limits, plus the job starter
- principle: a profile attribute is added by the spec that builds its job
  feature; requeue/success exit values -> job-requeue (new backlog item),
  checkpoint and warning-before-kill later, output path -> I/O track,
  runtime estimate is not a profile attribute
- log bug-1970: REST submit accepts rerunable, requeue_error_values,
  run_time_estimation, mig_threshold, chkpnt_*, warning_* and drops them

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 13:08:29 +00:00
83c6eb8024
docs(spec): xcecli-presets: server preset directory, pull name collisions, /xce/v1 routes
- server presets live in <TopDir>/config/presets/ (or presets.dir in
  app.yaml), one file per preset, re-read on change; not in ClusterConfig
- pull refuses a name collision unless it updates the same server preset;
  --as / --force (keeps .bak); submit uses local presets only
- fix route prefix: /xce/v1/presets, not /api/v1

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 10:33:31 +00:00
d1e03055e4
docs(spec): split execution modes from application-profile into job-sandbox-execution
- application-profile keeps the profile core: config, access and submit,
  dispatch record, outer pre/post-exec layer; mode: accepts only direct
- sandbox mode + options, I/O directories, capability advertisement and
  placement by mode move to job-sandbox-execution
- order: application-profile requirements/design before job-config-merge
  design; implementation interleaves

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 10:20:15 +00:00
8900f8876b
docs(spec): application-profile: profile aliases; moving pending jobs deferred to job-modify
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 10:18:06 +00:00
c0bd701f48
docs(spec): xcecli-presets: one file per preset, same layout on client and server
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 10:15:34 +00:00
1a5ddc2642
docs(spec): xcecli-presets: environment capture by name (XCE_ and secret exclusions)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 10:14:50 +00:00
8f8be20885
docs(spec): application-profile: clean env for the outer pre/post-exec, reserved XCE_ prefix
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 10:12:15 +00:00
d88b9cb31f
docs(spec): application-profile: dispatch-window handling and profile content hash
- profile gone or changed between scheduler decision and controller
  dispatch: dispatch fails (retryable) and the job returns to PEND via
  requeue, never EXIT
- internal per-profile content hash (canonical capnp, excluding
  description) carried on the dispatch decision and the dispatch record

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 10:09:38 +00:00
84f2068ae3
docs(spec): application-profile: dispatch record covers resreq; removed profile makes jobs pend
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 09:57:37 +00:00
3088a21c86
docs(spec): application-profile: freeze execution values on the dispatch record, re-read on requeue
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 09:55:53 +00:00
4536d36f47
docs(spec): application profiles hold essentials only; additive rule; client-side presets
- profiles hold only what every job of the application must have; every
  profile value binds and a job may add to it, never change or remove it
  (replaces the default/fixed markers of 2026-10-09)
- convenience defaults move to client-side presets (new xcecli-presets
  brief): option-level expansion on the client, the apiserver only shares
  admin-deployed presets read-only, pull copies, export/import
- service section stays in the profile: probes, restart policy, ports bind;
  replica count within the profile range; spread/rollout if unset
- job-config-layering, job-config-merge brief/requirements, roadmap and
  resource-questions updated to the additive rule
- app:override and profile inheritance deferred; recommendations target
  site presets

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 09:47:30 +00:00
3fa9361ad8
docs(spec): application-profile: convenience purpose, advisory recommendations, resreq tuning questions
- profiles exist mainly so users need not repeat resreq and other settings;
  most values are defaults, only what the application needs is fixed
- usage-based recommendations are advisory (user decision); new backlog
  item profile-usage-insight
- open questions: per-term resreq markers with ranges, app:override,
  inheritance, presets, job labels, compound resreqs

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 09:30:51 +00:00
84501d30da
docs(spec): application-profile brief: own config file, default_application, live merge cleanup
- profiles in src/configs/applications.yaml (+ schema, ClusterConfig and
  Conf4Sched), optional file with a built-in 'default' profile
- default_application in xce.yaml; an undefined name is a config error at
  xceadmin build, live upgrade and controller start, never a fallback
- remove the superseded submit-time resolution text: the job keeps its
  profile name and own values, effective values come from job-config-merge
- this spec owns the profile attribute schema and override markers
- record the 2026-10-12 open questions with leanings

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 09:11:06 +00:00
19c9f616fb
docs(steering): resource log: delivery plan (tracks, first slices, deferred list with revisit triggers)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 08:00:30 +00:00
680a8bb641
docs(steering): resource log: relationships and compound resreqs (PR-15, N45-N50)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 07:59:41 +00:00
a14595deb0
docs(steering): resource log: uniform task relationship description, canonical jobspec (PR-14, N41-N44)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 07:58:01 +00:00
a6c18162ca
docs(steering): resource log: task relationship model (PR-13, N35-N40)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 07:32:42 +00:00