feat(gildi): Guild Hall hub — foundation (design, plan, scaffold, mermaid)#11
Conversation
Design for `gildi`, the first custom frontend plugin — the Guild Hall hub page plus entity-page decoration for the practice layer. Captures the decisions from the brainstorm: new-frontend-system Blueprints; `plugins/gildi` as an extraction-ready workspace package (Cycle/Saga stay as ecosystem kinds); the five-section swappable layout (bounded drives band, wide growing guilds column, chronicle rail, tag-sourced actions); the curated card system with the identity-mark rule and generated heraldic crests; annotation- driven decoration with front-matter preview cards; the aspect-ladder vs component-badge model (with deferred ladder differentiation); config-driven customization; the `guild-hall` Component retiring; the `gildi`→`guild` group-type rename; and the Mermaid TechDocs Addon. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…mermaid Resolve the design's open questions per review: - action discovery tag = `guild-hall` (slug; "Guild Hall" stays the display). - crests are guilds-only in v1 (non-guild teams may get arms later). - the `guildhall` dogfood practice + aspect ships in v1. - Mermaid TechDocs addon is prioritized to land early and independently. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rmaid) First of the per-slice implementation plans for the Guild Hall plugin. Plan 1 covers the decision-free foundation: scaffold `plugins/gildi` (new-frontend- system page + sidebar item), rename the guild group type `gildi` → `guild`, and wire Mermaid via the TechDocs Addons framework. Grounded in the in-repo module patterns (modules/cycle, modules/nav) and the installed package versions. Surfaces one decision the design left implicit — retiring the `guild-hall` Component also orphans the root TechDocs anchor — with two options and a recommendation, flagged as needing Cervator's pick before that task runs. Later slices (crest module, catalog-querying cards, drives/chronicle/actions, entity decoration, dogfood) get their own plans. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cervator chose Option 1 (re-home the root TechDocs, then delete the entity) over demoting it. Records the retirement sequencing — surface the guildhall-model concept map on the plugin page, re-home the root mkdocs docs + vísir, then delete the guild-hall entity + its app-config location and sweep refs. Runs in its own later plan, after the page exists. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rename the guild Group type value `gildi` -> `guild` across the seed, smoke assertion, and type-citing doc references. Only the spec.type value changes; group names (security-gildi, release-captains-gildi) and the institution word "gildi" are untouched. "gildi" survives only as the plugin/package name. Verified via make smoke-catalog. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…item Scaffold @siliconsaga/plugin-gildi on the new frontend system: a PageBlueprint mounting the Guild Hall page at /guild-hall, and the plugin registered in the app's features. Placeholder page content; catalog querying + cards land in later slices. Verified: package tsc + render test pass, and `ws test leidangr` (make ci) is green. Browser visual check pending human confirmation. API note: @backstage/frontend-plugin-api@0.17.2 removed `NavItemBlueprint` (BREAKING in 0.17.0) - nav items are now discovered from `PageBlueprint` extensions via their `title`/`icon` params, so the page doubles as the sidebar entry (no separate nav-item extension needed). Also added plugins/gildi/.eslintrc.js (delegating to @backstage/cli/config/eslint-factory, matching packages/app and packages/backend - every workspace package needs its own) and plugins/gildi/src/setupTests.ts (imports @testing-library/jest-dom so `toBeInTheDocument` works, matching packages/app's convention; added @testing-library/jest-dom as a devDependency). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add backstage-plugin-techdocs-addon-mermaid@0.26.0 so ```mermaid``` fences in TechDocs render as diagrams client-side (unblocks the root guildhall-model.md concept maps, which currently degrade to code blocks). No new app module or App.tsx code was needed. The addon's package.json declares the same backstage.role: frontend-plugin-module / pluginId: techdocs / pluginPackage: @backstage/plugin-techdocs marker as the already-installed @backstage/plugin-techdocs-module-addons-contrib, and ships an identical-shape ./alpha export (AddonBlueprint.make + createFrontendModule, default export techDocsMermaidAddonModule). That contrib package is itself wired with zero App.tsx code today, picked up purely by the app's app-config.yaml app.packages: all discovery setting, so the mermaid addon registers the same way by simply being a dependency. Compatibility note (spike finding): the addon's own dependency on @backstage/frontend-plugin-api is ^0.13.4, well behind the app's installed ^0.17.2, so yarn nests a private 0.13.4 copy under its node_modules rather than deduping. This is a real version-skew risk on Backstage's still-alpha new frontend system, mitigated by @backstage/frontend-plugin-api shipping @backstage/version-bridge for cross-version extension compatibility, and by the extension contract here being the plain string-tagged techdocs.addon kind rather than a class-identity check. `ws test leidangr` (make ci) is green, but that gate does not exercise discovery (the Jest APP_CONFIG in App.test.tsx has no app.packages key), so it does not prove the addon loads at runtime. In-product TechDocs render of docs/guildhall-model.md against the root site is the human's pending visual confirmation, and is the first real test of the version-skew risk noted above. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…print identity matches the app's The mermaid TechDocs addon (0e1b4ea) registered via `app.packages: all` discovery exactly as theorized, but still rendered as a plain code block. Root cause was NOT the discovery mechanism (verified directly from `@backstage/cli-module-build`'s `packageDetection.cjs.js`: it detects any direct dependency with `backstage.role` in `["frontend-plugin", "frontend-plugin-module"]` and imports both its `.` and `./alpha` entries whenever `./alpha` is present in `exports` — both the mermaid addon and the already-working `@backstage/plugin-techdocs-module-addons-contrib` satisfy this with zero App.tsx wiring, and `discoverAvailableFeatures` only checks a generic `$$type` string tag, so the module itself always got picked up). The real break was a three-way dual-package hazard inside the addon's own resolved dependency tree. `backstage-plugin-techdocs-addon-mermaid` directly depends on `@backstage/frontend-plugin-api@^0.13.4` (nested locally), while `AddonBlueprint` comes via `@backstage/plugin-techdocs-react/alpha` — and yarn had *also* nested a private `plugin-techdocs-react@1.3.13` under the addon (requiring `frontend-plugin-api@^0.17.3`, itself nested one level deeper). So the addon's `alpha.esm.js` built its extension using an `AddonBlueprint` instance from one `frontend-plugin-api` copy (via the nested 1.3.13 techdocs-react) and wrapped it with `createFrontendModule` from yet another, older copy (the addon's own direct 0.13.4) — neither of which was the single copy (`frontend-plugin-api@0.17.2` / `plugin-techdocs-react@ 1.3.12`) that the app and the reader page that actually consumes `techdocs.addon` extensions use. The extension module still passed the generic discovery check, but the addon's `AddonBlueprint`-tagged data was built from a foreign module instance the reader page's blueprint-identity lookup doesn't recognize, so it silently never rendered — no console error, just a plain code block. Fix: add root `resolutions` entries pinning `@backstage/frontend-plugin-api` and `@backstage/plugin-techdocs-react` to the app's already-installed ranges (`^0.17.2` / `^1.3.12`). After `yarn install`, both packages collapsed to a single top-level copy each — the mermaid addon's nested node_modules no longer carries its own frontend-plugin-api or plugin-techdocs-react at all, so `AddonBlueprint` and `createFrontendModule` now resolve to the exact same instances the app and reader page use. `ws test leidangr` (config-check, repo lint, tsc, both jest suites) stays green with no type errors, confirming the addon's API surface is compatible with the app's 0.17.2 — this was a duplicate- install problem, not a genuine breaking-API one, so no addon vendoring was needed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The TechDocs Addons mermaid addon now renders these fences as diagrams (see the frontend-plugin-api dedupe in the preceding fix), so the comment claiming they degrade to code blocks is no longer true. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 17 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe change standardizes guild group types from ChangesGuild Hall foundation
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant App
participant gildiPlugin
participant GuildHallPage
App->>gildiPlugin: Register frontend feature
gildiPlugin->>GuildHallPage: Lazy-load page route
GuildHallPage-->>App: Render Guild Hall page
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
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/plans/2026-07-20-gildi-guildhall-hub-plan.md`:
- Around line 156-174: Update the Step 5 blueprint example to match the
implemented current API: use a single PageBlueprint configured with path, title,
and icon, and remove the outdated NavItemBlueprint/defaultPath shape.
Alternatively, explicitly label the existing snippet as the older API, but
ensure the documented example is not presented as the current implementation.
In `@packages/app/src/App.tsx`:
- Around line 7-8: Update the createApp configuration in App.tsx to import and
register the backstage-plugin-techdocs-addon-mermaid integration in the TechDocs
add-ons alongside the existing features. Ensure the Mermaid addon is mounted
through the app’s TechDocs configuration so Mermaid fences render.
🪄 Autofix (Beta)
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 227e2d99-84dc-4975-9b57-c50cc399f029
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (21)
docs/demo-visir.mddocs/guildhall-model.mddocs/plans/2026-07-10-guilds-skills-standards-design.mddocs/plans/2026-07-20-gildi-guildhall-hub-design.mddocs/plans/2026-07-20-gildi-guildhall-hub-plan.mdexamples/mock-org/README.mdexamples/mock-org/org.yamlmkdocs.ymlpackage.jsonpackages/app/package.jsonpackages/app/src/App.tsxplugins/gildi/.eslintrc.jsplugins/gildi/package.jsonplugins/gildi/src/components/GuildHallPage.tsxplugins/gildi/src/index.tsplugins/gildi/src/plugin.test.tsxplugins/gildi/src/plugin.tsxplugins/gildi/src/routes.tsplugins/gildi/src/setupTests.tsplugins/gildi/tsconfig.jsonscripts/smoke-catalog.sh
💤 Files with no reviewable changes (1)
- mkdocs.yml
…lueprint API Per CodeRabbit on PR #11: the plan's Step 5 example still showed the pre- implementation `NavItemBlueprint` + `defaultPath` shape, which the actual plugin dropped (NavItemBlueprint was removed in frontend-plugin-api 0.17.0). Update the snippet to the as-built single `PageBlueprint` with `path`/`title`/ `icon`, and keep a historical note explaining the API shift. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/plans/2026-07-20-gildi-guildhall-hub-plan.md`:
- Around line 150-172: Update Step 10 to use the PageBlueprint navigation model
established in Step 5, stating that the page’s path, title, and icon provide the
sidebar entry automatically. Remove references to NavItemBlueprint,
nav.take('nav-item:gildi'), and any obsolete navigation item ID.
🪄 Autofix (Beta)
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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: d5c5b7b0-d4f4-4b6d-892d-4fbc2d22be02
📒 Files selected for processing (1)
docs/plans/2026-07-20-gildi-guildhall-hub-plan.md
There was a problem hiding this comment.
Pull request overview
Introduces the first custom frontend plugin (@siliconsaga/plugin-gildi) to establish a “Guild Hall” hub page on Backstage’s new frontend system, enables Mermaid rendering in TechDocs via the addons framework, and renames the guild Group spec.type value from gildi to guild across the seed, smoke checks, and referenced docs.
Changes:
- Added
plugins/gildiscaffold (createFrontendPlugin+PageBlueprint) mounting a placeholder page at/guild-hall, registered in the app. - Added
backstage-plugin-techdocs-addon-mermaidand dependency resolutions to ensure consistent TechDocs addon wiring. - Renamed mock-org guild Group type value
gildi→guildand updated the catalog smoke assertions + documentation references.
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| yarn.lock | Locks new dependencies for the gildi plugin and TechDocs Mermaid addon. |
| scripts/smoke-catalog.sh | Updates the Ravenline guild-type smoke assertion to expect type: guild. |
| plugins/gildi/tsconfig.json | Adds TypeScript config for the new @siliconsaga/plugin-gildi workspace package. |
| plugins/gildi/src/setupTests.ts | Adds Jest DOM matchers for plugin tests. |
| plugins/gildi/src/routes.ts | Declares the plugin’s root route ref. |
| plugins/gildi/src/plugin.tsx | Defines the frontend plugin and a PageBlueprint for /guild-hall. |
| plugins/gildi/src/plugin.test.tsx | Adds a basic render test for the placeholder page. |
| plugins/gildi/src/index.ts | Exports the plugin as the default export. |
| plugins/gildi/src/components/GuildHallPage.tsx | Implements the placeholder Guild Hall page UI. |
| plugins/gildi/package.json | Declares the new frontend-plugin package metadata and dependencies. |
| plugins/gildi/.eslintrc.js | Adds standard Backstage ESLint config for the plugin package. |
| packages/app/src/App.tsx | Registers gildiPlugin in the app’s features. |
| packages/app/package.json | Adds dependencies on @siliconsaga/plugin-gildi and the Mermaid TechDocs addon. |
| package.json | Adds resolutions to align @backstage/frontend-plugin-api / @backstage/plugin-techdocs-react versions. |
| mkdocs.yml | Removes now-outdated commentary about Mermaid not rendering in TechDocs. |
| examples/mock-org/README.md | Updates documentation to refer to spec.type: guild for guild Groups. |
| examples/mock-org/org.yaml | Renames the two mock guild Groups’ spec.type from gildi → guild. |
| docs/plans/2026-07-20-gildi-guildhall-hub-plan.md | Adds the Plan 1 implementation plan for the Guild Hall foundation slice. |
| docs/plans/2026-07-20-gildi-guildhall-hub-design.md | Adds the design doc for the Guild Hall hub plugin. |
| docs/plans/2026-07-10-guilds-skills-standards-design.md | Updates the “Gildi” mapping row to spec.type: guild. |
| docs/guildhall-model.md | Updates Mermaid model diagram text to spec.type:guild. |
| docs/demo-visir.md | Updates demo checklist/tour text to refer to guild-typed Groups. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| **Goal:** Stand up the `gildi` plugin as a mounted, sidebar-linked (empty) Guild Hall page on the new frontend system, get Mermaid rendering in TechDocs, and rename the guild **group type** `gildi` → `guild` — the prerequisites every later slice builds on. | ||
|
|
||
| **Architecture:** A new workspace package `plugins/gildi` exposes a `createFrontendPlugin` default export with a `PageBlueprint` (route `/guild-hall`) and a `NavItemBlueprint` (sidebar "Guild Hall"); the app registers it in `packages/app/src/App.tsx` `features`. Mermaid is wired via the TechDocs Addons framework. The seed's guild Groups switch `spec.type: gildi` → `guild`. No catalog querying or cards yet — that is Plan 2+. |
|
|
||
| - [ ] **Step 1: Find every occurrence of the type, separating type-value from concept/name.** | ||
|
|
||
| Run: `rg -n "gildi" components/leidangr` (via the Grep tool). Classify each hit: **rename** only where it is the *type value* (`spec.type: gildi`, "type `gildi`", "`spec.type:gildi`", "gildi-typed"); **leave** group *names* (`security-gildi`, `release-captains-gildi`), the plugin/concept word "gildi", and the `-gildi` suffixes in refs. |
| - **`PageBlueprint`** — the Guild Hall page, mounted at `/guild-hall` (route ref in `src/routes.ts`). | ||
| - **`NavItemBlueprint`** — a "Guild Hall" sidebar entry (see §9 on the eventual "Hubs" group). | ||
| - **`EntityCardBlueprint`** — the entity-page decoration cards (guild / practice / aspect), mirroring the existing `packages/app/src/modules/cycle/` card as the in-repo pattern. |
…lign docs with as-built nav API Address CodeRabbit + Copilot on PR #11: - **Real gap (Copilot):** ADR 0009 still cited `spec.type: gildi` — a type-value occurrence Task A's sweep missed. Renamed to `guild`; verified no other type-value citations remain outside the plan's own before/after examples. Added ADR 0009 to the plan's Task A sweep list. - **Stale nav API (CodeRabbit Step 10 + Copilot):** the design §2 bullet, the plan's Architecture line, and plan Step 10 still referenced `NavItemBlueprint` / `nav.take('nav-item:gildi')`. `NavItemBlueprint` was removed in frontend-plugin-api 0.17.0; aligned all three to the as-built model (the `PageBlueprint`'s `title`/`icon` provide the sidebar entry). - **Path nit (Copilot):** the plan's Step 1 grep used the workspace path `components/leidangr`; changed to repo-relative `.`. Doc-only; no code change (build unaffected). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
@siliconsaga/plugin-gildi, on Backstage's new frontend system. Design:docs/plans/2026-07-20-gildi-guildhall-hub-design.md; Plan 1 (this PR's implementation):docs/plans/2026-07-20-gildi-guildhall-hub-plan.md.spec.type: gildi→guildacross the seed, smoke assertion, and type-citing docs ("gildi" survives only as the plugin/package name; group names and the kennings vocabulary are untouched).gildiplugin scaffold —createFrontendPluginwith aPageBlueprintmounting a placeholder Guild Hall page at/guild-halland a sidebar entry, registered inpackages/app/src/App.tsx. (New-frontend-system note:NavItemBlueprintwas removed infrontend-plugin-api@0.17.0, so the nav item ridesPageBlueprint'stitle/icon.) This is the foundation shell only — catalog querying, the card system, and section content are later slices (Plan 2+).backstage-plugin-techdocs-addon-mermaidaddon (auto-registers viaapp.packages: alldiscovery) and aresolutionsdedupe of@backstage/frontend-plugin-api/@backstage/plugin-techdocs-reactso the addon's blueprint identity matches the app's; the rootdocs/guildhall-model.mdconcept maps now render as diagrams.Test plan
ws test leidangr(make ci: config-check + lint + tsc + jest suites) — green.make smoke-catalog— 28/28, incl.Guild Group ingested (type guild).plugins/gildi/src/plugin.test.tsx) passes./guild-hall.guild-hallDocs → "Guildhall model" Mermaid diagrams render (not code blocks), console clean.Related
graft→adoptionterminology rename (refactor(guildhall): rename graft → adoption #10).@backstage/plugin-catalog-reactdep inplugins/gildiis staged for that slice.