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
62 changes: 62 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,68 @@ keeps reading that version for at least 24 months after a successor lands.

## [Unreleased]

## [1.0.9] — 2026-07-13

Twenty operator-annoyance fixes, found by systematically exercising the
user-facing surface (first-run flows, error hints, exit codes, output
consistency) and each covered by a regression test.

### Fix: first-run experience

- `init` no longer busy-loops forever (flooding the terminal) when
stdin is closed — a CI pipe or Ctrl-D now aborts with a structured
error pointing at flags + `--yes`.
- `init --quick` defaults to a user-writable repository path for
non-root users instead of failing on `/var/backups/pg_hardstorage`
with a permission error.
- init's "Next steps" suggests the flagless `wal stream <deployment>`
(the config it just wrote makes it work) instead of a literal
`--pg-connection ...` placeholder that retried an unparseable DSN
forever; operator-input (`usage.*`) errors now fail the stream
setup fast instead of retrying.
- Ctrl-C / SIGTERM now cancel the command context so deferred cleanup
runs — interrupting `demo` no longer leaks its throwaway PostgreSQL
container.

### Fix: hints and error classification

- Every remediation hint is copy-pasteable: doctor's audit-anchor
hints include `--repo <url>`; the checkpoint-mismatch suggestion
gives the resume command (it previously steered operators — and
automation reading its `command` field — toward `rm -rf` of the
partially-restored target, and referenced a flag that doesn't
exist); the GDPR erasure report and `jit` help no longer recommend
the nonexistent `kms shred --tenant`; the plain-restore notice
names the real `--to` flag.
- A typo'd subcommand under a group (`wal audi`, `repo bogus`) now
fails with exit 2 and a "did you mean" instead of printing help and
exiting 0 (a cron job with a typo stayed green forever); unknown
top-level commands also exit 2.
- An empty backup-ID argument (unset shell variable) is a usage error
(exit 2) — `verify` previously reported it as a manifest SIGNATURE
failure (exit 9, the pager-worthy "corrupt/tampered" code).
- A typo'd deployment name yields `notfound.deployment` listing the
configured names instead of demanding `--pg-connection`/`--repo`.

### Fix: consistency and safety

- `--version` works (CLI muscle memory); the help banner no longer
claims "v0.2"; `changelog` reports the real binary version.
- `daily_at` schedules are documented as host-local time (they always
were) and the schedule display shows the actual zone + UTC offset.
- `backup delete` — the most destructive verb — now requires `--yes`
(or an approval), matching every other gated verb.
- Bare `status` / `rotate` / `audit anchor` resolve `--repo` from the
config when every deployment shares one repository.
- `--verify` and `--verify-restore` accept each other's vocabulary
(`skip`≡`off`, `require`≡`required`).
- Durations render as `N ms` everywhere (list/init/verify matched
show/backup/restore); the `status` tombstone footnote no longer
blows the table fifty columns wide.
- The generated `restore_command` runs `wal fetch` with `-o text -q`,
so routine end-of-WAL probes log one line instead of ten-line JSON
documents in the PostgreSQL server log.

## [1.0.8] — 2026-07-06

### Fix: post-restore verification failed on every base-only restore
Expand Down
2 changes: 1 addition & 1 deletion docs/compliance/pci-dss.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ audit period plus the cosign signatures on the running
binary:

```sh
VERSION=1.0.8 # the release / image tag you're attesting
VERSION=1.0.9 # the release / image tag you're attesting

# 1. Audit chain bundle
pg_hardstorage audit export-bundle \
Expand Down
6 changes: 3 additions & 3 deletions docs/compliance/slsa-l3-provenance.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Verify a downloaded artifact against its provenance with the
`slsa-verifier`:

```sh
VERSION=1.0.8 # the release you're verifying
VERSION=1.0.9 # the release you're verifying
slsa-verifier verify-artifact \
--provenance-path pg_hardstorage.intoto.jsonl \
--source-uri github.com/cybertec-postgresql/pg_hardstorage \
Expand Down Expand Up @@ -109,7 +109,7 @@ When images ship, they are intended to carry a cosign
signature plus an image-level SLSA provenance attestation:

```sh
VERSION=1.0.8 # the image tag you're verifying
VERSION=1.0.9 # the image tag you're verifying

# Verify the image signature
cosign verify "ghcr.io/cybertec-postgresql/pg_hardstorage:v${VERSION}" \
Expand Down Expand Up @@ -139,7 +139,7 @@ JSON format, generated by `syft` (configured via the
and attached to the GitHub Release:

```sh
VERSION=1.0.8 # the release you're inspecting
VERSION=1.0.9 # the release you're inspecting
# The SBOM is a plain file on the Release; inspect it directly
jq -r '.packages[].name' \
"pg_hardstorage_${VERSION}_linux_amd64.tar.gz.spdx.sbom.json"
Expand Down
8 changes: 5 additions & 3 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,11 @@ pgBackRest's incremental chain; see

#### How do I delete an old backup?

`pg_hardstorage backup delete <deployment> <backup-id>`.
The manifest soft-deletes immediately; chunks stay until
the next `repo gc` decides nothing else references them.
`pg_hardstorage backup delete <deployment> <backup-id> --yes`
(the `--yes` confirmation gate is required; an approved
`--require-approval` also satisfies it). The manifest soft-deletes
immediately; chunks stay until the next `repo gc` decides nothing
else references them.
See [`backup delete` reference](reference/cli/pg_hardstorage_backup_delete.md)
for `--undelete` (within the trash TTL) and `--force` (skip
confirmation prompt). Retention can run this for you
Expand Down
6 changes: 3 additions & 3 deletions docs/how-to/operating/legal-hold.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ pg_hardstorage list db1
```console
Backups for db1 (3):
BACKUP ID TYPE WHEN FILES SIZE DEDUP DURATION
db1.full.20260427T020000Z full 2026-04-27 02:00 1284 12.3 GiB 1.42x 38210ms
db1.full.20260420T020000Z full 2026-04-20 02:00 1281 12.1 GiB 1.41x 37544ms
db1.full.20260413T020000Z full 2026-04-13 02:00 1279 11.9 GiB 1.40x 36988ms
db1.full.20260427T020000Z full 2026-04-27 02:00 1284 12.3 GiB 1.42x 38210 ms
db1.full.20260420T020000Z full 2026-04-20 02:00 1281 12.1 GiB 1.41x 37544 ms
db1.full.20260413T020000Z full 2026-04-13 02:00 1279 11.9 GiB 1.40x 36988 ms
```

### 2. Place an indefinite hold
Expand Down
2 changes: 1 addition & 1 deletion docs/how-to/operating/verify-fast-vs-full.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pg_hardstorage verify db1 latest
verify db1/db1.full.20260427T020000Z (full)
manifest signature: valid
chunks: 3245 referenced, 3245 unique, 3245 sampled
✓ 3245 chunk(s) verified — 12.3 GiB in 9412ms
✓ 3245 chunk(s) verified — 12.3 GiB in 9412 ms
```

`--repo <url>` overrides the deployment's configured repo for
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ Every command is a real implementation (no scaffolding stubs).
The advanced surfaces — gRPC, OIDC + RBAC, advise+execute LLM mode,
sandbox-PG runtime — extend per docs/SPEC.md.

```
pg_hardstorage [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_anomaly.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ Findings flip the exit code to 9 (ExitVerifyFailed) so cron-driven
checks alarm. An audit-chain entry is written on every flag —
bit-rot-style: rare enough to be signal, not noise.

```
pg_hardstorage anomaly <subcommand> [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_approval.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ Approvals are signed with each approver's ed25519 keypair (the same
shape as the manifest-signing keys we already use). Tampering with
the request invalidates every existing signature.

```
pg_hardstorage approval [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ event's prev_hash; `audit verify-chain` walks the chain and
reports both kinds of finding (hash mismatch on an event, or chain
break between events).

```
pg_hardstorage audit [flags]
```

### Options

```
Expand Down
1 change: 1 addition & 0 deletions docs/reference/cli/pg_hardstorage_backup_delete.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pg_hardstorage backup delete <deployment> <backup-id> [flags]
--reason string free-form reason captured in the tombstone + audit chain
--repo string repository URL (required)
--require-approval string approval request ID that must be in approved state for backup.delete + this backup ID (n-of-m gate; strongly recommended)
--yes confirm the tombstone (not needed when --require-approval is given)
```

### Options inherited from parent commands
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_capacity.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ tags:

Projected repository size, WAL volume, and pre-flight free-space checks

```
pg_hardstorage capacity <report|preflight> [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_classify.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ The tag is informational in v0.1 — surfaced in doctor and stored
in pg_hardstorage.yaml. wires it to retention floor, allowed
regions, and required-encryption enforcement.

```
pg_hardstorage classify [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_compat.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ surface live in their own binaries (pg-hardstorage-pgbackrest,
pg-hardstorage-barman); this subcommand is only for the
config-translation half of the migration story.

```
pg_hardstorage compat <translate> [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_compliance.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ Today the only subcommand is `compliance report`; the namespace is
reserved for additional reports without disturbing the v1 contract
on the existing one.

```
pg_hardstorage compliance [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_cost.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ tags:

Per-deployment / per-tenant repository cost

```
pg_hardstorage cost <report> [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_db.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ tags:

In-database integration (SQL views, upsert helpers)

```
pg_hardstorage db <install-extension|uninstall-extension> [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ A deployment is the unit of "what we back up" — one PostgreSQL
service. The subcommands here mutate the deployments: block in
pg_hardstorage.yaml.

```
pg_hardstorage deployment [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_dsa.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ Exit codes:
6 notfound (report id absent for show/verify)
9 verify failure (signature does not validate)

```
pg_hardstorage dsa [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_fleet.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ v0.1 ships fleet search — point at a repository, give a key:value
query, and get back every matching backup. Multi-repo aggregation
arrives with the control plane.

```
pg_hardstorage fleet <search> [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_gameday.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ tags:

Opt-in chaos automation

```
pg_hardstorage gameday <list|run|report> [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_hold.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ so it survives agent restarts and is visible across operators.
Removing a hold is the explicit `hold remove` operation; nothing
else clears it.

```
pg_hardstorage hold [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_insider.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ Each scan compares a baseline window (default 30 d) against a target
window (default 24 h). Findings carry severity, actor, action, the
audit event IDs that triggered them, and a human-readable reason.

```
pg_hardstorage insider [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_integrity.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Exit codes:
code matches the "verify-failed" namespace; cron will alert.
6 notfound (run id or strategy target absent)

```
pg_hardstorage integrity [flags]
```

### Options

```
Expand Down
8 changes: 6 additions & 2 deletions docs/reference/cli/pg_hardstorage_jit.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,19 @@ Operationally:

# operator consumes (future commit will wire --jit-token
# into kms shred + other destructive commands)
pg_hardstorage kms shred --tenant T \
--jit-token <encoded-token> --repo s3://acme
pg_hardstorage kms shred --repo s3://acme \
--confirm-keyring <keyring-dir> --require-approval <id> --yes

# admin lists current tokens
pg_hardstorage jit list --repo s3://acme

# admin revokes if needed
pg_hardstorage jit revoke <token-id> --reason "..."

```
pg_hardstorage jit [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_kms.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ verbs (rotate, shred, hsm-status) land alongside the KMS
plugin tier (gcp-kms, azure-key-vault, vault-transit) and the PKCS#11
/ TPM 2.0 integrations.

```
pg_hardstorage kms [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_llm_history.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ tags:

Inspect / shred encrypted LLM conversation transcripts

```
pg_hardstorage llm history <list|show|shred> [flags]
```

### Options

```
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cli/pg_hardstorage_llm_skill.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ tags:

Manage LLM skill files

```
pg_hardstorage llm skill <list|show|lint|install|rollback|history> [flags]
```

### Options

```
Expand Down
Loading
Loading