Skip to content

Data-Flow Foundation F1+F2 — PR1: types + interfaces#130

Merged
jukka-matti merged 8 commits into
mainfrom
data-flow-foundation-f1-f2
May 6, 2026
Merged

Data-Flow Foundation F1+F2 — PR1: types + interfaces#130
jukka-matti merged 8 commits into
mainfrom
data-flow-foundation-f1-f2

Conversation

@jukka-matti
Copy link
Copy Markdown
Owner

Summary

PR1 of 3 in the Data-Flow Foundation F-series (F1+F2: type-level normalization + repository pattern). Pure-types + interfaces in @variscout/core plus consumer fixes across the monorepo. No runtime behavior change. F3 (PR7 in canvas migration sequence) swaps the PWA Dexie backend without changing this PR's surface.

Spec: docs/superpowers/specs/2026-05-06-data-flow-foundation-design.md
Plan: docs/superpowers/plans/2026-05-06-data-flow-foundation-f1-f2.md
Audit (P0): docs/superpowers/plans/2026-05-06-data-flow-foundation-f1-f2-audit.md — 15 plan-revising findings (R1–R15) absorbed before P1 dispatch.

What landed

# Commit Phase
1 160978ea P1.1 — @variscout/core/identity (EntityBase + generateDeterministicId); sweeps both Math.random generateId instances
2 34cb664d P1.2 — ProcessHub + OutcomeSpec (surrogate id added) + ProcessHubInvestigation extend EntityBase
3 a006f420 P1.3 — Evidence types (EvidenceSource, EvidenceSnapshot, RowProvenanceTag) extend EntityBase; EvidenceSourceCursor relocated azure→core (R4); ADR-077 amended
4 94051a31 P1.4 — Findings types (10 entities) extend EntityBase; CausalLink.hubId → suspectedCauseId rename (R5)
5 51abfb80 P1.4 review fixes — tsc-clean fixtures + createFinding/createQuestion/createSuspectedCause investigationId hardening; 'general-unassigned' debt logged in investigations.md
6 bb6c078d P1.4b — Sustainment + ControlHandoff EntityBase; tombstoneAt → deletedAt rename (R3)
7 5c6b9183 P1.5 — Canvas embedded entity typed FKs (ProcessMapNode, ProcessMapTributary, ProcessMapArrow, ProcessMapHunch); ProcessMap itself stays non-EntityBase per spec D3 (R6)
8 e7a9938e P2.1–P2.5 — HubAction discriminated union (kind discriminator + SCREAMING_SNAKE_CASE per R2) + HubRepository interface + cascadeRules (12 EntityKinds) + exhaustiveness test

Architectural decisions absorbed

  • kind discriminator + SCREAMING_SNAKE_CASE action values match the existing canvas migration convention (packages/core/src/canvas/types.ts); CanvasAction re-exported as-is.
  • createdAt: number (Unix ms) atomically across all entities — half the codebase had ISO strings, converted in same PR per feedback_no_backcompat_clean_architecture.
  • All id, createdAt, deletedAt REQUIRED — no optional/loose typing.
  • 'general-unassigned' placeholder for Finding.investigationId / Question.investigationId until F6 multi-investigation lifecycle ships; logged as architectural debt in docs/investigations.md.
  • RowProvenanceTag.snapshotId = '' at paste-flow call sites — F3 wiring gap, documented in code comments + ADR-077 amendment.

Scope

  • 8 commits, 174 files changed (+3334 / -1107)
  • Branch: data-flow-foundation-f1-f2
  • Worktree: .worktrees/data-flow-foundation-f1-f2/
  • PR2 (PwaHubRepository + PWA UI/app composition migration) and PR3 (AzureHubRepository + ESLint guard + final Opus review) are out of scope for this PR.

Test plan

  • pnpm --filter @variscout/core test — 3241 tests passing (3230 baseline + 11 new actions/cascade tests)
  • All package builds clean (@variscout/ui, @variscout/azure-app, @variscout/pwa tsc all 0 errors)
  • bash scripts/pr-ready-check.sh — green (tests + lint + docs:check + PWA dist integrity)
  • Per-task spec compliance + code quality reviewers (P1.1, P1.2, P1.3, P1.4) — all approved or fix-then-approved
  • Verify on claude --chrome walk that existing dev-state hubs still render identically (no runtime behavior change expected)
  • CI green on push

Known follow-ups (deferred to PR2 or later F-series slices)

  • Reviewer nit: generateDeterministicId name doesn't match implementation (UUID v4 is non-deterministic); rename to generateEntityId if the Important issue surfaces during PR2 review.
  • Reviewer nit: id: \snapshot-${Date.now()}`inProcessHubEvidencePanel.tsx:333— should reuse capturedtimestamp` variable. F3 will replace this surface entirely.
  • Reviewer nit: useEvidenceSourceSync.markSeen overwrites createdAt on every put — F3 normalization concern.
  • Pre-existing Math.random in packages/core/src/__tests__/stackDetection.test.ts — out of scope per feedback_fix_absorbed_violations_at_seam (file not touched in this PR).

🤖 Generated with ruflo

jukka-matti and others added 8 commits May 6, 2026 11:01
…) [P1.1]

Introduces packages/core/src/identity.ts with the EntityBase interface
(id, createdAt, deletedAt) and generateDeterministicId(), which delegates
to crypto.randomUUID and throws on unsupported runtimes instead of
falling back to Math.random.

Sweeps both Math.random generateId instances per plan decision D-P3 /
audit R11: packages/core/src/findings/factories.ts now re-exports
generateDeterministicId as generateId (preserving all external call
sites) and uses it internally; apps/azure/src/lib/persistence.ts drops
its local generateId in favour of the canonical import from
@variscout/core/identity.

Also fixes pre-existing toFixed violations in createFactorFinding
(feedback_fix_absorbed_violations_at_seam): guards with Number.isFinite
before each .toFixed() call. Four new Vitest tests cover UUID format,
uniqueness, throw-on-missing-crypto, and EntityBase runtime shape.
Test count: 3226 -> 3230.

Co-Authored-By: ruflo <ruv@ruv.net>
…Base [P1.2]

Extends ProcessHub, OutcomeSpec, and ProcessHubInvestigation to implement
EntityBase (id, createdAt: number, deletedAt: number | null) per audit R1/R7.
Renames ProcessHubInvestigation.modified → updatedAt (number). Converts
ProcessHub.createdAt/updatedAt and latestActivity fields across rollup/review/
cadence types from ISO strings to Unix ms numbers. Sweeps all downstream
consumers in @variscout/ui, @variscout/azure-app, and @variscout/pwa; all
3230+1604+1042+189 tests pass and all four tsc builds are clean.

Co-Authored-By: ruflo <ruv@ruv.net>
…on [P1.3]

EvidenceSource, EvidenceSnapshot, RowProvenanceTag, and SnapshotProvenance all
extended to EntityBase (id, createdAt: number, deletedAt: number|null). All
ISO-string timestamps (createdAt, updatedAt, importedAt, lastSeenAt) converted
to Unix ms numbers.

RowProvenanceTag substantive shape change per R8: adds snapshotId FK,
rowKey (was the Map's composite key), plus EntityBase fields. Sidecar
Map<rowKey, RowProvenanceTag> preserved as runtime index. Both paste wedges
(useEditorDataFlow, usePasteImportFlow) updated to populate all required fields;
snapshotId='' is the placeholder until F3 wires snapshot-creation.

EvidenceSourceCursor relocated from apps/azure/src/db/schema.ts to
packages/core/src/evidenceSources.ts per R4. lastSeenAt: string → number.
Azure schema now re-exports the type from @variscout/core; Dexie composite key
[hubId+sourceId] is unchanged.

EvidenceSnapshot.importedAt + createdAt: kept both fields (importedAt is the
domain name from ADR-077 D6; createdAt is EntityBase lifecycle). Same value
at creation. Avoids renaming churn across ADR + tests.

Consumer sweep: ProcessHubEvidencePanel nowMs(), 12 azure test files, 3 pwa
test files, SnapshotTimelineStrip test, provenance tests. ADR-077 amended
with Amendment — 2026-05-06 block per convention.

Co-Authored-By: ruflo <ruv@ruv.net>
- Adds EntityBase lifecycle fields (id, createdAt: number, deletedAt: number|null)
  to Finding, Question, SuspectedCause, CausalLink, FindingComment, ActionItem,
  ImprovementIdea, InvestigationCategory, and related types.
- Converts all ISO-string createdAt/updatedAt fields to Unix ms (number) atomically.
- Renames CausalLink.hubId → suspectedCauseId (R5) — the FK pointed at SuspectedCause,
  not ProcessHub.
- Adds FindingComment.parentId + parentKind discriminator for polymorphic parent.
- Adds investigationId FK to Finding, Question, and SuspectedCause.
- Sweeps all consumers: stores, hooks, ui, charts, azure-app, pwa — 8338 tests green.
- Fixes pre-existing .toFixed() violation in useJournalEntries (replaced with formatStatistic).

Co-Authored-By: ruflo <ruv@ruv.net>
Backfill `investigationId` + `deletedAt` on all test fixtures across
`@variscout/core`, `@variscout/hooks`, and `@variscout/stores` that
reference the domain entity types (`Finding`, `Question`,
`SuspectedCause`, `FindingComment`, `InvestigationCategory`,
`ActionItem`, `PhotoAttachment`, `OutcomeSpec`, `ProcessHubInvestigation`).

Hard `investigationId` required as 2nd arg in `createQuestion` factory;
all single-arg call-sites updated. All `Date.now()` / ISO timestamp
literals in VALUE positions replaced with deterministic `1714000000000`.
`FilterAction` missing fields (`id`, `source`, `timestamp`, `label`)
added. `SpecLimits` field names corrected to lowercase `lsl`/`usl`.
`parentKind` corrected to camelCase `'finding'`/`'suspectedCause'`.

Logs `'general-unassigned'` investigationId placeholder pattern as
architectural debt in `docs/investigations.md`.

All packages: zero new tsc errors; full monorepo test suite green.

Co-Authored-By: ruflo <ruv@ruv.net>
….4b]

SustainmentRecord, SustainmentReview, and ControlHandoff now extend EntityBase
(id, createdAt: number, deletedAt: number | null). tombstoneAt is fully removed;
all 20 call-sites updated to deletedAt !== null soft-delete semantics. ControlHandoff
recordedAt renamed to createdAt (EntityBase). Dexie Version 9 added to rename the
indexed column. All 3230 core + 1042 azure tests pass, @variscout/ui build clean.

Co-Authored-By: ruflo <ruv@ruv.net>
ProcessMapNode.parentStepId, ProcessMapArrow.fromStepId/toStepId,
ProcessMapTributary.stepId, and ProcessMapHunch.tributaryId/stepId
retyped from plain `string` to `ProcessMapNode['id']` /
`ProcessMapTributary['id']` per R6 typed-FK audit.

ProcessMap interface itself is unchanged — per spec D3 the canvas state
is a 1:1 single-row schema embedded in the hub blob; no surrogate id
at the map level and no EntityBase extension (that is F3 territory).

3230 core tests + 261 store tests pass; UI, PWA, and Azure-app builds
all clean; no consumer fixtures required adjustment (string aliases are
transparent at runtime).

Co-Authored-By: ruflo <ruv@ruv.net>
… cascadeRules [P2.1-P2.5]

Adds the action surface (packages/core/src/actions/) and persistence
surface (packages/core/src/persistence/) to @variscout/core.

- 10 action sub-unions (outcome/evidence/evidenceSource/investigation/
  finding/question/causalLink/suspectedCause/hubMeta/canvas), each in
  their own file under actions/.
- HubAction top-level discriminated union; discriminator is `kind` with
  SCREAMING_SNAKE_CASE values per plan R2 (matching the existing canvas
  convention at core/canvas/types.ts).
- canvasActions.ts re-exports CanvasAction from canvas/types.ts as-is;
  no redefinition (R2: canvas was the source-of-truth).
- HubRepository interface in persistence/HubRepository.ts with single
  dispatch(action) write path + 10 grouped read APIs per D-P1.
- cascadeRules data + transitiveCascade BFS helper covering 12 EntityKinds
  (hub/outcome/evidenceSnapshot/rowProvenance/evidenceSource/
  evidenceSourceCursor/investigation/finding/question/causalLink/
  suspectedCause/canvasState) per spec D4/D6.
- Exhaustiveness test in actions/__tests__/exhaustiveness.test.ts ensures
  every action kind literal has a TypeScript-level case branch.
- ./actions and ./persistence sub-path exports added to package.json.
- Root barrel (src/index.ts) re-exports HubAction, all 10 sub-unions,
  HubRepository, EntityKind, cascadeRules, transitiveCascade.
- No implementation classes (PwaHubRepository/AzureHubRepository) — those
  are PR2/PR3 territory. P2 is interfaces + types only.

Tests: 3241 pass (baseline 3230 + 11 new: 1 exhaustiveness + 10 cascade).
Build: full monorepo build green.

Refs: spec D4/D6, plan tasks P2.1-P2.5, locked decision D-P1.

Co-Authored-By: ruflo <ruv@ruv.net>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
mean-beoynd-lite-pwa Ready Ready Preview, Comment May 6, 2026 0:02am
variscout_website Ready Ready Preview, Comment May 6, 2026 0:02am

jukka-matti added a commit that referenced this pull request May 6, 2026
Plan updated with Session 1 status block: 8 commits landed across
P0+P1.1-P1.5+P1.4 fix+P1.4b+P2.1-P2.5; PR1 opened at #130 awaiting
CI/merge. Resume point + watchlist items captured for fresh Session 2
to start PR2 (PWA repository + composition migration).

Co-Authored-By: ruflo <ruv@ruv.net>
@jukka-matti jukka-matti merged commit d2822ea into main May 6, 2026
3 checks passed
@jukka-matti jukka-matti deleted the data-flow-foundation-f1-f2 branch May 6, 2026 12:08
jukka-matti added a commit that referenced this pull request May 6, 2026
PR3 (Azure repository + ESLint guard) merged at 2490fc8, completing
F1+F2 across all three squash commits on origin/main:
- d2822ea PR #130 (F1 types)
- 7fc1a36 PR #131 (F2 PWA)
- 2490fc8 PR #132 (F2 Azure + ESLint guard)

Plan updated with F1+F2 SHIPPED block + Session 3 closeout (P5-P8
delivered, plan-reality deltas, F-series forward, watchlist).
Original Session 2 closeout preserved as PR2 history.

Spec already flipped status: active → delivered as part of PR3 P8.2.

Co-Authored-By: ruflo <ruv@ruv.net>
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.

1 participant