Skip to content

Commit 69cbeb7

Browse files
forkrulclaude
andauthored
docs: phased single-founder production-readiness plan (#3)
* docs: phased single-founder production-readiness plan Five phases from licensing baseline to automated maintenance: license + requirements, CI safety net with macOS portability, versioned releases, installer self-diagnosis (--verify/--dry-run/ prune), and dependabot-driven submodule bumps. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014xQJ2a7n3KXhouygPtCK5Z * feat: production readiness — license, CI, portable installer, release + maintenance scaffolding Implements phases 0-4 of docs/production-readiness.md: - MIT LICENSE; README requirements, pinned-tag install, upgrading, support posture and licensing sections - install.sh: bash 3.2 / stock macOS compatible (drop declare -A and readlink -f); new --verify, --dry-run; stale-link pruning on install; uninstall now sweeps every owned link, not just known names - tests/smoke.sh: end-to-end installer test (idempotency, ownership guarantee, prune, verify, dry-run, uninstall) in a throwaway repo - CI: shellcheck + syntax, alias-symlink and frontmatter integrity, smoke test on ubuntu + macos (incl. /bin/bash 3.2), changelog gate - Dependabot (gitsubmodule + github-actions, monthly); bug-report issue template asking for --verify output - CLAUDE.md: release ritual (semver, tag from changelog) and submodule bump policy; plan doc updated with remaining manual GitHub-side steps (cut v0.1.0, enable branch protection) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014xQJ2a7n3KXhouygPtCK5Z --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 72a49cd commit 69cbeb7

10 files changed

Lines changed: 632 additions & 40 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
name: Bug report
3+
about: Something broke — installer, a stage skill, or a gate behaving wrongly
4+
labels: bug
5+
---
6+
7+
## What happened
8+
9+
<!-- What did you run, what did you expect, what did you get? -->
10+
11+
## Environment
12+
13+
- OS:
14+
- `bash --version` (first line):
15+
- damascus version (`git -C vendor/damascus describe --tags --always`):
16+
17+
## Installer health
18+
19+
<!-- Paste the full output of: -->
20+
21+
```
22+
./vendor/damascus/install.sh --verify
23+
```
24+
25+
## For skill/pipeline bugs
26+
27+
<!-- Which stage (forge / anvil / temper / quench / smithy), and the relevant
28+
artifact paths (.prd/NNN_*.md, specs/NNN-*/...) if applicable. -->

.github/dependabot.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
version: 2
2+
updates:
3+
# vendor/superpowers and vendor/spec-kit — the CI smoke test validates each
4+
# bump (KEEP-class linking fails if upstream renames or removes a skill).
5+
# Policy (see CLAUDE.md): only merge bumps that land on an upstream tag.
6+
- package-ecosystem: gitsubmodule
7+
directory: /
8+
schedule:
9+
interval: monthly
10+
11+
- package-ecosystem: github-actions
12+
directory: /
13+
schedule:
14+
interval: monthly

.github/workflows/ci.yml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
8+
jobs:
9+
lint:
10+
name: shellcheck + repo integrity
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: bash syntax check
16+
run: bash -n install.sh tests/smoke.sh
17+
18+
- name: shellcheck
19+
run: shellcheck install.sh tests/smoke.sh
20+
21+
- name: alias symlinks are relative and resolve to stage skills
22+
run: |
23+
for l in skills/*; do
24+
[ -L "$l" ] || continue
25+
target="$(readlink "$l")"
26+
case "$target" in
27+
/*) echo "::error::$l is an absolute symlink"; exit 1 ;;
28+
esac
29+
[ -f "$l/SKILL.md" ] || { echo "::error::$l does not resolve to a skill"; exit 1; }
30+
done
31+
32+
- name: every stage skill and agent named in install.sh exists on disk
33+
run: |
34+
for s in forge anvil temper quench smithy; do
35+
[ -f "skills/$s/SKILL.md" ] || { echo "::error::skills/$s/SKILL.md missing"; exit 1; }
36+
done
37+
for a in bdd-scenario-writer tdd-test-generator playwright-e2e-tester fastapi-implementer labcoat; do
38+
[ -f "agents/$a.md" ] || { echo "::error::agents/$a.md missing"; exit 1; }
39+
done
40+
41+
- name: frontmatter lint (name + description)
42+
run: |
43+
for f in skills/*/SKILL.md agents/*.md; do
44+
head -1 "$f" | grep -qx -- '---' || { echo "::error::$f has no YAML frontmatter"; exit 1; }
45+
awk '/^---$/{c++; next} c==1 && /^name:/{n=1} c==1 && /^description:/{d=1} END{exit !(n && d)}' "$f" \
46+
|| { echo "::error::$f frontmatter is missing name or description"; exit 1; }
47+
done
48+
49+
smoke:
50+
name: install/uninstall smoke test
51+
strategy:
52+
fail-fast: false
53+
matrix:
54+
os: [ubuntu-latest, macos-latest]
55+
runs-on: ${{ matrix.os }}
56+
steps:
57+
- uses: actions/checkout@v4
58+
with:
59+
submodules: recursive
60+
61+
- name: smoke test (default bash)
62+
run: tests/smoke.sh
63+
64+
- name: smoke test (stock macOS bash 3.2)
65+
if: runner.os == 'macOS'
66+
run: SMOKE_BASH=/bin/bash tests/smoke.sh
67+
68+
changelog:
69+
name: changelog updated
70+
if: github.event_name == 'pull_request' && github.actor != 'dependabot[bot]'
71+
runs-on: ubuntu-latest
72+
steps:
73+
- uses: actions/checkout@v4
74+
with:
75+
fetch-depth: 0
76+
77+
- name: PR touches CHANGELOG.md
78+
run: |
79+
git fetch origin "${{ github.base_ref }}" --depth=1
80+
if git diff --name-only "origin/${{ github.base_ref }}...HEAD" | grep -qx 'CHANGELOG.md'; then
81+
echo "CHANGELOG.md updated"
82+
else
83+
echo "::error::every PR must update CHANGELOG.md under [Unreleased] (see CLAUDE.md)"
84+
exit 1
85+
fi

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,18 @@ All notable changes to this project are documented here, following [Common Chang
1111
- Add the five quench dispatch agents: `bdd-scenario-writer`, `tdd-test-generator`, `playwright-e2e-tester`, `fastapi-implementer`, `labcoat`
1212
- Add `install.sh` for symlinking skills and agents into a consumer repo's `.claude/`
1313
- Vendor [obra/superpowers](https://github.com/obra/superpowers) v4.3.1 and [github/spec-kit](https://github.com/github/spec-kit) v0.10.1 as pinned submodules
14+
- Add `docs/production-readiness.md` — phased single-founder plan (licensing, CI, releases, installer hardening, automated maintenance)
15+
- Add MIT `LICENSE` (vendored submodules retain their upstream licenses)
16+
- Add CI workflow: shellcheck + syntax checks, alias-symlink and frontmatter integrity, install/uninstall smoke test on Ubuntu and macOS (including stock bash 3.2), and a changelog-updated gate on PRs
17+
- Add `tests/smoke.sh` — end-to-end installer test against a throwaway consumer repo (idempotency, ownership guarantee, pruning, verify, dry-run, uninstall)
18+
- Add `install.sh --verify` (link health report for bug reports) and `--dry-run` (print planned actions without touching anything)
19+
- Add stale-link pruning: install now sweeps damascus-owned links whose names are no longer shipped; uninstall removes every owned link, not just known names
20+
- Add Dependabot config for monthly vendor-submodule and GitHub Actions bumps, and a bug-report issue template
21+
- Add README sections: requirements, pinned-tag install, upgrading, support posture and licensing; document the release ritual and submodule bump policy in CLAUDE.md
1422

1523
### Changed
1624

25+
- Make `install.sh` portable to bash 3.2 / stock macOS (replace `declare -A` and `readlink -f` with portable equivalents)
1726
- Replace the external-API review gate in `temper` with a fully local adversarial panel (3 critic lenses + judge; A++ = two consecutive zero-blocking rounds, max 5 rounds)
1827

1928
### Fixed

CLAUDE.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,24 @@ Guidance for Claude Code when working in this repository.
44

55
## What this repo is
66

7-
Damascus packages the **SPDD pipeline** (forge → anvil → temper → quench, orchestrated by smithy) as Claude Code skills, consumed by other repos as a `vendor/damascus` submodule via `install.sh`. There is no build step or test runner — "running" this repo means exercising `install.sh` and the SKILL.md files.
7+
Damascus packages the **SPDD pipeline** (forge → anvil → temper → quench, orchestrated by smithy) as Claude Code skills, consumed by other repos as a `vendor/damascus` submodule via `install.sh`. There is no build step — "running" this repo means exercising `install.sh` and the SKILL.md files; `tests/smoke.sh` is the test suite.
88

99
## Working here
1010

1111
- The five stage skills under `skills/` are the product. Keep them concise; every behavioral contract lives in the SKILL.md body, not in external docs.
1212
- `skills/<alias>` entries are relative symlinks to stage dirs — preserve them.
13-
- `vendor/superpowers` and `vendor/spec-kit` are **pinned submodules**. Bump deliberately (checkout a tag, commit the pointer); never edit vendor content.
14-
- `install.sh` must stay idempotent and only ever touch symlinks that resolve into this checkout. Test with a throwaway repo:
15-
```bash
16-
mkdir -p /tmp/t && cd /tmp/t && git init -q && /path/to/damascus/install.sh && /path/to/damascus/install.sh --uninstall
17-
```
18-
- Every PR updates `CHANGELOG.md` under `[Unreleased]` (Common Changelog categories).
13+
- `vendor/superpowers` and `vendor/spec-kit` are **pinned submodules**. Bump deliberately (checkout a tag, commit the pointer); never edit vendor content. Dependabot opens monthly bump PRs — only merge bumps that land on an upstream **tag**, and when superpowers adds or renames skills, re-check the DENY/KEEP/CONDITIONAL table in the README (a new upstream skill overlapping a stage becomes DENY; a renamed KEEP skill needs the `SUPERPOWERS_KEEP` array in `install.sh` updated — CI's smoke test fails until it is).
14+
- `install.sh` must stay idempotent, bash 3.2 compatible (no `declare -A`, no GNU-only flags without a fallback), and only ever touch symlinks that resolve into this checkout. `tests/smoke.sh` encodes these guarantees against a throwaway repo — run it locally before pushing; CI runs it on Ubuntu and macOS (including stock bash 3.2).
15+
- Every PR updates `CHANGELOG.md` under `[Unreleased]` (Common Changelog categories). CI enforces this.
1916
- Branch → PR → squash merge. Never push to `master` directly.
2017
- The temper stage is **local-only by design** — do not reintroduce external-API review dependencies.
18+
19+
## Releasing
20+
21+
Semver. Breaking changes to a skill contract or to `install.sh` behavior bump the major version (the minor version while pre-1.0). To cut a release from `master`:
22+
23+
1. Move the `[Unreleased]` section of `CHANGELOG.md` under a `## [X.Y.Z] - YYYY-MM-DD` heading (via a normal PR).
24+
2. `git tag vX.Y.Z && git push origin vX.Y.Z`
25+
3. Create a GitHub Release from the tag; the body is that changelog section verbatim.
26+
27+
Consumers pin tags (see the README install/upgrading sections) — never point them at `master`.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Carel van Rooyen
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,22 @@ Every stage halts at its gate for user signoff. State lives in the disk artifact
3232

3333
Temper needs **no external API**. Each round, three critic subagents with distinct lenses (completeness, feasibility, testability) try to *refute* the spec triplet; a judge dedupes findings and assigns a rating. Blocking findings are applied, the round is logged, and the loop repeats. **A++ requires two consecutive rounds with zero blocking findings** (max 5 rounds, then escalate). The full trail lives in `specs/NNN-<slug>/review.md`, append-only.
3434

35+
## Requirements
36+
37+
- git ≥ 2.13 (submodules)
38+
- bash 3.2+ (`install.sh` runs on stock macOS bash)
39+
- a filesystem with symlink support
40+
3541
## Install
3642

37-
From your repo root:
43+
From your repo root, pinning a release tag:
3844

3945
```bash
4046
git submodule add <this-repo-url> vendor/damascus
47+
git -C vendor/damascus checkout v0.1.0 # pin a release, not a moving branch
4148
git submodule update --init --recursive
4249
./vendor/damascus/install.sh
50+
git add .gitmodules vendor/damascus && git commit -m "chore: vendor damascus v0.1.0"
4351
```
4452

4553
This symlinks into your `.claude/`:
@@ -48,7 +56,27 @@ This symlinks into your `.claude/`:
4856
- 5 quench agents (`bdd-scenario-writer`, `tdd-test-generator`, `playwright-e2e-tester`, `fastapi-implementer`, `labcoat`) → `.claude/agents/`
4957
- the KEEP-class [obra/superpowers](https://github.com/obra/superpowers) skills (see policy below) → `.claude/skills/`
5058

51-
Re-run any time to refresh; `./vendor/damascus/install.sh --uninstall` removes everything it owns and nothing else.
59+
Re-run any time to refresh; the install prunes damascus-owned links whose names are no longer shipped. Other modes:
60+
61+
```bash
62+
./vendor/damascus/install.sh --verify # link health report; exit 1 if repair is needed
63+
./vendor/damascus/install.sh --dry-run # print planned actions, touch nothing
64+
./vendor/damascus/install.sh --uninstall # removes everything it owns and nothing else
65+
```
66+
67+
`--verify` output is the first thing to include in a bug report.
68+
69+
## Upgrading
70+
71+
```bash
72+
git -C vendor/damascus fetch --tags
73+
git -C vendor/damascus checkout v0.2.0 # the new release
74+
git submodule update --init --recursive
75+
./vendor/damascus/install.sh # idempotent: refreshes and prunes
76+
git add vendor/damascus && git commit -m "chore: bump damascus to v0.2.0"
77+
```
78+
79+
Breaking changes to skill contracts or `install.sh` behavior are called out in [CHANGELOG.md](CHANGELOG.md) and, past 1.0, bump the major version.
5280

5381
## Vendored Submodules
5482

@@ -90,6 +118,12 @@ The skills degrade gracefully — each of these is used when present and skipped
90118
- **Phase signalling** — if your repo has a status-bar helper (e.g. tmux), quench calls it at red/amber/green transitions
91119
- **Drift detection** — if a pre-commit hook flags code changes without spec changes, smithy halts on it
92120

121+
## Support & license
122+
123+
Maintained by one person; issues are welcome and responses are best-effort. Please include your OS, `bash --version`, and `install.sh --verify` output when reporting installer problems.
124+
125+
MIT licensed (see [LICENSE](LICENSE)). The vendored submodules `vendor/superpowers` and `vendor/spec-kit` retain their own upstream licenses and are not relicensed by this repo.
126+
93127
## Credits
94128

95129
- Martin Fowler — [*Structured Prompt-Driven Development*](https://martinfowler.com/articles/structured-prompt-driven/) (REASONS Canvas, Golden Rule)

0 commit comments

Comments
 (0)