test(xce-harness-component): verify build isolation; narrow requirement 2.2
Validation task 4.3 found a real, deterministic conflict with the original requirement 2.2 wording, not a flake: /xce-build controller alone's default asan profile transitively rebuilds harness/xce_test, because Meson's test-runner rebuilds every registered test's build- order dependencies project-wide before filtering by --suite, and harness_unit_test (task 2.1) depends on it. Confirmed via build-log step-count analysis (explicit compile: 209 steps, clean; subsequent meson test: 844 steps, resurrects it) and independently reproduced twice, with an exact step-count match both times. User decision (2026-09-14): accept as a documented Meson limitation rather than auditing every component's test-target list (controller's own suite already relies on this same mechanism for 4 of its own test binaries) or weakening harness_unit_test's build-order guarantee (verified load-bearing in task 4.2). Requirement 2.2 narrowed to what the build system directly controls: its explicit compile-target list never names xce_test. requirements.md/design.md/tasks.md updated to match and cross-reference each other; logged as bug-1806 (accepted, not fixed) for the record. Also commits the xce-harness-component spec's remaining docs (requirements.md, brief.md, research.md, spec.json) and the roadmap.md promotion entry from discovery, none of which had been committed yet. Task 4.3 of xce-harness-component. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
This commit is contained in:
parent
7958b395ae
commit
b3aa2af242
7 changed files with 258 additions and 5 deletions
62
.kiro/specs/xce-harness-component/brief.md
Normal file
62
.kiro/specs/xce-harness-component/brief.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# Brief: xce-harness-component
|
||||
|
||||
## Problem
|
||||
|
||||
`xce_test` — the REPL-driven wire-protocol test client used to drive/verify controller, scheduler, and worker (HA soak, resource-value verification, multi-host allocation proof, WAL/snapshot inspection) — is physically and organizationally welded to the controller component, even though it has no real dependency on it. Its 15 source files live in `src/controller/testsuite/` and its build target is defined inside `src/controller/meson.build`, so it is invisible as a first-class thing in the project's own component vocabulary (`CLAUDE.md`'s `/xce-build` component list: `all, lib, controller, scheduler, worker, apiserver, xcecli, xceadmin` has no entry for it) despite being load-bearing infrastructure for at least four other skills (`/xce-test-ha`, `/xce-deploy-ha`, `/xce-test-multihost`, `/xce-test-resources`).
|
||||
|
||||
## Current State
|
||||
|
||||
- **Binary**: `xce_test`, defined at `src/controller/meson.build:58-85` (`xce_test_src`, `xce_test_deps`, `xce_test = executable(...)`).
|
||||
- **Sources** (15 files, all in `src/controller/testsuite/`): `test.c` (REPL/dispatch entry), `waldump.c`, `walcompare.c`, `snapverify.c`, `snapdiff.c`, `configcompare.c`, `resval_typeresolve.c`, `joblist_display.c`, `join_worker_args.c`, `rcfile.c`, `flagspec.c`, `interruptcall.c`, `confirm.c`, `listfmt_json.c`, `listrow_json.c` — plus their matching `.h` headers.
|
||||
- **Verified finding (de-risks the move)**: none of these 15 files `#include` any controller-private header (`ha.h`, `repl.h`, `config_repl.h`, `myconf.h`, etc.). They depend only on libxce public headers (`src/include/*.h`, e.g. `client.h`, `config.h`, `delay.h`, `idgen.h`, `persist.h`, `preason.h`, `utils.h`, `wal_types.h`, `xce/cluster.h`, `xce/types.h`), the generated `controller.capnp.h` schema header, and xce_test's own component-local headers. `xce_test_deps` is `libxce_dep, librtti_dep, struct2json_dep, libedit_dep, tinylog_dep, zlib_dep, c_capnproto_dep, ssl_dep, thread_dep` — no `controller_deps`-only dependency. It is a pure network client, not a controller-internals harness.
|
||||
- **Hidden coupling to untangle**: `src/controller/meson.build`'s `controller_unit_test_src` (lines ~160-466) currently recompiles ~14 of these same 15 production files a second time, paired with their own white-box unit tests, directly into the controller's own `controller_unit_test` binary: `test_waldump.c`+`waldump.c`, `test_walcompare.c`+`walcompare.c`, `test_snapverify.c`+`snapverify.c`, `test_snapdiff.c`+`snapdiff.c`, `test_configcompare.c`+`configcompare.c`, `test_rcfile.c`+`rcfile.c`, `test_flagspec.c`+`flagspec.c`, `test_interruptcall.c`+`interruptcall.c` (+`test_xcetest_interrupt.c`), `test_confirm.c`+`confirm.c`, `test_listfmt_json.c`+`listfmt_json.c`, `test_resval_typeresolve.c`+`resval_typeresolve.c`, `test_joblist_display.c`+`joblist_display.c`, `test_join_worker_args.c`+`join_worker_args.c`, `test_listrow_json.c`+`listrow_json.c` — plus `test_xcetest_process_entry.c` and `test_test_cli.c`, which white-box-test `test.c`'s own REPL dispatch. This pairing is the real reason a naive "just move the 15 files" plan breaks: those ~16 test files have no production code left to compile against once their counterpart moves.
|
||||
- Not part of any nix/AppImage production package (`src/flake.nix` and `src/meson.build` have zero references to `xce_test`/`testsuite`) — it is dev/test-only tooling, so there is no release-artifact impact.
|
||||
- Existing behavior specs (`xce-test-cli-ux` — tasks generated, ready for implementation; `xce-test-e2e-primitives` — implemented; `xce-test-rc-file` — implementation-complete) all govern xce_test's *behavior* (CLI UX, REPL primitives, rc-file config) and reference these same files by their current `src/controller/testsuite/` paths. None of them address where the code lives or how it's built.
|
||||
|
||||
## Desired Outcome
|
||||
|
||||
`xce_test` (built at) becomes a genuine standalone component under `src/harness/`, following the project's existing C Daemon Layout Pattern (own `meson.build`, `CLAUDE.md`, `include/`, `testsuite/`) exactly like `worker/` and `scheduler/`. It has its own explicit `/xce-build harness` entry, its own unit-test binary covering the ~16 white-box tests currently trapped inside `controller_unit_test`, and building `controller` no longer implicitly produces it. Every consumer that currently assumes "build controller → xce_test exists" is updated to build it explicitly.
|
||||
|
||||
## Approach
|
||||
|
||||
Pure structural relocation + build-graph split — no behavioral/logic changes to xce_test itself:
|
||||
|
||||
1. **Move** the 15 production files + their headers from `src/controller/testsuite/` into `src/harness/` (layout to be finalized in design — e.g. flat under `src/harness/` mirroring controller's own flat-root exception, or `src/harness/src/` + `src/harness/include/` per the standard pattern; `test.c` stays the REPL entry point).
|
||||
2. **Split the unit-test binary**: carve the ~16 paired white-box test files out of `controller_unit_test_src` into a new `harness_unit_test` binary defined in `src/harness/meson.build`, registered as its own `meson test()` (new suite, e.g. `harness`, parallel to the existing `suite: 'controller'`). `controller_unit_test` keeps every other file untouched — this is confirmed to be `test_*.c` domain tests for `ha`/`persist`/`commit`/`repl`/`job`/etc., which are genuinely controller-internal and stay exactly where they are.
|
||||
3. **Rewire the build**: new `src/harness/meson.build`, `subdir('harness')` added to `src/meson.build`, remove `xce_test_src`/`xce_test_deps`/`xce_test` executable and the moved entries out of `controller_unit_test_src` in `src/controller/meson.build`.
|
||||
4. **Fully decouple** (per user decision): `/xce-build controller` no longer transitively builds the harness. Add `harness` as a new first-class `/xce-build` component (`.claude/skills/xce-build/`), update its component list and the `Key Files`/`Components` line in root `CLAUDE.md`.
|
||||
5. **Fix every consumer** that currently assumes xce_test exists right after building controller: `/xce-test-ha`, `/xce-deploy-ha`, `/xce-test-multihost` (`.claude/skills/xce-test-multihost/run-multihost-verify.sh`), `/xce-test-resources` — each needs an explicit `/xce-build harness` step added (or a documented prerequisite) wherever it currently piggybacks on `/xce-build controller`.
|
||||
6. **Update steering**: `build-deployment.md` (line 24's "`controller` always builds `xce_test`..." claim, the Meson Structure tree, the `/xce-build` command table), `structure.md` (component table + C Daemon Layout Pattern exceptions list), and a new `src/harness/CLAUDE.md`.
|
||||
|
||||
## Scope
|
||||
|
||||
- **In**: relocating xce_test's 15 source files + headers into `src/harness/`; splitting the paired ~16 white-box tests into a new `harness_unit_test` binary; new `src/harness/meson.build` + `src/harness/CLAUDE.md`; adding `harness` to `/xce-build`; decoupling it from `/xce-build controller`; updating every downstream skill/script and steering doc that assumes the old coupling.
|
||||
- **Out**: any behavioral change to xce_test itself (owned by `xce-test-cli-ux`/`xce-test-e2e-primitives`/`xce-test-rc-file` and future xce_test feature work — e.g. the still-open `xce_test WAL/snapshot inspection tooling` roadmap item); packaging xce_test into the nix/AppImage production artifacts (it is dev/test tooling today and stays that way); reorganizing `controller`'s own domain unit tests (ha/persist/commit/repl/job/etc. — confirmed to stay in `src/controller/testsuite/`).
|
||||
|
||||
## Boundary Candidates
|
||||
|
||||
- The production-binary move (files + meson target) is independent of the unit-test-binary split, but both must land together — an intermediate state where `xce_test.c`'s sources live in `src/harness/` while their unit tests still reference the old `src/controller/testsuite/` paths would not build.
|
||||
- The build/skill decoupling (item 4-5 above) is separable follow-up work from the pure file move (items 1-3) and could in principle be its own task group within the same spec, but is NOT a separate spec — it's required for the "standalone component" outcome to actually hold (a component whose build is still silently triggered by another component's build isn't standalone).
|
||||
|
||||
## Out of Boundary
|
||||
|
||||
- Renaming the `xce_test` binary itself (stays `xce_test`; only the *directory*/component is named `harness`).
|
||||
- Any new xce_test functionality (commands, REPL features, output formats).
|
||||
- Touching `xceadmin`, `xcecli`, or any Go frontend build wiring.
|
||||
- Re-litigating which controller unit tests belong where beyond the ~16 files whose production counterpart is physically moving.
|
||||
|
||||
## Upstream / Downstream
|
||||
|
||||
- **Upstream**: none — this is a pure internal restructuring with no external dependency.
|
||||
- **Downstream**: `/xce-test-ha`, `/xce-deploy-ha`, `/xce-test-multihost`, `/xce-test-resources` skills (must be updated to build `harness` explicitly); the three existing `xce-test-*` behavior specs (their task/design docs reference file paths under `src/controller/testsuite/` that will need a path-only update, not a re-review of their approved requirements/design); the still-open roadmap backlog item "xce_test WAL/snapshot inspection tooling" (new `snapdump`/`walcompare` work should target the post-move `src/harness/` location).
|
||||
|
||||
## Existing Spec Touchpoints
|
||||
|
||||
- **Extends**: none directly — this is a new boundary, not an extension of an approved spec.
|
||||
- **Adjacent**: `xce-test-cli-ux`, `xce-test-e2e-primitives`, `xce-test-rc-file` — same binary, disjoint concern (behavior vs. location/build). File-path references in their design/tasks docs will go stale after this spec lands; worth a quick path-only sync pass once implemented, not a re-open of their approved content.
|
||||
|
||||
## Constraints
|
||||
|
||||
- No behavioral regression in xce_test — every existing command/REPL feature must work identically post-move (verify via the existing `xce-test-e2e-primitives`/`xce-test-cli-ux` test coverage rerun against the new binary location).
|
||||
- Meson/build hygiene: must respect the project's existing `--incremental` vs. full-wipe build-dir semantics (`build-deployment.md` bug-1565 note) — a two-component build (`controller` + `harness`) in the same dir needs either `/xce-build all` or `--incremental`, same as any other two-component combo today.
|
||||
- User decisions locked in for this spec (2026-09-13, `/kiro-discovery`): component directory name is `src/harness/` (binary name unchanged, `xce_test`); build coupling is **fully decoupled** (not transitional-compatible) — downstream skills must be fixed as part of this spec, not left broken.
|
||||
|
|
@ -271,7 +271,7 @@ sequenceDiagram
|
|||
|
||||
| Field | Detail |
|
||||
|-------|--------|
|
||||
| Intent | Independent `harness` build entry point; `controller` no longer produces xce_test as a side effect |
|
||||
| Intent | Independent `harness` build entry point; `controller`'s explicit compile step no longer names xce_test (see Implementation Notes for a documented Meson test-runner exception) |
|
||||
| Requirements | 2.1, 2.2, 2.3, 2.4 |
|
||||
|
||||
**Responsibilities & Constraints**
|
||||
|
|
@ -293,8 +293,9 @@ sequenceDiagram
|
|||
|
||||
**Implementation Notes**
|
||||
- Integration: no new orchestration concept — this is the same case-block template every other component already uses.
|
||||
- Validation: run `/xce-build harness` alone (no prior controller build) and confirm `xce_test` is produced; run `/xce-build controller` alone and confirm `xce_test` is absent; run `/xce-build all` and confirm both exist.
|
||||
- Validation: run `/xce-build harness` alone (no prior controller build) and confirm `xce_test` is produced; run `/xce-build controller` alone and confirm its explicit compile step never targets `xce_test`; run `/xce-build all` and confirm both exist.
|
||||
- Risks: none beyond the pre-existing, already-documented full-wipe behavior.
|
||||
- **Known limitation, discovered and accepted in task 4.3**: under the default `asan` profile (which runs tests), `/xce-build controller`'s `meson test --suite controller` step transitively rebuilds `harness/xce_test` on disk, because Meson's test-runner rebuilds every registered test's build-order dependencies project-wide before filtering which tests actually run by `--suite` — and `harness_unit_test` (Requirement 3.2) depends on `xce_test`. Verified deterministic via build-log line analysis (the explicit `meson compile` step is clean; only the subsequent `meson test` step touches it), not a flake. Requirement 2.2 was narrowed to scope this component's guarantee to what it directly controls — its own explicit compile-target list — rather than the full transitive behavior of Meson's test infrastructure. See requirements.md's Boundary Context → "Known limitation" for the full rationale and rejected alternatives (completing every component's explicit test-target list; weakening `harness_unit_test`'s build-order dependency, which task 4.2 verified is load-bearing).
|
||||
|
||||
#### Downstream Verification Skills
|
||||
|
||||
|
|
|
|||
70
.kiro/specs/xce-harness-component/requirements.md
Normal file
70
.kiro/specs/xce-harness-component/requirements.md
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
# Requirements Document
|
||||
|
||||
## Project Description (Input)
|
||||
XCE engineers who build, deploy, and use `xce_test` — the REPL-driven wire-protocol test client that drives HA soak testing, multi-host allocation proof, resource-value verification, and WAL/snapshot inspection against controller/scheduler/worker — currently have no way to build, reference, or reason about it as a first-class component. Today `xce_test`'s 15 source files live inside `src/controller/testsuite/`, its build target is defined inside `src/controller/meson.build`, and building `controller` implicitly produces it — despite `xce_test` having zero dependency on controller-private headers (verified: it only includes libxce public headers and the generated capnp schema). `controller_unit_test` also currently recompiles ~14 of xce_test's own source files a second time, paired with their white-box unit tests, further entangling it with the controller build.
|
||||
|
||||
This should change so that `xce_test` is promoted to a standalone `src/harness/` component, following the project's existing C Daemon Layout Pattern (own `meson.build`, `CLAUDE.md`, `include/`, `testsuite/`) exactly like `worker/` and `scheduler/`. It gets its own unit-test binary (carved out of the ~16 white-box tests currently trapped inside `controller_unit_test`) and its own explicit `/xce-build harness` entry, fully decoupled from `/xce-build controller` — building `controller` will no longer implicitly build it. Every downstream consumer that assumes the old coupling (`/xce-test-ha`, `/xce-deploy-ha`, `/xce-test-multihost`, `/xce-test-resources` skills) must be updated to build `harness` explicitly, and steering docs (`build-deployment.md`, `structure.md`, root `CLAUDE.md`) must reflect the new component. The binary itself keeps its current name, `xce_test` (per user decision — only the component/directory is renamed to `harness`); no `xce_test` behavior changes as part of this work. Full context, verified findings, and locked-in scope decisions: `.kiro/specs/xce-harness-component/brief.md`.
|
||||
|
||||
## Introduction
|
||||
|
||||
`xce_test` is currently housed inside the controller component (`src/controller/testsuite/`, built from `src/controller/meson.build`) even though it has no structural dependency on controller internals — it is a network client that drives controller, scheduler, and worker over the wire. This entanglement means building the controller silently produces `xce_test` as a side effect, `xce_test` has no independent build entry point, and several of its own source files are re-compiled a second time inside the controller's unit-test binary alongside their white-box tests. This spec promotes `xce_test` to a standalone `src/harness/` component with its own build target, unit-test suite, and documentation, fully decoupled from the controller build, while preserving `xce_test`'s exact current behavior and binary name and updating every downstream workflow that depends on the old coupling.
|
||||
|
||||
## Boundary Context (Optional)
|
||||
- **In scope**: relocating xce_test's source files into a standalone `src/harness/` component with its own build target, unit-test suite, and component documentation; making the harness independently buildable and no longer an implicit side effect of building the controller; updating every skill/workflow that currently assumes building the controller also produces the harness; updating steering documentation to describe the new component.
|
||||
- **Out of scope**: any new xce_test capability, REPL command, or output-format change (owned by `xce-test-cli-ux`, `xce-test-e2e-primitives`, `xce-test-rc-file`, and future roadmap items such as the pending WAL/snapshot inspector work); renaming the `xce_test` binary; any change to `xcecli`, `xceadmin`, or the Go frontend build; reorganizing the controller's own domain unit tests (HA, persistence, commit, replication, job, etc.); adding `xce_test` to any nix/AppImage production package (it is not part of one today and stays that way).
|
||||
- **Adjacent expectations**: the three existing xce-test-* specs continue to govern xce_test's behavior and are not reopened by this spec; their file-path references become stale after this move and should be refreshed as a follow-up, not as part of this spec's own acceptance criteria.
|
||||
- **Known limitation (accepted, verified during task 4.3)**: when a controller-only build's profile also runs the project's full registered test suite (the default `asan` profile), Meson's own test-runner rebuilds every registered test's build-order dependencies before filtering which tests actually run by `--suite` — including `xce_test`, via `harness_unit_test`'s own dependency on it (Requirement 3.2). This means `xce_test` can still end up rebuilt on disk as a transitive side effect of a controller-only build's test-running step, even though the build's own explicit compile step never names it (Requirement 2.2, as narrowed). This is a documented Meson platform behavior, not a defect in this spec's implementation — verified deterministic and traced to a specific build-log mechanism, not a flake. Fixing it further would require either auditing and completing every component's explicit compile-target list to cover its full test suite (non-trivial: several components, including controller itself, already rely on this same auto-rebuild for test binaries not in their own explicit target list) or weakening `harness_unit_test`'s build-order guarantee that Requirement 3.2 depends on (itself verified load-bearing in task 4.2) — both rejected as disproportionate to this spec's scope. Requirement 2.2 is scoped to what the build system directly controls (its own explicit compile step).
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement 1: Standalone Component Structure
|
||||
**Objective:** As an XCE engineer, I want xce_test organized as its own top-level component, so that I can build, navigate, and reason about it independently of the controller.
|
||||
|
||||
#### Acceptance Criteria
|
||||
1. The harness component shall exist as its own top-level directory, independent of the controller component's directory.
|
||||
2. The harness component shall provide its own build definition, its own component documentation, and its own test directory, matching the structure that other standalone components (worker, scheduler) provide.
|
||||
3. The harness component shall retain the `xce_test` binary name unchanged.
|
||||
4. The harness component shall have no dependency on any controller-private source file or header.
|
||||
|
||||
### Requirement 2: Independent, Decoupled Build
|
||||
**Objective:** As an XCE engineer, I want to build the harness independently of the controller, so that building one does not implicitly build or silently omit the other.
|
||||
|
||||
#### Acceptance Criteria
|
||||
1. When an engineer requests a harness-only build, the XCE build system shall produce the `xce_test` binary without requiring a controller build.
|
||||
2. When an engineer requests a controller-only build, the XCE build system's explicit compile step shall not name `xce_test` as a target.
|
||||
3. The XCE build system shall expose the harness as its own selectable build component, listed alongside the project's existing components (lib, controller, scheduler, worker, apiserver, xcecli, xceadmin).
|
||||
4. When an engineer requests a build of all components, the XCE build system shall include the harness component's binary in the result.
|
||||
|
||||
### Requirement 3: Unit Test Coverage Continuity
|
||||
**Objective:** As an XCE engineer relying on automated tests, I want the harness's existing white-box unit tests to keep running after the move, so that no test coverage is silently lost or misattributed.
|
||||
|
||||
#### Acceptance Criteria
|
||||
1. When the harness component is built and tested, the XCE build system shall run every unit test that validates one of xce_test's own source files, with the same pass/fail semantics those tests had before the move.
|
||||
2. If a unit test validates one of xce_test's own source files, then that test shall run and report as part of the harness component's own test suite, not the controller's, after the move.
|
||||
3. The controller's unit test suite shall continue to run every test that does not validate an xce_test source file, unaffected by this change.
|
||||
4. The harness component's test results shall be reported under a test suite name distinct from the controller's, so pass/fail outcomes are attributable to the harness specifically.
|
||||
|
||||
### Requirement 4: Behavioral Parity
|
||||
**Objective:** As an engineer or operator using xce_test day to day, I want its behavior to be completely unchanged by this restructuring, so that existing scripts, muscle memory, and documentation referencing xce_test keep working.
|
||||
|
||||
#### Acceptance Criteria
|
||||
1. The harness component shall preserve every xce_test REPL command, command-line flag, and output format exactly as it behaved before the move.
|
||||
2. When xce_test is invoked with any command-line flag or REPL command that existed before the move, the harness component shall produce output identical to its pre-move behavior.
|
||||
3. The harness component shall not introduce any new xce_test command, flag, or output change as part of this restructuring.
|
||||
|
||||
### Requirement 5: Downstream Workflow Compatibility
|
||||
**Objective:** As an XCE engineer running HA soak tests, multi-host verification, resource verification, or a local cluster deployment, I want my existing workflows to keep working after xce_test is decoupled from the controller build, so this restructuring does not silently break the tooling I rely on.
|
||||
|
||||
#### Acceptance Criteria
|
||||
1. When an engineer runs the HA soak test workflow, that workflow shall ensure the harness is built before it is needed, without relying on a controller build having produced it.
|
||||
2. When an engineer runs the local HA cluster deployment workflow, that workflow shall ensure the harness is built or shall clearly report that it is missing, rather than silently assuming it exists because the controller was built.
|
||||
3. When an engineer runs the multi-host verification workflow or the resource-value verification workflow, that workflow shall ensure the harness is built before it is used.
|
||||
4. If a downstream workflow requires the harness binary and it has not been built, then that workflow shall report a clear, actionable message rather than failing with an unrelated error or silently skipping the step that depends on it.
|
||||
|
||||
### Requirement 6: Documentation and Steering Consistency
|
||||
**Objective:** As an XCE engineer reading project documentation, I want the steering docs and component guides to accurately describe the harness as a standalone component, so that I don't rely on stale information about where xce_test lives or how it's built.
|
||||
|
||||
#### Acceptance Criteria
|
||||
1. The harness component shall have its own component guide describing its purpose, build command, and structure, consistent with the guides other standalone components have.
|
||||
2. The project's build and deployment documentation shall describe the harness as an independently buildable component and shall no longer state that building the controller also builds xce_test.
|
||||
3. The project's structure documentation shall list the harness component alongside the project's other component directories.
|
||||
96
.kiro/specs/xce-harness-component/research.md
Normal file
96
.kiro/specs/xce-harness-component/research.md
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# Research & Design Decisions
|
||||
|
||||
## Summary
|
||||
- **Feature**: `xce-harness-component`
|
||||
- **Discovery Scope**: Extension (existing system) — Light Discovery
|
||||
- **Key Findings**:
|
||||
- 14 of xce_test's 15 source files have zero dependency on controller-private headers or sources; only `ctrlstatus_fmt.h` is genuinely shared with controller, and it is header-only (`static inline`), so it can be promoted to a neutral shared location instead of creating a cross-component dependency in either direction.
|
||||
- **Corrected during `/kiro-validate-design` review**: only 13 of the 17 xce_test-related test files actually live inside the single `controller_unit_test` binary (`test_waldump.c` through `test_test_cli.c`). The other 4 — `test_resval_typeresolve.c`, `test_joblist_display.c`, `test_join_worker_args.c`, `test_listrow_json.c` — are **already separate standalone executables** in `src/controller/meson.build` (`resval_typeresolve_unit_test`, `joblist_display_unit_test`, `join_worker_args_unit_test`, `listrow_json_unit_test`), each split out specifically because they have "zero dependency on controller.c/cluster.c internals" — the same property verified for all 15 xce_test production files. User decision: preserve all 5 as 5 separate binaries after the move (no consolidation) — see Design Decisions.
|
||||
- Two of the 13 files in the main group (`test_test_cli.c`, `test_xcetest_process_entry.c`) are process-spawning integration tests: they locate and `exec` the actual built `xce_test` binary over a pty (`clitest_spawn`/`resolve_xce_test_path`), not white-box linkage. The new `harness_unit_test` binary (the one genuinely new binary — the other 4 relocate verbatim) therefore has a genuine build-order dependency on the `xce_test` executable target — a pattern `controller_unit_test` never needed (it never had to build another executable as its own prerequisite).
|
||||
- `controller_test.c` (`src/controller/testsuite/controller_test.c`) is the master Unity runner for the 13-file group — confirmed by reading it directly: it declares one `extern`/`RUN_TEST` pair per test function (lines 68-80 for the 13 moving functions; `test_ctrlstatus` at line 64 stays, since it tests controller's own `ctrlstatus.c`). This file must be edited, not just the meson source lists — an item the original design pass missed entirely.
|
||||
- The exact site to decouple the build is concrete and single-line: `src/tools/xce-build.sh:295`'s `controller)` case compiles `xce_controller controller_unit_test controller/xce_test` — `controller/xce_test` is the one target to drop, and a new `harness)` case follows the identical pattern already used by `scheduler)`/`worker)`.
|
||||
- Four downstream skills assume xce_test exists once controller is built: `xce-test-ha` (`run-ha-soak.sh`), `xce-deploy-ha` (`SKILL.md`, soft-skip pattern), `xce-test-multihost` (`run-multihost-verify.sh`), `xce-test-resources` (`run-resource-verify.sh`) — each needs an explicit harness-build step or prerequisite check.
|
||||
|
||||
## Research Log
|
||||
|
||||
### Controller-dependency audit of xce_test's 15 source files
|
||||
- **Context**: Requirement 1.4 requires the harness to have no dependency on controller-private sources/headers; this must be verified, not assumed.
|
||||
- **Sources Consulted**: `grep -h '^#include "'` across all 15 `xce_test_src` files (`test.c`, `waldump.c`, `walcompare.c`, `snapverify.c`, `snapdiff.c`, `configcompare.c`, `resval_typeresolve.c`, `joblist_display.c`, `join_worker_args.c`, `rcfile.c`, `flagspec.c`, `interruptcall.c`, `confirm.c`, `listfmt_json.c`, `listrow_json.c`).
|
||||
- **Findings**: Every include resolves to either a libxce public header (`src/include/*.h`: `client.h`, `config.h`, `delay.h`, `idgen.h`, `persist.h`, `preason.h`, `utils.h`, `wal_types.h`, `xce/cluster.h`, `xce/types.h`), the generated `controller.capnp.h` schema header, xce_test's own component-local headers (14 of the 15, one-to-one with the `.c` files, plus `xcetest_interrupt.h`), or the one shared exception below (`ctrlstatus_fmt.h`).
|
||||
- **Implications**: The move is a pure relocation for 14/15 files — no header untangling needed. Only `ctrlstatus_fmt.h` requires an explicit decision (see Decision below).
|
||||
|
||||
### `ctrlstatus_fmt.h` shared-header investigation
|
||||
- **Context**: `#include "ctrlstatus_fmt.h"` appeared in both an xce_test file (`joblist_display.c`) and a controller test file — needed to confirm whether this is a real controller-private dependency (which would violate Requirement 1.4) or something safely shareable.
|
||||
- **Sources Consulted**: `grep -rl "ctrlstatus_fmt.h"` across `src/controller/*.c` and `src/controller/testsuite/*.c`; read the function definition.
|
||||
- **Findings**: `ctrlstatus_fmt.h` declares exactly one function, `ctrlstatus_format_time_ms()`, as `static inline` (`ctrlstatus_fmt.h:33`) — header-only, no `.c` implementation, no link-time dependency. Four consumers: `test_ctrlstatus.c` (controller's own white-box test — stays with controller), and `joblist_display.c` / `test.c` / `test_joblist_display.c` (all three move to harness). No production controller `.c` file includes it.
|
||||
- **Implications**: Because it is header-only, it can move to a neutral shared location without creating a link dependency in either direction. See Decision below.
|
||||
|
||||
### `test_test_cli.c` / `test_xcetest_process_entry.c` linkage mechanism
|
||||
- **Context**: These two files are part of `controller_unit_test_src` but have no matching production `.c` counterpart (unlike the other 14 pairs) — needed to understand how they test xce_test if `test.c` itself isn't recompiled into `controller_unit_test`.
|
||||
- **Sources Consulted**: Read `test_test_cli.c` (`clitest_spawn`/`clitest_spawn_ex`/`resolve_xce_test_path`) and grep for `resolve_xce_test_path` across the testsuite.
|
||||
- **Findings**: `test_test_cli.c` defines `resolve_xce_test_path()` and `clitest_spawn()`/`clitest_spawn_ex()` itself — these locate the already-built `xce_test` binary on disk and `fork`/`exec` it under a pty, then drive it as a real subprocess (matching bug-1792's fix in `.wolf/buglog.json`, which touched this exact spawn path). `test_xcetest_process_entry.c` reuses `resolve_xce_test_path` via an `extern` declaration into the same `controller_unit_test` binary (both are linked into one executable today, so `extern` resolves within that one binary).
|
||||
- **Implications**: These are integration tests wearing a unit-test binary's clothes. The new harness unit-test binary must build (or otherwise guarantee the existence of) the `xce_test` executable *before* running these two tests — a real build-order dependency to declare explicitly in `src/harness/meson.build`, not an incidental one.
|
||||
|
||||
### Downstream consumer inventory
|
||||
- **Context**: Requirement 5 requires every workflow that assumes "building controller also builds xce_test" to keep working once that coupling is removed.
|
||||
- **Sources Consulted**: `grep -rl "xce_test\|xce-build controller"` across the four named skills' directories.
|
||||
- **Findings**: `xce-test-ha/run-ha-soak.sh` + `SKILL.md`, `xce-deploy-ha/SKILL.md` (no script of its own — `/xce-deploy-ha` deploys already-built binaries and soft-skips missing ones per `build-deployment.md`), `xce-test-multihost/run-multihost-verify.sh` + `SKILL.md`, `xce-test-resources/run-resource-verify.sh` + `SKILL.md`.
|
||||
- **Implications**: Three shell scripts plus four `SKILL.md` docs are the concrete edit surface for Requirement 5; `xce-deploy-ha` needs only its soft-skip documentation/message updated (mirroring its existing worker/scheduler/xceadmin soft-skip pattern), not a new build step of its own.
|
||||
|
||||
### `xce-build.sh` decoupling site
|
||||
- **Context**: Needed the exact, current mechanism coupling `controller` and `xce_test` builds to plan the decoupling precisely rather than guessing at meson internals.
|
||||
- **Sources Consulted**: Read `src/tools/xce-build.sh:282-340` (the `case "$COMPONENT" in ... esac` dispatch).
|
||||
- **Findings**: `controller)` (lines 292-299) runs `meson compile ... xce_controller controller_unit_test controller/xce_test` then `meson test --suite controller`. Sibling cases (`scheduler)`, `worker)`) follow an identical three-part pattern: `setup_build`, an explicit `meson compile` target list, then a conditional `meson test --suite <name>`. `all)` (not shown here, documented in `build-deployment.md`) compiles with no explicit target list, so it will automatically pick up a new `harness` target once `src/meson.build` gains `subdir('harness')` — no `all)` case change needed.
|
||||
- **Implications**: The fix is mechanical and low-risk: drop `controller/xce_test` from line 295, and add a new `harness)` case built from the same three-part template already proven by `scheduler)`/`worker)`.
|
||||
|
||||
## Architecture Pattern Evaluation
|
||||
|
||||
| Option | Description | Strengths | Risks / Limitations | Notes |
|
||||
|--------|-------------|-----------|---------------------|-------|
|
||||
| Nested `src/` per structure.md's general pattern (`src/harness/src/*.c`, `src/harness/include/*.h`) | Follow the worker/scheduler layout exactly | Consistent with the *documented* general pattern | xce_test's files were already flat siblings in `testsuite/`; adding a nesting layer is pure churn with no benefit for a single-purpose CLI tool | Rejected — no multi-domain internal structure to justify the extra nesting |
|
||||
| Flat root, controller-exception style (`src/harness/*.c`, `src/harness/include/*.h`, `src/harness/testsuite/*.c`) | Mirror controller's own documented layout exception | Matches the closest sibling in both size and shape (single-purpose C program, not a multi-file daemon); minimal file churn (headers/`.c` files keep flat sibling relationships they already have) | Diverges from the "general" worker/scheduler pattern, but that pattern is documented as having an existing exception already (controller) | **Selected** |
|
||||
|
||||
## Design Decisions
|
||||
|
||||
### Decision: Directory layout mirrors controller's flat-root exception, not the nested worker/scheduler pattern
|
||||
- **Context**: `structure.md`'s C Daemon Layout Pattern nests implementation under `src/<component>/src/`, but documents `controller/` as an explicit exception that keeps `.c` files flat in the component root while still having its own `testsuite/`.
|
||||
- **Alternatives Considered**: (1) nested `src/`/`include/` per the general pattern; (2) flat root matching controller's exception.
|
||||
- **Selected Approach**: `src/harness/*.c` + `src/harness/include/*.h` for production sources (the 15 files), `src/harness/testsuite/*.c` for the 17 white-box/integration test files plus a new Unity runner.
|
||||
- **Rationale**: xce_test's files are already flat siblings today; nesting them would be churn without a corresponding benefit, since there is no multi-domain internal structure (unlike worker/scheduler, which separate plugin/provider subsystems).
|
||||
- **Trade-offs**: A future reader must know controller and harness are the two flat-root exceptions to the general pattern — mitigated by recording both in `structure.md`'s Exceptions list (Requirement 6.3).
|
||||
- **Follow-up**: None.
|
||||
|
||||
### Decision: Promote `ctrlstatus_fmt.h` to `src/include/xce/`
|
||||
- **Context**: It is the one header genuinely shared between controller (`test_ctrlstatus.c`) and harness (`joblist_display.c`, `test.c`, `test_joblist_display.c`); leaving it in either component's tree would make the other component depend on it.
|
||||
- **Alternatives Considered**: (1) leave it in `src/controller/testsuite/`, have harness include it via a relative path back into controller (violates Requirement 1.4's "no dependency on any controller-private header" literally, and creates a harness→controller direction the standalone-component goal is meant to eliminate); (2) move it to `src/controller/include/` (controller's real component-header dir) and have harness depend on that explicitly as an allowed exception; (3) promote it to bare `src/include/` (the libxce public-header boundary); (4) promote it to `src/include/xce/` (the existing small subset of cross-daemon shared headers — `cluster.h`, `types.h`, `errnox.h`, `client_failover.h`, `cluster_def.h` — distinct from libxce's own API headers).
|
||||
- **Selected Approach**: (4) — move to `src/include/xce/ctrlstatus_fmt.h`, update its three moving consumers plus controller's `test_ctrlstatus.c` to include it as `xce/ctrlstatus_fmt.h`.
|
||||
- **Rationale**: It is header-only (`static inline`, zero link surface) and used for display formatting, not controller business logic, so it fits a shared boundary cleanly and satisfies Requirement 1.4 literally rather than by exception. Raised as a `/kiro-validate-design` critical issue (bare `src/include/` reads as libxce's real runtime API surface, which this isn't) — resolved to the existing `xce/` prefix instead, which is explicitly precedented for exactly this kind of small, cross-daemon, non-core-API shared header.
|
||||
- **Trade-offs**: Nominally grows `src/include/xce/`'s surface by one small formatting helper; judged acceptable given the existing precedent and that it removes a real cross-component coupling.
|
||||
- **Follow-up**: None.
|
||||
|
||||
### Decision: Keep the 5 harness test binaries separate rather than consolidating
|
||||
- **Context**: `/kiro-validate-design` review found the original design's "one new `harness_unit_test` binary" model was factually incomplete — 4 of the 17 test files are already independent binaries in `src/controller/meson.build`, split out because they have no dependency on controller internals. Once relocated, that original isolation reason no longer distinguishes them from the rest of harness (everything in harness has that same property), which made consolidation into one binary a plausible simplification.
|
||||
- **Alternatives Considered**: (1) consolidate all 17 files into one `harness_unit_test` binary; (2) preserve today's 5-binary structure verbatim, just relocated and re-suited.
|
||||
- **Selected Approach**: (2) — user decision.
|
||||
- **Rationale**: Lower risk and higher file-for-file fidelity to the current, working structure; avoids introducing a new merge step (and its own risk of a missed extern/RUN_TEST wiring mistake) into a spec whose entire purpose is a low-risk relocation.
|
||||
- **Trade-offs**: Forgoes a small simplification opportunity (one binary instead of five); judged acceptable given this spec's goal is decoupling, not build consolidation.
|
||||
- **Follow-up**: None — the 4 standalone binaries relocate with no internal changes beyond their `suite:` tag and include/dependency paths.
|
||||
|
||||
### Decision: `harness_unit_test` declares an explicit build-order dependency on the `xce_test` executable
|
||||
- **Context**: `test_test_cli.c` and `test_xcetest_process_entry.c` spawn the built `xce_test` binary as a subprocess; they will silently exec a stale or missing binary if the harness's own build doesn't guarantee `xce_test` is built first.
|
||||
- **Alternatives Considered**: (1) leave build ordering implicit (risk: flaky/stale-binary test runs); (2) declare the dependency explicitly in `src/harness/meson.build` so meson's own DAG enforces it.
|
||||
- **Selected Approach**: (2).
|
||||
- **Rationale**: This is exactly the kind of implicit-but-load-bearing coupling this spec exists to eliminate elsewhere (controller↔harness); introducing a new implicit one inside harness itself would be inconsistent.
|
||||
- **Trade-offs**: None material — this is the same pattern meson already supports for any test that needs another target built first.
|
||||
- **Follow-up**: Verify during implementation that the two spawning tests fail loudly (not silently pass against a stale binary) if the dependency were ever removed by accident — worth one regression test.
|
||||
|
||||
## Risks & Mitigations
|
||||
- **Risk**: A downstream skill script is missed, silently breaking a workflow the first time someone runs it without having built harness. — **Mitigation**: Requirement 5.4 requires a clear, actionable failure message wherever the harness binary is expected but absent; the four consumers were enumerated by grep across all four skill directories, not guessed.
|
||||
- **Risk**: Splitting `controller_unit_test_src`/`controller_test.c` by hand introduces a copy/paste error (a test moves but its production pairing or its `extern`/`RUN_TEST` entry doesn't, or one of the 4 standalone `executable()`/`test()` blocks is only partially relocated) and the build fails or silently drops coverage. — **Mitigation**: Requirement 3 requires the same pass/fail semantics and a distinct `harness` suite name, so a dropped test surfaces as a suite-count regression rather than a silent gap; `design.md`'s File Structure Plan now names every moving file and every moving meson block explicitly (13 files into `harness_unit_test` + 4 named standalone binaries + the `controller_test.c` extern list), rather than referring to "the test files" generically.
|
||||
- **Risk**: `meson setup`'s full-wipe-by-default behavior (`build-deployment.md`, bug-1565) means a `harness` build after a `controller` build in the same dir (or vice versa) silently deletes the other's binaries unless `--incremental` or `/xce-build all` is used — pre-existing project behavior, not introduced by this spec, but now applies to one more pair of components. — **Mitigation**: no design change needed; document as an existing, already-understood constraint (Boundary Commitments/Constraints in `design.md`).
|
||||
|
||||
## References
|
||||
- `.kiro/specs/xce-harness-component/brief.md` — original discovery brief with locked-in scope decisions (directory name `src/harness/`, binary name unchanged, fully decoupled build).
|
||||
- `.kiro/steering/structure.md` — C Daemon Layout Pattern and its documented controller exception.
|
||||
- `.kiro/steering/build-deployment.md` — `/xce-build` command semantics, meson structure, full-wipe-vs-incremental behavior.
|
||||
- `.wolf/buglog.json` bug-1792 — prior fix to `clitest_spawn()`'s pty echo handling, confirms the subprocess-spawning nature of `test_test_cli.c`.
|
||||
22
.kiro/specs/xce-harness-component/spec.json
Normal file
22
.kiro/specs/xce-harness-component/spec.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"feature_name": "xce-harness-component",
|
||||
"created_at": "2026-09-14T02:46:14Z",
|
||||
"updated_at": "2026-09-14T03:35:00Z",
|
||||
"language": "en",
|
||||
"phase": "tasks-generated",
|
||||
"approvals": {
|
||||
"requirements": {
|
||||
"generated": true,
|
||||
"approved": true
|
||||
},
|
||||
"design": {
|
||||
"generated": true,
|
||||
"approved": true
|
||||
},
|
||||
"tasks": {
|
||||
"generated": true,
|
||||
"approved": true
|
||||
}
|
||||
},
|
||||
"ready_for_implementation": true
|
||||
}
|
||||
|
|
@ -85,9 +85,9 @@
|
|||
- Observable: the deliberate-removal run reports a clear failure from the two pty-spawning tests; the normal run reports the full suite green
|
||||
- _Requirements: 3.1, 3.2_
|
||||
- _Depends: 2.1, 3.1_
|
||||
- [ ] 4.3 Verify independent and combined build behavior
|
||||
- Run `/xce-build harness` alone on a clean build dir and confirm `xce_test` is produced; run `/xce-build controller` alone and confirm `xce_test` is absent; run `/xce-build all` and confirm both exist
|
||||
- Observable: each of the three build invocations produces exactly the binaries described above
|
||||
- [x] 4.3 Verify independent and combined build behavior
|
||||
- Run `/xce-build harness` alone on a clean build dir and confirm `xce_test` is produced; run `/xce-build controller` alone and confirm its explicit compile step never targets `xce_test` (a full default-profile test run may still transitively rebuild it via `harness_unit_test`'s dependency -- a documented, accepted Meson limitation, not a defect; see requirements.md's "Known limitation" boundary note); run `/xce-build all` and confirm both exist
|
||||
- Observable: each of the three build invocations produces exactly the binaries described above, and the controller-only build's explicit `meson compile` step is confirmed (via build-log inspection) to never name `xce_test`
|
||||
- _Requirements: 2.1, 2.2, 2.4_
|
||||
- _Depends: 3.1_
|
||||
- [ ] 4.4 Verify every downstream workflow from a clean build state
|
||||
|
|
@ -103,6 +103,7 @@
|
|||
- **Task 1.1 gotcha**: a meson `custom_target` command's `@INPUT0@`/`@OUTPUT0@` tokens expand to build-root-relative paths, but a symlink's target string is resolved relative to the *symlink's own directory* at dereference time, not the invocation cwd or the string's own reference frame — using `@INPUT0@` directly as an `ln -sf` target from a different subdirectory produces a broken link. Use an explicit `../`-relative (or absolute) path instead.
|
||||
- **Build dir note**: this repo's default build dir resolves to `src/xce.build/` (relative to `src/tools/xce-build.sh`'s own cwd), not a bare `xce.build/` at the repo root.
|
||||
- **Task 4.1**: Confirmed behavioral parity conclusively — found a genuine pre-relocation binary (`src/build.dbg/controller/xce_test`, predates commit `cf55d691` by 3 days) and byte-diffed its `--help`/`--usage`/piped-REPL output against the harness-built binary: identical (only `--version`'s embedded build-hash/timestamp differs, as expected). Real, non-blocking follow-up found (out of this spec's boundary, pre-scoped by requirements.md's Adjacent Expectations for the `xce-test-rc-file`-owned one): `src/controller/testsuite/test_rcfile_integration.sh` and `clean_failover_preservation.sh` (the latter actually belongs to `ha-term-safety` task 5.2, not one of the three named xce-test-* specs) both hardcode a stale default binary path (`src/xce.build/controller/xce_test`) and the latter's failure message still says "run /xce-build controller" — should be repointed to `src/xce.build/harness/xce_test` by whoever owns each script next.
|
||||
- **Task 4.3**: found a real, deterministic Requirement 2.2 conflict, not a flake — under the default `asan` profile, `/xce-build controller`'s `meson test --suite controller` step transitively rebuilds `harness/xce_test` on disk, because Meson's test-runner rebuilds every registered test's build-order dependencies project-wide before filtering by `--suite`, and `harness_unit_test` (task 2.1) depends on `xce_test`. Traced precisely via build-log line analysis (explicit `meson compile` step: 209 steps, clean; subsequent `meson test` step: 844 steps, resurrects it) -- this is why task 3.1's own validation missed it: it checked the old `controller/xce_test` path (correctly absent), not `harness/xce_test` (the path that actually gets touched). User decision 2026-09-14: accept as a documented Meson limitation and narrow Requirement 2.2's wording to what the build system directly controls (its own explicit compile-target list), rather than auditing every component's test-target list (non-trivial -- controller's own suite already has 4 small test binaries not in its own explicit compile list, relying on this exact same auto-rebuild) or weakening `harness_unit_test`'s build-order dependency (task 4.2 verified load-bearing). requirements.md/design.md updated accordingly; logged as bug (not-fixed, accepted) for the record.
|
||||
- **Task 3.7**: Major Task 3 (Integration) is now fully complete. Task 3.6's review round caught a real doc-consistency miss (a partial fix left a contradicting stale claim elsewhere in the same file); the lesson (full end-to-end file re-read, not just the two named spots) was applied successfully in 3.7 and independently confirmed by review. Non-blocking follow-up noted for a future pass: `structure.md` line 92's generic "`test.c` provides the test runner harness" line is doubly stale (controller's runner is `controller_test.c`, harness's is `harness_test.c`) and also coincidentally collides with `src/harness/test.c`, which is real production code (xce_test's REPL entry point), not a test runner — worth a one-line correction sometime, out of this spec's boundary.
|
||||
- **Task 2.2**: Major Task 2 (Core) is now fully complete — all 5 harness test binaries exist under `suite: 'harness'` (4/20/5/12/132 tests, all green), controller's suite is fully clean at 1199 tests. Minor non-blocking cleanup found for a future pass: `src/controller/meson.build:211`'s `struct2json_dep` comment still cites `test_listfmt_json.c` (relocated to harness in task 2.1) as a consumer, and its own dependency may now be unused in `controller_unit_test_deps` — worth checking whether it can be dropped entirely once someone audits it.
|
||||
- **Task 2.1**: confirmed `resolve_xce_test_path()` (`/proc/self/exe` dirname + sibling lookup) needed zero code change once both `xce_test` and `harness_unit_test` build under the same `src/harness/meson.build` — they land in the same build-dir subdir automatically. Test counts cross-checked and consistent end to end: 1331 (pre-move) → 1228 (after task 1.1's 11-entry removal) → 1199 controller + 132 harness = 1331 (after task 2.1). Minor non-blocking nit for a future pass: `test_xcetest_process_entry.c`'s header comment still describes the old controller-embedded build layout — stale prose only, not a functional issue.
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ The protocol **drive** is NOT fully event-driven. Root cause: `peer_ctrl_msg_han
|
|||
|
||||
## Future Specs / Backlog (dependency order)
|
||||
|
||||
- [ ] **xce-harness-component** — **PROMOTED to spec 2026-09-13** (`/kiro-discovery`; brief at `.kiro/specs/xce-harness-component/brief.md`). Elevate `xce_test` (the REPL-driven wire-protocol test client used by HA soak / multi-host / resource-value verification) out of `src/controller/testsuite/` into its own first-class `src/harness/` component — own `meson.build`, `CLAUDE.md`, and unit-test binary (carved out of `controller_unit_test`, which today recompiles ~14 of xce_test's own files a second time paired with white-box tests) — fully decoupled from `/xce-build controller` (today's implicit "controller always builds xce_test" coupling, `build-deployment.md:24`). Verified finding: none of xce_test's 15 source files include any controller-private header — only libxce public headers + generated capnp schema — so this is a pure relocation + build-graph split, not a dependency untangling problem, and no xce_test behavior changes. Touches `/xce-test-ha`, `/xce-deploy-ha`, `/xce-test-multihost`, `/xce-test-resources` (each must build `harness` explicitly once decoupled) and is adjacent to (not overlapping) the three existing behavior specs `xce-test-cli-ux`/`xce-test-e2e-primitives`/`xce-test-rc-file`, whose file-path references go stale after the move. Next: `/kiro-spec-init xce-harness-component`.
|
||||
- [ ] config-upgrade-snapshot — **descoped from `ha-term-safety` R8 on 2026-06-21 (requirements generated; `.kiro/specs/config-upgrade-snapshot/`).** Closes **bug-857**: a configuration upgrade can leave members with DIVERGENT materialized state because today it does config-push + restart + per-node WAL replay under the new config (`config_repl.c` `do_upgrade_config_with_bytes` ~1001-1163), with no snapshot pinning an identical post-upgrade state (replay is config-dependent — `lost_and_found` re-homes orphaned entities). Approach: an upgrade materializes a **full entity-bearing state snapshot at the config-change marker's `(term,lsn)` boundary**, embeds the new config, and installs it on every member via the `snapshot_transfer_s` transport — no per-node re-derivation; supersedes `ha-term-safety` R7's interim config-push byte delivery for upgrades. **Former HARD dependency `entity-bearing-snapshots` is CLEARED** — it shipped as spec `ha-entity-snapshots` (**IMPLEMENTATION-COMPLETE, validate-impl GO 2026-07-18**; see Future Specs/Backlog below), and `ha-term-safety` (the config-change marker it anchors on) is also implemented. `config-upgrade-snapshot`'s own `spec.json` now has `blocked_on: []`. Verify by reproducing bug-857 (upgrade during chaotic multi-kill, diff materialized state). **Ready to promote to design.**
|
||||
- [ ] component-failover-adoption — **recorded 2026-06-16; depends on libxce-failover (HARD).** Make the C daemons and the Go apiserver actually exercise libxce's transparent failover. The mechanism reaches them for free (worker/scheduler/controller link `libxce_dep`; apiserver uses it via cgo, `src/frontend/apiserver/backend/clib.go`), but two per-component integration items remain: (1) each component must hand libxce the **full master list** instead of a single endpoint (today even the CLI uses only `conf->masters[0]`, `client.c:122`); (2) bounded retry makes the already-blocking `xce_request` block **longer** (seconds of backoff) — for the async C daemons (worker `controller_connector.c`, scheduler `handler.c`) this must be verified **liveness-safe**, i.e. it must not stall a thread that also drives heartbeats (the "never block the iomgr thread" rule). Scope: per-component master-list config + retry policy + liveness-safe blocking + per-component E2E failover for **scheduler, worker, apiserver**. (`xce_test` is NOT here — it is the in-spec verification client of libxce-failover.) Promote via `/kiro-spec-init component-failover-adoption` after libxce-failover lands.
|
||||
- [x] ~~worker-rejoin-resync~~ — **PROMOTED to spec 2026-08-10, see In Flight (Raft Apply-Ordering family) above** for current status and brief. No longer tracked here.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue