diff --git a/.kiro/specs/application-profile/brief.md b/.kiro/specs/application-profile/brief.md index 390422e2..11072282 100644 --- a/.kiro/specs/application-profile/brief.md +++ b/.kiro/specs/application-profile/brief.md @@ -31,8 +31,8 @@ decisions):** and recomputes them when a profile changes (a pending job that no longer satisfies its profile pends with a reason; running jobs are unaffected). Execution-side values (mode, options, launch type, env, pre/post-exec) are - still taken from the profile at dispatch time; requirements decide whether - dispatch freezes them on the job record. + still taken from the profile at dispatch time and frozen on the dispatch + record (decided 2026-10-12, "Dispatch record" below). **Update 2026-10-10 (`/kiro-discovery`, long-running services):** a profile may declare **kind `service`** with a service section: restart policy @@ -354,6 +354,28 @@ Not part of this spec, recorded here because they replace profile defaults: - Presets carry no privilege: `app:use`, `queue:submit`, the profile's essentials, queue ceilings and project quotas still apply at submit. +### Dispatch record +Decided 2026-10-12 (user): execution-side values are **frozen at dispatch**. +- At each dispatch the controller reads the job's profile and puts the + effective execution values (mode, mode options, launch type, env, outer + pre/post-exec, limits) into the job's `start_info` for the worker, **and** + into an additive payload on the WAL dispatch fact + (`persist_submit_job_dispatch_fact`, `controller/persist.c:8167`) and the + snapshot. Both apply seams decode it; `/xce-audit-invariants` checks the + round trip. +- Today the queue's pre/post-exec copied at dispatch (`controller/job.c` + 1825-1897) is kept in memory only, so after a failover the new primary + does not know what a running job was given. The frozen record closes that + gap as pre/post-exec moves to the profile. +- A running or finished job's details show the frozen values, and say + "profile changed since dispatch" when the current profile differs. +- **Requeue or restart re-reads the profile** at the next dispatch, the same + as the live merge does for pending jobs. +- Why: for sandboxed jobs the mode and mounts a job actually ran with is a + security/audit fact, and `job-sandbox-execution`'s mandatory cleanup + depends on it; `persistence.md` does not allow memory-only state without a + documented scope decision. + ### Default profile - **Set by `default_application: ` in `xce.yaml`**, a cluster parameter (as LSF keeps `DEFAULT_APPLICATION` in `lsb.params`), not a flag @@ -413,9 +435,6 @@ Not part of this spec, recorded here because they replace profile defaults: - Whether the profile can be changed for a pending job (leaning yes: re-check `app:use`, store the new name, the scheduler re-evaluates). - Raised 2026-10-12, not yet decided: - - Whether execution-side values read at dispatch are frozen on that - run's record (leaning yes: display and post-dispatch failover use what - actually ran; a requeue reads the current profile again). - Removing a non-default profile that pending jobs still name (leaning: xceadmin warns, the jobs pend with "profile X not defined", running jobs continue). @@ -424,7 +443,8 @@ Not part of this spec, recorded here because they replace profile defaults: - Job labels (`--label key=value`, e.g. the preset name) and a summary grouped by label, to compare tuning variants: here, `job-status-detail-display`, or `xcecli-presets`? - - Settled 2026-10-12: override granularity (no markers; additive rule), + - Settled 2026-10-12: execution values frozen at dispatch, re-read on + requeue ("Dispatch record"); override granularity (no markers; additive rule), limits a job may lower (profile limits are maximums), personal presets (client side), `app:override` and inheritance (deferred). - Splitting the spec: execution mode, I/O directories, capability