Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
with:
persist-credentials: false
- name: Setup Rust
uses: leynos/shared-actions/.github/actions/setup-rust@73f02134f6f1c2335326d1b9cdefaddd287bf23e
- name: Format
Expand All @@ -32,11 +34,10 @@ jobs:
**/*.md
!**/target/**
!**/dist/**
- name: Setup uv
uses: astral-sh/setup-uv@12d13f90bc3a5a1971bebad4beb09a4dfa962e91
- name: Install interrogate
run: |
python -m pip install --user uv==0.11.19
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
"$HOME/.local/bin/uv" tool install interrogate==1.7.0
run: uv tool install interrogate==1.7.0
- name: Lint
run: make lint
- name: Install cargo-nextest
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ project:
### Dependency Management

- **Mandate caret requirements for all dependencies.** All crate versions
specified in `Cargo.toml` must use SemVer-compatible caret requirements
(e.g., `some-crate = "1.2.3"`). This is Cargo's default and allows for safe,
specified in `Cargo.toml` must use SemVer-compatible caret requirements (e.g.,
`some-crate = "1.2.3"`). This is Cargo's default and allows for safe,
non-breaking updates to minor and patch versions while preventing breaking
changes from new major versions. This approach is critical for ensuring build
stability and reproducibility.
Expand Down
94 changes: 94 additions & 0 deletions docs/adr-004-enhanced-lint-requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# ADR 004: enhanced lint and formatting requirements

## Status

Accepted on 2026-07-03. The repository imports the shared Rust formatting and
Clippy policy, pins a dated nightly toolchain for unstable rustfmt options, and
adds `interrogate` as a Python docstring-coverage tier in the lint gate.

## Date

2026-07-03.

## Context and problem statement

The project already requires Rust formatting, Rust documentation checks,
Clippy, and tests before changes are accepted. The previous policy left two
gaps:

- Rust formatting and Clippy settings could drift from the shared agent
template used across Leynos Rust projects.
- Python helper files could pass linting even when documentable functions,
fixtures, or test utilities lacked docstrings.

The shared template rustfmt configuration uses unstable rustfmt options, so
adopting it requires a nightly toolchain. Using the floating `nightly` channel
would make formatting results change as upstream nightly builds change.

## Decision drivers

- Keep Rust formatting and Clippy policy aligned with the shared Leynos Rust
agent template.
- Make formatting reproducible by pinning the nightly toolchain to a dated
release.
- Enforce complete Python docstring coverage through an objective gate.
- Keep the new checks inside the existing `make lint` and CI workflow rather
than introducing a parallel contributor process.

## Options considered

### Option A: keep the existing stable formatter and lint policy

Continue using the previous stable rustfmt behaviour and omit Python docstring
coverage checks.

This avoids toolchain churn, but it leaves the repository out of sync with the
shared Rust template and keeps Python documentation coverage subjective.

### Option B: import the template policy and pin nightly rustfmt

Add the template `rustfmt.toml` and Clippy policy, pin `rust-toolchain.toml` to
`nightly-2026-04-25`, and run `interrogate --fail-under 100 .` as the first
`make lint` tier.

This provides reproducible formatting, keeps Rust lint policy aligned with the
template, and makes Python docstring coverage complete and objective. The cost
is that contributors must use the pinned nightly toolchain for formatting.

### Option C: use a floating nightly channel

Adopt the template configuration but set `rust-toolchain.toml` to `nightly`.

This keeps the configuration small, but rustfmt and Clippy results may drift as
nightly changes. That drift makes CI failures harder to reproduce and upgrades
less intentional.

## Decision outcome

Choose Option B.

The repository pins `rust-toolchain.toml` to `nightly-2026-04-25` so unstable
rustfmt features from the imported template remain reproducible. `make lint`
runs these tiers in order:

1. `interrogate --fail-under 100 .` for Python docstring coverage.
2. `cargo doc --workspace --no-deps` with warnings denied.
3. `cargo clippy --all-targets --all-features -- -D warnings`.

CI installs `interrogate==1.7.0` as a uv tool before the lint step, keeping the
docstring-coverage gate pinned with the workflow.

## Consequences

### Positive

- Rust formatting and Clippy policy match the shared Leynos template.
- Nightly rustfmt output is reproducible because the channel is date-pinned.
- Python docstring coverage is enforced at 100% by a dedicated tool.

### Negative

- Contributors need the pinned nightly toolchain for formatting checks.
- New or changed Python helpers must document every documentable node.
- Future rustfmt or Clippy template upgrades require an intentional toolchain
update rather than an implicit nightly drift.
4 changes: 2 additions & 2 deletions docs/complexity-antipatterns-and-refactoring-strategies.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ the number of edges, N is the number of nodes, and P is the number of connected
components (typically 1 for a single program or method).3 A simpler formulation
for a single subroutine is

M = number of decision points + 1, where decision points include constructs
like `if` statements and conditional loops.3
M = number of decision points + 1, where decision points include constructs like
`if` statements and conditional loops.3

Thresholds and Implications:

Expand Down
27 changes: 27 additions & 0 deletions docs/developers-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,33 @@ also runs a Linux matrix for unprivileged and root execution. The root variant
invokes the test suite under `sudo` so root-only privilege paths execute, while
the unprivileged variant continues to collect coverage.

## Lint and formatting toolchain

The repository pins `rust-toolchain.toml` to `nightly-2026-04-25` because the
imported `rustfmt.toml` template uses unstable rustfmt options. Use the
Makefile targets rather than invoking Cargo directly so local checks and CI
exercise the same nightly formatter and Clippy policy:

```sh
make check-fmt
```

Run the complete lint gate before committing changes:

```sh
make lint
```

`make lint` runs three tiers in order, each gating the next:

1. `interrogate --fail-under 100 .` — Python docstring coverage at 100%.
2. `cargo doc --workspace --no-deps` with `RUSTDOCFLAGS` set to deny warnings.
3. `cargo clippy --all-targets --all-features -- -D warnings`.

CI installs the pinned `interrogate==1.7.0` uv tool before running `make lint`.
Keep the Makefile and workflow versions aligned when updating the
docstring-coverage policy.

## Release process

Tagging a release with `v*` triggers `.github/workflows/release.yml`. The
Expand Down
7 changes: 3 additions & 4 deletions docs/execplans/configure-pg-worker-count.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Configure postgres-embedded worker counts at cluster setup

This execution plan (ExecPlan) is a living document. The sections
`Constraints`, `Tolerances`, `Risks`, `Progress`, `Surprises & Discoveries`,
`Decision Log`, and `Outcomes & Retrospective` must be kept up to date as work
proceeds.
This execution plan (ExecPlan) is a living document. The sections `Constraints`,
`Tolerances`, `Risks`, `Progress`, `Surprises & Discoveries`, `Decision Log`,
and `Outcomes & Retrospective` must be kept up to date as work proceeds.

Status: COMPLETE

Expand Down
13 changes: 6 additions & 7 deletions docs/execplans/data-directory-recovery-logic.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Data Directory Recovery Logic for pg_worker

This Execution Plan (ExecPlan) is a living document. The sections
`Constraints`, `Tolerances`, `Risks`, `Progress`, `Surprises & Discoveries`,
`Decision Log`, and `Outcomes & Retrospective` must be kept up to date as work
proceeds.
This Execution Plan (ExecPlan) is a living document. The sections `Constraints`,
`Tolerances`, `Risks`, `Progress`, `Surprises & Discoveries`, `Decision Log`,
and `Outcomes & Retrospective` must be kept up to date as work proceeds.

Status: COMPLETED

Expand Down Expand Up @@ -298,8 +297,8 @@ Validation for Stage C:
Run quality gates to ensure code meets project standards.

1. Run `make test` (equivalent to `cargo test --workspace`)
2. Run `make lint` (equivalent to `cargo clippy --workspace
--all-targets --all-features -- -D warnings`)
2. Run `make lint` (equivalent to
`cargo clippy --workspace --all-targets --all-features -- -D warnings`)
3. Run `make check-fmt` (equivalent to `cargo fmt --workspace -- --check`)

## Concrete Steps
Expand Down Expand Up @@ -330,7 +329,7 @@ Step 2: Remove dead_code expectation

Command: Edit `tests/support/pg_worker.rs` and remove the
`#[expect(dead_code, reason = "variant reserved for future data directory recovery errors")]`
line and the closing `]` from the `WorkerError::DataDirRecovery` variant.
line and the closing `]` from the `WorkerError::DataDirRecovery` variant.

Expected result: No change to behaviour, clippy no longer expects the variant
to be unused.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Refactor worker payload serde via secrecy

This Execution Plan (ExecPlan) is a living document. The sections
`Constraints`, `Tolerances`, `Risks`, `Progress`, `Surprises & Discoveries`,
`Decision Log`, and `Outcomes & Retrospective` must be kept up to date as work
proceeds.
This Execution Plan (ExecPlan) is a living document. The sections `Constraints`,
`Tolerances`, `Risks`, `Progress`, `Surprises & Discoveries`, `Decision Log`,
and `Outcomes & Retrospective` must be kept up to date as work proceeds.

Status: COMPLETE

Expand Down
12 changes: 6 additions & 6 deletions docs/execplans/issue-50-async-support.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Add async API for TestCluster

This Execution Plan (ExecPlan) is a living document. The sections
`Constraints`, `Tolerances`, `Risks`, `Progress`, `Surprises & discoveries`,
`Decision log`, and `Outcomes & retrospective` must be kept up to date as work
proceeds.
This Execution Plan (ExecPlan) is a living document. The sections `Constraints`,
`Tolerances`, `Risks`, `Progress`, `Surprises & discoveries`, `Decision log`,
and `Outcomes & retrospective` must be kept up to date as work proceeds.

Status: COMPLETE

Expand Down Expand Up @@ -190,8 +189,9 @@ Successfully implemented async API for `TestCluster`:
- `src/cluster/runtime.rs` (22 lines) - Builds the single-threaded Tokio
runtime via `build_runtime()`.

- `Cargo.toml` - Line 43: `tokio = { version = "1", features = ["rt", "macros"]
}`. Line 70-77: Feature flags section.
- `Cargo.toml` - Line 43:
`tokio = { version = "1", features = ["rt", "macros"] }`. Line 70-77: Feature
flags section.

### Current architecture

Expand Down
17 changes: 8 additions & 9 deletions docs/execplans/issue-59-make-pg-worker-a-first-class-binary.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Promote pg_worker to first-class binary

This Execution Plan (ExecPlan) is a living document. The sections
`Constraints`, `Tolerances`, `Risks`, `Progress`, `Surprises & discoveries`,
`Decision log`, and `Outcomes & retrospective` must be kept up to date as work
proceeds.
This Execution Plan (ExecPlan) is a living document. The sections `Constraints`,
`Tolerances`, `Risks`, `Progress`, `Surprises & discoveries`, `Decision log`,
and `Outcomes & retrospective` must be kept up to date as work proceeds.

Status: COMPLETED

Expand Down Expand Up @@ -110,7 +109,7 @@ After this change:
`CapabilityTempDir` are only used in test code (under `tests/`), which
documentation builds don't see. Solution: Add
`#[cfg(any(doc, test, feature = "cluster-unit-tests", feature = "dev-worker"))]`
attributes to align with how they're exported in `mod.rs`.
attributes to align with how they're exported in `mod.rs`.

## Decision log

Expand Down Expand Up @@ -714,10 +713,10 @@ These are independent and serve different purposes:

*Table 1: Discovery mechanisms by context.*

| Context | Discovery mechanism | Purpose |
| ---------- | ------------------------------- | ------------------------- |
| Tests | Build directory search | Find freshly built binary |
| Production | Explicit config → PATH search | Find installed binary |
| Context | Discovery mechanism | Purpose |
| ---------- | ----------------------------- | ------------------------- |
| Tests | Build directory search | Find freshly built binary |
| Production | Explicit config → PATH search | Find installed binary |

### Binary location structure

Expand Down
30 changes: 15 additions & 15 deletions docs/execplans/issue-60-3-environment-mutation-abstraction.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Issue 60.3: Environment Mutation Abstraction

This execution plan (ExecPlan) is a living document. The sections
`Constraints`, `Tolerances`, `Risks`, `Progress`, `Surprises & Discoveries`,
`Decision Log`, and `Outcomes & Retrospective` must be kept up to date as work
proceeds.
This execution plan (ExecPlan) is a living document. The sections `Constraints`,
`Tolerances`, `Risks`, `Progress`, `Surprises & Discoveries`, `Decision Log`,
and `Outcomes & Retrospective` must be kept up to date as work proceeds.

Status: COMPLETE

Expand Down Expand Up @@ -106,8 +105,8 @@ actual current state of the work.
and pass to `apply_worker_environment`.
- [x] (2026-01-21 21:22Z) Add unit test for `TestEnvStore`
demonstrating `get`, `set`, and `remove`.
- [x] (2026-01-21 21:28Z) Run `make check-fmt`, `make lint`, and `make
test` to validate all changes.
- [x] (2026-01-21 21:28Z) Run `make check-fmt`, `make lint`, and `make test` to
validate all changes.
- [x] (2026-01-21 21:29Z) Commit the changes with a descriptive message.

## Surprises & discoveries
Expand Down Expand Up @@ -138,8 +137,8 @@ All objectives achieved:
with `set` and `remove` methods.
- `ProcessEnvStore` wraps real `env::set_var` and `env::remove_var` with
explicit SAFETY comments.
- `TestEnvStore` provides in-memory storage with `HashMap<String,
Option<String>>` and a `get` method for test assertions.
- `TestEnvStore` provides in-memory storage with
`HashMap<String, Option<String>>` and a `get` method for test assertions.
- `apply_worker_environment` refactored to accept `&mut dyn EnvStore`
parameter.
- `run_worker` updated to create `ProcessEnvStore` and pass to
Expand Down Expand Up @@ -213,8 +212,8 @@ Existing tests use an `EnvironmentOperations` trait from

This plan introduces a new `EnvStore` trait that:

- Defines `set(&mut self, key: &str, value: &str)` and `remove(&mut self, key:
&str)` methods
- Defines `set(&mut self, key: &str, value: &str)` and
`remove(&mut self, key: &str)` methods
- Is placed directly in `tests/support/pg_worker.rs` alongside the production
code
- Provides two implementations: `ProcessEnvStore` for production and
Expand Down Expand Up @@ -283,9 +282,10 @@ Validation: The code should compile with
In `tests/support/pg_worker.rs`, modify the `apply_worker_environment` function
(currently lines 208-221):

1. Change the function signature from `fn apply_worker_environment(environment:
&[(String, Option<PlainSecret>)])` to `fn apply_worker_environment(store:
&mut dyn EnvStore, environment: &[(String, Option<PlainSecret)])`.
1. Change the function signature from
`fn apply_worker_environment(environment: &[(String, Option<PlainSecret>)])`
to
`fn apply_worker_environment(store: &mut dyn EnvStore, environment: &[(String, Option<PlainSecret>)])`.

2. Update the function body to use the store parameter instead of calling
`env::set_var` and `env::remove_var` directly. Replace the unsafe calls with
Expand Down Expand Up @@ -328,8 +328,8 @@ Validation:
- The existing test `apply_worker_environment_uses_plaintext_and_unsets`
should continue to pass as it uses the separate `EnvironmentOperations` trait
from helpers.
- All tests in the file should pass with `cargo test --bin pg_worker
--features dev-worker --lib`.
- All tests in the file should pass with
`cargo test --bin pg_worker --features dev-worker --lib`.

### Stage D: validation and commit

Expand Down
7 changes: 3 additions & 4 deletions docs/execplans/issue-66-raii-fixture-cleanup.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# Fix TestCluster RAII cleanup (issue 66)


This execution plan (ExecPlan) is a living document. The sections
`Constraints`, `Tolerances`, `Risks`, `Progress`, `Surprises & discoveries`,
`Decision log`, and `Outcomes & retrospective` must be kept up to date as work
proceeds.
This execution plan (ExecPlan) is a living document. The sections `Constraints`,
`Tolerances`, `Risks`, `Progress`, `Surprises & discoveries`, `Decision log`,
and `Outcomes & retrospective` must be kept up to date as work proceeds.

Status: COMPLETE (2026-01-28)

Expand Down
Loading
Loading