Revise the Seriatim plan and workspace conventions

This commit is contained in:
2026-09-08 00:16:12 +00:00
parent aafee9ea62
commit fc803587b8
13 changed files with 479 additions and 895 deletions

View File

@@ -1,47 +1,49 @@
# Feature 0001: Seriatim Source Installation
Status: done
Status: ready
## Summary
Implement the first independently usable application role by teaching
`ansible-role-seriatim` to install Seriatim from a pinned upstream source
release. This feature establishes the source-build and role conventions that
can be reviewed before analogous work begins in the other application roles.
Provide a small, independently usable `rakestraw.seriatim` role that installs
Seriatim from a pinned Git tag, builds the native executable on the managed
host, and converges idempotently. This revised specification replaces the
original overengineered implementation target and establishes the preferred
module-driven style for subsequent application roles.
## Problem or Opportunity
The pipeline applications do not yet share a uniform prebuilt release model,
and the new Ansible role repositories contain only initial scaffolding. The MVP
therefore builds applications on the managed host. Seriatim is the smallest
useful proving ground because it has no central application configuration file,
allowing this feature to isolate installation, reproducibility, idempotence,
and validation concerns.
The current role reaches the basic deployment outcome, but it does so with
manual source cleanup, compiler parsing, build-input serialization, hashes,
checksums, sidecar state, path-shape recovery, and a large defensive test
matrix. Those mechanisms are disproportionate to the MVP and obscure the
simple job of checking out a repository, building one executable, and
installing it with known metadata.
Seriatim remains the right proving ground because it has no central
configuration file. Simplifying it before implementing another role prevents
the current design from becoming an accidental suite-wide pattern.
## Scope
- Establish a conventional, independently usable Ansible role structure in
`ansible-role-seriatim`.
- Simplify `ansible-role-seriatim` into concise, idiomatic Ansible.
- Support Ubuntu 26.04 on native `amd64` and `arm64` hosts.
- Install Git and the official Go Snap using classic confinement when build
- Install Git and the official Go Snap with classic confinement when build
dependency management is enabled.
- Default the Go Snap channel to `1.26/stable` and allow consumers to override
the channel or disable build-dependency management.
- Clone the official Seriatim repository into a root-owned managed source
directory, defaulting to `/usr/local/src/seriatim`.
- Default to the immutable `v1.5.0` release tag, verified as the latest current
upstream tag on 2026-09-07, while supporting explicit branch or commit
overrides for development.
- Build a native, statically linked Seriatim binary using the upstream build
contract, including release-version injection.
- Validate a staged binary before installing it as
`/usr/local/bin/seriatim` with `root:root` ownership and mode `0755`.
- Record sufficient build state to rebuild when the resolved source commit,
Go compiler version, or effective build arguments change.
- Validate the installed binary and demonstrate convergence on a repeated role
run.
- Document the role interface, defaults, supported platform, development
overrides, and validation procedure.
- Default the Go Snap channel to `1.26/stable`.
- Check out the selected Seriatim version from its official Git repository,
defaulting to immutable tag `v1.5.0`, under a root-owned
`/usr/local/src/seriatim`.
- Build Seriatim using the fixed upstream release build contract and install
it at `/usr/local/bin/seriatim`.
- Rebuild when the source checkout changes, the binary is absent, or the
installed binary does not report the selected version.
- Converge the installed binary to `root:root` ownership and mode `0755`.
- Validate a newly built binary with `seriatim --version`.
- Keep the role interface, README, metadata, and focused local tests consistent
with the simplified behavior.
- Remove obsolete build-state files and implementation machinery from the
role repository. Existing build-state data on previously managed hosts does
not need to be removed by the role.
## Non-goals
@@ -49,123 +51,169 @@ and validation concerns.
- Creation or management of the `narratio` account or operator membership.
- Installation or configuration of any other pipeline application.
- Pipeline composition, campaign data, prompts, secrets, or scheduling.
- Installation from prebuilt Seriatim release artifacts.
- Removal or purge behavior.
- A shared build helper role or premature abstraction of the first
implementation.
- Full Ubuntu 26.04 platform-matrix or `arm64` integration infrastructure.
- Installation from prebuilt release artifacts or removal behavior.
- Detecting rebuild needs from Go compiler patch changes, fixed build-command
changes, or manually altered binary contents that still report the selected
version.
- Build fingerprints, binary checksums, or persistent sidecar build state.
- Transactional replacement that preserves a previous executable after a
failed local build.
- Automatic recovery from deliberately malformed paths, symbolic-link
redirection, hostile source trees, or other adversarial host state.
- A shared build helper role or abstraction.
- Dedicated platform-matrix infrastructure beyond the approved local MVP
proxy.
## Target End State
On an Ubuntu 26.04 `amd64` or `arm64` host, applying the role with default
variables checks out Seriatim `v1.5.0` under `/usr/local/src/seriatim`, builds
it with the locally installed Go 1.26 toolchain, validates it, and installs a
root-owned executable at `/usr/local/bin/seriatim`. The installed command
reports `v1.5.0` through its global version flag.
variables installs Git and Go when requested, checks out Seriatim `v1.5.0`
under a root-owned `/usr/local/src/seriatim`, and installs a native executable at
`/usr/local/bin/seriatim`. The executable is owned by `root:root`, has mode
`0755`, and reports `seriatim version v1.5.0`.
A second application of the role makes no changes when the selected source,
compiler, build arguments, and installed binary are unchanged. Changing the
selected revision, compiler patch version, or effective build arguments causes
a rebuild. A failed build or validation does not replace an existing working
binary.
An immediate second application makes no changes. A changed Git checkout, a
missing binary, or a binary reporting another version causes one build. The
following application is again unchanged.
The managed source checkout is authoritative and may be reset to the selected
revision; local modifications beneath it are not preserved. Development users
may select a branch or commit explicitly, but released role and collection
manifests use immutable release tags.
The role trusts `apt`, `community.general.snap`, `file`, and `git` to provide
their documented idempotence and change detection. It does not inspect state
before invoking those modules or maintain a parallel model of the state they
already manage.
## Repository Ownership
- `ansible-role-seriatim` owns all implementation, defaults, documentation,
and repository-local validation added by this feature.
- `../seriatim` is the read-only authority for the application build, version,
and CLI contracts.
- `ansible-role-seriatim` owns the role implementation, defaults, metadata,
README, dependency declaration, and repository-local validation.
- `../seriatim` is the read-only authority for the build, version, and CLI
contracts.
- `rakestraw-ansible` is a read-only style reference.
- `ansible-workspace-dnd` owns this roadmap, the active implementation plan,
and cross-repository status only.
- The remaining role, collection, application, content, and proof-of-concept
repositories remain unchanged.
and cross-repository status.
- All other repositories remain unchanged.
## Constraints and Settled Decisions
- The suite MVP supports Ubuntu 26.04 and native `amd64` and `arm64` builds.
- Local execution on the current Ubuntu 26.04 development host is a sufficient
MVP integration proxy; dedicated platform-matrix infrastructure is deferred.
- Go is installed from Snap with classic confinement. Builds use the local
toolchain with `GOTOOLCHAIN=local` rather than allowing automatic toolchain
downloads.
MVP integration proxy.
- Go is installed from Snap with classic confinement and defaults to channel
`1.26/stable`.
- `community.general` is an approved dependency and provides Snap management;
its version is pinned in the role's collection requirements.
- The suite standardizes on Go channel `1.26/stable`, even though Seriatim's
current `go.mod` requires Go 1.25.
- Builds use `GOWORK=off`, `CGO_ENABLED=0`, and `-trimpath`.
- Release builds inject the selected release version into
`gitea.maximumdirect.net/eric/seriatim/internal/buildinfo.Version` with
`-ldflags`.
- A change to the installed Go compiler patch version is a build-input change
and triggers a rebuild.
- `/usr/local/src/seriatim` is fully Ansible-managed. The role enforces the
selected Git revision rather than preserving local changes.
- Source and installed binaries are owned by `root` and are not writable by
runtime operators.
- The build runs from the checked-out source using `/snap/bin/go`,
`GOWORK=off`, `GOTOOLCHAIN=local`, `CGO_ENABLED=0`, `-trimpath`, package
`./cmd/seriatim`, and the upstream linker flag that injects the selected
version into `internal/buildinfo.Version`.
- The selected version is both the Git revision and the version injected into
the executable. Supporting independent source and build identities is not an
MVP requirement.
- The public interface is limited to meaningful deployment choices:
`seriatim_version`, `seriatim_repository_url`, `seriatim_source_dir`,
`seriatim_binary_path`, `seriatim_manage_build_dependencies`, and
`seriatim_go_snap_channel`.
- Fixed executable paths, build flags, linker symbols, environment values, and
package paths are implementation details, not public variables.
- `docs/decisions/0001-minimal-module-driven-ansible.md` governs the role's
implementation style.
## Simplest Viable Implementation
The intended Seriatim implementation is approximately the following ten
ordinary tasks.
1. Assert the supported distribution, release, and architecture.
2. Install Git with `ansible.builtin.apt` when dependency management is
enabled.
3. Install Go with `community.general.snap` when dependency management is
enabled.
4. Create the source and binary parent directories with one
`ansible.builtin.file` loop.
5. Check out the selected source with `ansible.builtin.git` and register its
normal changed result.
6. Inspect whether the installed binary exists.
7. Read its version when it exists, without reporting a change.
8. Run the upstream Go build when the Git checkout changed, the binary is
absent, or its reported version differs from the selected version.
9. Converge source ownership and the installed binary's ownership and mode
with one `ansible.builtin.file` loop.
10. Validate the version after a build, without reporting a change.
For this fixed set of three rebuild triggers, the build remains an ordinary
task with the conditions applied directly to its `when` expression. This keeps
the complete decision visible at the action site and avoids deferred execution
or a play-wide handler flush. Permission convergence and post-build validation
then follow in their natural task order. Do not create an intermediate
`seriatim_build_required` fact.
The implementation may combine or split a task when required for clear and
correct Ansible, but it must not add preflight checks around idempotent modules
or reintroduce persistent build-state machinery. Prefer a single readable task
file unless a split materially improves navigation.
## Rationale and Alternatives
Starting with Seriatim exercises the common source installation path without
mixing in application configuration, credentials, shared accounts, or pipeline
composition. This makes the first implementation small enough to review
carefully and allows its conventions to be corrected before being repeated.
This design uses the Git module's changed result as the natural signal that
source changed. The installed application's version is the only additional
state needed to decide whether a binary must be built. That preserves useful
convergence without maintaining a second database of compiler and build
inputs.
Using Go `1.26/stable` across the suite favors one predictable host toolchain
over selecting each application's minimum supported version. Rebuilding after
a compiler patch change preserves an honest relationship between recorded
build inputs and installed output. Keeping the first role self-contained also
avoids committing to a shared abstraction before repeated implementation has
shown which behavior is truly common.
Building directly to the configured binary path is intentionally simpler than
staging, checksumming, and recording a transactional installation. A failed
build will fail the play visibly; preserving an older executable in every
failure mode is not an MVP requirement.
## Acceptance Criteria
- The role rejects unsupported distributions, Ubuntu releases, and
architectures with a clear diagnostic before modifying application state.
- Default role execution on the local Ubuntu 26.04 host installs or confirms
the required Git and Go build dependencies.
- The source checkout resolves to the commit referenced by tag `v1.5.0` and is
root-owned at `/usr/local/src/seriatim` by default.
- The role builds with the documented local-toolchain and version-injection
contract and installs `/usr/local/bin/seriatim` as `root:root` mode `0755`.
- `/usr/local/bin/seriatim --version` reports `v1.5.0`.
architectures before modifying application state.
- Default execution on the local Ubuntu 26.04 host installs or confirms Git
and Go and checks out Seriatim tag `v1.5.0`.
- The role builds with the documented fixed upstream contract and installs
`/usr/local/bin/seriatim` as `root:root` mode `0755`.
- The managed source checkout is owned by `root:root`.
- `/usr/local/bin/seriatim --version` reports
`seriatim version v1.5.0`.
- An immediate second role run reports no changes.
- A changed selected revision, Go compiler patch version, or effective build
argument invalidates recorded build state and rebuilds the binary.
- A deliberately failed staged build or version validation leaves a previously
installed working binary intact.
- Development revision overrides converge to the requested branch or commit
and discard unmanaged changes in the source checkout.
- Role defaults, metadata, README documentation, syntax validation, focused
automated checks, and local integration evidence are present in the owning
repository.
- A missing binary or a binary reporting the wrong version causes one rebuild
followed by an unchanged run.
- A changed selected version causes the Git task and build task to change and
then converges.
- The implementation contains no build-input documents, fingerprints, binary
checksums, sidecar build state, manual Git reset or clean commands, or
preliminary checks for state already managed by `apt`, Snap, `file`, or
`git`.
- Public defaults and argument specifications contain only the six variables
named in this roadmap.
- Syntax checking, ansible-lint, a focused local convergence test, and a clean
repeated run pass.
- Role documentation describes the actual concise behavior and does not claim
transactional build safety or exhaustive corruption recovery.
- No repository other than `ansible-role-seriatim` and the workspace control
repository is modified.
## Dependencies and Follow-up Work
This feature depends only on access to the Seriatim Git repository, Ubuntu Snap
infrastructure, and Go module sources from the managed host.
The role requires access to the Seriatim Git repository, Ubuntu Snap
infrastructure, and Go module sources from the managed host. After this revised
implementation is reviewed, its minimal conventions can inform a fresh Audita
roadmap and the remaining application roles.
After review, the source-build conventions may be adopted by the Audita,
Scriptorium, Notarius, and Narratio roles. Generalization into shared tooling,
prebuilt-binary installation, removal behavior, and dedicated multi-platform
test infrastructure remain deferred until concrete experience justifies them.
The original implementation commits remain in Git history as evidence of the
superseded design. The prior completion and remediation documents must not be
used as templates for another role.
## Completion Evidence
## Potential Future Hardening
- `ansible-role-seriatim` commits `ac35c1f` through `efd4734` implement the
staged role contract, source installation, reproducible build, and integration
coverage.
- Remediation commits `c6c1907` through `6fb1aa2` close all findings recorded in
`docs/roadmap/remediation.md`, including malformed state and metadata drift.
- The complete integration suite passes on the local Ubuntu 26.04 development
host, restores the default installation, and finishes with a clean idempotent
convergence.
- The verified installation reports `seriatim version v1.5.0`, uses upstream
commit `0fc92f364316c874d366b00cdc884a33e1900b25`, and has consistent source,
binary, ownership, and build-state metadata.
- Build in a temporary location and validate before replacing the installed
executable.
- Verify release signatures or source checksums.
- Record compiler and build-input identity for exact rebuild invalidation.
- Detect arbitrary binary modification independently of reported version.
- Protect or recover from unexpected symbolic links and malformed managed
paths.
- Add dedicated Ubuntu release and architecture test matrices.
These are candidates for separately selected features if operational
experience or a changed threat model justifies them.

View File

@@ -0,0 +1,35 @@
# Feature 0002: Audita Source Installation and Configuration
Status: proposed
## Planning Note
Audita remains the likely next application role, but its previously drafted
roadmap and implementation plan were withdrawn before implementation. They
depended on the original Seriatim fingerprint, sidecar-state, staged-build,
and corruption-recovery architecture, which is no longer an approved pattern.
Do not implement this feature from the withdrawn plan. After the simplified
Seriatim role has been implemented and reviewed, discuss Audita again and
write a fresh feature roadmap using the workspace's minimal, module-driven
conventions.
## Preserved Upstream Research
- The latest selected immutable release was `v0.9.1`, resolving to commit
`a84941d68168a1ed9ea7423b6477ae8218be73f9` when inspected.
- The tag declares Go 1.24.0 and builds the package
`gitea.maximumdirect.net/eric/audita/cmd/audita` with `CGO_ENABLED=0`,
`GOWORK=off`, `GOTOOLCHAIN=local`, `-trimpath`, and the documented release
linker flags.
- The release does not expose a CLI version command suitable for Seriatim's
version-based rebuild check. The simplest appropriate rebuild signal must be
decided during renewed roadmap discussion.
- Audita configuration schema version is `1`. Its native validator accepts
`audita config validate --config <path>` and reports `config is valid` for a
valid file.
- Default configuration discovery prefers
`/usr/local/etc/audita/config.yml` over `/etc/audita/config.yml`.
These facts should be revalidated against the authoritative `../audita`
repository before a new roadmap is approved.

View File

@@ -34,6 +34,14 @@ application contracts.
Link the MVP roadmap and applicable decision records. Record technical or
operational constraints that implementations must preserve.
## Simplest Viable Implementation
Outline the direct, module-driven task flow at the level needed to constrain
the implementation without turning the roadmap into an execution plan. Trust
module idempotence and change detection. Identify any non-obvious probe,
sidecar state, staging mechanism, command, or abstraction and tie it to a
specific acceptance criterion.
## Rationale and Alternatives
Explain material tradeoffs and why the selected end state is preferred. Omit
@@ -47,3 +55,8 @@ this section when the choice is mechanical and needs no durable rationale.
List prerequisites and explicitly deferred work without expanding this
feature's scope.
## Potential Future Hardening
List worthwhile security or resilience improvements that are deliberately not
part of the initial implementation. Omit this section when there are none.