markharness

0038: The GUI is an independent project, and markharness gui only launches it

Status

Accepted (decided 2026-10-02). Not implemented. It keeps the policies of 0022 (no UI bundled into the core) and 0032 (the CLI’s JSON is the external contract) and decides how to build a GUI on top of them.

Background

Test knowledge in markharness has relationships among Requirements, Features, Behaviors, Scenarios, and TestCases. When people edit YAML directly, they must understand the related elements and the effects of a change, then preserve consistency while handling UIDs and file locations. This burden can discourage even small additions, as well as larger changes, and make it harder to keep test knowledge current.

The CLI outputs these relationships, Change Impact, and Release Coverage as JSON. The GUI is intended to let people follow the relationships, select what to change, edit test knowledge in that context, and check the resulting relationships. It also lets people who do not use a terminal (including non-developers) do this work on screen. A viewing-only stage is allowed during development, but it still sends people back to YAML to make changes; the GUI is therefore bundled into the markharness distribution only once it can edit. This record decides in what form the GUI is provided.

0022 removed the dashboard that was bundled into the core because it meant “permanently bearing the maintenance cost of a UI that does not serve the MVP’s thesis.” 0032 made the JSON of traceability, impact, and coverage an external contract and left display to a separate tool.

The precedent is git gui. The official Git manual says git-gui is maintained as an independent project and that its stable releases are distributed as part of Git. It is launched by the subcommand git gui, which finds and runs a separate executable, git-gui. git-gui uses Git by calling the git CLI as a child process, and its implementation language is independent of Git itself.

Decision

1. The GUI is a project independent of the core

The GUI is built in a separate repository (markharness-gui) as a separate executable (markharness-gui). Its implementation technology, screen design, and internal structure are decided by the GUI repository; the core does not assume them. The core holds no HTTP server, frontend assets, or browser-launching code.

2. The only point of contact with the core is the JSON the CLI outputs

The GUI calls markharness as a child process from outside and reads only its JSON output. It does not read the internal files under .markharness/ directly, and it does not call the core’s Rust library directly.

The viewing-only intermediate stage uses only the existing read outputs: traceability (with --at omitted, so the working tree), binding list, coverage, and impact. Detail fields such as axes, descriptions, and steps are not in the existing output. To show them, which editing needs, first add a read output to the CLI and have the GUI read that output (decision 10). axes list is not used in this intermediate stage. It returns only a list of axis definitions (id and label), and traceability returns no per-element axis, so the screen has nothing to attach the list to. Its output is also a bare array with neither record_kind nor schema_version, so decision 5’s check of the record kind cannot apply to it.

3. markharness gui only launches

markharness gui [--dir <path>]

4. Distribution keeps the CLI-only archive unchanged and adds a separate GUI-bundled archive

So that people who use only the CLI (CI, AI) do not get a larger download for the GUI, the current CLI-only archive stays as it is. A separate GUI-bundled archive is built with markharness and markharness-gui in the same directory. The GUI artifact is the stable release published by the GUI repository, pinned and pulled in when markharness is released. The stable release pulled in is limited, as decision 10 says, to one that can edit test knowledge. Running markharness gui from a CLI-only distribution gives the “not bundled” error of decision 3.

5. Version compatibility is decided by schema_version; during 0.x it does not change, so the bundled combination is trusted

The GUI checks that the record_kind of the JSON it receives is the kind it expects and that its schema_version is a version the GUI supports, and stops displaying if not. It shows the supported version and the received version, guides the user to update, and does not show partial results. Showing wrong relations does more harm than stopping. The GUI treats a rise in schema_version as the signal of a change that requires it to read differently. Which changes raise it is decided by the core, as 0039 says.

The GUI reads only the fields it needs, and ignores unknown keys added to existing objects and unknown new arrays, because such additions do not make the relations within the range the GUI displays wrong. On the other hand, when a value the GUI does not know appears in a set of values whose meaning the GUI interprets (such as the kind of a relation, the source of a Requirement, or the mode of a binding), it does not silently drop that element but stops displaying, as an unsupported version. It stops in the same way when a field it needs is missing. This detects a case where schema_version is the same but a field that was added is absent from an older markharness, and a case where a newer markharness emits a new value. That no partial results are shown applies to these cases where the GUI stops.

However, by 0026 decision 7 and 0039, the schema_version of public JSON is fixed at 1 during 0.x and is not raised even when the shape of an output changes. During that time the schema_version check cannot detect a compatibility change (only a missing required field can be detected). So during 0.x the bundled combination is trusted: the GUI calls only the markharness of the same distribution (decision 3), and the GUI’s stable release is pinned to the markharness release it is bundled with (decision 4). As a result, when the GUI is started on its own and uses a markharness of a different version, a difference in the shape of an output cannot be detected.

The criterion for raising schema_version is decided when the criteria for 1.0 are met, as 0039 says. Once schema_version is actually raised, the GUI’s check works as a compatibility judgment without any change to the GUI.

6. The CLI’s error format is not unified

The GUI treats a non-zero exit code as failure and shows the standard-error text as it is. Some commands report errors as JSON and others as plain text, but there is no concrete case yet where the GUI needs to branch mechanically, so it is not unified.

7. The GUI runs strictdoc export to get StrictDoc display information

For a Requirement with source: external, traceability returns only up to source_key; it does not include the requirement’s title or hierarchy. To show them, the GUI runs strictdoc export --formats=json and reads that JSON. This is an exception for the GUI alone, which keeps the policy that the core neither holds nor duplicates external content (0023) and the decision that the core does not run strictdoc (0036 decision 2). StrictDoc stays an optional integration; where it is absent, the GUI shows only markharness’s data.

The export takes time (see the measurements below). The GUI stores the export JSON as its basis and re-exports in the background only when the StrictDoc documents or configuration files are newer than that JSON. During this, it shows markharness’s data first. The core imposes only one constraint: never keep showing stale content. The user must have a way, which does not use the cache (a forced re-export), to get out of a stale display for sure. The storage location, the details of the check, and the in-progress display are decided by the GUI repository.

8. The display is refreshed by a manual refresh action

The GUI does not watch files. It re-fetches the JSON when the user refreshes. After the GUI itself writes (edits), it re-fetches automatically. Changes made outside the GUI are picked up by the refresh action.

9. Not covered at this time

10. The condition for bundling the GUI into the markharness distribution is that it can edit test knowledge

The GUI is responsible for both viewing and editing. A viewing-only version may exist as an intermediate stage of development in the GUI repository, but it is not bundled into the GUI-bundled archive. Bundling starts with a stable release that can edit test knowledge.

Editing goes only through knowledge reconcile, as §14.2 of the design document cli-read-model-design.md requires, and the GUI does not rewrite Knowledge files directly. The detail fields that an editing screen needs (axes, descriptions, steps, and so on) are, as decision 2 says, first added to the CLI as read outputs, and the GUI reads those outputs.

Scope of impact

Alternatives considered and not adopted

Reference: time taken by strictdoc export --formats=json

Measured on 2026-10-02 with strictdoc 0.30.1 on Windows. One environment and one real project only; not measured on Linux or macOS.

Target Requirements Default --no-parallelization
Synthetic data (simple requirements, 8 .sdoc files) 400 4.1 s 2.0 s
StrictDoc’s own whole repository (strictdoc export .) 358 20.6 s 18.6 s
A copy with only the same docs/ and spec/ 358 6.3 s 3.9 s

Open items (decided in the GUI repository)