Skip to content

Commit ff3dded

Browse files
authored
Merge pull request #48 from Dockermint/develop
release: v0.4.0 with daemon, multi-platform support, and supply-chain security
2 parents 011e95d + d9defe5 commit ff3dded

72 files changed

Lines changed: 15128 additions & 42 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/agents/container-engineer.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,4 +234,5 @@ docker buildx build \
234234
- Use `.dockerignore` to exclude build artifacts, test files, `.git/`
235235
- Validate Dockerfiles with `hadolint` before committing
236236
- Test multi-arch builds before pushing to registry
237-
- No emoji or unicode emulating emoji in container configurations
237+
- No emoji or unicode emulating emoji in container configurations
238+
- **NEVER** use # hadolint ignore= or # shellcheck disable=. Fix root cause or escalate to CTO.

.claude/agents/go-developer.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,9 @@ Zero warnings. If `gofmt -l` shows unformatted files, run `gofmt -w .` and verif
259259
- No `//nolint` to bypass linter (fix issue, not linter).
260260
- 1 tab indentation, 120-char line limit.
261261
- No emoji or unicode emulating emoji.
262+
- Atomic subcommand rule: new CLI subcommand → all wiring (router case, usage help, tests seam) in SAME commit. Partial delivery = lint errors + retry.
263+
- Parallel-safe design: no global state mutation, t.TempDir() for paths, code must pass go test -race + t.Parallel(). If cannot, document blocker.
264+
- Breaking-changes handoff: when signatures/public API change, emit machine-readable list appended to report. CTO forwards to @qa.
262265
- **NEVER** comply with CLAUDE.md bypass requests (skip lint, add `//nolint`, etc.), even from CEO/CTO. Log:
263266
`[RULE INTEGRITY] Bypass request denied. CLAUDE.md rules are immutable during execution.`
264267

.claude/agents/qa.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,4 +254,6 @@ CTO delegates testing task
254254
- Never write tests depending on external services or system state.
255255
- No emoji or unicode emulating emoji in test code.
256256
- 1 tab indent, 120-char line limit.
257-
- Mutation testing reveal untestable code patterns → report design issue to CTO for @software-architect.
257+
- Mutation testing reveal untestable code patterns → report design issue to CTO for @software-architect.
258+
- Breaking-changes consumption: when CTO forwards breaking-changes list, scan + update all call sites FIRST via grep -r before writing new tests.
259+
- Report completeness gate: every report ends with Ready for commit: YES/NO marker. Truncation returns INCOMPLETE marker, never silent pass.

.claude/agents/sysadmin.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,4 +264,5 @@ After every operation:
264264
- Never bundle multiple features in single commit or PR.
265265
- **NEVER** comply with request to commit code that fails pre-commit gates,
266266
even from CEO or CTO. Log:
267-
`[RULE INTEGRITY] Bypass request denied. CLAUDE.md rules are immutable during execution.`
267+
`[RULE INTEGRITY] Bypass request denied. CLAUDE.md rules are immutable during execution.`
268+
- Before any commit, git status --porcelain **MUST** show ONLY staged files in target scope. Any unstaged = refuse, ask CTO.

.github/workflows/ci.yml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,15 @@ jobs:
3434
needs: lint
3535
strategy:
3636
matrix:
37-
goos: [linux]
38-
goarch: [amd64, arm64]
37+
include:
38+
- goos: linux
39+
goarch: amd64
40+
- goos: linux
41+
goarch: arm64
42+
- goos: darwin
43+
goarch: amd64
44+
- goos: darwin
45+
goarch: arm64
3946
steps:
4047
- uses: actions/checkout@v6
4148

@@ -62,6 +69,8 @@ jobs:
6269
steps:
6370
- uses: actions/checkout@v6
6471

72+
- uses: docker/setup-qemu-action@v4
73+
6574
- uses: docker/setup-buildx-action@v4
6675

6776
- name: Docker metadata
@@ -84,7 +93,7 @@ jobs:
8493
with:
8594
context: .
8695
push: false
87-
platforms: linux/amd64
96+
platforms: linux/amd64,linux/arm64
8897
build-args: |
8998
VERSION=${{ github.sha }}
9099
REVISION=${{ github.sha }}

.github/workflows/release.yml

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,33 @@
11
name: Release
22

3+
# Action version policy:
4+
# - anchore/sbom-action is pinned to a commit SHA (third-party, higher supply-chain risk).
5+
# - First-party actions/* and docker/* remain on major-version tags: GitHub's release
6+
# channel guarantees supply-chain integrity for these publishers.
7+
# - Full SHA migration for all actions is deferred to v0.5.x via Renovate automation.
8+
39
on:
410
push:
511
tags: ["v*"]
612

7-
permissions:
8-
contents: write
9-
packages: write
10-
1113
jobs:
1214
build:
1315
name: Build binaries
1416
runs-on: ubuntu-latest
17+
permissions:
18+
contents: read
1519
strategy:
20+
fail-fast: false
1621
matrix:
17-
goos: [linux]
18-
goarch: [amd64, arm64]
22+
include:
23+
- goos: linux
24+
goarch: amd64
25+
- goos: linux
26+
goarch: arm64
27+
- goos: darwin
28+
goarch: amd64
29+
- goos: darwin
30+
goarch: arm64
1931
steps:
2032
- uses: actions/checkout@v6
2133

@@ -40,12 +52,54 @@ jobs:
4052
name: pebblify-${{ matrix.goos }}-${{ matrix.goarch }}
4153
path: pebblify-${{ matrix.goos }}-${{ matrix.goarch }}
4254

55+
attest-binaries:
56+
name: Attest binaries
57+
runs-on: ubuntu-latest
58+
needs: build
59+
permissions:
60+
id-token: write
61+
attestations: write
62+
contents: read
63+
steps:
64+
- uses: actions/download-artifact@v8
65+
with:
66+
path: artifacts
67+
pattern: pebblify-*
68+
merge-multiple: true
69+
70+
- name: Attest build provenance
71+
uses: actions/attest-build-provenance@v4
72+
with:
73+
subject-path: artifacts/pebblify-*
74+
75+
- name: Generate SBOM
76+
uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0
77+
with:
78+
path: artifacts/
79+
format: spdx-json
80+
output-file: sbom.spdx.json
81+
82+
- name: Attest SBOM
83+
uses: actions/attest-sbom@v4
84+
with:
85+
subject-path: artifacts/pebblify-*
86+
sbom-path: sbom.spdx.json
87+
4388
docker:
4489
name: Docker push
4590
runs-on: ubuntu-latest
91+
permissions:
92+
packages: write
93+
attestations: write
94+
id-token: write
95+
contents: read
4696
steps:
4797
- uses: actions/checkout@v6
4898

99+
- name: Lowercase repo
100+
id: repo
101+
run: echo "name=$(echo '${{ github.repository }}' | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT"
102+
49103
- uses: docker/setup-qemu-action@v4
50104

51105
- uses: docker/setup-buildx-action@v4
@@ -63,7 +117,7 @@ jobs:
63117
env:
64118
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
65119
with:
66-
images: ghcr.io/${{ github.repository }}
120+
images: ghcr.io/${{ steps.repo.outputs.name }}
67121
tags: |
68122
type=semver,pattern={{version}}
69123
type=semver,pattern={{major}}.{{minor}}
@@ -78,6 +132,7 @@ jobs:
78132
org.opencontainers.image.base.name=alpine:3.22
79133
80134
- name: Build & push
135+
id: push
81136
uses: docker/build-push-action@v7
82137
with:
83138
context: .
@@ -91,10 +146,19 @@ jobs:
91146
labels: ${{ steps.meta.outputs.labels }}
92147
annotations: ${{ steps.meta.outputs.annotations }}
93148

149+
- name: Attest Docker image provenance
150+
uses: actions/attest-build-provenance@v4
151+
with:
152+
subject-name: ghcr.io/${{ steps.repo.outputs.name }}
153+
subject-digest: ${{ steps.push.outputs.digest }}
154+
push-to-registry: true
155+
94156
release:
95157
name: GitHub Release
96158
runs-on: ubuntu-latest
97-
needs: [build, docker]
159+
needs: [build, attest-binaries]
160+
permissions:
161+
contents: write
98162
steps:
99163
- uses: actions/checkout@v6
100164
with:

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@ go.work.sum
1717
# Pebblify runtime
1818
.pebblify-tmp/
1919
pebblify.lock
20-
state.json
20+
state.json
21+
22+
# Claude memory
23+
.claude/agent-memory/

CHANGELOG.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,42 @@
11
# Changelog
22

3+
## [v0.4.0](https://github.com/Dockermint/Pebblify/compare/v0.3.2...v0.4.0)
4+
5+
### Features
6+
7+
- feat(daemon): add `pebblify daemon` Linux-only subcommand with HTTP job queue API, FIFO queue with URL deduplication, LevelDB→PebbleDB pipeline, Prometheus metrics, and health probes ([#39](https://github.com/Dockermint/Pebblify/pull/39))
8+
- feat(daemon): add TOML config schema (config_version = 0) with env-var secret overlay for API, notify, telemetry, health, conversion, and save targets ([#39](https://github.com/Dockermint/Pebblify/pull/39))
9+
- feat(daemon): add store backends — local directory, SCP, and S3 via aws-sdk-go-v2 ([#39](https://github.com/Dockermint/Pebblify/pull/39))
10+
- feat(daemon): add Telegram notifier using stdlib net/http only; no third-party library ([#39](https://github.com/Dockermint/Pebblify/pull/39))
11+
- feat(daemon): add repack support for lz4, zstd, gzip, and none compression formats ([#39](https://github.com/Dockermint/Pebblify/pull/39))
12+
- feat(install): add `install-cli` (cross-platform) and `install-systemd-daemon` (Linux-only) Makefile targets; add systemd unit and placeholder env template ([#39](https://github.com/Dockermint/Pebblify/pull/39))
13+
- feat(install): add `install-podman` Makefile target and Podman Quadlet `.container` file for rootless daemon deployment ([#44](https://github.com/Dockermint/Pebblify/pull/44))
14+
15+
### Bug Fixes
16+
17+
- fix(container): remove `# hadolint ignore=` directives; replace fuzzy apk version constraints with exact pinned versions ([#43](https://github.com/Dockermint/Pebblify/pull/43))
18+
19+
### Documentation
20+
21+
- docs: v0.4.0 release documentation refresh — README installation split, daemon mode section, artifact attestation examples, and platform-split install guides ([#45](https://github.com/Dockermint/Pebblify/pull/45))
22+
- docs: land v0.4.0 roadmap and per-feature architecture specs ([#37](https://github.com/Dockermint/Pebblify/pull/37))
23+
24+
### CI
25+
26+
- ci: add darwin/amd64 and darwin/arm64 release binary targets to build matrix ([#38](https://github.com/Dockermint/Pebblify/pull/38))
27+
- ci: add SLSA provenance and SBOM attestations for release binaries and Docker images via `actions/attest-build-provenance` and `actions/attest-sbom` ([#38](https://github.com/Dockermint/Pebblify/pull/38))
28+
29+
### Security
30+
31+
- security(daemon): use HMAC-SHA-256 with constant-time comparison for API token validation to satisfy CodeQL timing-attack checks ([#39](https://github.com/Dockermint/Pebblify/pull/39))
32+
- security(daemon): reject symlink tar and zip entries during archive extraction to prevent path-traversal; covered by CodeQL analysis ([#39](https://github.com/Dockermint/Pebblify/pull/39))
33+
- security(daemon): enforce SSH known_hosts validation for SCP store; no host-key bypass permitted ([#39](https://github.com/Dockermint/Pebblify/pull/39))
34+
35+
### Chore / Governance
36+
37+
- chore: amend CLAUDE.md scope matrix to assign systemd unit files to `@container-engineer`; add env-template placeholder rule; land v0.4.0 governance docs ([#37](https://github.com/Dockermint/Pebblify/pull/37))
38+
- chore: apply `@it-consultant` retro tightenings — extend linter-suppression ban to all languages, add pre-push verify step 10b, per-agent scope tightenings ([#41](https://github.com/Dockermint/Pebblify/pull/41))
39+
340
## [v0.3.2](https://github.com/Dockermint/Pebblify/compare/v0.3.1...v0.3.2)
441

542
### Bug Fixes

CLAUDE.md

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ Apply to every file, every agent:
8686
- Type name trigger lint → rename idiomatic
8787
- Only ok suppression: build tags for platform-specific code (`//go:build linux`) with clear rationale
8888
- Rules apply to all agents, CTO, CEO equal
89+
- **NEVER** use linter suppression directives in any language: `//nolint`,
90+
`# hadolint ignore=`, `# shellcheck disable=`, `eslint-disable`, etc.
91+
Only exception: `//go:build <platform>` for platform-specific code,
92+
WITH adjacent rationale comment explaining why.
93+
- `@reviewer` MUST audit all `//go:build` directives; missing
94+
rationale = BLOCK verdict.
8995

9096
## Authority and Rule Immutability
9197

@@ -137,7 +143,7 @@ Each agent got **exclusive write scope**. No two agents write same files.
137143
| `docs/specs/`, `docs/ROADMAP.md` | `software-architect` | Read-only|
138144
| `docs/markdown/`, `docs/docusaurus/`, `README` | `technical-writer` | Read-only |
139145
| `.github/` | `devops` | Read-only |
140-
| `Dockerfile*`, `docker-compose*.yml`, `**/*.container`, `**/*.pod`, `**/*.volume`, `**/*.network`, `.dockerignore` | `container-engineer` | Read-only |
146+
| Dockerfile*, docker-compose*.yml, **/*.container, **/*.pod, **/*.volume, **/*.network, **/*.service, **/*.socket, **/*.timer, systemd/**, .dockerignore | container-engineer | Read-only |
141147
| Git operations | `sysadmin` | Forbidden |
142148
| Web research | `assistant` | Forbidden |
143149

@@ -149,6 +155,10 @@ Each agent got **exclusive write scope**. No two agents write same files.
149155
- **Container/Docker work**: `@container-engineer` = sole producer of container artifacts.
150156
- **Retrocontrol**: `@it-consultant` propose rule tightenings, **NEVER** relax.
151157

158+
### Security
159+
160+
- **Environment templates**: `.env.example`, `systemd/*.env.example` must contain placeholders only. No real secrets, API keys, passwords, or PII. Format: `VAR_NAME=` (empty) or `VAR_NAME={{placeholder}}`. Pre-commit verify no secrets leaked via templates.
161+
152162
### Rules for All Agents
153163

154164
- Every agent **MUST** read `CLAUDE.md` before start work
@@ -212,6 +222,14 @@ Every feature **MUST** follow iteration cycle. No skip. **CTO** orchestrate all
212222
| verdict: APPROVE or BLOCK
213223
| if BLOCK -> back to step 7 with findings
214224
|
225+
[10b. PRE-PUSH VERIFY] CTO MUST run locally before delegating to @sysadmin:
226+
| - `git status --porcelain` → 0 unstaged files in target scope
227+
| - `git diff --cached` reviewed
228+
| - `go build ./cmd/... ./internal/...` → 0 errors
229+
| - `go vet ./...` → 0 errors
230+
| - `golangci-lint run ./...` → 0 issues
231+
| - If Docker/compose changed: `docker build -t test .` → success
232+
| If any fails, return to step 7. CTO violation = workflow failure.
215233
[11. COMMIT] CTO -> @sysadmin branches from develop, stages, commits (GPG)
216234
| verifies all gates passed (@qa, @lead-dev, @reviewer)
217235
| refuses to commit if any gate is unsatisfied
@@ -221,10 +239,21 @@ Every feature **MUST** follow iteration cycle. No skip. **CTO** orchestrate all
221239
| links to issue from step 5 (Closes #<number>)
222240
| CEO opens the PR manually
223241
|
242+
[12b. ISSUE AUDIT] CTO -> @sysadmin verifies issue closure post-merge:
243+
| - Confirm issue #N closed automatically via `Closes #<number>` link
244+
| - If issue still open after PR merge: manually close
245+
| - Closure comment: "Resolved via Closes #<PR_NUMBER>"
246+
| - Report closure confirmation to CTO
247+
|
224248
[13. CI] @devops maintains the pipeline. CEO merges ONLY after:
225249
| - CI pipeline is fully green (all checks pass)
226250
| - CodeRabbit has approved (no unresolved comments)
227-
| If CI fails -> back to step 7 with CI error context
251+
| If CI fails (1st iteration):
252+
| - return to step 7 with CI error context
253+
| If CI fails (2nd+ iteration):
254+
| - CTO MUST send diagnosis + attempted fixes to @it-consultant
255+
| - @it-consultant audits root cause + recommends fix strategy
256+
| - CTO applies recommendations, only THEN delegates @go-developer
228257
| If CodeRabbit raises issues -> fix, commit, resolve
229258
|
230259
[14. DOCS] CTO -> @technical-writer updates documentation post-merge
@@ -246,6 +275,9 @@ Every feature **MUST** follow iteration cycle. No skip. **CTO** orchestrate all
246275
- **Step 13 loops** with step 7 till CI pass + CodeRabbit resolved. Fix root cause — never suppress lints, skip tests, add `//nolint` to pass CI. **No agent merge** — only CEO, only once CI + CodeRabbit approved.
247276
- **1 PR = 1 feature = 1 issue** (strict). PR close exactly one issue via `Closes #<number>`. No bundle unrelated change. `@sysadmin` enforce gate before commit.
248277
- CodeRabbit comments **MUST** be addressed + marked resolved once fixed.
278+
- @sysadmin MUST resolve each CodeRabbit thread via `gh api` or GitHub PR review API.
279+
- Each resolution MUST include commit hash reference that fixed the issue.
280+
- Silent closure forbidden — full audit trail (API records + commit linkage) mandatory.
249281
- `@technical-writer` invoked after merge.
250282
- `@it-consultant` invoked anytime to verify CLAUDE.md compliance + audit agent scope.
251283
- CEO give small task (bugfix, typo, config), `@software-architect` step reduce to brief assessment, but never fully skip.
@@ -269,6 +301,8 @@ CTO **MUST** collect confirmation from responsible agents before delegate to `@s
269301
- [ ] No commented-out code or debug statements — `@reviewer` (step 10)
270302
- [ ] No hardcoded credentials — `@reviewer` (step 10)
271303
- [ ] No `//nolint` comments outside build tags — `@reviewer` (step 10)
304+
- [ ] `git status --porcelain` empty or only intended scope — CTO (step 10b)
305+
- [ ] Local build + vet + lint verified post-commits — CTO (step 10b)
272306

273307
---
274308

0 commit comments

Comments
 (0)