docs(adr): ratify ADR-0001 and add ADR-0002 for org-wide tenants - #8
docs(adr): ratify ADR-0001 and add ADR-0002 for org-wide tenants#8JustAGhosT wants to merge 1 commit into
Conversation
ADR-0001 had been Proposed since 2026-07-11. A harness workbench panel (baton e650d56c) would have been the third tenant built on an unratified foundational decision, so ratify it: Status Accepted, dated 2026-08-12, with the trigger for ratification recorded in the Date section. The harness panel is org-wide, not Mystira, while ADR-0001 is titled and framed entirely around Mystira R13. Its decision text generalises; its framing does not. Rather than silently stretch it -- the "coupling creep" its own Consequences names as the top risk -- add ADR-0002 generalising panel-host to org-wide tenants and citing 0001 as the specific case. This leaves the Mystira narrative intact as history, including the extraction evidence that justified the panel-host shape in the first place. ADR-0002 carries over 0001's rules at org scope and adds two that only surface once tenants are org-wide: deck must not compute a number another repo owns (baton computes the score, deck renders it), and deck does not become an execution substrate (no run identity, no lease, no model call outside sluice). No panel registry. The deferral in 0001 is re-affirmed with an explicit expiry trigger instead: a second org adopting deck, or a tenant that must be hidden from an operator who has the others. Tenant count alone is not the cost -- all current tenants share one operator. Also corrects stale stack facts in five docs (React 18 -> 19, Vite 5 -> 8, Tailwind 3 -> 4, Tauri 1.5 -> 2.0) against app/package.json and app/src-tauri/Cargo.toml. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe PR adds ADR-0002 for org-wide panel hosting, accepts and cross-references ADR-0001, adds panel architecture guidance, and updates documented React, Vite, Tailwind CSS, and Tauri versions. ChangesPanel architecture and stack guidance
Estimated code review effort: 2 (Simple) | ~10 minutes Mergeability Score: 🟡 Moderate · up to The PR records org-wide panel-host rules, but its documentation currently omits part of the registration contract and overstates how tenant-neutral the shell is. This could mislead future panel additions and architectural decisions, so those bounded inconsistencies should be corrected before merge. Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 09f24a9baf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| tenant semantics and stay reusable by any phoenixvc project. Tenant-specific strings and types | ||
| live inside the tenant's own panel and backend files; the `VIEWS` registry is the only shared | ||
| touch-point. |
There was a problem hiding this comment.
Account for every shared routing touch-point
For any tenant following the recipe at lines 65–67, tenant-specific imports, labels, and branches also enter App.tsx, AppContent.tsx, and AppSidebar.tsx (the current Camera panel demonstrates all three), so VIEWS is not the only shared touch-point. Removing such a tenant necessarily edits those shell files, directly contradicting the omissibility invariant at line 81 and making the ADR's primary coupling boundary impossible to apply during future panel reviews; either classify all four routing files as allowed shared registries or change the routing design before asserting this boundary.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/adr/0002-deck-as-panel-host-for-org-wide-tenants.md`:
- Around line 65-81: The panel registration documentation is inconsistent about
the shared four-file recipe and tenant removal. In
docs/adr/0002-deck-as-panel-host-for-org-wide-tenants.md lines 65-81, identify
all four registration files—VIEWS, ACTIVITY_BAR_ITEMS, the AppContent route, and
the AppSidebar block—as shared touch-points, and state that removing a tenant
requires removing its registrations without modifying generic shell code. In
CLAUDE.md line 41, add the AppSidebar block to the panel-creation checklist.
- Around line 73-77: Revise the generic-shell boundary claim in the ADR to
acknowledge that the current cli.rs bridge, including execute_devhub_cli and its
Mystira.DevHub.CLI executable reference, is tenant-specific. Do not describe
cli.rs ↔ .NET-sidecar bridging as reusable or tenant-neutral unless the
implementation is decoupled; keep the remaining shared-shell boundaries
unchanged.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 2575f366-a971-41ce-8645-4b1e7a58f224
📒 Files selected for processing (7)
CLAUDE.mdREADME.mdapp/README.mdapp/architecture.mddocs/adr/0001-deck-as-panel-host-for-mystira-ops-tooling.mddocs/adr/0002-deck-as-panel-host-for-org-wide-tenants.mddocs/specs/deck-ops-cockpit.md
| A **tenant** is a bounded set of panels serving one domain, added through deck's existing four-file | ||
| recipe (a `VIEWS` entry + `ACTIVITY_BAR_ITEMS` + an `AppContent` route + an `AppSidebar` block) plus | ||
| whatever backend module it needs. Tenants as of this ADR: the generic shell's own panels (Dashboard, | ||
| Service Manager, Infrastructure), **Camera** (PR #3), **Mystira ops** (ADR-0001), and the | ||
| **harness workbench** (org-meta doc 07). | ||
|
|
||
| The rules, carried over from ADR-0001 and now stated at org scope: | ||
|
|
||
| - **The shell is the generic asset.** `VSCodeLayout`, the activity bar / `VIEWS` routing, the Rust | ||
| exec primitives (`Command::new`, argv-only), and the `cli.rs` ↔ .NET-sidecar JSON bridge carry no | ||
| tenant semantics and stay reusable by any phoenixvc project. Tenant-specific strings and types | ||
| live inside the tenant's own panel and backend files; the `VIEWS` registry is the only shared | ||
| touch-point. | ||
| - **Panels consume external contracts; they do not embed domain logic.** deck is a viewer and a | ||
| trigger. This was written for Mystira and holds unchanged for every tenant. | ||
| - **Secrets never enter the repo** — session or machine-local only, per deck's `security.md`. | ||
| - **A tenant is omissible.** Removing it must not require touching the shell. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Keep the panel registration contract consistent across the documentation.
The repository uses a four-file panel recipe, but the ADR describes VIEWS as the only shared touch-point and CLAUDE.md omits AppSidebar.
docs/adr/0002-deck-as-panel-host-for-org-wide-tenants.md#L65-L81: document all shared registration files and define how tenant removal works.CLAUDE.md#L41-L41: add theAppSidebarblock to the panel-creation checklist.
📍 Affects 2 files
docs/adr/0002-deck-as-panel-host-for-org-wide-tenants.md#L65-L81(this comment)CLAUDE.md#L41-L41
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/adr/0002-deck-as-panel-host-for-org-wide-tenants.md` around lines 65 -
81, The panel registration documentation is inconsistent about the shared
four-file recipe and tenant removal. In
docs/adr/0002-deck-as-panel-host-for-org-wide-tenants.md lines 65-81, identify
all four registration files—VIEWS, ACTIVITY_BAR_ITEMS, the AppContent route, and
the AppSidebar block—as shared touch-points, and state that removing a tenant
requires removing its registrations without modifying generic shell code. In
CLAUDE.md line 41, add the AppSidebar block to the panel-creation checklist.
| - **The shell is the generic asset.** `VSCodeLayout`, the activity bar / `VIEWS` routing, the Rust | ||
| exec primitives (`Command::new`, argv-only), and the `cli.rs` ↔ .NET-sidecar JSON bridge carry no | ||
| tenant semantics and stay reusable by any phoenixvc project. Tenant-specific strings and types | ||
| live inside the tenant's own panel and backend files; the `VIEWS` registry is the only shared | ||
| touch-point. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift
Align the generic-shell claim with the current CLI bridge.
In app/src-tauri/src/cli.rs Lines 23-69, the bridge is named execute_devhub_cli and its missing-executable message points to tools/Mystira.DevHub.CLI. This is tenant-specific coupling. The ADR cannot state that cli.rs carries no tenant semantics while this implementation remains unchanged. Revise the boundary claim or decouple the bridge before accepting it.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/adr/0002-deck-as-panel-host-for-org-wide-tenants.md` around lines 73 -
77, Revise the generic-shell boundary claim in the ADR to acknowledge that the
current cli.rs bridge, including execute_devhub_cli and its Mystira.DevHub.CLI
executable reference, is tenant-specific. Do not describe cli.rs ↔ .NET-sidecar
bridging as reusable or tenant-neutral unless the implementation is decoupled;
keep the remaining shared-shell boundaries unchanged.
Follow-up to the decision accepting deck as host for the harness workbench panel (baton
e650d56c, org-meta projectb024b02f). Docs only — no code changes.1. ADR-0001 ratified
It had been
Proposedsince 2026-07-11. The harness panel would have been the third tenant built on an unratified foundational decision, so it is now Accepted, dated2026-07-11 (proposed) → 2026-08-12 (accepted), with the trigger for ratification recorded in the Date section rather than left implicit.2. Scope mismatch resolved by a new ADR, not by broadening 0001
ADR-0001 is titled and framed entirely around Mystira R13 — its whole Context is Cosmos Explorer, Migration Manager, the story-generator Batch API, docket spend. The harness panel is org-wide. The ADR's decision text generalises cleanly ("deck is a generic panel-host"; "panels consume external contracts, they do not embed domain logic"); its framing does not.
Reading "Mystira ops tooling" as silently covering a non-Mystira tenant would be the coupling creep ADR-0001's own Consequences names as its top risk — applied to the ADR text rather than to the code, which is worse, since the ADR is the instrument meant to detect it.
So: new ADR-0002 generalising panel-host to org-wide tenants, citing 0001 as the specific case.
Why not broaden 0001 in place (recorded as its Alternative 2 — this is the part worth disagreeing with, if any): ADR-0001's Context is its evidence — the half-wired extraction, the three R13 facets, the alternatives those specific facts ruled out. Generalising that away leaves an ADR whose Context no longer explains its own Decision, and destroys the record of why deck is a panel-host at all.
0001 is generalised, not superseded. It stays Accepted and stays the record of the Mystira tenant; Status and References now point forward to 0002.
3. What ADR-0002 adds
Carries over 0001's rules at org scope, and adds two that only surface once tenants are org-wide:
RunRecord/leases/usage; deck renders. One store, many readers — deck is always a reader.It also records Camera (#3) as the non-Mystira tenant that already shipped on the four-file recipe — precedent that existed but was never written down as a decision.
4. No panel registry
Deliberately not built. The 0001 deferral was re-reviewed and judged still correct: all
VIEWSstay compiled in, and one more costs nothing today.One correction to the framing, though — a deferral without an expiry condition is just an omission. org-meta doc 07 §2.6 argues a third tenant makes config-driven selection "urgent rather than later"; that is the wrong axis. Tenant count is not the cost, since all current tenants share one operator. The trigger recorded in 0002 is instead: a second org adopts deck, or a tenant must be hidden from an operator who has the others.
5. Stale stack facts corrected
React 18 → 19, Vite 5 → 8, Tailwind 3 → 4, Tauri 1.5 → 2.0, verified against
app/package.jsonandapp/src-tauri/Cargo.toml. The same wrong fact was in five files, not the two originally flagged:README.md,CLAUDE.md,app/README.md,app/architecture.md,docs/specs/deck-ops-cockpit.md.Reviewer notes
CLAUDE.md's "Adding a new panel" recipe gained a line pointing at ADR-0002 with its constraints. Without it the ADR is invisible at the moment it matters — an agent adding a panel readsCLAUDE.md, notdocs/adr/. Still discipline, not enforcement. Easy to drop if unwanted.Acceptedon merge, notProposed— the decision was made upstream in baton; this PR records it. Landing itProposedwould repeat the drift this PR exists to clean up.🤖 Generated with Claude Code
Summary by CodeRabbit