chore(docs+devops): cross-module doc sync + sprint archival moves + compose updates
Bundled pre-session doc + ops work: - docs/modules/**: sync across advisory-ai, airgap, cli, excititor, export-center, findings-ledger, notifier, notify, platform, router, sbom-service, ui, web (architectural + operational updates) - docs/features/**: updates to checked excititor vex pipeline, developer workspace, quick verify drawer - docs top-level: README, quickstart, API_CLI_REFERENCE, UI_GUIDE, code-of-conduct/TESTING_PRACTICES updates - docs/qa/feature-checks/: FLOW.md + excititor state update - docs/implplan/: remaining sprint updates + new Concelier source credentials sprint (SPRINT_20260422_003) - docs-archived/implplan/: 30 sprint archival moves (ElkSharp series, misc completed sprints) - devops/compose: .env + services compose + env example + router gateway config updates File-level granularity preserved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
69
docs/modules/workflow/slot-lattice.md
Normal file
69
docs/modules/workflow/slot-lattice.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# ElkSharp — Node Slot Lattice (per-kind port metadata)
|
||||
|
||||
> Status: Introduced by Sprint 20260420.013 (BK Phase A — port-slot lattice).
|
||||
> Consumers: `ElkOrthogonalRouter` (Sprint 16+), future `ElkBrandesKopfPlacement` (Sprint 14+).
|
||||
> Source: `src/__Libraries/StellaOps.ElkSharp/ElkNodeSlotLattice.cs`.
|
||||
|
||||
## What is the lattice?
|
||||
|
||||
For every `ElkNode.Kind` that the Stella Ops workflow engine emits, the
|
||||
lattice declares a fixed set of *slots* on the node's boundary. Each slot
|
||||
is a tuple `(face, fractionAlongFace, direction)` where:
|
||||
|
||||
- `face` — one of `NORTH`, `SOUTH`, `EAST`, `WEST`.
|
||||
- `fractionAlongFace` — `0.0 .. 1.0` position along the face.
|
||||
- `direction` — `IncomingOnly`, `OutgoingOnly`, or `Either`.
|
||||
|
||||
The lattice is **static per kind**. Slot counts, positions, and direction
|
||||
restrictions are hard-coded; no per-instance configuration. Unknown kinds
|
||||
fall through to the rectangular default.
|
||||
|
||||
## Per-kind declarations
|
||||
|
||||
| Kind | Faces & slots | Direction |
|
||||
|------|---------------|-----------|
|
||||
| `Start` | 1 slot on SOUTH, centred (0.5) | OutgoingOnly |
|
||||
| `End` | 1 slot on NORTH, centred (0.5) | IncomingOnly |
|
||||
| `Task`, `SetState`, `BusinessReference`, `TransportCall`, `ServiceCall`, `Timer`, `Repeat` | 3 slots each on E/W faces (0.25, 0.5, 0.75); 5 slots each on N/S faces (0.17, 0.33, 0.5, 0.67, 0.83) | Either |
|
||||
| `Decision` (diamond) | N tip (0.5) incoming; S tip (0.5) outgoing; E tip (0.5) and W tip (0.5) incoming-only | mixed (see column) |
|
||||
| `Fork`, `Join` (hexagon) | 2 slots per N face (0.25, 0.75); 2 slots per S face (0.25, 0.75); E/W closed | Either |
|
||||
| `Dummy` | point — 1 slot on every face at 0.5 | Either |
|
||||
|
||||
## API surface
|
||||
|
||||
```csharp
|
||||
// Fetch all declared slots for a kind.
|
||||
IReadOnlyList<ElkNodeSlot> ElkNodeSlotLattice.GetSlots(string kind);
|
||||
|
||||
// Resolve a slot to an absolute (x, y) point on a positioned node.
|
||||
ElkPoint ElkNodeSlotLattice.ResolveSlotPoint(
|
||||
ElkPositionedNode node,
|
||||
ElkNodeSlot slot);
|
||||
|
||||
// Pick the best slot for an edge given its direction toward the other
|
||||
// endpoint. Respects direction restrictions (IncomingOnly vs OutgoingOnly).
|
||||
ElkNodeSlot? ElkNodeSlotLattice.ResolveSlotForEdge(
|
||||
ElkPositionedNode node,
|
||||
ElkPoint edgeDirection,
|
||||
bool isIncoming);
|
||||
```
|
||||
|
||||
## Consumer contract
|
||||
|
||||
- `ElkOrthogonalRouter.TryRoute` uses `ResolveSlotForEdge` to pick exit/entry
|
||||
slots on the source and target's primary-end / primary-start faces.
|
||||
- When the lattice returns no admissible slot, callers fall back to the
|
||||
legacy face-centre heuristic.
|
||||
- Multiple edges landing on the same slot are expected: the router's per-group
|
||||
spread heuristic spaces them apart.
|
||||
|
||||
## Design notes
|
||||
|
||||
- Slot sets are the *minimum* viable count for the current workflow set.
|
||||
Denser faces can be added without breaking the contract (the lattice API
|
||||
is additive).
|
||||
- Direction restrictions on `Decision` tips encode the flow-control semantics
|
||||
of diamond gateways: the south tip is the sole outgoing anchor so the
|
||||
downstream branches radiate from a single point.
|
||||
- `Fork` / `Join` use 2-slot N/S faces because parallel/merge branches are
|
||||
inherently binary-clustered in Stella Ops workflow semantics.
|
||||
Reference in New Issue
Block a user