Commit Graph
8 Commits
Author SHA1 Message Date
user 5b238e740b Enforce real timeouts on gpg subprocess calls (closes #62)
check / check (push) Successful in 1m0s
Every gpg invocation went through runGPG, which built its command with
exec.CommandContext(context.Background(), ...). That is the right call
with the wrong context: context.Background() never expires, so no
deadline was ever enforced on any of the five gpg call sites.

runGPG now takes a context and derives a gpgTimeout deadline from it,
honouring an earlier caller deadline when there is one. The gpg-touching
library entry points take a ctx as their first argument so cancellation
propagates from above: Builder.Build, NewManifestFromReader,
NewManifestFromFile, NewChecker, Checker.ExtractEmbeddedSigningKeyFP.
Scanner.ToManifest already had a ctx and now passes it down, which
withdraws the //nolint:contextcheck claiming signing was "not
cancellable by design" -- it is, and now it is.

A deadline alone is not enough, and the added test proves it. gpg
delegates to helpers (gpg-agent, pinentry) that inherit the captured
stdout and stderr pipes. Go's default cancellation kills only the direct
child, so the helper keeps the pipes open and Cmd.Wait blocks on the
output-copying goroutines forever -- a dead process and a call that
still never returns. Two additions fix that: the child runs in its own
process group and cancellation kills the group, and Cmd.WaitDelay caps
how long Wait will hold on for the pipes if something escapes the group
anyway. Measured with the stand-in gpg from the new test: neither
mechanism, hangs until `go test` gives up; WaitDelay only, returns in
2.2s; both, returns in 0.20s.

Timeout errors now name the operation and how long gpg ran instead of
surfacing a bare "signal: killed" or "context deadline exceeded", and a
cancellation from above is reported as a cancellation rather than a
timeout, so an abort is distinguishable from a stall.

The test helper's own keygen invocations had the same unbounded
context.Background() and the same pipe-inheriting agent problem, which
makes them the actual mechanism behind the intermittent suite timeout
noted in the issue: keygen starts gpg-agent, and a stalled agent hung
the suite rather than failing it. They now run under a deadline with the
same hardening, so a broken gpg environment skips instead of hanging.

Verified with a cold `docker buildx build --no-cache`: prettier, gofmt,
`make lint` (0 issues) and `make test` all executed and passed. The
golang:1.23 image ships gpg, so the real signing, export, fingerprint,
import and verify tests run against real gpg there, not skipped.

The process-group kill is unix-only and lives in a build-tagged file; on
other platforms the deadline is still enforced via cancellation plus
WaitDelay, only the group kill of helpers is unavailable.
2026-09-03 14:50:59 +00:00
clawbot 5683d0f4ff Configure prettier and make fmt-check cover markdown (closes #69)
check / check (push) Successful in 4s
Adds .prettierrc and .prettierignore, a single script/prettier entrypoint shared by fmt and fmt-check so the two cannot drift, and prettier 3.9.6 pinned by yarn.lock integrity hash.

Markdown formatting is now gated in the authoritative Docker build via a new mdfmt stage, since the golangci-lint image has no node. REPO_POLICIES.md is ignored so local tooling cannot drift it from upstream.

Removes the || true that made the previous prettier invocation unable to fail.
2026-08-10 16:16:42 +02:00
clawbot de476708e9 Update golangci-lint to v2.12.2 with canonical config (closes #60)
check / check (push) Has been cancelled
Adopts golangci-lint v2.12.2 and the canonical .golangci.yml (default: all), and fixes all resulting findings across the tree.

Two intended behavior changes: absent MFFilePath.Mtime is handled explicitly in freshen, list and export rather than dereferenced (main panicked); gpg positional key IDs now follow an explicit -- end-of-options marker.

All twelve reworded user-visible error messages restored to byte-identical parity with main and pinned by tests.
2026-08-10 16:06:12 +02:00
sneak 6d19de74e7 scripts-to-rule-them-all (#58)
check / check (push) Successful in 6s
Reviewed-on: #58
Co-authored-by: sneak <sneak@sneak.berlin>
Co-committed-by: sneak <sneak@sneak.berlin>
2026-07-07 02:13:35 +02:00
sneak 688ebd90a4 TODO (#57)
check / check (push) Successful in 5s
Reviewed-on: #57
Co-authored-by: sneak <sneak@sneak.berlin>
Co-committed-by: sneak <sneak@sneak.berlin>
2026-07-06 21:19:31 +02:00
9ce16a83ad Add TODO section to README with 1.0 roadmap, remove TODO.md (#54)
check / check (push) Successful in 4s
## Summary

Performs a design and status review of the codebase and adds a comprehensive TODO section to `README.md` listing remaining work for a 1.0 release.

### What changed

- **README.md**: Added a `TODO: Remaining Work for 1.0` section covering:
  - **7 design questions** requiring @sneak's input before implementation (manifest type export, Go module path, GPG vs pure-Go crypto, format framing, etc.) — each with an answer field for inline decisions
  - **Implementation tasks** organized by category: repo infrastructure, format & correctness, library, CLI, testing & robustness, documentation, and release checklist
  - Updated build status section (removed stale Drone CI badge, replaced with description of current Docker-based CI)
- **TODO.md**: Removed — items integrated into README TODO section
- **AGENTS.md**: Updated reference from `TODO.md` to README TODO section

### Design review findings

**What works well:**
- Core library (Builder, Scanner, Checker) is solid with good test coverage
- Format specification is well-designed (protobuf + zstd, multihash, deterministic serialization)
- CLI covers all major operations (gen, check, list, export, freshen, fetch)
- Test suite is thorough — builder, scanner, checker, GPG, CLI integration, corruption detection
- afero abstraction enables clean testing without filesystem side effects

**Key gaps for 1.0:**
- Missing repo infrastructure (`.golangci.yml`, `.editorconfig`, CI workflow)
- `manifest` type is unexported — consumers can't use it in their own type declarations
- GPG signing shells out to `gpg` subprocess — fragile and may not be installed
- Go module path inconsistency between `go.mod` and proto `go_package`
- `fetch` command lacks retry logic and has no HTTP timeout
- Missing fuzz tests for untrusted input deserialization
- Freshen CLI command has incomplete integration test coverage

closes #47
closes #50

Co-authored-by: user <user@Mac.lan guest wan>
Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de>
Co-authored-by: Jeffrey Paul <sneak@noreply.example.org>
Reviewed-on: #54
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>
2026-04-07 00:43:56 +02:00
clawbotandclawbot 6ba32f5b35 Add REPO_POLICIES.md, rename CLAUDE.md to AGENTS.md, deduplicate (#51)
Closes #48

## Changes

- **Added `REPO_POLICIES.md`** — copied from the standard template at [sneak/prompts](https://git.eeqj.de/sneak/prompts/src/branch/main/prompts/REPO_POLICIES.md) (last_modified: 2026-03-10). This is the authoritative cross-project policy document covering repository structure, tooling, Docker, formatting, testing, and workflow standards.

- **Renamed `CLAUDE.md` → `AGENTS.md`** — deduplicated content:
  - Rules already covered by `REPO_POLICIES.md` (e.g. `git add -A`, Makefile targets) are no longer repeated
  - `AGENTS.md` retains only agent-specific workflow instructions: test-first bug fixing, no AI attribution in commits, per-change make fmt/test/lint workflow, and repo-specific notes (proto files, FORMAT.md, TODO.md)

- **Updated `README.md`** — added a reference to `REPO_POLICIES.md` in the Participation section

- **Formatting** — `make fmt` (prettier) applied to all markdown files

## Verification

`docker build .` passes clean — lint, fmt-check, and all tests green.

Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de>
Reviewed-on: #51
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>
2026-03-17 05:07:43 +01:00
sneak 5aae442156 add links to metalink format (#7)
Reviewed-on: #7
2026-02-09 02:15:58 +01:00