Skip to content

feat(gildi): Guild Hall page — crests, guilds, drives, chronicle, actions#12

Merged
Cervator merged 16 commits into
mainfrom
feat/gildi-crest-guilds
Jul 24, 2026
Merged

feat(gildi): Guild Hall page — crests, guilds, drives, chronicle, actions#12
Cervator merged 16 commits into
mainfrom
feat/gildi-crest-guilds

Conversation

@agent-refr

Copy link
Copy Markdown

AI-assisted change proposal. Filed by agent driven by @Cervator via GDD.

Summary

Builds the Guild Hall page out from the empty foundation (#11) to a full designed surface, in two batched slices (Plan 2 + Plan 3 in docs/plans/2026-07-21-gildi-*):

  • Generated heraldic crests (plugins/gildi/src/crest/) — a deterministic FNV-1a hash → blazon (honouring the rule of tincture) → inline-SVG Crest, with a useId clip-path and unit tests. Every guild gets its own coat of arms, generated from its id (no assets).
  • Guilds section — the first frontend catalog-querying in the repo (kind:Group spec.type:guild joined to owned type:practice Components), rendered as curated guild cards (crest + name + description + practice/aspect chips, EntityRefLink to the entity page) via InfoCard + theme-aware MUI Typography/Chip.
  • Drives band, Chronicle rail, Actions panel — mirroring the Guilds pattern: active drive Cycles; recent Sagas (newest-first, compact rows with skald byline); and scaffolder-template links (small buttons) sourced by the guild-hall tag, backed by three mock debug:log dogfood Templates (charter-a-practice / establish-a-guild / start-a-drive).
  • Two-zone layout — a wide column (Drives + Guilds) beside a top-aligned rail (Actions + Chronicle).
  • Seed fill — two more guilds (Platform, Incident Commanders), a second drive (operational-readiness), and display titles on the Cycles/Sagas so cards read as human names, not kebab ids.

Scope note: presentation deferred (logged in the plans) — typed/colored tag chips, front-matter-fetched Saga previews, skald avatars, and an owner-ref-join test-coverage hardening.

Test plan

  • ws test leidangr (make test test-app) and ws lint leidangr (make lint tsc) green at each step (crest unit tests, section render tests, page render test).
  • make smoke-catalog green (the dogfood Templates + new seed entities ingest).
  • Visual (human-confirmed): the full page renders — two drives, four guilds (3-across at full width) with distinct crests, a three-button Actions panel routing to working scaffolder templates, and a titled chronicle; reads well in light + dark.

Related

Cervator and others added 13 commits July 21, 2026 13:48
Second implementation slice: the deterministic heraldic crest generator (pure
FNV-1a hash → blazon honouring the rule of tincture → inline SVG Crest, with a
monogram fallback), the typed-catalog-search Guilds section (kind:Group
spec.type:guild joined to owned practices), the curated guild card composing the
crest with name/description/practice+aspect chips, and a plain plugin README.
Grounded in the design (§4 card system, §5 crests, §7 data model); catalog-react
import sources flagged for verification against installed versions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Task 0 of Plan 2: a plain README for the gildi plugin (noticed missing post-#11).
Also corrects the rule-of-tincture assertion in Plan 2's crest test snippet
(the original had a garbled tautology) to the clean "exactly one of field/charge
is a metal" check, before the crest task runs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pure FNV-1a hash -> blazon (rule of tincture: a colour field pairs with a metal
charge or vice versa) -> inline SVG Crest component (shield + division + charge),
deterministic per seed. Unit-tested for determinism, rule of tincture, and
distinctness. Task 2's guild card renders <Crest seed={guildName} />.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ards

Query kind:Group spec.type:guild (joined to owned type:practice Components),
render a responsive grid of curated guild cards (crest + name + description +
practice/aspect chips) linking to each guild's entity page. First frontend
catalog-querying in the repo. Also hardens the crest clipPath id to useId for
unique rendering across the grid, and adds a default case to the crest's
charge-shape switch to satisfy the repo-wide lint gate. Updates the existing
GuildHallPage smoke test to mock catalogApiRef now that the page mounts the
guilds section. ws test + ws lint green; browser visual check of the rendered
cards pending human confirmation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add display titles to the guild Groups + security-practice so cards read
"Security guild" / "Release Captains" / "Security practice" not raw kebab ids.
Refactor GuildCard to theme-aware MUI Typography/Chip + EntityRefLink
(consuming GuildView.entityRef) instead of fixed inline pixel styles, fixing
the small-font look and dropping the hand-built entity path. Adds
@material-ui/core as an explicit gildi plugin dependency (was only hoisted
transitively before). Updates GuildsSection.test.tsx to bind entityRouteRef
via mountedRoutes, which EntityRefLink now requires under renderInTestApp.
ws test + ws lint green; browser re-check pending.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…, layout)

Third slice, batched onto this branch per Cervator (conserve PR review quota,
and the page reads better whole): the Drives band, the Chronicle rail (recent
Sagas), the Actions panel (scaffolder links + a light charter-a-practice dogfood
template), and the two-zone layout composing all five sections. Each new section
mirrors the reviewed Guilds pattern (useX hook + XCard InfoCard/EntityRefLink/
Crest/Typography + XSection states). Grounded in the seed's Cycle/Saga shapes.
Deferred (noted): typed+colored chips, front-matter saga previews, skald avatars.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Query Cycle spec.type:drive, render a bounded "Active & upcoming drives" band of
curated drive cards (owner-guild crest + title + description + timeframe) linking
to the Cycle entity. Mirrors the reviewed Guilds section pattern. Not yet mounted
in the page (layout task composes all sections).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Query kind:Saga (newest-first by timeframe.end), render a compact "Recent
chronicle" rail of saga preview cards (touched-guild crest + title + one-line
description + skald byline + Read link). Mirrors the reviewed Guilds/Drives
pattern. Not yet mounted (layout task composes sections). Front-matter previews
deferred - uses metadata.description for now.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Query scaffolder Templates tagged guild-hall, render an "Actions" panel of
curated action cards (glyph + title + Create-page link). Seed a mock
charter-a-practice Template (debug:log only) tagged guild-hall + register it in
app-config, so the hub dogfoods its own model. Mirrors the reviewed section
pattern. Not yet mounted (layout task).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Compose the full Guild Hall page: intro header, a bounded Drives band up top,
then a two-zone Grid - a wide Guilds column and a rail holding Actions above the
Chronicle. Extend the page render test's catalog mock for the kinds all sections
now query. Full-page browser visual check pending human confirmation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…icle, top-aligned rail

Move Drives+Guilds into a wide column and Actions+Chronicle into a top-aligned
rail (fills the empty upper-right). Render Actions as small outlined buttons
(Create-page links) rather than heavy cards, and Chronicle as compact saga rows
rather than InfoCards - so the rail reads "a few buttons, then a list of sagas"
per the design mockup. Tests updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ild Hall

Flesh out the demo so the Guild Hall reads fuller:
- Two more guilds: Platform (aspect-aligned, operational-readiness) and Incident
  Commanders (craft-aligned) — with egil/sigrid joining them.
- A second drive Cycle: operational-readiness-drive (Platform guild).
- Display `title`s on the Cycles and Sagas (they were showing raw kebab ids as the
  card/link text with the human title stuck in the description) — mock-org and the
  MTL soccer saga. Descriptions reworked into short previews.

Verified: org.yaml + cycles.yaml parse and carry the new entities (yq).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…start-a-drive)

Complete the Actions set to the mockup's three buttons: add mock (debug:log)
scaffolder Templates `establish-a-guild` (New guild) and `start-a-drive` (Start
a drive), tagged guild-hall, registered in app-config alongside charter-a-practice.
Real scaffolding is future work; these log their plan on the Create page.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Cervator
Cervator requested a review from Copilot July 22, 2026 04:00
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0c625cc2-3e2d-429b-b0ab-4dba8d98f3ed

📥 Commits

Reviewing files that changed from the base of the PR and between 1e73c1a and 6315a24.

📒 Files selected for processing (2)
  • plugins/gildi/src/chronicle/useSagas.ts
  • plugins/gildi/src/drives/useDrives.ts

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Expanded the Guild Hall hub with a new Guilds section, Active & upcoming Drives band, Recent Chronicle rail, and a curated Actions panel.
    • Added deterministic guild crest rendering plus richer guild/drive/saga/action cards with loading, empty, and error states.
    • Added new scaffolder templates to support Guild Hall actions (charter a practice, establish a guild, start a drive).
  • Documentation
    • Added a Guild Hall plugin README and published planning docs for the Guilds hub and full-page shell.
  • Chores
    • Updated mock catalog data and catalog ingestion configuration to include the new Guild Hall templates and entity metadata.

Walkthrough

Adds catalog-backed Guild Hall sections for guilds, drives, chronicle Sagas, and actions; introduces deterministic SVG crests, mock catalog data, dogfood templates, responsive page composition, tests, dependencies, and plugin documentation.

Changes

Guild Hall hub

Layer / File(s) Summary
Catalog data and actions
app-config.yaml, examples/mock-org/*, examples/mtl.yaml, examples/mock-org/guildhall/actions/*
Adds Guild, practice, drive, Saga, and Template catalog data, plus Guild Hall scaffolder templates and catalog ingestion locations.
Deterministic crest rendering
plugins/gildi/src/crest/*, docs/plans/2026-07-21-gildi-crest-and-guilds-plan.md
Adds deterministic hashing, blazon generation, tincture mapping, clipped SVG crest rendering, exports, and unit tests.
Guild catalog section
plugins/gildi/src/guilds/*, docs/plans/2026-07-21-gildi-crest-and-guilds-plan.md
Queries guild Groups and practice Components, joins annotations and ownership, and renders guild cards with practice and aspect chips.
Drives, Chronicle, and Actions sections
plugins/gildi/src/drives/*, plugins/gildi/src/chronicle/*, plugins/gildi/src/actions/*, docs/plans/2026-07-21-gildi-full-page-shell-plan.md
Adds catalog hooks and UI sections for drives, Sagas, and tagged Templates with state handling and focused tests.
Page composition and plugin validation
plugins/gildi/src/components/GuildHallPage.tsx, plugins/gildi/src/plugin.test.tsx, plugins/gildi/package.json, plugins/gildi/README.md
Replaces the page placeholder with the full layout, adds catalog-isolated smoke rendering, updates runtime dependencies, and documents plugin setup.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CatalogAPI
  participant GuildHallPage
  participant GuildsSection
  participant DrivesBand
  participant ActionsPanel
  participant ChronicleRail

  GuildHallPage->>DrivesBand: render drives section
  DrivesBand->>CatalogAPI: query drive Cycles
  GuildHallPage->>GuildsSection: render guilds section
  GuildsSection->>CatalogAPI: query guild Groups and practice Components
  GuildHallPage->>ActionsPanel: render actions panel
  ActionsPanel->>CatalogAPI: query tagged Templates
  GuildHallPage->>ChronicleRail: render chronicle rail
  ChronicleRail->>CatalogAPI: query Saga entities
Loading

Possibly related PRs

  • SiliconSaga/leidangr#11: Provides the scaffolded Guild Hall plugin that this change expands with the full page layout and catalog-backed sections.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: the Guild Hall page gaining crests, guilds, drives, chronicle, and actions sections.
Description check ✅ Passed The description is detailed and directly matches the implemented Guild Hall page, data seeds, templates, and test plan changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/gildi-crest-guilds

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR builds out the @siliconsaga/plugin-gildi Guild Hall page from a placeholder into a functional, catalog-driven surface, adding deterministic heraldic crests and multiple curated sections (Guilds, Drives, Actions, Chronicle) plus updated mock seed data and catalog ingestion.

Changes:

  • Add a deterministic crest generator (FNV-1a → blazon → inline SVG) and use it across Guild/Drive/Saga cards.
  • Implement catalog-backed sections for guilds (with practices/aspects), drives, actions (scaffolder templates), and a chronicle rail (recent sagas), composed into a two-zone layout.
  • Expand mock org seed entities (titles, guilds, drives, templates) and register new Template locations in app-config.yaml.

Reviewed changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
plugins/gildi/src/plugin.test.tsx Updates page smoke test to mount routes and provide a catalog API stub.
plugins/gildi/src/guilds/useGuilds.ts Adds catalog queries/join logic to build a GuildView list.
plugins/gildi/src/guilds/GuildsSection.tsx Renders a loading/error/empty state + responsive guild card grid.
plugins/gildi/src/guilds/GuildsSection.test.tsx Adds render test with mocked catalog results.
plugins/gildi/src/guilds/GuildCard.tsx Adds curated guild InfoCard using crest + chips + entity link.
plugins/gildi/src/drives/useDrives.ts Adds catalog query + view shaping for drive Cycles.
plugins/gildi/src/drives/DrivesBand.tsx Renders drives band with loading/error/empty states and grid.
plugins/gildi/src/drives/DrivesBand.test.tsx Adds render test for drives band with mocked drive Cycle.
plugins/gildi/src/drives/DriveCard.tsx Adds curated drive InfoCard with optional owner guild crest.
plugins/gildi/src/crest/index.ts Barrel exports for crest module.
plugins/gildi/src/crest/hash.ts Deterministic FNV-1a 32-bit hash utility.
plugins/gildi/src/crest/Crest.tsx Inline SVG crest renderer (division + charge) using useId clipPath.
plugins/gildi/src/crest/blazon.ts Blazon generator honoring rule of tincture + palette helpers.
plugins/gildi/src/crest/blazon.test.ts Unit tests for determinism, tincture rule, distinctness.
plugins/gildi/src/components/GuildHallPage.tsx Composes Drives/Guilds/Actions/Chronicle into the page layout.
plugins/gildi/src/chronicle/useSagas.ts Adds catalog query + sorting and view shaping for sagas.
plugins/gildi/src/chronicle/SagaCard.tsx Adds compact saga row with crest, title, description, byline.
plugins/gildi/src/chronicle/ChronicleRail.tsx Renders recent chronicle rail with cap + “more” indicator.
plugins/gildi/src/chronicle/ChronicleRail.test.tsx Adds sorting/byline test for chronicle rail.
plugins/gildi/src/actions/useActions.ts Adds template discovery for guild-hall tagged actions + Create hrefs.
plugins/gildi/src/actions/ActionsPanel.tsx Renders actions as buttons (currently anchor-based) with loading/error states.
plugins/gildi/src/actions/ActionsPanel.test.tsx Adds render test asserting Create-page href.
plugins/gildi/README.md Adds plugin README (status/install/dev notes).
plugins/gildi/package.json Adds missing runtime deps for crest/hooks/MUI usage.
examples/mtl.yaml Adds Saga title and refines description for display.
examples/mock-org/repos/security-aspect/catalog-info.yaml Adds Component title for nicer card rendering.
examples/mock-org/org.yaml Adds new guild groups + titles; updates org children + memberships.
examples/mock-org/guildhall/actions/guild-actions.template.yaml Adds two additional mock scaffolder Templates tagged guild-hall.
examples/mock-org/guildhall/actions/charter-practice.template.yaml Adds mock “charter-a-practice” Template tagged guild-hall.
examples/mock-org/cycles.yaml Adds Cycle/Saga titles + second drive and updated descriptions.
docs/plans/2026-07-21-gildi-full-page-shell-plan.md Adds Plan 3 implementation plan documentation.
docs/plans/2026-07-21-gildi-crest-and-guilds-plan.md Adds Plan 2 implementation plan documentation.
app-config.yaml Registers new mock Template locations for catalog ingestion.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -0,0 +1,34 @@
import { Button, Typography } from '@material-ui/core';
import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline';
import { Progress, ResponseErrorPanel } from '@backstage/core-components';
Comment on lines +20 to +21
component="a"
href={a.createHref}
Comment on lines +18 to +20
const touches = (s.spec?.touches as string[]) ?? [];
const guildRef = touches.find(t => t.startsWith('group:') && t.includes('gildi')) ?? touches.find(t => t.startsWith('group:'));
const tf = (s.spec?.timeframe as { end?: string }) ?? {};
Comment thread plugins/gildi/README.md Outdated

## Status

Foundation shipped: a page at `/guild-hall` with a sidebar entry. Sections land incrementally (guilds first). See `docs/plans/2026-07-20-gildi-guildhall-hub-design.md` in the leidangr repo for the full design.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🤖 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-21-gildi-crest-and-guilds-plan.md`:
- Line 16: Resolve the mismatch between the documented crest fallback contract
and the Crest behavior: either implement an explicit generation-disabled path
that returns a monogram and add coverage for it, or remove the monogram fallback
requirement from the plan. Update the Crest contract and related plan statements
consistently, while preserving the existing empty-seed behavior.
- Line 175: Update the crest ID guidance around the seed-based ID construction
to use React’s useId() approach from Crest.tsx instead of normalized seed text.
Ensure each SVG instance receives a unique, collision-free ID and remove the
non-injective seed-derived identifier.

In `@docs/plans/2026-07-21-gildi-full-page-shell-plan.md`:
- Around line 120-122: Update the guildRef selection in the views mapping so it
matches only documented guild references: inspect the final reference segment
and require it to end with “-gildi”, or resolve referenced Groups and select
only actual guild Groups. Remove the broad includes('gildi') predicate while
preserving the fallback behavior for valid group references.

In `@examples/mock-org/guildhall/actions/charter-practice.template.yaml`:
- Around line 11-14: Mark the practice input in
examples/mock-org/guildhall/actions/charter-practice.template.yaml lines 11-14
as required and enforce minLength: 1. Apply the same required and minLength: 1
constraints to guild and stewards in
examples/mock-org/guildhall/actions/guild-actions.template.yaml lines 14-18, and
to drive and guild at lines 36-40, so blank submissions are rejected.

In `@plugins/gildi/README.md`:
- Around line 5-7: Update the Status section in the Gildi README to reflect that
the page now includes Guilds, Drives, Chronicle, and Actions, removing the
outdated statement that sections land incrementally with guilds first. Preserve
the existing route, sidebar, and design-document references.

In `@plugins/gildi/src/actions/useActions.ts`:
- Around line 20-28: The template links built in useActions must preserve each
template’s namespace instead of always using default. Update createHref to use
metadata.namespace with default as the fallback, update the button key in
ActionsPanel to use the namespaced href, and add a non-default-namespace case in
ActionsPanel.test.tsx covering the generated link.

In `@plugins/gildi/src/chronicle/ChronicleRail.tsx`:
- Around line 6-10: Update ChronicleRail so the “Recent chronicle” heading
renders outside the loading, error, and empty-state early returns. Keep each
existing state body unchanged while ensuring the heading remains visible and
navigable in every state.

In `@plugins/gildi/src/drives/useDrives.ts`:
- Around line 15-16: Update the drive retrieval and mapping flow in useDrives to
exclude Cycle entities whose timeframe.end has passed, while retaining active
and upcoming drives. Apply the filtering before returning the mapped items,
using the existing status or date fields, and preserve the current UI contract
for “Active & upcoming drives.”
- Line 24: The entity references currently hardcode the default catalog
namespace. In plugins/gildi/src/drives/useDrives.ts:24 and
plugins/gildi/src/chronicle/useSagas.ts:25, update the link construction to use
stringifyEntityRef with each entity’s actual metadata reference, preserving the
correct namespace for Cycle and Saga links.

In `@plugins/gildi/src/guilds/useGuilds.ts`:
- Around line 27-32: Update useGuilds so practice join keys and
GuildView.entityRef preserve each guild’s actual namespace instead of
hard-coding group:default. Normalize both the owner value used in
practicesByOwner and the guild ref created in the guildsRes.items mapping, using
the catalog-model helpers if available, and ensure practices from non-default
namespaces still join correctly.
🪄 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: bc5eeecb-82ce-4f21-9134-1d38084dcc73

📥 Commits

Reviewing files that changed from the base of the PR and between 1862400 and e79903c.

📒 Files selected for processing (33)
  • app-config.yaml
  • docs/plans/2026-07-21-gildi-crest-and-guilds-plan.md
  • docs/plans/2026-07-21-gildi-full-page-shell-plan.md
  • examples/mock-org/cycles.yaml
  • examples/mock-org/guildhall/actions/charter-practice.template.yaml
  • examples/mock-org/guildhall/actions/guild-actions.template.yaml
  • examples/mock-org/org.yaml
  • examples/mock-org/repos/security-aspect/catalog-info.yaml
  • examples/mtl.yaml
  • plugins/gildi/README.md
  • plugins/gildi/package.json
  • plugins/gildi/src/actions/ActionsPanel.test.tsx
  • plugins/gildi/src/actions/ActionsPanel.tsx
  • plugins/gildi/src/actions/useActions.ts
  • plugins/gildi/src/chronicle/ChronicleRail.test.tsx
  • plugins/gildi/src/chronicle/ChronicleRail.tsx
  • plugins/gildi/src/chronicle/SagaCard.tsx
  • plugins/gildi/src/chronicle/useSagas.ts
  • plugins/gildi/src/components/GuildHallPage.tsx
  • plugins/gildi/src/crest/Crest.tsx
  • plugins/gildi/src/crest/blazon.test.ts
  • plugins/gildi/src/crest/blazon.ts
  • plugins/gildi/src/crest/hash.ts
  • plugins/gildi/src/crest/index.ts
  • plugins/gildi/src/drives/DriveCard.tsx
  • plugins/gildi/src/drives/DrivesBand.test.tsx
  • plugins/gildi/src/drives/DrivesBand.tsx
  • plugins/gildi/src/drives/useDrives.ts
  • plugins/gildi/src/guilds/GuildCard.tsx
  • plugins/gildi/src/guilds/GuildsSection.test.tsx
  • plugins/gildi/src/guilds/GuildsSection.tsx
  • plugins/gildi/src/guilds/useGuilds.ts
  • plugins/gildi/src/plugin.test.tsx

Comment thread docs/plans/2026-07-21-gildi-crest-and-guilds-plan.md Outdated
Comment thread docs/plans/2026-07-21-gildi-crest-and-guilds-plan.md Outdated
Comment thread docs/plans/2026-07-21-gildi-full-page-shell-plan.md Outdated
Comment thread examples/mock-org/guildhall/actions/charter-practice.template.yaml Outdated
Comment thread plugins/gildi/README.md Outdated
Comment thread plugins/gildi/src/actions/useActions.ts
Comment thread plugins/gildi/src/chronicle/ChronicleRail.tsx Outdated
Comment thread plugins/gildi/src/drives/useDrives.ts Outdated
Comment thread plugins/gildi/src/drives/useDrives.ts Outdated
Comment thread plugins/gildi/src/guilds/useGuilds.ts Outdated
…er, section headings, SPA action links, saga guild suffix, doc/README accuracy, template validation

CodeRabbit + Copilot on PR #12 (all valid): use stringifyEntityRef/namespace
instead of hardcoded default across the hooks; filter drives to active/upcoming;
keep section headings visible in loading/empty/error; pick the touched guild by
-gildi suffix; SPA Link for action buttons (no full reload); required+minLength
on the mock template params; refresh the README status; and align the plan docs
with the as-built crest (useId, no monogram fallback) + saga selection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 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-21-gildi-crest-and-guilds-plan.md`:
- Line 157: Insert a blank line between the preceding list item and the opening
```tsx fenced block to satisfy Markdownlint MD031, without changing the block
content.

In `@docs/plans/2026-07-21-gildi-full-page-shell-plan.md`:
- Line 122: Update the Drive and Saga hook samples in the plan to construct
entity references with stringifyEntityRef instead of manually building
cycle:default/... and saga:default/... strings. Add the Drive sample’s
active/upcoming end-date filter, matching shipped behavior, while preserving the
corrected guild predicate.

In `@plugins/gildi/src/drives/DrivesBand.tsx`:
- Line 18: Use canonical entity references for catalog list keys: in
plugins/gildi/src/drives/DrivesBand.tsx lines 18-18, update the drives map key
from d.name to d.entityRef; in plugins/gildi/src/chronicle/ChronicleRail.tsx
lines 22-24, update the stories map key from s.name to s.entityRef.

In `@plugins/gildi/src/drives/useDrives.ts`:
- Around line 30-31: Update the today value in the drive filtering logic to
construct YYYY-MM-DD from the local Date year, month, and day fields instead of
using toISOString(). Preserve the existing views.filter condition and date
format.

In `@plugins/gildi/src/guilds/useGuilds.ts`:
- Around line 28-31: Protect the owner parsing in the practices-by-owner loop
around parseEntityRef and stringifyEntityRef: validate or catch malformed
spec.owner values per practice, skip that practice when parsing fails, and
continue processing the remaining practices without rejecting useGuilds.
🪄 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: f3b41051-086a-4cd9-a4fd-df138242b457

📥 Commits

Reviewing files that changed from the base of the PR and between e79903c and 6a45c0d.

📒 Files selected for processing (13)
  • docs/plans/2026-07-21-gildi-crest-and-guilds-plan.md
  • docs/plans/2026-07-21-gildi-full-page-shell-plan.md
  • examples/mock-org/guildhall/actions/charter-practice.template.yaml
  • examples/mock-org/guildhall/actions/guild-actions.template.yaml
  • plugins/gildi/README.md
  • plugins/gildi/src/actions/ActionsPanel.tsx
  • plugins/gildi/src/actions/useActions.ts
  • plugins/gildi/src/chronicle/ChronicleRail.tsx
  • plugins/gildi/src/chronicle/useSagas.ts
  • plugins/gildi/src/drives/DrivesBand.test.tsx
  • plugins/gildi/src/drives/DrivesBand.tsx
  • plugins/gildi/src/drives/useDrives.ts
  • plugins/gildi/src/guilds/useGuilds.ts

Comment thread docs/plans/2026-07-21-gildi-crest-and-guilds-plan.md
Comment thread docs/plans/2026-07-21-gildi-full-page-shell-plan.md
Comment thread plugins/gildi/src/drives/DrivesBand.tsx Outdated
Comment thread plugins/gildi/src/drives/useDrives.ts Outdated
Comment thread plugins/gildi/src/guilds/useGuilds.ts
…ve filter, entity-ref keys, namespace action test

CodeRabbit re-scan (all valid):
- useGuilds: guard parseEntityRef per practice (try/catch, skip malformed owner)
  so one bad entity can't reject the whole section.
- useDrives: build the expiry `today` from local Date fields, not toISOString()
  (UTC), so a drive ending today doesn't vanish during the prior local evening.
- DrivesBand/ChronicleRail: list keys use `entityRef` (namespace-unique), not
  bare `name`.
- ActionsPanel.test: add a non-default-namespace Template case asserting the
  Create link preserves the namespace (completes the earlier action-links fix
  so CodeRabbit's thread resolves).
- Plan docs: MD031 blank line before a fence; reconcile the useDrives/useSagas
  samples with the shipped stringifyEntityRef + active/upcoming filter.
Verified: ws test (25) + ws lint green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 33 out of 33 changed files in this pull request and generated 2 comments.

Comment on lines +1 to +20
import useAsync from 'react-use/lib/useAsync';
import { useApi } from '@backstage/core-plugin-api';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
import { stringifyEntityRef } from '@backstage/catalog-model';

export interface DriveView {
name: string; title: string; description?: string;
entityRef: string; // cycle:default/<name>
ownerGuildName?: string; // for the crest, when owner is a guild Group
start?: string; end?: string;
}

export function useDrives() {
const catalog = useApi(catalogApiRef);
const state = useAsync(async () => {
const res = await catalog.getEntities({ filter: { kind: 'Cycle', 'spec.type': 'drive' } });
const views = res.items.map(c => {
const owner = (c.spec?.owner as string) ?? '';
const ownerName = owner.startsWith('group:') ? owner.split('/').pop() : undefined;
const tf = (c.spec?.timeframe as { start?: string; end?: string }) ?? {};
Comment on lines +19 to +30
const touches = (s.spec?.touches as string[]) ?? [];
const guildRef = touches.find(t => t.startsWith('group:') && (t.split('/').pop() ?? '').endsWith('-gildi')) ?? touches.find(t => t.startsWith('group:'));
const tf = (s.spec?.timeframe as { end?: string }) ?? {};
return {
name: s.metadata.name,
title: s.metadata.title ?? s.metadata.name,
description: s.metadata.description,
entityRef: stringifyEntityRef(s),
skaldRef: s.spec?.skald as string | undefined,
guildName: guildRef ? guildRef.split('/').pop() : undefined,
end: tf.end,
} as SagaView;
Copilot flagged both crest-seed extractions using naive `owner.split('/').pop()`,
which mis-derives the seed for valid non-canonical refs (e.g. `group:security-gildi`
with no namespace yields the whole string as the seed → wrong/blank crest). The
current seed is all-canonical so there is no bug today, but this is the same
fragility already fixed with parseEntityRef in useGuilds — so make it consistent:

- useDrives: parse `spec.owner` with the backend's { defaultKind: Group,
  defaultNamespace: default } and take the name only when kind is Group;
  malformed refs leave the crest off rather than seeding it garbage.
- useSagas: resolve each `touches` entry the same way, keep the group-kind names,
  then prefer the `-gildi` guild (unchanged selection semantics).

Verified: ws test (25) + ws lint green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Cervator
Cervator merged commit a40ca94 into main Jul 24, 2026
1 check passed
@Cervator
Cervator deleted the feat/gildi-crest-guilds branch July 24, 2026 17:31
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.

3 participants