review-architecture
Review a PR against the Pascal architectural rules — package boundaries (core/viewer/editor/nodes), the registry-driven composition model (def.geometry / def.renderer / def.system), legacy-dispatch regressions, the slots + world-scale-UV convention for new nodes/geometry, hook hygiene (useEditor/use…
Install / Use
npx skills add pascalorg/editor --skill review-architectureInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
Development & EngineeringSupported Platforms
Our assessment of review-architecture
review-architecture scores 90/100 on our quality scale, 506th of 2,860 Development & Engineering skills we index (top 18%).
Its SKILL.md is 29 KB long, well organised into 17 sections with 2 code examples: a thorough specification that gives an agent plenty to work with.
With 24,281 GitHub stars, it is one of the more widely adopted skills in the catalogue.
Maintenance, license and trust
- The repository was last updated 4 days ago, so review-architecture is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
review-architecture compared with similar skills
All 4 of these similar skills score higher than review-architecture; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| review-architecture (this skill)by pascalorg | 90 | 24.3k | 4d ago | SKILL.md |
| Agent-Reachby Panniantong | 100 | 85.7k | 12d ago | CLAUDE.md |
| ai-job-searchby MadsLorentzen | 100 | 44.1k | today | CLAUDE.md |
| claude-howtoby luongnv89 | 100 | 41.7k | 1d ago | CLAUDE.md |
| algorithmic-artby anthropics | 100 | 177.9k | 5d ago | SKILL.md |
Frequently asked questions
- How do I install review-architecture?
- Run
npx skills add pascalorg/editor --skill review-architecture. The install tabs above show the steps for each supported agent. - Which AI agents does review-architecture work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is review-architecture safe to use?
- It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is review-architecture still maintained?
- The repository was last updated 4 days ago, so review-architecture is actively maintained.
Skill content
View source on GitHubname: review-architecture description: Review a PR against the Pascal architectural rules — package boundaries (core/viewer/editor/nodes), the registry-driven composition model (def.geometry / def.renderer / def.system), legacy-dispatch regressions, the slots + world-scale-UV convention for new nodes/geometry, hook hygiene (useEditor/useScene/useViewer), and selector performance. Use when the user asks to review a PR, audit a branch, or check that changes respect the codebase's architecture. metadata: internal: true allowed-tools: Bash(git *) Bash(gh *) Read Grep Glob
Architectural review for Pascal PRs. The user will provide a PR URL, branch name, or ask to review the current branch.
1. Load the rules (required — do not skip)
Read these before reviewing any diff. They are the source of truth, not your training data:
wiki/architecture/layers.mdwiki/architecture/systems.md— core systems vs viewer systems, what each may dowiki/architecture/renderers.md— renderer responsibilities and prohibitionswiki/architecture/tools.md— editor tools live only inapps/editor/components/tools/orpackages/nodes/src/<kind>/wiki/architecture/viewer-isolation.md— viewer must stay editor-agnosticwiki/architecture/node-definitions.md— the three-checkbox composition model (geometry/renderer/system)wiki/architecture/plugin-authoring.md— public contract for external node packs
Required on every review. Read the remaining pages on demand when the diff touches their subject area:
wiki/architecture/selection-managers.mdwiki/architecture/scene-registry.mdwiki/architecture/spatial-queries.mdwiki/architecture/node-schemas.mdwiki/architecture/inspector-field-limits.md— no arbitrarymin/maxon dimension fields. Read whenever the diff adds or editsparametrics.ts, a kindpanel.tsx, or<SliderControl>bounds.wiki/architecture/events.mdwiki/architecture/interaction-scope.md— the interaction state machine + the unified snapping/modifier convention. Read whenever the diff touches a tool, amove-tool/selection/ endpoint / reshape file,lib/interaction/**,lib/snapping-mode.ts, oruse-interaction-scope.
If anything in the diff looks like a new dispatch surface or registry concept, also skim the live charter at plans/editor-node-registry.md (in the private-editor repo) — it owns the current contract and which kind sits at which migration stage.
2. Fetch the diff
# If the user gave a PR URL or number:
gh pr diff <pr-number-or-url>
# If reviewing the current branch:
git diff main...HEAD
Also list changed files so you can map each to the relevant rule:
gh pr view <pr> --json files --jq '.files[].path'
# or
git diff --name-only main...HEAD
3. Layer classification — do this BEFORE the checklist
For every new file, new type, new store field, or new exported helper introduced by the diff, answer one question: which package does this belong to — core, viewer, editor, or nodes? If the answer is "editor" but the code lives in packages/core or packages/viewer (or vice versa), or if kind-specific code lands anywhere other than packages/nodes/src/<kind>/, flag it as a blocker. This is the most common and most damaging class of violation, and the checklist below won't reliably catch it on its own — do this pass explicitly.
The four packages and what they own
packages/core — domain data + pure logic.
Owns: node schemas, the scene store (useScene), live transforms store, core systems (wall mitering, slab polygons, space detection), event bus, plain 2D/3D math helpers, sceneRegistry, the registry primitives (nodeRegistry, registerNode, loadPlugin, discoverPlugins/setPluginDiscovery, SceneApi, Plugin/NodeDefinition types). Consumed by every downstream package, including read-only embeds. Must not know about: Three.js/R3F, packages/viewer, apps/editor, packages/nodes, any rendering or UI concept, any tool/mode/phase concept, or any view-specific concept (floorplan, paint preview, cursor indicators, selection outline styling).
packages/viewer — the 3D canvas, shippable standalone.
Owns: <Viewer>, the generic <NodeRenderer> / <ParametricNodeRenderer> / <GeometrySystem> / <RegisteredSystems> / <FloorplanRegistryLayer> plumbing, viewer systems (cutouts, zones, level positions, scans), the viewer store (useViewer) for genuine presentation state only (selection path, camera/level/wall/view modes, theme, display toggles, hover id), useNodeEvents. Consumed by both the editor and the read-only /viewer/[id] route. Must not know about: editor state (useEditor, tools, phases, modes), editor-only names baked into presentation modes ('delete', 'paint-ready'), editor-only state types (material preview, active paint target, floorplan anything), packages/nodes.
packages/editor (and apps/editor) — the editing experience.
Owns: the tool framework (useDragAction, ParametricInspector, <MoveRegistryNodeTool>, the registry-aware dispatchers in tool-manager.tsx / MoveTool / panel-manager.tsx / helper-manager.tsx), useEditor, action menus, panels, the floorplan panel and its helpers, paint mode, selection-manager phase/mode logic, cursor badges, command palette, keyboard shortcuts — anything absent from the read-only viewer route. Injects itself into <Viewer> via children and props, never the reverse. Must not import from packages/nodes.
packages/nodes — the built-in plugin (pascal:core).
Owns: one folder per node kind (packages/nodes/src/<kind>/) containing definition.ts, schema.ts, optionally geometry.ts / renderer.tsx / system.tsx / floorplan.ts / tool.tsx / move-tool.tsx / panel.tsx / parametrics.ts / preview.tsx. Exports builtinPlugin. Depends on editor, viewer, and core via their public surfaces — the same surfaces a third-party plugin uses (peer-dep style). Nothing in core/, viewer/, or editor/ may import from @pascal-app/nodes. The dependency arrow is one-way: framework code consults nodeRegistry, never reaches into a specific kind's folder.
Triggers that mean "this is probably in the wrong package"
- Would the read-only
/viewer/[id]route need this? If no, it belongs inapps/editor/packages/editor. - Does the name contain an editor-specific word? (
Floorplan,Paint…,Draft…,Marquee,CursorBadge,HoverMode,…Tool,Moving…,Curving….) Default to editor and justify loudly if it's anywhere else. - Does the type or field reference a tool/mode/phase vocabulary? (
'delete','paint-ready','material-paint','site'/'structure'/'furnish','build'/'edit'.) Belongs inuseEditor, notuseVieweror core. - Does the helper compute something only a 2D editor view needs? (Floorplan transforms, measurement offsets, SVG path builders, marquee bounds scoped to floorplan.) Editor. Generic 2D geometry that any view could use (polygon math, rotation, clamping, line thickening) can live in core as long as its names are generic — no
Floorplanprefix. - Does a new store field have a setter that no part of the target layer ever calls? (e.g.
setMaterialPreviewinuseViewerthat only the editor would ever invoke.) That's a layering smell — the state belongs in the caller's layer. - Does the new file mention a specific kind by name? (
door-…,wall-…,item-…, etc.) Then it belongs inpackages/nodes/src/<kind>/, not underpackages/viewer/src/components/renderers/<kind>/,packages/viewer/src/systems/<kind>.ts,packages/editor/src/components/tools/<kind>/, orpackages/editor/src/components/ui/panels/<kind>-panel.tsx. Those legacy locations were deleted at Phase 6 cleanup — reintroducing one is a regression to the dispatch model. - Does an
importline readfrom '@pascal-app/nodes'insidecore/,viewer/, oreditor/? Blocker. The BiomenoRestrictedImportsrule already bans this; if it slipped through, the framework is reaching down into the plugin.
Write the classification down before writing findings. If core gains "Floorplan" types, the viewer gains paint-mode vocabulary, a renderer grows editor awareness, or a kind-specific file appears outside packages/nodes/src/<kind>/ — those are the blockers to lead with, not downstream symptoms.
4. Review checklist
A. Package boundaries
packages/viewer/**does not import from@pascal-app/editor,apps/editor, or@pascal-app/nodes, and does not referenceuseEditor, tool state, phase, or mode.packages/core/**does not import Three.js, react-three-fiber,@pascal-app/viewer,@pascal-app/editor, or@pascal-app/nodes.packages/editor/**does not import from@pascal-app/nodes.packages/core/**does not introduce types or helpers named after an editor view (Floorplan*,Paint*,Draft*). Generic plan-geometry helpers are fine; view-specific vocabulary is not.- No new
case '<kind>':clauses (or equivalent kind-specific branching keyed onnode.type) insidepackages/viewer/**orpackages/editor/**. Phase 6 deleted these; the dispatch happens vianodeRegistry. The exceptions left in tree aretreeNodeByType(a lookup map, not a switch) and unit-formatting switches (centimeters/feet/inches). Any newcase 'door'|'wall'|'item'…in a framework package is a blocker — the behavior belongs on the kind'sNodeDefinition. - Tools mutate
useScene(committed state) anduseLiveTransforms(ephemeral drag state); directsceneRegistrymesh transforms are allowed only under the live-drag exception inwiki/architecture/tools.md. No business logic, no imports frompackages/viewer.
B. Node registry & composition (packages/nodes)
If the PR adds or modifies a node kind, check against wiki/architecture/node-definitions.md and wiki/architecture/plugin-authoring.md:
- Three independent fields:
def.geometry?: (node, ctx) => Object3D,def.renderer?: () => Promise<{ default }>,def.system?: () => Promise<{ default }>. There is no discriminator — presence is participation. Setting all three is fine if the kind genuinely needs them; setting adef.systemwhose only job is to rebuild geometry on dirty is a smell — collapse todef.geometryand let<GeometrySystem>do the work. - Builders must be pure. A
def.geometryfunction must not importuseScene, must not mutate the store, and must not depend on React context. Read other nodes viaGeometryContext(ctx.resolve/ctx.children/ctx.siblings/ctx.parent). - Builders emit local-space children.
<ParametricNodeRenderer>binds<group position={liveTransform?.position ?? node.position}>in JSX. A builder that bakes world position into vertex coords, or a system that imperatively writesgroup.position/group.rotation, will desync R3F's prop binding — the node will snap to(0,0,0)after rebuild. Flag any imperativegroup.position.set(...)insidedef.geometryor a registered system. (Tool-drivensceneRegistry.nodes.get(id).position.set(...)during a live drag is fine and is the documented pattern — see hook hygiene below.) - Tag geometry-built children.
<GeometrySystem>only disposes children carryinguserData.__fromGeometry = true. Custom systems that imperatively add children to a registered group must follow the same convention if the group can host React-mounted children (e.g. shelf surfaces hosting items). - One registered mesh per node ID. If a custom renderer mounts multiple objects, register the parent group (or whichever object the system needs to address via
sceneRegistry.nodes.get(id)). - Previews must clone cached materials. If
def.previewcalls the geometry builder and then setsmaterial.opacity = 0.5, but the builder caches materials at module scope (most do, keyed onmaterial/ `mate
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
85.7kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
ai-job-search
44.1kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
claude-howto
41.7kA visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value.
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
