@hegemonart/get-design-done 1.39.2 → 1.40.0
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 +79 -0
- package/README.md +8 -0
- package/SKILL.md +3 -0
- package/agents/conflict-resolver.md +80 -0
- package/agents/decision-journal-exporter.md +68 -0
- package/agents/design-reflector.md +2 -0
- package/agents/pr-commenter.md +1 -0
- package/package.json +2 -1
- package/reference/DEPRECATIONS.md +40 -0
- package/reference/STATE-TEMPLATE.md +3 -0
- package/reference/config-schema.md +19 -0
- package/reference/multi-author-model.md +112 -0
- package/reference/registry.json +7 -0
- package/reference/schemas/config.schema.json +37 -0
- package/reference/schemas/generated.d.ts +50 -0
- package/scripts/lib/collab/attribution.cjs +83 -0
- package/scripts/lib/collab/cycle-mode.cjs +41 -0
- package/scripts/lib/collab/lock-policy.cjs +37 -0
- package/scripts/lib/collab/permissions.cjs +53 -0
- package/scripts/lib/collab/review-queue.cjs +64 -0
- package/scripts/lib/collab/section-merge.cjs +77 -0
- package/scripts/lib/collab/sync-backend.cjs +36 -0
- package/scripts/lib/deprecation-registry.cjs +99 -0
- package/skills/migrate/SKILL.md +70 -0
- package/skills/review-decisions/SKILL.md +42 -0
- package/skills/unlock-decision/SKILL.md +54 -0
- package/skills/update/SKILL.md +18 -0
|
@@ -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). v1.20.0 ships the SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream, and resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) for rate-limit + 429 + context-overflow recovery. Full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows) and release automation (auto-tag + GitHub Release + release-time smoke test).",
|
|
8
|
-
"version": "1.
|
|
8
|
+
"version": "1.40.0"
|
|
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. v1.20.0 SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream at .design/telemetry/events.jsonl, resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) with rate-limit + 429 + context-overflow recovery, and TypeScript toolchain.",
|
|
15
|
-
"version": "1.
|
|
15
|
+
"version": "1.40.0",
|
|
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.
|
|
4
|
+
"version": "1.40.0",
|
|
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. v1.20.0 SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream at .design/telemetry/events.jsonl, resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) with rate-limit + 429 + context-overflow recovery, and TypeScript toolchain. v1.27.7 ships gdd-mcp (Phase 27.7): 12 read-only MCP tools for sub-3s priming. v1.28.0 (Phase 28): Foundational References Tier 2 — 5 new reference files (color-theory, composition, proportion-systems, i18n, contrast-advanced), 2 verifier i18n probes + 1 explore i18n-readiness probe, 12 additive cross-link insertions across 10 existing references, 2 orthogonal audit-scoring lens-tags (composition_alignment + i18n_readiness).",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "hegemonart",
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,85 @@ All notable changes to get-design-done are documented here. Versions follow [sem
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [1.40.0] - 2026-06-01
|
|
8
|
+
|
|
9
|
+
### Phase 40 — Team Collaboration Mode
|
|
10
|
+
|
|
11
|
+
The largest architectural phase: GDD's single-operator baseline (Phase 20 lockfile + atomic STATE.md) now extends to **multiple developers**. Multi-writer STATE.md merges per-section, decisions are attributed + reviewed through an async queue with hard locks, a conflict-resolver reconciles parallel branches, decisions export to a read-only shared journal, and per-section permissions + sectional handoff gate who writes what. Everything is **git-native + advisory** — no server, no live multiplayer, no SSO. **No new runtime dependency, no new egress.**
|
|
12
|
+
|
|
13
|
+
### Breaking changes
|
|
14
|
+
|
|
15
|
+
**None.** Every Phase 40 surface is additive and **off by default**: `gdd_cycle_mode` defaults to `full` (current behavior), `permissions` absent = everyone is `owner`, `collab.multi_writer_enabled` defaults to `false`, `collab.sync_backend` defaults to `git`, and the decision attribution suffix is optional + backward-compatible. A single-operator project upgrading to v1.40.0 behaves exactly as it did on v1.39.5.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- **`reference/multi-author-model.md`** — the team-collaboration contract (merge model, attribution, review queue + locks, lock policy, sectional handoff, permissions, journal export + PR threading, opt-in sync). Registered.
|
|
20
|
+
- **`scripts/lib/collab/`** — 7 pure, dep-free cores: `attribution` (decision `[author= co-author=]` suffix), `section-merge` (git-merge-driver per-section semantic merge — union by D-id, conflict only on same-id divergence), `lock-policy` (team-mode advisory-lock backoff), `review-queue` (proposed→reviewing→approved→locked + audited unlock), `cycle-mode` (sectional handoff stage gate), `permissions` (per-section `can()`), `sync-backend` (git/s3/git-lfs selector).
|
|
21
|
+
- **`agents/conflict-resolver.md`** — three-way STATE.md merge, per-section + human-confirmed; never auto-picks or drops a decision.
|
|
22
|
+
- **`agents/decision-journal-exporter.md`** — `<decisions>` → `pseudonymize` → read-only Notion/Confluence on cycle close (write-only; degrades to local markdown).
|
|
23
|
+
- **`skills/review-decisions/SKILL.md`** (`/gdd:review-decisions`) + **`skills/unlock-decision/SKILL.md`** (`/gdd:unlock-decision <id> --approver`, the only audited escape from a hard lock).
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **`reference/schemas/config.schema.json`** — + `gdd_cycle_mode` (designer|dev|full) + `permissions` + `collab` (multi_writer_enabled / lock_timeout_ms / sync_backend); `generated.d.ts` regenerated.
|
|
28
|
+
- **`reference/STATE-TEMPLATE.md`** — document the optional decision attribution suffix.
|
|
29
|
+
- **`agents/design-reflector.md`** — a "Per-author patterns" note (reads attribution).
|
|
30
|
+
- **`agents/pr-commenter.md`** — thread PR comments on `D-XX` decisions (team-mode).
|
|
31
|
+
|
|
32
|
+
### Notes
|
|
33
|
+
|
|
34
|
+
- **No new runtime dependency, no new egress** — 7 pure cores + reference/agent/skill prose + an additive config-schema; the live S3/git-LFS sync client is explicitly out of scope (the selector ships, the backend is pluggable).
|
|
35
|
+
- 6-manifest lockstep at **v1.40.0** + `OFF_CADENCE_VERSIONS.add('1.40.0')` (a minor bump) + the 33 live-pinned `manifests-version.txt` baselines forward-propagated 1.39.5 → 1.40.0.
|
|
36
|
+
- Inventory relock: registry-diff 158 → 159 (+`multi-author-model`), skill-list 80 → 82 (+`review-decisions`, +`unlock-decision`), agent-list +`conflict-resolver` +`decision-journal-exporter` + both frontmatter-snapshots, skill-length-distribution relocked, tarball golden 709 → 721 (+12). Root `SKILL.md` command table += both skills.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## [1.39.5] - 2026-06-01
|
|
41
|
+
|
|
42
|
+
### Phase 39.5 — GDD Self-Migration Tooling
|
|
43
|
+
|
|
44
|
+
GDD migrates *user* design systems (39.1) but had no systematic story for **its own** breaking
|
|
45
|
+
changes — Phase 31.5 moved `scripts/lib/**` → `sdk/**` with ad-hoc shims. 39.5 formalizes it: a
|
|
46
|
+
machine-readable deprecation registry, a version-aware reader, a `/gdd:migrate` skill, a post-update
|
|
47
|
+
advisory, and two CI gates (a completeness check + a CHANGELOG Breaking-changes linter). **No new
|
|
48
|
+
runtime dependency, no new egress** — two pure helpers + a docs/skill surface.
|
|
49
|
+
|
|
50
|
+
### Breaking changes
|
|
51
|
+
|
|
52
|
+
None. (This release *adds* the deprecation machinery; it removes nothing. The historical Phase 31.5 →
|
|
53
|
+
`sdk/` removals it documents already shipped in v1.33.0.)
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
- **`reference/DEPRECATIONS.md`** — a `## Path migrations (machine-readable)` table
|
|
58
|
+
(`Since · Removed in · Old · New · Migration hint`) + status semantics, backfilled with the 10
|
|
59
|
+
verified Phase 31.5 → `sdk/` removals (all confirmed gone from the tree).
|
|
60
|
+
- **`scripts/lib/deprecation-registry.cjs`** — pure, dep-free reader: `compareVersions`,
|
|
61
|
+
`parseDeprecations` (markdown-table parser), `classify` (pending/deprecated/removed by version),
|
|
62
|
+
`checkReference`.
|
|
63
|
+
- **`skills/migrate/SKILL.md`** (`/gdd:migrate [--yes] [--dry-run]`) — scans a project's references for
|
|
64
|
+
paths deprecated/removed at the installed version and **previews a diff** before rewriting. Preview-first.
|
|
65
|
+
- **`scripts/lint-changelog.cjs`** (`npm run lint:changelog`) — every `## [x.y.0]` minor at/after the
|
|
66
|
+
1.39.0 floor must declare a `### Breaking changes` section; historical minors are grandfathered.
|
|
67
|
+
- **`test/suite/deprecation-completeness.test.cjs`** — the SC#4 gate: every `removed` entry's old path
|
|
68
|
+
is gone + its replacement exists; every `deprecated` entry still has a shim. No orphan entries.
|
|
69
|
+
|
|
70
|
+
### Changed
|
|
71
|
+
|
|
72
|
+
- **`skills/update/SKILL.md`** — a post-update step that reports deprecations crossing into
|
|
73
|
+
`deprecated`/`removed` over the upgrade window and points the user at `/gdd:migrate`.
|
|
74
|
+
|
|
75
|
+
### Notes
|
|
76
|
+
|
|
77
|
+
- **No new runtime dependency, no new egress.** `lint-changelog.cjs` is a maintainer/CI tool (not shipped).
|
|
78
|
+
- 6-manifest lockstep at **v1.39.5** + `OFF_CADENCE_VERSIONS.add('1.39.5')` + the 32 live-pinned
|
|
79
|
+
`manifests-version.txt` baselines forward-propagated 1.39.2 → 1.39.5.
|
|
80
|
+
- Inventory relock: skill-list 79 → 80 (+`migrate`, phase-20 + current), tarball golden 707 → 709
|
|
81
|
+
(+`deprecation-registry.cjs` + `skills/migrate/SKILL.md`). No agent/event/connection deltas. Root
|
|
82
|
+
`SKILL.md` command table += `migrate`.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
7
86
|
## [1.39.2] - 2026-06-01
|
|
8
87
|
|
|
9
88
|
### Phase 39.2 — Long-Horizon Cost Governance
|
package/README.md
CHANGED
|
@@ -186,6 +186,14 @@ When a design system ships a breaking major — shadcn/ui v1→v2, Tailwind v3
|
|
|
186
186
|
|
|
187
187
|
GDD already tracks cost per task and per runtime — now it **forecasts** it, **caps** it at the project level, and shows whether the spend **shipped**. [`/gdd:budget`](skills/budget/SKILL.md) groups `costs.jsonl` by cycle and (via [`cost-forecaster`](agents/cost-forecaster.md) → the pure [`cost-forecast`](scripts/lib/budget/cost-forecast.cjs)) projects the next N cycles in **best / typical / worst** scenarios — "at the current rate you'll hit your $X project cap in Y cycles." A new `budget.json.project_cap_usd` adds a **project-level hard cap**: the [`budget-enforcer`](hooks/budget-enforcer.ts) hook warns at 50% + 80% and **gracefully halts** the next agent spawn at 100% (via the pure [`project-cap`](scripts/lib/budget/project-cap.cjs) classifier) — **disabled by default**, so existing users are unaffected. [`/gdd:roi`](skills/roi/SKILL.md) joins per-cycle cost with commits that shipped (survived ≥ 14 days) vs reverted into a cost-per-shipped-commit table ([`roi`](scripts/lib/budget/roi.cjs)). **No new runtime dependency, no new egress** — the hook only ever blocks, never spends.
|
|
188
188
|
|
|
189
|
+
### GDD self-migration (v1.39.5)
|
|
190
|
+
|
|
191
|
+
GDD migrates *your* design systems (above) — now it migrates **itself**. When GDD ships a breaking path change (like the Phase 31.5 `scripts/lib/**` → `sdk/**` reorg), a machine-readable registry in [`reference/DEPRECATIONS.md`](reference/DEPRECATIONS.md) records `Since · Removed in · Old · New · hint`. After an upgrade, [`/gdd:update`](skills/update/SKILL.md) flags anything that crossed into deprecated/removed, and [`/gdd:migrate`](skills/migrate/SKILL.md) rewrites your project's stale references — **previewing a diff first, never silent** — via the pure [`deprecation-registry`](scripts/lib/deprecation-registry.cjs). Two CI gates keep the system honest: a completeness check (every entry has a shim or a confirmed removal) and `lint-changelog` (every future minor must declare a `### Breaking changes` section). **No new runtime dependency, no new egress.**
|
|
192
|
+
|
|
193
|
+
### Team collaboration mode (v1.40.0)
|
|
194
|
+
|
|
195
|
+
GDD's single-operator baseline now extends to **teams** — git-native + advisory, no server. Two developers working a cycle on parallel branches merge their `.design/STATE.md` **per section** ([`section-merge`](scripts/lib/collab/section-merge.cjs) unions decisions by `D-id`; a real conflict is only a same-id divergence, which [`conflict-resolver`](agents/conflict-resolver.md) reconciles with human confirmation — never auto-picking or dropping a decision). Decisions carry optional `[author= co-author=]` attribution, move through an async review queue (`proposed → reviewing → approved → locked`) with **hard locks** (the only escape is an audited [`/gdd:unlock-decision`](skills/unlock-decision/SKILL.md)), and [`/gdd:review-decisions`](skills/review-decisions/SKILL.md) surfaces what's pending. [`decision-journal-exporter`](agents/decision-journal-exporter.md) publishes a **pseudonymized, read-only** Notion/Confluence journal for stakeholders who don't run GDD. `gdd_cycle_mode` (designer/dev/full) partitions a cycle by role, a `permissions` model gates per-section writes, and `collab.multi_writer_enabled` switches the advisory lock to a team-mode backoff. The full contract: [`reference/multi-author-model.md`](reference/multi-author-model.md). **Everything is off by default** — a single-operator project is unaffected. **No new runtime dependency.**
|
|
196
|
+
|
|
189
197
|
### Previous releases
|
|
190
198
|
|
|
191
199
|
- **v1.26.0** — Headless Model Resolver (per-runtime tier→model map, `resolved_models` router field, per-runtime price tables, `reasoning-class` runtime-neutral alias).
|
package/SKILL.md
CHANGED
|
@@ -104,6 +104,9 @@ Each stage produces artifacts in `.design/` inside the current project.
|
|
|
104
104
|
| `rollout-status [<cycle>] [--all] [--stuck]` | `get-design-done:gdd-rollout-status` | Phase 38.5 — track a shipped cycle's production rollout (unrolled / staging-only / canary-N% / prod-100%) by reading the feature-flag service via `rollout-coordinator`; surfaces STUCK rollouts; feeds `design_arms` by deployed %. Read-only — never advances or rolls back |
|
|
105
105
|
| `budget [--cycles N] [--scenario best\|typical\|worst]` | `get-design-done:gdd-budget` | Phase 39.2 — forecast design-cycle spend (best/typical/worst from telemetry variance) via `cost-forecaster`; "at the current rate you'll hit your $X project cap in Y cycles." Read-only — never spends, edits `budget.json`, or halts (the budget-enforcer hook halts) |
|
|
106
106
|
| `roi [--since <date>] [--window-days 14]` | `get-design-done:gdd-roi` | Phase 39.2 — ROI table joining per-cycle cost with commits that shipped (survived ≥14d) vs reverted → cost-per-shipped-commit + stick rate. Read-only markdown report |
|
|
107
|
+
| `migrate [--yes] [--dry-run]` | `get-design-done:gdd-migrate` | Phase 39.5 — migrate a project off GDD's own deprecated paths after an upgrade; reads `reference/DEPRECATIONS.md` via `deprecation-registry.cjs`, previews a diff, applies on confirm. Preview-first; never edits silently |
|
|
108
|
+
| `review-decisions [<id>] [--pending]` | `get-design-done:gdd-review-decisions` | Phase 40 — surface the async decision-review queue (`proposed → reviewing → approved → locked`); `--pending` shows decisions still awaiting action. Read-only |
|
|
109
|
+
| `unlock-decision <id> --approver <who> [--reason <text>] [--dry-run]` | `get-design-done:gdd-unlock-decision` | Phase 40 — reopen a LOCKED decision (the only escape hatch); requires an approver + writes an audit entry; previews before writing |
|
|
107
110
|
|
|
108
111
|
## Handoff Routing
|
|
109
112
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: conflict-resolver
|
|
3
|
+
description: Resolves design-artifact merge conflicts when two developers worked a cycle on parallel branches. Reads the conflicted STATE.md from both sides (ours/theirs) plus the merge base, runs the pure scripts/lib/collab/section-merge.cjs per-section semantic merge (union the <decisions> by D-id; a real conflict is only a same-id divergence), and proposes a resolution PER SECTION for explicit human confirmation. Never auto-commits a conflicted section — decisions are durable. Spawned during a team-mode merge.
|
|
4
|
+
tools: Read, Bash, Grep, Glob
|
|
5
|
+
color: green
|
|
6
|
+
default-tier: sonnet
|
|
7
|
+
tier-rationale: "Three-way semantic merge of a structured STATE.md via a pure helper + a human-confirmed per-section proposal; bounded reconciliation, not open design judgment — sonnet-tier."
|
|
8
|
+
size_budget: M
|
|
9
|
+
size_budget_rationale: "Honest tier sized to the ~95-line body. DELEGATES the merge math to scripts/lib/collab/section-merge.cjs + the attribution parse to scripts/lib/collab/attribution.cjs, and the model to reference/multi-author-model.md."
|
|
10
|
+
parallel-safe: false
|
|
11
|
+
typical-duration-seconds: 45
|
|
12
|
+
reads-only: false
|
|
13
|
+
required_reading:
|
|
14
|
+
- "reference/multi-author-model.md"
|
|
15
|
+
writes:
|
|
16
|
+
- ".design/STATE.md (only the sections the human confirms)"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# conflict-resolver
|
|
20
|
+
|
|
21
|
+
Two developers ran a GDD cycle on parallel branches; their `.design/STATE.md` now conflicts. You
|
|
22
|
+
reconcile it **per section, with human confirmation** — you never silently pick a winner, and you
|
|
23
|
+
never drop a decision. **Read `reference/multi-author-model.md` first** (the merge model).
|
|
24
|
+
|
|
25
|
+
## Inputs
|
|
26
|
+
|
|
27
|
+
A git merge conflict in `.design/STATE.md`. Recover the three versions:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
git show :1:.design/STATE.md > /tmp/state.base # merge base (common ancestor)
|
|
31
|
+
git show :2:.design/STATE.md > /tmp/state.ours # ours (current branch)
|
|
32
|
+
git show :3:.design/STATE.md > /tmp/state.theirs # theirs (incoming)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
(If a stage isn't available — e.g. an add/add conflict with no base — treat the base as empty.)
|
|
36
|
+
|
|
37
|
+
## Procedure
|
|
38
|
+
|
|
39
|
+
1. **Parse each side's `<decisions>` block** with `scripts/lib/collab/attribution.cjs`
|
|
40
|
+
(`parseDecisionsBlock`), preserving the `[author= co-author=]` attribution.
|
|
41
|
+
2. **Three-way merge** via the pure helper — never merge by hand:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
node -e '
|
|
45
|
+
const fs = require("fs");
|
|
46
|
+
const at = require("./scripts/lib/collab/attribution.cjs");
|
|
47
|
+
const sm = require("./scripts/lib/collab/section-merge.cjs");
|
|
48
|
+
const block = (f) => { const m = fs.readFileSync(f,"utf8").match(/<decisions>([\s\S]*?)<\/decisions>/); return m ? at.parseDecisionsBlock(m[1]) : []; };
|
|
49
|
+
const r = sm.mergeDecisions(block("/tmp/state.base"), block("/tmp/state.ours"), block("/tmp/state.theirs"));
|
|
50
|
+
console.log(JSON.stringify(r, null, 2));
|
|
51
|
+
'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
3. **Report the proposal per section.** For `<decisions>`:
|
|
55
|
+
- the clean union (auto-mergeable D-NN, both new adds kept) — show it,
|
|
56
|
+
- each **conflict** (same D-id, divergent text/status) — show ours vs theirs side by side and ask
|
|
57
|
+
the human which to keep (or to author a merged text). Never decide unilaterally.
|
|
58
|
+
Repeat for any other conflicted section (status, `<prototyping>`, `<rollout_status>`) using
|
|
59
|
+
`mergeStatusScalar` for single-value sections.
|
|
60
|
+
4. **Apply only confirmed sections.** Write the merged `<decisions>` (re-formatted via
|
|
61
|
+
`attribution.formatDecisionLine`, attribution preserved) back to `.design/STATE.md`, leaving any
|
|
62
|
+
unconfirmed conflict marked for the human. Then `git add .design/STATE.md` is the human's call.
|
|
63
|
+
5. **Never drop a decision.** A `D-NN` removed on one side but unchanged on the other is kept — surface
|
|
64
|
+
it, don't delete it.
|
|
65
|
+
|
|
66
|
+
## Record
|
|
67
|
+
|
|
68
|
+
Print a `## Conflict resolution` summary: sections merged, D-NN auto-unioned, conflicts surfaced +
|
|
69
|
+
how each was resolved, and any section left for the human. Append one JSONL line to
|
|
70
|
+
`.design/intel/insights.jsonl` recording the merge outcome. Close with:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
## CONFLICT RESOLUTION COMPLETE
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Boundaries
|
|
77
|
+
|
|
78
|
+
- Per-section, human-confirmed; no unilateral winner, no silent deletion.
|
|
79
|
+
- Reconciles design artifacts (STATE.md); it does not run `git commit` or resolve source-code conflicts.
|
|
80
|
+
- No network.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: decision-journal-exporter
|
|
3
|
+
description: Exports a cycle's design decisions to a read-only shared journal (Notion/Confluence) so PMs, designers, and stakeholders who don't run GDD locally can see what was decided and why. Reads STATE.md <decisions>, pipes every line through scripts/lib/pseudonymize.cjs (git identity + stable hash) so author names are masked before leaving the repo, and writes a read-only page via the connections/notion.md interface on cycle close. Write-only (non-GDD users read; they never write back). Degrades to a local markdown file when no Notion connection is available.
|
|
4
|
+
tools: Read, Write, Bash, Grep, Glob, ToolSearch
|
|
5
|
+
color: green
|
|
6
|
+
default-tier: sonnet
|
|
7
|
+
tier-rationale: "Reads a STATE block, redacts via a pure helper, and renders a page through an existing connection; bounded transform + publish, no design judgment — sonnet-tier."
|
|
8
|
+
size_budget: M
|
|
9
|
+
size_budget_rationale: "Honest tier sized to the ~90-line body. DELEGATES redaction to scripts/lib/pseudonymize.cjs, the Notion write to connections/notion.md, and the contract to reference/multi-author-model.md."
|
|
10
|
+
parallel-safe: false
|
|
11
|
+
typical-duration-seconds: 45
|
|
12
|
+
reads-only: false
|
|
13
|
+
required_reading:
|
|
14
|
+
- "reference/multi-author-model.md"
|
|
15
|
+
- "connections/notion.md"
|
|
16
|
+
writes:
|
|
17
|
+
- "a read-only Notion/Confluence page (external) OR .design/exports/decisions-<cycle>.md (fallback)"
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# decision-journal-exporter
|
|
21
|
+
|
|
22
|
+
You publish a cycle's decisions to a **read-only shared journal** so non-GDD stakeholders can follow
|
|
23
|
+
the "what + why" without the repo. You run on cycle close. **Read `reference/multi-author-model.md`
|
|
24
|
+
and `connections/notion.md` first.** Every author name is **pseudonymized before it leaves the repo**.
|
|
25
|
+
|
|
26
|
+
## Procedure
|
|
27
|
+
|
|
28
|
+
1. **Read the decisions.** Parse `.design/STATE.md` `<decisions>` (with
|
|
29
|
+
`scripts/lib/collab/attribution.cjs` `parseDecisionsBlock`), capturing id, text, status, and
|
|
30
|
+
attribution.
|
|
31
|
+
2. **Pseudonymize.** Pipe the rendered decision text through `scripts/lib/pseudonymize.cjs` BEFORE any
|
|
32
|
+
outbound call — R1 (git identity) + R8 (stable pseudonym) mask `author=`/`co-author=` into a stable
|
|
33
|
+
hash. Never publish a raw git identity.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
node -e '
|
|
37
|
+
const fs = require("fs");
|
|
38
|
+
const { pseudonymize } = require("./scripts/lib/pseudonymize.cjs");
|
|
39
|
+
const raw = fs.readFileSync(0, "utf8");
|
|
40
|
+
process.stdout.write(pseudonymize(raw, {}));
|
|
41
|
+
' < /tmp/decisions.md > /tmp/decisions.redacted.md
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
3. **Render** a read-only page: cycle id, the decision table (id · text · status · pseudonymous
|
|
45
|
+
author), and a "generated by GDD on cycle close — read-only" header. Regenerate each cycle (replace,
|
|
46
|
+
don't append duplicates).
|
|
47
|
+
4. **Publish.** If a Notion connection is `available` (probe via `connections/notion.md`), write the
|
|
48
|
+
page through its write interface (redaction already applied; the connection's own redact pass is a
|
|
49
|
+
second belt). Otherwise **degrade**: write `.design/exports/decisions-<cycle>.md` locally and tell
|
|
50
|
+
the user to share it manually. Confluence follows the same shape if its connection is present.
|
|
51
|
+
5. **Write-only.** You publish; you never read stakeholder edits back into STATE.md (bidirectional sync
|
|
52
|
+
is out of scope this phase).
|
|
53
|
+
|
|
54
|
+
## Record
|
|
55
|
+
|
|
56
|
+
Print a `## Decision journal export` summary: cycle, decisions exported, destination (Notion page /
|
|
57
|
+
local fallback), and confirmation that redaction ran. Append one JSONL line to
|
|
58
|
+
`.design/intel/insights.jsonl`. Close with:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
## DECISION JOURNAL EXPORT COMPLETE
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Boundaries
|
|
65
|
+
|
|
66
|
+
- **Pseudonymize before publish** — no raw git identity ever leaves the repo.
|
|
67
|
+
- Write-only, read-only-for-readers; no bidirectional sync; degrade to local markdown on no connection.
|
|
68
|
+
- Only the `<decisions>` block — not the full STATE.md, not telemetry.
|
|
@@ -92,6 +92,8 @@ After listing standard surprises, apply the **Four Principles Checks** from `ref
|
|
|
92
92
|
|
|
93
93
|
Scan STATE.md `<decisions>` block for D-XX codes. Cross-reference `.design/learnings/` files from prior cycles if present. Flag decisions that: (a) appeared in multiple sessions of the same cycle, or (b) appear under the same keyword in learnings from ≥2 prior cycles. These are candidates for `reference/` additions.
|
|
94
94
|
|
|
95
|
+
**Per-author patterns (Phase 40, team mode).** When decisions carry the `[author= co-author=]` attribution suffix (see `reference/multi-author-model.md`), parse it with `scripts/lib/collab/attribution.cjs` (`parseDecisionsBlock` + `groupByAuthor`) and add a brief **Per-author patterns** sub-note: who locks decisions early, whose decisions get reverted or unlocked most, and any author whose decisions cluster around a recurring keyword. Skip silently when no decision is attributed (single-author projects).
|
|
96
|
+
|
|
95
97
|
### 3. Agent Performance
|
|
96
98
|
|
|
97
99
|
Read `.design/agent-metrics.json`. For each agent:
|
package/agents/pr-commenter.md
CHANGED
|
@@ -67,6 +67,7 @@ const safeBody = redact(commentBody);
|
|
|
67
67
|
1. **Inline review comments** — for each verify/audit finding that maps to a changed file+line, post an inline comment via `gh api repos/{owner}/{repo}/pulls/{n}/comments` (path + line + redacted body: the finding, the rule/pillar, and a one-line suggested fix). Findings with no changed-line locus go into a single summary review comment, not scattered.
|
|
68
68
|
2. **Screenshot pairs (degrade, D-04)** — when `.design/STATE.md` `<connections>` shows `preview: available` or `chromatic: available` AND a before-after pair exists for a changed surface, attach the image refs in the comment/PR timeline. When absent → text-only; never a precondition.
|
|
69
69
|
3. **`gdd/design-review` check-run (D-03)** — `gh api repos/{owner}/{repo}/check-runs` with `name: "gdd/design-review"`, a `conclusion` (`success` if verify passed + no blocker pillars, `failure` if verify failed or a11y-gate failed, else `neutral`), and an `output.summary` carrying the audit pillar scores + verify pass/fail + a11y result. This is the gate a teammate's branch-protection rule can require — see the reference for the required-check setup (`scripts/apply-branch-protection.sh`); you **register** the check, you never edit branch protection.
|
|
70
|
+
4. **Decision threading (Phase 40, team mode)** — for each `D-XX` decision referenced in the PR's `DESIGN.md` / `DESIGN-VERIFICATION.md`, thread a PR comment keyed to that decision (one comment per `D-XX`, body = the decision text + its `proposed/reviewing/approved/locked` review state from `reference/multi-author-model.md`), so decision discussion persists as part of the PR history. Redacted like every other body; degrade-to-noop when `gh` is absent. This makes a decision's rationale reviewable inline by teammates who don't run GDD.
|
|
70
71
|
|
|
71
72
|
---
|
|
72
73
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hegemonart/get-design-done",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.40.0",
|
|
4
4
|
"description": "A design-quality pipeline for AI coding agents: brief, plan, implement, and verify UI work against your design system.",
|
|
5
5
|
"author": "Hegemon",
|
|
6
6
|
"homepage": "https://github.com/hegemonart/get-design-done",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"lint:md": "npx --yes markdownlint-cli2 \"**/*.md\" \"#node_modules\" \"#.planning\" \"#.claude\" \"#test/fixtures/baselines\"",
|
|
57
57
|
"lint:links": "npx --yes lychee --no-progress --accept 200,206,403,429 \"**/*.md\" || true",
|
|
58
58
|
"lint:agentskills": "node scripts/lint-agentskills-spec.cjs",
|
|
59
|
+
"lint:changelog": "node scripts/lint-changelog.cjs",
|
|
59
60
|
"validate:schemas": "node --experimental-strip-types scripts/validate-schemas.ts",
|
|
60
61
|
"validate:frontmatter": "node --experimental-strip-types scripts/validate-frontmatter.ts agents/",
|
|
61
62
|
"detect:stale-refs": "node scripts/detect-stale-refs.cjs",
|
|
@@ -39,3 +39,43 @@ the scanner pattern list in lockstep.
|
|
|
39
39
|
|
|
40
40
|
The scanner excludes `.planning/`, `.claude/`, `.design/`, `node_modules/`,
|
|
41
41
|
`test-fixture/`, and this file itself.
|
|
42
|
+
|
|
43
|
+
## Path migrations (machine-readable)
|
|
44
|
+
|
|
45
|
+
Phase 39.5 adds a machine-readable registry of **path** migrations — modules/files GDD moved or
|
|
46
|
+
removed. `scripts/lib/deprecation-registry.cjs` parses the table below; `/gdd:migrate` consults it to
|
|
47
|
+
help users update local references; `test/suite/deprecation-completeness.test.cjs` asserts every row
|
|
48
|
+
is honest (a `removed` row's `Old` path must be gone from the tree; a `deprecated` row's `Old` path
|
|
49
|
+
must still carry a shim).
|
|
50
|
+
|
|
51
|
+
### Status semantics
|
|
52
|
+
|
|
53
|
+
A row's status is derived from the running plugin version `v`:
|
|
54
|
+
|
|
55
|
+
- **pending** — `v` < `Since` (deprecation announced for a future version; rare).
|
|
56
|
+
- **deprecated** — `Since` ≤ `v` < `Removed in` (the old path still works via a shim; update at leisure).
|
|
57
|
+
- **removed** — `v` ≥ `Removed in` (the old path is gone; you MUST use the new path).
|
|
58
|
+
|
|
59
|
+
**Default shim lifetime is one minor version** (the Phase 31.5 precedent): a path deprecated in `x.y.z`
|
|
60
|
+
is removed in the next minor `x.(y+1).0`. The `Removed in` column is authoritative per row.
|
|
61
|
+
|
|
62
|
+
### Table
|
|
63
|
+
|
|
64
|
+
Columns: `Since` (version the move shipped) · `Removed in` (version the old path stops working;
|
|
65
|
+
blank = still shimmed) · `Old` (pre-move path) · `New` (current path) · `Migration hint`.
|
|
66
|
+
|
|
67
|
+
| Since | Removed in | Old | New | Migration hint |
|
|
68
|
+
|---|---|---|---|---|
|
|
69
|
+
| 1.31.5 | 1.33.0 | `scripts/lib/cli` | `sdk/cli` | Import the CLI barrel from `sdk/cli` instead of `scripts/lib/cli`. |
|
|
70
|
+
| 1.31.5 | 1.33.0 | `scripts/lib/event-stream` | `sdk/event-stream` | Import the event-stream barrel from `sdk/event-stream`. |
|
|
71
|
+
| 1.31.5 | 1.33.0 | `scripts/lib/gdd-state` | `sdk/state` | Import the STATE primitives from `sdk/state`. |
|
|
72
|
+
| 1.31.5 | 1.33.0 | `scripts/lib/gdd-errors` | `sdk/errors` | Import the error types from `sdk/errors`. |
|
|
73
|
+
| 1.31.5 | 1.33.0 | `scripts/lib/error-classifier.cjs` | `sdk/primitives/error-classifier.cjs` | Require `sdk/primitives/error-classifier.cjs`. |
|
|
74
|
+
| 1.31.5 | 1.33.0 | `scripts/lib/iteration-budget.cjs` | `sdk/primitives/iteration-budget.cjs` | Require `sdk/primitives/iteration-budget.cjs`. |
|
|
75
|
+
| 1.31.5 | 1.33.0 | `scripts/lib/jittered-backoff.cjs` | `sdk/primitives/jittered-backoff.cjs` | Require `sdk/primitives/jittered-backoff.cjs`. |
|
|
76
|
+
| 1.31.5 | 1.33.0 | `scripts/lib/lockfile.cjs` | `sdk/primitives/lockfile.cjs` | Require `sdk/primitives/lockfile.cjs`. |
|
|
77
|
+
| 1.31.5 | 1.33.0 | `scripts/mcp-servers/gdd-state/server.ts` | `sdk/mcp/gdd-state/server.ts` | Point the MCP server config at `sdk/mcp/gdd-state/server.ts`. |
|
|
78
|
+
| 1.31.5 | 1.33.0 | `scripts/mcp-servers/gdd-mcp/server.ts` | `sdk/mcp/gdd-mcp/server.ts` | Point the MCP server config at `sdk/mcp/gdd-mcp/server.ts`. |
|
|
79
|
+
|
|
80
|
+
All ten rows are **removed** as of the current release (the Phase 31.5 → `sdk/` reorg; shims removed
|
|
81
|
+
in v1.33.0). The completeness gate confirms none of the `Old` paths remain in the tree.
|
|
@@ -47,6 +47,9 @@ skipped_stages: ""
|
|
|
47
47
|
<decisions>
|
|
48
48
|
<!-- Filled by discover stage. Format: -->
|
|
49
49
|
<!-- D-01: [decision text] (locked | tentative) -->
|
|
50
|
+
<!-- Phase 40 (team mode): an optional attribution suffix records provenance for multi-author merges: -->
|
|
51
|
+
<!-- D-01: [decision text] (locked | tentative) [author=<git-user> co-author=<gdd-instance-id>] -->
|
|
52
|
+
<!-- The suffix is optional + backward-compatible; see reference/multi-author-model.md. -->
|
|
50
53
|
</decisions>
|
|
51
54
|
|
|
52
55
|
<must_haves>
|
|
@@ -376,3 +376,22 @@ If `.design/cache-manifest.json` is missing when `hooks/budget-enforcer.js` read
|
|
|
376
376
|
- `.design/budget.json` — provides `cache_ttl_seconds` default.
|
|
377
377
|
- `.design/telemetry/costs.jsonl` (Plan 10.1-05) — records `cache_hit: true` rows with zero tokens and zero cost when the short-circuit fires.
|
|
378
378
|
- D-05, D-08, D-09 in `.planning/phases/10.1-optimization-layer-cost-governance/10.1-CONTEXT.md` — decision lineage.
|
|
379
|
+
|
|
380
|
+
## Team collaboration (Phase 40)
|
|
381
|
+
|
|
382
|
+
Three optional top-level `.design/config.json` keys enable team mode. All are absent/off by default —
|
|
383
|
+
single-operator projects are unaffected. Full contract: `reference/multi-author-model.md`.
|
|
384
|
+
|
|
385
|
+
- **`gdd_cycle_mode`** (`designer` | `dev` | `full`, default `full`) — sectional handoff. `designer`
|
|
386
|
+
permits Brief + Explore writes; `dev` permits Plan + Design + Verify; `full` = all stages.
|
|
387
|
+
`scripts/lib/collab/cycle-mode.cjs` `stagePermitted(mode, stage)` gates STATE writes by stage.
|
|
388
|
+
- **`permissions`** — per-section write permissions (`scripts/lib/collab/permissions.cjs`). Permissive
|
|
389
|
+
by default (absent = everyone `owner`). Shape: `{ default, actors: {<actor>: <role>}, rules:
|
|
390
|
+
[{section, action, roles}] }`, roles in `owner|contributor|reviewer|viewer`. A rule restricts a
|
|
391
|
+
`(section, action)` to its listed roles; an unruled pair is allowed. `viewer` never mutates. A CI
|
|
392
|
+
gate calls `can(config, actor, section, action)` to enforce on PRs.
|
|
393
|
+
- **`collab`** — `{ multi_writer_enabled (bool), lock_timeout_ms (int), sync_backend
|
|
394
|
+
(git|s3|git-lfs) }`. `multi_writer_enabled: true` switches the gdd-state advisory lock to the
|
|
395
|
+
team-mode policy (`scripts/lib/collab/lock-policy.cjs` — 30 s wait + 100 ms backoff);
|
|
396
|
+
`sync_backend` selects the cross-machine `.design/` backend (`scripts/lib/collab/sync-backend.cjs`,
|
|
397
|
+
default `git`; `s3`/`git-lfs` are opt-in declarations — a live client is not bundled this phase).
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Multi-Author Model — Team Collaboration Contract
|
|
2
|
+
|
|
3
|
+
Phase 40 contract. GDD's single-process baseline (Phase 20 lockfile + atomic STATE.md RMW) is safe for
|
|
4
|
+
one operator. This file is the contract for **multiple developers** working a design in parallel: how
|
|
5
|
+
STATE.md merges, how decisions are attributed and reviewed, how writes coordinate across processes,
|
|
6
|
+
and who is allowed to write what. Everything here is **git-native + advisory** — no server, no live
|
|
7
|
+
multiplayer, no SSO.
|
|
8
|
+
|
|
9
|
+
## 1. Multi-writer STATE.md — git-merge-driver with per-section semantic merge
|
|
10
|
+
|
|
11
|
+
GDD does **not** ship a CRDT or OT engine. The chosen model (lowest risk, highest familiarity) is a
|
|
12
|
+
**git merge driver with per-section semantic conflict detection**. The append-mostly `<decisions>`
|
|
13
|
+
block is the common case: two branches each adding a new `D-NN` must merge cleanly. The pure core
|
|
14
|
+
`scripts/lib/collab/section-merge.cjs` implements the rule:
|
|
15
|
+
|
|
16
|
+
- **Union by id.** A `D-NN` present on only one side (vs the merge base) is kept.
|
|
17
|
+
- **Equal duplicates collapse.** The same `D-NN` with identical text/status/attribution on both sides
|
|
18
|
+
is kept once.
|
|
19
|
+
- **Divergence is the only conflict.** The same `D-NN` with different text or status on the two sides
|
|
20
|
+
is a genuine conflict — surfaced to `agents/conflict-resolver.md`, never auto-resolved.
|
|
21
|
+
- **Decisions are durable.** A `D-NN` removed on one side but unchanged on the other is **kept** — a
|
|
22
|
+
decision is never silently deleted by a merge; removal goes through the unlock flow (§3).
|
|
23
|
+
|
|
24
|
+
A single-value section (e.g. `status`) merges with `mergeStatusScalar`: if only one side changed, take
|
|
25
|
+
that side; if both changed differently, it's a conflict.
|
|
26
|
+
|
|
27
|
+
## 2. Attribution
|
|
28
|
+
|
|
29
|
+
A decision line carries an **optional** attribution suffix:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
D-07: Use OKLCH design tokens (locked) [author=alice co-author=gdd-3f9a]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- `author` — the git user who made the decision.
|
|
36
|
+
- `co-author` — the GDD instance id (which machine/agent run produced it).
|
|
37
|
+
|
|
38
|
+
The suffix is backward-compatible: a plain `D-01: text (locked)` parses with `author`/`co-author` =
|
|
39
|
+
null. `scripts/lib/collab/attribution.cjs` parses + formats the line and groups decisions by author.
|
|
40
|
+
`agents/design-reflector.md` reads attribution to surface **per-author patterns** (who tends to lock
|
|
41
|
+
early, whose decisions get reverted). This is the SC#5 "attribution field" — encoded in the line, not
|
|
42
|
+
a schema-breaking change to the `Decision` type.
|
|
43
|
+
|
|
44
|
+
## 3. Async review queue + decision locks
|
|
45
|
+
|
|
46
|
+
Each decision under review lives at `.design/reviews/<decision-id>/`, moving through a state machine
|
|
47
|
+
(`scripts/lib/collab/review-queue.cjs`):
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
proposed → reviewing → approved → locked
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- **`locked` is terminal and hard.** A locked decision cannot be amended. `canAmend(state)` is true
|
|
54
|
+
only for `proposed`/`reviewing`.
|
|
55
|
+
- **Unlock is explicit + audited.** `/gdd:unlock-decision <id> --approver <who>` moves `locked →
|
|
56
|
+
reviewing` and appends an audit entry (`{ from:'locked', to:'reviewing', approver, reason }`). There
|
|
57
|
+
is no silent unlock.
|
|
58
|
+
- **`/gdd:review-decisions`** surfaces every queue entry by state (and `--pending` for the ones
|
|
59
|
+
awaiting action).
|
|
60
|
+
|
|
61
|
+
## 4. Multi-writer lock policy
|
|
62
|
+
|
|
63
|
+
`scripts/lib/collab/lock-policy.cjs` derives the `acquire()` options from config. In single-process
|
|
64
|
+
mode the Phase 20 defaults apply (`maxWaitMs: 5000`). When `collab.multi_writer_enabled: true`, a
|
|
65
|
+
teammate's write may be queued, so the policy waits up to **30 s** with a **100 ms** backoff poll and a
|
|
66
|
+
2-minute stale threshold. `collab.lock_timeout_ms` overrides the wait. The gdd-state MCP write path
|
|
67
|
+
passes these options to the existing advisory lock — coordinated multi-process writes, no new lock
|
|
68
|
+
mechanism.
|
|
69
|
+
|
|
70
|
+
## 5. Sectional handoff — `gdd_cycle_mode`
|
|
71
|
+
|
|
72
|
+
`.design/config.json#gdd_cycle_mode` partitions a cycle by role (`scripts/lib/collab/cycle-mode.cjs`):
|
|
73
|
+
|
|
74
|
+
| Mode | Permitted stages |
|
|
75
|
+
|---|---|
|
|
76
|
+
| `designer` | Brief, Explore |
|
|
77
|
+
| `dev` | Plan, Design, Verify |
|
|
78
|
+
| `full` | all (the default / current behavior) |
|
|
79
|
+
|
|
80
|
+
`stagePermitted(mode, stage)` gates STATE writes by stage — a designer-mode cycle cannot write Plan/Design
|
|
81
|
+
state, and vice versa. This lets a designer hand a brief to a dev without either overwriting the other's
|
|
82
|
+
sections.
|
|
83
|
+
|
|
84
|
+
## 6. Permissions
|
|
85
|
+
|
|
86
|
+
`.design/config.json#permissions` declares who can write which sections
|
|
87
|
+
(`scripts/lib/collab/permissions.cjs` `can(config, actor, section, action)`). The default policy is
|
|
88
|
+
permissive (`owner` can do everything); an override can restrict, e.g. "only `@lead-designer` can
|
|
89
|
+
`lock` decisions". A CI gate asserts the permission model is enforced on PRs.
|
|
90
|
+
|
|
91
|
+
## 7. Decision-journal export + PR threading
|
|
92
|
+
|
|
93
|
+
- **`agents/decision-journal-exporter.md`** writes a **read-only** Notion/Confluence page from the
|
|
94
|
+
`<decisions>` block on cycle close (write-only this phase; non-GDD stakeholders read it). Every
|
|
95
|
+
decision is piped through `scripts/lib/pseudonymize.cjs` first (R1 git-identity + R8 stable hash), so
|
|
96
|
+
author names are masked before they leave the repo. Degrades to a local markdown file when no Notion
|
|
97
|
+
connection is available.
|
|
98
|
+
- **`agents/pr-commenter.md`** threads PR review comments on the `D-XX` decisions referenced in
|
|
99
|
+
DESIGN.md / DESIGN-VERIFICATION.md, so decision discussion persists as part of the PR history.
|
|
100
|
+
|
|
101
|
+
## 8. Cross-machine sync (opt-in)
|
|
102
|
+
|
|
103
|
+
`scripts/lib/collab/sync-backend.cjs` `resolveBackend(config)` selects the `.design/` sync backend:
|
|
104
|
+
`git` (the **default** — existing behavior), or an opt-in `s3` / `git-lfs` for orgs whose git
|
|
105
|
+
push/pull cadence is too slow. Sync is **opt-in and off by default**; a live S3/LFS client is out of
|
|
106
|
+
scope for this phase — the selector + contract ship, the backend is pluggable.
|
|
107
|
+
|
|
108
|
+
## Boundaries
|
|
109
|
+
|
|
110
|
+
No real-time multiplayer, no SSO/SAML, no GDD-side user accounts (users are git authors), no
|
|
111
|
+
bidirectional Notion, no merge-queue automation beyond the conflict-resolver. Everything is advisory
|
|
112
|
+
and git-native: a team that already uses git + PRs gets collaboration without new infrastructure.
|
package/reference/registry.json
CHANGED
|
@@ -1028,6 +1028,13 @@
|
|
|
1028
1028
|
"type": "heuristic",
|
|
1029
1029
|
"phase": 39.2,
|
|
1030
1030
|
"description": "Phase 39.2 cost-governance contract: the per-cycle forecast model (best/typical/worst from mean ± k·σ, cyclesToCap) via scripts/lib/budget/cost-forecast.cjs; the project_cap hard-halt (disabled by default, graceful PreToolUse:Agent block, warn 50/80 + halt 100) via scripts/lib/budget/project-cap.cjs + hooks/budget-enforcer.ts; the ROI dashboard (shipped = surviving >=14d, cost-per-shipped-commit) via scripts/lib/budget/roi.cjs; and the budget_forecast/project_cap_warning/project_cap_halt events. Agent agents/cost-forecaster.md; skills /gdd:budget + /gdd:roi. Read/report-only — the hook only blocks, never spends."
|
|
1031
|
+
},
|
|
1032
|
+
{
|
|
1033
|
+
"name": "multi-author-model",
|
|
1034
|
+
"path": "reference/multi-author-model.md",
|
|
1035
|
+
"type": "meta-rules",
|
|
1036
|
+
"phase": 40,
|
|
1037
|
+
"description": "Phase 40 team-collaboration contract: multi-writer STATE.md via a git-merge-driver with per-section semantic merge (scripts/lib/collab/section-merge.cjs — union by D-id, conflict only on same-id divergence); decision attribution line-suffix [author= co-author=] (attribution.cjs); the async review queue proposed->reviewing->approved->locked with hard locks + audited /gdd:unlock-decision (review-queue.cjs); the multi-writer advisory-lock policy (lock-policy.cjs, 30s/100ms backoff in team mode); sectional handoff gdd_cycle_mode designer|dev|full (cycle-mode.cjs); the permission model (permissions.cjs) + CI gate; decision-journal-exporter (pseudonymized, write-only Notion) + pr-commenter D-XX threading; opt-in cross-machine sync (sync-backend.cjs, defaults to git). Agents conflict-resolver + decision-journal-exporter; skills /gdd:review-decisions + /gdd:unlock-decision."
|
|
1031
1038
|
}
|
|
1032
1039
|
]
|
|
1033
1040
|
}
|
|
@@ -40,6 +40,43 @@
|
|
|
40
40
|
"update_dismissed": {
|
|
41
41
|
"type": "string",
|
|
42
42
|
"description": "Latest plugin tag (e.g. \"v1.0.7.3\") whose update nudge the user has dismissed. Set by /gdd:check-update --dismiss and by hooks/update-check.sh on the --dismiss code path. When a newer tag ships, the nudge reappears."
|
|
43
|
+
},
|
|
44
|
+
"gdd_cycle_mode": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"enum": ["designer", "dev", "full"],
|
|
47
|
+
"description": "Phase 40 sectional handoff. designer = Brief + Explore only; dev = Plan + Design + Verify; full = all stages (default). scripts/lib/collab/cycle-mode.cjs gates STATE writes by stage so a designer and a dev can hand a cycle back and forth without overwriting each other's sections."
|
|
48
|
+
},
|
|
49
|
+
"permissions": {
|
|
50
|
+
"type": "object",
|
|
51
|
+
"additionalProperties": true,
|
|
52
|
+
"description": "Phase 40 per-section write permissions (scripts/lib/collab/permissions.cjs). Permissive by default (absent = everyone is owner). A team narrows it, e.g. only @lead-designer may lock decisions. A CI gate enforces on PRs.",
|
|
53
|
+
"properties": {
|
|
54
|
+
"default": { "type": "string", "enum": ["owner", "contributor", "reviewer", "viewer"], "description": "Role for any actor not listed in `actors`. Default owner." },
|
|
55
|
+
"actors": { "type": "object", "additionalProperties": { "type": "string", "enum": ["owner", "contributor", "reviewer", "viewer"] }, "description": "Per-actor role map (git user/handle -> role)." },
|
|
56
|
+
"rules": {
|
|
57
|
+
"type": "array",
|
|
58
|
+
"items": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"additionalProperties": true,
|
|
61
|
+
"properties": {
|
|
62
|
+
"section": { "type": "string", "description": "STATE.md section (decisions/prototyping/rollout_status/status/progress/blockers) or '*'." },
|
|
63
|
+
"action": { "type": "string", "enum": ["write", "lock", "unlock", "approve", "*"] },
|
|
64
|
+
"roles": { "type": "array", "items": { "type": "string", "enum": ["owner", "contributor", "reviewer", "viewer"] } }
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"description": "Restrictive rules: a (section, action) is limited to the listed roles. No matching rule = allowed (permissive)."
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"collab": {
|
|
72
|
+
"type": "object",
|
|
73
|
+
"additionalProperties": true,
|
|
74
|
+
"description": "Phase 40 team-collaboration settings.",
|
|
75
|
+
"properties": {
|
|
76
|
+
"multi_writer_enabled": { "type": "boolean", "description": "When true, the gdd-state advisory lock uses the team-mode policy (longer wait + backoff) via scripts/lib/collab/lock-policy.cjs. Default false (single-process)." },
|
|
77
|
+
"lock_timeout_ms": { "type": "integer", "minimum": 0, "description": "Override the team-mode lock acquire maxWaitMs (default 30000)." },
|
|
78
|
+
"sync_backend": { "type": "string", "enum": ["git", "s3", "git-lfs"], "description": "Cross-machine .design/ sync backend (scripts/lib/collab/sync-backend.cjs). Default git (existing push/pull). s3 / git-lfs are opt-in declarations; a live client is not bundled this phase." }
|
|
79
|
+
}
|
|
43
80
|
}
|
|
44
81
|
}
|
|
45
82
|
}
|