Revise the Seriatim plan and workspace conventions
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user