@hegemonart/get-design-done 1.14.1 → 1.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +14 -0
- package/agents/design-research-synthesizer.md +32 -5
- package/connections/claude-design.md +106 -22
- package/package.json +4 -1
- package/reference/BRANCH-PROTECTION.md +0 -65
- package/scripts/apply-branch-protection.sh +0 -75
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
},
|
|
6
6
|
"metadata": {
|
|
7
7
|
"description": "Get Design Done — 5-stage agent-orchestrated design pipeline with 9 connections, handoff-first workflow, bidirectional Figma write-back, 22+ specialized agents, queryable knowledge layer (intel store, dependency analysis, learnings extraction), and a self-improvement loop (reflector, frontmatter + budget feedback, global-skills layer). Ships with a full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows) and release automation (auto-tag + GitHub Release + release-time smoke test).",
|
|
8
|
-
"version": "1.14.
|
|
8
|
+
"version": "1.14.2"
|
|
9
9
|
},
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "get-design-done",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"description": "Agent-orchestrated 5-stage design pipeline: Brief → Explore → Plan → Design → Verify. 22+ specialized agents, 9 connections (Figma, Refero, Preview, Storybook, Chromatic, Figma Writer, Graphify, Pinterest, Claude Design), Claude Design handoff, bidirectional Figma write-back, and a queryable intel store (.design/intel/) for dependency and learnings queries. Standalone commands: style, darkmode, compare, figma-write, graphify, handoff, analyze-dependencies, skill-manifest, extract-learnings. Embeds NNG heuristics, WCAG thresholds, typographic systems, motion framework, and anti-pattern catalog. Ships with a full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows) and release automation. Optimization layer (v1.0.4.1, retroactive): gdd-router + gdd-cache-manager skills, PreToolUse budget-enforcer hook, tier-aware agent frontmatter, lazy checker gates, streaming synthesizer, /gdd:warm-cache + /gdd:optimize commands, and cost telemetry at .design/telemetry/costs.jsonl — targeting 50-70% per-task token-cost reduction with no quality-floor regression.",
|
|
15
|
-
"version": "1.14.
|
|
15
|
+
"version": "1.14.2",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "hegemonart"
|
|
18
18
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "get-design-done",
|
|
3
3
|
"short_name": "gdd",
|
|
4
|
-
"version": "1.14.
|
|
4
|
+
"version": "1.14.2",
|
|
5
5
|
"description": "Agent-orchestrated 5-stage design pipeline: Brief → Explore → Plan → Design → Verify. 22+ specialized agents, 9 connections (Figma, Refero, Preview, Storybook, Chromatic, Figma Writer, Graphify, Pinterest, Claude Design), handoff-first workflow via Claude Design bundles, bidirectional Figma write-back (annotations, Code Connect), queryable intel store (`.design/intel/`) for O(1) design surface lookups, and self-improvement loop (reflector agent, frontmatter + budget feedback, global-skills layer at `~/.claude/gdd/global-skills/`). Standalone commands: style, darkmode, compare, figma-write, graphify, handoff, analyze-dependencies, skill-manifest, extract-learnings, reflect, apply-reflections. Embeds NNG heuristics, WCAG thresholds, typographic systems, motion framework, and anti-pattern catalog. Ships with a full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows, lint + schema + frontmatter + stale-ref + shellcheck + gitleaks + injection-scan + blocking size-budget) and release automation (auto-tag + GitHub Release + release-time smoke test). Optimization layer (v1.0.4.1, retroactive): gdd-router + gdd-cache-manager skills, PreToolUse budget-enforcer hook, tier-aware agent frontmatter, lazy checker gates, streaming synthesizer, /gdd:warm-cache + /gdd:optimize commands, and cost telemetry at .design/telemetry/costs.jsonl — targeting 50-70% per-task token-cost reduction with no quality-floor regression.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "hegemonart",
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ All notable changes to get-design-done are documented here. Versions follow [sem
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [1.14.2] — 2026-04-20
|
|
8
|
+
|
|
9
|
+
### Added — Multi-format Claude Design handoff ingestion
|
|
10
|
+
|
|
11
|
+
- **URL entry point**: detect `https://api.anthropic.com/v1/design/h/<hash>` in agent prompt (native "Send to local coding agent" flow); `WebFetch` with `Content-Type` routing — HTML parsed directly, ZIP downloaded and extracted
|
|
12
|
+
- **ZIP bundle**: extract to `.design/handoff/`, find primary HTML + readme, parse normally, clean up after
|
|
13
|
+
- **PDF format**: `pdftotext` text extraction; grep for token values; all decisions tagged `(tentative — text-only)` since no CSS is present
|
|
14
|
+
- **PPTX format**: slide XML text extraction (`ppt/slides/*.xml`); same tentative-only tagging as PDF
|
|
15
|
+
- Updated synthesizer parsing algorithm step 1 with format dispatch before parsing
|
|
16
|
+
- Updated probe pattern: URL detection takes priority over file path lookup
|
|
17
|
+
- New `handoff_source` values: `claude-design-url`, `claude-design-zip`, `claude-design-pdf`, `claude-design-pptx`
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
7
21
|
## [1.14.1] — 2026-04-19
|
|
8
22
|
|
|
9
23
|
### Fixed — Security hardening (full codebase review)
|
|
@@ -99,10 +99,29 @@ Read .design/STATE.md
|
|
|
99
99
|
|
|
100
100
|
### Parsing algorithm (handoff mode)
|
|
101
101
|
|
|
102
|
-
1. **
|
|
102
|
+
1. **Resolve the bundle** from STATE.md fields in priority order:
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
```
|
|
105
|
+
handoff_url present → fetch URL with WebFetch tool
|
|
106
|
+
check Content-Type:
|
|
107
|
+
text/html → use response body as html_content (goto step 2)
|
|
108
|
+
application/zip → save to .design/handoff/bundle.zip, goto ZIP branch
|
|
109
|
+
other → warn user, abort handoff mode
|
|
110
|
+
handoff_path present → check extension:
|
|
111
|
+
.html → read file, goto step 2
|
|
112
|
+
.zip → goto ZIP branch
|
|
113
|
+
.pdf → goto PDF branch
|
|
114
|
+
.pptx / .pptx → goto PPTX branch
|
|
115
|
+
neither present → warn "no handoff_path or handoff_url in STATE.md", abort handoff mode
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**ZIP branch:** Extract `.design/handoff/bundle.zip` to `.design/handoff/extracted/`. Find primary HTML (`index.html`, `design.html`, or first `.html` at root). Find spec file (`readme.md`, `spec.md`, or first `.md` at root). Set html_content + spec_content. Delete `.design/handoff/extracted/` after parsing.
|
|
119
|
+
|
|
120
|
+
**PDF branch:** Extract all text content (Bash: `pdftotext <file> -` or python `pdfminer`). Set text_content. Skip to step 3b.
|
|
121
|
+
|
|
122
|
+
**PPTX branch:** Extract slide text (Bash: unzip `.pptx`, parse `ppt/slides/*.xml` for `<a:t>` text nodes). Set text_content. Skip to step 3b.
|
|
123
|
+
|
|
124
|
+
2. **Parse HTML export** (primary — html_content available):
|
|
106
125
|
- Extract all CSS custom properties from `<style>` blocks: grep for `--[a-z]+-[a-z-]+:\s*[^;]+`
|
|
107
126
|
- Categorize by prefix:
|
|
108
127
|
- `--color-*` → `[Color]` decisions
|
|
@@ -114,15 +133,23 @@ Read .design/STATE.md
|
|
|
114
133
|
- Extract component names from `class="component-*"` or `data-component="*"` patterns → `[Component]` decisions
|
|
115
134
|
- Detect layout patterns: `display: grid`, `display: flex` in component-level sections → `[Layout]` decisions
|
|
116
135
|
|
|
117
|
-
3. **Parse spec
|
|
118
|
-
|
|
136
|
+
3. **Parse spec text** (secondary):
|
|
137
|
+
|
|
138
|
+
3a. **Spec markdown / JSON** (if html_content path had a `.md` sibling, or ZIP contained spec):
|
|
119
139
|
- Grep for `Decision:`, `Rationale:`, `Token:`, `Component:` prefixes
|
|
120
140
|
- Treat found lines as pre-formed D-XX entries
|
|
121
141
|
|
|
142
|
+
3b. **PDF / PPTX text** (text_content only, no HTML):
|
|
143
|
+
- Grep text_content for same prefixes as 3a
|
|
144
|
+
- Also grep for hex colors (`#[0-9a-fA-F]{3,6}`), rem/px values (`[\d.]+rem|[\d]+px`), font names
|
|
145
|
+
- Tag ALL entries `(tentative — text-only, no CSS confirmation)`
|
|
146
|
+
- Note in STATE.md: `handoff_format: pdf` or `handoff_format: pptx` with caveat that token values need user confirmation
|
|
147
|
+
|
|
122
148
|
4. **Translate to D-XX decisions**:
|
|
123
149
|
- CSS custom property: `D-NN: [Category] Token name: value (source: claude-design-handoff) (tentative — confirm with user)`
|
|
124
150
|
- Explicit spec markdown decision: `D-NN: [Category] decision text (source: claude-design-handoff) (locked — from handoff spec)`
|
|
125
151
|
- Inferred component/layout: `D-NN: [Category] inferred text (source: claude-design-handoff) (tentative — inferred)`
|
|
152
|
+
- PDF/PPTX text value: `D-NN: [Category] extracted text (source: claude-design-pdf/pptx) (tentative — text-only, no CSS confirmation)`
|
|
126
153
|
|
|
127
154
|
5. **Append to STATE.md `<decisions>` block** under `### Handoff-sourced decisions` subsection header.
|
|
128
155
|
|
|
@@ -6,20 +6,94 @@ This file is the connection specification for Claude Design (https://claude.ai/d
|
|
|
6
6
|
|
|
7
7
|
## What Is a Claude Design Handoff Bundle?
|
|
8
8
|
|
|
9
|
-
Claude Design produces AI-generated designs that can be exported
|
|
9
|
+
Claude Design produces AI-generated designs that can be exported in several formats or sent directly to Claude Code via a hosted URL. The pipeline supports all of them.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|----------|--------|---------|
|
|
13
|
-
| Standalone HTML export | `.html` | Rendered component tree, inline CSS (design tokens as CSS custom properties), component structure, color/spacing/typography values |
|
|
14
|
-
| Design spec (optional) | `.md` or `.json` | Design decisions as structured text, token tables, component annotations |
|
|
15
|
-
| Assets (optional) | `assets/` dir | Icons, images referenced by the HTML export |
|
|
11
|
+
### Entry Points
|
|
16
12
|
|
|
17
|
-
|
|
13
|
+
| Source | How it arrives | handoff_source value |
|
|
14
|
+
|--------|---------------|----------------------|
|
|
15
|
+
| **"Send to local coding agent"** | Anthropic-hosted URL in the agent prompt | `claude-design-url` |
|
|
16
|
+
| **"Download zip"** | `.zip` bundle dropped into project | `claude-design-zip` |
|
|
17
|
+
| **"Save as standalone HTML"** | `.html` file dropped into project | `claude-design-html` |
|
|
18
|
+
| **"Save as PDF"** | `.pdf` file (spec text extraction only) | `claude-design-pdf` |
|
|
19
|
+
| **"Save as PPTX"** | `.pptx` file (spec text extraction only) | `claude-design-pptx` |
|
|
20
|
+
| **Bundle directory** | Unzipped directory with HTML + spec + assets | `claude-design-bundle` |
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
### Bundle contents by format
|
|
23
|
+
|
|
24
|
+
| Format | Primary artifact | Design tokens | Spec text | Images |
|
|
25
|
+
|--------|-----------------|---------------|-----------|--------|
|
|
26
|
+
| URL (hosted) | Fetched HTML | ✅ CSS custom props | ✅ if readme present | ✅ |
|
|
27
|
+
| ZIP | Unzipped HTML | ✅ CSS custom props | ✅ `readme.md` inside | ✅ |
|
|
28
|
+
| Standalone HTML | `.html` file | ✅ CSS custom props | ✅ if `.md` alongside | ✅ inline |
|
|
29
|
+
| PDF | `.pdf` text | ❌ (no CSS) | ✅ extracted text | ❌ |
|
|
30
|
+
| PPTX | `.pptx` slides | ❌ (no CSS) | ✅ slide text only | ❌ |
|
|
31
|
+
|
|
32
|
+
**Bundle entry point:** The primary parseable artifact is always the HTML — it contains inline `<style>` blocks with CSS custom properties (e.g., `--color-primary: #3B82F6`) and class-level token usage. PDF and PPTX are text-extraction fallbacks when no HTML is available.
|
|
33
|
+
|
|
34
|
+
**Bundle discovery:** The pipeline looks for the bundle in this priority order:
|
|
35
|
+
1. A `https://api.anthropic.com/v1/design/h/` URL in the agent invocation arguments
|
|
36
|
+
2. The path passed via `--from-handoff <path>` flag or `handoff <path>` sub-command
|
|
37
|
+
3. The value of `handoff_source` in `.design/STATE.md` (if a prior session already set it)
|
|
38
|
+
4. A `claude-design-handoff.{html,zip,pdf,pptx}` file in the project root (convention — not required)
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Format-Specific Ingestion
|
|
43
|
+
|
|
44
|
+
### URL format — `https://api.anthropic.com/v1/design/h/<hash>`
|
|
45
|
+
|
|
46
|
+
This is the native entry point when the user clicks **"Send to local coding agent"** in Claude Design. The agent prompt arrives as:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
Fetch this design file, read its readme, and implement the relevant aspects of the design. https://api.anthropic.com/v1/design/h/<hash>
|
|
50
|
+
Implement: <user description>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Detection:** grep the raw arguments/prompt for the pattern `https://api\.anthropic\.com/v1/design/h/[A-Za-z0-9_-]+`.
|
|
54
|
+
|
|
55
|
+
**Fetch sequence:**
|
|
56
|
+
1. `WebFetch` the URL — the response is either an HTML bundle or a redirect to a ZIP download
|
|
57
|
+
2. If `Content-Type: text/html` → treat as standalone HTML, parse normally
|
|
58
|
+
3. If `Content-Type: application/zip` or redirect to `.zip` → download to `.design/handoff/claude-design-handoff.zip`, then follow ZIP ingestion below
|
|
59
|
+
4. Check the response for an embedded `readme.md` link (often served alongside) — fetch it separately if present
|
|
60
|
+
5. Set `handoff_source: claude-design-url` and `handoff_url: <url>` in STATE.md
|
|
61
|
+
|
|
62
|
+
**Implement description:** The text after `Implement:` in the agent prompt is the user's implementation scope — capture it as a project note, not a D-XX decision.
|
|
63
|
+
|
|
64
|
+
### ZIP format
|
|
65
|
+
|
|
66
|
+
**Detection:** input path ends in `.zip` OR fetched from URL as zip.
|
|
67
|
+
|
|
68
|
+
**Ingestion sequence:**
|
|
69
|
+
1. Extract to `.design/handoff/` (temp directory, not committed)
|
|
70
|
+
2. Find the primary HTML: `index.html`, `design.html`, or any `.html` at root
|
|
71
|
+
3. Find spec: `readme.md`, `spec.md`, `design.md`, or any `.md` at root
|
|
72
|
+
4. Parse HTML + spec using the standard field catalogue below
|
|
73
|
+
5. Clean up `.design/handoff/` after parsing (keep only extracted decisions in STATE.md)
|
|
74
|
+
|
|
75
|
+
### PDF format
|
|
76
|
+
|
|
77
|
+
**Detection:** input path ends in `.pdf`.
|
|
78
|
+
|
|
79
|
+
**Ingestion:** PDF yields no CSS custom properties — token extraction is not possible. Instead:
|
|
80
|
+
1. Extract all text content (pdftotext or equivalent)
|
|
81
|
+
2. Grep for `Decision:`, `Rationale:`, `Token:`, `Color:`, `Typography:`, `Spacing:` prefixes
|
|
82
|
+
3. Treat matched lines as spec text → translate to D-XX entries tagged `(source: claude-design-pdf)` + `(tentative — text-only, no CSS confirmation)`
|
|
83
|
+
4. Note in STATE.md: `handoff_format: pdf` + caveat that token values were extracted from text, not CSS
|
|
84
|
+
|
|
85
|
+
**Limitation:** PDF handoffs cannot produce `(locked)` token decisions — all are `(tentative)`. Surface this explicitly to the user in the discussant step.
|
|
86
|
+
|
|
87
|
+
### PPTX format
|
|
88
|
+
|
|
89
|
+
**Detection:** input path ends in `.pptx`.
|
|
90
|
+
|
|
91
|
+
**Ingestion:** Same as PDF — text extraction only, no CSS tokens.
|
|
92
|
+
1. Extract slide text (python-pptx or unzip `.pptx` and parse `ppt/slides/*.xml`)
|
|
93
|
+
2. Same grep patterns as PDF
|
|
94
|
+
3. Tag all entries `(source: claude-design-pptx)` + `(tentative — text-only)`
|
|
95
|
+
|
|
96
|
+
**Limitation:** Same as PDF — all decisions are tentative. PPTX format is the weakest source; prefer HTML or ZIP if available.
|
|
23
97
|
|
|
24
98
|
---
|
|
25
99
|
|
|
@@ -114,13 +188,15 @@ Claude Design is not an MCP server — it has no tools to probe via ToolSearch.
|
|
|
114
188
|
|
|
115
189
|
```
|
|
116
190
|
At scan stage entry:
|
|
117
|
-
1. Check
|
|
191
|
+
1. Check invocation arguments/prompt for https://api.anthropic.com/v1/design/h/ URL
|
|
118
192
|
2. Check $ARGUMENTS for --from-handoff <path> flag
|
|
119
|
-
3. Check
|
|
193
|
+
3. Check STATE.md <position> for handoff_source / handoff_url / handoff_path field
|
|
194
|
+
4. Check project root for claude-design-handoff.{html,zip,pdf,pptx}
|
|
120
195
|
|
|
121
|
-
→
|
|
122
|
-
→
|
|
123
|
-
→
|
|
196
|
+
→ URL detected (step 1) → claude_design: available (fetch at ingest time)
|
|
197
|
+
→ File path found AND file exists → claude_design: available
|
|
198
|
+
→ Path/URL provided but unreachable/bad → claude_design: unavailable
|
|
199
|
+
→ None of the above → claude_design: not_configured
|
|
124
200
|
```
|
|
125
201
|
|
|
126
202
|
Write result to STATE.md `<connections>` at scan entry.
|
|
@@ -168,17 +244,25 @@ skipped_stages: scan, discover, plan
|
|
|
168
244
|
|
|
169
245
|
**`handoff_source` values:**
|
|
170
246
|
|
|
171
|
-
| Value | Meaning |
|
|
172
|
-
|
|
173
|
-
| `claude-design-
|
|
174
|
-
| `claude-design-
|
|
175
|
-
| `
|
|
247
|
+
| Value | Meaning | Token quality |
|
|
248
|
+
|-------|---------|---------------|
|
|
249
|
+
| `claude-design-url` | Fetched from Anthropic-hosted URL (Send to local coding agent) | High — HTML |
|
|
250
|
+
| `claude-design-zip` | ZIP bundle dropped into project | High — HTML inside |
|
|
251
|
+
| `claude-design-html` | Standalone HTML export | High — CSS custom props |
|
|
252
|
+
| `claude-design-bundle` | Directory with HTML + spec markdown + assets | High — CSS custom props |
|
|
253
|
+
| `claude-design-pdf` | PDF export (text extraction only) | Low — text only, all tentative |
|
|
254
|
+
| `claude-design-pptx` | PPTX export (text extraction only) | Low — text only, all tentative |
|
|
255
|
+
| `manual` | User manually initialized STATE.md with design decisions (no bundle file) | N/A |
|
|
176
256
|
|
|
177
257
|
---
|
|
178
258
|
|
|
179
259
|
## Caveats and Pitfalls
|
|
180
260
|
|
|
181
|
-
1. **Handoff bundle format is undocumented by Anthropic.** The Claude Design handoff bundle format is inferred from the product
|
|
261
|
+
1. **Handoff bundle format is undocumented by Anthropic.** The Claude Design handoff bundle format is inferred from the product UI and common HTML export patterns. The pipeline uses defensive parsing: grep for CSS custom properties in `<style>` tags, extract component class names from `class="component-*"` patterns, and fall back to the spec markdown/JSON if CSS parsing yields no results. If the format changes in a future Claude Design release, update this spec and the synthesizer's parsing patterns. The URL endpoint (`/v1/design/h/<hash>`) may return different content types — always check `Content-Type` before deciding whether to parse as HTML or unzip.
|
|
262
|
+
|
|
263
|
+
6. **PDF and PPTX handoffs produce only tentative decisions.** These formats contain no CSS — all token values must be inferred from prose. Never promote PDF/PPTX-sourced decisions to `(locked)` without explicit user confirmation. If the user provides both a PDF and an HTML export, always prefer the HTML.
|
|
264
|
+
|
|
265
|
+
7. **ZIP extraction is ephemeral.** Extracted ZIP contents go to `.design/handoff/` and are deleted after parsing. Only the extracted D-XX decisions are persisted to STATE.md. Never commit the raw extracted files.
|
|
182
266
|
|
|
183
267
|
2. **`(tentative)` decisions MUST be confirmed by the user.** The discussant `--from-handoff` mode surfaces all tentative decisions for confirmation before proceeding to verify. Do NOT skip this step — implementing against unconfirmed inferred values is the primary failure mode of handoff-sourced workflows.
|
|
184
268
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hegemonart/get-design-done",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.2",
|
|
4
4
|
"description": "A Claude Code plugin for systematic design improvement",
|
|
5
5
|
"author": "Hegemon",
|
|
6
6
|
"homepage": "https://github.com/hegemonart/get-design-done",
|
|
@@ -25,6 +25,9 @@
|
|
|
25
25
|
"CHANGELOG.md",
|
|
26
26
|
"LICENSE"
|
|
27
27
|
],
|
|
28
|
+
"bin": {
|
|
29
|
+
"get-design-done": "./scripts/install.cjs"
|
|
30
|
+
},
|
|
28
31
|
"publishConfig": {
|
|
29
32
|
"access": "public",
|
|
30
33
|
"provenance": true
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# Branch Protection — Two-Phase Rollout
|
|
2
|
-
|
|
3
|
-
Per D-16 / D-17: branch protection on `main` is rolled out in two phases. The
|
|
4
|
-
repo admin applies each phase manually via `scripts/apply-branch-protection.sh`
|
|
5
|
-
(no CI automation — avoids leaking repo admin credentials).
|
|
6
|
-
|
|
7
|
-
## Phase A — Advisory (initial state)
|
|
8
|
-
|
|
9
|
-
Status checks **run** on every push, but they are **not required to merge**.
|
|
10
|
-
This is the default posture while CI stabilizes and baselines are established.
|
|
11
|
-
|
|
12
|
-
Apply:
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
bash scripts/apply-branch-protection.sh --advisory
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
Effects:
|
|
19
|
-
|
|
20
|
-
- Required status checks: **none** (checks run but don't block)
|
|
21
|
-
- `main` accepts direct pushes (the solo maintainer's existing workflow)
|
|
22
|
-
- Force-push: allowed by admins
|
|
23
|
-
|
|
24
|
-
## Phase B — Enforcing (after first clean release)
|
|
25
|
-
|
|
26
|
-
After the first full release cycle ships clean (plan 13-06 / 13-07 smoke test
|
|
27
|
-
passes on a real tag + GitHub Release), tighten to enforcing.
|
|
28
|
-
|
|
29
|
-
Apply:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
bash scripts/apply-branch-protection.sh --enforcing
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Effects:
|
|
36
|
-
|
|
37
|
-
- Required status checks (all must pass to merge):
|
|
38
|
-
- `Lint (markdown + frontmatter + stale-refs)`
|
|
39
|
-
- `Validate (schemas + plugin + shellcheck)`
|
|
40
|
-
- `Test (Node 22 / ubuntu-latest)`
|
|
41
|
-
- `Test (Node 22 / macos-latest)`
|
|
42
|
-
- `Test (Node 22 / windows-latest)`
|
|
43
|
-
- `Test (Node 24 / ubuntu-latest)`
|
|
44
|
-
- `Test (Node 24 / macos-latest)`
|
|
45
|
-
- `Test (Node 24 / windows-latest)`
|
|
46
|
-
- `Security (secrets + injection scan)`
|
|
47
|
-
- `Size budget (blocking)`
|
|
48
|
-
- Require linear history (no merge commits)
|
|
49
|
-
- Disallow force-push
|
|
50
|
-
- Admins still bypass for emergency fixes (logged)
|
|
51
|
-
|
|
52
|
-
## When to promote Phase A → Phase B
|
|
53
|
-
|
|
54
|
-
- [ ] Wave A + B of Phase 13 merged to main
|
|
55
|
-
- [ ] `release.yml` (plan 13-06) merged and triggered at least once successfully
|
|
56
|
-
- [ ] Release smoke test (plan 13-07) passed on a real tag
|
|
57
|
-
- [ ] Baseline lock (plan 13-08) committed
|
|
58
|
-
|
|
59
|
-
When all four are true, run `apply-branch-protection.sh --enforcing`.
|
|
60
|
-
|
|
61
|
-
## Rollback
|
|
62
|
-
|
|
63
|
-
To revert either phase: `apply-branch-protection.sh --disable` removes all
|
|
64
|
-
protection rules. Use only if a protection misconfiguration is blocking a
|
|
65
|
-
legitimate merge.
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# apply-branch-protection.sh — manually apply branch protection to `main`.
|
|
3
|
-
# Per D-16: this script is run by the repo admin locally, NOT from CI.
|
|
4
|
-
# Usage:
|
|
5
|
-
# bash scripts/apply-branch-protection.sh --advisory
|
|
6
|
-
# bash scripts/apply-branch-protection.sh --enforcing
|
|
7
|
-
# bash scripts/apply-branch-protection.sh --disable
|
|
8
|
-
|
|
9
|
-
set -euo pipefail
|
|
10
|
-
|
|
11
|
-
MODE="${1:-}"
|
|
12
|
-
REPO="${GITHUB_REPOSITORY:-hegemonart/get-design-done}"
|
|
13
|
-
|
|
14
|
-
if ! command -v gh >/dev/null 2>&1; then
|
|
15
|
-
echo "ERROR: gh CLI not found. Install from https://cli.github.com/"
|
|
16
|
-
exit 1
|
|
17
|
-
fi
|
|
18
|
-
|
|
19
|
-
case "$MODE" in
|
|
20
|
-
--advisory)
|
|
21
|
-
echo "Applying ADVISORY branch protection to $REPO main..."
|
|
22
|
-
gh api -X PUT "repos/${REPO}/branches/main/protection" \
|
|
23
|
-
-H "Accept: application/vnd.github+json" \
|
|
24
|
-
-f "required_status_checks=null" \
|
|
25
|
-
-F "enforce_admins=false" \
|
|
26
|
-
-f "required_pull_request_reviews=null" \
|
|
27
|
-
-F "restrictions=null" \
|
|
28
|
-
-F "required_linear_history=false" \
|
|
29
|
-
-F "allow_force_pushes=true" \
|
|
30
|
-
-F "allow_deletions=false"
|
|
31
|
-
echo "Advisory mode applied. CI checks will run but not block merges."
|
|
32
|
-
;;
|
|
33
|
-
--enforcing)
|
|
34
|
-
echo "Applying ENFORCING branch protection to $REPO main..."
|
|
35
|
-
# Status check names must match the `name:` field of each job exactly.
|
|
36
|
-
# See reference/BRANCH-PROTECTION.md §Phase B for the authoritative list.
|
|
37
|
-
gh api -X PUT "repos/${REPO}/branches/main/protection" \
|
|
38
|
-
-H "Accept: application/vnd.github+json" \
|
|
39
|
-
--input - <<'JSON'
|
|
40
|
-
{
|
|
41
|
-
"required_status_checks": {
|
|
42
|
-
"strict": true,
|
|
43
|
-
"contexts": [
|
|
44
|
-
"Lint (markdown + frontmatter + stale-refs)",
|
|
45
|
-
"Validate (schemas + plugin + shellcheck)",
|
|
46
|
-
"Test (Node 22 / ubuntu-latest)",
|
|
47
|
-
"Test (Node 22 / macos-latest)",
|
|
48
|
-
"Test (Node 22 / windows-latest)",
|
|
49
|
-
"Test (Node 24 / ubuntu-latest)",
|
|
50
|
-
"Test (Node 24 / macos-latest)",
|
|
51
|
-
"Test (Node 24 / windows-latest)",
|
|
52
|
-
"Security (secrets + injection scan)",
|
|
53
|
-
"Size budget (blocking)"
|
|
54
|
-
]
|
|
55
|
-
},
|
|
56
|
-
"enforce_admins": false,
|
|
57
|
-
"required_pull_request_reviews": null,
|
|
58
|
-
"restrictions": null,
|
|
59
|
-
"required_linear_history": true,
|
|
60
|
-
"allow_force_pushes": false,
|
|
61
|
-
"allow_deletions": false
|
|
62
|
-
}
|
|
63
|
-
JSON
|
|
64
|
-
echo "Enforcing mode applied. CI must pass before merge; linear history required."
|
|
65
|
-
;;
|
|
66
|
-
--disable)
|
|
67
|
-
echo "Removing branch protection from $REPO main..."
|
|
68
|
-
gh api -X DELETE "repos/${REPO}/branches/main/protection" || true
|
|
69
|
-
echo "Protection removed."
|
|
70
|
-
;;
|
|
71
|
-
*)
|
|
72
|
-
echo "Usage: $0 --advisory | --enforcing | --disable"
|
|
73
|
-
exit 1
|
|
74
|
-
;;
|
|
75
|
-
esac
|