myxce/.kiro/specs/admin-config-tool/tasks.md
Rongsong Shen 2e4ef4e209 feat(admin-config-tool): task 1.2 - shared exception taxonomy
XceAdminError base plus 8 subclasses (schema-not-found, validation,
reserved-name, duplicate-entry, connection-timeout, reply-decode,
too-many-redirects, no-primary) giving the future CLI layer one
dispatch surface instead of catching unrelated types per module.

Requirements: 7.1, 7.2, 7.3, 7.4
2026-07-22 03:06:40 +00:00

9.3 KiB

Implementation Plan

  • 1. Foundation: package scaffolding, shared errors, build/toolchain integration

  • 1.1 Set up the xceadmin Python package skeleton

    • Editable install registers a real xceadmin console-script entry point backed by an empty, working click group (no subcommands yet — config build/config push are added by task 4.1, not this task)
    • xcecommon is importable as a standalone package independent of xceadmin's CLI
    • Observable: running the entry point after an editable install prints usage/help text without error, showing zero commands
    • Requirements: 5.4
  • 1.2 Establish a shared error-handling foundation

    • One common base exception type carries a human-readable message
    • Every specific failure mode (schema not found, validation failure, reserved name, duplicate entry, connection timeout, corrupt reply, too many redirects, no primary available) has its own subclass
    • Observable: raising any of these subclasses and catching the common base type recovers the message
    • Requirements: 7.1, 7.2, 7.3, 7.4
  • 1.3 Wire xceadmin into the project's build and dev-shell tooling

    • Nix dev shell provides the Python interpreter and all dependencies needed to build and test xceadmin
    • Running the build command for xceadmin performs an editable install by default and a pinned non-editable install under the release profile, running the test suite after whichever install just happened
    • The build step keeps the packaged copies of the wire-protocol schema and the validation schemas in sync with their source locations elsewhere in the repo, and packages both correctly under either install mode
    • Build/test command documentation, permission allowlist entries, and automatic formatting/linting on Python file edits all exist for the new component
    • Observable: running the build command for this component from a clean checkout succeeds and reports test pass/fail
    • Requirements: 5.5, 8.1, 8.2, 8.6
  • 2. Core: xcecommon shared library

  • 2.1 (P) Validate operator-authored YAML against the bundled schemas

    • Each of the seven config file types can be checked against its own bundled validation schema, independent of anything the operator supplies
    • Reserved queue/host names are rejected even when otherwise schema-valid
    • Duplicate names within a single file/section are rejected
    • Cross-references to undefined groups or resources are flagged as warnings without blocking the build
    • Observable: validating a config directory with no schema files present anywhere in it still succeeds
    • Requirements: 4.1, 4.2, 4.3, 4.4, 4.5, 5.5
    • Boundary: xcecommon.validation
  • 2.2 (P) Load the cluster wire-protocol schema

    • The wire-protocol schema loads once per process and exposes every message type xceadmin needs to build or decode
    • Loading works identically whether xceadmin was installed in editable or pinned mode
    • A missing or corrupted schema copy produces a clear, actionable error rather than a crash
    • Observable: loading the schema under a pinned (non-editable) install still resolves the bundled copy correctly
    • Requirements: 5.1, 5.5, 7.4
    • Boundary: xcecommon.schema
  • 2.3 (P) Map validated YAML into cluster configuration fields

    • Every field the cluster configuration binary format defines is either populated from validated YAML or deliberately left untouched, with no field silently dropped
    • List-based sections preserve the exact order they appeared in the YAML
    • No timestamp, hostname, or username value ever enters the mapped output
    • Building the same input twice produces identical output
    • Requirements: 1.1, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12, 5.3, 9.1, 9.2, 9.3
    • Boundary: xcecommon.mapping
    • Depends: 2.2
  • 2.4 (P) Establish the TLS connection and wire framing to the controller

    • A single request can be sent and a single reply received over a TLS connection using the cluster's existing certificate trust model
    • Message framing matches the controller's own byte-for-byte, verified against known-good byte sequences
    • The connection always closes cleanly, including on error or interruption
    • Requirements: 2.1, 2.3, 2.4, 5.2, 6.1, 7.1, 7.3, 7.6
    • Boundary: xcecommon.wire
    • Depends: 2.2
  • 3. Core: xceadmin CLI orchestration

  • 3.1 (P) Compile a configs directory into a deployable cluster binary

    • Running the build command against a directory of YAML files produces a binary output file with a printed checksum
    • A missing individual YAML file is treated as an empty section, not an error
    • Unrecognized-but-valid YAML fields produce a warning, not a failure
    • Output can be directed to a specific path or to standard output
    • Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.9, 8.3, 8.4
    • Boundary: xceadmin.build
    • Depends: 2.1, 2.3
  • 3.2 (P) Follow controller redirects to find the primary

    • A reply pointing at a different host/port is followed automatically, up to a bounded number of hops
    • Exceeding the hop limit or waiting past the connection timeout produces a clear error naming the last host contacted
    • Observable: a chain of up to three redirects resolves to a final destination without operator intervention
    • Requirements: 3.1, 3.2, 3.3, 3.4
    • Boundary: xceadmin.discovery
    • Depends: 2.4
  • 3.3 Push a cluster binary to the controller, with a dry-run mode

    • A real push reports the assigned configuration version, acknowledgement count, and any error, exiting non-zero on failure
    • A dry-run reports whether the controller would accept the config without ever committing it
    • Every connection failure, protocol-level rejection, corrupt input, or missing schema maps to a specific, distinct error
    • Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 6.1, 6.2, 6.3, 7.1, 7.2, 7.3, 7.4, 7.5, 7.6
    • Boundary: xceadmin.push
    • Depends: 2.4, 3.2
  • 4. Integration: wire the CLI entry point and hook xceadmin into cluster deployment

  • 4.1 Expose config build and config push as a single command-line tool

    • xceadmin config build and xceadmin config push (with --dry-run) are both reachable from one installed command
    • Any failure surfaces as a specific, human-readable message with a non-zero exit code, not a raw traceback
    • Interrupting a push mid-flight leaves no dangling connection and reports a clean cancellation
    • Requirements: 1.2, 1.3, 2.2, 2.4, 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 8.1, 8.2
    • Boundary: xceadmin.cli
    • Depends: 3.1, 3.3
  • 4.2 Build cluster configuration automatically during HA deployment

    • Deploying a cluster with the build-config option produces a fresh binary from the current YAML before startup
    • Deploying with no binary present and no flag still produces one automatically
    • Deploying with an existing binary and no flag leaves it untouched, matching prior behavior
    • Requirements: 8.3, 8.4, 8.5
    • Boundary: deploy-ha.sh
    • Depends: 4.1
  • 5. Validation: test coverage across build, push, and packaging

  • 5.1 (P) Unit test the field-mapping logic in isolation

    • Both mapper shapes (list sections and the scalar section) are verified against in-memory input with no file I/O
    • The one file that feeds two separate output fields is verified explicitly
    • Requirements: 1.1, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12, 5.3, 9.1, 9.2, 9.3
    • Boundary: xcecommon.mapping
    • Depends: 2.3
  • 5.2 (P) Unit test wire framing

    • Framing round-trips correctly against a fixed, known byte sequence and against a local loopback connection
    • Requirements: 2.1
    • Boundary: xcecommon.wire
    • Depends: 2.4
  • 5.3 (P) Verify bundled schemas resolve under every install mode

    • Both the wire-protocol schema and the validation schemas resolve to real, parseable files under the currently active install
    • A deliberately corrupted or absent packaged schema produces the expected installation-hint error rather than a crash
    • Meaningful confirmation of the pinned install path requires running this under the release build profile
    • Requirements: 5.5, 7.4
    • Boundary: xcecommon.schema, xcecommon.validation
    • Depends: 2.1, 2.2, 1.3
  • 5.4 (P) Golden-file test config build determinism

    • Building from a minimal fixture, a full fixture covering all seven file types, and a set of intentionally invalid fixtures each produce the expected result
    • Building the same fixture twice produces byte-identical output and an identical checksum
    • Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12, 9.1, 9.2, 9.3
    • Boundary: xceadmin.build
    • Depends: 3.1
  • 5.5 (P) Test every YAML validation failure mode

    • Each invalid-fixture case (schema violation, reserved name, duplicate name including a cross-type collision, undefined reference) produces the documented outcome — hard failure or warning, matching the requirement
    • Requirements: 4.1, 4.2, 4.3, 4.4, 4.5
    • Boundary: xcecommon.validation
    • Depends: 2.1
  • 5.6 (P) Test config push and dry-run against a mock controller

    • A mock TLS server standing in for the controller confirms the full push flow: successful push, redirect-following, and every documented error path
    • The same mock confirms dry-run reports both an accepted and a rejected outcome correctly
    • Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.1, 3.2, 3.3, 3.4, 6.1, 6.2, 6.3, 7.1, 7.2, 7.3
    • Boundary: xceadmin.push, xceadmin.discovery
    • Depends: 3.3