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
23 changes: 23 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: validate

on:
pull_request:
push:
branches: [main]

# The validator runs code from the pull request's checkout, so the job gets a
# read-only token and no persisted credentials: nothing in it can push.
permissions:
contents: read

jobs:
catalog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# Pin verification resolves commits in the repository's own history.
fetch-depth: 0
persist-credentials: false
- name: Validate catalog, specs, and dependency pins
run: bash scripts/validate-catalog.sh
6 changes: 5 additions & 1 deletion schematics/fetch-movies-over-usenet/SCHEMATIC.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ description: Privately acquiring movies over usenet - Radarr automating grabs th

| Id | What | Why needed | Discovery | Failure behavior |
|-----|------|------------|-----------|------------------|
| D-1 | [fetch-over-usenet v0.1.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/fetch-over-usenet/SCHEMATIC.md) `sha256:bef7d4c87fa7227f5f6d9653365a1ab66f6e7429978e8ef221939cf772ea64a3` | The shared downloader, indexer authority, unpackerr | Its phases 1-2 green | Blocker: nothing to register with |
| D-1 | [fetch-over-usenet v0.1.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/fetch-over-usenet/SCHEMATIC.md) `sha256:bef7d4c87fa7227f5f6d9653365a1ab66f6e7429978e8ef221939cf772ea64a3` | The shared downloader, indexer authority, unpackerr | Its phases 1-2 green | Blocker: nothing to register with |
| D-2 | Radarr image | Movie automation | Digest-pinned | No movie fetching |

## Parameters
Expand Down Expand Up @@ -142,6 +142,10 @@ Decisions:
SABnzbd, unpackerr, Bazarr, flaresolverr) moved to
`fetch-over-usenet`; this package keeps only what is genuinely
movie-specific.
- 2026-09-17: Schematic dependencies are pinned to commit `81721d8` (the full
sha is in the link) with the SHA-256 of the file at that commit. Verify a
pin with `curl -s https://raw.githubusercontent.com/cameri/schematics/<commit>/<path> | sha256sum`
and compare the result with the digest in the table.

Open questions:

Expand Down
6 changes: 5 additions & 1 deletion schematics/fetch-music-over-usenet/SCHEMATIC.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ description: Privately acquiring music over usenet - Lidarr automating artist an

| Id | What | Why needed | Discovery | Failure behavior |
|-----|------|------------|-----------|------------------|
| D-1 | [fetch-over-usenet v0.1.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/fetch-over-usenet/SCHEMATIC.md) `sha256:bef7d4c87fa7227f5f6d9653365a1ab66f6e7429978e8ef221939cf772ea64a3` | The shared indexer manager and downloader | Its phases 1-2 green | Blocker: deploy it first |
| D-1 | [fetch-over-usenet v0.1.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/fetch-over-usenet/SCHEMATIC.md) `sha256:bef7d4c87fa7227f5f6d9653365a1ab66f6e7429978e8ef221939cf772ea64a3` | The shared indexer manager and downloader | Its phases 1-2 green | Blocker: deploy it first |
| D-2 | Lidarr image | Music automation | Digest-pinned | No music fetching |

## Parameters
Expand Down Expand Up @@ -147,6 +147,10 @@ Decisions:
provider config as the parent stack. If an operator wants the whole
pipeline behind a VPN, that is `fetch-books-over-vpn`'s pattern
applied to this stack - a deliberate composition, not a default.
- 2026-09-17: Schematic dependencies are pinned to commit `81721d8` (the full
sha is in the link) with the SHA-256 of the file at that commit. Verify a
pin with `curl -s https://raw.githubusercontent.com/cameri/schematics/<commit>/<path> | sha256sum`
and compare the result with the digest in the table.

Open questions:

Expand Down
6 changes: 5 additions & 1 deletion schematics/fetch-series-over-usenet/SCHEMATIC.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ description: Privately acquiring series over usenet - Sonarr automating episode

| Id | What | Why needed | Discovery | Failure behavior |
|-----|------|------------|-----------|------------------|
| D-1 | [fetch-over-usenet v0.1.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/fetch-over-usenet/SCHEMATIC.md) `sha256:bef7d4c87fa7227f5f6d9653365a1ab66f6e7429978e8ef221939cf772ea64a3` | The shared downloader, indexer authority, unpackerr | Its phases 1-2 green | Blocker: nothing to register with |
| D-1 | [fetch-over-usenet v0.1.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/fetch-over-usenet/SCHEMATIC.md) `sha256:bef7d4c87fa7227f5f6d9653365a1ab66f6e7429978e8ef221939cf772ea64a3` | The shared downloader, indexer authority, unpackerr | Its phases 1-2 green | Blocker: nothing to register with |
| D-2 | Sonarr image | Series automation | Digest-pinned | No series fetching |

## Parameters
Expand Down Expand Up @@ -138,6 +138,10 @@ Decisions:
series are independently deployable halves over one shared
infrastructure package; everything infrastructure-shaped moved to
`fetch-over-usenet`.
- 2026-09-17: Schematic dependencies are pinned to commit `81721d8` (the full
sha is in the link) with the SHA-256 of the file at that commit. Verify a
pin with `curl -s https://raw.githubusercontent.com/cameri/schematics/<commit>/<path> | sha256sum`
and compare the result with the digest in the table.

Open questions:

Expand Down
10 changes: 7 additions & 3 deletions schematics/improve-docker-security/SCHEMATIC.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ against. See the composition-convention module for the full rules.
| Id | Kind | What | Why needed | Discovery | Failure behavior |
|-----|------|------|------------|-----------|------------------|
| D-1 | system | Docker Engine + Compose v2 | Runs everything | `docker compose version` | Blocker |
| D-2 | schematic | [restrict-docker-api-access v0.3.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/restrict-docker-api-access/SCHEMATIC.md) `sha256:29951fd2252a342d2863e960b4eaa8095599227d70d7e36694769af84ccaa50a` | Closes container→daemon access (R-1) | Its phases green | Consumers fall back to socket mounts - forbidden (R-1) |
| D-3 | schematic | [authorize-docker-requests v0.2.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/authorize-docker-requests/SCHEMATIC.md) `sha256:73a1a2423df279ea1c163ae51496ef12b68882b7801cca819126ad4b192af506` | Polices daemon control (R-2) | Its phases green | OPA down → clients blocked by design; rollback line re-opens |
| D-4 | schematic | [encrypt-container-secrets v0.2.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/encrypt-container-secrets/SCHEMATIC.md) `sha256:a776b9b1d34d5fc7883ecee8f7616d39860a9236f5d875dc476013fae413ba45` | Closes secrets at rest (R-3) | Its phases green | Deployment halts rather than falling back to plaintext |
| D-2 | schematic | [restrict-docker-api-access v0.3.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/restrict-docker-api-access/SCHEMATIC.md) `sha256:29951fd2252a342d2863e960b4eaa8095599227d70d7e36694769af84ccaa50a` | Closes container→daemon access (R-1) | Its phases green | Consumers fall back to socket mounts - forbidden (R-1) |
| D-3 | schematic | [authorize-docker-requests v0.2.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/authorize-docker-requests/SCHEMATIC.md) `sha256:73a1a2423df279ea1c163ae51496ef12b68882b7801cca819126ad4b192af506` | Polices daemon control (R-2) | Its phases green | OPA down → clients blocked by design; rollback line re-opens |
| D-4 | schematic | [encrypt-container-secrets v0.2.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/encrypt-container-secrets/SCHEMATIC.md) `sha256:a776b9b1d34d5fc7883ecee8f7616d39860a9236f5d875dc476013fae413ba45` | Closes secrets at rest (R-3) | Its phases green | Deployment halts rather than falling back to plaintext |

## Parameters

Expand Down Expand Up @@ -243,6 +243,10 @@ Decisions:
(composition-convention): the composition states exactly which contract
it was built against, and verification is a hash comparison, not a
trust statement.
- 2026-09-17: Schematic dependencies are pinned to commit `81721d8` (the full
sha is in the link) with the SHA-256 of the file at that commit. Verify a
pin with `curl -s https://raw.githubusercontent.com/cameri/schematics/<commit>/<path> | sha256sum`
and compare the result with the digest in the table.

Open questions:

Expand Down
8 changes: 6 additions & 2 deletions schematics/run-a-book-library/SCHEMATIC.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ marketplace entries as the version pins.
| Id | Kind | What | Why needed | Discovery | Failure behavior |
|-----|------|------|------------|-----------|------------------|
| D-1 | system | Docker + Compose v2 | Runs both stacks | `docker compose version` | Blocker |
| D-2 | schematic | [fetch-books-over-vpn v0.2.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/fetch-books-over-vpn/SCHEMATIC.md) `sha256:973e73f65376d1f54353ab94be05975cd60fce4f13f486b61390cd970030b3fa` | Acquires books/audiobooks privately | Its phases 1-4 green | No new content; serving still works |
| D-3 | schematic | [serve-books-using-containers v0.2.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/serve-books-using-containers/SCHEMATIC.md) `sha256:5f09a47942d10f401a09753ead33e8c52bf26b298c26eb0101e189b6793588b7` | Serves the library | Its phases 1-3 green | Library present but silent |
| D-2 | schematic | [fetch-books-over-vpn v0.2.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/fetch-books-over-vpn/SCHEMATIC.md) `sha256:973e73f65376d1f54353ab94be05975cd60fce4f13f486b61390cd970030b3fa` | Acquires books/audiobooks privately | Its phases 1-4 green | No new content; serving still works |
| D-3 | schematic | [serve-books-using-containers v0.2.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/serve-books-using-containers/SCHEMATIC.md) `sha256:5f09a47942d10f401a09753ead33e8c52bf26b298c26eb0101e189b6793588b7` | Serves the library | Its phases 1-3 green | Library present but silent |
| D-4 | system | One shared media root on the host | The R-1 contract | `ls <media root>` | Blocker: no common tree |

## Parameters
Expand Down Expand Up @@ -232,6 +232,10 @@ Decisions:
content SHA-256 (convention v2; see improve-docker-security's
composition-convention module). Relative links are gone: the pinned
URL is the version-of-record for the contract.
- 2026-09-17: Schematic dependencies are pinned to commit `81721d8` (the full
sha is in the link) with the SHA-256 of the file at that commit. Verify a
pin with `curl -s https://raw.githubusercontent.com/cameri/schematics/<commit>/<path> | sha256sum`
and compare the result with the digest in the table.

Open questions:

Expand Down
34 changes: 24 additions & 10 deletions schematics/run-a-movies-and-series-library/SCHEMATIC.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- Recommended: use the schematics@cameri/schematics plugin to build this schematic -->
---
name: run-a-movies-and-series-library
version: 0.2.1
version: 0.2.2
status: published
description: A composition schematic - runs a complete movies-and-series library by wiring the fetching half (Prowlarr, Sonarr, Radarr, Bazarr, SABnzbd, unpackerr) to the serving half (Jellyfin, Jellyseerr) through the shared media tree, with the request flow closing the loop from "I want to watch X" to "X is playing". Recommended but optional: hardening the Docker host and keeping deployments current. No images of its own; the glue is the loop, the ordering, and the cross-verification.
---
Expand Down Expand Up @@ -72,10 +72,10 @@ the file's content SHA-256 (composition-convention, rule 2).
| Id | Kind | What | Why needed | Discovery | Failure behavior |
|-----|------|------|------------|-----------|------------------|
| D-1 | system | Docker + Compose v2 | Runs both halves | `docker compose version` | Blocker |
| D-2 | schematic | [fetch-over-usenet v0.1.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/fetch-over-usenet/SCHEMATIC.md) `sha256:bef7d4c87fa7227f5f6d9653365a1ab66f6e7429978e8ef221939cf772ea64a3` | The shared downloading infrastructure | Its phases 1-3 green | Blocker: nothing to grab with |
| D-3 | schematic | [fetch-movies-over-usenet v0.1.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/fetch-movies-over-usenet/SCHEMATIC.md) `sha256:372c9af317196df3ef6a71f42151aaa0076eb47c6cfad7d6123f90e3af55ca64` | Acquires movies | Its phases 1-2 green | Series-only fetching |
| D-4 | schematic | [fetch-series-over-usenet v0.1.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/fetch-series-over-usenet/SCHEMATIC.md) `sha256:06b6fc8df40c70568be9323a8a670746e8c1ebbaefa166628b98accaf8c12d28` | Acquires series | Its phases 1-2 green | Movies-only fetching |
| D-5 | schematic | [serve-movies-and-series v0.2.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/serve-movies-and-series/SCHEMATIC.md) `sha256:384ec85884529472943287701cc9912eeceedd4fa53591d77a7fd45a6c3745ce` | Serves content, takes requests | Its phases 1-2 green | Fetching continues; nothing watchable |
| D-2 | schematic | [fetch-over-usenet v0.1.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/fetch-over-usenet/SCHEMATIC.md) `sha256:bef7d4c87fa7227f5f6d9653365a1ab66f6e7429978e8ef221939cf772ea64a3` | The shared downloading infrastructure | Its phases 1-3 green | Blocker: nothing to grab with |
| D-3 | schematic | [fetch-movies-over-usenet v0.1.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/fetch-movies-over-usenet/SCHEMATIC.md) `sha256:0df9912e26f8a2b26fb79f454f044d0b7663829827c5360e12e02a9fb37a2e46` | Acquires movies | Its phases 1-2 green | Series-only fetching |
| D-4 | schematic | [fetch-series-over-usenet v0.1.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/fetch-series-over-usenet/SCHEMATIC.md) `sha256:5ec2c9a3ae0160e79d1eeb7618207a9b7ddeacd3a173b09fadcb09107a912b90` | Acquires series | Its phases 1-2 green | Movies-only fetching |
| D-5 | schematic | [serve-movies-and-series v0.2.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/serve-movies-and-series/SCHEMATIC.md) `sha256:384ec85884529472943287701cc9912eeceedd4fa53591d77a7fd45a6c3745ce` | Serves content, takes requests | Its phases 1-2 green | Fetching continues; nothing watchable |

## Recommended

Expand All @@ -84,8 +84,8 @@ them leaves every requirement above satisfiable (R-6).

| Id | Kind | What | Adds | Without it |
|-----|------|------|------|------------|
| RD-1 | schematic | [improve-docker-security v0.1.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/improve-docker-security/SCHEMATIC.md) `sha256:08b9f072a0a96047fcce8036c519d61e5b76b9fd02c98b1ce85ed43324ff153b` | Hardens the Docker host this stack runs on: scoped API access, OPA-policed control, encrypted secrets (including this stack's many API keys, R-3's rule enforced mechanically) | The stack works, but socket-mounting consumers and plaintext keys remain accepted risk |
| RD-2 | schematic | [update-images-on-push v0.2.1](https://github.com/cameri/schematics/blob/56e02f9/schematics/update-images-on-push/SCHEMATIC.md) `sha256:810129ef2839e77f88b469601e494e6367a9cc5afd1b1c904fb9e1fe37705067` | Keeps the images current from git pushes without cron-based full-socket updaters | Manual or watchtower-style updates |
| RD-1 | schematic | [improve-docker-security v0.1.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/improve-docker-security/SCHEMATIC.md) `sha256:173d89578cb487139584f76efefa013c20ffa070349401db3d7897076838e10d` | Hardens the Docker host this stack runs on: scoped API access, OPA-policed control, encrypted secrets (including this stack's many API keys, R-3's rule enforced mechanically) | The stack works, but socket-mounting consumers and plaintext keys remain accepted risk |
| RD-2 | schematic | [update-images-on-push v0.2.1](https://github.com/cameri/schematics/blob/81721d8ff548ad0f4b1477e696b7899d30f999fa/schematics/update-images-on-push/SCHEMATIC.md) `sha256:810129ef2839e77f88b469601e494e6367a9cc5afd1b1c904fb9e1fe37705067` | Keeps the images current from git pushes without cron-based full-socket updaters | Manual or watchtower-style updates |

## Parameters

Expand Down Expand Up @@ -120,9 +120,10 @@ halves. Any new duplicated value joins this table, not a compose line.

### Phase 0: Install dependencies in isolation

1. Execute D-2's and D-3's phases separately; each acceptance set
green before glue.
2. Verification: two green lists, no cross-wiring.
1. Execute D-2's phases first (it owns the shared infrastructure), then
D-3's and D-4's (each registers with D-2), then D-5's; each
acceptance set green before glue.
2. Verification: four green lists, no cross-wiring.

### Phase 1: Reconcile parameters

Expand Down Expand Up @@ -191,6 +192,19 @@ Decisions:
feature (separate table, same pinning, degraded-mode behavior stated
per row); canonical text in improve-docker-security's
composition-convention module.
- 2026-09-17: Schematic dependencies are pinned to commit `81721d8` (the full
sha is in the link) with the SHA-256 of the file at that commit. Verify a
pin (A-7) with
`curl -s https://raw.githubusercontent.com/cameri/schematics/<commit>/<path> | sha256sum`
and compare the result with the digest in the table. The cross-references
the glue relies on: R-3's key rule is fetch-over-usenet R-5, restated by
fetch-movies-over-usenet R-4 and fetch-series-over-usenet R-4; P-1 feeds
fetch-movies P-1 (`${MEDIA_ROOT}/movies`) and fetch-series P-1
(`${MEDIA_ROOT}/tvseries`); the categories both arrs register under come
from fetch-over-usenet P-6; RD-1's secrets layer (improve-docker-security
R-3) is what makes R-3 mechanical. Phase 0 runs the four dependencies in
registration order: the shared infrastructure first, the two arrs that
register with it, then the server. Version 0.2.2.

Open questions:

Expand Down
Loading
Loading