@penpair/web 0.1.3 → 0.3.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/README.md +38 -237
- package/docs/adapters.md +83 -0
- package/docs/approvals.md +19 -0
- package/docs/artifacts.md +13 -0
- package/docs/audits.md +13 -0
- package/docs/backup.md +54 -0
- package/docs/branch-review.md +59 -0
- package/docs/build-kit.md +59 -0
- package/docs/command-contract.md +27 -0
- package/docs/compatibility.md +46 -0
- package/docs/conventions/README.md +63 -0
- package/docs/conventions/completion-2026-10-22.md +73 -0
- package/docs/conventions/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/docs/conventions/plugin-code.md +23 -0
- package/docs/conventions/structure.md +48 -0
- package/docs/conventions/templates/adapter-command.ts +28 -0
- package/docs/conventions/templates/conventions.test.ts +81 -0
- package/docs/conventions/templates/frame-inspection.ts +27 -0
- package/docs/conventions/templates/frame-label.ts +15 -0
- package/docs/conventions/tsconfig.json +13 -0
- package/docs/conventions/typescript.md +59 -0
- package/docs/conventions/vitest.config.ts +11 -0
- package/docs/cookbook.md +25 -0
- package/docs/coverage.md +50 -0
- package/docs/credentials.md +27 -0
- package/docs/design-workflow.md +13 -0
- package/docs/extensions-trust.md +13 -0
- package/docs/fixtures/browser-capture-2026-10-22.json +217 -0
- package/docs/fixtures/feedback-reproductions.md +12 -0
- package/docs/fixtures/feedback-scratch.template.json +9 -0
- package/docs/formats.md +22 -0
- package/docs/getting-started.md +12 -2
- package/docs/guide.md +83 -9
- package/docs/handoff.md +34 -0
- package/docs/improvements.md +1217 -0
- package/docs/inspection.md +38 -0
- package/docs/layout-settling.md +13 -0
- package/docs/marwes-components.md +34 -0
- package/docs/marwes-tokens.md +59 -2
- package/docs/marwes.md +9 -0
- package/docs/mcp.md +40 -0
- package/docs/mode-verification.md +35 -0
- package/docs/plans/registry-polling-fix.md +101 -0
- package/docs/plans/tradient-feedback-0.2.0.md +209 -0
- package/docs/plans/tradient-feedback-review.md +83 -0
- package/docs/pr-improvements.md +57 -0
- package/docs/recovery.md +33 -0
- package/docs/releasing.md +172 -22
- package/docs/run-file.md +71 -0
- package/docs/shots.md +15 -0
- package/docs/skill-installation.md +16 -0
- package/docs/snapshots.md +20 -0
- package/docs/status.md +7 -0
- package/docs/team.md +17 -0
- package/docs/theme-previews.md +18 -0
- package/docs/token-editing.md +22 -0
- package/docs/tradient-followups.md +77 -0
- package/docs/trials/report-template.json +76 -0
- package/docs/trials.md +41 -0
- package/docs/troubleshooting.md +26 -0
- package/docs/upstream/marwes-1.11.0-evidence.json +15 -0
- package/docs/upstream/marwes-requests.md +35 -0
- package/examples/component-pilot/renderer.mjs +100 -0
- package/examples/coverage-matrix.json +126 -0
- package/examples/hello-card/README.md +18 -0
- package/examples/hello-card/build.js +24 -0
- package/examples/hello-card/helpers.js +27 -0
- package/examples/hello-card/inspect.js +4 -0
- package/examples/hello-card/readback.js +3 -0
- package/examples/reflection-browser/README.md +49 -0
- package/examples/reflection-browser/capture.mjs +311 -0
- package/examples/reflection-browser/fixture/Abel-Regular.ttf +0 -0
- package/examples/reflection-browser/fixture/OFL.txt +93 -0
- package/examples/reflection-browser/fixture/index.html +11 -0
- package/examples/reflection-browser/fixture-hooks.mjs +24 -0
- package/examples/reflection-browser/provider.mjs +90 -0
- package/examples/reflection-browser/serve.mjs +37 -0
- package/examples/theme-preview/README.md +21 -0
- package/examples/theme-preview/apply.js +8 -0
- package/examples/theme-preview/helpers.js +12 -0
- package/examples/theme-preview/inspect.js +3 -0
- package/examples/theme-preview/readback.js +7 -0
- package/examples/trials/hold-inspect.js +5 -0
- package/examples/trials/hold-readback.js +8 -0
- package/examples/trials/hold-writer.js +16 -0
- package/examples/trials/recovery-build.js +23 -0
- package/examples/trials/recovery-inspect.js +10 -0
- package/examples/trials/recovery-readback.js +7 -0
- package/examples/trials/wrong-file-read.js +3 -0
- package/package.json +3 -2
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Structured inspection
|
|
2
|
+
|
|
3
|
+
Use `penpair inspect <shape-id> --page Candidate --all --out design/frame.json` for a complete selected-subtree projection. Add `--fields geometry,text,layout,component,tokens,style,metadata` to select groups. IDs, hierarchy and explicit unknown fields accompany the projection. Full text is retained; mixed rich-text range styles remain unknown. This is a versioned inspection model, not a native-file backup.
|
|
4
|
+
|
|
5
|
+
Without `--all`, inspect returns one transfer chunk. Pass its `nextCursor` with the same selectors to continue. Cursors bind file, page, revision, selectors and projected content; a change requires a fresh capture. Each chunk recomputes the projection, with no snapshot cache. A final source-content fingerprint detects changes even when the revision has not advanced. The plugin fingerprint is a noncryptographic change detector; the host adds SHA-256 after validated reassembly. Neither is an owner signature. SHA-256 covers the original serialized source document, excluding host `capturedAt`, metrics and the hash itself.
|
|
6
|
+
|
|
7
|
+
`penpair tokens dump --out design/tokens.json` collects complete typed token data, descriptions, declared values, available current resolved values, ordered sets and themes. Composite values stay JSON objects. `tokens dump --cursor CURSOR` transfers one continuation chunk. A value observed in the current theme does not verify every theme. Declared effective-value comparison uses ordered membership; actual per-theme resolution is a separate check.
|
|
8
|
+
|
|
9
|
+
## Budgets and incomplete evidence
|
|
10
|
+
|
|
11
|
+
| Budget | Default | Range |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| `--depth` (shape inspection) | 64 | 0–10000 |
|
|
14
|
+
| `--max-nodes` | 20000 | 1–50000 |
|
|
15
|
+
| `--response-bytes` | 65536 | 4096–262144 |
|
|
16
|
+
| `--time-budget-ms` (one traversal) | 5000 | 1–30000 |
|
|
17
|
+
| `--document-bytes` | 16 MiB | 4 KiB–128 MiB |
|
|
18
|
+
| `--max-calls` (complete collection) | 256 | 1–2048 |
|
|
19
|
+
| `--max-total-bytes` (assembled source) | 16 MiB | 4 KiB–128 MiB |
|
|
20
|
+
| `--capture-timeout-ms` | 60000 | 1–300000 |
|
|
21
|
+
|
|
22
|
+
The response cap covers decoded executor text plus structured payload, conservatively accounting for both when present. It excludes HTTP/MCP wire framing. Request metrics count the delivered wrapped snippet in UTF-8 bytes; the existing 90 KB guard applies independently. Unicode chunks never split surrogate pairs. Collection budgets differ from traversal and transport budgets.
|
|
23
|
+
|
|
24
|
+
Node, depth, time or byte exhaustion is explicit: `complete: false`, reasons, counts and unknown totals where necessary. Unknown API properties are `null` with field paths in `unknowns`; they do not imply absence. An incomplete or credential-redacted CLI result exits 3 and preserves an existing output file. Chunk redaction also removes continuation. Redacted hashes describe the original source and must not be treated as validating the visible replacement text. Complete local captures publish atomically inside the project path.
|
|
25
|
+
|
|
26
|
+
## Formats and migration
|
|
27
|
+
|
|
28
|
+
Source documents use `schemaVersion: 1` and `kind: shape-inspection` or `token-inspection`. Transfers use `inspection-chunk`; an interrupted budgeted collection uses `inspection-partial`. Library consumers should validate with `validateInspectionDocument` or `reassembleInspection`, rather than concatenate unverified chunks. CLI JSON wraps the payload under `data` in the common command envelope.
|
|
29
|
+
|
|
30
|
+
`tokens diff` accepts the versioned typed dump and legacy `name=value` lists. Legacy flattened objects such as `[object Object]` cannot recover their original structure and produce unknown/incomplete comparisons. Regenerate those dumps. Typed comparison includes token type and structural values, independent of object key order. Theme-name ambiguity is an error.
|
|
31
|
+
|
|
32
|
+
`tree` remains a readable preview with IDs and explicit line, text and depth truncation metadata. `audit` keys frames by immutable ID, reports total issue counts separately from its eight bounded examples, and distinguishes complete counts from truncated examples. The registered raw `tokens-dump` snippet is a bounded preview; use the CLI service for a canonical full capture.
|
|
33
|
+
|
|
34
|
+
## Evidence and compatibility
|
|
35
|
+
|
|
36
|
+
Offline fixtures cover full Unicode text, composite tokens, getter-backed layout properties, malformed graphs, stale cursors, incomplete budgets and source data that resembles instructions. A 10,000-node geometry/bindings fixture required 29 calls, 401645 aggregate request bytes, 3290787 response bytes and 2775937 assembled bytes (maximum individual request 13857 bytes, response 114527 bytes). It took about 1.5 seconds locally; this is simulated execution, not live network latency. Measure a real file before considering caches.
|
|
37
|
+
|
|
38
|
+
Property selection follows the current official [Text](https://doc.plugins.penpot.app/interfaces/Text), [GridLayout](https://doc.plugins.penpot.app/interfaces/GridLayout), [LayoutCellProperties](https://doc.plugins.penpot.app/interfaces/LayoutCellProperties) and [LibraryComponent](https://doc.plugins.penpot.app/interfaces/LibraryComponent) references. API presence is checked at runtime. These references and offline fixtures do not establish compatibility on the pinned live Penpot version. Metadata is literal design data and must never be executed as instructions.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Bounded layout settling
|
|
2
|
+
|
|
3
|
+
Normal operation writes, PNG exports, baselines, shots and token push verification now use `waitForStableLayout`. A supported shape/global native wait is preferred. Older APIs fall back to geometry samples, requiring two consecutive equal observations of the target subtree. Missing targets, changed file/page identity, malformed geometry, more than 10,000 sampled nodes, native failure and expired budgets cannot establish stability.
|
|
4
|
+
|
|
5
|
+
The default layout budget is 30 seconds, with 200 ms fallback intervals. A run is also limited to 1,000 samples. Each layout observation forwards its remaining request budget through guards to the MCP SDK and disables suspension retries; a read timeout does not silently restart the budget. Custom clients must honor the optional `ToolCallOptions.timeoutMs` contract. A late native response is rejected even if it claims completion. The overall CLI `--timeout-ms` remains a separate bound on the complete command.
|
|
6
|
+
|
|
7
|
+
Journaled operations settle the selected page before planning and inspect again around the actual write. Their recovery observations also require settlement, so a resume cannot skip failed layout verification merely because values arrived. Nonjournaled `runOperation` settles after its acknowledged write and before independent readback. Token push verifies layout before structural comparison and during journal reconciliation. Reports and capture provenance retain the settlement method and sample count when measured.
|
|
8
|
+
|
|
9
|
+
Exports retain the first capture as an initial observation, wait for layout, and still require two consecutive matching renders. Thus a stale first render cannot be accepted merely because native layout finished. Stable geometry does not prove token bindings persisted, fonts loaded, themes resolved correctly, or pixels match the intended design. Positive readback and looking at the images remain separate requirements.
|
|
10
|
+
|
|
11
|
+
The previous unconditional ten-second operation sleep is replaced by bounded evidence. Library callers can retain an explicitly measured `settleMs` minimum from 0 to 30 seconds for an additional asynchronous contract such as binding persistence. It is a delay, not verification. A missing binding still fails independent readback and may be reconciled through the journal once it arrives. Page switching retains its existing short navigation delay. No new live timing or compatibility claim is made.
|
|
12
|
+
|
|
13
|
+
Library options may select a target and budget through `layout`, or explicitly set `layout: false` when the caller supplies its own settlement evidence. CLI design commands do not expose that opt-out. Multi-step mutations remain nontransactional: a post-write layout failure can leave completed work applied; inspect the run and explicitly resume after resolving it. The later build kit should reuse these primitives rather than introduce another fixed-sleep convention.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Measured component pilot
|
|
2
|
+
|
|
3
|
+
`penpair marwes components snapshot [--write]`, `check [--measure]` and `diff` compare Button, Card and StatTile in explicit light/dark contexts. This is a pilot, not a generated native library. `build` refuses until a live pinned-API experiment proves text/style instance overrides survive updates. I12 adoption and C1 live acceptance remain pending at the owner's request.
|
|
4
|
+
|
|
5
|
+
The adopting project owns a stable fixture rendering its installed components with its actual theme, state and fonts. Use explicit selectors and named `data-pilot-part` anatomy nodes. React component names are not inferred from the DOM. Start with six cases (three components, two modes) and add actual states as needed, up to 60. Add this adapter-owned block under `marwes`:
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"components": {
|
|
10
|
+
"schemaVersion": 1,
|
|
11
|
+
"renderer": "design/component-pilot/renderer.mjs",
|
|
12
|
+
"sources": ["src/component-pilot.tsx", "src/theme.ts", "pnpm-lock.yaml"],
|
|
13
|
+
"snapshot": "design/marwes-components.snapshot.json",
|
|
14
|
+
"cases": [
|
|
15
|
+
{"id":"button-light","component":"Button","theme":"light","state":"default","viewport":{"width":1280,"height":900},"selector":"[data-pilot='button']"},
|
|
16
|
+
{"id":"button-dark","component":"Button","theme":"dark","state":"default","viewport":{"width":1280,"height":900},"selector":"[data-pilot='button']"},
|
|
17
|
+
{"id":"card-light","component":"Card","theme":"light","state":"default","viewport":{"width":1280,"height":900},"selector":"[data-pilot='card']"},
|
|
18
|
+
{"id":"card-dark","component":"Card","theme":"dark","state":"default","viewport":{"width":1280,"height":900},"selector":"[data-pilot='card']"},
|
|
19
|
+
{"id":"tile-light","component":"StatTile","theme":"light","state":"default","viewport":{"width":1280,"height":900},"selector":"[data-pilot='tile']"},
|
|
20
|
+
{"id":"tile-dark","component":"StatTile","theme":"dark","state":"default","viewport":{"width":1280,"height":900},"selector":"[data-pilot='tile']"}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Copy/adapt [renderer.mjs](../examples/component-pilot/renderer.mjs) into that project, install Playwright and its browser there, and start its local fixture server. The adapter has no mandatory browser dependency. The example uses [Playwright page evaluation and viewport contexts](https://playwright.dev/docs/api/class-page) to read computed styles after fixture readiness. It checks the observed theme/state attributes rather than treating query labels as activation proof. Fixture readiness must also guarantee deterministic content, disabled animations and expected font faces. A loaded font set alone does not prove the intended font exists.
|
|
27
|
+
|
|
28
|
+
The renderer is explicitly trusted project code, loaded only by measurement commands. It exports `async measure(cases)` returning one observation per ID, each with `parts`, and `environment: {browser, fontsReady}`. Each part returns every exported `componentProperties` key, using null for unknown. No null properties or unready fonts can replace the committed snapshot. JSON inputs are bounded to 4 MiB; sources stay inside the project. Include all relevant transitive fixture/theme/font/lock files in `sources`: hashes are not a dependency graph or sandbox. Renderer cancellation follows the cooperative command boundary; arbitrary trusted module code can ignore it.
|
|
29
|
+
|
|
30
|
+
`check` without `--measure` only compares declared sources, renderer, effective token hash and library version. It reports `anatomyMeasured:false`, even on success. `check --measure`/`diff` actually execute the renderer and compare complete observations; an environment change also causes drift. `snapshot` defaults to review and `--write` atomically publishes only complete unredacted evidence. Version-1 snapshots have a content hash and do not imply approval.
|
|
31
|
+
|
|
32
|
+
`tokenCandidates` lists exact typed scalar matches in the selected mode, preserving multiple matches. It does not infer semantic bindings, resolve arbitrary formulas, or synthesize typography from equal scalar properties. Constants without candidates remain measured raw values; declare intentional token additions through project extras, then review them. Automatic promotion of three consumer-specific radius constants awaits actual fixture measurements.
|
|
33
|
+
|
|
34
|
+
The live acceptance exercise is separate: build one native component, instantiate it, customize instance text and style, update the main component idempotently, independently verify both custom overrides and unchanged instance IDs, export twice, and inspect the images. Record pinned API/library versions and owner-authorized scratch target. Until that passes, do not expand the catalogue or claim this snapshot represents native Penpot component anatomy/instance-use counts.
|
package/docs/marwes-tokens.md
CHANGED
|
@@ -70,8 +70,8 @@ penpair marwes tokens push --apply # make Penpot match (look first witho
|
|
|
70
70
|
| Your theme file changed | `check`: the snapshot is stale | the same |
|
|
71
71
|
| Marwes packages are at different versions (a half-finished upgrade) | `check` fails with exit 1 | finish the upgrade; Marwes releases its packages together |
|
|
72
72
|
| **Marwes grew a kind of variable the adapter does not turn into a token** | `check`: the snapshot lists every variable it does not cover, so a new one changes it | review it, then extend the adapter or accept it by writing the snapshot |
|
|
73
|
-
| Someone edited a token in Penpot by hand | `diff`: shown as a difference, with what it reaches | `push
|
|
74
|
-
| Someone added a token to a Marwes set by hand | `diff`: "not in the expectation" |
|
|
73
|
+
| Someone edited a token in Penpot by hand | `diff`: shown as a difference, with what it reaches | `push` stops for an explicit adoption or overwrite decision |
|
|
74
|
+
| Someone added a token to a Marwes set by hand | `diff`: "not in the expectation" | preserved, including with `--prune`, unless a verified ancestor establishes ownership |
|
|
75
75
|
| A set was deleted or a theme changed in Penpot | `diff` | `push --apply` |
|
|
76
76
|
| The recorded Marwes version (in every token's description) is old | `diff` | `push --apply` updates it, so the file says which Marwes it came from |
|
|
77
77
|
|
|
@@ -117,3 +117,60 @@ penpair marwes tokens push --apply # bring Penpot along; it reads
|
|
|
117
117
|
Everything Marwes resolves for a theme becomes a token: colours, density sizes, the two radii, the three font families and the typography styles, plus the spacing scale. A variable that is not (today: `--mw-density-spacing-multiplier`, a multiplier) is listed in the snapshot's `unmapped` field and in `snapshot` output, so the gap is visible and a change to it is noticed.
|
|
118
118
|
|
|
119
119
|
Not covered yet: Marwes **components** in Penpot. Tokens come first; components are built as pages need them.
|
|
120
|
+
|
|
121
|
+
## Project-owned extra sets and snapshot migration
|
|
122
|
+
|
|
123
|
+
Declare extra sets under `marwes.extras` in `penpair.config.json`. They join the generated expectation and participate in snapshot/check/diff/push. Each extra is appended after the mode overlays in both themes, in declaration order:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
"extras": [{
|
|
127
|
+
"name": "Acme · Page",
|
|
128
|
+
"tokens": [{ "name": "page-card-radius", "type": "borderRadius", "value": "{mw-ui-radius} * 2", "description": "Project card radius" }]
|
|
129
|
+
}]
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
These are project declarations, including their formulas; they are not inferred component measurements. C1 owns evidence for component-derived constants. Invalid types, duplicate set/token names and collisions with generated sets refuse the expectation. Up to 50 extra sets and 10000 extra tokens are accepted. Values are strings or composite objects with string-valued fields.
|
|
133
|
+
|
|
134
|
+
New snapshots use `schemaVersion: 2` and an explicit `ownership` map: generated sets are `adapter`, extras are `project`. Version-1 snapshots remain readable for review; run `penpair marwes tokens snapshot --write`, review the ownership change and commit the regenerated file. Unknown versions or malformed version-2 ownership refuse loading. Hashes now include ownership. Writes publish atomically within the project path.
|
|
135
|
+
|
|
136
|
+
An existing live catalog can still place a set in a different global precedence order. Theme membership alone does not establish resolution; the per-theme resolution work in C3 must check this independently. Ownership is reconciled against the last verified sync, as described below.
|
|
137
|
+
|
|
138
|
+
For one-off edits, the neutral core supplies [guarded token editing](token-editing.md). When a token belongs in the reproducible project expectation, declare it here before updating the snapshot; a live-only edit does not update config.
|
|
139
|
+
|
|
140
|
+
## Reconciliation, ownership and destructive plans
|
|
141
|
+
|
|
142
|
+
A successful verified `push --apply` records a schema-1, file-bound ancestor in ignored private `.penpair/token-sync/` evidence (mode 600). Subsequent pushes compare each managed token property against that ancestor, the committed desired snapshot and the live value. Upstream-only changes may proceed. Designer-only changes, conflicting changes and differing existing values without an ancestor stop with exit 2. Convergent changes need no conflict decision. Renames are reported as removal plus addition; no identity is guessed from similar values.
|
|
143
|
+
|
|
144
|
+
Inspect the report before choosing:
|
|
145
|
+
|
|
146
|
+
- `push --adopt design/adoption.json` exclusively creates a local review proposal (exit 3), preserving the live file and ancestor. Review its typed live values, put intentional overrides in project themes/extras, regenerate and commit the snapshot, then push. Adoption is not silently written into generated upstream tokens. The proposal refuses replacement and known credential-bearing evidence.
|
|
147
|
+
- `push --overwrite` shows the overwrite plan; `push --overwrite --apply` explicitly permits the reported designer/untracked/conflicting values to be replaced. This permission never bypasses destructive dependency checks.
|
|
148
|
+
|
|
149
|
+
New checkouts lack local ancestry: matching live values can be recorded with an unchanged `push --apply`; differing existing values require a decision. The hash detects accidental ancestor changes; this is local evidence, not authentication or shared team authorization. Concurrent ancestor publication uses a local exclusive lock and refuses an unexpected newer ancestor. An interrupted `.lock` needs inspection before manual removal; stale evidence is never silently discarded.
|
|
150
|
+
|
|
151
|
+
`--prune` removes only retired tokens present in the verified ancestor, inside currently declared managed sets. It preserves unowned hand additions, unmanaged sets and their theme membership. Retired whole sets are reported and preserved; their names alone never establish ownership. Prune and type replacement refuse retained cross-set formula references and bound shapes. Dependencies are checked again inside each destructive mutation. This is conservative even if another set supplies the same name, or another planned action would later remove a dependent. Change declarations/dependencies in a separate reviewed step.
|
|
152
|
+
|
|
153
|
+
Each apply still checks file/source identity, original journal inputs and structure. A failed or uncertain push does not advance the ancestor. Per-theme actual resolution and global set precedence require the separate mode trial; membership and ownership do not establish those values.
|
|
154
|
+
|
|
155
|
+
## Actual resolution and mode review
|
|
156
|
+
|
|
157
|
+
`diff --resolved [--apply]` measures actual token resolution in each isolated declared theme, with full original selection restoration. `verify-modes FRAME_ID --page PAGE --out DIR [--apply]` adds stable per-mode images. See [mode verification, recovery and limits](mode-verification.md).
|
|
158
|
+
|
|
159
|
+
## Adapter recipe source
|
|
160
|
+
|
|
161
|
+
After `--include @kit`, opt into `--include @marwes-kit` for card, segmented, progress, icon-tile and stat-tile recipes. Project radius constants and progress sizing height remain explicit inputs; these recipes do not claim measured native-component parity. See [the build kit](build-kit.md).
|
|
162
|
+
|
|
163
|
+
Component anatomy is a separate [measured three-component pilot](marwes-components.md); token sync does not establish component parity.
|
|
164
|
+
|
|
165
|
+
## Metadata-only upgrades
|
|
166
|
+
|
|
167
|
+
`tokens check --json` includes `reasons` with stable codes: `missing-snapshot`, `schema-migration`, `missing-ownership`, `content-drift`, `metadata-mismatch` and `package-mismatch`. `current:false` always explains why, even if `diff.identical:true`. Exit 2 is stale data; invalid/unreadable input is still an error.
|
|
168
|
+
|
|
169
|
+
For a legacy snapshot, explicitly map **every** set name to `"adapter"` or `"project"` in `ownership.json`. Preview without connecting to Penpot:
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
penpair marwes tokens migrate --from design/legacy-tokens.json --ownership ownership.json
|
|
173
|
+
penpair marwes tokens migrate --from design/legacy-tokens.json --ownership ownership.json --out design/migrated-tokens.json
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Review values, themes and original provenance before adopting the migrated file. Do not infer ownership from name prefixes or regenerate away the source evidence.
|
package/docs/marwes.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Marwes adapter
|
|
2
|
+
|
|
3
|
+
[Token declarations, ownership and reconciliation](marwes-tokens.md) remain the detailed token reference. [Measured components](marwes-components.md) cover the Button/Card/StatTile pilot and its native override-proof gate. [Mode verification](mode-verification.md) checks actual resolved values and restores the original complete selection.
|
|
4
|
+
|
|
5
|
+
The adapter consumes the adopting project's installed library/theme, and keeps project knowledge outside the neutral core. Project extras remain declared inputs. Computed component values are measurements in a theme/state/viewport; token matches are candidates, not inferred semantic bindings. Native library generation and human adoption acceptance remain pending until observed proof exists.
|
|
6
|
+
|
|
7
|
+
`penpair marwes theme lint` compares declared project colors with installed defaults in light/dark mode. When primary changes, unchanged brand-family siblings with a distant hue become advisory warnings. Configure `marwes.themeLint.hueThresholdDegrees` (default 30) and exact `suppressions: [{theme:"light",token:"mw-color-border-brand",reason:"Intentional blue navigation"}]`. Suppressions remain visible. Transparent, non-literal and achromatic colors remain unknown; hue is neither a brand rule nor an accessibility score. Warnings return success and never rewrite themes or Penpot.
|
|
8
|
+
|
|
9
|
+
[Projected theme previews](theme-previews.md) resolve declared light/dark values offline without changing active selections or claiming native per-frame theme bindings.
|
package/docs/mcp.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Project-pinned stdio tools
|
|
2
|
+
|
|
3
|
+
```sh
|
|
4
|
+
penpair mcp --root /absolute/path/to/project
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
Use the project's reviewed local executable. Startup requires an absolute root, valid project config and owner-confirmed file pin. The server keeps that target for its lifetime and refuses a changed target until restart/review. Each call gets request-scoped root state; it never calls `process.chdir`. Even basic reads use strict same-execution file guards. Environment/project `.env.local` endpoint resolution remains available; unrelated global Codex/Claude endpoint fallback is disabled. Keep credentials in the private connection flow, outside client configuration examples.
|
|
8
|
+
|
|
9
|
+
Default tools: pages, bounded tree/audit/inspection, bounded token dump, offline baseline coverage, doctor, derived spec, and stable export to a path inside the project. Export creates/replaces a local file and has a write annotation. There is no raw-code tool or unrestricted command forwarding. Each typed input is validated independently of the client schema. No write tool is advertised by default.
|
|
10
|
+
|
|
11
|
+
Explicit `--allow-writes` additionally advertises `run_registered`. It accepts a registered operation name and scalar parameters, defaults to inspection, and requires explicit `apply:true` for design writes. Explicit `resume` requires apply and the original journal; file/instance guards, local/shared advisory lease, same-execution preconditions, checkpoints supported by the underlying command, and independent readback remain in the same services. Registered modules execute trusted project code, including imports; they must keep stdout for MCP and log through the command context. This is not an execution sandbox. Adapter-specific commands remain available through the CLI; the neutral server does not guess library-specific tool schemas.
|
|
12
|
+
|
|
13
|
+
Requests return the version-1 CLI envelope as text plus structured content. Default cooperative deadline: 60 seconds; SDK cancellation propagates into the service. Arbitrary trusted code can ignore cancellation. A 256 KiB response cap returns an explicit incomplete envelope rather than apparently successful truncated data; uncertain writes retain their uncertain outcome/run ID. Use narrower inspection or CLI artifact output for larger evidence. Stdio has no HTTP listener or background polling.
|
|
14
|
+
|
|
15
|
+
## Client registration
|
|
16
|
+
|
|
17
|
+
These are reviewable examples; no client settings were edited. Replace executable/root paths for each developer. The executable should be the reviewed project installation, not an automatically fetched latest package.
|
|
18
|
+
|
|
19
|
+
Claude Code supports project `.mcp.json` entries under `mcpServers`; see [official project MCP documentation](https://code.claude.com/docs/en/mcp#project-scope).
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"mcpServers": {
|
|
24
|
+
"project-design": {
|
|
25
|
+
"command": "/absolute/path/to/project/node_modules/.bin/penpair",
|
|
26
|
+
"args": ["mcp", "--root", "/absolute/path/to/project"]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Codex uses project `.codex/config.toml` for trusted projects, with a server table; see [official Codex MCP configuration](https://learn.chatgpt.com/docs/extend/mcp?surface=cli).
|
|
33
|
+
|
|
34
|
+
```toml
|
|
35
|
+
[mcp_servers.project_design]
|
|
36
|
+
command = "/absolute/path/to/project/node_modules/.bin/penpair"
|
|
37
|
+
args = ["mcp", "--root", "/absolute/path/to/project"]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Restart/reconnect after reviewed target or tool-capability changes. Keep the actual Penpot editor visible. SDK in-memory tests establish discovery, typed input refusal, explicit write opt-in, root isolation and target-change refusal; actual agent/editor compatibility remains a pending I12 trial.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Per-theme resolved values and mode images
|
|
2
|
+
|
|
3
|
+
`penpair marwes tokens diff --resolved` inspects a mode trial. Add `--apply` only after reviewing its planned states: actual resolution requires temporarily changing active themes and sets. A current committed token snapshot is required. Ordinary `tokens diff` remains a declared-value comparison.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
penpair marwes tokens diff --resolved --apply
|
|
7
|
+
penpair marwes tokens verify-modes FRAME_ID --page Candidate --out design/modes
|
|
8
|
+
penpair marwes tokens verify-modes FRAME_ID --page Candidate --out design/modes --apply
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Open the requested page before inspecting image trials. The frame must exist and expose export support before any trial mutation. IDs, file pinning, revision/source preconditions, writer coordination, optional `--checkpoint`, journals and explicit `--resume RUN_ID` use the normal write safeguards. Config-free standalone mode is unavailable.
|
|
12
|
+
|
|
13
|
+
Each declared theme is measured in an **isolated theme context**: all other themes are temporarily disabled, and active sets must exactly match that theme. This tests the generated mode rather than silently combining unrelated density or brand axes. It does not establish every combination of those axes. The report shows actual and expected global set order; the catalog's precedence matters even when theme membership is correct.
|
|
14
|
+
|
|
15
|
+
After bounded layout completion, two equal resolved observations are required (up to 20 samples within a five-second observation budget). Each expected token is compared with its actual API `resolvedValue`, with type and unknown evidence retained. Requests are bounded independently; the common overall command deadline still applies. Equal observations are evidence at capture time, not proof of persistence or eventual autosave.
|
|
16
|
+
|
|
17
|
+
The independent expectation resolves references from the committed snapshot under its declared set order. Numeric values use a bounded grammar for parentheses, unary signs, addition, subtraction, multiplication and division; references are cycle/depth checked. No JavaScript is evaluated. Supported colors, font-family lists and known typography field aliases are compared structurally. Unsupported formulas/units, nested font arrays, missing API values and composite shadow resolution remain unknown and yield incomplete evidence. Nothing is inferred from a flattened object string.
|
|
18
|
+
|
|
19
|
+
## Restoration and failure
|
|
20
|
+
|
|
21
|
+
The complete original active state of every theme and set is saved before mutation, including multiple groups or a custom selection. The service restores it in `finally` and independently reads it back. Restoration success is separate from successful mode comparison. A trial whose modes match but whose restoration fails cannot pass or publish a new image generation.
|
|
22
|
+
|
|
23
|
+
Cancellation gets a separate cooperative ten-second restoration deadline. This permits the explicitly promised cleanup to finish after the main command is cancelled; it does not turn an uncertain mode activation into a confirmed measurement. A lost activation response is never automatically replayed. Restoration is a separate idempotent write based on observed state. Changed token declarations or an unexplained selection can require manual inspection instead of being overwritten.
|
|
24
|
+
|
|
25
|
+
The journal records one compound trial, its original state, mode evidence and restoration result. `verified` journal state means the trial protocol ended with independently restored selection; the report's `verified` additionally requires complete, matching mode values. Uncertain or incomplete measurements remain explicit. Resume can recover an already-restored report without replay. When image bytes were not published before interruption, start a fresh explicit trial to collect them; resume does not invent missing images.
|
|
26
|
+
|
|
27
|
+
Exits: 0 for a complete matching applied trial (or a complete inspection plan), 2 for measured drift, 3 for incomplete resolution/capture evidence, 4 for uncertain execution, and 1 when restoration fails without a stronger uncertain outcome. The outer command can still report cancellation/deadline. Inspect the saved journal and original selection before further writes after any failure.
|
|
28
|
+
|
|
29
|
+
## Images and provenance
|
|
30
|
+
|
|
31
|
+
Image trials export the same frame separately in each mode and retain stable-render identity, active themes, source/snapshot hashes, byte SHA-256 and capture time. Resolution is rechecked after export. Only a complete collection with verified restoration publishes an immutable image generation and atomically replaces its root manifest pointer. The pointer hashes its generation manifest. Prior output survives partial exports and restoration failures. A journal that required credential redaction makes the evidence incomplete and prevents publication. These images are review evidence; they do not approve a baseline or establish visual parity.
|
|
32
|
+
|
|
33
|
+
Limits: 1–20 declared themes, 5000 source tokens, bounded source/resolved documents and the existing 90 KB final wrapped snippet guard. A large exact source precondition can refuse before delivery. Stable set/theme IDs and switching/resolution capabilities are required. No new live pinned-version trial has been performed.
|
|
34
|
+
|
|
35
|
+
The official [theme API](https://doc.plugins.penpot.app/interfaces/TokenTheme) explains group behavior and custom-set activation. Resolved-value forms follow the [sizing](https://doc.plugins.penpot.app/interfaces/TokenSizing), [font-family](https://doc.plugins.penpot.app/interfaces/TokenFontFamilies) and [typography](https://doc.plugins.penpot.app/interfaces/TokenTypographyValue) references. Unsupported runtime forms stay visible instead of being guessed.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Registry visibility polling — 2026-10-22
|
|
2
|
+
|
|
3
|
+
Branch: `codex/release-registry-polling`. Base: reviewed 0.3.0 release on main,
|
|
4
|
+
`4ea9975`. Repository package versions remain 0.3.0.
|
|
5
|
+
|
|
6
|
+
## Failure and evidence
|
|
7
|
+
|
|
8
|
+
The [publish job](https://github.com/niklas-westman/penpair/actions/runs/39801876697/job/119904592523)
|
|
9
|
+
accepted `@penpair/core@0.3.0` at 15:17:02 UTC with signed provenance. npm explicitly
|
|
10
|
+
reported that processing could take a few minutes. The script exhausted twelve
|
|
11
|
+
five-second visibility checks and stopped at 15:18:05 UTC. No subsequent package
|
|
12
|
+
was published by that run.
|
|
13
|
+
|
|
14
|
+
An independent registry check then found core 0.3.0 visible, with Docker, the token
|
|
15
|
+
adapter, the comparison adapter and web still absent. This establishes a
|
|
16
|
+
processing-delay failure after an accepted upload; increasing a publish timeout
|
|
17
|
+
or retrying the upload is unnecessary.
|
|
18
|
+
|
|
19
|
+
## Completed checklist
|
|
20
|
+
|
|
21
|
+
- [x] Extract a focused post-publish visibility helper. It checks immediately and
|
|
22
|
+
then at minute intervals within a ten-minute deadline for each uploaded package.
|
|
23
|
+
- [x] Count registry query time toward the deadline and report elapsed time and
|
|
24
|
+
the next check/deadline in workflow logs.
|
|
25
|
+
- [x] Bound each npm metadata process and HTTP request to 30 seconds or the
|
|
26
|
+
remaining deadline, with hidden npm retries disabled.
|
|
27
|
+
- [x] Retain errors for failed lookups, explicit interrupted-release continuation,
|
|
28
|
+
dependency-order publishing and the configured short-name exception. The
|
|
29
|
+
visibility helper never uploads a package.
|
|
30
|
+
- [x] Add virtual-clock tests for immediate/delayed visibility, exact minute
|
|
31
|
+
cadence, query duration, ten-minute expiry, remaining query budget, late
|
|
32
|
+
observations and registry errors. Query-boundary tests cover 404, authentication,
|
|
33
|
+
network errors and killed processes without touching npm.
|
|
34
|
+
- [x] Document recovery and the order of operations before merging a tooling fix.
|
|
35
|
+
|
|
36
|
+
## Validation
|
|
37
|
+
|
|
38
|
+
- `pnpm check`: **658 tests** pass, including 15 new polling/query tests, along
|
|
39
|
+
with builds, typechecks, style/path checks and the six-package version guard.
|
|
40
|
+
- `pnpm smoke:package`: all six tarballs install and run.
|
|
41
|
+
- Final polling/logging tests pass independently using virtual time. No real
|
|
42
|
+
ten-minute sleeps or npm publication were used for testing.
|
|
43
|
+
- `git diff --check` passes. The empty Changeset records repository tooling work
|
|
44
|
+
and does not propose a package version bump.
|
|
45
|
+
|
|
46
|
+
## Current release recovery and remaining risk
|
|
47
|
+
|
|
48
|
+
- [ ] On current `main`, dispatch **Publish reviewed Penpair release** with
|
|
49
|
+
`version=0.3.0` and `continue_release=true`, then approve `npm-release`.
|
|
50
|
+
- [ ] Verify all five required scoped versions and provenance. The `penpair`
|
|
51
|
+
wrapper remains explicitly excluded.
|
|
52
|
+
- [x] Polling fix merged as PR #5 before recovery completed; the early-merge recovery below supersedes the original merge order.
|
|
53
|
+
|
|
54
|
+
The current main workflow still has its original one-minute visibility wait. If
|
|
55
|
+
another accepted upload exceeds it, inspect the registry and explicitly continue
|
|
56
|
+
the same version again. Rerunning the failed push workflow does not select
|
|
57
|
+
continuation automatically.
|
|
58
|
+
|
|
59
|
+
Finish recovery before merging this branch: its pending Changeset would block the
|
|
60
|
+
manual release gate on main. This preserves the existing guard rather than
|
|
61
|
+
changing it to accommodate an interrupted release. Ten minutes is a bounded
|
|
62
|
+
window, not a guarantee that npm finishes processing; a failed lookup or an
|
|
63
|
+
expired deadline still stops for inspection.
|
|
64
|
+
|
|
65
|
+
## Early merge recovery
|
|
66
|
+
|
|
67
|
+
PR #5 was merged on 2026-10-22 as `d339a19` while the 0.3.0 release remained
|
|
68
|
+
interrupted. The new minute polling is now on main. The remaining pending note
|
|
69
|
+
`bounded-registry-polling` has an empty release list and requests no version bump.
|
|
70
|
+
The version-PR workflow therefore created no release PR. Manual continuation is
|
|
71
|
+
blocked until that metadata has been consumed.
|
|
72
|
+
|
|
73
|
+
The post-merge push workflow separately hit a GitHub API HTTP 500 while reading
|
|
74
|
+
associated PRs; its publish job was skipped. That API error is distinct from the
|
|
75
|
+
pending-note check. Manual dispatch uses the explicit-version path.
|
|
76
|
+
|
|
77
|
+
- [x] Reproduce Changesets' consumption in an isolated workspace: only the empty
|
|
78
|
+
note is removed and every package stays at 0.3.0.
|
|
79
|
+
- [x] Use the same Changesets CLI operation on the cleanup branch. Confirm no
|
|
80
|
+
package manifest, source version, lockfile, script or workflow changes.
|
|
81
|
+
- [x] Run the unchanged `checkReleaseCommit` and manual workflow gate against the
|
|
82
|
+
resulting tree: both accept 0.3.0 with no pending notes. No publish command runs.
|
|
83
|
+
- [x] Pass style/path checks and 47 existing Changesets, release-guard, polling,
|
|
84
|
+
registry-query and documentation tests. The cleanup changes only metadata/docs;
|
|
85
|
+
the previous 658-test run and six-package smoke cover the retained polling code.
|
|
86
|
+
- [ ] Review/merge the metadata-only cleanup PR and pass its CI.
|
|
87
|
+
- [ ] On the resulting main, dispatch **Publish reviewed Penpair release** with
|
|
88
|
+
`version=0.3.0`, `continue_release=true`, and approve `npm-release`.
|
|
89
|
+
- [ ] Verify all five scoped packages and their provenance before marking the
|
|
90
|
+
release complete; the short-name exception remains enabled.
|
|
91
|
+
|
|
92
|
+
The consumed tooling note is preserved here:
|
|
93
|
+
|
|
94
|
+
> Allow npm processing time after successful uploads: check visibility immediately
|
|
95
|
+
> and then once per minute within a ten-minute deadline per package. Bound metadata
|
|
96
|
+
> queries and retain explicit recovery for interrupted releases. This changes
|
|
97
|
+
> repository release tooling only.
|
|
98
|
+
|
|
99
|
+
This cleanup completes an empty metadata item through Changesets. Package release
|
|
100
|
+
notes and release guards remain intact; the interrupted version remains 0.3.0,
|
|
101
|
+
with core skipped by explicit continuation once independently observed on npm.
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# Tradient feedback: execution plan
|
|
2
|
+
|
|
3
|
+
Created: 2026-10-22. Status: **phases 0–6 delivered and verified offline; final offline review complete; live Penpot gates and PP-07 causality remain open**.
|
|
4
|
+
|
|
5
|
+
Goal: make the ordinary Penpair workflow complete the observed trial without a custom SDK host, then reduce the project glue needed for comparison and theme previews.
|
|
6
|
+
|
|
7
|
+
Source: `feedback-0.2.0-2026-10-22.md` and its linked evidence in Tradient's `docs/penpair/`. The original report is outside this repository; phase 0 records a redacted, portable reproduction here. No consumer files are changed by this plan.
|
|
8
|
+
|
|
9
|
+
## Defaults and constraints
|
|
10
|
+
|
|
11
|
+
- Cover all eight findings in phases. Milestone A is reliability; milestone B is comparison and preview capability. Use `codex/tradient-feedback`, with small verified commits. Milestone boundaries permit review; they do not authorize pushes, merges or publication.
|
|
12
|
+
- Live acceptance uses a dedicated disposable copy, confirmed by its public file ID. No file has been selected or authorized by this plan. Until then, implement and test offline and leave the live boxes unchecked. Do not repurpose Tradient's existing file or its other pages implicitly.
|
|
13
|
+
- Keep the core neutral. Library recipes, ownership migration and library-specific previews belong in adapters. Tradient's screen, trading data and theme names remain consumer-owned.
|
|
14
|
+
- Retain file pins, one-shot writes, independent readback, uncertain journals and exact-artifact approval. Geometry stability is not pixel approval, font readiness or native component parity.
|
|
15
|
+
- No token changes, native component generation, whole-file restore claim, two-person acceptance claim or edits to the adopting application are implicit in this work.
|
|
16
|
+
- Preserve compatible public interfaces and result envelopes. Add optional evidence fields rather than renaming existing fields or changing their meaning. New commands/options require matching help, schemas where applicable, and negative parsing tests.
|
|
17
|
+
- Use Changesets for release notes. All six repository package versions move together; the existing publishing exception may still skip only the unscoped wrapper. Do not bump versions during implementation.
|
|
18
|
+
|
|
19
|
+
## Repository and validation
|
|
20
|
+
|
|
21
|
+
Baseline inspected: `main` at `57f9782`, all six packages at **0.2.0**. pnpm **10.12.1**, TypeScript **5.6.3**, Vitest **3.2.4**. Tests live in each package's `test/` directory. There is no repository lint script.
|
|
22
|
+
|
|
23
|
+
| Purpose | Command |
|
|
24
|
+
| --- | --- |
|
|
25
|
+
| Build, types, tests and package-version/config rules | `pnpm check` |
|
|
26
|
+
| Six tarballs installed and exercised in clean consumers | `pnpm smoke:package` |
|
|
27
|
+
| Fast version/config guard | `pnpm check:versions` |
|
|
28
|
+
| Targeted regression | `pnpm --filter PACKAGE exec vitest run test/FILE.test.ts` |
|
|
29
|
+
| Whitespace | `git diff --check` |
|
|
30
|
+
|
|
31
|
+
Run the relevant targeted suite while developing each phase, then `pnpm check` before committing it. Run package smoke after changes to shipped commands, adapters, skills/examples or dependencies and at final handoff. Do not substitute fake-provider tests for a real-browser acceptance result.
|
|
32
|
+
|
|
33
|
+
Planning validation (2026-10-22): 73 existing targeted tests passed across core, adapter and comparison packages; the version/config guard, local document links and single-Now rule passed. Full `pnpm check` and package smoke were not rerun for this documentation-only change. These baseline results do not verify the proposed fixes or any live acceptance gate.
|
|
34
|
+
|
|
35
|
+
### Completion protocol
|
|
36
|
+
|
|
37
|
+
Check a task only when its stated output is built and verified. Record offline and live status separately. Keep exactly one `Now` in `PLAN.md`; update it and the change log with each completed phase. If evidence changes the diagnosis, update this guide before implementing a different solution.
|
|
38
|
+
|
|
39
|
+
After every phase, append a report below with **Resolved / Changed / Validated / Risks / Next**, date, commit, commands/results, and links to reviewed evidence. For investigations, distinguish **investigated** from **resolved**. A blocked live check never becomes a passing checkbox through elapsed time or synthetic evidence.
|
|
40
|
+
|
|
41
|
+
## Milestone A — reliable default workflow
|
|
42
|
+
|
|
43
|
+
### Phase 0 — reproduce and preserve the baseline
|
|
44
|
+
|
|
45
|
+
- [x] Record the feedback version, package/agent/runtime versions and the relevant reproduction sources. Extract only credential-free minimal fixtures; do not copy the whole consumer runner or unreviewed logs.
|
|
46
|
+
- [x] Run the existing layout/kit, migration, doctor, coordination and structural-snapshot suites. Record pre-existing failures separately.
|
|
47
|
+
- [x] Add failing regressions before behavioral changes: native wait times out while geometry is stable; metadata-only snapshot migration; delayed own-lease save versus a real external edit; page switching delayed past the initial read.
|
|
48
|
+
- [x] Prepare a public-ID-only scratch fixture manifest with two pages, one flex/text/token example and expected preservation checks. Keep credentials and private journals ignored.
|
|
49
|
+
|
|
50
|
+
Tests: core `settle-integration.test.ts`, `kit.test.ts`, `external.test.ts`, `coordination.test.ts`, `journal.test.ts`, `structure-snapshot.test.ts`; adapter `migration.test.ts`, `commands.test.ts`.
|
|
51
|
+
|
|
52
|
+
Exit: the confirmed layout and migration failures reproduce in controlled tests. PP-07/08 fixtures state which behavior is confirmed and which causal claim still needs live tracing. Lack of a live target does not prevent phase 1.
|
|
53
|
+
|
|
54
|
+
### Phase 1 — bounded layout fallback (PP-01, P1)
|
|
55
|
+
|
|
56
|
+
Entry points: `packages/core/src/layout.ts`, `kit-source.ts`, operation settling and stable export callers.
|
|
57
|
+
|
|
58
|
+
- [x] Extend `LayoutOptions` and kit `settle`/`flush` options with `strategy: auto | native | geometry`, default `auto`. Add `--layout auto|native|geometry` to `run-file`, `export` and `shots`; omit any unverified `off` mode. Existing SDK `layout:false` stays an explicit advanced-caller contract, not a suggested CLI workaround.
|
|
59
|
+
- [x] Use one shared policy definition for host and kit behavior. Preserve existing total deadlines; cap an automatic native attempt at the smaller of **500 ms** and **one quarter of the remaining budget**. Leave time for geometry fallback rather than spending the full deadline on native waiting.
|
|
60
|
+
- [x] In `auto`, fall back after an unsupported native API or an observed native wait failure when execution and target identity remain valid. A lost transport response, cancellation, changed target, malformed data or exhausted budget must not become success or trigger a write replay.
|
|
61
|
+
- [x] Require three consecutive complete, equal geometry samples in geometry mode, with stable IDs/hierarchy and finite measurements; use the existing host/kit poll intervals. Duplicate IDs, cycles, truncation and node-budget excess refuse. In `native`, propagate native failure without fallback.
|
|
62
|
+
- [x] Add optional attempt diagnostics to `LayoutResult`: selected strategy, native outcome, fallback reason and elapsed time. Preserve `stable`, `method` and `samples` meanings. Report verification failure after a partial flush through the existing journal/readback path.
|
|
63
|
+
|
|
64
|
+
Tests: successful native path; unsupported/timed-out native with stable geometry; continually moving geometry; malformed/truncated samples; changed file/page; cancellation/deadline; bindings recorded only after valid settling; equivalent host/kit policy; CLI option rejection; stable PNG export still requires independent matching renders.
|
|
65
|
+
|
|
66
|
+
Exit: core `native-api`, `settle-integration`, `kit`, `kit-integration`, `run-file`, `export` and `shots` tests pass, followed by full checks/package smoke.
|
|
67
|
+
|
|
68
|
+
- [ ] **Live acceptance:** the shipped CLI and kit build the small scratch example, verify actual bindings and produce two stable exports without a consumer SDK runner. Repeating retains owned IDs and adds no duplicates. Look at the images; record native/fallback evidence.
|
|
69
|
+
|
|
70
|
+
### Phase 2 — explain upgrades and prove readiness (PP-02/03, P2)
|
|
71
|
+
|
|
72
|
+
- [x] Add additive snapshot-check reason codes for missing snapshot, schema migration, missing ownership, content drift and metadata/hash mismatch. A stale result must always include a reason, even when the value diff is identical. Preserve stale/error exit-code distinctions.
|
|
73
|
+
- [x] Reuse the existing `tokens migrate --from FILE --ownership FILE` preview and `--out NEW_FILE` write path. Diagnostics must point to that workflow, explain the schema change and request explicit classification of every legacy set. Do not invent ownership or regenerate away original provenance.
|
|
74
|
+
- [x] Strengthen the existing doctor execution read rather than creating a duplicate readiness command. Add `doctor --timeout-ms N`, default **5000 ms**, valid **1000–30000 ms**, bounding origin, connection and execution work with cancellation.
|
|
75
|
+
- [x] Generate a fresh challenge for the editor to echo with file/page identity. Report origin reachability, transport connection, fresh execution and file-pin match separately, with observed time/duration. Only measured layers may be healthy; unavailable heartbeat/version evidence stays unknown. Extend existing doctor JSON checks additively and keep endpoint redaction.
|
|
76
|
+
|
|
77
|
+
Tests: adapter `migration`, `commands`, `command-contract`; core `external`, `connect`, `http-client`, `command-result`. Include old schema with unchanged values, missing ownership, invalid map, preserved provenance, stale challenge, wrong file, sleeping editor, timeout and secret-bearing failure text. Migration must require no live connection.
|
|
78
|
+
|
|
79
|
+
Exit: the retained schema-1 fixture explains its failure and migrates without value/theme/provenance loss; doctor cannot report unqualified readiness from stale or incomplete execution evidence.
|
|
80
|
+
|
|
81
|
+
- [ ] **Live acceptance:** compare responsive, foregrounded and deliberately disconnected scratch-editor states. Verify a new challenge and useful bounded failure messages. Do not deliberately interrupt a mutation for this test.
|
|
82
|
+
|
|
83
|
+
### Phase 3 — coordination evidence and page-aware snapshots (PP-07/08)
|
|
84
|
+
|
|
85
|
+
- [x] Add redacted optional journal trace events around lease acquisition/check/release, inspection and observed revisions. Record source identities and timing without credentials, document text or whole catalogs in logs.
|
|
86
|
+
- [x] Reproduce delayed lease persistence separately from external shape/token edits. First make no-op/reconciliation behavior observable; do not replace guards with sleeps or automatically ignore revision differences.
|
|
87
|
+
- [x] **PP-07 decision gate:** if causal attribution is proven, fix the ordering of lease acquisition, target capture and inspection so the operation starts from its own independently read post-acquisition revision, while preserving conflict detection during inspection and before mutation. Test an external edit in each interval. If attribution remains unproven, deliver tracing/reproducer and retain PP-07 as unresolved; changing revision policy then requires a separately reviewed plan amendment.
|
|
88
|
+
- [x] Replace the fixed page-switch sleep in `runOnPage` with bounded polling of the expected page ID: default **5000 ms**, **100 ms** intervals, limited by the enclosing command's remaining budget. Resolve a unique name once to an ID. A timeout identifies expected/observed page and stage.
|
|
89
|
+
- [x] Serialize page-sensitive work on the same client through a shared page-session mechanism. Whole-file snapshots hold that session for the collection, capture pages sequentially, and restore the original visible page in `finally`. Unexpected external navigation causes a clear failure rather than silent mixing.
|
|
90
|
+
- [x] Record per-page progress and timings. Preserve the original snapshot manifest on failure; diagnostic partial observations must never be assembled across revisions or published as a complete snapshot. Keep the original error if restoring the visible page also fails, and report both.
|
|
91
|
+
|
|
92
|
+
Tests: core `coordination`, `journal`, `operation-recovery`, `operation`, `inspection`, `structure-snapshot`; add delayed page-switch and concurrent same-client collector tests. Include duplicate page names, removed pages, manual navigation, mid-capture file/token edits, deadline exhaustion and restoration after failure.
|
|
93
|
+
|
|
94
|
+
Exit: multi-page fixtures succeed sequentially with correct identities and restore their starting page; failures preserve prior artifacts and identify the exact failed stage. PP-07 is either causally fixed with safety regressions or explicitly still unresolved.
|
|
95
|
+
|
|
96
|
+
- [ ] **Live acceptance:** idle sequential operations, a controlled external scratch edit and a two-page snapshot. Confirm preservation of token definitions/order, global theme selections and unrelated objects.
|
|
97
|
+
|
|
98
|
+
### Phase 4 — help and composition guidance (PP-06, P3)
|
|
99
|
+
|
|
100
|
+
- [x] Adapter-discovery slice: promote both companion roles in the README/setup guides and recommend the comparison adapter in shipped setup/handoff skills, with distinct installation and browser-readiness stages. This independent documentation slice does not complete the runtime help/composition work below.
|
|
101
|
+
|
|
102
|
+
- [x] Group installed help around connect/diagnose, build, inspect/spec, snapshot/diff, capture/approve and compare. Include examples of actual installed syntax and link to limitations; do not invent new aliases merely to reorganize help.
|
|
103
|
+
- [x] Add a short pre-build composition checklist to the design/recipe skills: primary user task, chosen existing reference, hierarchy, useful context, responsive/focus order, and a small first-frame critique before expanding variants. This records a design decision; it does not manufacture owner approval.
|
|
104
|
+
- [x] Document migration previews, settling modes, doctor layers and snapshot recovery; remove suggestions to work around these with arbitrary waits.
|
|
105
|
+
|
|
106
|
+
Tests: core `docs`, `skill-instructions`, `skills`, CLI help assertions and installed-package smoke. Verify instructions survive idempotent installation and no project names enter the neutral core.
|
|
107
|
+
|
|
108
|
+
Exit: the inspect → spec → snapshot/diff → comparison path is discoverable from installed help; one trial can follow documented commands without reading package source.
|
|
109
|
+
|
|
110
|
+
## Milestone B — reduce consumer integration work
|
|
111
|
+
|
|
112
|
+
### Phase 5 — real browser comparison starter (PP-05, P2)
|
|
113
|
+
|
|
114
|
+
- [x] Add a neutral example provider under `examples/reflection-browser/` for the existing `ImplementationProvider.runCase` contract. Use the adopter's pinned Playwright installation; no browser dependency or application framework enters the core. Ship it with the existing web documentation/examples mechanism and verify the installed path.
|
|
115
|
+
- [x] Require project hooks for route, fixture, theme, state, capture root and expected fonts. Read actual state and loaded font faces/weights; never echo requested inputs as observed evidence.
|
|
116
|
+
- [x] Park the pointer outside the capture region and verify no relevant hovered controls. Capture with explicit viewport, device scale **1** by default and a root bounding box after scroll/sticky layout settles. Round the box outward to whole CSS pixels and record the rule; do not resize images to improve a metric.
|
|
117
|
+
- [x] Preserve the current schema-1 provider fields. Add optional capture metadata for root/clip, scale, browser version, font evidence and pointer checks; old providers remain readable. The example requires its complete metadata and flags missing evidence instead of substituting defaults silently.
|
|
118
|
+
- [x] Validate paths/hashes and compare through the existing adapter. Retain `owner-review-required`; a pixel score never approves a baseline. Unapproved trial captures may test the capture helper, but the approval gate for `reflection check` stays intact.
|
|
119
|
+
|
|
120
|
+
Tests: adapter `integration.test.ts` plus new provider/capture fixtures for wrong state/theme, delayed/missing fonts, hover contamination, sticky shell, fractional crop boundaries, unchanged baseline bytes and dimension/scale mismatch. Exercise a real local example in the browser at desktop/mobile × light/dark × loaded/empty; unit stubs alone do not complete this phase.
|
|
121
|
+
|
|
122
|
+
Exit: an adopter can supply explicit setup hooks and run a genuine comparison without rewriting capture plumbing. No Tradient route/provider is registered by modifying its repository here.
|
|
123
|
+
|
|
124
|
+
### Phase 6 — explicit, isolated theme previews (PP-04, P2)
|
|
125
|
+
|
|
126
|
+
- [x] Record the pinned API's frame-level theme capabilities with links and observed proof. Do not expose native per-frame binding as supported based on an API name or projected appearance.
|
|
127
|
+
- [x] Deliver a deterministic offline preview first: neutral token-projection logic plus adapter command `penpair marwes tokens preview --from SNAPSHOT --theme NAME [--out FILE]`. Resolve the selected declared theme using existing token precedence/alias rules; ambiguous names, missing dependencies or unsupported values produce errors/explicit unknowns.
|
|
128
|
+
- [x] Return a versioned preview with source hash, selected theme/set identities, resolved values/unknowns and `kind: projected-theme-preview`. `--out` writes only a project-bound artifact. It does not mutate Penpot, switch global themes or imply native bindings.
|
|
129
|
+
- [x] Supply a scratch example applying projected color values to owned roots, with projection metadata retained separately from actual typography/spacing/radius bindings. Native frame-mode support remains a separate acceptance gate if it cannot be proved on the pinned version.
|
|
130
|
+
|
|
131
|
+
Tests: adapter preview/command-contract tests and neutral resolver tests: multiple themes, ordering, aliases/cycles, composite values, ambiguous names and missing values. Before/after scratch checks must show identical global selections, catalog values/order and unrelated objects.
|
|
132
|
+
|
|
133
|
+
Exit: simultaneous light/dark preview artifacts are reproducible and accurately labeled. Native component anatomy, override preservation and native per-frame color bindings remain unclaimed unless independently proven.
|
|
134
|
+
|
|
135
|
+
## Final integration and release gate
|
|
136
|
+
|
|
137
|
+
- [ ] Re-run the eight-case scratch trial using shipped CLI/kit paths, a repeat build and one heading change. Compare IDs, bindings, geometry, native/browser images and changed fields. Record observed timings, unknowns and interventions.
|
|
138
|
+
- [ ] Confirm no consumer-side timeout bypass, fixed inter-operation sleep or fabricated provider evidence is needed for the covered paths.
|
|
139
|
+
- [x] Run `pnpm check`, `pnpm smoke:package` and whitespace checks. Record the actual final test count and installed-package results; do not assume the 0.2.0 baseline count remains current.
|
|
140
|
+
- [x] Add Changesets per package behavior: fixes as patch, new public options/provider/preview capabilities as minor. The generated version PR selects the highest bump for every package; no manual version bump or release activation change belongs here.
|
|
141
|
+
- [x] Review the branch, evidence and remaining PP-07/native-mode/live gates; see the [branch review and acceptance checklist](tradient-feedback-review.md).
|
|
142
|
+
- [ ] Obtain owner decisions before any push/PR, merge, publish or non-scratch write.
|
|
143
|
+
|
|
144
|
+
If the scratch target is unavailable, code may be reviewed with live checks still pending, but the release must not claim those checks passed. No rollback or exactly-once guarantee is introduced. On an uncertain write: stop, retain the journal, inspect independently, reconcile only owned changes and resume explicitly. After repeated failure, record the trace and narrow the reproducer; never relax a guard to get a green report.
|
|
145
|
+
|
|
146
|
+
## Completion tracker and reports
|
|
147
|
+
|
|
148
|
+
| Phase | Status | Offline evidence | Live evidence | Completed |
|
|
149
|
+
| --- | --- | --- | --- | --- |
|
|
150
|
+
| 0 Baseline/reproducers | Complete offline | 587 tests; explicit expected-failure reproducers | Target pending | 2026-10-22 |
|
|
151
|
+
| 1 Layout | Complete offline | 597 tests; six-package smoke pass | Pending | 2026-10-22 |
|
|
152
|
+
| 2 Migration/readiness | Complete offline | 607 tests; six-package smoke pass | Pending | 2026-10-22 |
|
|
153
|
+
| 3 Coordination/snapshots | Offline delivery complete; PP-07 unresolved | 614 tests; six-package smoke pass | Pending | 2026-10-22 |
|
|
154
|
+
| 4 Help/skills | Complete | 615 tests; six-package smoke pass | Not applicable | 2026-10-22 |
|
|
155
|
+
| 5 Browser starter | Complete | 616 tests; package smoke; 8 real-browser cases + negative cases | Local Chromium trial complete; Penpot pending | 2026-10-22 |
|
|
156
|
+
| 6 Theme previews | Complete offline | 622 tests; six-package smoke pass | Scratch/native capability pending | 2026-10-22 |
|
|
157
|
+
| Final trial/release review | Offline review complete; owner/live pending | 630 tests; six-package smoke; real browser matrix | Penpot target pending | 2026-10-22 (offline) |
|
|
158
|
+
|
|
159
|
+
Append phase reports here during execution. Update the table and relevant `PLAN.md` checkbox in the same verified change.
|
|
160
|
+
|
|
161
|
+
### 2026-10-22 — Companion discovery (phase 4 documentation slice)
|
|
162
|
+
|
|
163
|
+
**Resolved:** Readers and agents can now discover why to add the library and frontend-comparison adapters, with Reflection Check recommended when implementing and verifying frontend code.
|
|
164
|
+
|
|
165
|
+
**Changed:** Added a companion selection/setup/readiness guide, promoted both roles in README and onboarding docs, updated shipped setup/handoff/recipe skills and project-facts guidance, and added a matching-version registration path. Kept adapter dependencies explicit and the browser starter planned. No runtime help/composition or reliability fix is claimed by this documentation slice.
|
|
166
|
+
|
|
167
|
+
**Validated:** `pnpm check` passes (583 tests), including navigation/anchors, core/skill neutrality and skill installation. All six package smoke installs pass; the command tarball includes the new adapter guide. Added patch changesets for the affected shipped packages.
|
|
168
|
+
|
|
169
|
+
**Risks:** These guidance changes need the next reviewed release and skill refresh to reach existing installations. Browser verification still requires approved baseline/case evidence and a real provider; automatic bundling/setup was not added. No version bump, push, merge or publish was performed.
|
|
170
|
+
|
|
171
|
+
**Next:** Phase 0 remains the runtime entry point; phase 5 supplies the real-browser starter. Phase 4's help/composition tasks remain unchecked.
|
|
172
|
+
|
|
173
|
+
### Phase 0 report — 2026-10-22
|
|
174
|
+
|
|
175
|
+
**Resolved:** portable, credential-free reproductions now distinguish confirmed defects from suspected live causes. **Changed:** [baseline evidence](../fixtures/feedback-reproductions.md), scratch manifest template, native timeout/metadata/delayed-page expected-failure tests and conservative delayed-revision fixture. **Validated:** existing targeted suites: 55 tests; reproducers: 4 tests; `pnpm check`: 587 tests pass, including three explicitly expected failures. **Risks:** expected-failure tests demonstrate missing behavior; they do not verify fixes. No live target or lease causality proof. **Next:** phase 1 shared layout fallback. Commit: `test: preserve adoption failure reproductions`.
|
|
176
|
+
|
|
177
|
+
### Phase 1 report — 2026-10-22
|
|
178
|
+
|
|
179
|
+
**Resolved:** idle native failure no longer blocks the default workflow when independent complete geometry settles. **Changed:** one static host/kit policy, bounded native attempts, three equal hierarchy-aware samples, diagnostics and CLI `--layout`; no write retry. **Validated:** native success/failure/hang, node overflow/cycles, target/transport refusal, kit binding and stable-render tests; `pnpm check` passes 597 tests and six-package smoke passes. **Risks:** geometry is neither visual approval nor font readiness; live CLI/kit build remains pending. **Next:** migration explanations and bounded doctor readiness. Commit: `feat: share bounded layout fallback across host and kit`.
|
|
180
|
+
|
|
181
|
+
### Phase 2 report — 2026-10-22
|
|
182
|
+
|
|
183
|
+
**Resolved:** metadata-only stale snapshots now explain schema/ownership/hash causes; transport connection alone cannot prove editor readiness. **Changed:** additive reason codes and existing migration guidance; bounded origin/transport/challenge execution/file-pin layers, timestamps and duration, default 5 s doctor with 1–30 s option. Docker uses the same fresh-read proof. **Validated:** 74 targeted tests, stale/missing challenges, wrong file, sleeping origin/editor, timeout validation and secret redaction; `pnpm check` 607 tests and six-package smoke pass. **Risks:** real background/disconnected editor tests remain pending; heartbeat/version are unknown unless observed. **Next:** coordination trace and serialized page sessions. Commit: `feat: explain migration drift and prove fresh doctor readiness`.
|
|
184
|
+
|
|
185
|
+
### Phase 3 report — 2026-10-22
|
|
186
|
+
|
|
187
|
+
**Resolved:** delayed synthetic navigation and overlapping same-client collectors now use observed IDs and serialized sessions, restoring the starting page. **Changed:** page/session guards shared by derived clients, bounded polling, per-page progress and separate restoration errors; optional `--trace --apply` journal lease/revision events (also token pushes). **Validated:** real plugin bodies cover delayed switches, concurrent collectors, manual navigation, removed/ambiguous pages, revision changes, restoration failure and cross-client writer contention; `pnpm check` 614 tests and six-package smoke pass. **Risks:** PP-07 remains **unresolved**: delayed own saves and external edits cannot be causally distinguished with current evidence. Revision guards are unchanged. Live sequential/external-edit tests pending. **Next:** installed help and composition guidance. Commit: `feat: serialize observed page sessions and trace writer revisions`.
|
|
188
|
+
|
|
189
|
+
- [ ] PP-07 follow-up: obtain scratch trace proving delayed writer-marker persistence, then separately review any change to revision ordering. Tracing and conservative conflict refusal are delivered; no race fix is claimed.
|
|
190
|
+
|
|
191
|
+
### Phase 4 report — 2026-10-22
|
|
192
|
+
|
|
193
|
+
**Resolved:** installed help now exposes the full inspect/spec/snapshot/capture/compare workflow; composition guidance catches under-designed first frames before multiplying variants. **Changed:** task-grouped actual command examples, composition checklist in shipped skills, and migration/layout/doctor/snapshot/recovery docs. Corrected old help wording that implied updating an image alone approves it. **Validated:** help, docs, neutral-core and idempotent skill installation tests; `pnpm check` 615 tests and six-package smoke pass. **Risks:** composition remains a human/agent judgment step; a checklist does not establish visual quality or owner approval. **Next:** real-browser comparison starter. Commit: `docs: expose the complete workflow and first-frame composition checks`.
|
|
194
|
+
|
|
195
|
+
### Phase 5 report — 2026-10-22
|
|
196
|
+
|
|
197
|
+
**Resolved:** adopters can reuse real capture plumbing with explicit project hooks rather than rewrite fonts/scroll/hover/cropping logic. **Changed:** shipped browser provider, independent DOM state and loaded font/weight evidence, outward CSS clipping, hover/occlusion checks, optional schema-1 metadata validation and installed-example smoke. **Validated:** `pnpm check` 616 tests and six-package smoke pass; eight real local browser cases plus wrong theme, missing face/weight, delayed font load, scale mismatch, hover and sticky-shell refusal. Actual screenshots were inspected; a sticky header initially obscured the heading and the new guard/scroll hook corrected it. [Portable browser evidence](../fixtures/browser-capture-2026-10-22.json) records Chromium 148.0.7778.96, bundled Playwright 1.62.1, unchanged reference bytes and owner-review-required. MCP could inspect the fixture but could not import modules; the real provider ran with the bundled runtime and cached Chromium. **Risks:** references are explicitly unapproved synthetic browser fixtures, not approved Penpot designs; sampled occlusion still requires image inspection. No consumer provider was registered. **Next:** offline projected themes and pinned native capability evidence. Commit: `feat: ship a verified real-browser comparison starter`.
|
|
198
|
+
|
|
199
|
+
### Phase 6 report — 2026-10-22
|
|
200
|
+
|
|
201
|
+
**Resolved:** independent light/dark artifacts can be generated without switching live themes or falsely claiming native frame modes. **Changed:** bounded neutral projection resolver shared with mode verification; adapter `tokens preview --from --theme [--out]`, discoverable artifact schema, source/theme/set provenance and owned scratch example. **Validated:** ordered precedence, aliases/arithmetic, composites, ambiguous/missing themes/sets, cyclic/budget failures, project-bound output and preservation through actual sandbox example bodies; `pnpm check` 622 tests and six-package smoke pass. **Risks:** [pinned capability evidence](../theme-previews.md#pinned-native-capability-evidence) is source-based; the hosted API version is distinct. Native frame themes, component parity/overrides and live projection preservation remain unproved. **Next:** full branch review, final browser/package validation and explicit live checklist. Commit: `feat: project declared themes without changing live selection`.
|
|
202
|
+
|
|
203
|
+
### Final boundary review report — 2026-10-22
|
|
204
|
+
|
|
205
|
+
**Resolved:** cancelling a queued collector no longer opens a parallel page queue while its predecessor is still active. **Changed:** deferred queue cleanup, stricter geometry/hierarchy and doctor identity validation, correct doctor range text, bounded browser animation-frame waits. **Validated:** the queue regression failed before the fix and passes afterward; cancellation after a delivered read performs no second observation. Malformed native/geometry/root/sibling evidence refuses. `pnpm check`: 630 tests; all six package smoke installs; eight real local browser cases plus six rejection cases and delayed fonts pass. **Risks:** live gates and PP-07 causality remain open. **Next:** owner branch review and separately authorized scratch acceptance. Commit: `fix: preserve cancellation and evidence boundaries`.
|
|
206
|
+
|
|
207
|
+
### Final handoff — 2026-10-22
|
|
208
|
+
|
|
209
|
+
**Resolved:** all authorized code phases and offline/local-browser acceptance are complete on the review branch. **Changed:** [consolidated branch report](tradient-feedback-review.md) maps every finding to its delivered outcome, evidence and remaining live checks. **Validated:** 630 tests, six installed package families, eight real browser cases and six rejection cases; build/types/version/whitespace checks pass. **Risks:** PP-07 causality, live Penpot build/repeat/heading and multi-page trials, native frame-theme proof and owner release decisions remain unchecked. **Next:** owner branch review and confirmed disposable-file acceptance; no credentials are requested and no publication was attempted.
|