Revise the Seriatim plan and workspace conventions
This commit is contained in:
102
AGENTS.md
102
AGENTS.md
@@ -7,96 +7,14 @@ deploy the D&D transcript-processing pipeline. It owns cross-repository plans,
|
||||
decisions, status, and workspace tooling. Each application and Ansible project
|
||||
is an independent Git repository.
|
||||
|
||||
## Repository Map
|
||||
## Required Reading
|
||||
|
||||
Repositories inside this directory:
|
||||
|
||||
- `ansible-collection-dnd`: the `rakestraw.dnd` collection that bundles and
|
||||
distributes the pipeline suite.
|
||||
- `ansible-role-dnd-pipeline`: independent source repository for the
|
||||
suite-level role exposed by the collection as `rakestraw.dnd.pipeline`.
|
||||
- `ansible-role-{narratio,notarius,audita,seriatim,scriptorium}`: standalone
|
||||
application roles.
|
||||
- `rakestraw-ansible`: working deployment repository containing the
|
||||
`pipeline_dnd` proof of concept; treat it as read-only reference unless the
|
||||
task explicitly includes it.
|
||||
|
||||
Relevant upstream repositories are siblings of this directory:
|
||||
|
||||
- `../{narratio,notarius,audita,seriatim,scriptorium}`: application source and
|
||||
authoritative application contracts.
|
||||
- `../narratio-prompts`: pipeline prompt-library content.
|
||||
|
||||
Use `workspace.yml` as the complete machine-readable inventory of paths and
|
||||
remotes.
|
||||
|
||||
## Sources of Truth
|
||||
|
||||
- `docs/roadmap/mvp.md`: settled MVP scope, architecture, and open design work.
|
||||
- `docs/roadmap/features/`: durable scope and target state for selected units
|
||||
of work.
|
||||
- `docs/status.md`: current cross-repository progress and next work.
|
||||
- `docs/decisions/`: durable rationale for significant architectural choices.
|
||||
- `docs/roadmap/implementation.md`: the single active staged implementation
|
||||
plan, replaced for each selected feature after its feature roadmap is agreed.
|
||||
- Application repositories: CLI, configuration, build, and integration
|
||||
contracts.
|
||||
- Individual Ansible repositories: implementation and repository-local tests.
|
||||
|
||||
Do not duplicate an application contract in workspace documentation when a
|
||||
link and a concise deployment consequence are sufficient.
|
||||
|
||||
## Working Conventions
|
||||
|
||||
- Confirm the target repository before editing; never treat this directory as
|
||||
a monorepo.
|
||||
- Inspect the relevant upstream application before designing or changing its
|
||||
Ansible role.
|
||||
- Keep standalone application roles independently usable. Cross-application
|
||||
policy belongs in `ansible-role-dnd-pipeline` and is exposed to consumers as
|
||||
`rakestraw.dnd.pipeline`.
|
||||
- Prefer `ansible.builtin` modules where they directly fit the task.
|
||||
`community.general` is an approved, stable dependency and its modules may be
|
||||
selected freely when appropriate; declare and pin the collection wherever a
|
||||
role or collection depends on it.
|
||||
- Prefer codebase-memory graph tools for code discovery. Use text/file search
|
||||
for documentation, configuration, literals, or when the graph is
|
||||
insufficient.
|
||||
- Preserve unrelated and pre-existing working-tree changes in every
|
||||
repository.
|
||||
- Never place credentials or secret values in plans, examples, inventory, or
|
||||
tests.
|
||||
- Validate changes in the repository that owns them and report the commands
|
||||
run.
|
||||
|
||||
## Planning and Progress
|
||||
|
||||
- Update `docs/roadmap/mvp.md` when a design question becomes a settled scope
|
||||
or architecture decision.
|
||||
- Discuss and select the next unit of work before planning implementation.
|
||||
- Give each selected feature a four-digit identifier and a durable document at
|
||||
`docs/roadmap/features/<id>-<slug>.md`. Add the same identifier to
|
||||
`docs/status.md`.
|
||||
- Write and agree on the feature roadmap before writing its implementation
|
||||
plan. The roadmap owns scope, target end state, rationale, constraints, and
|
||||
acceptance criteria.
|
||||
- Always write the current implementation plan to
|
||||
`docs/roadmap/implementation.md`. Replace that file when planning the next
|
||||
selected feature; Git history preserves prior plans when needed.
|
||||
- Write implementation plans as dependency-ordered stages suitable for
|
||||
GPT-5.6-Terra to execute sequentially. Number stages with consecutive
|
||||
integers beginning with `Stage 1`; do not skip numbers or use nested stage
|
||||
numbering. Each stage must identify its repository, preconditions, required
|
||||
behavior, validation, completion criteria, and expected commit.
|
||||
- Resolve architectural choices during roadmap and plan review. Do not leave
|
||||
unresolved design judgment to the implementation agent.
|
||||
- Update `docs/status.md` when cross-repository work starts, becomes blocked,
|
||||
or is completed. Completed items must point to concrete evidence.
|
||||
- Out-of-band implementation should commit each completed stage when that
|
||||
stage leaves its owning repository valid. Review the implementation and its
|
||||
validation evidence before marking the feature complete.
|
||||
- Retain feature roadmaps as durable records. Remove or archive obsolete
|
||||
implementation detail after completion; durable architectural rationale
|
||||
belongs in `docs/decisions/`.
|
||||
- Use the status values `proposed`, `ready`, `in_progress`, `blocked`, `done`,
|
||||
and `deferred`.
|
||||
- Read [the workspace orientation](docs/orientation.md) before selecting,
|
||||
inspecting, or modifying a repository. It maps the repositories and defines
|
||||
the canonical sources of truth.
|
||||
- Read [the workspace conventions](docs/conventions.md) before reviewing or
|
||||
changing Ansible, preparing a feature roadmap or implementation plan, or
|
||||
making any repository change. It defines the normative house style and
|
||||
working conventions.
|
||||
- Read [the planning policy](docs/planning.md) before preparing a feature
|
||||
roadmap or implementation plan or managing an ongoing work stream.
|
||||
|
||||
49
docs/conventions.md
Normal file
49
docs/conventions.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Workspace Conventions
|
||||
|
||||
## Working Conventions
|
||||
|
||||
- Confirm the target repository before editing; never treat this directory as
|
||||
a monorepo.
|
||||
- Inspect the relevant upstream application before designing or changing its
|
||||
Ansible role.
|
||||
- Keep standalone application roles independently usable. Cross-application
|
||||
policy belongs in `ansible-role-dnd-pipeline` and is exposed to consumers as
|
||||
`rakestraw.dnd.pipeline`.
|
||||
- Prefer codebase-memory graph tools for code discovery. Use text/file search
|
||||
for documentation, configuration, literals, or when the graph is
|
||||
insufficient.
|
||||
- Preserve unrelated and pre-existing working-tree changes in every
|
||||
repository.
|
||||
- Never place credentials or secret values in plans, examples, inventory, or
|
||||
tests.
|
||||
- Validate changes in the repository that owns them and report the commands
|
||||
run.
|
||||
- Do not duplicate an application contract in workspace documentation when a
|
||||
link and a concise deployment consequence are sufficient.
|
||||
|
||||
## Ansible House Style (Normative)
|
||||
|
||||
- Always use the smallest clear sequence of declarative tasks that reaches the
|
||||
required end state.
|
||||
- Prefer `ansible.builtin` modules where they directly fit the task.
|
||||
`community.general` is an approved, stable dependency and its modules may be
|
||||
selected freely when appropriate; declare and pin the collection wherever a
|
||||
role or collection depends on it.
|
||||
- Trust the documented contract of each Ansible module, including its
|
||||
idempotence and change detection.
|
||||
- Gather state only when the result controls necessary behavior that the
|
||||
responsible module cannot determine. Fingerprints, checksums, sidecar state,
|
||||
manual drift detection, and speculative recovery paths require an explicit
|
||||
acceptance criterion and rationale. Do not precede a declarative module with
|
||||
a probe or recreate its internal logic unless a concrete requirement cannot
|
||||
be expressed by the module itself.
|
||||
- Consider whether a conditional task or a notified handler best expresses the
|
||||
dependency. A `when` condition keeps triggers visible at the action site but
|
||||
grows with their number. Notifications keep the action independent of the
|
||||
number of notifiers, but distribute the control flow and defer execution
|
||||
until the next handler flush. An explicit
|
||||
`ansible.builtin.meta: flush_handlers` affects all pending handlers in the
|
||||
play.
|
||||
- Treat `rakestraw-ansible` as a style reference for direct tasks, shallow
|
||||
control flow, and concise variable use, while retaining current practices
|
||||
such as fully qualified collection names.
|
||||
52
docs/decisions/0001-minimal-module-driven-ansible.md
Normal file
52
docs/decisions/0001-minimal-module-driven-ansible.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Decision 0001: Minimal, Module-Driven Ansible
|
||||
|
||||
Status: accepted
|
||||
|
||||
Date: 2026-09-07
|
||||
|
||||
## Context
|
||||
|
||||
The first Seriatim implementation surrounded ordinary Ansible operations with
|
||||
preflight inspection, fingerprints, sidecar build state, manual drift logic,
|
||||
and recovery behavior. Much of that machinery duplicated behavior already
|
||||
provided by Ansible modules or addressed threats and failure modes outside the
|
||||
MVP. The result was harder to understand, review, and maintain than the
|
||||
deployment it represented.
|
||||
|
||||
The proof-of-concept roles in `rakestraw-ansible` demonstrate the preferred
|
||||
style: direct module use, shallow task flow, small public interfaces, and
|
||||
loops only for genuinely uniform resources.
|
||||
|
||||
## Decision
|
||||
|
||||
Roles in this workspace will express the required end state with the most
|
||||
direct suitable Ansible module and trust that module's documented idempotence,
|
||||
change detection, check-mode behavior, and error handling.
|
||||
|
||||
Additional inspection or state machinery is justified only when a selected
|
||||
requirement falls outside that module contract. In particular:
|
||||
|
||||
- Do not use `stat`, package queries, content comparisons, or account lookups
|
||||
merely to decide whether to invoke an idempotent module.
|
||||
- Gather state when it is genuinely needed to control application behavior,
|
||||
such as determining whether a locally built executable is missing or has
|
||||
the wrong application version.
|
||||
- Do not introduce fingerprints, checksums, sidecar state, staged replacement,
|
||||
custom drift recovery, or abstractions without an explicit acceptance
|
||||
criterion and rationale.
|
||||
- Keep role variables to meaningful consumer choices. Do not expose every
|
||||
fixed argument of an upstream build command as a public interface.
|
||||
- Test the intended operating contract and idempotent convergence. Do not
|
||||
build a speculative hardening test matrix into the MVP.
|
||||
|
||||
## Consequences
|
||||
|
||||
Feature roadmaps describe the simplest viable implementation shape, and
|
||||
implementation plans must justify any material complexity beyond it. Reviews
|
||||
should remove logic that merely reimplements a module's contract.
|
||||
|
||||
Potential security hardening and unusual recovery behavior may be recorded for
|
||||
future consideration without becoming part of the initial implementation.
|
||||
This accepts that an MVP role may fail plainly when the managed host contains
|
||||
malicious, corrupted, or unsupported state rather than attempting automatic
|
||||
recovery from every condition.
|
||||
44
docs/orientation.md
Normal file
44
docs/orientation.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Workspace Orientation
|
||||
|
||||
## Repository Map
|
||||
|
||||
Repositories inside this directory:
|
||||
|
||||
- `ansible-collection-dnd`: the `rakestraw.dnd` collection that bundles and
|
||||
distributes the pipeline suite.
|
||||
- `ansible-role-dnd-pipeline`: independent source repository for the
|
||||
suite-level role exposed by the collection as `rakestraw.dnd.pipeline`.
|
||||
- `ansible-role-{narratio,notarius,audita,seriatim,scriptorium}`: standalone
|
||||
application roles.
|
||||
- `rakestraw-ansible`: working deployment repository containing the
|
||||
`pipeline_dnd` proof of concept; treat it as read-only reference unless the
|
||||
task explicitly includes it.
|
||||
|
||||
Relevant upstream repositories are siblings of this directory:
|
||||
|
||||
- `../{narratio,notarius,audita,seriatim,scriptorium}`: application source and
|
||||
authoritative application contracts.
|
||||
- `../narratio-prompts`: pipeline prompt-library content.
|
||||
|
||||
Use [the workspace inventory](../workspace.yml) as the complete
|
||||
machine-readable inventory of paths and remotes.
|
||||
|
||||
## Sources of Truth
|
||||
|
||||
- [Workspace conventions](conventions.md): normative working and Ansible house
|
||||
style.
|
||||
- [Planning policy](planning.md): normative feature planning and progress
|
||||
workflow.
|
||||
- [MVP roadmap](roadmap/mvp.md): settled MVP scope, architecture, and open
|
||||
design work.
|
||||
- [Feature roadmaps](roadmap/features/): durable scope and target state for
|
||||
selected units of work.
|
||||
- [Workspace status](status.md): current cross-repository progress and next
|
||||
work.
|
||||
- [Decision records](decisions/): durable rationale for significant
|
||||
architectural choices.
|
||||
- [Implementation plan](roadmap/implementation.md): the fixed location for the
|
||||
active staged plan or, when no plan is approved, a pending-plan notice.
|
||||
- Application repositories: CLI, configuration, build, and integration
|
||||
contracts.
|
||||
- Individual Ansible repositories: implementation and repository-local tests.
|
||||
44
docs/planning.md
Normal file
44
docs/planning.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Planning and Progress
|
||||
|
||||
- Read and follow [the workspace conventions](conventions.md) before preparing
|
||||
or revising any roadmap or implementation plan.
|
||||
- Update [the MVP roadmap](roadmap/mvp.md) when a design question becomes a
|
||||
settled scope or architecture decision.
|
||||
- Discuss and select the next unit of work before planning implementation.
|
||||
- Give each selected feature a four-digit identifier and a durable document at
|
||||
`docs/roadmap/features/<id>-<slug>.md`. Start from the
|
||||
[feature-roadmap template](roadmap/features/template.md) and add the same
|
||||
identifier to [workspace status](status.md).
|
||||
- Write and agree on the feature roadmap before writing its implementation
|
||||
plan. The roadmap owns scope, target end state, rationale, constraints, and
|
||||
acceptance criteria.
|
||||
- Every feature roadmap must describe its simplest viable implementation shape
|
||||
and identify any deliberate complexity. Keep optional security hardening,
|
||||
unusual corruption recovery, and other speculative resilience outside the
|
||||
MVP unless explicitly selected as requirements.
|
||||
- Start from the [implementation-plan template](roadmap/implementation-template.md)
|
||||
and always write the current plan to
|
||||
[the fixed implementation-plan location](roadmap/implementation.md). Replace
|
||||
that file when planning the next selected feature; Git history preserves
|
||||
prior plans when needed.
|
||||
- When a prior plan has been withdrawn and its replacement has not yet been
|
||||
agreed, replace stale execution instructions with a brief pending-plan
|
||||
notice. Never leave an obsolete plan looking executable.
|
||||
- Write implementation plans as dependency-ordered stages suitable for
|
||||
GPT-5.6-Terra to execute sequentially. Number stages with consecutive
|
||||
integers beginning with `Stage 1`; do not skip numbers or use nested stage
|
||||
numbering. Each stage must identify its repository, preconditions, required
|
||||
behavior, validation, completion criteria, and expected commit.
|
||||
- Resolve architectural choices during roadmap and plan review. Do not leave
|
||||
unresolved design judgment to the implementation agent.
|
||||
- Update [workspace status](status.md) when cross-repository work starts,
|
||||
becomes blocked, or is completed. Completed items must point to concrete
|
||||
evidence.
|
||||
- Out-of-band implementation should commit each completed stage when that
|
||||
stage leaves its owning repository valid. Review the implementation and its
|
||||
validation evidence before marking the feature complete.
|
||||
- Retain feature roadmaps as durable records. Remove or archive obsolete
|
||||
implementation detail after completion; durable architectural rationale
|
||||
belongs in [decision records](decisions/).
|
||||
- Use the status values `proposed`, `ready`, `in_progress`, `blocked`, `done`,
|
||||
and `deferred`.
|
||||
@@ -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.
|
||||
|
||||
@@ -23,6 +23,14 @@ for scope, rationale, target end state, and acceptance criteria.
|
||||
- Preserve unrelated and pre-existing changes.
|
||||
- Do not make unresolved product or architecture decisions during execution;
|
||||
stop and report the decision required.
|
||||
- Start from the feature roadmap's simplest viable implementation. Trust
|
||||
module-provided idempotence, change detection, check-mode behavior, and
|
||||
error handling rather than reproducing them with preliminary probes or
|
||||
supplemental state.
|
||||
- Do not add a task merely for defensive completeness. Every probe, fact,
|
||||
checksum, custom `changed_when`, shell or command invocation, sidecar state
|
||||
file, staging layer, or abstraction must be required by an
|
||||
acceptance criterion and must solve behavior that a direct module does not.
|
||||
- Run every stage's validation before committing it.
|
||||
- Commit each completed stage when it leaves the repository in a valid state,
|
||||
using the commit intent specified by that stage.
|
||||
@@ -57,6 +65,8 @@ State the single outcome delivered by this stage.
|
||||
1. Describe concrete behavior to implement, including relevant files or
|
||||
components where known.
|
||||
2. State invariants, compatibility requirements, and explicit exclusions.
|
||||
3. Give the expected module-driven task flow. Call out every required use of
|
||||
`command`, `shell`, state inspection, or manual change detection.
|
||||
|
||||
### Validation
|
||||
|
||||
@@ -91,6 +101,8 @@ and subsequent consecutive integers as needed.
|
||||
- Confirm every changed repository is clean and identify all resulting commit
|
||||
hashes.
|
||||
- Summarize deviations from this plan, unresolved findings, and deferred work.
|
||||
- Report any implementation complexity added beyond the planned task flow and
|
||||
the acceptance criterion that required it.
|
||||
- Do not mark the feature `done`; implementation results require review first.
|
||||
|
||||
## Progress Notes
|
||||
|
||||
@@ -1,507 +1,12 @@
|
||||
# Implementation Plan 0001: Seriatim Source Installation
|
||||
# Active Implementation Plan
|
||||
|
||||
Status: proposed
|
||||
There is no approved implementation plan at present.
|
||||
|
||||
Target executor: GPT-5.6-Terra
|
||||
Feature 0001 has been reopened with a revised, minimal specification at
|
||||
`docs/roadmap/features/0001-seriatim-source-installation.md`. Prepare its
|
||||
numbered staged implementation plan here only after that revised roadmap and
|
||||
the workspace implementation conventions have been reviewed.
|
||||
|
||||
Feature roadmap:
|
||||
`docs/roadmap/features/0001-seriatim-source-installation.md`
|
||||
|
||||
## Objective
|
||||
|
||||
Implement `ansible-role-seriatim` as an independently usable role that installs
|
||||
Seriatim `v1.5.0` from its pinned Git source, builds it with the local Go 1.26
|
||||
Snap toolchain, installs it safely, and converges idempotently. Preserve the
|
||||
feature roadmap as the authority for scope, rationale, target state, and
|
||||
acceptance criteria.
|
||||
|
||||
## Execution Rules
|
||||
|
||||
- Execute Stage 1 through Stage 4 in numeric order.
|
||||
- Before each stage, confirm its preconditions and the working-tree state of
|
||||
every repository named by that stage.
|
||||
- Preserve unrelated and pre-existing changes. Stop if the owning repository
|
||||
is not clean at a stage boundary unless the changes are the expected output
|
||||
of the immediately preceding stage.
|
||||
- Do not modify `rakestraw-ansible`, any upstream application repository, any
|
||||
other role, or the collection.
|
||||
- Do not make new product or architecture decisions. Stop and report any
|
||||
conflict between this plan, the feature roadmap, and an upstream contract.
|
||||
- Prefer `ansible.builtin` modules where they directly fit. Use the approved
|
||||
`community.general.snap` module for channel-aware Snap management and pin
|
||||
its collection dependency.
|
||||
- Run every stage's validation before committing it. Do not begin a dependent
|
||||
stage after a validation failure.
|
||||
- Commit each completed stage in `ansible-role-seriatim` using the specified
|
||||
commit intent. Do not push unless separately instructed.
|
||||
- Treat `/usr/local/src/seriatim`, `/usr/local/bin/seriatim`, and the adjacent
|
||||
role build-state directory as disposable managed test state during local
|
||||
integration. Do not remove or alter unrelated host paths.
|
||||
- Leave workspace roadmap and status files unchanged during implementation;
|
||||
report stage commits and evidence for review instead.
|
||||
|
||||
## Starting State and Preconditions
|
||||
|
||||
- `ansible-workspace-dnd` and `ansible-role-seriatim` start clean on `main`.
|
||||
- The active implementation plan has been reviewed and committed before
|
||||
execution begins.
|
||||
- The controller host is Ubuntu 26.04.1 `amd64` and has passwordless privilege
|
||||
escalation available for the approved local integration run.
|
||||
- Workspace tools are available at `../.venv/bin` from the role repository,
|
||||
including Ansible Core 2.21.3 and ansible-lint 26.8.0.
|
||||
- The managed host has working Snap infrastructure and outbound access to the
|
||||
Seriatim Git repository, the Snap Store, and Go module sources.
|
||||
- Upstream tag `v1.5.0` resolves to commit
|
||||
`0fc92f364316c874d366b00cdc884a33e1900b25`.
|
||||
- The upstream `v1.5.0` contract is:
|
||||
- module requirement `go 1.25`;
|
||||
- build package `./cmd/seriatim`;
|
||||
- `CGO_ENABLED=0` and `-trimpath`;
|
||||
- linker flags `-s -w -X
|
||||
gitea.maximumdirect.net/eric/seriatim/internal/buildinfo.Version=<version>`;
|
||||
- `seriatim --version` output `seriatim version <version>`.
|
||||
|
||||
## Repository Scope
|
||||
|
||||
- `ansible-role-seriatim` is the only implementation repository and owns every
|
||||
role, test, dependency, and README change in this plan.
|
||||
- `ansible-workspace-dnd` owns this plan and the feature roadmap but remains
|
||||
read-only during out-of-band execution.
|
||||
- `../seriatim` may be inspected as the authoritative upstream contract and
|
||||
must remain unchanged.
|
||||
- All other repositories in `workspace.yml` remain unchanged.
|
||||
|
||||
## Fixed Role Interface
|
||||
|
||||
Define and document these public defaults. All paths are managed-host paths.
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `seriatim_version` | `v1.5.0` | Release identity expected from the installed binary |
|
||||
| `seriatim_repository_url` | `https://gitea.maximumdirect.net/eric/seriatim.git` | Authoritative source repository |
|
||||
| `seriatim_source_ref` | `{{ seriatim_version }}` | Git tag, branch, or commit to check out |
|
||||
| `seriatim_build_version` | `{{ seriatim_version }}` | Value injected into Seriatim build metadata |
|
||||
| `seriatim_source_dir` | `/usr/local/src/seriatim` | Fully managed source checkout |
|
||||
| `seriatim_binary_path` | `/usr/local/bin/seriatim` | Installed executable |
|
||||
| `seriatim_build_state_dir` | `/usr/local/src/seriatim.ansible-build-state` | Sidecar build inputs, fingerprint, and checksum |
|
||||
| `seriatim_manage_build_dependencies` | `true` | Whether the role installs Git and Go |
|
||||
| `seriatim_go_snap_channel` | `1.26/stable` | Go Snap channel |
|
||||
| `seriatim_go_binary` | `/snap/bin/go` | Go executable used for version discovery and builds |
|
||||
| `seriatim_go_build_flags` | `[-trimpath]` | Ordered arguments passed before `-ldflags` |
|
||||
| `seriatim_go_ldflags` | upstream release linker flags using `seriatim_build_version` | Linker argument passed as one value |
|
||||
| `seriatim_go_package` | `./cmd/seriatim` | Package built from the checkout |
|
||||
|
||||
`seriatim_source_ref` and `seriatim_build_version` are deliberately distinct.
|
||||
A development branch or commit override must set an honest build-version value
|
||||
as well as the source ref. Fixed build environment values are not public
|
||||
overrides: `GOWORK=off`, `GOTOOLCHAIN=local`, and `CGO_ENABLED=0`.
|
||||
|
||||
## Stage 1: Establish the Role Contract and Static Validation
|
||||
|
||||
Completed: `ac35c1f` (`feat: define Seriatim role contract`)
|
||||
|
||||
### Objective
|
||||
|
||||
Create a conventional role skeleton with a fully specified variable contract,
|
||||
argument validation, platform guards, dependency manifest, and syntax-test
|
||||
entry point, without installing application state yet.
|
||||
|
||||
### Preconditions
|
||||
|
||||
- `ansible-role-seriatim` is clean on `main` and tracks `origin/main`.
|
||||
- The workspace virtual environment passes
|
||||
`../.venv/bin/ansible-playbook --version`.
|
||||
- The feature roadmap and Fixed Role Interface above have no unresolved
|
||||
conflicts.
|
||||
|
||||
### Owning Repository
|
||||
|
||||
`ansible-role-seriatim`
|
||||
|
||||
### Required Changes
|
||||
|
||||
1. Add the standard role paths `defaults/`, `meta/`, `tasks/`, `tests/`, and
|
||||
`collections/`. Use YAML document markers and fully qualified module names.
|
||||
2. Define every variable in the Fixed Role Interface in `defaults/main.yml`.
|
||||
Do not expose aliases, compatibility variables, removal controls, or
|
||||
configuration-file settings.
|
||||
3. Add `meta/main.yml` with Eric Rakestraw as author, BSD-3-Clause licensing,
|
||||
minimum Ansible Core 2.18, Ubuntu `resolute` platform metadata, source and
|
||||
issue URLs, and tags appropriate to Seriatim and transcript processing.
|
||||
4. Add `meta/argument_specs.yml`. Validate booleans, strings, lists, and paths
|
||||
by type; require nonempty repository/ref/version/build values; and describe
|
||||
every public variable.
|
||||
5. Add `tasks/main.yml` and `tasks/validate.yml`. Run validation before every
|
||||
task that can change the host. Assert:
|
||||
- distribution is Ubuntu;
|
||||
- distribution version is `26.04`;
|
||||
- architecture is `x86_64` or `aarch64`;
|
||||
- source, binary, and state paths are absolute and pairwise distinct;
|
||||
- repository, source ref, build version, Go binary, build flags, linker
|
||||
flags, and package are nonempty;
|
||||
- build version contains no whitespace.
|
||||
6. Pin `community.general` version `13.3.0` in
|
||||
`collections/requirements.yml`. This collection requires Ansible Core 2.18
|
||||
or newer and supplies the channel-aware `community.general.snap` module.
|
||||
7. Extend `.gitignore` only for repository-local validation state, including
|
||||
`.ansible/`, test output, and retry files. Preserve the existing general
|
||||
ignore entries.
|
||||
8. Add `tests/inventory` targeting localhost with local connection and an
|
||||
explicit `/usr/bin/python3.14` interpreter. Add `tests/converge.yml` that
|
||||
gathers facts, enables privilege escalation, and applies the repository
|
||||
role through `ANSIBLE_ROLES_PATH`.
|
||||
9. Replace the placeholder README with the role purpose, supported platform,
|
||||
dependency-installation command, complete variable table, development-ref
|
||||
rule, and an explicit statement that this stage does not yet install a
|
||||
binary.
|
||||
|
||||
### Validation
|
||||
|
||||
From `ansible-role-seriatim`, run:
|
||||
|
||||
```sh
|
||||
../.venv/bin/ansible-galaxy collection install \
|
||||
-p .ansible/collections -r collections/requirements.yml
|
||||
ANSIBLE_COLLECTIONS_PATH="$PWD/.ansible/collections" \
|
||||
../.venv/bin/ansible-playbook -i tests/inventory tests/converge.yml \
|
||||
--syntax-check
|
||||
ANSIBLE_COLLECTIONS_PATH="$PWD/.ansible/collections" \
|
||||
../.venv/bin/ansible-lint .
|
||||
git diff --check
|
||||
```
|
||||
|
||||
Expected result: `community.general` 13.3.0 is installed under the ignored
|
||||
repository-local path, the test playbook passes syntax checking, ansible-lint
|
||||
reports no violations, and Git reports no whitespace errors. Do not run the
|
||||
converge playbook without `--syntax-check` during this stage.
|
||||
|
||||
### Completion Criteria
|
||||
|
||||
- The public defaults exactly match the Fixed Role Interface.
|
||||
- Invalid platform and malformed-variable paths fail before host mutation.
|
||||
- Static validation passes with the pinned collection available locally.
|
||||
- Only `ansible-role-seriatim` contains implementation changes.
|
||||
|
||||
### Commit
|
||||
|
||||
Commit intent: `feat: define Seriatim role contract`
|
||||
|
||||
## Stage 2: Manage Build Dependencies and the Source Checkout
|
||||
|
||||
Completed: `b84b045` (`feat: manage Seriatim source prerequisites`)
|
||||
|
||||
### Objective
|
||||
|
||||
Implement idempotent Git and Go prerequisite management and converge the
|
||||
root-owned Seriatim checkout to the selected source revision, without building
|
||||
or installing the application binary yet.
|
||||
|
||||
### Preconditions
|
||||
|
||||
- Stage 1 is committed and its validation still passes.
|
||||
- `snap info go` shows the configured `1.26/stable` channel.
|
||||
- No unmanaged data that must be retained exists under the configured source
|
||||
directory; that tree is deliberately authoritative and disposable.
|
||||
|
||||
### Owning Repository
|
||||
|
||||
`ansible-role-seriatim`
|
||||
|
||||
### Required Changes
|
||||
|
||||
1. Add `tasks/dependencies.yml` and include it after validation.
|
||||
2. When `seriatim_manage_build_dependencies` is true:
|
||||
- install the Ubuntu `git` package with `ansible.builtin.apt`, using a
|
||||
reasonable cache-validity interval rather than refreshing on every run;
|
||||
- install the single `go` Snap through `community.general.snap` with
|
||||
`classic: true`, `channel: "{{ seriatim_go_snap_channel }}"`, and
|
||||
`state: present`.
|
||||
3. Whether dependency management is enabled or disabled, resolve Git and the
|
||||
configured Go executable and fail clearly if either is unavailable. Run
|
||||
`go version`, extract its semantic version, and require Go 1.25 or newer.
|
||||
4. Add `tasks/source.yml` and include it after dependencies. Create the parent
|
||||
source directory as `root:root` before cloning.
|
||||
5. Use `ansible.builtin.git` with the configured repository and source ref,
|
||||
`update: true`, `force: true`, and no shallow-clone assumption. Do not accept
|
||||
host keys automatically and do not embed credentials.
|
||||
6. Make the checkout fully managed: detect tracked or untracked dirt after the
|
||||
Git task, reset tracked files to the selected checkout, and remove untracked
|
||||
and ignored content with explicit Git commands only when dirt exists. Keep
|
||||
the build-state sidecar outside the checkout so cleanup cannot remove it.
|
||||
7. Enforce root ownership on the checkout and resolve the final commit with
|
||||
`git rev-parse HEAD`. Assert that the default `v1.5.0` execution resolves to
|
||||
`0fc92f364316c874d366b00cdc884a33e1900b25` in the local integration test;
|
||||
nondefault refs record their actual resolved commit without that assertion.
|
||||
8. Update the README to describe dependency opt-out behavior, channel
|
||||
convergence, authoritative checkout cleanup, and requirements for private
|
||||
repository authentication overrides without documenting any credentials.
|
||||
|
||||
### Validation
|
||||
|
||||
Run the Stage 1 static commands, then run:
|
||||
|
||||
```sh
|
||||
ANSIBLE_COLLECTIONS_PATH="$PWD/.ansible/collections" \
|
||||
ANSIBLE_ROLES_PATH="$(dirname "$PWD")" \
|
||||
../.venv/bin/ansible-playbook -i tests/inventory tests/converge.yml
|
||||
/snap/bin/go version
|
||||
sudo git -C /usr/local/src/seriatim rev-parse HEAD
|
||||
sudo test "$(stat -c '%U:%G' /usr/local/src/seriatim)" = root:root
|
||||
```
|
||||
|
||||
Expected result: the play completes successfully without creating
|
||||
`/usr/local/bin/seriatim`; Go is on the `1.26/stable` track and satisfies the
|
||||
minimum version; the checkout resolves to the expected `v1.5.0` commit; and its
|
||||
root directory is owned by `root:root`.
|
||||
|
||||
Create an untracked file and a tracked-file modification beneath the checkout,
|
||||
rerun convergence, and verify both are removed. Run convergence once more and
|
||||
require `changed=0` in the play recap.
|
||||
|
||||
### Completion Criteria
|
||||
|
||||
- Dependency management and opt-out behavior fail or converge as specified.
|
||||
- Go channel and minimum-version validation are explicit and idempotent.
|
||||
- Default source state is the expected clean, root-owned commit.
|
||||
- Unmanaged checkout changes are discarded by a subsequent role run.
|
||||
- A clean repeated run reports no changes.
|
||||
|
||||
### Commit
|
||||
|
||||
Commit intent: `feat: manage Seriatim source prerequisites`
|
||||
|
||||
## Stage 3: Build and Install Seriatim Reproducibly
|
||||
|
||||
Completed: `81313f0` (`feat: build and install Seriatim from source`)
|
||||
|
||||
### Objective
|
||||
|
||||
Add fingerprint-driven source compilation, staged validation, atomic binary
|
||||
installation, and durable build-state recording without replacing a working
|
||||
binary after a failed build.
|
||||
|
||||
### Preconditions
|
||||
|
||||
- Stage 2 is committed and its clean repeated convergence reports no changes.
|
||||
- The default checkout is the expected `v1.5.0` commit.
|
||||
- `/snap/bin/go version` reports a toolchain compatible with the upstream
|
||||
module requirement.
|
||||
|
||||
### Owning Repository
|
||||
|
||||
`ansible-role-seriatim`
|
||||
|
||||
### Required Changes
|
||||
|
||||
1. Add `tasks/build.yml` after source convergence.
|
||||
2. Construct one canonical build-input document containing at least:
|
||||
- resolved source commit;
|
||||
- complete `go version` output;
|
||||
- configured Go binary path;
|
||||
- build version;
|
||||
- ordered build flags;
|
||||
- linker flags;
|
||||
- package path;
|
||||
- fixed `GOWORK`, `GOTOOLCHAIN`, and `CGO_ENABLED` values.
|
||||
Store the readable input document and its SHA-256 fingerprint in
|
||||
`seriatim_build_state_dir` only after successful installation.
|
||||
3. Record the installed binary's SHA-256 checksum beside the fingerprint.
|
||||
Require a rebuild when the binary, any state file, or the checkout is
|
||||
missing; when the desired fingerprint differs; when the installed checksum
|
||||
differs; or when the installed version command fails or differs from
|
||||
`seriatim version {{ seriatim_build_version }}`. Malformed or unreadable
|
||||
state must cause a rebuild rather than an unhandled template failure.
|
||||
4. When no rebuild is required, perform no mutating build or install task and
|
||||
report no change.
|
||||
5. When rebuilding, create a unique temporary directory with
|
||||
`ansible.builtin.tempfile`. Invoke the configured Go binary with
|
||||
`ansible.builtin.command` `argv`, the fixed environment, configured build
|
||||
flags, one `-ldflags` value, a staged output path, and the configured package
|
||||
from `seriatim_source_dir`.
|
||||
6. Validate the staged binary before installation. Require exact stdout
|
||||
`seriatim version {{ seriatim_build_version }}` and a successful exit from
|
||||
`--version`.
|
||||
7. Install the validated staged binary to `seriatim_binary_path` using an
|
||||
atomic Ansible file operation with `root:root` ownership and mode `0755`.
|
||||
Validate the installed binary again, calculate its checksum, and only then
|
||||
write the build-input, fingerprint, and checksum state files.
|
||||
8. Use an `always` cleanup path so temporary build content is removed after
|
||||
success or failure. Never delete or overwrite the previously installed
|
||||
binary or successful build state before a replacement has passed staged
|
||||
validation.
|
||||
9. Give command tasks precise `changed_when` and `failed_when` behavior so
|
||||
ansible-lint passes and check/reporting semantics are honest.
|
||||
10. Update the README with the exact build contract, rebuild triggers, state
|
||||
location, ownership, safe replacement behavior, and development override
|
||||
example setting both `seriatim_source_ref` and
|
||||
`seriatim_build_version`.
|
||||
|
||||
### Validation
|
||||
|
||||
Run static validation, then converge and inspect:
|
||||
|
||||
```sh
|
||||
ANSIBLE_COLLECTIONS_PATH="$PWD/.ansible/collections" \
|
||||
ANSIBLE_ROLES_PATH="$(dirname "$PWD")" \
|
||||
../.venv/bin/ansible-playbook -i tests/inventory tests/converge.yml
|
||||
/usr/local/bin/seriatim --version
|
||||
sudo stat -c '%U:%G %a' /usr/local/bin/seriatim
|
||||
sudo find /usr/local/src/seriatim.ansible-build-state \
|
||||
-maxdepth 1 -type f -print -exec sed -n '1,80p' {} \;
|
||||
```
|
||||
|
||||
Expected result: the command prints exactly `seriatim version v1.5.0`; the
|
||||
binary is `root:root` mode `755`; readable build inputs, fingerprint, and
|
||||
checksum exist in the sidecar state directory; and no temporary staging
|
||||
directory remains.
|
||||
|
||||
Run the same convergence immediately again and require `changed=0`. Then change
|
||||
one effective build flag through an extra variable, run convergence, and
|
||||
require the build/install tasks to report changes. Repeat with that override
|
||||
and require `changed=0`; finally restore defaults and require exactly one more
|
||||
rebuild followed by a clean repeat.
|
||||
|
||||
### Completion Criteria
|
||||
|
||||
- The installed binary matches the upstream version and ownership contract.
|
||||
- Build state records every required input and the installed checksum.
|
||||
- Missing, corrupt, or changed binary/state/input conditions rebuild.
|
||||
- Unchanged convergence reports no changes.
|
||||
- Temporary content is cleaned on both successful and failed task paths.
|
||||
- Static validation remains clean.
|
||||
|
||||
### Commit
|
||||
|
||||
Commit intent: `feat: build and install Seriatim from source`
|
||||
|
||||
## Stage 4: Add Local Integration Regression Coverage
|
||||
|
||||
Completed: `efd4734` (`test: verify Seriatim source installation`)
|
||||
|
||||
### Objective
|
||||
|
||||
Turn the required local validation into a repeatable, failure-safe repository
|
||||
test harness and complete the role's operator and maintainer documentation.
|
||||
|
||||
### Preconditions
|
||||
|
||||
- Stage 3 is committed, statically clean, and manually converges twice with the
|
||||
second run reporting no changes.
|
||||
- The default installed binary and build state are known-good before testing
|
||||
deliberate failure paths.
|
||||
- No unrelated local host data exists at the managed Seriatim paths.
|
||||
|
||||
### Owning Repository
|
||||
|
||||
`ansible-role-seriatim`
|
||||
|
||||
### Required Changes
|
||||
|
||||
1. Add `tests/verify.yml` with nonmutating assertions for:
|
||||
- supported platform facts;
|
||||
- source commit and cleanliness;
|
||||
- source, binary, and state ownership;
|
||||
- binary mode;
|
||||
- exact installed version output;
|
||||
- presence and consistency of build inputs, fingerprint, and installed
|
||||
checksum.
|
||||
2. Add an executable `tests/integration` shell driver that locates the
|
||||
workspace virtual environment relative to the repository, installs the
|
||||
pinned collection into `.ansible/collections`, exports local collection and
|
||||
role paths, and runs syntax checking plus ansible-lint before host mutation.
|
||||
3. Have the driver run default convergence, verification, and an immediate
|
||||
second convergence. Parse the second recap and fail unless `changed=0` and
|
||||
`failed=0`.
|
||||
4. Test the mutation guard with separate plays that override gathered facts to
|
||||
represent an unsupported distribution, Ubuntu release, and architecture.
|
||||
Each play must fail in validation before a mutating task; capture the
|
||||
installed binary checksum and successful state beforehand and require both
|
||||
to remain unchanged afterward.
|
||||
5. Test source authority by creating both a tracked modification and an
|
||||
untracked file in the managed checkout, converging, and verifying a clean
|
||||
checkout at the expected commit.
|
||||
6. Test compiler-input invalidation with a temporary Go wrapper. Its `version`
|
||||
path must report a distinct valid Go 1.26 patch identity while all other
|
||||
commands delegate to `/snap/bin/go`. Converge with
|
||||
`seriatim_go_binary` set to the wrapper, require a rebuild, repeat and
|
||||
require idempotence, then restore the default Go path and require one final
|
||||
rebuild followed by idempotence.
|
||||
7. Test failure preservation with a second temporary Go wrapper that reports a
|
||||
valid version but fails the build invocation. Capture the installed binary
|
||||
checksum and successful state files before the expected failed play. After
|
||||
failure, require the binary checksum and state contents to be byte-for-byte
|
||||
unchanged and require `seriatim --version` still to report `v1.5.0`.
|
||||
8. Use a temporary directory and cleanup trap for wrappers and captured test
|
||||
output. The driver must restore default role convergence before exit where
|
||||
possible and must never delete unrelated host content.
|
||||
9. Update the README with development-environment setup, static validation,
|
||||
local integration warnings, the single test-driver command, expected host
|
||||
mutations, and recovery instructions limited to rerunning default
|
||||
convergence.
|
||||
10. Remove any Stage 1 wording that says installation is not implemented.
|
||||
|
||||
### Validation
|
||||
|
||||
From `ansible-role-seriatim`, run:
|
||||
|
||||
```sh
|
||||
tests/integration
|
||||
git diff --check
|
||||
git status --short
|
||||
```
|
||||
|
||||
Expected result: the driver completes every static, convergence, idempotence,
|
||||
source-cleanup, compiler-change, failure-preservation, and final verification
|
||||
case; the installed host state ends at default Seriatim `v1.5.0`; Git reports
|
||||
no whitespace errors; and only intended repository changes are present before
|
||||
the stage commit.
|
||||
|
||||
After committing, run `tests/integration` once more. The repository must remain
|
||||
clean afterward.
|
||||
|
||||
### Completion Criteria
|
||||
|
||||
- One documented command reproduces all MVP validation on the local Ubuntu
|
||||
26.04 proxy.
|
||||
- Idempotence, compiler-version invalidation, managed-source cleanup, exact
|
||||
versioning, and failed-build preservation have executable regression
|
||||
coverage.
|
||||
- README instructions match the implemented role and test behavior.
|
||||
- The post-commit integration run passes and leaves the role repository clean.
|
||||
|
||||
### Commit
|
||||
|
||||
Commit intent: `test: verify Seriatim source installation`
|
||||
|
||||
## Final Validation and Handoff
|
||||
|
||||
After Stage 4, run:
|
||||
|
||||
```sh
|
||||
tests/integration
|
||||
git log --oneline -4
|
||||
git status --short --branch
|
||||
cd ..
|
||||
./scripts/status
|
||||
```
|
||||
|
||||
The implementation handoff must report:
|
||||
|
||||
- the four stage commit hashes in order;
|
||||
- the final `seriatim --version` output;
|
||||
- the final source commit, Go version, binary checksum, ownership, and mode;
|
||||
- the clean-repeat recap showing `changed=0` and `failed=0`;
|
||||
- confirmation that deliberate build failure preserved the prior binary and
|
||||
state;
|
||||
- every deviation from this plan or feature roadmap;
|
||||
- any unresolved findings or recommended follow-up work.
|
||||
|
||||
Do not mark Feature 0001 `done` and do not edit workspace status during the
|
||||
out-of-band execution. Completion requires subsequent review.
|
||||
|
||||
## Progress Notes
|
||||
|
||||
- Stage 1 completed in `ansible-role-seriatim` commit `ac35c1f`.
|
||||
- Stage 2 completed in `ansible-role-seriatim` commit `b84b045`.
|
||||
- Stage 3 completed in `ansible-role-seriatim` commit `81313f0`.
|
||||
- Stage 4 completed in `ansible-role-seriatim` commit `efd4734`.
|
||||
The prior Audita plan was withdrawn because it propagated the superseded
|
||||
Seriatim build-state and hardening architecture. Git history preserves that
|
||||
research, but those execution instructions must not be used.
|
||||
|
||||
@@ -50,17 +50,21 @@ role will manage the native configuration needed to connect to it.
|
||||
- Released roles build an explicitly selected application release tag.
|
||||
Development may override the selected revision with a branch or commit.
|
||||
- Source checkouts reside at `/usr/local/src/<app>` and are owned by `root`.
|
||||
- Roles build into a staging location, validate the result, and then install
|
||||
the binary at `/usr/local/bin/<app>` with `root:root` ownership and mode
|
||||
`0755`. A failed build must not replace a working installed binary.
|
||||
- Roles build and install the binary at `/usr/local/bin/<app>` with
|
||||
`root:root` ownership and mode `0755`, using the application's native build
|
||||
command and the simplest clear Ansible task flow.
|
||||
- Builds use the application repository's own build contract, including any
|
||||
application-specific version-injection linker flags. The common baseline is
|
||||
`GOWORK=off`, `GOTOOLCHAIN=local`, `CGO_ENABLED=0`, and `-trimpath`.
|
||||
- Build state must account for the checked-out commit, Go toolchain, and build
|
||||
arguments so that roles rebuild when a relevant input changes rather than
|
||||
relying only on the existence of the installed binary.
|
||||
- Each application role exposes variables for its repository, selected
|
||||
version or revision, source directory, binary path, and build settings.
|
||||
- Roles normally rebuild when the Git task reports a changed checkout, the
|
||||
binary is absent, or an application-level version or smoke check shows that
|
||||
the installed binary is unsuitable. They do not maintain fingerprints,
|
||||
checksums, or sidecar build-state files for the MVP.
|
||||
- Each application role exposes variables only for meaningful consumer
|
||||
choices, normally including its repository, selected version or revision,
|
||||
source directory, binary path, dependency management, and Go Snap channel.
|
||||
Fixed details of the upstream build contract need not become public
|
||||
variables.
|
||||
|
||||
### Go toolchain
|
||||
|
||||
@@ -131,6 +135,13 @@ application-role releases in one source repository.
|
||||
- Small amounts of repeated prerequisite or installation logic are acceptable
|
||||
during the MVP. A shared helper role or collection plugin should be
|
||||
introduced only if substantial, stable shared behavior emerges.
|
||||
- Ansible modules are trusted to implement their documented state transitions,
|
||||
idempotence, and change detection. Roles do not add preliminary existence
|
||||
checks, manual comparisons, or supplemental state around a module that
|
||||
already owns the desired behavior.
|
||||
- State gathering is appropriate only when it controls behavior outside the
|
||||
responsible module's contract, such as deciding whether an application
|
||||
binary must be rebuilt.
|
||||
|
||||
### Dependency and release reproducibility
|
||||
|
||||
@@ -213,6 +224,12 @@ remain to be designed.
|
||||
- Deploying or managing WhisperX
|
||||
- Versioned Narratio prompt-library releases and pinning
|
||||
- A role-managed scheduler or persistent Narratio service
|
||||
- Cryptographic artifact verification, supply-chain hardening, and protection
|
||||
against adversarial source or dependency infrastructure
|
||||
- Transactional binary replacement and preservation of the prior executable
|
||||
after a local build failure
|
||||
- Compiler-identity fingerprints, binary checksums, sidecar build-state files,
|
||||
and recovery from deliberately malformed or redirected managed paths
|
||||
|
||||
## Design Work Still Open
|
||||
|
||||
|
||||
@@ -1,174 +1,19 @@
|
||||
# Feature 0001 Remediation Findings
|
||||
# Feature 0001 Prior Remediation Record
|
||||
|
||||
Status: resolved
|
||||
Historical record: superseded
|
||||
|
||||
## Review Scope
|
||||
The original Feature 0001 review required increasingly elaborate recovery for
|
||||
build-state files, metadata drift, custom path shapes, and symbolic links.
|
||||
Those findings were resolved in `ansible-role-seriatim` commits `c6c1907`
|
||||
through `6fb1aa2`, but the resulting architecture was later rejected as
|
||||
disproportionate to the MVP.
|
||||
|
||||
This review compared `ansible-role-seriatim` commits `ac35c1f` through
|
||||
`efd4734` with the Feature 0001 roadmap and staged implementation plan. It also
|
||||
ran the committed static and integration validation and performed targeted
|
||||
state-corruption, permission-drift, and custom-path checks on the managed local
|
||||
installation.
|
||||
The authoritative replacement specification is
|
||||
`docs/roadmap/features/0001-seriatim-source-installation.md`. It deliberately
|
||||
removes persistent build state and treats unusual corruption, adversarial path
|
||||
redirection, exact compiler-input tracking, and transactional replacement as
|
||||
potential future hardening rather than current requirements.
|
||||
|
||||
The four planned implementation stages are structurally present and the
|
||||
committed integration suite passes. The findings below are gaps that must be
|
||||
addressed before Feature 0001 is marked complete or its patterns are copied to
|
||||
other application roles.
|
||||
|
||||
## Finding 1: Build-input state content is not part of convergence
|
||||
|
||||
Severity: high
|
||||
|
||||
`tasks/build.yml` checks whether `build-inputs.json` exists but never reads or
|
||||
compares its content. The rebuild decision trusts `fingerprint.sha256`
|
||||
independently. An empty, corrupted, stale, or replaced build-input document is
|
||||
therefore accepted as converged when the fingerprint and binary checksum files
|
||||
remain unchanged.
|
||||
|
||||
This diverges from the plan's requirement that malformed or unreadable state
|
||||
cause a rebuild and from the role's claim that readable inputs and their
|
||||
fingerprint describe the installed result. A targeted test truncated
|
||||
`build-inputs.json`; convergence returned `changed=0` and `failed=0`, while the
|
||||
subsequent verification play correctly failed its input/fingerprint assertion.
|
||||
|
||||
Required remediation:
|
||||
|
||||
- Read the stored build-input document safely during convergence.
|
||||
- Require its exact canonical content to match the desired build inputs and
|
||||
require its SHA-256 digest to match the stored and desired fingerprint.
|
||||
- Treat missing, unreadable, malformed, or inconsistent input state as a
|
||||
rebuild condition rather than an unhandled failure.
|
||||
- Extend `tests/integration` to corrupt or replace `build-inputs.json`, verify
|
||||
that convergence repairs it, and verify that the following run is
|
||||
idempotent.
|
||||
|
||||
## Finding 2: Managed ownership and modes drift without repair
|
||||
|
||||
Severity: medium
|
||||
|
||||
The binary's checksum and version participate in the rebuild decision, but its
|
||||
owner, group, and mode do not. Binary metadata is set only inside the rebuild
|
||||
block. Build-state directory and file metadata are likewise set only after a
|
||||
build. A content-identical installation can therefore remain in an unsafe or
|
||||
incorrect metadata state indefinitely.
|
||||
|
||||
A targeted test changed `/usr/local/bin/seriatim` from mode `0755` to `0777`.
|
||||
Convergence returned `changed=0` and left mode `0777` in place. This violates
|
||||
the target state requiring a root-owned, non-operator-writable binary. The same
|
||||
design leaves drifted state-file ownership and permissions uncorrected.
|
||||
|
||||
Required remediation:
|
||||
|
||||
- Converge `seriatim_binary_path` to `root:root` mode `0755` whenever a valid
|
||||
installed regular file exists, without forcing an unnecessary rebuild.
|
||||
- Converge `seriatim_build_state_dir` to `root:root` mode `0755` and its three
|
||||
managed files to `root:root` mode `0644` on every successful role run.
|
||||
- Treat unexpected file types, including a directory at the binary path, as a
|
||||
clear validation or repair condition rather than passing them into the build
|
||||
copy operation.
|
||||
- Add integration cases that drift binary and build-state metadata, require
|
||||
one repairing run, and require an idempotent repeat.
|
||||
|
||||
## Finding 3: A configurable binary path requires a pre-existing parent
|
||||
|
||||
Severity: medium
|
||||
|
||||
`seriatim_binary_path` is a documented public path override, but the role does
|
||||
not create or validate its parent directory. `ansible.builtin.copy` consequently
|
||||
fails after a successful build when the configured parent is absent. A
|
||||
targeted run using `/tmp/seriatim-review-missing-parent/seriatim` failed with
|
||||
`Destination directory ... does not exist`.
|
||||
|
||||
Required remediation:
|
||||
|
||||
- Inspect the configured binary parent before building.
|
||||
- Fail clearly if an existing parent is not a directory.
|
||||
- Create a missing parent as `root:root` mode `0755` without changing ownership
|
||||
or mode on an already existing shared directory.
|
||||
- Add an isolated integration case proving that a nondefault binary path with
|
||||
a missing parent installs, validates, and converges idempotently.
|
||||
|
||||
## Finding 4: Role metadata and privilege documentation are incomplete
|
||||
|
||||
Severity: low
|
||||
|
||||
Stage 1 required role source and issue information, but `meta/main.yml` omits
|
||||
the supported `issue_tracker_url` field. The README also does not state plainly
|
||||
that consumers must apply the role with privilege escalation, even though it
|
||||
manages packages, snaps, root-owned source, and `/usr/local/bin`.
|
||||
|
||||
Required remediation:
|
||||
|
||||
- Add the role repository's Gitea issue tracker to `meta/main.yml`.
|
||||
- Add role repository and issue links to the README where appropriate.
|
||||
- State explicitly that the consuming play must use `become: true` or provide
|
||||
equivalent root privileges.
|
||||
- Re-run metadata/schema validation and ansible-lint.
|
||||
|
||||
## Remediation Completion Criteria
|
||||
|
||||
- All four findings are addressed in `ansible-role-seriatim`.
|
||||
- Static validation and the expanded `tests/integration` suite pass.
|
||||
- Targeted corruption, metadata-drift, and alternate-path cases converge to
|
||||
the documented state and then report `changed=0` on an immediate repeat.
|
||||
- The default local installation ends at Seriatim `v1.5.0`, source commit
|
||||
`0fc92f364316c874d366b00cdc884a33e1900b25`, with a clean checkout and
|
||||
consistent build state.
|
||||
- The role and workspace repositories are clean, and remediation commits are
|
||||
ready for review before Feature 0001 is marked complete.
|
||||
|
||||
## Resolution Evidence
|
||||
|
||||
- Finding 1 was resolved by `ansible-role-seriatim` commit `c6c1907`.
|
||||
- Finding 2 was resolved by `ansible-role-seriatim` commit `f2c1b1a`.
|
||||
- Finding 3 was resolved by `ansible-role-seriatim` commit `92906eb`.
|
||||
- Finding 4 was resolved by `ansible-role-seriatim` commit `07dd736`.
|
||||
- Malformed state-object recovery was hardened by
|
||||
`ansible-role-seriatim` commit `ca49dae` during the completion audit.
|
||||
- The expanded `tests/integration` suite passed after all remediation commits
|
||||
and restored the default Seriatim installation.
|
||||
|
||||
## Completion Review
|
||||
|
||||
The four original findings are resolved, and the expanded integration suite
|
||||
passes. A focused review of the malformed-state recovery identified one
|
||||
additional edge case, which has also been resolved.
|
||||
|
||||
## Finding 5: A malformed build-state directory is not handled
|
||||
|
||||
Severity: medium
|
||||
|
||||
`tasks/build.yml` inspects the three state files beneath
|
||||
`seriatim_build_state_dir` without first inspecting the state-directory path.
|
||||
If that configured path exists as a regular file, the first
|
||||
`ansible.builtin.stat` fails with `Not a directory`. This is an unhandled
|
||||
malformed-state failure rather than the planned recovery behavior. A targeted
|
||||
run with an otherwise valid custom binary confirmed that the role exits before
|
||||
rebuilding or converging the state directory. A second targeted run using a
|
||||
symbolic link as the state-directory path succeeded and wrote all three
|
||||
root-owned state files into the link target while leaving the configured path
|
||||
as a symbolic link.
|
||||
|
||||
Required remediation:
|
||||
|
||||
- Inspect `seriatim_build_state_dir` before inspecting any child state path.
|
||||
- Define and implement deliberate behavior for an existing non-directory
|
||||
object. Because the state directory is fully managed, replacing that object
|
||||
and rebuilding is consistent with the existing malformed-state-file
|
||||
behavior; alternatively, fail with a purpose-written assertion if preserving
|
||||
an unexpected object is preferred.
|
||||
- Ensure an existing symbolic link is not silently treated as the managed
|
||||
state directory or used to redirect root-owned state writes.
|
||||
- Add integration coverage for the selected non-directory behavior and require
|
||||
an idempotent immediate repeat after recovery when recovery is supported.
|
||||
|
||||
Resolution:
|
||||
|
||||
- `ansible-role-seriatim` commit `6fb1aa2` makes the build-state directory
|
||||
authoritative, replacing regular files and symbolic links with a root-owned
|
||||
directory before inspecting child state.
|
||||
- Integration coverage confirms repair and immediate idempotence for both
|
||||
regular-file and symbolic-link drift, and confirms that the symbolic-link
|
||||
target remains untouched.
|
||||
- The complete integration suite passes and restores a verified default
|
||||
installation.
|
||||
This file is retained only to explain the historical commit sequence. It is
|
||||
not an active remediation specification and must not be used as a template for
|
||||
another role.
|
||||
|
||||
@@ -4,7 +4,8 @@ Last updated: 2026-09-07
|
||||
|
||||
Current milestone: MVP standalone application roles
|
||||
|
||||
Current focus: Select the next standalone application-role feature.
|
||||
Current focus: Review the revised Feature 0001 specification and prepare a
|
||||
minimal Seriatim simplification plan.
|
||||
|
||||
| ID | Deliverable | Owner | State | Evidence or next step |
|
||||
| --- | --- | --- | --- | --- |
|
||||
@@ -13,11 +14,12 @@ Current focus: Select the next standalone application-role feature.
|
||||
| M0-03 | Tracked MVP roadmap | workspace | done | `docs/roadmap/mvp.md` established |
|
||||
| M0-04 | Aggregate repository status | workspace | done | `scripts/status` created |
|
||||
| M0-05 | Suite-level role repository | ansible-role-dnd-pipeline | done | Repository created and added to `workspace.yml` |
|
||||
| M1-01 | Remaining MVP design decisions | workspace | ready | Select the next item from the roadmap |
|
||||
| M1-02 | Standalone application roles | role repositories | in_progress | Seriatim complete; select the next application role |
|
||||
| M1-01 | Remaining MVP design decisions | workspace | ready | Resume after the revised Seriatim pattern is accepted |
|
||||
| M1-02 | Standalone application roles | role repositories | in_progress | Simplify Seriatim before continuing to other roles |
|
||||
| M1-03 | Suite-level pipeline role | ansible-role-dnd-pipeline | proposed | Begin after standalone role interfaces stabilize |
|
||||
| M1-04 | Collection assembly | ansible-collection-dnd | proposed | Select and implement the pipeline-role incorporation mechanism |
|
||||
| F0001 | Install Seriatim from pinned source | ansible-role-seriatim | done | Role commit `6fb1aa2`; feature and remediation acceptance checks pass |
|
||||
| F0001 | Install Seriatim from pinned source | ansible-role-seriatim | ready | Revised roadmap ready; staged simplification plan is next |
|
||||
| F0002 | Install and configure Audita | ansible-role-audita | proposed | Replan after the simplified Seriatim role is reviewed |
|
||||
|
||||
## Updating This File
|
||||
|
||||
|
||||
Reference in New Issue
Block a user