S255 Handoff
Documentation for Sessions
S255 Handoff — Platform Generation Quality & Universe Data Lifecycle
Session: 255 | Date: 2026-03-23 | Status: Complete Branch: session-252-256_5 (shared with concurrent sessions)
What Was Done
1. Generation Pipeline — Template Variable Resolution (CRITICAL FIX)
Problem: Every generated file had undefined in its name: models/undefined.model.ts, components/undefined-list/undefined-list.component.ts.
Root Cause: preGenerateTemplateFiles() set entityName and entityNamePlural, but interpolate() read entity, Entity, entities, Entities — completely different variable names. JavaScript .replace() converts undefined to the string "undefined".
Secondary Bug: extractPrimaryEntity("manage players") returned "players" (plural). The pluralizer then produced "playerses".
Fix:
phase-orchestrator.service.ts: Now populates ALL canonical template variables + addedsingularize()methodtemplate-registry.service.ts:interpolate()has fallback chain — if canonical vars are missing, resolves from aliases
Files:
APIs/backend-ai-api/src/app/workflow/phase-executor/phase-orchestrator.service.tsAPIs/backend-ai-api/src/app/workflow/templates/template-registry.service.ts
Verified: Test generation produces player.model.ts, player-list.component.ts correctly.
2. Preview Runtime — SDK Stub Contract Fixes
All fixes in libs/libs-structural/platform-preview/src/lib/config/sdk-preview-stubs.ts:
| Fix | Before | After |
|---|---|---|
deleteFn signature |
Called with string |
Called with string[] (matches real API) |
update() body |
Sent raw data | Wraps in { data } (matches backend) |
query() response |
Only { data, total } |
Both { items, totalItems } AND { data, total } |
read() implementation |
return of(null) |
Real HTTP fetch |
| Form validation | No check before submit | Blocks invalid forms, calls markAllAsTouched() |
GgsToggleComponent |
Missing | Added with ControlValueAccessor |
GgsTableComponent |
Missing | Added with data/loading inputs |
3. Preview Runtime — JIT Compiler Loading
Problem: @angular/compiler is not available error in blob URL preview iframe.
Root Cause: rspack drops import '@angular/compiler' (side-effect-only external). esm.sh may not trigger Angular's publishFacade().
Fix (three layers):
- Named import:
import { VERSION } from '@angular/compiler'(prevents rspack from dropping) - Prerequisite script: also imports
@angular/platform-browser-dynamic(registers JIT internally) - Explicit:
if (compiler.publishFacade) compiler.publishFacade(globalThis)
Files:
libs/libs-structural/platform-preview/src/lib/services/preview-server.service.tslibs/libs-structural/platform-preview/src/lib/services/bundler-filesystem.service.ts
4. Universe Deletion Cascade
Problem: Deleting a universe left orphaned data in 6+ collections and git repos.
Fix: Added cascade cleanup to SpacesService.deleteUniverse():
| Data | Status |
|---|---|
generation_manifests |
Now cleaned |
deployments |
Now cleaned |
draft_sessions |
Now cleaned |
| Galaxies | Now cleaned (method existed, was never called) |
| Git repository (GitLab/Hetzner/Local) | Now cleaned |
| Backend-ai-api data | Still orphaned (intentional — no hard cross-service dependency) |
Files:
APIs/backend-api/src/app/spaces/spaces.service.tsAPIs/backend-api/src/app/spaces/spaces.module.ts
5. Other Preview Improvements
| Change | File |
|---|---|
| VFS-aware import path fixer | bundler-filesystem.service.ts |
| API_BASE_URL injection into stubs | preview.service.ts |
| Modulepreload hints for CDN | preview-server.service.ts |
| Debounce 150ms → 800ms | preview.service.ts |
What Was NOT Done (Future Work)
High Priority
Cross-service orphan cleanup for backend-ai-api data
- Configuration sessions, generated modules, deployment snapshots remain when universe is deleted
- Recommended: Event-driven cascade (emit
UniverseDeletedevent from backend-api, backend-ai-api subscribes and cleans its own data) - Alternative: Scheduled orphan cleanup job that scans for universeIds that no longer exist
Full E2E generation test
- The Vitto backend (port 3003) was down due to MongoDB timeout to Hetzner (
34.56.108.77:27017) - Once Hetzner MongoDB is reachable, test full generation → preview flow
- The Vitto backend (port 3003) was down due to MongoDB timeout to Hetzner (
Preview stub filter implementation
setFilter,removeFilter,clearFiltersare currently no-ops- Filters appear functional in UI but don't actually filter the list
- Need to implement client-side filtering in the stub's
doLoad()function
GgsCrudFormShellComponent missing saveError input
- Shell component has no
@Input() saveError— save failures don't display in the shell - Either add the input to the stub or update the prompt to have generated templates handle errors outside the shell
- Shell component has no
Medium Priority
Automated prompt-stub audit
- Currently manual. Should be a script that parses
implement.prompt.mdfor SDK imports/components and verifies each has a matching stub export - Could run as a pre-commit hook or CI check
- Currently manual. Should be a script that parses
SCSS flattener v2
- Current flattener handles nesting +
&only. Variables, mixins,@useare not supported - If generated code ever uses these, need dart-sass WASM compiler
- Current flattener handles nesting +
Key Architectural Decisions
No hard cross-service dependencies: Universe deletion in backend-api does NOT call backend-ai-api. Each backend must be able to operate independently.
Stubs mirror real contracts: Preview stubs must exactly match the real
useCrudList/useCrudForm/useCrudDetailsignatures fromlibs/core/module-base. Any drift causes runtime errors.Three-layer JIT defense: CDN module loading is unreliable — multiple fallback paths ensure Angular JIT compiler is available regardless of how esm.sh packages modules.
Template variable defensive fallbacks: Both the producer (
preGenerateTemplateFiles) and consumer (interpolate) now handle missing variables gracefully.
Files Modified in S255
Backend API (APIs/backend-api/)
src/app/spaces/spaces.service.ts— Universe deletion cascadesrc/app/spaces/spaces.module.ts— Import GitProviderModule, GenerationsModule
Backend AI API (APIs/backend-ai-api/)
src/app/workflow/phase-executor/phase-orchestrator.service.ts— Template variable resolution + singularize()src/app/workflow/templates/template-registry.service.ts— interpolate() fallback chain
Platform Preview (libs/libs-structural/platform-preview/)
src/lib/config/sdk-preview-stubs.ts— deleteFn, update, query, read, GgsToggle, GgsTable, form validationsrc/lib/services/preview-server.service.ts— JIT compiler loading, modulepreload hintssrc/lib/services/bundler-filesystem.service.ts— Named compiler import, VFS path fixer
Vitto Studio (libs/libs-structural/vitto-studio/)
src/lib/services/preview.service.ts— API_BASE_URL injection, debounce tuning
MCP Decisions Logged
| ID | Type | Summary |
|---|---|---|
dev_1774273985474_i19atie |
bugfix | Template variable resolution (undefined filenames) |
dev_1774273994975_bl5j5mp |
bugfix | deleteFn contract mismatch (string vs string[]) |
dev_1774274007253_fwb2mv4 |
bugfix | JIT compiler not available in preview |
dev_1774274035712_v7gypzh |
architecture | Universe deletion cascade (6 orphaned data types) |
dev_1774274043708_kdsd7xj |
bugfix | update() body wrapping + query() response mapping |
dev_1774274051363_jlljnra |
implementation | Missing GgsToggle/GgsTable stubs + form validation |
Conventions Added
| ID | Category | Rule |
|---|---|---|
conv_..._5axoh |
generation-pipeline | ALL canonical template variable forms must be populated |
conv_..._4vk8w |
preview-stubs | Every SDK component in prompts must have matching stub |
conv_..._8ycl8 |
data-lifecycle | Cascade deletion must be non-blocking, no cross-service hard deps |