Behavioral state machines
The machines below describe the implemented build, exploration and inspection lifecycles. They coordinate through an immutable build identity and per-view request tokens. Occurrence mode remains deferred. Implementation progress and executed evidence are recorded in Project maturity; the accepted target contracts remain in Internal interfaces and model contract.
Editable source: architecture/diagrams/state-machine.drawio; adjacent SVG
is exported with Draw.io and published interactively.
Build lifecycle
Owners: Extension lifecycle and dir... (STV_SWE_DIRECTIVE), Graph adapter and indexes (STV_SWE_GRAPH), Rendered detail extraction (STV_SWE_DETAIL_BUILD) and Static bundle emission (STV_SWE_BUNDLE). Their component source and unit-test paths are listed in Software elements. Initial state is collected invocations; terminal states are finalized output or failed build. Hidden Needs and their incident edges never enter the snapshot. Published detail fragments are keyed and named by the full content hash; identical fragments share one asset. Manifests name the required revision explicitly. This naming change does not change build, exploration or inspection states or transitions. Copied host relationship wrappers lose hidden-target references; deliberately published prose and ordinary author links are preserved. Executable URL schemes are rejected, including active data URLs in replaced embeds; permitted data images remain static resources.
From / event |
Guard |
Action / destination |
Coverage |
|---|---|---|---|
Collection / directive |
At most 200 distinct seeds |
|
Register the RST entry point (STV_SWR_001), Report invalid invocation s... (STV_SWR_026); |
Collection / write-started |
HTML builder, valid model, visible seeds and portable original URLs |
|
Author and resolve embedded... (STV_SYS_001), Integrate the host data model (STV_SYS_002); |
Pending / build-finished |
No fatal exception; every local rendered Need exists |
|
Publish full rendered details (STV_SWR_015), Avoid runtime network loading (STV_SWR_017); |
Pending / extraction or write failure |
Missing page/body or filesystem error |
Raise SphinxError; pending marker remains, no finalized view is claimed. Existing content-addressed files remain immutable. |
Tolerate host broken traces (STV_SWR_027); |
Existing environment / purge or rebuild |
Document reread/deleted |
|
Use portable output URLs (STV_SWR_018); |
Exploration lifecycle
Owners: Exploration state engine (STV_SWE_STATE), Semantic rank layout (STV_SWE_LAYOUT) and Accessible view and viewport (STV_SWE_RENDER); see Software elements for component boundaries. Initial state contains all explicit seeds or the project root with its first five stakeholder entries. Only seeds or the open current project’s entry page are reachability roots. Remembered expansions of hidden descendants and inactive pages do not create visibility roots. The 200-node cap includes missing objects and the synthetic project root.
From / event |
Guard |
Action / destination |
Coverage |
|---|---|---|---|
Committed / toggle group or project root |
Available group; nonempty entries for root |
|
Initialize collapsed state (STV_SWR_003), Collapse relationship groups (STV_SWR_007), Compute seed-rooted visibility (STV_SWR_025); |
Committed / Previous or Next |
Root open; valid page index |
Save outgoing page’s expansions into candidate map; restore target page’s expansions; candidate state. |
Page stakeholder entry links (STV_SWR_052); project pages Node case |
Committed / confirmed exact Need or Project overview |
Existing published non-hidden Need, or explicit overview action |
Propose fresh single-seed state or first open five-entry project page; clear candidate expansion/page memory. Invalid input leaves committed state unchanged. Typing and suggestion browsing do not dispatch a change. |
Confirm local interactive s... (STV_SWR_057); seed catalog/state and Firefox picker cases |
Candidate / capacity validation |
At most 200 visible nodes |
|
Enforce visible occurrence ... (STV_SWR_043), Reject over-limit transitio... (STV_SWR_044); capacity Node case |
Laying out / successful completion |
Current request token; valid finite nonoverlapping geometry |
Commit scene, page and expansion state together; close hover details; retain persistent boxes; restore focus without scrolling; commit the matching geometry snapshot; committed state. Preserve the current control within the view; fall back to the initiating surviving control if its focused descendant disappears. A late completion does not pull focus back after the user has moved outside that view. Seed/overview replacement resets only that view’s viewport and retains picker focus; a late prior request cannot restore old exploration. |
Render fixed node summaries (STV_SWR_008), Honor resolved declared lev... (STV_SWR_037); layout Node case and browser case |
Laying out / stale completion |
Newer request exists |
Discard geometry; remove staged measurement elements; newer request owns state. |
Reject over-limit transitio... (STV_SWR_044); |
Laying out / failure |
Solver or geometry error |
Preserve committed scene and state; announce failure. On first layout, retain starting summaries; expose Retry. Retry reuses committed state. |
Reject over-limit transitio... (STV_SWR_044); |
Committed / zoom or pan |
Within view; pointer background or toolbar control |
D3 transforms edges and nodes together; exploration state unchanged; dismiss details. Focus navigation pans off-screen controls into view. Initial layout and Reset align the first occupied band with the viewport; native focus scrolling is folded into the same D3 transform. |
Scope state to view roots (STV_SWR_038), Implement view-local zoom (STV_SWR_039), Implement view-local pan (STV_SWR_040); browser cases |
Fresh layout computes collision-aware parent centers; edge-free ordinary rows use natural ID ordering. Group/root commands supply committed geometry and an activated anchor, then preserve surviving slots and open vertical space only where required. Final routes are computed after placement and the SVG covers negative extents. Failed/stale completions do not replace the snapshot; viewport Reset does not relayout. See Center parent boxes with co... (STV_SWR_056), Stabilize committed navigat... (STV_SWR_058), Render complete edge bounds... (STV_SWR_059), Use natural ID order for fr... (STV_SWR_060) and STV_ADR_008: Stable navigation after fresh placement. No states, guards, events, timers or transition topology change; this refines the existing layout/commit actions. The adjacent Draw.io/SVG topology is unchanged.
Hover inspection lifecycle
Owner: frontend/src/inspect/inspect.js. Initial and terminal state is closed.
Each open increments a token; late fragment/position completions cannot insert
into a different inspection. Promises cache by build identity and Need ID.
The project root and missing targets never request details.
Escape cancellation is observed at document scope for each view: pointer hover
need not move keyboard focus into the view. Explicit Details activation cancels hover and opens/focuses the independent
persistent collection. Escape affects hover only.
From / event |
Guard |
Action / destination |
Coverage |
|---|---|---|---|
Closed / node hover |
Resolved real Need |
Start one 1000 ms timer; hover pending. Entering its Details button retains the timer. |
Separate transient hover an... (STV_SWR_050); |
Hover pending / departure, Escape, scene commit or viewport change |
Timer pending |
Cancel timer; closed, no panel or detail load. |
Separate transient hover an... (STV_SWR_050); |
Hover pending / 1000 ms elapsed |
Same connected trigger, no cancellation |
Open details; loading state. |
Separate transient hover an... (STV_SWR_050); |
Closed, pending or open / explicit Details activation |
Resolved Need; separate collection |
Cancel hover; persistent manager opens/focuses its box immediately. |
Own a per-view persistent d... (STV_SWR_063); persistent details browser cases |
Loading / script registered |
Current inspection token |
Rebase URLs, namespace IDs and IDREFs, insert static host fragment; open state. Local resource scripts require no fetch or service. |
Publish full rendered details (STV_SWR_015), Avoid runtime network loading (STV_SWR_017), Use portable output URLs (STV_SWR_018); detail and browser cases |
Loading / asset failure |
Current token |
Show explicit local-asset error; error state. Failed script requests are evicted from cache for retry on next open. |
Constrain and retain detail... (STV_SWR_033); |
Loading, open or error / Escape or Close |
Panel exists |
|
Provide keyboard interaction (STV_SWR_034), Separate transient hover an... (STV_SWR_050); browser case |
Loading, open or error / pointer departure |
Grace period elapsed; neither panel nor trigger hovered/focused |
|
Constrain and retain detail... (STV_SWR_033); |
Loading, open or error / new object, scene commit, pan or zoom |
New inspection or changed scene |
Close previous panel, invalidate async completion, release listeners; closed or new loading state. |
Scope state to view roots (STV_SWR_038); browser cases |
Source entry points
Lifecycle:
src/sphinx_traceability_view/directive/lifecycle.pyDirective:
src/sphinx_traceability_view/directive/directives.pyGraph:
src/sphinx_traceability_view/graph/__init__.pyDetail extraction:
src/sphinx_traceability_view/detail_build/__init__.pyBundle emission:
src/sphinx_traceability_view/bundle/__init__.pyExploration state:
frontend/src/state/state.jsLayout:
frontend/src/layout/layout.jsView and async commit:
frontend/src/render/view.jsInspection:
frontend/src/inspect/inspect.js
Transition tables distinguish code behavior from executed verification. A linked requirement or test source is not itself a passing result; consult the coverage and release execution records from Project maturity.
Build-time placement classification
At write-started, MODEL validates configured selectors before GRAPH resolves fixed/tag owners and one-hop execution placement. Invalid model configuration uses the existing build-failed transition; unclassified data uses the configured fallback row, or the same failed transition if fallback is absent. The immutable snapshot contains resolved levels. Browser expansions do not reclassify it. All existing layout/capacity/stale/failure commit transitions remain unchanged. Owners and criteria: Host model normalization (STV_SWE_MODEL), Graph adapter and indexes (STV_SWE_GRAPH), Resolve configurable per-ob... (STV_SWR_061); tests Validate classified placeme... (STV_TC_SW_046), Resolve stable classificati... (STV_TC_SW_047), Published nine-row evidence... (STV_TC_SY_061). Source: model/__init__.py and graph/__init__.py under src/sphinx_traceability_view. The diagram refines the snapshot action only.
Viewport boundary presentation
The clipping separator is CSS on the viewport container, outside the D3 scene.
It follows normal document flow during resizing and stays fixed as existing
pan/zoom transitions move the scene. No event, guard, action, ownership, timer or
transition changes; the Draw.io/SVG state topology remains unchanged.
Source: frontend/src/render/stv.css; Mark the viewport clipping ... (STV_SWR_062),
Visible viewport boundary d... (STV_TC_SY_062). This presentation-only increment needs no diagram edits.
Persistent inspection lifecycle
Owner: frontend/src/inspect/persistent.js and collection.js; renderer
owns the dock/control wiring. Initial collection is empty; it is page-local and
independent per view. Entry state is loading, ready/error or removed. Hover’s
timer/token/position listeners are not collection state.
Event / guard |
Owner |
Action and destination |
|---|---|---|
Details / ID already open |
Collection/inspector |
Focus and reveal existing Close; keep age and content; active collection. |
Details / new ID, capacity available |
Inspector |
Append fresh entry, loading body and focus; active collection. |
Details / new ID, full |
Collection/inspector |
Remove oldest live entry, append new entry; focus new Close. Old async completion cannot insert because its entry identity is no longer live. |
Close / live entry |
Inspector |
Remove only this entry; focus fresh node trigger or Close all if absent. |
Close all |
Renderer/inspector |
Clear this collection, invalidate all live entries; focus Close all; empty. |
Content completion / same live entry |
Inspector/content |
Restore safe unique-ID body, or explicit error; retain focus; ready/error. |
Late completion / entry removed or replaced |
Inspector |
Ignore; do not insert, revive or focus any panel. |
Graph commit, seed/overview/page, pan/zoom or Escape |
Renderer |
Close/cancel hover only; persistent collection stays unchanged. Commits refresh associations with newly rendered Details triggers. |
Document navigation/reload / pagehide |
Renderer/browser document |
Clear entries without restoring focus, including back-forward cache suspension; late completions are ignored. Unload discards page-local state. |
Coverage: Ordered detail collection c... (STV_TC_SW_049), Persistent limit configurat... (STV_TC_SW_050), Persistent details across n... (STV_TC_SY_063), Persistent loading cancella... (STV_TC_SY_064). Source contracts: Own a per-view persistent d... (STV_SWR_063), Present and focus persisten... (STV_SWR_064), Validate and publish the pe... (STV_SWR_065) and STV_ADR_010: Separate persistent details from hover inspection.
Copied metadata disclosure
Owner: initializeMetadata in frontend/src/inspect/content.js. Every new
hover or persistent fragment starts folded. State is per copied Need table,
independent from collection order, hover cancellation and other copies. Box reuse
keeps this DOM and its current disclosure state; removal discards the handlers.
State/event |
Guard |
Action/destination |
|---|---|---|
New restored fragment |
Control has matching rows in its own Need table |
Assign unique IDs/ARIA; hide metadata, show right arrow; folded. |
Folded / click, Enter or Space |
Owned control |
Show only this table’s metadata, show down arrow, expanded=true; expanded. |
Expanded / click, Enter or Space |
Owned control |
Hide only this table’s metadata, show right arrow, expanded=false; folded. |
Box reuse |
Existing entry |
Keep disclosure state and focus the box’s Close control. |
Fragment removal |
Hover closes or persistent entry is removed |
Discard DOM/handlers; a later new fragment starts folded. |
No matching rows means no actionable arrow is published. Header artifact-ID navigation uses its source URL and opens a new tab; ordinary copied-body fragment navigation remains local. Source: Present and focus persisten... (STV_SWR_064), Open canonical object links (STV_SWR_016); rendered verification: Readable details, metadata ... (STV_TC_SY_065).
Collapse-all and export commands
Collapse-all is an atomic STATE transition from any committed shared exploration state to initial (current roots), clearing every expanded group and page cache. Project mode restores page zero and its initial entry group. A new revision invalidates old layout generations; successful fresh layout commits/fits, failure retains the last committed presentation for retry. Persistent collection state is orthogonal and unchanged. This command does not enable deferred occurrence mode.
Export has per-view idle -> captured -> serializing -> download-requested -> idle states, with capture/resource/serialization failure returning to idle with a readable error. Pointer cancellation before activation discards its snapshot. No export state writes exploration or collection state. A separate URL-lease registry survives a completed request until cleanup expiry/pagehide; browser completion/cancellation is not observable as a product success state. Page-wide metadata commands have no graph-state transition. See Internal interfaces and model contract.
Diagram source: architecture/diagrams/export-lifecycle.drawio. EXPORT owns
capture/serialization/download; RENDER owns activation and readable status.
Trigger / guard |
Owner / source |
Action / resulting state |
|---|---|---|
Collapse all nodes |
STATE transition(), RENDER update() |
initial(current roots), clear page caches, revision increment; fresh layout and fit commit together, retaining persistent details. Failure retains the previous scene; Retry layout repeats the rejected command. |
Primary pointerdown / committed layout and ready resources |
render/view.js, export/snapshot.js capture() |
Freeze detached presentation with crop/styles/scroll and selected resources. Empty crop, loading fonts or missing images fail readably without download. |
Pointer cancellation, release outside or blur |
render/view.js |
Discard the pending snapshot. Keyboard activation always captures current presentation rather than reusing a cancelled pointer snapshot. |
Save activation / frozen or fresh capture |
export/snapshot.js serialize(), export/download.js saveSVG() |
Parse/serialize XML and request Blob download. Errors announce and release operation state; no graph/card mutation or false disk-save completion. |
URL lease expiry or pagehide |
export/download.js releaseDownloads() |
Revoke owned URLs; browser/OS retains responsibility for actual save/cancel. |
Page Expand all / Collapse all after host readiness |
render/page-metadata.js |
Normalize only original host metadata to the requested state; sync icons and ARIA. Preserve source body, individual controls and copied STV details. |
Source modules use the component paths in Software elements. Executable coverage is in Executable requirement coverage; developer verification is recorded centrally in Implementation criterion review and operating limits. These are implemented transitions, while occurrence-mode behavior retains its existing deferred scope.
Remembered view lifecycle
STATE owns snapshot validation/storage in frontend/src/state/persistence.js;
RENDER owns the mount/save gate in frontend/src/render/view.js. INSPECT reopens
ordered IDs without focus; LAYOUT checks dimensions/ranks before position reuse.
See Store opt-in snapshots inde... (STV_SWR_073), Validate and reconstruct re... (STV_SWR_074), Restore presentation withou... (STV_SWR_075).
State / trigger |
Guard, action and destination |
|---|---|
Startup / read |
No snapshot: Off. Valid snapshot: Restoring. Invalid/unavailable storage: ordinary startup plus accessible explanation. |
Restoring / layout completion |
Current request only; restore ordered cards without focus and apply saved transform, then enable saving. Unusable saved geometry retries fresh layout. |
Off / enable |
Save the committed view, enter On. Failure enters Storage error. |
On / graph or card commit, zoom end |
Save current committed state. Pending/failed/stale layout does not save. |
On or Storage error / disable |
Remove this key, keep live display; Off. Removal failure is announced. |
Storage error / next view change |
Retry saving; success returns On; failure retains usable live display. |
On / another tab saves |
No live transition. The next page load reads the last successful save. |
On / pagehide |
Remembering enabled: no empty-card write or clearing; back/forward cache remains usable. Disabled: ordinary card cleanup without saving. |
Snapshot validation cases are in frontend/src/state/tests/persistence.test.js;
real reload/control checks are in docs/test-scripts/test_remembered_view.py.
Validate and store remember... (STV_TC_SW_056) and Remember and restore a real... (STV_TC_SY_070) define criterion coverage.