MVP M4: SysML metamodel + validator + dependency graph + UI surfacing
apps/web/lib/sysml — pure engine (no UI deps) - model.ts: canonical types ported from phase-0 (Block, Property, Association, Constraint, Requirement, SysMLModel) - validate.ts: 12 rules grouped Structural (S1–S5) / Semantic (M1–M5) / Traceability (T1–T2). Pure function returning element-anchored issues. Cycle detection via DFS with canonical-key dedup. T3 deferred to Phase 1.5 (depends on narrative chip references). - depgraph.ts: directed graph over Blocks / Properties / Constraints / Requirements with `dependentsOf()` and `neighborhood()` for impact analysis (substrate for M7). - fromFixture.ts: loose FixtureData → strict SysMLModel converter (interim until M5 unifies state). - breaks.ts: 8 named model corruptions (S1/S2/S3/M2/M3/M5/T1/T2) for ?break=... demonstrations. UI integration in EditorShell + LeftRail + DiagramCanvas + IssuesPanel - Floating IssuesPanel (bottom-right) with severity-grouped counts and collapse. Click an issue to focus its anchor across the rail and diagram. - LeftRail: severity dots on each block in the Model section and on each requirement entry. Tooltips show full issue text. - DiagramCanvas: red/blue/dotted ring around offending blocks via issuesByElement → BlockNode.data.issueSeverity. - ?break=S1-dangling,M2-cycle,M5-dup-property,... query param injects corruptions for verification of the "done when" criterion. - Suspense boundary added at the editor route for useSearchParams. Two pre-existing TipTap typing fixes (editor.storage cast through unknown).
This commit is contained in:
75
apps/web/lib/sysml/model.ts
Normal file
75
apps/web/lib/sysml/model.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
// Canonical SysML metamodel types — adapted from phase-0/src/types.ts
|
||||
// (the Phase 0 validation that ran 10/10 against the corpus).
|
||||
//
|
||||
// See docs/sysml-modeling.md §6 for the design rationale and §3 for what we
|
||||
// deliberately don't model.
|
||||
|
||||
export type BlockKind = "block" | "actor" | "constraint" | "system";
|
||||
|
||||
export type PropertyType =
|
||||
| { kind: "string" }
|
||||
| { kind: "number" }
|
||||
| { kind: "boolean" }
|
||||
| { kind: "enum"; values: string[] };
|
||||
|
||||
export type Multiplicity = "0..1" | "1" | "0..*" | "1..*";
|
||||
|
||||
export interface Property {
|
||||
id: string;
|
||||
name: string;
|
||||
type: PropertyType;
|
||||
multiplicity: Multiplicity;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface Block {
|
||||
id: string;
|
||||
label: string;
|
||||
kind: BlockKind;
|
||||
stereotypes: string[];
|
||||
properties: Property[];
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export type AssociationKind =
|
||||
| "association"
|
||||
| "composition"
|
||||
| "aggregation"
|
||||
| "generalization"
|
||||
| "constraintApplies";
|
||||
|
||||
export interface Association {
|
||||
id: string;
|
||||
fromBlockId: string;
|
||||
toBlockId: string;
|
||||
label: string;
|
||||
kind: AssociationKind;
|
||||
multiplicity?: { from: Multiplicity; to: Multiplicity };
|
||||
}
|
||||
|
||||
export interface Constraint {
|
||||
id: string;
|
||||
label: string;
|
||||
expression: string;
|
||||
appliesTo: string[];
|
||||
}
|
||||
|
||||
export type RequirementRelation =
|
||||
| { kind: "satisfy"; blockId: string }
|
||||
| { kind: "derive"; fromReqId: string }
|
||||
| { kind: "verify"; experimentId: string };
|
||||
|
||||
export interface Requirement {
|
||||
id: string;
|
||||
tag: string;
|
||||
text: string;
|
||||
relations: RequirementRelation[];
|
||||
}
|
||||
|
||||
export interface SysMLModel {
|
||||
systemOfInterestId?: string;
|
||||
blocks: Block[];
|
||||
associations: Association[];
|
||||
constraints: Constraint[];
|
||||
requirements: Requirement[];
|
||||
}
|
||||
Reference in New Issue
Block a user