@hegemonart/get-design-done 1.39.5 → 1.40.5
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 +63 -0
- package/README.md +8 -0
- package/SKILL.md +3 -0
- package/agents/README.md +1 -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 +1 -1
- package/reference/STATE-TEMPLATE.md +3 -0
- package/reference/cli-localization.md +61 -0
- package/reference/config-schema.md +27 -0
- package/reference/multi-author-model.md +112 -0
- package/reference/registry.json +14 -0
- package/reference/schemas/config.schema.json +42 -0
- package/reference/schemas/generated.d.ts +54 -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/i18n/index.cjs +95 -0
- package/scripts/lib/i18n/messages/de.json +7 -0
- package/scripts/lib/i18n/messages/en.json +27 -0
- package/scripts/lib/i18n/messages/fr.json +7 -0
- package/scripts/lib/i18n/messages/ja.json +7 -0
- package/scripts/lib/i18n/messages/ru.json +27 -0
- package/scripts/lib/i18n/messages/uk.json +7 -0
- package/scripts/lib/i18n/messages/zh.json +7 -0
- package/skills/locale/SKILL.md +51 -0
- package/skills/review-decisions/SKILL.md +42 -0
- package/skills/unlock-decision/SKILL.md +54 -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.5"
|
|
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.5",
|
|
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.5",
|
|
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,69 @@ All notable changes to get-design-done are documented here. Versions follow [sem
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [1.40.5] - 2026-06-01
|
|
8
|
+
|
|
9
|
+
### Phase 40.5 — GDD CLI Localization
|
|
10
|
+
|
|
11
|
+
GDD's README is multilingual, but the CLI talked English. 40.5 adds locale resolution + per-locale
|
|
12
|
+
message tables for the highest-traffic surface — `--help`, common error messages, and skill prompt
|
|
13
|
+
headers. English is always the final fallback, so a partial locale never breaks the CLI. **No new
|
|
14
|
+
runtime dependency, no new egress.**
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`scripts/lib/i18n/index.cjs`** — locale resolver: `resolveLocale` (`config.locale` > env `LANG`/`LC_ALL` > `en`), `fallbackChain` (`locale → base → en`), `translate` (chain walk; a missing key returns the key, never throws), `descriptionFor` (`description_i18n` || English). Pure functions + a thin `loadTable` reader.
|
|
19
|
+
- **`scripts/lib/i18n/messages/{en,ru,uk,de,fr,zh,ja}.json`** — flat message tables. `en` is the complete source (24 keys: `help.*`/`error.*`/`prompt.*`/`status.*`), `ru` a full translation, `uk`/`de`/`fr`/`zh`/`ja` placeholders (a `_meta` marker + a starter subset) that fall back to English.
|
|
20
|
+
- **`skills/locale/SKILL.md`** (`/gdd:locale [<code>]`) — inspect the resolved locale + per-locale coverage, or set `.design/config.json#locale`.
|
|
21
|
+
- **`reference/cli-localization.md`** — the resolver contract + the add-a-locale contribution path (translate the table, add a `NOTICE` translator credit, open a PR; warn-only completeness). Registered. Distinct from `reference/i18n.md` (which covers *user-design* i18n).
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- **`reference/schemas/config.schema.json`** — + `locale` (enum en/ru/uk/de/fr/zh/ja); `generated.d.ts` regenerated.
|
|
26
|
+
- **`agents/README.md`** — document the opt-in `description_i18n` frontmatter field (falls back to the English `description`; backward-compatible — the 28.5 contract validates it only when present).
|
|
27
|
+
|
|
28
|
+
### Notes
|
|
29
|
+
|
|
30
|
+
- **No new runtime dependency, no new egress.** Pure resolver + JSON tables + docs.
|
|
31
|
+
- The completeness gate is **warn-only** — only `en` + `ru` are full; the five placeholder locales rely on the English fallback and are never required to be 100%.
|
|
32
|
+
- 6-manifest lockstep at **v1.40.5** + `OFF_CADENCE_VERSIONS.add('1.40.5')` + the 34 live-pinned `manifests-version.txt` baselines forward-propagated 1.40.0 → 1.40.5.
|
|
33
|
+
- Inventory relock: registry-diff 159 → 160 (+`cli-localization`), skill-list 82 → 83 (+`locale`), skill-length-distribution relocked, tarball golden 721 → 731 (+10). No agent/event deltas. Root `SKILL.md` command table += `locale`.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## [1.40.0] - 2026-06-01
|
|
38
|
+
|
|
39
|
+
### Phase 40 — Team Collaboration Mode
|
|
40
|
+
|
|
41
|
+
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.**
|
|
42
|
+
|
|
43
|
+
### Breaking changes
|
|
44
|
+
|
|
45
|
+
**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.
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- **`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.
|
|
50
|
+
- **`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).
|
|
51
|
+
- **`agents/conflict-resolver.md`** — three-way STATE.md merge, per-section + human-confirmed; never auto-picks or drops a decision.
|
|
52
|
+
- **`agents/decision-journal-exporter.md`** — `<decisions>` → `pseudonymize` → read-only Notion/Confluence on cycle close (write-only; degrades to local markdown).
|
|
53
|
+
- **`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).
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- **`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.
|
|
58
|
+
- **`reference/STATE-TEMPLATE.md`** — document the optional decision attribution suffix.
|
|
59
|
+
- **`agents/design-reflector.md`** — a "Per-author patterns" note (reads attribution).
|
|
60
|
+
- **`agents/pr-commenter.md`** — thread PR comments on `D-XX` decisions (team-mode).
|
|
61
|
+
|
|
62
|
+
### Notes
|
|
63
|
+
|
|
64
|
+
- **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).
|
|
65
|
+
- 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.
|
|
66
|
+
- 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.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
7
70
|
## [1.39.5] - 2026-06-01
|
|
8
71
|
|
|
9
72
|
### Phase 39.5 — GDD Self-Migration Tooling
|
package/README.md
CHANGED
|
@@ -190,6 +190,14 @@ GDD already tracks cost per task and per runtime — now it **forecasts** it, **
|
|
|
190
190
|
|
|
191
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
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
|
+
|
|
197
|
+
### CLI localization (v1.40.5)
|
|
198
|
+
|
|
199
|
+
GDD's README is multilingual — now its **CLI** is too. [`/gdd:locale <code>`](skills/locale/SKILL.md) sets the language of `--help`, common error messages, and skill prompt headers, resolved by [`scripts/lib/i18n`](scripts/lib/i18n/index.cjs) (precedence: `config.locale` > env `LANG` > `en`; fallback chain `locale → base → en`). Flat-JSON message tables ship for **en** (complete source), **ru** (full), and **uk/de/fr/zh/ja** placeholders — a missing key always falls back to English, so a partial locale never breaks the CLI. Skills + agents can carry an opt-in `description_i18n` map. Adding a locale is a PR: translate the table, add a `NOTICE` credit (the contribution path is in [`reference/cli-localization.md`](reference/cli-localization.md)). Completeness is **warn-only**. **No new runtime dependency.**
|
|
200
|
+
|
|
193
201
|
### Previous releases
|
|
194
202
|
|
|
195
203
|
- **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
|
@@ -105,6 +105,9 @@ Each stage produces artifacts in `.design/` inside the current project.
|
|
|
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
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 |
|
|
110
|
+
| `locale [<code>]` | `get-design-done:gdd-locale` | Phase 40.5 — inspect or set the GDD CLI locale (en/ru/uk/de/fr/zh/ja) for `--help`, errors, and skill prompt headers; missing keys fall back to English. No arg reports the resolved locale + coverage |
|
|
108
111
|
|
|
109
112
|
## Handoff Routing
|
|
110
113
|
|
package/agents/README.md
CHANGED
|
@@ -39,6 +39,7 @@ Every agent file begins with a YAML frontmatter block. All fields except `model`
|
|
|
39
39
|
|-------|------|-----------------|---------|
|
|
40
40
|
| `name` | kebab-case string | unique within plugin | Identifier passed to the `Task` tool — must match the filename without `.md` |
|
|
41
41
|
| `description` | string | free-form | One sentence: what the agent does + when it is spawned |
|
|
42
|
+
| `description_i18n` | object | `{ <locale>: "<description>" }` | **Phase 40.5, opt-in.** Localized descriptions keyed by locale (en/ru/uk/de/fr/zh/ja). `scripts/lib/i18n/index.cjs` `descriptionFor(frontmatter, locale)` resolves it via the fallback chain and falls back to the English `description` when a locale is absent. Backward-compatible — omit it and nothing changes. |
|
|
42
43
|
| `tools` | comma-separated list | `Read`, `Write`, `Edit`, `Bash`, `Grep`, `Glob`, `Task`, `WebFetch`, `TodoWrite`, `mcp__*` | Claude tools the agent may use — list only what is needed |
|
|
43
44
|
| `color` | enum | `yellow`, `green`, `blue`, `red` | Terminal display color for the agent's output |
|
|
44
45
|
| `model` | enum (optional) | `inherit`, `sonnet`, `haiku` | Omit to use the project's configured profile default. Use `inherit` to bypass the profile and use the highest available model (quality-tier work) |
|
|
@@ -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.5",
|
|
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",
|
|
@@ -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>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# CLI Localization — GDD's Own Surface
|
|
2
|
+
|
|
3
|
+
Phase 40.5 contract. `reference/i18n.md` covers internationalizing *user designs*; this file covers
|
|
4
|
+
**GDD's own CLI** — `--help`, the common error messages, and skill prompt headers. The goal is the
|
|
5
|
+
lowest-effort, highest-impact subset; full skill-body translation is deferred (per-locale demand).
|
|
6
|
+
|
|
7
|
+
## Resolution
|
|
8
|
+
|
|
9
|
+
`scripts/lib/i18n/index.cjs` resolves the active locale with this precedence:
|
|
10
|
+
|
|
11
|
+
1. **`.design/config.json#locale`** — an explicit per-project override (set via `/gdd:locale <code>`).
|
|
12
|
+
2. **`process.env`** — `LC_ALL` / `LC_MESSAGES` / `LANG` / `LANGUAGE` (normalized: `ru_RU.UTF-8` → `ru`).
|
|
13
|
+
3. **`en`** — the default.
|
|
14
|
+
|
|
15
|
+
A `C` / `POSIX` env locale resolves to `en`. The resolved code then drives a **fallback chain**
|
|
16
|
+
`locale → base → en` (e.g. `de-DE → de → en`), so a regional locale degrades to its base and finally
|
|
17
|
+
to English — the complete source table.
|
|
18
|
+
|
|
19
|
+
## Message tables
|
|
20
|
+
|
|
21
|
+
Flat-JSON tables live at `scripts/lib/i18n/messages/<locale>.json` (chosen over ICU MessageFormat for
|
|
22
|
+
simplicity). Each is `{ "_meta": { locale, coverage, fallback }, "<key>": "<string>", ... }`. Keys are
|
|
23
|
+
namespaced: `help.*` (usage + section headers), `error.*` (the common CLI errors), `prompt.*` (skill
|
|
24
|
+
prompt headers), `status.*`.
|
|
25
|
+
|
|
26
|
+
- **`en.json`** — the **complete source of truth**; every key lives here.
|
|
27
|
+
- **`ru.json`** — a complete second-locale translation (covers every `en` key).
|
|
28
|
+
- **`uk.json` / `de.json` / `fr.json` / `zh.json` / `ja.json`** — **placeholders**: a `_meta` marker
|
|
29
|
+
(`coverage: "placeholder"`) plus a starter subset. Any missing key falls back to `en` per the chain.
|
|
30
|
+
|
|
31
|
+
`translate(tables, key, locale)` walks the chain and returns the first hit, or the key itself if no
|
|
32
|
+
table has it (a missing key is always visible, never a crash).
|
|
33
|
+
|
|
34
|
+
## Frontmatter `description_i18n`
|
|
35
|
+
|
|
36
|
+
Skills and agents may carry an **opt-in** `description_i18n: { <locale>: "<description>" }` map.
|
|
37
|
+
`descriptionFor(frontmatter, locale)` returns the localized description via the fallback chain, or the
|
|
38
|
+
plain English `description` when the locale is absent. The field is fully backward-compatible — a
|
|
39
|
+
skill/agent without it is unaffected, and the Phase 28.5 contract only validates it (as an object of
|
|
40
|
+
locale→string) when present.
|
|
41
|
+
|
|
42
|
+
## Completeness policy
|
|
43
|
+
|
|
44
|
+
The completeness gate is **warn-only**. Only `en` (source) and `ru` (full) are expected to be 100%; the
|
|
45
|
+
five placeholder locales are intentionally partial and rely on the English fallback. A locale is never
|
|
46
|
+
required to be complete to ship — partial is better than English-only, and fallback guarantees no key
|
|
47
|
+
is ever missing at runtime.
|
|
48
|
+
|
|
49
|
+
## Adding or completing a locale (contribution path)
|
|
50
|
+
|
|
51
|
+
1. Edit `scripts/lib/i18n/messages/<locale>.json` — add the keys you can translate (any `en` key is
|
|
52
|
+
fair game; you do not need 100%).
|
|
53
|
+
2. Set `_meta.coverage` to `"complete"` once every `en` key is present, else leave `"placeholder"`.
|
|
54
|
+
3. Add a translator-credit line to `NOTICE` under the attributions section (name/handle + locale).
|
|
55
|
+
4. Open a PR. The warn-only gate reports coverage; it does not block on partial locales.
|
|
56
|
+
|
|
57
|
+
## Boundaries
|
|
58
|
+
|
|
59
|
+
`--help` + common errors + skill prompt headers only — not full skill bodies (deferred per demand),
|
|
60
|
+
not RTL terminal rendering (a terminal concern), not voice/conversational localization. English is
|
|
61
|
+
always the final fallback, so the CLI is never broken by a partial translation.
|
|
@@ -376,3 +376,30 @@ 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).
|
|
398
|
+
|
|
399
|
+
## CLI localization (Phase 40.5)
|
|
400
|
+
|
|
401
|
+
- **`locale`** (`en`|`ru`|`uk`|`de`|`fr`|`zh`|`ja`) — overrides the language of GDD's own `--help`,
|
|
402
|
+
common error messages, and skill prompt headers. Set via `/gdd:locale <code>`. Precedence: this key >
|
|
403
|
+
env `LANG`/`LC_ALL` > `en`. Missing message keys fall back to English (`scripts/lib/i18n/index.cjs`,
|
|
404
|
+
chain `locale → base → en`); `en` + `ru` are complete, the other five are placeholders. Full
|
|
405
|
+
contract: `reference/cli-localization.md`.
|
|
@@ -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,20 @@
|
|
|
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."
|
|
1038
|
+
},
|
|
1039
|
+
{
|
|
1040
|
+
"name": "cli-localization",
|
|
1041
|
+
"path": "reference/cli-localization.md",
|
|
1042
|
+
"type": "meta-rules",
|
|
1043
|
+
"phase": 40.5,
|
|
1044
|
+
"description": "Phase 40.5 CLI-localization contract: locale resolution (config.locale > env LANG > en) + fallback chain locale->base->en + flat-JSON message tables via scripts/lib/i18n/index.cjs; tables at scripts/lib/i18n/messages/{en,ru,uk,de,fr,zh,ja}.json (en source-complete, ru full, 5 placeholders with en fallback); the opt-in description_i18n frontmatter (descriptionFor falls back to English); /gdd:locale skill; warn-only completeness; the add-a-locale contribution path (translate table + NOTICE credit + PR). Distinct from reference/i18n.md (which covers USER-design i18n)."
|
|
1031
1045
|
}
|
|
1032
1046
|
]
|
|
1033
1047
|
}
|
|
@@ -40,6 +40,48 @@
|
|
|
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
|
+
"locale": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"enum": ["en", "ru", "uk", "de", "fr", "zh", "ja"],
|
|
47
|
+
"description": "Phase 40.5 CLI locale override for GDD's own --help, error messages, and skill prompt headers. Set via /gdd:locale <code>. Precedence: this key > env LANG/LC_ALL > en. Missing message keys fall back to English per scripts/lib/i18n/index.cjs (locale -> base -> en). en + ru are complete; uk/de/fr/zh/ja are placeholders that fall back to English."
|
|
48
|
+
},
|
|
49
|
+
"gdd_cycle_mode": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"enum": ["designer", "dev", "full"],
|
|
52
|
+
"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."
|
|
53
|
+
},
|
|
54
|
+
"permissions": {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"additionalProperties": true,
|
|
57
|
+
"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.",
|
|
58
|
+
"properties": {
|
|
59
|
+
"default": { "type": "string", "enum": ["owner", "contributor", "reviewer", "viewer"], "description": "Role for any actor not listed in `actors`. Default owner." },
|
|
60
|
+
"actors": { "type": "object", "additionalProperties": { "type": "string", "enum": ["owner", "contributor", "reviewer", "viewer"] }, "description": "Per-actor role map (git user/handle -> role)." },
|
|
61
|
+
"rules": {
|
|
62
|
+
"type": "array",
|
|
63
|
+
"items": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"additionalProperties": true,
|
|
66
|
+
"properties": {
|
|
67
|
+
"section": { "type": "string", "description": "STATE.md section (decisions/prototyping/rollout_status/status/progress/blockers) or '*'." },
|
|
68
|
+
"action": { "type": "string", "enum": ["write", "lock", "unlock", "approve", "*"] },
|
|
69
|
+
"roles": { "type": "array", "items": { "type": "string", "enum": ["owner", "contributor", "reviewer", "viewer"] } }
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"description": "Restrictive rules: a (section, action) is limited to the listed roles. No matching rule = allowed (permissive)."
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"collab": {
|
|
77
|
+
"type": "object",
|
|
78
|
+
"additionalProperties": true,
|
|
79
|
+
"description": "Phase 40 team-collaboration settings.",
|
|
80
|
+
"properties": {
|
|
81
|
+
"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)." },
|
|
82
|
+
"lock_timeout_ms": { "type": "integer", "minimum": 0, "description": "Override the team-mode lock acquire maxWaitMs (default 30000)." },
|
|
83
|
+
"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." }
|
|
84
|
+
}
|
|
43
85
|
}
|
|
44
86
|
}
|
|
45
87
|
}
|