Files
ansible-workspace-dnd/docs/roadmap/implementation.md

314 lines
13 KiB
Markdown

# Implementation Plan 0001: Simplify Seriatim Source Installation
Status: proposed
Target executor: GPT-5.6-Terra
Feature roadmap:
[Feature 0001: Seriatim Source Installation](features/0001-seriatim-source-installation.md)
## Objective
Replace the current overengineered `ansible-role-seriatim` implementation with
the concise, module-driven role defined by Feature 0001. Preserve the useful
role metadata and supported installation outcome while removing persistent
build state, duplicated module logic, speculative recovery, and obsolete test
coverage.
## Execution Rules
- Execute Stage 1 and Stage 2 in numeric order.
- Before each stage, confirm its preconditions and the working-tree state of
the owning repository.
- Modify only `ansible-role-seriatim`. Treat this workspace plan,
`rakestraw-ansible`, and `../seriatim` as read-only during implementation.
- Preserve unrelated and pre-existing changes. Stop if the role repository is
not clean at a stage boundary unless its changes are the expected output of
the immediately preceding stage.
- Follow `docs/conventions.md` and the Feature 0001 task flow. Trust the
idempotence and change detection of `apt`, Snap, `file`, and `git`.
- Keep the three rebuild triggers directly on the build task. Do not create an
intermediate rebuild fact, build handlers, or a handler flush.
- Do not reintroduce fingerprints, checksums, sidecar build state, manual Git
cleanup, staged replacement, compiler inspection, or malformed-path
recovery.
- Use fully qualified collection names and `argv` for command execution.
- Run each stage's validation before committing it. Do not begin Stage 2 if
Stage 1 fails validation.
- Commit each completed stage with the plain-English message specified below.
Do not push.
- Treat `/usr/local/src/seriatim` and `/usr/local/bin/seriatim` as disposable
role-managed state during local integration. Do not remove the obsolete
`/usr/local/src/seriatim.ansible-build-state` directory from the host; the
revised role simply stops managing it.
## Starting State and Preconditions
- `ansible-role-seriatim` is clean on `main` at commit `6fb1aa2` and is ten
commits ahead of its current `origin/main`.
- The workspace plan and revised feature roadmap are reviewed and committed
before out-of-band execution begins.
- The local controller and managed host are Ubuntu 26.04 `amd64`, with
passwordless privilege escalation available for the approved integration
test.
- Workspace tooling is available in `../.venv/bin` from the role repository:
Ansible Core 2.21.3 and ansible-lint 26.8.0.
- `community.general` 13.3.0 remains pinned in
`collections/requirements.yml`, and the Go Snap channel `1.26/stable` is
available.
- Upstream tag `v1.5.0` resolves to commit
`0fc92f364316c874d366b00cdc884a33e1900b25`.
- The upstream `v1.5.0` contract remains:
- Go module requirement 1.25;
- build package `./cmd/seriatim`;
- `CGO_ENABLED=0`, `GOWORK=off`, `GOTOOLCHAIN=local`, and `-trimpath`;
- linker flags `-s -w -X
gitea.maximumdirect.net/eric/seriatim/internal/buildinfo.Version=<version>`;
- `seriatim --version` output `seriatim version <version>`.
- Upstream tag `v1.4.0` resolves to
`9202ccddb962ab499f0772d3c01efdf2ff703077` and supports the same build and
version contracts for the selected-version integration case.
## Repository Scope
- `ansible-role-seriatim` owns every implementation, interface, README, and
repository-local test change in this plan.
- `ansible-workspace-dnd` owns the roadmap, this plan, and aggregate status but
remains unchanged during out-of-band implementation.
- `../seriatim` is the authoritative read-only application contract.
- `rakestraw-ansible` is a read-only style reference.
- Every other repository in `workspace.yml` remains unchanged.
## Fixed Public Interface
Retain exactly these public defaults:
| Variable | Default | Purpose |
| --- | --- | --- |
| `seriatim_version` | `v1.5.0` | Git revision and version injected into the executable |
| `seriatim_repository_url` | `https://gitea.maximumdirect.net/eric/seriatim.git` | Source repository |
| `seriatim_source_dir` | `/usr/local/src/seriatim` | Managed source checkout |
| `seriatim_binary_path` | `/usr/local/bin/seriatim` | Installed executable |
| `seriatim_manage_build_dependencies` | `true` | Whether to install Git and Go |
| `seriatim_go_snap_channel` | `1.26/stable` | Go Snap channel |
The Go executable, package, build flags, linker symbol, and build environment
are fixed implementation details. The selected version is both the Git ref and
the value injected into the binary.
## Stage 1: Replace the Role with the Minimal Implementation
**Completion:** Complete (`ansible-role-seriatim` commit `325a5c7`).
### Objective
Replace the existing role contract, task graph, documentation, and baseline
test harness with one coherent minimal implementation that installs and
validates the default Seriatim release idempotently.
### Preconditions
- The starting-state commits and upstream contracts above are unchanged.
- `ansible-role-seriatim` has no uncommitted changes.
- The default managed paths contain no data that must be preserved.
### Owning Repository
`ansible-role-seriatim`
### Required Changes
1. Reduce `defaults/main.yml` and `meta/argument_specs.yml` to the six variables
in the Fixed Public Interface. Retain useful role and Galaxy metadata in
`meta/main.yml`.
2. Replace the imported task structure with one readable `tasks/main.yml` and
remove the obsolete task files. Implement approximately this task flow:
1. assert Ubuntu 26.04 and architecture `x86_64` or `aarch64`;
2. install Git with `ansible.builtin.apt` when dependency management is
enabled;
3. install the classic Go Snap from `seriatim_go_snap_channel` with
`community.general.snap` when dependency management is enabled;
4. create the source and binary parent directories as `root:root` mode
`0755` with one `ansible.builtin.file` loop;
5. check out `seriatim_version` with `ansible.builtin.git`, using
`seriatim_repository_url`, `seriatim_source_dir`, and `force: true`, and
register the module result;
6. inspect `seriatim_binary_path` with `ansible.builtin.stat`;
7. run `seriatim_binary_path --version` only when the binary exists,
registering the result without reporting change or failing the play;
8. build directly to `seriatim_binary_path` when the Git task changed, the
binary is absent, or the version command failed or returned anything
other than `seriatim version {{ seriatim_version }}`;
9. converge recursive `root:root` source ownership and binary
`root:root` mode `0755` with one item-driven `ansible.builtin.file` loop;
10. validate the binary version after a build without reporting change.
3. Put the rebuild expression directly on the build command. Register the
build result for post-build validation and mark the command changed only
when it runs.
4. Invoke `/snap/bin/go build` with `argv`, the fixed package, flags, linker
value, output path, working directory, and environment from the upstream
contract. Do not turn those fixed values into defaults or facts.
5. Remove all code for Git executable discovery, Go executable and compiler
validation, manual Git status/reset/clean, resolved-commit facts, temporary
build directories, build inputs, fingerprints, checksums, sidecar state,
special path-object recovery, and transactional installation.
6. Do not add `handlers/main.yml`; the build, permission, and validation tasks
execute in normal order.
7. Rewrite the README to document the six-variable interface, privilege and
fact requirements, dependency opt-out behavior, authoritative Git checkout,
direct build contract, three rebuild triggers, installed metadata, and
validation commands. Remove every claim or example tied to deleted
variables, state files, staging, compiler invalidation, or failure
preservation.
8. Rewrite `tests/verify.yml` to check only the selected commit, recursive
source ownership, binary type and metadata, and exact version output.
9. Replace `tests/integration` with a focused baseline driver that installs the
pinned collection locally, runs syntax checking and ansible-lint, converges
the default role, runs `tests/verify.yml`, and requires `changed=0` and
`failed=0` on an immediate repeat. Keep `tests/converge.yml`,
`tests/inventory`, and the compatible platform-guard playbook concise.
### Validation
From `ansible-role-seriatim`, run:
```sh
tests/integration
! rg -n \
'seriatim_(source_ref|build_version|build_state_dir|go_binary|go_build_flags|go_ldflags|go_package)|fingerprint|checksum' \
defaults meta tasks tests README.md
git diff --check
git status --short
```
Expected result: static validation passes; the default source resolves to
`0fc92f364316c874d366b00cdc884a33e1900b25`; the binary reports
`seriatim version v1.5.0` with `root:root` ownership and mode `0755`; the
immediate repeat reports `changed=0` and `failed=0`; and only intended Stage 1
changes remain before commit.
### Completion Criteria
- The public interface contains exactly six defaults and matching argument
specifications.
- The role's effective task flow matches the roadmap without intermediate
rebuild state or handlers.
- No role code or active documentation references the obsolete sidecar state
or removed variables.
- The baseline integration driver passes and proves default idempotence.
- No repository outside `ansible-role-seriatim` changed.
### Commit
Commit message: `Simplify the Seriatim role`
## Stage 2: Add Focused Behavioral Coverage
### Objective
Extend the baseline test harness only far enough to prove the revised feature's
selected rebuild triggers, metadata convergence, platform guard, and final
default state.
### Preconditions
- Stage 1 is committed and the role repository is otherwise clean.
- The Stage 1 baseline integration test passes.
- Upstream tags `v1.4.0` and `v1.5.0` remain available.
### Owning Repository
`ansible-role-seriatim`
### Required Changes
1. Extend `tests/integration` using strict shell options, repository-relative
paths, a private temporary directory, and cleanup that restores the default
`v1.5.0` installation when possible.
2. Retain the baseline convergence, verification, and clean-repeat cases, then
add focused cases for:
- an absent binary causing one rebuild followed by an unchanged run;
- an executable that reports the wrong version causing one rebuild followed
by an unchanged run;
- binary ownership or mode drift being repaired by the ordinary `file` task
without requiring a rebuild, as shown by the captured Ansible task output;
- selecting `v1.4.0`, confirming its commit and version output, and reaching
an unchanged repeat;
- restoring `v1.5.0`, confirming its commit and version output, and reaching
a final unchanged repeat;
- unsupported distribution, Ubuntu release, and architecture inputs failing
before creating application state at isolated temporary paths.
3. Keep recap checks simple and fail the driver on hidden task failures or
unexpected changes during idempotence runs.
4. Keep test mutation limited to the two declared managed paths and paths below
the driver's private temporary directory.
5. Do not add cases for fingerprints, checksums, compiler changes, source-tree
dirt, staged failure preservation, custom-parent recovery, symbolic links,
malformed state, or the obsolete build-state directory.
6. Update the README test section to describe the actual focused suite and its
managed-host effects without advertising superseded behavior.
### Validation
From `ansible-role-seriatim`, run:
```sh
tests/integration
git diff --check
git status --short
```
Then confirm the restored default installation:
```sh
/usr/local/bin/seriatim --version
sudo git -C /usr/local/src/seriatim rev-parse HEAD
sudo stat -c '%U:%G %a' /usr/local/bin/seriatim
```
Expected result: the complete focused suite passes; all expected negative
platform cases are recognized; the final repeat reports `changed=0` and
`failed=0`; the restored executable reports `seriatim version v1.5.0`; the
source is at `0fc92f364316c874d366b00cdc884a33e1900b25`; binary metadata is
`root:root 755`; and only intended Stage 2 changes remain before commit.
### Completion Criteria
- Every Feature 0001 acceptance criterion has direct test or static evidence.
- The suite tests only the revised operational contract and contains no
superseded hardening matrix.
- The README, defaults, argument specifications, task flow, and tests agree.
- The default local installation is restored and idempotent.
- No repository outside `ansible-role-seriatim` changed.
### Commit
Commit message: `Focus Seriatim integration coverage`
## Final Validation and Handoff
After Stage 2, run:
```sh
tests/integration
git log --oneline -2
git status --short --branch
cd ..
./scripts/status
```
The implementation handoff must report:
- the Stage 1 and Stage 2 commit hashes in order;
- the final integration result and clean-repeat recap;
- the final source commit, version output, ownership, and mode;
- any deviation from this plan or the feature roadmap;
- any remaining implementation concern or potential future hardening item.
Do not edit workspace roadmap or status files, mark Feature 0001 `done`, or
push during out-of-band execution. Completion requires subsequent review.
## Progress Notes
No stages have been executed.