diff --git a/.kiro/specs/application-profile/brief.md b/.kiro/specs/application-profile/brief.md index 80550ec5..f13a96dd 100644 --- a/.kiro/specs/application-profile/brief.md +++ b/.kiro/specs/application-profile/brief.md @@ -572,10 +572,6 @@ Decided 2026-10-12 (user), so a rename never strands jobs: - **Open for requirements**: - ~~How resource defaults combine with a job's own resreq~~ — settled 2026-10-09, owned by `job-config-merge`. - - Raised 2026-10-12, not yet decided: - - 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: scheduling and execution values frozen at dispatch, re-read on requeue ("Dispatch record"); a removed profile makes its jobs pend ("Profile removed while jobs use it"); clean env for @@ -586,7 +582,9 @@ Decided 2026-10-12 (user), so a rename never strands jobs: split into `job-sandbox-execution`; v1 attributes are the four plus the job starter, others ship with their job features; profile history and change audit deferred to the roadmap (`config-history-audit`): the - content hash and the dispatch record already show what each run used. + content hash and the dispatch record already show what each run used; + no job labels needed here (presets record themselves in `exdata.meta`; + general labels are the `job-labels` backlog item). - **Out**: - The `sandbox` mode and its options, I/O directories, capability advertisement, placement by mode and the worker sandbox mechanics diff --git a/.kiro/specs/xcecli-presets/brief.md b/.kiro/specs/xcecli-presets/brief.md index baa38882..ca33b394 100644 --- a/.kiro/specs/xcecli-presets/brief.md +++ b/.kiro/specs/xcecli-presets/brief.md @@ -122,8 +122,35 @@ configuration level. - **Safety and visibility:** a warning on export/import when env variable names look like secrets; `xcecli jobs submit --dry-run` shows the expanded options and the effective values after the profile merge - (`job-config-merge`); optionally the preset name is recorded as a job - label (`preset=`) for comparing variants. + (`job-config-merge`). +- **No preset field on the server; preset identity in `exdata.meta`** + (user, 2026-10-12). Expansion is entirely client-side and the server sees + ordinary job options. To compare variants, the client adds one opaque key + to the job's exdata JSON: + + ```json + { "sub_env_vars": {...}, "limits": {...}, + "meta": { "preset": "cfd-team/openfoam-large", "preset_hash": "3f2a9c" } } + ``` + - exdata already round-trips with no schema change: client → + `start_info.exdata` → WAL submit fact and snapshot → worker, and job + queries return it as `extend_data` (`apiserver/backend/convert_pure.go` + :388, :537); 16 KB cap (`maxExdataLen`, :395). + - `meta` is client-only metadata: apiserver and controller pass it + through uninterpreted. The worker's `parse_exdata()` + (`worker/src/xcecd_exdata.c`) ignores unknown top-level keys but logs a + NOTICE for each; this spec makes `meta` a known, silently skipped key + (one-line worker change). + - `xcecli preset report ` lists the user's jobs through the normal + API and filters on `extend_data.meta.preset` client-side: runtime, peak + memory, efficiency and exit status per preset or preset version. It + covers jobs from any login node, and the portal when it writes the same + key. No local submission log. + - Limits: the server cannot filter or index `meta`, so the report fetches + and filters the user's jobs (fine for personal tuning); `meta` is + whatever the client wrote, informational only, never trusted. + - Server-side labels for filtering and team-wide grouping are a separate, + general feature (`job-labels`, backlog). - **Portal:** the same expansion (a small option-level merge) and the same read-only listing; its personal presets are stored by the portal itself and are not shared with xcecli in the first version. @@ -131,13 +158,13 @@ configuration level. ## Scope - **In:** preset format, xcecli commands, expansion and precedence, the read-only apiserver listing/fetch and its file directory, pull/diff, - export/import, secret warning, dry-run display, tests. + export/import, secret warning, dry-run display, `exdata.meta` and + `preset report`, the worker's `meta` skip, tests. - **Out:** writable server-side shared presets (would need owners, visibility and durable storage; revisit only if the portal needs it, after `rbac-persistence`), automatic application of presets, any server-side preset expansion. -- **Open:** whether the preset-name label lives here or in - `job-status-detail-display` (job labels); the portal's preset storage. +- **Open:** the portal's preset storage. ## Upstream / Downstream - **Upstream:** `application-profile` (profiles and `--app`), diff --git a/.kiro/steering/roadmap.md b/.kiro/steering/roadmap.md index 86de589d..70422f5a 100644 --- a/.kiro/steering/roadmap.md +++ b/.kiro/steering/roadmap.md @@ -124,8 +124,9 @@ Direction: `.kiro/steering/resource-model.md`. Decisions, proposals (PR-1 generi - [ ] project-delegated-membership — NEW 2026-10-10 (from project-config requirements, user decision: future). Project managers edit their project's (and subtree's) members at runtime without an admin config push; needs a durable store that coexists with `xceadmin` config pushes (e.g. a separate delegated member list) and audit. Dependencies: project-config, rbac-persistence. - [ ] job-modify — NEW 2026-10-12 (from application-profile discussion, user decision; backlog, no brief yet). Modify a pending job (LSF `bmod`): apiserver action (today `"modify"` is commented out, `controllers/jobs.go:2446`; `JOB_MODIFY` only an enum), controller opcode, WAL fact with snapshot field-completeness, scheduler re-merge, xcecli. First attributes: `--app` (owner with `app:use` on the new profile; admins in bulk, e.g. `--app-from `), `-R`, `-n`, queue; later begin/end time (`job-time-window`), dependencies. Dependencies: application-profile, job-config-merge. - [ ] config-history-audit — NEW 2026-10-12 (from application-profile discussion, user decision: needed, roadmap). Keep past cluster-config versions (including `applications.yaml` profiles) with who changed what and when: `xceadmin config history` / `diff`, look up a profile by its content hash (the application-profile hash recorded on dispatch records), audit trail of live upgrades. Per-job display of the values a run used is already covered by the application-profile dispatch record; this adds admin history and audit. Covers the whole cluster config, not only profiles (the controller already tracks `configVersion`/`configChecksum`). Dependencies: application-profile, admin-config-tool. +- [ ] job-labels — NEW 2026-10-12 (from application-profile discussion; backlog, no brief yet). General Kubernetes-style job labels: `--label key=value` (repeatable, limited charset and size), an additive submit-data field through WAL and snapshot (field completeness), server-side filtering (`jobs list -l k=v`) and summaries grouped by label (runtime, peak memory, efficiency); metadata only, never used for placement. Reuses or replaces the REST `tags` field that is silently dropped today (bug-1970). Not needed for presets (those use `exdata.meta`); candidates: team-wide comparison, services labelling replicas. Dependencies: none. - [ ] job-requeue — NEW 2026-10-12 (from application-profile discussion, user decision; backlog, no brief yet). Automatic requeue on given exit values (LSF `REQUEUE_EXIT_VALUES`) and success exit values (`SUCCESS_EXIT_VALUES`), with a requeue loop limit; wires the commented-out `requeue` job action (`apiserver/controllers/jobs.go`) and the REST `requeue_error_values` / `rerunable` options that are silently dropped today (bug-1970). Adds the matching application-profile attributes (a profile attribute ships with its job feature). Later, same principle: checkpoint settings and warning-before-kill each get their own spec. Dependencies: application-profile. -- [ ] xcecli-presets — NEW 2026-10-12 (from application-profile discussion, user decisions). Client-side presets replace convenience defaults in profiles: a preset is a set of job options (`--app`, `--queue`, `-R`, `-n`, env, limits) expanded by the client, a flag replacing the preset's value for that option; one file per preset (`~/.config/xce/presets//.yaml`, same layout in the apiserver's presets dir), env capture by name (`pass:`; `XCE_*` and secret-looking names excluded); the apiserver only shares admin-deployed presets read-only (`GET /xce/v1/presets[/{ns}/{name}]`, files in `/config/presets/` or `presets.dir`, re-read on change; not in ClusterConfig), and `preset pull` copies one locally so server-side removal never affects users; on a name collision pull refuses unless it is an update of the same server preset (`--as` / `--force` with `.bak`); submit uses local presets only (`preset diff`, `pull --force` user-initiated); user-to-user sharing by `preset export`/`import`; presets carry no privilege and are not a configuration level; optional preset-name job label; the portal does the same expansion. Brief: `.kiro/specs/xcecli-presets/brief.md`. Dependencies: application-profile. +- [ ] xcecli-presets — NEW 2026-10-12 (from application-profile discussion, user decisions). Client-side presets replace convenience defaults in profiles: a preset is a set of job options (`--app`, `--queue`, `-R`, `-n`, env, limits) expanded by the client, a flag replacing the preset's value for that option; one file per preset (`~/.config/xce/presets//.yaml`, same layout in the apiserver's presets dir), env capture by name (`pass:`; `XCE_*` and secret-looking names excluded); the apiserver only shares admin-deployed presets read-only (`GET /xce/v1/presets[/{ns}/{name}]`, files in `/config/presets/` or `presets.dir`, re-read on change; not in ClusterConfig), and `preset pull` copies one locally so server-side removal never affects users; on a name collision pull refuses unless it is an update of the same server preset (`--as` / `--force` with `.bak`); submit uses local presets only (`preset diff`, `pull --force` user-initiated); user-to-user sharing by `preset export`/`import`; presets carry no privilege and are not a configuration level; no preset field on the server: the client records preset name + hash in the job's `exdata.meta` (passed through uninterpreted; worker skips `meta`), and `preset report` filters jobs on it client-side; the portal does the same expansion. Brief: `.kiro/specs/xcecli-presets/brief.md`. Dependencies: application-profile. - [ ] profile-usage-insight — NEW 2026-10-12 (from application-profile discussion, backlog; no brief yet). Per-profile report over recent jobs comparing the profile's defaults with actual use (requested vs. peak memory, CPU efficiency, OOM kills, pend time, runtime by variant) and suggesting better values for site presets (or a profile essential), e.g. "preset openfoam rusage mem 4000, p95 peak 1600 → suggest 2000" (Kubernetes VPA recommender precedent). **Advisory only** (user decision): the admin applies changes to site presets or `applications.yaml`; nothing tunes itself. Optional user hint ("used 1.4G of 4G requested"). Dependencies: application-profile, run usage in job records. - [ ] lsf-config-migration — NEW 2026-10-09 (user idea, backlog; no brief yet). A tool (likely an `xceadmin` subcommand) that converts LSF configuration (`lsb.queues`, `lsb.applications`, `lsb.resources` Limit sections, `lsb.users`/`lsb.hosts` groups, `lsb.params` defaults, project settings) into XCE `configs/*.yaml`, with a report of what does not map: queue `RES_REQ` (XCE queues are policy only; move into a profile or drop), LSF's full per-section merge rules vs XCE's simplified ones, compound/alternative resreqs, unsupported parameters. Dependencies: job-config-merge, application-profile, project-config, parjob-placement (span), admin-config-tool. Promote via `/kiro-discovery` when those land. diff --git a/.wolf/buglog.json b/.wolf/buglog.json index 1ab3b6c6..0d783a94 100644 --- a/.wolf/buglog.json +++ b/.wolf/buglog.json @@ -18776,7 +18776,7 @@ "timestamp": "2026-10-12T13:07:37Z", "last_seen": "2026-10-12T13:07:37Z", "occurrences": 1, - "error_message": "apiserver accepts rerunable, requeue/checkpoint/runtime/warning submit options, never sends them\n\n**Observed:** (source reading, 2026-10-12, at 83c6eb80)\n`POST /xce/v1/jobs/create` accepts these `JobSubmitRequest` fields\n(`src/frontend/apiserver/models/jobs.go`, struct at :636) and answers success,\nbut none of them reaches the controller:\n```go\nRerunable bool `json:\"rerunable,omitempty\"`\nWarningTimePeriod int `json:\"warning_time_period,omitempty\"`\nWarningAction string `json:\"warning_action,omitempty\"`\nRequeueErrorValues string `json:\"requeue_error_values,omitempty\"`\nRunTimeEstimation int `json:\"run_time_estimation,omitempty\"`\nMigThreshold int `json:\"mig_threshold,omitempty\"`\nChkpntPeriod int `json:\"chkpnt_period,omitempty\"`\nChkpntDir string `json:\"chkpnt_dir,omitempty\"`\nInitChkpntPeriod int `json:\"init_chkpnt_period,omitempty\"`\n```\n- `rerunable`, `warning_time_period`, `warning_action`, `init_chkpnt_period`\n are not read anywhere outside `models/`.\n- `requeue_error_values`, `run_time_estimation`, `mig_threshold`,\n `chkpnt_period`, `chkpnt_dir` are copied into `models.JobInfo`\n (`controllers/jobs.go:1214-1218`, and on restart :1013-1025), but\n `modelJobToSubmit()` (`backend/convert.go:334`) never reads them, and the\n controller's `JobSubmitData` / `JobStartInfo` (`src/schema/controller.capnp`\n :583, :314) have no field for them.\n- None is in `preCheckSubmitOptions()`'s list of refused options\n (`controllers/jobs.go:1285`), which bug-1936 added for exactly this kind of\n option (in/out/err files, asked hosts, begin/term time).\n\n**Expected:** each submit option is either passed on to the job or rejected\nwith 400 naming the option, as `preCheckSubmitOptions()` does for the others.\n**Impact:** wrong result: a user asking for automatic requeue on given exit\ncodes, rerun on host failure, periodic checkpoints or a warning signal before\nthe run limit gets a success reply and a job that does none of it.\n**Found by:** review during the `application-profile` brief discussion\n(extra v1 attributes), 2026-10-12.", + "error_message": "apiserver accepts rerunable, requeue/checkpoint/runtime/warning submit options, never sends them\n\n**Observed:** (source reading, 2026-10-12, at 83c6eb80)\n`POST /xce/v1/jobs/create` accepts these `JobSubmitRequest` fields\n(`src/frontend/apiserver/models/jobs.go`, struct at :636) and answers success,\nbut none of them reaches the controller:\n```go\nRerunable bool `json:\"rerunable,omitempty\"`\nWarningTimePeriod int `json:\"warning_time_period,omitempty\"`\nWarningAction string `json:\"warning_action,omitempty\"`\nRequeueErrorValues string `json:\"requeue_error_values,omitempty\"`\nRunTimeEstimation int `json:\"run_time_estimation,omitempty\"`\nMigThreshold int `json:\"mig_threshold,omitempty\"`\nChkpntPeriod int `json:\"chkpnt_period,omitempty\"`\nChkpntDir string `json:\"chkpnt_dir,omitempty\"`\nInitChkpntPeriod int `json:\"init_chkpnt_period,omitempty\"`\n```\n- `rerunable`, `warning_time_period`, `warning_action`, `init_chkpnt_period`\n are not read anywhere outside `models/`.\n- `requeue_error_values`, `run_time_estimation`, `mig_threshold`,\n `chkpnt_period`, `chkpnt_dir` are copied into `models.JobInfo`\n (`controllers/jobs.go:1214-1218`, and on restart :1013-1025), but\n `modelJobToSubmit()` (`backend/convert.go:334`) never reads them, and the\n controller's `JobSubmitData` / `JobStartInfo` (`src/schema/controller.capnp`\n :583, :314) have no field for them.\n- None is in `preCheckSubmitOptions()`'s list of refused options\n (`controllers/jobs.go:1285`), which bug-1936 added for exactly this kind of\n option (in/out/err files, asked hosts, begin/term time).\n\n**Expected:** each submit option is either passed on to the job or rejected\nwith 400 naming the option, as `preCheckSubmitOptions()` does for the others.\n**Impact:** wrong result: a user asking for automatic requeue on given exit\ncodes, rerun on host failure, periodic checkpoints or a warning signal before\nthe run limit gets a success reply and a job that does none of it.\n**Found by:** review during the `application-profile` brief discussion\n(extra v1 attributes), 2026-10-12.\n\nUPDATE (2026-10-12): The REST submit model's `Tags []string` (`json:\"tags\"`, models/jobs.go JobSubmitRequest) is also accepted and dropped: nothing outside models/ reads it, and it is not in preCheckSubmitOptions(). Roadmap item job-labels would reuse or replace it.", "file": "src/frontend/apiserver/controllers/jobs.go, src/frontend/apiserver/backend/convert.go, src/frontend/apiserver/models/jobs.go", "root_cause": "TODO: required for fixed/partial", "fix": "TODO: required for fixed/partial\n\nVerification:\n- Test: TODO: name + file; RED before the fix, GREEN after\n- Suites: TODO: suite results and build profile\n- Live: TODO: soak/deploy run, or n/a and why", diff --git a/.wolf/bugs/bug-1970.md b/.wolf/bugs/bug-1970.md index 628e6caf..d5332fd5 100644 --- a/.wolf/bugs/bug-1970.md +++ b/.wolf/bugs/bug-1970.md @@ -51,6 +51,8 @@ the run limit gets a success reply and a job that does none of it. **Found by:** review during the `application-profile` brief discussion (extra v1 attributes), 2026-10-12. +UPDATE (2026-10-12): The REST submit model's `Tags []string` (`json:"tags"`, models/jobs.go JobSubmitRequest) is also accepted and dropped: nothing outside models/ reads it, and it is not in preCheckSubmitOptions(). Roadmap item job-labels would reuse or replace it. + ## Environment - OS: no /etc/os-release; Docker container; NixOS kernel; kernel Linux 6.18.33 x86_64 - libc: n/a: found by source reading, no binary run (host ldd reports glibc 2.40)