docs(spec): promote eliminate-frontend-makefile backlog item to a brief
/kiro-discovery investigation of removing src/frontend/Makefile in favor of Meson as the sole build system. Records the quick investigation's findings (5 boundary seams, current-state evidence that build-cli/ build-server are already dead from /xce-build's perspective and build-server is already broken today) and the user's confirmed decision to fully remove the Makefile rather than keep a compat wrapper. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AgYRU3zDTqNGV5Jk8aiKLg
This commit is contained in:
parent
d8bf8fb2e1
commit
5e68fcc0d8
3 changed files with 83 additions and 1 deletions
58
.kiro/specs/eliminate-frontend-makefile/brief.md
Normal file
58
.kiro/specs/eliminate-frontend-makefile/brief.md
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# Brief: eliminate-frontend-makefile
|
||||
|
||||
## Problem
|
||||
`src/frontend/Makefile` and Meson's `tools/go_build` wrapper are two independent build systems for the same two Go binaries (apiserver, xcecli), each computing its own copy of the same version-fingerprint logic (`commit_id`/`build_time`/`dirty_fingerprint`). This is an already-realized, not theoretical, drift risk: the Makefile's independent fingerprint computation needed three adversarial review rounds to fix a shell exit-status bug during `dirty-content-fingerprint` task 4.3 (`roadmap.md:82`), and `build-server` — the Makefile's OWN apiserver build target — is independently confirmed *currently broken* (bug-1597, `.wolf/cerebrum.md:48`): a bare `go build` with no `CGO_CFLAGS`/`CGO_LDFLAGS`, failing outright with `fatal error: client.h: No such file or directory`. `src/docs/deployment.md:243-247` already documents this exact failure as a "build gotcha" and tells developers to use `/xce-build apiserver` instead — i.e., the project's own docs already steer people away from the target that's supposed to be the Makefile's main value proposition.
|
||||
|
||||
## Current State
|
||||
- `src/frontend/Makefile` (195 lines) has 5 targets: `build-cli`, `build-server`, `test`, `test-backend`, `test-integration` (+ `test-all`).
|
||||
- `build-cli`/`build-server` are each 2 lines of actual build logic; the surrounding ~130 lines exist entirely to independently re-derive version-fingerprint `-ldflags`, duplicating logic `src/tools/xce-build.sh` already owns.
|
||||
- Meson already builds both binaries today via `tools/go_build` (`apiserver/meson.build`'s `custom_target`, `xcecli/meson.build`'s equivalent) — confirmed working, lands in the per-profile build dir (e.g. `build.dbg/frontend/apiserver/xce_apiserver`).
|
||||
- `/xce-build apiserver`/`/xce-build all` (`xce-build.sh`) already build via meson exclusively (`meson compile ... apiserver xcecli`, line 237) — the Makefile's `build-cli`/`build-server` are not in that path at all today.
|
||||
- `xce-build.sh` DOES still shell out to `cd frontend && make test` for running Go unit tests (lines 240, 287) — this is the one live automation dependency on the Makefile from the project's own canonical build tool.
|
||||
- No meson `test()` exists anywhere for the CGO-backed backend test suite (`apiserver/meson.build` has a build-only `custom_target`, zero test registrations) — `make test-backend` is the ONLY way to run these tests today.
|
||||
- One other live script (`run-resource-verify.sh:350`) checks for a binary at the Makefile's hardcoded `/tmp/apiserver` output path and prints a `make build-server`-referencing error if absent.
|
||||
- `deploy-ha.sh` used to hard-depend on the same `/tmp/apiserver` path; this was just fixed (this session, uncommitted) to prefer the meson build-dir path first, matching the pattern already used for xceadmin/worker/scheduler, falling back to `/tmp/apiserver` only if the meson one is absent.
|
||||
|
||||
## Desired Outcome
|
||||
`src/frontend/Makefile` is deleted. All Go builds for apiserver/xcecli happen exclusively via Meson (`/xce-build apiserver`/`/xce-build xcecli`/`/xce-build all`). Go test execution (unit + CGO backend + integration) is either wired into meson as real `test()` targets, or reduced to plain, documented `go test`/shell invocations with no Makefile indirection — matching the pattern `xce-build.sh`'s own `xcecli` case (line 249) already uses today for xcecli's tests, bypassing Make entirely. No developer or script depends on a Makefile-specific fixed output path (`/tmp/apiserver`, `/tmp/xce_static`) after this lands.
|
||||
|
||||
## Approach
|
||||
**Decision confirmed with user (2026-08-27): keep a single build system — Meson survives, `src/frontend/Makefile` is removed entirely, not kept as a thin/compat wrapper.** No alternative approach was considered or offered; this was a direct instruction, not a selection among options.
|
||||
|
||||
**Phased replacement, test-coverage-preserving order** (see Boundary Candidates below for the split). Not a single mechanical deletion — the CGO backend test suite has no meson equivalent today, so that gap must be closed BEFORE the Makefile can be safely removed, or backend CGO regression coverage silently disappears.
|
||||
|
||||
Two sub-approaches were considered for the CGO backend test gap specifically:
|
||||
1. **Add a meson `test()` wired with the same CGO env `apiserver/meson.build`'s `custom_target` already derives** (cgo_cflags/cgo_ldflags via the same `apiserver_cgo_deps` pkg-config loop, lines 20-38) — single source of truth, no duplicate derivation. **Recommended.**
|
||||
2. Keep a minimal, build-free shell script (not a Makefile) that just runs `go test ./backend/...` with hand-derived CGO flags — avoids touching `apiserver/meson.build`, but reintroduces exactly the duplicate-derivation risk this whole effort exists to eliminate.
|
||||
|
||||
## Scope
|
||||
- **In**: deleting `src/frontend/Makefile`; migrating `xce-build.sh`'s 2 `make test` call sites to direct `go test` invocations (mirroring the existing `xcecli` case); adding a meson `test()` (or equivalent) for the CGO backend suite so that coverage isn't lost; migrating `test-integration`'s `XCE_BIN`/`SRV_URL` convention to point at the meson-built binary; updating the ~9 files with live-relevant doc references (`tech.md`, `build-deployment.md`, `testing.md`, `structure.md`, `frontend/CLAUDE.md`, `src/docs/deployment.md`, `xce-deploy-ha/SKILL.md`); updating `run-resource-verify.sh`'s apiserver-binary discovery to the same dual-path pattern `deploy-ha.sh` now uses.
|
||||
- **Out**: rewriting historical spec docs (`tasks.md`/`research.md`/`design.md` under already-completed specs like `ha-config-bootstrap`, `component-failover-adoption`, etc.) that mention `make test`/`make build-server` as acceptance criteria for work already shipped — those are frozen records, not live automation, and editing them provides no value. Any change to the underlying version-fingerprint computation itself (`xce-build.sh`'s own logic) — this effort only removes the SECOND, duplicate computation site, not the first.
|
||||
|
||||
## Boundary Candidates
|
||||
- **Seam 1 — Build targets** (`build-cli`/`build-server`): already effectively dead from `/xce-build`'s perspective; lowest risk, smallest diff. Can land independently of the other seams.
|
||||
- **Seam 2 — Unit test target** (`test`): 2 call sites in `xce-build.sh`, already has a proven direct-`go test` replacement pattern in the same file. Low risk.
|
||||
- **Seam 3 — CGO backend test target** (`test-backend`): needs a genuinely new meson `test()` registration (no existing equivalent) before the Makefile target can be removed without losing coverage. This is the one seam that's real net-new work, not just deletion — highest-effort seam.
|
||||
- **Seam 4 — Integration test target** (`test-integration`): depends on Seam 1 (needs a `build-cli` replacement first) plus its own `XCE_BIN` path update.
|
||||
- **Seam 5 — Doc/script updates**: mechanical once seams 1-4 land; the actual reference list is already enumerated (see this investigation's own findings).
|
||||
|
||||
Given all 5 seams touch the same small `src/frontend/` + `src/tools/xce-build.sh` area, share one dependency graph (Seam 4 depends on Seam 1; nothing else cross-depends), and total scope is well under 20 tasks, this is a **single spec**, not a multi-spec decomposition — Path C.
|
||||
|
||||
## Out of Boundary
|
||||
- Any change to `apiserver/meson.build`'s existing CGO flag derivation logic itself (only *reusing* it for the new test() target, not modifying it).
|
||||
- Any change to `xce-build.sh`'s version-fingerprint computation (the "source of truth" side of the duplication, not the Makefile side being removed).
|
||||
- Rewriting frozen historical spec documents.
|
||||
- The `set -euo pipefail`-causes-CGO-tests-to-be-structurally-skipped-in-`all` gap noted in `component-failover-adoption/tasks.md:201` — real, adjacent, but a separate `xce-build.sh` control-flow bug, not something this removal effort should silently fix as a side effect.
|
||||
|
||||
## Upstream / Downstream
|
||||
- **Upstream**: `apiserver/meson.build`'s existing CGO dependency list (`apiserver_cgo_deps`) is the thing Seam 3's new test() target must reuse, not re-derive.
|
||||
- **Downstream**: `deploy-ha.sh` (already migrated this session), `run-resource-verify.sh` (needs the same dual-path treatment), any future skill/script that currently assumes `/tmp/apiserver`/`/tmp/xce_static` as a fixed discovery path.
|
||||
|
||||
## Existing Spec Touchpoints
|
||||
- **Extends**: none directly — this is genuinely new spec-shaped work, not an extension.
|
||||
- **Adjacent**: `dirty-content-fingerprint` (the spec whose task 4.3 review first surfaced the duplication risk this effort resolves — provenance only, not reopened); `build-time-versioning` (owns the version-fingerprint computation `xce-build.sh` is the single source of truth for, post this change).
|
||||
|
||||
## Constraints
|
||||
- Must not reduce CGO backend test coverage at any point during the migration (Seam 3 must land before Seam 3's Makefile target is removed, not after).
|
||||
- Nix devShell already bundles the full C/Go/Python toolchain uniformly — there is no "avoid installing the C toolchain" argument for keeping a Make-only path, unlike projects where Go-only contributors might want to skip C dependencies.
|
||||
- `go test -race` is confirmed unusable in this ASAN-linked CGO environment (independently hit 3 times per `component-failover-adoption/tasks.md:197`) — any new test() wiring must not attempt to add `-race`.
|
||||
24
.kiro/specs/eliminate-frontend-makefile/spec.json
Normal file
24
.kiro/specs/eliminate-frontend-makefile/spec.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"feature_name": "eliminate-frontend-makefile",
|
||||
"created_at": "2026-08-27T00:00:00Z",
|
||||
"updated_at": "2026-08-27T00:00:00Z",
|
||||
"language": "en",
|
||||
"phase": "brief",
|
||||
"description": "Remove src/frontend/Makefile entirely, consolidating Go builds (apiserver, xcecli) and their tests onto Meson's tools/go_build wrapper. Closes a real, already-realized duplicate version-fingerprint-computation risk (roadmap.md backlog item, recorded 2026-08-21). Path C single-scope investigation via /kiro-discovery, 2026-08-27.",
|
||||
"approvals": {
|
||||
"requirements": {
|
||||
"generated": false,
|
||||
"approved": false
|
||||
},
|
||||
"design": {
|
||||
"generated": false,
|
||||
"approved": false
|
||||
},
|
||||
"tasks": {
|
||||
"generated": false,
|
||||
"approved": false
|
||||
}
|
||||
},
|
||||
"ready_for_implementation": false,
|
||||
"blocked_on": []
|
||||
}
|
||||
|
|
@ -79,7 +79,7 @@ The protocol **drive** is NOT fully event-driven. Root cause: `peer_ctrl_msg_han
|
|||
|
||||
Smaller items that likely don't warrant a full spec; pick up opportunistically or bundle into adjacent spec work.
|
||||
|
||||
- [ ] **eliminate src/frontend/Makefile, consolidate Go builds onto meson** — **recorded 2026-08-21, from `dirty-content-fingerprint` spec's task 4.3.** The Makefile's `build-cli`/`build-server` targets exist as a "no meson involved" fast dev-loop path for apiserver/xcecli, but they achieve this by INDEPENDENTLY REIMPLEMENTING the same `commit_id`/`build_time`/`dirty_fingerprint` computation `src/tools/xce-build.sh` already owns (two separate computation sites for the identical values, a pattern `build-time-versioning`'s own research.md already flagged as an accepted-but-real drift risk). That risk materialized concretely: task 4.3's Makefile-side fingerprint computation needed **three adversarial review rounds** to fix a shell multi-stage-pipe exit-status bug (`{ cmd1; cmd2; } >file`'s exit status only reflects the last command, silently swallowing an earlier failure and fabricating output from incomplete data) — a bug class that could not have existed if there were only one computation site. Since XCE's nix devShell already bundles the full C/Go/Python toolchain uniformly (no dependency-avoidance benefit to a separate meson-free path the way there might be in a project where Go contributors don't want the C toolchain installed), the Makefile's marginal value may just be "skip the initial `meson setup` step" — `meson compile -C <builddir> apiserver`/`xcecli` should already give an equivalent single-target incremental rebuild once a build directory exists. **Not started — investigation first**: measure actual dev-loop friction of `meson compile` vs. `make build-cli`/`build-server` (first-configure cost vs. per-rebuild cost) before committing to removing the Makefile; if removed, `build-deployment.md` and any CI/doc references to `make build-cli`/`build-server` need updating too. Promote via `/kiro-discovery` or direct investigation when ready.
|
||||
- [x] ~~eliminate src/frontend/Makefile, consolidate Go builds onto meson~~ — **PROMOTED to spec 2026-08-27** (`/kiro-discovery`; brief at `.kiro/specs/eliminate-frontend-makefile/brief.md`). Investigation (recorded 2026-08-21, from `dirty-content-fingerprint` spec's task 4.3) confirmed the risk is real and independently corroborated: `build-server` is separately confirmed BROKEN today (bug-1597, bare `go build` with no CGO flags, `fatal error: client.h: No such file or directory`; `src/docs/deployment.md:243-247` already tells developers to use `/xce-build apiserver` instead). Blast radius is narrower than originally framed: `/xce-build` already builds both binaries via meson exclusively (`build-cli`/`build-server` are dead weight from that path today); only 2 live call sites (`xce-build.sh:240,287`) depend on `make test`, with an already-proven direct-`go test` replacement 3 lines away in the same file. One genuine gap found: no meson `test()` exists for the CGO backend suite (`test-backend`) — that must be added before the Makefile can be safely removed, or backend CGO coverage is lost, not just inconvenienced. Next: `/kiro-spec-init eliminate-frontend-makefile`.
|
||||
- [ ] **job_ctrl direct-mutate path — migrate to commit-then-apply** — **recorded 2026-07-13, investigated 2026-08-19 (finding: real risk, wider scope than originally framed).** `raft-apply-decoupling` deliberately scoped `job_ctrl`'s `mark_job_update`/`mark_job_fail` (admin SIGCONT/SIGSTOP) OUT-OF-BOUNDARY (task 4.1/6.1 Implementation Notes). The 2026-08-19 investigation found the original framing wrong in two ways: (1) **NOT the only remaining call site** — `on_job_stop`/`on_job_resume`/`on_job_ckpt` (`job.c:2067-2222`) share the identical unconverted mutate-then-notify-then-WAL-append pattern, fed by ordinary worker/scheduler traffic, not "rare, admin-only" as originally described; (2) **blast radius (a) is confirmed real, not theoretical** — the pre-commit mutation is synchronously pushed live to BOTH the scheduler (`sched_job_update_fun`) AND every connected apiserver/client (`apiserver_job_update_fun`) before the commit barrier resolves; on barrier timeout the admin gets a failure reply but `job->job.state` is never rolled back and no retraction is ever sent — matching the bug-795/828/851/1060 shape. Live-apply vs replay-apply (b) is narrower than feared for `job_ctrl` specifically (the `allocs != NULL` gate mutually excludes it from the converted deferred-apply fact types), but the investigation surfaced a SEPARATE bug underpinning that safety argument: `job_ctrl` (`job.c:999`) holds only a read lock while mutating job state — every other mutator in this file takes a write lock — so two concurrent admin commands on the same job aren't mutually excluded, undermining the "same lock, no staleness window" claim the replay-safety argument depends on (already flagged by a `raft-apply-decoupling` task 2.1 reviewer, never fixed). **Recommendation**: promote to a small follow-up spec covering all four call sites together (bounded, well-precedented fix — same shape as the fact-receipt conversion `raft-apply-decoupling` already built for job submit); the lock-type bug is independently fixable and low-risk regardless of when/whether the larger migration happens. Not yet promoted — user decision 2026-08-19 to correct scope/framing here first, promote later.
|
||||
- [x] **WAL-trim cursor-bound guard (bug-1147; surfaced 2026-06-25 by raft-drive-async design review)** — **IMPLEMENTED** as part of `raft-drive-async` task 3.2 (`raft-drive-async` is IMPLEMENTED, validate-impl GO 2026-07-18; see above). `trim_wal_segments` (`persist.c` ~2597-2644) now computes `floor = repl_trim_lsn(&p->repl, active_seg_lsn, p->config.snap_interval_s)` — folding in active-standby `acked_lsn` and disconnected-slot `last_disconnected_lsn` — and only unlinks segments below that floor; the code comment at `persist.c:2634` explicitly labels this the "(bug-1147 guard)". Far-behind/empty join (cursor=0) is additionally covered now that `entity-bearing snapshots` (strategy B) has landed as `ha-entity-snapshots` (see above), with a live decision path (`ha.c:4413`, "< oldest_wal_lsn → requesting snapshot transfer"). Related: bug-795, bug-828, bug-1060.
|
||||
- [ ] OP_heartbeat peers cross-validation — include a hash of the local `--peers` string in heartbeat requests; log ERROR on mismatch between candidates. Detects misconfigured nodes at election time instead of silently risking dual-primary split-brain. _(FUTURE_WORK.md §3.)_
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue