myxce/.kiro/specs/libxce-alloc-preason-equality/tasks.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

5.7 KiB
Raw Blame History

Implementation Plan

Task Format

Work is sequenced test-first where the deliverable is new library API (TDD: red → green → refactor), then the scheduler-side migration is a behavior-preserving refactor verified by the existing --sim-verify tests.


  • 1. Add a shared NULL-safe string helper to libxce (utils.c/utils.h)

    • Add int str_eq(const char* a, const char* b) beside the existing float_equal helper: returns non-zero iff both arguments are NULL, or both non-NULL and strcmp(a, b) == 0.
    • Document that it is the shared NULL-safe string-equality helper for the equality functions (and any future controller consumer).
    • Requirements: 1.1–1.6, 2.1–2.3 (supporting)
    • Boundary: utils.c, utils.h
  • 2. Add allocation equality API to libxce (xcealloc.c/xcealloc.h)

    • Implement alloc_eq(const xce_alloc_t*, const xce_alloc_t*) comparing value, duration, resname, reserve (excluding from/instid), with the shared NULL convention.
    • Implement host_alloc_eq(const xce_host_alloc_t*, const xce_host_alloc_t*) comparing host then allocs[i] in order.
    • Implement job_alloc_eq(const xce_job_alloc_t*, const xce_job_alloc_t*) comparing jobid, allocs[i] in order, then allocs_shared[i] in order.
    • Use str_eq from utils.h for the string fields.
    • Declare all three in src/include/xcealloc.h with a per-function doc comment capturing the equality contract (including the from/instid exclusion and NULL/order semantics).
    • Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6
    • Boundary: xcealloc.c, xcealloc.h
    • Depends: 1
  • 3. Add pending-reason equality API to libxce (preason.c/preason.h)

    • Implement job_preason_eq(const xce_job_preason_t*, const xce_job_preason_t*) as a full structural match: main_reason, then host_based_reasons[i] in order (each by host via str_eq + reason), then res_based_reasons[i] in order (each by resource + host via str_eq + reason), with the shared NULL convention.
    • Declare it in src/include/preason.h with a doc comment capturing the full-match contract (nothing excluded) and the NULL/order semantics.
    • Requirements: 2.1, 2.2, 2.3
    • Boundary: preason.c, preason.h
    • Depends: 1
  • 4. Add libxce unit tests for the new equality functions (TDD, before relying on them)

    • test_xcealloc.c: alloc_eq match/mismatch per field (value, duration, resname, reserve), from/instid exclusion, host_alloc_eq host-name and order sensitivity, job_alloc_eq jobid + ordered hosts + ordered shared, NULL at top and nested levels.
    • test_preason.c: job_preason_eq full match — main-reason match/mismatch, host-based list match/mismatch per field and order, resource-based list match/mismatch per field and order, NULL handling; plus str_eq NULL/NULL and NULL/non-NULL cases.
    • Confirm src/lib/testsuite builds and passes (/xce-build lib).
    • Requirements: 4.3, 4.4
    • Boundary: test_xcealloc.c, test_preason.c
    • Depends: 2, 3
  • 5. Migrate the simulator to the public API (sim_verify.c)

    • Delete the five static comparators (sim_verify_str_eq, sim_verify_alloc_eq, sim_verify_host_alloc_eq, sim_verify_job_alloc_eq, sim_verify_job_preason_eq).
    • Add a new static simulator-local sim_verify_pend_outcome_eq(const xce_job_preason_t*, const xce_job_preason_t*) (or an inline check) that compares main_reason only, documented with the bug-1845 rationale.
    • In sim_decision_eq, replace the DISPATCH payload comparison with job_alloc_eq(...) and the PEND payload comparison with jobid equality plus the local main-reason-only check.
    • Add #include "xcealloc.h" and #include "preason.h"; keep sim_log_mismatch and the describe_* helpers unchanged.
    • Requirements: 3.1, 3.2, 3.3, 3.4
    • Boundary: sim_verify.c
    • Depends: 2, 3
  • 6. Migrate the three white-box test consumers to the public API

    • test_sim_equivalence.c, test_repl_equivalence.c, test_repl_limit_table.c: replace direct calls to sim_verify_job_alloc_eq → job_alloc_eq and sim_verify_job_preason_eq → job_preason_eq; add the two headers.
    • Where a file no longer needs sim_decision_eq/sim_log_mismatch, drop its #include "../src/sim_verify.c"; otherwise keep it for the decision-level functions only.
    • Note: these fixtures produce zero-detail PEND reasons on both sides, so the switch from main-reason-only to full-match job_preason_eq is behavior-preserving for them; verify with the full scheduler suite.
    • Requirements: 4.1, 4.2
    • Boundary: test_sim_equivalence.c, test_repl_equivalence.c, test_repl_limit_table.c
    • Depends: 5
  • 7. Reconcile test_sim_verify.c with the relocated comparators

    • Remove the DISPATCH alloc-level unit tests that only re-prove the allocation comparators (identical-content match, per-field mismatch, from/instid exclusion) — these are now owned by libxce tests from task 4.
    • Keep the PEND unit tests (identical-content match, jobid/main-reason mismatch, detail-ignored) — these now pin sim_decision_eq's simulator-local main-reason-only behavior, not a libxce function.
    • Keep the sim_decision_eq-level tests (kind mismatch, PREEMPT always-false, NULL defense) and all integration-level --sim-verify round-trip tests, which now prove the relocation is behavior-preserving.
    • Requirements: 3.1, 3.4, 4.3
    • Boundary: test_sim_verify.c
    • Depends: 5
  • 8. Full build + test verification

    • /xce-build lib (debug + ASAN + tests) green.
    • /xce-build scheduler (debug + ASAN + tests) green, including test_sim_verify.c, test_sim_equivalence.c, test_repl_equivalence.c, test_repl_limit_table.c.
    • Requirements: 3.4, 4.4
    • Depends: 4, 5, 6, 7