Skip to content

docs(readme): add startup flow diagram - #15

Merged
JoergZeidler merged 6 commits into
omnect:mainfrom
JoergZeidler:docs/startup-flow-diagram
Jun 26, 2026
Merged

docs(readme): add startup flow diagram#15
JoergZeidler merged 6 commits into
omnect:mainfrom
JoergZeidler:docs/startup-flow-diagram

Conversation

@JoergZeidler

Copy link
Copy Markdown
Contributor

Summary

Adds a Mermaid flowchart to the README that traces every startup phase from PID 1 to switch_root, with inline release/debug branching at each error point.

Reason

The README described implemented features but gave no overview of how they connect at runtime. The diagram makes the startup sequence, degraded-boot split, and recovery policy visible at a glance.

Content

  • All 13 phases in execution order (early init → logger → config → core mount → boot env classification → first-boot detection → init_setup → mode dispatch → remaining mounts → overlays → switch_root)
  • Release vs debug error branches inline at each fatal failure point
  • FsckRequiresReboot always routing to Reboot regardless of image type
  • Degraded boot annotated on the APPLY → FBDETECT edge (ods.degraded_boot=true)
  • First-boot marker conditions summarized on the node
  • Color-coded terminal states (✅ success · 🔁 reboot · 🔴 halt · 🐚 debug shell)
  • Terminal-states legend table and prose note on the core_result capture invariant

Verification

Diagram syntax validated; renders correctly on GitHub.

Adds a Mermaid flowchart covering all startup phases from PID 1 to
switch_root, with inline release/debug branching at each error point.
Includes a terminal-states legend and a note on the apply_boot_env_decision
core_result capture invariant.

Signed-off-by: Joerg Zeidler <62105035+JoergZeidler@users.noreply.github.com>
@JoergZeidler
JoergZeidler requested a review from JanZachmann June 23, 2026 08:20

@JanZachmann JanZachmann left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The visual and doc look good. I expected some undefined flows but everything looks consistent. So is there something special I need to review or is this was last specs say?

@JoergZeidler

Copy link
Copy Markdown
Contributor Author

The visual and doc look good. I expected some undefined flows but everything looks consistent. So is there something special I need to review or is this was last specs say?

Imho, we haven't yet defined the behavior for how to handle certain situations. The README reflects the current status, and we may now have a basis for discussing changes to that behavior.

@JanZachmann JanZachmann left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: does the diagram match the specs and cover all paths?

Scope note: this is a docs-only change (one Mermaid diagram + tables). The code-focused review agents (silent-failure, type-design, test-coverage) don't apply — the relevant review for the stated goal is spec ↔ README ↔ impl traceability. I checked the diagram against src/ (main.rs, lib.rs, mode/normal.rs, init_setup/, filesystem/resize_data.rs, recovery.rs) and all 10 files in docs/superpowers/specs/.

Verdict: the diagram is an accurate, lightly-abstracted picture of the current code. Two things block the "spec and docs match and cover all paths" goal: (1) one region of the flow has no backing spec, and (2) two specs are stale/contradictory relative to what the diagram now shows. Inline comments mark the per-node items.

Coverage matrix (suggested gap-visualization format)

This is the table format you asked about — a traceability matrix is the clearest way to show "all paths covered" at a glance. Rows = flow phases; a row is only green when diagram, spec, and impl all agree.

Phase / node In diagram Backing spec Impl Status
Early init (MOUNT_ESS, EARLY_ERR) yes recovery-policy §2.5/§2.6 main.rs:33-45
Logger init yes recovery-policy §2.6(3) main.rs:50-62
Config/RDEV/LAYOUT/CORE yes boot-mode-dispatch, resize-data, preflight lib.rs:149-170
Boot-env classify/apply (degraded) yes degraded-boot-mode, degraded-boot lib.rs:179-182
First-boot detect + update_pending yes first-boot-detection, recovery-policy §2.5 lib.rs:184-192
init_setup / resize preflight yes (label issue) preflight, resize-data, fsck-and-resize init_setup/, resize_data.rs ⚠️ label + missing Fatal edge; specs #2/#4 stale on "resize fatal"
BootMode dispatch yes (no fail edge) boot-mode-dispatch, preflight lib.rs:205 ⚠️ minor
mount_remaining_partitions yes resize-data, boot-mode-dispatch normal.rs:51-57
Overlays / fs-links / ODS runtime (OVL,LINKS) yes none normal.rs:59-69 ❌ no spec
write_first_boot_marker (resize_ok gate) yes first-boot-detection, first-boot-retry normal.rs:74
switch_root yes mentioned only (endpoint) runtime::switch_root ⚠️ no design doc
Fatal handler (FEB) yes (Fatal branch only) recovery-policy main.rs:74, recovery.rs ✅ simplified

Legend: ✅ diagram = spec = impl · ⚠️ accurate but incomplete/abstracted · ❌ flow drawn, no spec.

Recommend keeping a trimmed version of this matrix in the README (or in a specs index) so the spec↔doc↔impl link is visible and stays maintained — that is what actually enforces "cover all paths" over time.

Spec-hygiene items (not visible in the diff, but block the goal)

  • Stale spec: 2026-05-12-first-boot-mode-design.md (BootMode::FirstBoot, mode::first_boot::run) is superseded by 2026-05-13-preflight-design.md. That flow exists in neither the diagram nor the code. Mark it superseded.
  • Contradiction: resize-data and preflight specs both state "resize failure is fatal". fsck-and-resize (#9) and first-boot-retry (#10) reclassify resize as ContinueDegraded (never fatal). The diagram (ISETUP non-fsck → BMODE, continue) and the code follow the latter — so the two earlier specs are stale and should be marked superseded, otherwise the spec set contradicts the README.

Not a gap (checked and ruled out)

Early-init error handling is spec-covered — recovery-policy §2.5 (early failure before boot env → not-pending → terminal) and §2.6 invariant 1 ("release never reaches Shell"). The diagram's EARLY_ERR release→halt / debug→emergency-sh split is exactly the fix that spec mandates.

Comment thread README.md Outdated
Comment thread README.md
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
Finding 1: ISETUP edge label was wrong — 'Other error → ContinueDegraded'
implied all non-reboot errors are absorbed. Only ResizeData errors are
absorbed by handle_result; non-ResizeData errors propagate as Fatal.
Relabelled edge and added missing ISETUP -->|Fatal (non-resize)| FEB edge.

Finding 3: FEB node understated its role. Renamed to 'Error handler /
RecoveryClass?' and expanded edges to show RebootToApply as a distinct
branch, making clear FsckRequiresReboot flows through this handler.
Added 'Notes on error handling' prose section.

Finding 4: persist_fsck_results was annotated only on FsckRequiresReboot
edges, implying it only runs on the reboot branch. Moved annotation to
the APPLY and MREM nodes where it actually runs (every mount path,
including degraded boot).

Finding 5: BMODE had no failure edge. Added BMODE -->|Fatal| FEB.

Signed-off-by: Joerg Zeidler <62105035+JoergZeidler@users.noreply.github.com>
The overlay, fs-link, and ODS setup steps have no dedicated design doc.
Added a prose note explaining this is a faithful port from the legacy
bash initramfs (fatal-on-fail matches the on_exit hook behaviour), with
the OTA rollback path added by the Rust rewrite.

Signed-off-by: Joerg Zeidler <62105035+JoergZeidler@users.noreply.github.com>
@JoergZeidler
JoergZeidler requested a review from JanZachmann June 24, 2026 04:40
@JanZachmann
JanZachmann force-pushed the docs/startup-flow-diagram branch from 8d771e4 to a703fbf Compare June 24, 2026 09:10

@JanZachmann JanZachmann left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New findings — still-open points

The five earlier threads are verified against the code (and, for the overlay block, against the legacy bash initramfs in meta-omnect) and resolved. These three points were raised in the original review summary but not addressed in the diff — filing them as discrete findings so they're tracked against the PR goal (spec ↔ README match, all paths covered).

Finding B — stale superseded spec (spec hygiene) · open

docs/superpowers/specs/2026-05-12-first-boot-mode-design.md designs BootMode::FirstBoot + mode::first_boot::run. That design is superseded by 2026-05-13-preflight-design.md, and the flow exists in neither the diagram nor the code. The spec should carry a Superseded by 2026-05-13-preflight-design.md header note (or be removed), otherwise the spec set documents a flow that no longer ships.

Finding C — spec contradicts shipped behaviour: "resize failure is fatal" · open

2026-05-04-resize-data-design.md and 2026-05-13-preflight-design.md both state resize failure is fatal. 2026-05-27-fsck-and-resize-design.md and 2026-06-22-first-boot-retry-on-resize-failure.md reclassify resize as ContinueDegraded (never fatal) — which the diagram (ISETUP non-fsck → BMODE) and the code (resize_data.rs::handle_result) follow. The two earlier specs directly contradict the README and the code; mark them superseded or update the claim.

Finding A — diagram: FsckRequiresReboot edges bypass the error handler · open

See the inline comment. Cosmetic + spec-alignment; not blocking.


Findings B and C are spec-file changes outside this PR's diff — they may be better tracked as a separate issue/PR if this one stays scoped to the README diagram.

Comment thread README.md Outdated
Finding B: 2026-05-12-first-boot-mode-design.md designed BootMode::FirstBoot
which was superseded before implementation. Added 'Status: Superseded by
2026-05-13-preflight-design.md' header and prose note.

Finding C: 2026-05-04-resize-data-design.md and 2026-05-13-preflight-design.md
both stated resize failure is fatal, contradicting the shipped ContinueDegraded
reclassification in 2026-05-27-fsck-and-resize-design.md. Added 'Status:
Partially superseded' headers referencing the correcting documents, and an
inline annotation on the specific table row in preflight-design.md.

Specs retained for design history.

Signed-off-by: Joerg Zeidler <62105035+JoergZeidler@users.noreply.github.com>
@JoergZeidler

Copy link
Copy Markdown
Contributor Author

Findings B and C — addressed in commit 0fd10f1.

Finding B: Added Status: Superseded by 2026-05-13-preflight-design.md header and a prose note to 2026-05-12-first-boot-mode-design.md clarifying that BootMode::FirstBoot / mode::first_boot::run were never shipped and that resize-data was implemented as a preflight step instead. Spec retained for design history.

Finding C: Added Status: Partially superseded header to both 2026-05-04-resize-data-design.md and 2026-05-13-preflight-design.md, referencing 2026-05-27-fsck-and-resize-design.md as the correcting document. Added an inline annotation directly on the contradicting table row in preflight-design.md so the conflict is visible at the point of reading. Specs retained for design history — removal is not preferred.

@JoergZeidler
JoergZeidler requested a review from JanZachmann June 24, 2026 11:07

@JanZachmann JanZachmann left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for one open item.

Finding A — diagram reroute not in the branch. The reply on that thread credits commit 8d771e4, but 8d771e4 was force-pushed away and is not in the history (head 0fd10f16's parent is a703fbf). The diagram at head still routes FsckRequiresReboot straight to REBOOT (L60/L65/L73) while FEB -->|RebootToApply| REBOOT (L88) has no incoming edge. Please re-apply the 4-line reroute documented in the Finding A thread so REBOOT is reached only through FEB (matches the code and recovery-policy §2.6 invariant 2).

Resolved and not blocking:

  • Findings 1–5 (diagram edges/labels, OVL/LINKS legacy annotation) — verified, threads resolved.
  • Finding B (stale 2026-05-12-first-boot-mode spec) — superseded header added in 0fd10f16.
  • Finding C (resize-fatal contradiction) — partially-superseded headers added in 0fd10f16.

Once the diagram edit lands, this is good to merge.

…l finding)

The FsckRequiresReboot edges from APPLY/ISETUP/MREM pointed straight at
REBOOT, bypassing FEB, while FEB carried an orphan RebootToApply branch
with no incoming edge. Redirect all three through FEB so the diagram
matches the code (every error reaches handle_fatal_error) and the
recovery-policy §2.6 invariant that the handler is the only reboot source.
REBOOT is now reached exclusively via FEB.

Signed-off-by: Jan Zachmann <50990105+JanZachmann@users.noreply.github.com>
@JoergZeidler
JoergZeidler requested a review from JanZachmann June 24, 2026 11:57

@JanZachmann JanZachmann left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All findings resolved. Finding A is now applied in 455e66aa — the three FsckRequiresReboot edges route through FEB, and REBOOT is reached only via FEB -->|RebootToApply (e.g. FsckRequiresReboot)| REBOOT, matching the code and recovery-policy §2.6 invariant 2.

Summary: diagram findings 1–5 fixed and verified; OVL/LINKS spec gap annotated (backed by the legacy bash initramfs); Finding B (stale 2026-05-12-first-boot-mode spec) and Finding C (resize-fatal contradiction) marked superseded in 0fd10f16. Diagram now matches the implementation; spec set is consistent with the README. Approving.

Comment thread README.md Outdated

@JanZachmann JanZachmann left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up: comment style — history-describing (non-evergreen) prose

One clear instance, one borderline. Flagging post-approval as a style nit — not re-blocking unless you want it fixed first.

  1. README OVL/LINKS note (inline below) — narrates the bash→Rust migration ("ported from the legacy bash initramfs", "The Rust port preserves this behaviour and adds…"). The README is a living doc; it should state the current contract, not the porting history. Evergreen rewrite in the inline comment.

  2. Spec status headers (0fd10f16) — borderline, I'd leave them. "Superseded by…" / "Partially superseded…" headers and the ← superseded: reclassified… table annotation are history by nature, but these are design-history documents where lifecycle metadata is conventional and stays true. If you want strict evergreen there too, replace the table annotation's narration with a plain corrected value (Resize failure → ContinueDegraded (non-fatal)).

The rest of the added prose ("Notes on error handling", "Notes on apply_boot_env_decision") is fine — current state and rationale, no history.

Minor: the "FsckRequiresReboot edges … flow through this handler — not via a separate mechanism" clause answers a past review point; trim the trailing clause and it reads as plain current-state.

Say the word and I'll convert this to REQUEST_CHANGES.

Comment thread README.md Outdated
@JanZachmann
JanZachmann self-requested a review June 25, 2026 11:24
Finding D: 'FEB' (diagram node label) appeared in prose at line 132;
replaced with 'the error handler'.

Finding E: OVL/LINKS note narrated bash→Rust migration history which
goes stale. Replaced with current-state contract: these steps abort
the boot on any failure, reaching handle_fatal_error.

Finding F: trimmed 'not via a separate mechanism' clause from the
FsckRequiresReboot note — it answered a past review comment rather
than describing current state.

Signed-off-by: Joerg Zeidler <62105035+JoergZeidler@users.noreply.github.com>
@JoergZeidler

Copy link
Copy Markdown
Contributor Author

Findings D, E, F addressed in commit 42cb4b5:

  • D: FEB in prose replaced with 'the error handler'
  • E: OVL/LINKS note rewritten as evergreen current-state contract (your suggested text)
  • F: 'not via a separate mechanism' clause trimmed from the FsckRequiresReboot note

Spec status headers left as-is — agreed these are conventional in design-history documents.

@JoergZeidler
JoergZeidler merged commit c48e94f into omnect:main Jun 26, 2026
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.

4 participants