Skip to content

docs: design plan for reverse Penpot→repo sync + scaling#202

Open
Hackshaven wants to merge 7 commits into
mainfrom
claude/inspiring-davinci-jcnuog
Open

docs: design plan for reverse Penpot→repo sync + scaling#202
Hackshaven wants to merge 7 commits into
mainfrom
claude/inspiring-davinci-jcnuog

Conversation

@Hackshaven

Copy link
Copy Markdown
Member

What

Adds docs/DESIGN_SYNC_PLAN.md — a "draft for review" plan that designs the reverse half of the design-system sync (Penpot → repo) and sketches how the pipeline could scale to complete panels and full-screen layouts. Cross-linked from DESIGN_SYSTEM_PLAN.md (Future Work), which remains the architecture-of-record for the forward direction. Planning only — no sync code is built and no tokens/*.json is changed.

Why

The forward direction (repo → Penpot, three seeder scripts) is shipped, but the reverse direction — a designer's Penpot change flowing back into tokens/*.json as a reviewed PR — only exists as a manual "export-and-commit" flow that DESIGN_SYSTEM_PLAN.md explicitly defers. This doc designs removing that friction.

Key findings & decisions

  • Audit: the Penpot MCP is four tools; everything funnels through execute_code against penpot.library.local.tokens. The reverse path is the same bridge the seeders already read from — a true mirror of the seeders.
  • Round-trip-hostile tokens (calc(...), number/fractional weight, composites) and the build's UI-scale/touch-floor wrapping stay repo-authoritative; the exporter restores them rather than trusting Penpot.
  • Two channels, one reconcile: native export holds the reliability contract (MCP is pre-beta); the MCP exporter is a preferred accelerant.
  • Acceptance gate = empty round-trip diff (seed → export → normalize → diff), validated first by hand on Components/Playback (Phase R0).
  • Three-way conflict detection with a git-anchored ancestor (recorded SHA), not a duplicate snapshot directory.
  • Scaling ceiling held conservative: tokens + breakpoint geometry in Penpot; layout/animation/structural CSS stay in code (R4 is a go/no-go spike, expected no-go).

The five original open questions were resolved in review and folded into §5; the only carried-forward item is operational — run the live read-only MCP probe (blocked under plan mode) as the first task of Phase R0.

https://claude.ai/code/session_01Mnw8HsYkYTFQiVkQghVnZu


Generated by Claude Code

claude added 2 commits June 15, 2026 21:59
Design the reverse half of the design-system sync and sketch how the
pipeline could scale to complete panels and full-screen layouts.
Cross-linked from DESIGN_SYSTEM_PLAN.md Future Work.

Status: draft for review.
Signed-off-by: Claude <noreply@anthropic.com>
Fold the five §7 questions into §5 Decisions: channel-B reliability
contract, draft-PR-per-sync, git-anchored three-way ancestor (replacing
the snapshot-directory approach), conservative §3 ceiling, and spacing
scale as a parallel track.

Signed-off-by: Claude <noreply@anthropic.com>
Claude Code on the web has no interactive MCP-approval UI and reads
settings only at session start. Pre-approve the Penpot MCP tools in the
committed settings so the design-sync reverse-export workflow can run
without per-call prompts. execute_code is write-capable; scope down or
remove before merging to main if the MCP workflow is not ongoing.

Signed-off-by: Claude <noreply@anthropic.com>
…ity gate (R0/R1)

Implements the reverse design-sync code from docs/DESIGN_SYNC_PLAN.md
phases R0/R1 — the Penpot→repo half that mirrors the three
sync-penpot-* seeders run in the read direction.

- scripts/read-penpot.ts — Channel-A reader: emits one read-only
  execute_code plugin that dumps the whole local token graph
  (PenpotGraph), file-guarded on currentFile. One unified reader, not
  three: reading is uniform over a single token graph and the reconcile
  needs all of it at once (modes live in separate Modes/* sets).
- scripts/penpot-reconcile.ts — the one shared reconcile/normalize step.
  Overlays round-trippable values onto the repo JSON as a structural
  template (structure is repo-owned), so the empty-diff gate is trivially
  correct, the hostile set (calc/number/composite) is restored for free,
  mode overrides re-nest in place, build artifacts are rejected, and new
  Penpot tokens are flagged not auto-added.
- scripts/check-design-roundtrip.ts + design-roundtrip.yml — the §2
  acceptance gate (seed → export → reconcile → diff) as advisory CI.
  Runs against a simulated post-seed graph (live MCP can't run in CI),
  proving reconcile ∘ seed = identity: empty diff across 122 tokens / 5
  files, 4 hostile values restored byte-identical.
- Gating unit tests for the reconcile core and reader.

R0's live empirical probe is the one remaining item: blocked by the
managed MCP gateway pinning Penpot tools to always_ask (an automated
cloud session has no approval channel), not by design. Connection/auth
are healthy and a direct streamable-HTTP path with the account MCP key
is verified feasible — recorded in §1/§4/§7.

Signed-off-by: Claude <noreply@anthropic.com>
…rt gate

Ran the R0 live read-only probe against the focused TerraViz - Design
System file (direct streamable-HTTP read, bypassing the gateway's
always_ask). The exported graph matched PenpotGraph exactly: all 8
seeded sets, all 4 themes WITH activeSets (the §6 unverified read path,
now confirmed), hostile set absent from base sets as designed.

- scripts/check-design-roundtrip.ts: add `--graph <file>` so the same
  reconcile + diff consumes a real export (channel A read-penpot output
  or channel B native export), unwrapping the MCP { result, log } shape.
  Running the live capture through it produced an empty diff for all 5
  files with the 4 hostile values restored — R0's empirical acceptance
  gate, met against the real file.

Two real-world findings, both handled correctly by the reconcile:
- The live Global set is missing the 4 facet-color.* tokens the repo
  has (the design file predates them). Reconcile kept repo values and
  warned `missing-in-export` rather than dropping — the §2 "exists only
  in repo → keep repo" rule, validated live. Forward follow-up: re-seed
  facet-color via sync-penpot-global.
- Penpot returns weight tokens as type `fontWeights`; repo uses W3C
  `fontWeight`. Reconcile keys round-trippability off the repo $type and
  matches by name, so the plural/singular gap is a non-issue.

Plan doc §1/§4/§7 updated to mark R0 done (live-validated).

Signed-off-by: Claude <noreply@anthropic.com>
claude added 2 commits June 16, 2026 19:13
Add the Tier-2 component token sets (info-panel, help) so the reverse
design-sync pipeline covers them end-to-end. The seeders, the Channel-A
reader, the reconcile core, and the fidelity gate all auto-discover
tokens/components/*.json, so the two new files flow through unchanged:

  - sync-penpot-components seeds Components/Info-Panel + Components/Help
  - sync-penpot-modes folds their tablet / phone-portrait overrides into
    the existing Modes/Tablet + Modes/Phone-Portrait sets and activates
    both new base sets under every theme
  - check:design-roundtrip now passes 128 tokens across 7 files with 6
    hostile values (the two calc(100vw - 1.5rem) tablet overrides added)
    asserted restored byte-identical

Values are derived from src/styles/{info-panel,help}.css and match the
DESIGN_SYSTEM_PLAN Tier-2 table. CSS consumption (wiring var(--component-
info-panel-*) / var(--component-help-*) into the stylesheets) is the
forward Tier-2 migration and remains a follow-up.

Tests: assert the new sets + their base values and that the calc tablet
widths are skipped (repo stays authoritative); fix the modes Default-theme
set list to include the two new base sets.

Signed-off-by: Claude <noreply@anthropic.com>
Update DESIGN_SYNC_PLAN §4 implementation status with an R2 block
(offline-validated: 128 tokens / 7 files / 6 hostile restored) and the
two remaining follow-ups (live round-trip confirmation, forward CSS
wiring). Update DESIGN_SYSTEM_PLAN Tier-2 note: the token files now
exist; CSS consumption is the staged forward step.

Signed-off-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants