# CrisisResponse V2 — what changed vs V1, and why

> **V2 is the "SysML v2 philosophy" edition of the pilot model.** V1 stays untouched as the
> baseline; every difference below is deliberate. For the guided tour of the model itself, read
> [`CrisisResponse.md`](CrisisResponse.md). Newest changes at the bottom.

## The idea in one paragraph

V1 proved the tool renders every construct group; its modelling style, though, was still v1-ish —
bare ports, units smuggled into names (`latencyMs`), a requirement checking its own private copy of
a value, a `bind` that declared a goal met by definition, three disconnected "incident" ideas. V2
keeps the same system (same assets, same wiring, same packages) and rewrites those spots the way
SysML v2 wants them said: **things that travel are items, values have units, requirements read
their subject, analyses compute, one Incident ties the story together, and the variation point is
actually used.**

## V1 → V2, by theme

| Area | V1 | V2 | The v2 idea |
|---|---|---|---|
| **Items** (new `05_items`) | Nothing travelled — ports and messages were untyped names | Shared `SensorReading`, `DispatchOrder`, `AlertMessage`, `ArrivalReport` items, referenced by ports, flows, messages and action pins | Model the *things that move*, once, and let every carrier name them |
| **Ports** (`10_core`) | `port def SensorFeedPort;` (empty) | Each port declares its cargo: `port def SensorFeedPort { item reading : SensorReading; }` | A port is a window for something — say what |
| **Units** (`10_core`) | `attribute latencyMs : Real` | `attribute latency :> ISQ::duration = 0.15 [SI::s]` | Quantities carry units from the standard library, not name suffixes |
| **Requirement** (`30_requirements`) | The requirement held a private `actualDispatchSec` copy | The constraint reads its **subject**: `in actual = system.dispatchSec` (a new `CoordinationCenter.dispatchSec`) | A requirement watches the system, not its own notebook |
| **Satisfy** (root) | Type-level only (`satisfy … by CoordinationCenter`) | Adds the usage-level form: `satisfy requirement fastDispatch : ResponseTimeRequirement by primaryCenter` | *This* system's part satisfies it, in context (type-level examples kept in `30_requirements` for contrast) |
| **Parametric** (`60_analysis`) | `bind achievedPct = requiredPct` — the goal "met" by definition | The `ResilienceIndex` calc **computes** `achievedPct`, `bind` only names the value, `assert constraint` states the claim | Compute → name → claim; a bind is not a proof |
| **Incident** (`60_analysis`) | `occurrence def Incident;` (empty), unrelated to the rest | `Incident` names its `IncidentCategory` (Core), `HazardModel` (Domain) and responding `TaskForce` (Domain) | One hub concept instead of three disconnected "incident" ideas |
| **Individual** (`60_analysis`) | `individual def HurricaneZeta :> Incident;` (empty) | Own attribute values plus `snapshot landfall` and `timeslice responsePhase` | An individual is one real thing with its own history |
| **Variation** (`20_domain` + root) | `ResponseStrategy` existed but nothing used it | `CrisisSystem` carries `part strategy : ResponseStrategy`; two **configurations** (`UrbanFireResponseSystem`, `CoastalFloodResponseSystem`) resolve it via `part redefines strategy : …` | A menu is only a menu once someone orders — product-line modelling in its smallest form |
| **Views** (`80_views`) | Hand-kept view contents | `missionCritical` view uses `filter @Criticality` over new metadata tags | A view is a query, not a list |
| **Behavior** (`40_behavior`) | Untyped triggers/messages | `accept arrival : ArrivalReport`, `message telemetry of SensorReading`, typed action pins, a real `entry action` | Behavior carries data, and the data is the shared items |
| **Relations** (`90_relations`) | Generic labels | Relabelled as the ASysT connector legend | The package doubles as the viewer's own legend |

## What deliberately did **not** change

- The system's identity: the same command-centre concept and the same package layout (`05…90`) —
  V2 changes *how things are said*, not *what the system is*. (The asset list itself was later
  slimmed 9 → 7 — see the 2026-07-03 declutter below.)
- LSP-cleanliness: every file parses with **zero diagnostics** against the bundled parser, and the
  model graph renders with **zero warnings** (each risky grammar form was probe-tested first).
- V1: untouched, kept as the comparison baseline.

## 2026-07-03 — entry-view declutter (owner feedback)

The first V2 cut made the **entry diagram busier than V1** — the opposite of the intent. Three
changes brought it back to *complex, but not too much*:

1. **The two configurations moved out of the root** into `20_domain`, right beside the
   `ResponseStrategy` variation they resolve. The entry view is a **single-system diagram** again
   (V1 parity); the Domain package now tells the whole product-line story in one place.
2. **The doubled sensing line is one line again.** V2 had added `flow telemetry of SensorReading`
   *on top of* the existing `connection sensorLink` — two parallel edges between the same ports.
   The wire is a single `connection` again, and "what travels" is told where V2 already says it:
   the ports' `item` declarations and the typed `message telemetry of SensorReading`.
   *(Also a viewer honesty note: a part-internal `flow … from … to …` parses but is not drawn in
   the IBD yet — tracked as an engine gap. The connection form draws.)*
3. **`strategy` stays** as the one small extra box inside `CrisisSystem` — it is the variation
   point the configurations redefine, and the product-line thread needs it on the system.
4. **The asset list slimmed 9 → 7** (owner call: "nine is a lot — merge or remove 1–2"):
   - **`relayNodes` folded into the backbone.** The regional relays are communications plumbing,
     not a headline asset: `RegionalNode` is now the *internal structure* of
     `CommunicationBackbone` (`part relayNodes : RegionalNode[2..*]` — drill ⊕ into the backbone
     to see them). The centre now reaches the regions **through** the backbone
     (`connection cmdRegions`), which also fixes a V1 oddity where the backbone was never
     connected to the centre at all. Two lines became one.
   - **`scoutFleet` removed as a permanent part.** Drone reconnaissance was overlapping with
     `aerialUnits` as "the airborne box". `DroneFleet` (and its drones' internal structure) stays
     in Core, and drones remain selectable as the `droneLed` **strategy variant** — a drone fleet
     is a *choice*, not a fixture. `aerialUnits` is the one permanent airborne responder.

Net effect: the root package shows **one** system box (was three), and `CrisisSystem`'s internal
view is **7 assets + `strategy` with 6 connectors** (was 9 assets + 2 extra system boxes and
8 lines) — every remaining box earns its place, and the removed detail is one drill-in or one
package away, not deleted.

## 2026-07-06 — ports declare their data direction (owner: "nodeLink should be a double arrow")

Every port usage in `10_core` now carries its direction prefix — `in` (data arrives), `out` (data
leaves) or `inout` (both ways, drawn as ASysT's double-headed ↔ arrow):

| Direction | Ports |
|---|---|
| `in` | `sensorFeed`, `orders` (ground + aerial), `control`, `alertIn` |
| `out` | `dispatch`, `alerts`, `telemetryOut`, `imagery`, `imageryOut`, `downlink` |
| `inout` | **`nodeLink`** (the comms fabric: dispatches in from the centre, traffic out to the satellite relay), `relay` (the satellites' backup comms), `uplink`, `link` (drone mesh) |

The old `10_core` comment claimed directions were off the table because the parser rejects `~`
conjugation — probing showed the direction *prefix* is accepted fine (only `~` itself is rejected),
so the comment now says that. The model stays **0-diagnostic / 0-warning** (12 files).

## 2026-07-11 — the `missionDashboard` view (owner: "a view that combines BDD + state machine + activity + a selection of 6 reqs, in one well-organised picture")

`80_views/Views.sysml` gained **`missionDashboard : SituationView`** — the showcase of what a SysML v2
`view` can do that a v1 diagram never could: **mix element kinds**. It exposes the system with its
three satisfying parts (`CrisisSystem`, `CoordinationCenter`, `SensorNetwork`,
`CommunicationBackbone`), the whole incident lifecycle (`Behavior::IncidentLifecycleStateMachine::**`
— the qualified `::**` form exposes the FQN subtree), the coordination flow
(`Behavior::CoordinateResponse::**`) and all **six requirement defs** — so the «satisfy» traces draw
between the structure and the requirement catalogue on one board.

Its arranged layout lives in **`Rendering/missionDashboard.asystrendering`** (structure left,
requirements middle, lifecycle right, flow bottom; the `responding` state's nested substates are
deliberately unplaced so the board shows the top-level lifecycle). Export it headlessly:

```bash
./asyst.cmd export Demo/CrisisResponse_V2/Model/80_views/Views.sysml --view missionDashboard -o dashboard.svg
```

The model stays **0-diagnostic** (12 files). The figure is `_Docs/_Master_Doc/images/vision-mission-dashboard.svg`
(Vision doc §3).

## 2026-07-12 — PM8: a 10-file/300-element default pilot

The bundled pilot now contains **10 SysML files** and fits the Alpha/Free default tier of **10 files / 300
graph elements**. `60_analysis/Analysis.sysml` and `70_integration/Integration.sysml` were removed from the
starter because their advanced SysML v2 semantics had not been given an end-to-end real-LSP graph contract.

This is a scope decision, not a claim that those constructs are invalid SysML or that they are views. The
focused pilot's model-wide graph is 98 nodes / 70 edges with no license-truncation warning. The advanced
topics can return in a separate example once their expected nodes, edges and warnings are pinned.
