LabKit MATLAB Workbench

guide

Documentation Architecture

This page defines how LabKit documentation is authored, organized, rendered, and validated. It is a maintainer reference; readers looking for an app or a MATLAB function should start at the documentation home.

Design Goals

LabKit documentation must support four distinct reading tasks:

The organization follows the successful division visible in MATLAB and Qt documentation: product and module landing pages orient the reader, task pages teach workflows, concept pages explain behavior, and one page per callable entity provides exact reference. A single long narrative must not try to serve all four purposes.

Source Tree

docs/ contains only author-maintained, human-readable documentation data:

docs/
  README.md
  getting-started/
  apps/
    <family>/README.md
    <family>/<app>/README.md
    <family>/<app>/<topic>.md
    <family>/history/
  framework/
    README.md
    <topic>.md
    history/
  libraries/
    <facade>/README.md
    <facade>/<topic>.md
    <facade>/history/
  reference/README.md
  development/
    build-apps/
    data-and-designs/
    maintain-and-release/
    tools/
      README.md
      <tool>.md
  history/README.md

Executable renderer code and synthetic-asset generators live under tools/docs/. Generated HTML, CSS, JavaScript, and search data live under site/. No executable .m file belongs under docs/, and no generated file under site/ is edited by hand.

Launcher documentation follows the user-facing app map under docs/apps/labkit-core/launcher/. Direct-call references for maintainer tools follow their development ownership under docs/development/tools/; executable implementations remain under the repository tools/ tree.

Page Types

Product landing page

The documentation home answers what LabKit is, who each major section is for, and where a reader should begin. It is a routing page, not a project history, launcher manual, or API dump.

Tutorial

A tutorial leads a new reader through one complete, successful result. It states prerequisites, sample/input expectations, ordered actions, the expected result, and the next relevant topic. Tutorials may teach one path and defer alternatives.

How-to guide

A how-to guide begins with a concrete goal and gives the shortest reliable procedure. It includes prerequisites, commands or actions, verification, and failure recovery. Background explanation is linked, not repeated.

App family page

A family page explains the shared experimental domain, compares sibling apps, shows how their files or outputs connect, and links the relevant reusable libraries. It must not contain detailed instructions for one app.

App manual

Every public app owns one manual at docs/apps/<family>/<app>/README.md. Its normal section order is:

  1. purpose and applicability;
  2. requirements and launch;
  3. supported inputs and file interpretation;
  4. a shortest successful workflow;
  5. controls and interaction modes;
  6. parameters, defaults, legal values, and units;
  7. calculations, algorithms, and scientific assumptions;
  8. outputs and result schemas;
  9. project state, autosave, recovery, and overwrite behavior;
  10. use without the GUI;
  11. errors, limitations, troubleshooting, related topics, and history.

Sections that genuinely do not apply may be omitted. Applicable information must not be hidden in an app catalog, family overview, changelog, or source comment. Complex apps add focused topic pages beside the manual rather than turning the manual into an unstructured notebook.

Framework module page

The framework landing page presents ownership and module relationships. Topic pages then document lifecycle, definition, callbacks, state transactions, busy behavior, file selection, persistence, layout, plotting, interactions, debugging, and extension rules. Each topic identifies:

Private runtime mechanics are explained only when necessary to understand a public behavior; private functions do not receive reference pages.

Library module page

Each labkit.* facade has a module landing page comparable to a MATLAB toolbox or Qt module page. It states scope, dependencies, data model, grouped public functions, common call sequences, numerical/scientific semantics, compatibility, errors, examples, and related apps. Exact per-function syntax is linked to generated reference pages.

Function reference page

Every public function has one generated page. The MATLAB help block immediately after its declaration is the only authoring source and documents, as applicable:

Function reference must not promise an overload, field, or default that the current implementation and tests do not support.

History record

History is component-owned. A record explains what changed, why it matters, compatibility, affected components, and validation evidence. It is not an instruction manual and must link to the current page that describes the final behavior. The global history page is only an index. The history record format requires a global positive-integer sequence; values are unique and contiguous, and a new record normally takes the previous maximum plus one. The renderer orders the timeline by descending sequence rather than inferring same-day order from a title, filename, filesystem timestamp, or Git checkout. Each rendered record ends with adjacent-record navigation: Previous change uses sequence - 1 and Next change uses sequence + 1. The first and last records show only the direction that exists.

Discovered Sources

The documentation model is assembled without a page registry or catalog JSON:

SourceAuthority
Markdown path and first headingPage identity, output route, title, navigation area, and reader-task branch.
labkit_launcher("list") plus docs/apps/<family>/<app>/README.mdPublic Apps, commands, owning folders, and App manuals.
Complete public MATLAB helpLibrary APIs and App-owned non-GUI APIs.
History record metadataChange identity, order, components, compatibility, and history associations.

Every non-history Markdown page under docs/ is published. README.md maps to its directory index; App manuals retain their established sibling HTML route. Missing titles, duplicate ids, duplicate outputs, missing App manuals, or ambiguous App ownership stop the build.

The top navigation selects a documentation area. The left sidebar then shows the current area's own hierarchy instead of repeating one flat site-wide list. Where a page has descendants, the sidebar uses labeled branches:

The first path segment selects the documentation area. Under framework/ and development/, the next directory names the sidebar branch, so moving a page also changes its ownership and navigation. App branches come from their family manual path, library branches come from facade directories, and history uses record sequence. A documentation area with no descendants remains a single page and does not render an empty artificial branch.

Markdown keeps standard relative links so source browsing works on GitHub. After moving pages, run:

maintainLabKitDocLinks(repoRoot, "Update", true)

The maintainer rewrites only uniquely identifiable moved targets. Its default read-only mode fails on unresolved or ambiguous links.

Authoring From Current Code

Documentation changes begin from the current implementation, not from old prose. For an app manual, inspect at least its entrypoint, runtime definition, workbench layout, state/options owner, input loader, output writer, public app-owned APIs, and focused tests. For a library, inspect its complete public surface and tests. Existing documentation and history may identify questions to investigate, but they are not evidence that a behavior still exists.

User-visible labels, defaults, supported file types, state fields, output columns, formulas, units, and error behavior must match their current code owners. If code and documentation disagree, resolve the product contract rather than documenting both as alternatives.

App manuals are reader-oriented product pages. Keep App-specific requirements, the shortest successful workflow, scientific semantics, outputs, recovery, limitations, and supported GUI-free APIs. Do not append implementation inventories or repeat framework contracts such as callback ownership, runtime lifecycle, hover-help coverage, source serialization, or layout binding. Document those contracts once under docs/framework/; link there only when a reader needs the shared behavior to use the App.

Public Function Help

A public function help block is part of the tested API. It states public call syntax, behavior, inputs, outputs, option fields, defaults, legal values, and errors or side effects where they matter. The documentation guardrail compares the names in the function signature with the Inputs and Outputs sections and requires option-bearing APIs to describe named fields. Generated API pages use this same help block, so the command-line help view and HTML reference do not have separate prose owners.

Code under an Example: heading is an executable contract. The test runner extracts that code from the function header and executes it in MATLAB. Use Typical Call: when a useful sketch depends on a user's data file, an existing app/session variable, or an interactive dialog. Such a sketch becomes an Example: only after it has self-contained synthetic setup and passes the example runner.

A self-contained MATLAB block in an app manual may be preceded by <!-- labkit-runnable-example -->. The documentation contract extracts and executes every marked block in a clean test setup. Mark only examples that use synthetic data, require no dialogs or user files, and avoid lasting file or UI side effects. Unmarked blocks may demonstrate a typical call with a user's own file, but every variable and placeholder must still be explained by the nearby text.

Cross-References

Use relative Markdown links between narrative sources. Link the first useful mention of an app, framework topic, library, or related guide. Function names use fully qualified MATLAB symbols so the renderer can link them to generated API pages.

Every app manual links its family, related apps, relevant libraries, public app APIs, and component history when records exist. Every library landing links representative apps. Related links should help the reader continue a task; they are not a list of every page sharing a keyword.

The renderer rejects unresolved local Markdown targets. External links remain ordinary HTTPS links and are not copied into the site.

tools/docs/renderLabKitDocs.m reads the structured model, renders all narrative and API pages, builds navigation and related links, and writes the static site to site/. The renderer uses MATLAB only and introduces no third-party runtime dependency.

Search is a generated static index containing titles, headings, descriptions, keywords, components, MATLAB symbols, and help text. It works from GitHub Pages and when site/index.html is opened directly from disk; it must not depend on a local web server or a fetch request.

Generated pages carry a generated-file marker. Regeneration builds a complete temporary tree, then synchronizes its files into site/: changed files are updated, obsolete files and empty directories are removed, and the canonical site/ directory itself is preserved. Keeping that root stable avoids numbered conflict copies when the repository is stored in a synchronized folder.

For direct MATLAB syntax, result fields, missing-output reconstruction, and consistency-check behavior, see Documentation Build Tools.

Build And Validate

Use the documentation build and consistency tasks listed in Testing. The build regenerates the tracked site; the consistency check renders independently and compares that result with site/. Project documentation tests additionally check page/output uniqueness, source and output existence, API coverage, local links, direct-file search, generated markers, and prohibited retired paths.

Before committing documentation work:

  1. review the Markdown diff for claims not backed by current code;
  2. regenerate site/;
  3. run the focused documentation guardrail;
  4. open representative app, module, API, history, and search pages;
  5. commit source and generated output together.