Founder rejected the lane-layout + synthetic-phase scaffolding shipped
via PR #1399/#1400/#1407. This commit restores the founder-tuned
natural view (FlowCanvasOrganic) and adds the per-bubble fold-
disclosure badge + top-right depth chip on top of it.
Adapter (products/openova-flow/adapter-flux/):
- mapper.go: BuildFromHR now returns ONE leaf FlowNode + finish-to-
start edges from spec.dependsOn only. Deleted BuildRegionNode,
BuildPhaseNodes, BuildPhaseEdges, phaseLabels, phaseSortKey,
AllPhaseSuffixes, PhaseSuffix* constants, derivePhase, PhaseLabel,
PhaseSortKey. Node-id separator changed "/" → ":" so ids do not
collide with URL routing (founder hit "Not Found" drilling into
contabo/phase-0).
- hr_informer.go: dropped bootstrap(), tracker, nodeGroups,
reemitGroups(), buildGroupNode(). handle() is now single-leaf
upsert + dependsOn edges.
- rollup.go: deleted entirely (StatusTracker only existed for
synthetic group rollups).
- mapper_synthetic_test.go + rollup_test.go: deleted; mapper_test.go
updated for the ":" separator + no-synthetic-rels assertions.
UI (products/catalyst/bootstrap/ui/):
- FlowPage.tsx: switched from @openova/flow-canvas's FlowCanvas back
to FlowCanvasOrganic. Dropped lane-layout (regionDescriptorsFromFlow),
defaultFoldedAtDepth from @openova/flow-core, FoldControls chrome
strip. Kept useFlowStream + ?folded=/?depth= URL contract.
- flowStreamToOrganic.ts (new): bridges live SSE state to the Job[]
+ hints + region/family descriptors flowLayoutOrganic expects.
Treats `contains` rels as parent-child and FS/SS/FF/SF/triggers as
dependsOn.
- FlowCanvasOrganic.tsx: ADDITIVE optional props onFoldToggle,
badgeCounts, nodeActions, onNodeAction. Renders per-bubble "⊕ K"/
"⊖" disclosure badge on group bubbles when wired; right-click
opens a small action menu. Existing call sites are unchanged.
- Depth chip: ◀ L<n>/<max> ▶ pinned top-right of canvas host,
visible only when real groups exist in the data. Esc clears
manual fold overrides.
Verification:
- go build ./... in adapter-flux: clean
- go test ./... in adapter-flux: PASS (12 tests)
- tsc --noEmit on bootstrap/ui: clean
- vitest FlowPage + FlowCanvasOrganic.bounded: 25/25 PASS
- vitest JobDetail + distribution + flowLayoutOrganic + flow-bridge:
27/27 PASS
Co-authored-by: e3mrah <1234567+e3mrah@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>