ccf-parity-playbook
Load before touching setup.sh or setup.ps1 in claude-code-framework, or when asked "does the PowerShell installer match the bash one?", "why does setup work…
Skill by BostonOrange
Chalk Labs
Need help deploying ccf-parity-playbook?
Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/bostonorange-ccf-parity-playbook
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: devops, agent-building
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/ccf-parity-playbook
What's inside
- Skill name
ccf-parity-playbook- Description
- Load before touching setup.sh or setup.ps1 in claude-code-framework, or when asked "does the PowerShell installer match the bash one?", "why does setup work on macOS but fail on Windows?", "where do I add a new setup prompt / CCF_* variable?", or when a Windows CI setup job fails while bash tests pass. Covers the bash<->PowerShell mirror discipline, the parity checklist to walk for any setup change, sed/python3/PowerShell platform traps that have actually bitten, and the currently-open parity gaps.
- License
- MIT
- Instructions
- 115 lines in SKILL.md · view on GitHub
Files (1)
- SKILL.md
SKILL.md (first lines)
# CCF Parity Playbook: setup.sh <-> setup.ps1 Mirror Discipline
## Usage
Load this skill when you are about to change `setup.sh` or `setup.ps1`, review a diff that touches either, debug a Windows-only installer failure, or audit whether the two installers still match. **Not** for: what the setup scripts install, their flag semantics, and the CCF_* variable catalog (see **ccf-release-and-install**), or general test anatomy (see **ccf-testing-and-qa**). Doc-count drift is **ccf-doc-sync-campaign**'s territory.
Core law (from `.claude/rules/setup-scripts.md`): the two installers MUST have feature parity — every prompt, placeholder mapping, copy operation, conditional, and summary line in one must exist in the other. There is no shared implementation; parity is maintained by hand and enforced only partially by tests, which is why this playbook exists.
## Process: the parity walk for any setup change
1. **Make the change in `setup.sh` first.** It is the reference implementation (1332 lines vs 1153 in `setup.ps1`, as of 2026-07-11) and the only one the local test suite executes.
2. **Walk the parity checklist** (next section) row by row and mirror each touched row into `setup.ps1`. Match section numbering — both scripts use identical numbered prompt sections `1. Project Type` through `7. Design System` (`setup.sh:138-407`, `setup.ps1:133-356`, as of 2026-07-11).
3. **If you added a prompt, add its `CCF_*` variable to BOTH non-interactive resolvers**: `setup.sh` ~lines 59-136 (`${CCF_X:-default}` plus a validation `case`) and `setup.ps1` ~lines 51-131 (`if ($env:CCF_X) {...} else {default}` plus validation). CLAUDE.md ("Non-Interactive Setup") makes this mandatory. Also register the placeholder in `config/placeholders.json` if templates consume it.
4. **Run the gates**: `bash tests/check-placeholders.sh`, then `bash tests/check-setup-smoke.sh`, then full `bash tests/run-all.sh`.
5. **Exercise `setup.ps1` yourself** — `pwsh -NoProfile -File tests/check-setup-smoke.ps1` if you have pwsh, otherwise a manual `-DryRun` run. Do not rely on run-all or CI here (see "How to verify parity" for why).
6. If your change alters install output or counts, hand off to **ccf-doc-sync-campaign** before calling it done.
## The parity checklist
For any setup change, confirm each surface exists in both scripts:
| Surface | setup.sh location | setup.ps1 location |
|---|---|---|
| Prompt text + numbered section header | `## 1..7` sections, lines 138-407 | `# -- 1..7 --` sections, lines 133-356 |
| `CCF_*` non-interactive resolver entry | lines 59-136 | lines 51-131 |
| Placeholder mapping | python3 heredocs (lines 412, 749, 793, 837, 945) reading `config/*.json` | `ConvertFrom-Json` blocks (lines 359, 716, 738, 768, 783) |
| Copy operation | `cp` loops after line 722 | `Copy-Item` loops after line 616 |
| Conditional logic (skip rules for backend, internal-app extras) | mirrored branches | mirrored branches |
| Summary output line | Summary block, lines 1281-1332 | Summary block, lines 1105-1153 |
| Smoke-test case | `tests/check-setup-smoke.sh` (`run_setup_case`) | `tests/check-setup-smoke.ps1` (`Run-SetupCase`) |
Line numbers are as of 2026-07-11; treat them as anchors, re-grep before relying on them.
## Bash-side portability traps
- **Portable in-place sed.** macOS `sed -i` requires an argument, GNU sed forbids one. `setup.sh:40-47` defines the wrapper — use it, never raw `sed -i`:
```bash
sed_inplace() {
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' "$@"
else
sed -i "$@"
fi
}
```
Note: `.claude/rules/setup-scripts.md` still calls this "`$SED_INPLACE` variable"; the current implementation is the `sed_inplace()` function (as of 2026-07-11). Same intent.
- **Export before python3 heredocs.** The replacement engine is python3 reading `os.environ` (e.g. the bulk pass at `setup.sh:945-982`). Any shell variable a heredoc consumes MUST be `export`ed first — see the export blocks at lines 747 and 931-942. A forgotten export fails *silently*: `os.environ.get(...)` returns the default and the placeholder gets wrong-but-plausible content.
- **The `eval "$(python3 <<EOF)"` blind spot — guarded since 2026-07-11.** The four config loaders are now `CONFIG_VARS=$(python3 …) || { echo "ERROR: failed to load config/<file>…"; exit 1; }; eval "$CONFIG_VARS"`, so a python failure aborts loudly (matching ps1's `$ErrorActionPreference = "Stop"` behavior). History and doctor command: **ccf-debugging-playbook** "Silent half-configuration". Keep the guard when touching these blocks — a bare `eval "$(python3 …)"` reintroduces silent half-configuration under `set -e`.
## PowerShell-side traps (all actually happened)
| Commit | What bit | Lesson |
|---|---|---|
| `42e6a98` (on main) | Windows PowerShell 5.1 read BOM-less `setup.ps1` as ANSI and mis-decoded an em-dash in the pre-commit sentinel string as a smart-quote, closing the string early — parser errors before a single line ran. Fixed by adding a UTF-8 BOM (1-line diff). | `setup.ps1` MUST keep its UTF-8 BOM (verify: `head -c 3 setup.ps1 \| xxd` → `efbb bf`). Any tool that rewrites the file BOM-less re-breaks WPS 5.1. Beware em-dashes in PS string literals generally. |
| `e052200` (2026-06-11, merged 2026-07-11 — full story: ccf-failure-archaeology Entry 1) | The PS smoke harness itself used `$Home`/`$home`/`$args` as a parameter and locals — read-only automatic variables — and crashed before any scenario ran, so the CI job "ran" while gating nothing. | Never name PS parameters/locals after automatic variables (`$Home`, `$args`, `$input`, ...). A test harness that crashes at startup is indistinguishable from a red build people learn to ignore — check the harness first. |
| `0fe93ea` (2026-06-11, merged 2026-07-11 — same Entry 1) | Real `setup.ps1` bugs surfaced only after the harness was repaired: (a) `ConvertFrom-Json` rejects npm `package-lock.json`'s empty-string root key — needs `-AsHashtable` on PS 6+; (b) the branch-rename confirmation was asked far later than in `setup.sh`, so scripted/dry-run input reached the wrong prompt. | A broken harness hides an entire class of bugs; expect a bug wave right after fixing one. |
| Latent (no incident yet) | Null-vs-empty divergence in the placeholder map builders: `setup.sh` python uses `os.environ.get(env, default)` — an exported-but-empty var wins with `''` (`setup.sh:959-961`); `setup.ps1` falls back to the `config/placeholders.json` default whenever the looked-up variable is `$null` (`setup.ps1:787-798`). A resolver path leaving a variable empty (`''` in bash, unassigned in PS) yields different installed content per platform. Currently unreachable — both resolvers assign every variable — but any new resolver branch can arm it. | When adding resolver variables, always assign a concrete string on every path in both scripts. |
## Known open parity gaps (as of 2026-07-11, each verified in the scripts)
Candidates to fix, not documentation of intent. (A former gap — branch-rename prompt ordering — was closed when `0fe93ea` merged on 2026-07-11: ps1 now asks right after the base-branch prompt, `setup.ps1:296-325`, mirroring `setup.sh:307`.)
1. **`-DryRun` has no early-exit summary in `setup.ps1`.** `setup.sh --dry-run` prints a `[DRY-RUN]` plan and `exit 0` (lines 673-716). `setup.ps1` threads `if (-not $DryRun)` and `[DRY-RUN] Would copy` messages through the whole script and ends by printing "Setup Complete!" even in dry-run — its only `exit 0`s are `-Help` and `-Reset`.
(Three former gaps closed 2026-07-11 in one parity commit: `-Help` now documents `-NonInteractive`; reset prints the "To fully clean up…" hint; the summary prints the conditional `CLAUDE.md — project instructions (customize!)` line. The same commit also mirrored setup.sh's new non-interactive tracker-detail validation and `.env` family gitignore handling into ps1.)
If you close one, mirror the fix, re-verify this list, and update this skill.
## How to verify parity
| Tool | What it checks | Blind spot |
|---|---|---|
| `bash tests/check-placeholders.sh` | Static: every `{{PLACEHOLDER}}` in `templates/` and `skills/` has a replacement in BOTH scripts (entries in `config/placeholders.json` count as present for both). | Only placeholders — nothing about prompts, ordering, output, or behavior. |
| `bash tests/check-setup-smoke.sh` | Behavioral, **bash only**: runs `setup.sh` in throwaway repos with isolated HOME (interactive-scripted, dry-run, non-interactive, missing-CCF_PROJECT_TYPE cases). | Never executes `setup.ps1`. |
| `tests/check-setup-smoke.ps1` | Behavioral for `setup.ps1`, mirror scenarios. | **TRAP:** `tests/run-all.sh` collects `check-*.sh` only (line 19) — the `.ps1` harness is CI-only (`.github/workflows/framework-tests.yml`, `powershell` job on windows-latest). A green local `run-all.sh` proves nothing about `setup.ps1`. (The harness startup crash that once disabled this gate was fixed by `e052200`, merged 2026-07-11 — history: ccf-failure-archaeology Entry 1.) |
## Edge Cases
| Situation | What to do |
|---|---|
| No pwsh available locally, change touches setup.ps1 | State it untested on PowerShell in the PR and watch the CI windows job (its harness has been sound since the 2026-07-11 merge; if it crashes at startup rather than failing an assert, suspect the harness per Entry 1's lesson). |
| Change only makes sense on one platform (e.g. `chmod +x`) | Mirror the *intent*: ps1 skips chmod but must still copy hooks; leave a comment in both scripts pointing at the counterpart. |
| Placeholder check passes but installed files differ per platform | Suspect the null-vs-empty divergence or a missing export before a python3 heredoc — both are invisible to the static check. |
| Corrupt or hand-edited `config/*.json` | Both scripts now fail loudly (guarded loaders in bash since 2026-07-11; `$ErrorActionPreference = "Stop"` in ps1). If bash instead continues silently, the loader guard was removed — restore it. |
| Editing `tests/check-setup-smoke.ps1` | Grep your diff for `$Home`, `$home`, `$args`, `$input` as parameter/local names before committing. |
| Tempted to fix a gap in only one script | Don't. Fixing sh-only widens the gap; a parity fix touches both scripts in one commit. |
## Related Skills
- **ccf-release-and-install** — what the installers actually do, flag semantics, CCF_* interface end-to-end; switch there for install/rollback questions.
- **ccf-domain-reference** — the CCF_* variable and `config/*.json` catalog.
- **ccf-testing-and-qa** — full anatomy of `tests/*.sh` and what each gates/misses.
- **ccf-doc-sync-campaign** — when your setup change alters counts or summary lines that appear in docs.
- **ccf-change-control** — merge gates and session-end workflow after any framework edit.
- **ccf-debugging-playbook** — symptom-first triage when an installer misbehaves and you don't yet know it's a parity issue.
## Provenance and maintenance
Re-verify before trusting; all facts dated 2026-07-11:
- Parity contract text: `cat .claude/rules/setup-scripts.md`
- Line counts / anchors: `wc -l setup.sh setup.ps1`; prompt sections: `grep -n '── [0-9]\|-- [0-9]' setup.sh setup.ps1`
- `sed_inplace` definition: `grep -n -A6 'sed_inplace()' setup.sh`
- loader guards present: `grep -c 'failed to load config' setup.sh` (expect 4)
- BOM present: `head -c 3 setup.ps1 | xxd` (expect `efbb bf`)
- Commit history: `git show --stat 42e6a98 e052200 0fe93ea`; merge status: `git branch --contains e052200` (merged 2026-07-11; expect the current integration branch listed)
- Harness fix present: `grep -n '\$Home\b\|\$args\b' tests/check-setup-smoke.ps1` (expect only the line-51 warning comment)
- Gap 1: `grep -n 'exit 0' setup.ps1` (dry-run early exit added when a third appears); gap 2: `sed -n '11,16p' setup.ps1`; gap 3: `grep -n 'fully clean up' setup.sh setup.ps1`; gap 4: `grep -n 'customize!' setup.sh setup.ps1`; closed rename-order gap: `grep -n 'Rename to' setup.sh setup.ps1` (both ~line 300)
- run-all glob trap: `grep -n 'check-\*.sh' tests/run-all.sh`; CI wiring: `cat .github/workflows/framework-tests.yml`
**Re-verify this skill whenever**: `setup.sh`/`setup.ps1`/`tests/check-setup-smoke.*` change (line-number anchors and the gaps list shift), or a new prompt/CCF_* variable is added. The 2026-07-11 assessment-branch merge is already reflected here.From BostonOrange/claude-code-framework, MIT.
More from BostonOrange/claude-code-framework
- 0.514score
ccf-architecture-contract
BostonOrange
Load when you need to know WHY claude-code-framework is shaped the way it is before changing its structure — questions like "where does this new file belong…
SkillCFreshness: C★ 3Claude Code +9 - 0.511score
install-framework
BostonOrange
Install the Claude Code Framework into the current repo by cloning it from GitHub (no local clone path needed).
SkillCFreshness: C★ 3Claude Code +9 - 0.510score
ccf-release-and-install
BostonOrange
Load when installing or uninstalling the claude-code-framework in a target repo, or answering how installation works — driving setup.sh / setup.ps1, choosing…
SkillCFreshness: C★ 3Claude Code +9 - 0.510score
ccf-build-and-env
BostonOrange
Load when setting up a dev environment for the claude-code-framework repo itself — fresh clone, new machine, new agent session — or when asked "how do I…
SkillCFreshness: C★ 3Claude Code +9 - 0.510score
ccf-dogfood-and-drift
BostonOrange
Load when working with claude-code-framework's own .claude/ directory or when tests/check-dogfood-drift.sh fails — symptoms like "Unexpected .claude/template…
SkillCFreshness: C★ 3Claude Code +9 - 0.510score
ccf-onboarding-tour
BostonOrange
Load this at the start of any first session in the claude-code-framework repo — when you (human or model) have zero context and need the right mental model…
SkillCFreshness: C★ 3Claude Code +9 - 0.510score
ccf-doc-sync-campaign
BostonOrange
Load when a count or table in claude-code-framework docs looks stale, when adding/removing a skill/agent/command/rule/hook (which changes counts everywhere)…
SkillCFreshness: C★ 3Claude Code +9 - 0.508score
team
BostonOrange
Spawn pre-configured agent teams for parallel review, analysis, or implementation tasks
SkillCFreshness: C★ 3Claude Code +9 - 0.508score
improve
BostonOrange
Self-improvement — analyze the project and update AGENTS.md, rules, settings, and agents to improve AI effectiveness
SkillCFreshness: C★ 3Claude Code +9 - 0.489score
ccf-failure-archaeology
BostonOrange
Load before re-investigating anything in claude-code-framework that smells like a past battle — "why did the PowerShell CI job fail?", "didn't we already fix…
SkillCFreshness: C★ 3Claude Code +9 - 0.485score
ccf-debugging-playbook
BostonOrange
Load when something in claude-code-framework is FAILING and you need to find the root cause — a tests/check-*.sh test went red (dogfood-drift, consistency…
SkillCFreshness: C★ 3Claude Code +9 - 0.485score
ccf-testing-and-qa
BostonOrange
Load this before claiming any claude-code-framework change is "done", before running or extending tests/run-all.sh, or when a check-*.sh test fails and you…
SkillCFreshness: C★ 3Claude Code +9
Signals
- Stars
- 3
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Jul 13, 2026 (3 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from BostonOrange
- 0.514score
ccf-architecture-contract
BostonOrange
Load when you need to know WHY claude-code-framework is shaped the way it is before changing its structure — questions like "where does this new file belong…
SkillCFreshness: C★ 3Claude Code +9 - 0.511score
install-framework
BostonOrange
Install the Claude Code Framework into the current repo by cloning it from GitHub (no local clone path needed).
SkillCFreshness: C★ 3Claude Code +9 - 0.510score
ccf-build-and-env
BostonOrange
Load when setting up a dev environment for the claude-code-framework repo itself — fresh clone, new machine, new agent session — or when asked "how do I…
SkillCFreshness: C★ 3Claude Code +9 - 0.510score
ccf-doc-sync-campaign
BostonOrange
Load when a count or table in claude-code-framework docs looks stale, when adding/removing a skill/agent/command/rule/hook (which changes counts everywhere)…
SkillCFreshness: C★ 3Claude Code +9 - 0.510score
ccf-dogfood-and-drift
BostonOrange
Load when working with claude-code-framework's own .claude/ directory or when tests/check-dogfood-drift.sh fails — symptoms like "Unexpected .claude/template…
SkillCFreshness: C★ 3Claude Code +9 - 0.510score
ccf-onboarding-tour
BostonOrange
Load this at the start of any first session in the claude-code-framework repo — when you (human or model) have zero context and need the right mental model…
SkillCFreshness: C★ 3Claude Code +9
Done for you
Rather not set it up yourself?
Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.
See how we build AI agents →Read the case studies
Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.
- launches shipped
- 50+
- launches shipped
- media placements
- 500+
- media placements
- founders on every account
- 2
- founders on every account
Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block
Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.
Get ccf-parity-playbook running in your business
Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.
Cite this page
ccf-parity-playbook skill. Agent Mart. https://agentmart.dev/skills/bostonorange-ccf-parity-playbook (last updated 2026-10-24)