myxce/.kiro/specs/libxce-alloc-preason-equality/requirements.md
Rongsong Shen 6e0463e707
chore: persist OpenWolf state and libxce-alloc-preason-equality spec
- .wolf/anatomy*, memory.md: hook-maintained index and session log
  through the bug-1851..1854 work.
- .kiro/specs/libxce-alloc-preason-equality/: requirements, design,
  research and tasks generated; none approved yet (spec.json phase
  tasks-generated).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 08:44:44 +00:00

51 lines
8.2 KiB
Markdown

# Requirements Document
## Introduction
Engineers maintaining the XCE scheduler and controller — anyone who needs to determine whether two scheduler allocation or pending-reason objects represent the same thing — currently have no shared way to do so. The structural equality comparators for the shared data structures `xce_alloc_t`, `xce_host_alloc_t`, `xce_job_alloc_t`, and `xce_job_preason_t` (all defined in libxce's `src/include/xce/types.h`) live as `static` functions inside the scheduler's simulation-verification module `src/scheduler/src/sim_verify.c`, written for `--sim-verify` replay checking. Three other scheduler test files already reuse two of these comparators (`sim_verify_job_alloc_eq`/`sim_verify_job_preason_eq`) — but only by white-box `#include "../src/sim_verify.c"` and calling the `static` functions directly, a fragile mechanism that drags the entire simulator translation unit into each consumer. Meanwhile the controller already consumes these same shared structs (`persist.c`, `resync.c`, `job.c`) with no equality API available at all. This should change so that the type-level equality comparators for these shared structures become public libxce API — `alloc_eq`/`host_alloc_eq`/`job_alloc_eq` in `xcealloc.{c,h}` (the module that already constructs and deep-copies them) and `job_preason_eq` in `preason.{c,h}` (the module that already owns pending-reason construction) — so any component or test can compare these shared objects by linking libxce, while the decision-level dispatcher (`sim_decision_eq`) and mismatch reporting (`sim_log_mismatch`) that are genuinely simulator-specific stay in `sim_verify.c`.
## Boundary Context
- **In scope**: extracting the four type-level comparators (`xce_alloc_t`, `xce_host_alloc_t`, `xce_job_alloc_t`, `xce_job_preason_t`) from the scheduler simulator into public libxce API; giving the allocation comparators a documented "identity" contract (excluding `from`/`instid`) and the pending-reason comparator a full structural-match contract (all fields, detail lists included); migrating every in-repo consumer of these comparators (the simulator plus the scheduler test files that currently reuse the static functions) to the public API; libxce unit tests for the new functions.
- **Out of scope**: the decision-level comparison dispatcher (`sim_decision_eq`) and mismatch reporting (`sim_log_mismatch` and its describe helpers), which depend on `replay_decision_t`, capnp enums, and `ERROR()` logging and remain in the scheduler; any change to the *semantics* of what is compared (the deliberate field exclusions are preserved, not re-litigated); any new comparison call site beyond the existing consumers; any change to the controller's persistence or resync behavior; any change to the `.replay` wire format.
- **Adjacent expectations**: the `.replay` wire format and the `replay_decision_t`/`xce_decision_t` decision types are unchanged; libxce's existing constructors and deep-copy helpers (`make_alloc`, `make_host_alloc`, `make_job_alloc`, `dup_job_alloc`, `make_pendreason`) and the `xce/types.h` struct layouts are unchanged; the controller's Cap'n Proto persistence round-trips for these structures are unchanged.
## Requirements
### Requirement 1: Shared equality API for allocation structures
**Objective:** As a scheduler or controller engineer who needs to compare two allocation objects, I want a public libxce equality function for each allocation structure, so that I can compare them correctly by linking libxce rather than reimplementing the comparison or white-box-including scheduler source.
#### Acceptance Criteria
1. The library shall provide a public equality function for `xce_alloc_t` that reports equal if and only if the two records have the same resource name, reserve, value, and duration.
2. The library shall provide a public equality function for `xce_host_alloc_t` that reports equal if and only if the two records have the same host name and, in order, the same per-resource `xce_alloc_t` records.
3. The library shall provide a public equality function for `xce_job_alloc_t` that reports equal if and only if the two records have the same job id, the same per-host `xce_host_alloc_t` records in order, and the same shared-resource `xce_alloc_t` records in order.
4. The allocation equality functions shall not consider a record's reservation start time (`from`) or allocation-instance id (`instid`) when determining equality, because these are runtime bookkeeping values, not part of an allocation's identity.
5. When the two arguments to an allocation equality function are the identical pointer (including two NULL pointers), the function shall report equal; when exactly one of the two arguments is NULL at the top level or at any nested level, the function shall report not-equal without crashing.
6. The allocation equality functions shall not modify either argument.
### Requirement 2: Shared equality API for the pending-reason structure
**Objective:** As a scheduler or controller engineer who needs to compare two pending-reason objects, I want a public libxce equality function that reports a full structural match, so that I can determine whether two pending reasons are identical by linking libxce rather than reimplementing the comparison.
#### Acceptance Criteria
1. The library shall provide a public equality function for `xce_job_preason_t` that reports equal if and only if the two records have the same main reason code, the same host-based reason entries in order, and the same resource-based reason entries in order.
2. The pending-reason equality function shall compare each host-based reason entry by its host name and reason code, and each resource-based reason entry by its resource name, host name, and reason code.
3. The pending-reason equality function shall handle NULL arguments the same way as the allocation equality functions (identical pointers including both NULL report equal; exactly one NULL at the top level or at any nested level reports not-equal) and shall not modify either argument.
### Requirement 3: Simulator verification behavior is preserved
**Objective:** As an operator relying on `--sim-verify` replay checking, I want the simulator's decision verification to behave exactly as it did before this change, so that no new false mismatch or missed mismatch is introduced.
#### Acceptance Criteria
1. The simulator shall continue to compare a recorded decision against a live decision using the same equality semantics as before this change.
2. The simulator shall continue to report a verification mismatch with the same logical-time and decision-detail context as before this change.
3. The simulator shall obtain its allocation comparison from the libxce public API rather than defining it itself.
4. The simulator shall keep its pending-decision comparison as a simulator-local main-reason-only check, because a recorded cache-hit pending reason carries no host/resource detail while a live replayed one always does — this documented asymmetry is unchanged by this feature and remains a simulator concern, not a property of the full-match libxce `job_preason_eq`.
5. Replaying a recording against its own previously-recorded output with verification enabled shall continue to report zero mismatches.
### Requirement 4: Single shared implementation across all consumers
**Objective:** As a maintainer, I want the allocation and pending-reason comparisons to exist exactly once, in libxce, so that future changes to their semantics are made in one place and every consumer picks them up.
#### Acceptance Criteria
1. Every in-repo consumer of these comparisons — the simulator and the scheduler test files that currently reuse the static comparators — shall obtain the allocation comparison and the full pending-reason comparison from the libxce public API; the simulator's main-reason-only pending-decision check is the single documented simulator-local exception.
2. A consumer that needs only the type-level comparisons shall be able to obtain them without white-box-including the simulator's verification source.
3. The library shall provide unit test coverage for each new equality function, covering a match, a mismatch on each compared field, and the NULL-handling cases.
4. Adding these functions shall not alter the behavior of any existing libxce function.