job-config-merge: spec initialized from its discovery brief. project-config: requirements generated (9 requirements): nested projects named by path, membership-based submit check with no inheritance and overlapping membership, group-default then cluster-default project, open mode until projects are defined, pending jobs held with a reason after project changes, roll-up quotas, project visibility, a project scope for job permissions covering the subtree and a project:view permission, compatibility. Roadmap: project-delegated-membership backlog item (runtime membership edits by project managers, deferred). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
17 KiB
Requirements Document
Project Description (Input)
Discovery brief: .kiro/specs/project-config/brief.md. Governing rules: .kiro/steering/job-config-layering.md (2026-10-09): the project owns resource ownership (membership, quotas, later guarantees, accounting) and never owns how a job runs or is ordered.
Who has the problem: cluster admins who need to control which users may charge work to a project and how much of the cluster each project may use; users who need to know which projects they can use and why a job is held by a project limit.
Current situation:
- A project is a free-text label on the job (
-P). Anyone can name any project. The apiserver only checks its length, and the scheduler maps an empty name to"default". - No project is defined anywhere in cluster config.
- Project-scoped limits exist in
limits.yaml, but the scheduler's project-group table is never loaded. The host-group and project-group managers were passed tobuild_limitswapped (bug-1933, fixed in6ecd418d). xcecli jobs list -Pis rejected by the apiserver ("unsupported filter").- Nothing shows a project's usage.
What should change (v1 = quota): nested project definitions in cluster config; default-project resolution; a membership check at submit; project limits working end to end and rolling up the tree; project visibility. Guarantees are project-guarantee.
Decisions (2026-10-10):
- Access is by project membership.
- Open mode applies until any project is defined.
- Default project: group default first, then the cluster default.
- A pending job held by a project change pends with a reason.
- Projects nest, named by path (e.g.
eng/hpc/cfd). - A job may be charged to any project in the tree.
- Membership is not inherited between parent and child, and a user may be a member of any number of projects.
- Quotas roll up: a job must fit the limits of its project and of every ancestor.
- RBAC interaction:
- a new
projectscope for job permissions, so a project manager can view and control the jobs of a project and its whole subtree; - a
project:viewpermission. - Runtime (delegated) membership edits are left for later; membership changes only through cluster config.
- a new
Introduction
This feature makes projects first-class cluster configuration entities that control resource ownership.
- Definitions: admins define a tree of projects named by path, each with its own members, and say which user groups default to which project.
- Submit: the system resolves each job's project, admits only members, and records the project on the job.
- Quotas: existing project-scoped limits apply to the right jobs and roll up the tree, and a held job's reason names the project.
- Visibility: users and admins can see projects and their usage against limits.
- RBAC: roles can grant job permissions over a project subtree (project managers) and the right to view projects one does not belong to.
- Compatibility: a cluster that defines no projects keeps today's behaviour.
Boundary Context
- In scope:
- nested project definitions (path name, description, members, default-for groups) and a cluster default project;
- default-project resolution, membership check at submit, and an "open" mode when no projects are defined;
- pending-job behaviour when a project or membership changes;
- project-scoped limits applying end to end and rolling up the tree, with project-naming pend reasons;
- overlapping membership (a user in several projects);
- project listing (as a tree) and detail with usage against limits;
- RBAC: a
projectscope for job permissions (covering the project's subtree) and aproject:viewpermission; - job filtering by project.
- Out of scope:
- guaranteed shares, owned pools, borrowing, reclaim (
project-guarantee); - fairshare;
- any project influence on job ordering or priority (queues own ordering);
- accounting history and billing of finished jobs;
- RBAC gating of which project a job is submitted under (membership decides; the existing queue permission still applies);
- runtime (delegated) membership edits by project managers (future; membership changes only through cluster config);
- per-user default projects in
users.yaml; - membership inherited between parent and child projects;
- moving or renaming a project while keeping its jobs' recorded name;
- wildcard or pattern matching of member names.
- guaranteed shares, owned pools, borrowing, reclaim (
- Adjacent expectations:
- The existing limit configuration (
limits.yaml) stays the place where project quotas are written; this feature makes those limits take effect for defined projects. - User groups come from the existing user-group configuration.
- Grants made through the role API are subject to the existing
rbac-persistencegap (not durable across apiserver restart) until that spec lands. job-config-mergetreats project quotas as ceilings: they hold or admit a job but never change its values.- The defect that resolved limit host and project scopes against each other's group tables (it also broke host-group limits) was fixed separately as bug-1933 (
6ecd418d); Requirement 6.7 keeps it as a requirement.
- The existing limit configuration (
Requirements
Requirement 1: Project definitions
Objective: As a cluster admin, I want to define projects and their members in the cluster configuration, so that project ownership is explicit and versioned with the rest of the cluster config.
Acceptance Criteria
- The configuration tool shall accept project definitions consisting of a path name, an optional description, members (user names, user-group names, or
all), optional excluded members, and an optional list of user groups for which the project is the default. - The configuration tool shall treat a path name of one segment (e.g.
eng) as a top-level project and a path of several/-separated segments (e.g.eng/hpc/cfd) as a child of the project named by the path without its last segment. - The configuration tool shall accept an optional cluster default project naming one defined project.
- If a project definition repeats a path name, uses a reserved name, has an empty or malformed path segment, names a parent project that is not defined, names an undefined user group, or lists a default-for user group that is not covered by the project's members, then the configuration tool shall reject the configuration with an error identifying the project and the offending field.
- If the cluster default project names an undefined project, or a project whose members do not include every user, then the configuration tool shall reject the configuration with an error naming the cluster default project.
- When a configuration with changed project definitions is applied by live configuration upgrade, the Cluster shall apply the new definitions to all subsequent submissions and scheduling decisions without a restart.
- The Cluster shall keep project definitions across controller failover and restart identically to other cluster configuration.
Requirement 2: Project resolution at submit
Objective: As a user, I want my job to get the right project when I do not name one, so that I do not have to pass -P for my usual project.
Acceptance Criteria
- When a job is submitted with a project path name, the Cluster shall use that project for the job, whether it is a top-level, inner or leaf project.
- When a job is submitted without a project name and at least one defined project lists a user group the submitter belongs to as default-for, the Cluster shall use the first such project in configuration order.
- When a job is submitted without a project name and no default-for rule matches the submitter, the Cluster shall use the cluster default project if one is configured, and otherwise the project
default. - The Cluster shall record the resolved project name on the job at submit, show it in the job's details, and keep it unchanged across later configuration changes, failover and restart.
- The Cluster shall apply the same project resolution to every submit path (REST API,
xcecli, harness and client library) and to every element of a job array.
Requirement 3: Membership check at submit
Objective: As a cluster admin, I want only a project's members to submit work under it, so that projects control who may use their resources.
Acceptance Criteria
- While at least one project is defined, when a job is submitted under a project whose members include the submitter, the Cluster shall accept the job's project.
- If, while at least one project is defined, a job is submitted under a project whose members do not include the submitter, then the Cluster shall reject the submission with an error naming the project and stating that the user is not a member.
- If, while at least one project is defined, a job is submitted under a project name that is not defined, then the Cluster shall reject the submission with an error naming the unknown project.
- Where the submitter has the cluster administrator role, the Cluster shall accept any defined project without a membership check.
- The Cluster shall treat a user as a member of a project if the user is listed directly in that project's own members, belongs to a user group listed there, or those members include
all, and the user is not excluded there. - The Cluster shall not infer membership of a project from membership of its parent, its children or any other project.
- Where a user is a member of several projects, the Cluster shall accept the user's jobs under any of those projects.
- The Cluster shall reject a non-member or unknown-project submission before the job is assigned a job ID or recorded, on every submit path.
Requirement 4: Open mode when no projects are defined
Objective: As an operator of an existing cluster, I want clusters without project definitions to keep working as today, so that upgrading does not break existing submissions.
Acceptance Criteria
- While no project is defined in the cluster configuration, the Cluster shall accept any project name at submit without a membership check.
- While no project is defined in the cluster configuration, when a job is submitted without a project name, the Cluster shall record the project
default. - When the first project definitions are applied to a cluster that had none, the Cluster shall apply Requirement 5 to pending jobs whose recorded project is undefined or does not include their owner.
Requirement 5: Pending jobs after project changes
Objective: As a cluster admin, I want project changes to take effect on work that has not started, without disturbing running work, so that removing a project or a member is effective and reversible.
Acceptance Criteria
- If, while projects are defined, a pending job's recorded project is no longer defined, then the Scheduler shall keep the job pending with a reason naming the project and stating that it is not defined.
- If a pending job's owner is no longer a member of the job's recorded project, then the Scheduler shall keep the job pending with a reason naming the project and stating that the owner is not a member.
- When a later configuration change makes a held job's project defined again, or restores its owner's membership, the Scheduler shall consider the job for scheduling again without user action.
- While a job is running, the Cluster shall not stop, requeue or alter the job because of a change to its project's definition or membership.
- The Cluster shall allow an admin to kill or modify a job held by Requirement 5 using the existing job controls.
Requirement 6: Project quotas
Objective: As a cluster admin, I want limits scoped to projects to cap each project's usage, so that a project cannot use more than its share of the cluster.
Acceptance Criteria
- When a limit is scoped to listed projects, the Scheduler shall count against that limit exactly the jobs whose recorded project is a listed project or a descendant of one (or any project, for
all), and is neither an excluded project nor a descendant of one. - When a limit is scoped per project, the Scheduler shall apply the limit value separately to each matching project, counting that project's own jobs and the jobs of its descendants.
- The Scheduler shall dispatch a job only if it fits every limit that applies to the job's recorded project or to any of its ancestors.
- The Scheduler shall count a job only against limits matched through its recorded project and that project's ancestors, never against limits of other projects its owner belongs to.
- If dispatching a job would exceed a project-scoped limit, then the Scheduler shall keep the job pending with a reason naming the limit and the project whose limit is full (the job's own project or the ancestor).
- When usage under a project-scoped limit falls below its value, the Scheduler shall consider jobs held by that limit for scheduling again.
- The Scheduler shall resolve each limit's user, queue, project and host scopes against the corresponding kind of names only, so that a project name never matches a host group and a host-group name in a host scope matches the hosts of that group.
- The live Scheduler and the scheduler simulator shall make identical project-limit decisions for the same input.
Requirement 7: Project visibility
Objective: As a user or admin, I want to see projects, their members and their usage against limits, so that I know which projects I can use and why a job is held.
Acceptance Criteria
- When a user lists projects through the REST API or
xcecli, the Cluster shall return every project the user is a member of, with its path name and description, shown in tree order, and mark the project that would be the user's default. - Where the requester has the cluster administrator role, or a
project:viewpermission covering a project, the Cluster shall include that project in the list with its members, excluded members and default-for user groups. - When a user requests a project's details, the Cluster shall show, for each limit that applies to the project or to any of its ancestors, the limit name, the project the limit is matched through, the limited resource, the limit value and the current usage counted against it (including descendants' jobs).
- If a user requests the details of a project they are not a member of, and they have neither the cluster administrator role nor a
project:viewpermission covering the project, then the Cluster shall reject the request without revealing the project's members or usage. - When a user lists jobs filtered by project through the REST API or
xcecli, the Cluster shall return only jobs with that recorded project, or, when the user asks to include sub-projects, with that project or any descendant, subject to the user's existing job-visibility permissions. - While no project is defined, the Cluster shall report that projects are not configured when projects are listed.
- The scheduler's diagnostic interface shall show, for a named project, the limits that apply to it and its current usage.
Requirement 8: Project-scoped access control
Objective: As a cluster admin, I want to grant a project manager rights over the jobs and details of a project and its sub-projects, so that project leads can manage their project's work without being cluster administrators.
Acceptance Criteria
- The Cluster shall accept roles that grant a job permission (view, kill, modify or any other existing job permission) with the scope type
projectand a list of project path names as scope values. - The Cluster shall treat a
project-scoped grant on a project as covering that project and every descendant project. - When a user performs a job operation, the Cluster shall allow it if any of the user's grants for that operation covers the job (scope
all,selffor the user's own jobs, orprojectcovering the job's recorded project), and shall reject it with a permission error otherwise. - When a user lists jobs, the Cluster shall return exactly the jobs covered by the user's view grants.
- The Cluster shall accept roles that grant
project:viewwith the scope typeallorproject; aprojectscope covers the named projects and their descendants. - If, while projects are defined, a role is created or updated with a
projectscope value that names an undefined project, then the Cluster shall reject the change with an error naming the unknown project. - While a
projectscope value names a project that is no longer defined, the Cluster shall treat that value as covering no project. - The Cluster shall leave the behaviour of existing roles and grants unchanged; the default RBAC configuration shall grant no
project-scoped permission to any role other than the cluster administrator.
Requirement 9: Compatibility and durability
Objective: As an operator, I want projects added without data migration or downtime, so that existing jobs and records keep working.
Acceptance Criteria
- When a job recorded before this feature is recovered, the Cluster shall keep its recorded project name, treating an empty name as
default. - The Cluster shall accept a cluster configuration without any project definitions and behave as Requirement 4 describes.
- When a configuration tool of an earlier version pushes a configuration without project definitions, the Cluster shall treat it as defining no projects.