diff --git a/.github/workflows/quality.yaml b/.github/workflows/quality.yaml
new file mode 100644
index 0000000..3b7f6c8
--- /dev/null
+++ b/.github/workflows/quality.yaml
@@ -0,0 +1,46 @@
+name: Quality & Validation
+
+# Runs the module's own gates on every PR:
+# - every skill test suite (uv run, PEP 723; ffmpeg and chromium installed
+# so the render and HTML-graphics suites exercise instead of skip)
+# - the genericity release gate (nothing user-, brand-, or show-specific ships)
+
+"on":
+ pull_request:
+ branches: ["**"]
+ workflow_dispatch:
+
+jobs:
+ tests:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Install uv
+ uses: astral-sh/setup-uv@v5
+
+ - name: Install ffmpeg and rsvg
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y ffmpeg librsvg2-bin
+
+ - name: Install chromium for the HTML graphics lane
+ run: uv run skills/mc-graphics/scripts/html_to_png.py --install-chromium
+ continue-on-error: true
+
+ - name: Run all skill test suites
+ run: |
+ set -e
+ fail=0
+ for t in $(find skills -path "*/tests/test-*.py" | sort); do
+ echo "=== $t"
+ if ! uv run "$t"; then
+ echo "FAIL: $t"
+ fail=1
+ fi
+ done
+ exit $fail
+
+ - name: Genericity release gate
+ run: uv run skills/mc-setup/scripts/lint_genericity.py skills/ docs/ README.md CHANGELOG.md
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
new file mode 100644
index 0000000..84474f2
--- /dev/null
+++ b/.github/workflows/release.yaml
@@ -0,0 +1,132 @@
+name: Release
+
+# Manual release: bumps the version in .claude-plugin/marketplace.json,
+# commits, tags vX.Y.Z, keyless-signs the tag SHA with cosign, and creates
+# the GitHub Release with the matching CHANGELOG section as notes.
+# Run from main only. The quality gates run first; a red gate stops the release.
+
+on:
+ workflow_dispatch:
+ inputs:
+ bump:
+ description: "Version bump type"
+ required: true
+ default: "patch"
+ type: choice
+ options:
+ - patch
+ - minor
+ - major
+
+concurrency:
+ group: release
+ cancel-in-progress: false
+
+permissions:
+ id-token: write
+ contents: write
+
+jobs:
+ release:
+ if: github.repository == 'bmad-code-org/bmad-manticore' && github.ref == 'refs/heads/main'
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Install uv
+ uses: astral-sh/setup-uv@v5
+
+ - name: Install ffmpeg and rsvg
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y ffmpeg librsvg2-bin
+
+ - name: Run all skill test suites
+ run: |
+ set -e
+ fail=0
+ for t in $(find skills -path "*/tests/test-*.py" | sort); do
+ uv run "$t" || { echo "FAIL: $t"; fail=1; }
+ done
+ exit $fail
+
+ - name: Genericity release gate
+ run: uv run skills/mc-setup/scripts/lint_genericity.py skills/ docs/ README.md CHANGELOG.md
+
+ - name: Configure git user
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "github-actions[bot]@users.noreply.github.com"
+
+ - name: Bump version in marketplace.json
+ id: version
+ run: |
+ python3 - "${{ inputs.bump }}" <<'EOF'
+ import json, sys
+ bump = sys.argv[1]
+ path = ".claude-plugin/marketplace.json"
+ data = json.load(open(path))
+ plugin = data["plugins"][0]
+ major, minor, patch = (int(x) for x in plugin["version"].split("."))
+ if bump == "major":
+ major, minor, patch = major + 1, 0, 0
+ elif bump == "minor":
+ minor, patch = minor + 1, 0
+ else:
+ patch += 1
+ plugin["version"] = f"{major}.{minor}.{patch}"
+ with open(path, "w") as f:
+ json.dump(data, f, indent=2)
+ f.write("\n")
+ print(plugin["version"])
+ EOF
+ VERSION=$(python3 -c "import json; print(json.load(open('.claude-plugin/marketplace.json'))['plugins'][0]['version'])")
+ echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
+ echo "tag=v${VERSION}" >> "$GITHUB_OUTPUT"
+
+ - name: Commit, tag, and push
+ run: |
+ TAG="${{ steps.version.outputs.tag }}"
+ git add .claude-plugin/marketplace.json
+ git commit -m "chore(release): ${TAG} [skip ci]"
+ git tag -a "${TAG}" -m "BMad Manticore ${{ steps.version.outputs.version }}"
+ git push origin main --follow-tags
+
+ - name: Install cosign
+ uses: sigstore/cosign-installer@v3
+
+ - name: Sign tag SHA with cosign (keyless)
+ run: |
+ TAG="${{ steps.version.outputs.tag }}"
+ SHA=$(git rev-parse "${TAG}")
+ printf '%s' "${SHA}" > "${TAG}.sha"
+ cosign sign-blob --yes \
+ --output-signature "${TAG}.sig" \
+ --output-certificate "${TAG}.pem" \
+ "${TAG}.sha"
+
+ - name: Extract CHANGELOG section
+ run: |
+ VERSION="${{ steps.version.outputs.version }}"
+ awk -v ver="$VERSION" '
+ $0 ~ "^## " ver { on=1; next }
+ on && /^## / { exit }
+ on { print }
+ ' CHANGELOG.md > release-notes.md
+ if [ ! -s release-notes.md ]; then
+ echo "No CHANGELOG section for ${VERSION}; using a pointer." > release-notes.md
+ echo "See CHANGELOG.md." >> release-notes.md
+ fi
+
+ - name: Create GitHub Release
+ env:
+ GH_TOKEN: ${{ github.token }}
+ run: |
+ TAG="${{ steps.version.outputs.tag }}"
+ gh release create "${TAG}" \
+ --title "BMad Manticore ${{ steps.version.outputs.version }}" \
+ --notes-file release-notes.md \
+ "${TAG}.sha" "${TAG}.sig" "${TAG}.pem"
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 0000000..9b4890f
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,77 @@
+
+
+
+
+
+BMad Manticore — the guides
+
+
+
+
+
+
+

+
+ BMad Manticore · the guides
+ An AI video production pipeline as skills: brain dump to a rough cut sitting in your editor, in your own words, with approval gates at every taste decision. Manny the Manticore runs the studio; these guides show you around it.
+
+
+ ▸Working with Manny
+ Nine scenarios, from a fresh install to a published video: what you say, what Manny does, what you approve, and what you get.
+
+
+ ▸Manny, under the hood
+ The technical deck: the tools and models behind every lane, the render pipeline, the graphics engines, and the film-strip flow diagrams.
+
+
+ ▸Configure your studio
+ The written walkthrough: install, the setup interview, your brand folder, formats, and your first video.
+
+
+
+
+
+
+