Validate asset creation, atomicity and write safety against the live instance #197

Closed
opened 2026-09-14 23:10:58 +00:00 by david · 1 comment
Owner

Summary

Validate the whole write pipeline against the live Penpot instance: stage a small asset set, commit it as a single revision, confirm a human sees it in the UI, confirm a refused target writes nothing, and confirm a rejected batch is atomic. Record the findings.

Background

Depends on: #196

This gate covers the highest-risk area of the feature — the write path. Everything downstream (screens, component instances, imported libraries) inherits whatever is proven here, and several of the semantics are counter-intuitive enough that they must be demonstrated, not assumed:

  • a lagged revn is accepted and applied (so the extension tracks the revision itself),
  • the response revn is the pre-write revision and lagged is not an acknowledgement,
  • a rejected batch leaves the revision untouched and applies nothing,
  • the designated-target guard refuses non-designated files before any request is sent.

Required environment: PENPOT_URL, PENPOT_TOKEN, and the scratch project (pi-penpot-scratch -- safe to delete). Never run against a project with real designs.

Documentation Required

A separate process downloads these into the listed folders before this issue is implemented. Check the folders for the actual reference material before starting.

docs/reference/penpot-api/

docs/reference/pi-coding-agent/

Implementation Details

Run each check, capture the evidence (tool output plus the observed revn before/after), and write the results to extensions/penpot/findings.md under a "Write path" heading.

  1. Single-revision asset creation.
    • Authorise the scratch file with penpot_authorize_target.
    • Read revn (via penpot_get_file).
    • Stage three colours and two typographies (penpot_create_color ×3, penpot_create_typography ×2).
    • Call penpot_commit — expect one update-file call.
    • Re-read and confirm: all five assets exist by id, and the file's revn advanced exactly once.
    • In the Penpot UI, reload the file and confirm all five assets appear in the Assets panel with the right names.
  2. Refusal writes nothing.
    • Stage a colour against a file that has not been authorised.
    • Call penpot_commit → expect a refusal naming penpot_authorize_target.
    • Re-read that file and confirm revn is unchanged and no asset was added.
  3. Atomicity on a rejected batch.
    • Construct a batch that the server will reject (for example a typography missing a required field — deliberately malformed, or an add-obj with an invalid shape if easier to trigger at this stage).
    • Note revn before, commit, and confirm: the call fails with the server's explain surfaced verbatim, revn is unchanged, and nothing was created.
    • Confirm the changeset is still staged afterwards so a retry is possible.
  4. Stale-revision behaviour.
    • Stage a change, then edit the same file in the UI to advance revn, then commit.
    • Confirm the commit succeeds (lagged revn is accepted / conflict-refresh path works as implemented) and that the file advanced by exactly one revision from the observed pre-write value.

Record in extensions/penpot/findings.md: for each check, the exact calls, the observed revn values before and after, the outcome, and any surprise (in particular any case where the revision advanced by more than one, or where a write landed after a refusal). Any behaviour that contradicts the implementation must be fixed in code, not just noted.

Acceptance Criteria

  • Three colours and two typographies staged and committed in a single update-file call, verified by the file's revn advancing exactly once.
  • All five assets are visible in the Penpot UI Assets panel after a reload.
  • A commit against a non-designated file is refused, and the target file's revn is provably unchanged.
  • A deliberately invalid batch fails with the server's explain surfaced verbatim, leaves revn unchanged, and leaves the changeset staged.
  • A stale-revn commit succeeds and advances the file by exactly one revision.
  • extensions/penpot/findings.md contains the evidence (calls, revisions before/after, outcomes) and the Penpot version validated (2.17).
  • Every contradiction found between behaviour and implementation has been fixed in code.

Test Plan

Manual, against the live instance:

# in pi
/reload
# penpot_authorize_target(project_id | file_id)
# penpot_create_color x3, penpot_create_typography x2
# penpot_commit  -> expect success; record revn before/after
# penpot_get_file -> confirm 5 assets and a single-revision advance
# penpot_commit against a non-designated file -> expect refusal, revn unchanged
# penpot_commit with an intentionally invalid change -> expect explain verbatim, revn unchanged

Then open the scratch file in the Penpot UI, reload, and confirm the assets are present.

## Summary Validate the whole write pipeline against the live Penpot instance: stage a small asset set, commit it as a single revision, confirm a human sees it in the UI, confirm a refused target writes nothing, and confirm a rejected batch is atomic. Record the findings. ## Background **Depends on:** #196 This gate covers the highest-risk area of the feature — the write path. Everything downstream (screens, component instances, imported libraries) inherits whatever is proven here, and several of the semantics are counter-intuitive enough that they must be demonstrated, not assumed: - a lagged `revn` is accepted and applied (so the extension tracks the revision itself), - the response `revn` is the pre-write revision and `lagged` is not an acknowledgement, - a rejected batch leaves the revision untouched and applies nothing, - the designated-target guard refuses non-designated files **before** any request is sent. Required environment: `PENPOT_URL`, `PENPOT_TOKEN`, and the scratch project (`pi-penpot-scratch -- safe to delete`). Never run against a project with real designs. ## Documentation Required A separate process downloads these into the listed folders before this issue is implemented. Check the folders for the actual reference material before starting. **`docs/reference/penpot-api/`** - `<PENPOT_URL>/api/main/doc/openapi.json` — the ground truth for `update-file`'s parameters and error types on the running version. - https://help.penpot.app/user-guide/design-systems/assets/ — what the Assets panel must show, to validate the committed colours/typographies visually. - https://help.penpot.app/technical-guide/integration/ — auth context for reproducing checks with `curl` if a failure needs isolating below the extension. **`docs/reference/pi-coding-agent/`** - https://pi.dev/docs/latest/extensions — `/reload` and tool-call output, for capturing the evidence below. ## Implementation Details Run each check, capture the evidence (tool output plus the observed `revn` before/after), and write the results to `extensions/penpot/findings.md` under a "Write path" heading. 1. **Single-revision asset creation.** - Authorise the scratch file with `penpot_authorize_target`. - Read `revn` (via `penpot_get_file`). - Stage three colours and two typographies (`penpot_create_color` ×3, `penpot_create_typography` ×2). - Call `penpot_commit` — expect one `update-file` call. - Re-read and confirm: all five assets exist by id, and the file's `revn` advanced **exactly once**. - In the Penpot UI, reload the file and confirm all five assets appear in the Assets panel with the right names. 2. **Refusal writes nothing.** - Stage a colour against a file that has not been authorised. - Call `penpot_commit` → expect a refusal naming `penpot_authorize_target`. - Re-read that file and confirm `revn` is unchanged and no asset was added. 3. **Atomicity on a rejected batch.** - Construct a batch that the server will reject (for example a typography missing a required field — deliberately malformed, or an `add-obj` with an invalid shape if easier to trigger at this stage). - Note `revn` before, commit, and confirm: the call fails with the server's `explain` surfaced verbatim, `revn` is unchanged, and nothing was created. - Confirm the changeset is still staged afterwards so a retry is possible. 4. **Stale-revision behaviour.** - Stage a change, then edit the same file in the UI to advance `revn`, then commit. - Confirm the commit succeeds (lagged `revn` is accepted / conflict-refresh path works as implemented) and that the file advanced by exactly one revision from the observed pre-write value. Record in `extensions/penpot/findings.md`: for each check, the exact calls, the observed `revn` values before and after, the outcome, and **any surprise** (in particular any case where the revision advanced by more than one, or where a write landed after a refusal). Any behaviour that contradicts the implementation must be fixed in code, not just noted. ## Acceptance Criteria - [ ] Three colours and two typographies staged and committed in a **single** `update-file` call, verified by the file's `revn` advancing exactly once. - [ ] All five assets are visible in the Penpot UI Assets panel after a reload. - [ ] A commit against a non-designated file is refused, and the target file's `revn` is provably unchanged. - [ ] A deliberately invalid batch fails with the server's `explain` surfaced verbatim, leaves `revn` unchanged, and leaves the changeset staged. - [ ] A stale-`revn` commit succeeds and advances the file by exactly one revision. - [ ] `extensions/penpot/findings.md` contains the evidence (calls, revisions before/after, outcomes) and the Penpot version validated (`2.17`). - [ ] Every contradiction found between behaviour and implementation has been fixed in code. ## Test Plan Manual, against the live instance: ```bash # in pi /reload # penpot_authorize_target(project_id | file_id) # penpot_create_color x3, penpot_create_typography x2 # penpot_commit -> expect success; record revn before/after # penpot_get_file -> confirm 5 assets and a single-revision advance # penpot_commit against a non-designated file -> expect refusal, revn unchanged # penpot_commit with an intentionally invalid change -> expect explain verbatim, revn unchanged ``` Then open the scratch file in the Penpot UI, reload, and confirm the assets are present.
david closed this issue 2026-09-15 02:55:24 +00:00
Author
Owner

pi-loop opened and merged a pull request for this issue: #230

pi-loop opened and merged a pull request for this issue: https://git.excelera.net/david/pi-extensions-and-skills/pulls/230
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
david/pi-extensions-and-skills#197
No description provided.