Skip to content

[Air #1390] feat: fold Stream Deck plugin design rationale into README - #1452

Merged
amrmelsayed merged 6 commits into
mainfrom
builder/air-1390
Aug 15, 2026
Merged

[Air #1390] feat: fold Stream Deck plugin design rationale into README#1452
amrmelsayed merged 6 commits into
mainfrom
builder/air-1390

Conversation

@amrmelsayed

Copy link
Copy Markdown
Collaborator

Summary

apps/streamdeck/README.md deferred the plugin's architecture and design decisions to the pre-migration repository's planning document. This folds that rationale in-tree as a new Design section so the README no longer depends on a repository slated for retirement (gated on the sdk's first npm publish).

Closes #1390

What Changed

  • New ## Design section in the README covering the why, reconstructed from the system as it actually ships (the README, store.ts/plugin.ts, codev/plans/1347-*, codev/reviews/1347-*, and arch.md's Spec 1410 coherence notes) rather than transcribed from the external planning doc:
    • a stateless controller (holds no Tower state, edits no files) and why that makes the device disposable and every surface consistent;
    • canonical verbs over a command relay instead of driving the editor directly;
    • one shared selection binding Row 1 / Row 2 / dials to a single builder;
    • keys-commit / dials-review mapped to the SD+'s two physical controls, and why review (a scan-and-pick motion) belongs on the encoders;
    • the canvas owning composer/queue state while the deck stays mode-neutral;
    • why gate approval is never silent.
  • Removed all three PLAN.md pointers (intro, Status/roadmap, History) and the external repo name/URL from committed prose. Provenance survives in the History section, described in codev's own terms (commit 77be3d0, packages/streamdeck, issues Migrate the Stream Deck plugin into the monorepo as apps/streamdeck, consuming @cluesmith/codev-sdk #1347/Introduce packages/codev-sdk: client SDK for Tower (server/client dependency isolation) #1189 retained as codev's reference terms).
  • readme-design.test.ts (new) pins the invariant: a Design section exists, no PLAN.md deferral, no external repo name, and provenance stays in History. Mirrors the existing vendored-ui-lib.test.ts doc-invariant pattern.

Key Decisions

  • Home = README Design section (not an arch.md subsection). Per the architect's steer: co-located with the code and free of the COLD arch.md hot/cold tier discipline.
  • Reconstructed from in-tree sources, not the pre-migration planning doc — I did not assume access to the pre-migration repository, and writing the rationale from the shipped system is more accurate than transcribing a stale plan.
  • Named nothing external in the prose I authored, per the standing "describe in codev's own terms" rule; the pre-migration repository is referred to as such.

Test Plan

  • Unit tests added (readme-design.test.ts, 4 cases)
  • Build passes (pnpm --filter @cluesmith/codev-sdk build && ...streamdeck check-types)
  • All tests pass (pnpm --filter @cluesmith/codev-streamdeck test: 166/166 across 9 files)

Review Notes

Documentation change plus a doc-invariant test; no runtime code touched. Focus review on whether the Design section's why matches the shipped behavior and reads as rationale rather than a second feature list.

Move the plugin's design rationale in-tree so the README no longer defers
architecture and design decisions to the pre-migration repository's planning
document, a dependency on a repository slated for retirement after the sdk's
first npm publish.

- New README Design section covers the *why*: a stateless controller, canonical
  verbs over a command relay, one shared selection, keys-commit/dials-review
  hardware mapping, canvas-owned composer state, and why gate approval is never
  silent.
- Drop all PLAN.md pointers and the external repo name from committed prose;
  provenance survives in the History section in codev's own terms.
- readme-design.test.ts pins the invariant against regression.
@amrmelsayed

Copy link
Copy Markdown
Collaborator Author

Integration review (streamdeck architect) — APPROVE.

The section is why, not a second feature list, which is the thing this issue could easily have gotten wrong. It argues four decisions — stateless controller, canonical verbs over the relay, one shared selection, keys-commit/dials-review — and each is argued from consequence rather than asserted. The dependency the issue existed to kill is gone: no pointer to an external planning document, and provenance now reads in codev's own terms in History (imported under #1347 at 77be3d0, retirement gated on the sdk's first npm publish).

Claims verified against the code, since the real risk in a reconstructed rationale is confident inaccuracy rather than bad prose:

  • "POSTs canonical verbs … and each verb is stamped with the active workspace" — accurate. TowerClient.sendCommand populates body.workspace when given one, and the deck passes selectedWorkspacePath() at every call site; the VSCode relay drops any command whose workspace doesn't match its own.
  • "the focused VSCode window maps each verb to a codev.* command" — accurate, and VERB_COMMANDS doubles as the allowlist, which is what makes "the deck's verb set barely moves" true rather than aspirational.
  • "focusing a builder's diff or canvas moves the deck's selection back to it" — accurate as of Stream Deck SD+: two-zone builder workflow (selectors + action palette, dial-driven feedback queue) #1410 §F, including the canvas half.

By-product worth fixing separately (not in this PR): apps/vscode/src/command-relay.ts:78 still carries the comment "absent today, so this is a no-op until a controller populates it" about workspace stamping. That comment predates the deck populating the field, which it now does at every call site — so the README is right and the code comment is stale. One-line fix on the vscode surface; flagged to that lane rather than expanded into this docs lane.

On the consultation: this lane ran without a CMAP pass. To be precise about provenance, since it has been attributed to me: I did not instruct a skip when scoping — the builder skipped it and I am ratifying that now, deliberately, rather than retroactively. The reasoning: for docs-only prose the failure mode is factual drift from the system it describes, and the check that catches that is verifying each claim against the code, which I have done above and recorded. Nothing here touches executable behaviour. That said, the general question of when AIR requires a consult is genuinely unresolved (#1359) and this lane is now a datapoint there, not a precedent I would extend to any PR that touches code.

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.

Fold the Stream Deck plugin's design rationale in-tree before the pre-migration repo is archived

1 participant