Back to Shift 1.0

Toolbox Web · Harness Documentation

How the Harness Was Built

View components

The rules, checks and harness that keep nxtg-react-components consistent, so people and agents can change it without drift. Everything below comes from the files in its harness/ folder.

25tasks, all passing
14decisions written down
0.3.1published, 2 releases
7files in harness/
Where the design comes from

From Toolbox’s app code to one package

Toolbox’s main branch is where the components were proven. They’re extracted into nxtg-react-components, which every product takes its UI from, with the rules that keep it on design beside it.

Toolbox’s app code

main branchthe source of truth

nxtg-react-components

tokens, componentstheme runtime: ikon, ikon-dark, Toolbox preset
v0.3.1decisions HD-001 … HD-014

For people

Storybook 10
a11y checks on every story
Visual Baseline
the visual reference
decisions.md
why each rule exists
contract tests fail CI if they disagree

For agents

AGENTS.md
the MUST rules
features.json
tasks and their checks
pnpm harness
the task lifecycle
Consumed byLot AuditSmart MarketingToolbox WebIkon KeyFinder
Behind the scenes

Who does what

Scripts check the rules. Agents do the work and review it. People write the tasks and decide what ships.

PeopleAgentsScripts
People
Agents
Scripts
PeopleWrite the taskfeatures.json: behavior, acceptance, allowed paths
AgentsMaker builds itharness start, then code, story, tests
ScriptsQuick checkharness check, tests, types
AgentsChecker reviewsharness review: scope and acceptance
PeopleSettle blocksthe reason is recorded
ScriptsVerifypnpm check, evidence stamped
PeopleMerge the PRCI runs pnpm check again
ScriptsPublishGitHub Packages, on main
One task at a time. Only verify can mark a task passing; nobody edits the status by hand.
Behind the scenes

How new components get in

Three ways in, all by hand today. Whatever the source, it becomes a task before any code changes.

Lifted out of ToolboxMIGRATION-001 to 003: foundation components, minus app logicDone, by hand
A consumer hits a gapLot Audit’s gap register: Avatar, tones, segmented TabsBy hand, per request
A product finds a bugMOBILE-001/002: phones zoomed into ComboBox and SelectBy hand, per report
Every change becomes a taskA features.json entry: behavior, acceptance, checks, allowed paths. A rule it sets goes in decisions.md.
Passingverify ran the gates; evidence is stamped
Blockedharness block, with its reason
Releasedversion bump, published on merge (RELEASE-001, 002)

The gap: nothing watches the products for new needs. Every one of the 25 tasks started because someone wrote it down.

What we’d automate next

Gap radar

Read each consumer’s gap register and draft the task, so a workaround in a product turns into a proposal here.

Visual regression

Screenshot every story and compare, so rendering drift like the Switch/Toggle fails CI the way token drift already does.

Release on passing

Bump the version when a release-worthy task passes, so a merge can’t skip publishing. RELEASE-002 exists because one did.

Every rule, three times

Written, required, tested

Each rule is written for people, required of agents and checked by a script.

People readdecisions.md · HD-009
  • Lot Audit is the default look: #319E83 green, Saira + JetBrains Mono, #FDFDFD surfaces, #e4e4e5 hairlines, a dark theme.
  • Ships as ikon / ikon-dark; Toolbox is an optional preset.
Agents readAGENTS.md · MUST
  • Use semantic token and variant names.
  • Never encode a product brand into a reusable component.
Scripts enforcevisual-style-contract.test.ts
✓ default theme is ikon
✓ --nui-color-accent is #319e83
✓ text, border and surface tokens match
✓ font is Saira
✓ ikon-dark covers the same tokens

A changed token turns CI red.

What stops drift

Four layers, softest to hardest

  • HD-001 … HD-014. Design: HD-009 baseline, HD-010 additions, HD-011 to HD-013 anatomy.
  • Each records why, and when to revisit.
Layer d, step by step

A task, from next to passing

Every task goes through the same six steps.

Step 1 of 6 · Select
$ pnpm harness next

Picks the next task.

Enforces: One task at a time.

Task status in features.json
pending→in progress→passing

Waiting in the list.

Behind the scenes

What “passing” leaves behind

Verify doesn’t just flip a status. It records what ran and fingerprints every file the task touched, so a later change can’t hide behind an old pass.

features.json · MODAL-001

Measure Modal against the Toolbox dialog

status
passing
run record
.harness/runs/2026-08-27T21-30-25-410Z-MODAL-001.json
commit
8cfbd54
command
pnpm check, exit 0, 12.3s
Files fingerprinted (sha256), 6 of 8 shown
src/components/Modal/Modal.tsx6a1eab5b…
src/test/modal-dialog-anatomy.test.tsx1b70852b…
src/components/Button/Button.tsxee2610a6…
src/components/ComboBox/ComboBox.tsx6e16420c…
src/theme.tsxa21b7bdf…
src/styles.css950ed6cd…
If src/theme.tsx is edited laterhash differs → stale

pnpm harness:check compares every fingerprint on every run. A mismatch reports the evidence as stale, and the task has to be verified again. That’s what RELEASE-002 fixed after a version bump skipped the flow.

The harness state

What’s in harness/

Versioned in Git, so any session picks up where the last one stopped.

▾harness/
harness/features.json

The task list, and the source of truth.

  • 25 tasks, all passing. Each has its behavior, acceptance criteria, the commands that verify it, the paths it may touch, its status history and its evidence.
  • Only pnpm harness verify can set a task to passing.
Known gap

The toggle

The Lot Audit and Smart Marketing toggles differ. The contract test covers tokens, not rendering.

What could driftChecked todayBy
Theme tokens● coveredvisual-style-contract.test.ts
Locked anatomy and variants● coveredper-component contract tests
Rendering, like the Switch/Toggle○ not coveredno test yet
Visual regression○ no runner yetsee docs/harness/quality.md

The fix, a good first joint task

Add a feature to align the Switch/Toggle to Lot Audit.
Write the canonical spec.
Add a story and a contract test.
Both products use it with no overrides.