Skip to content

Tune Spiral with Helix

Tuning is the process of adjusting the domain’s cost model — delay costs, noSoln outsourcing costs, travel factors, option times, quality settings — until Spiral’s decisions match the operation’s intent. Helix gives you a repeatable loop for it: replay a recorded situation, watch what Spiral decides and why, adjust the domain, replay again, compare. This guide walks that loop end to end.

(Prerequisites: an admin login, a client dev environment — see Develop a client extension — and one or more recorded .run.json files in the client’s tests/ tree.)

A run file (<name>.run.json) is a recorded input stream: every command that reached the CRUD, in order, with its Spiral synchronisation tag. Replaying one reproduces the recorded situation exactly.

From the landing screen choose Run File (shown when run files exist and you have the admin permission), then pick a file from the picker — it lists the client’s tests/ directory (HELIX_TESTS_DIR overrides the location).

Two modes:

  • Continuous (default): the file streams through at full speed. The application is read-only while loading (the top bar shows progress, e.g. 1240 of 3800 (32%)) and unlocks automatically when the final tag completes.
  • Single step (tick the checkbox in the picker): the file advances one tagged command at a time, and the application stays fully editable throughout — this is the tuning mode.

In single-step mode the dispatch top bar (the slot that normally shows progress/errors) becomes a release button showing the next waiting command:

▶ tag 1041 — {"add":{"project":{"id":20003,"stops":{...

Hover it to see the complete command; click it to release that command for processing. The next tagged command then takes its place. Untagged lines (comments, configuration) flow through without stopping.

This lets you bring the replay to precisely the moment you care about — the project whose allocation looked wrong, the surge that triggered outsourcing — then examine the world before letting the next command land. Because the app is not read-only, you can open editors, change values and probe between steps. (The parked command is also available programmatically: GET /run-files/next echoes it; POST /run-files/step releases it.)

3. Review the costs — Full / Developer mode and auto-allocate

Section titled “3. Review the costs — Full / Developer mode and auto-allocate”

Switch to Full or Developer mode from the top-bar settings menu (☰ → Mode: Full / Mode: Developer). Normal mode is the operator view; the tuning detail only shows in these modes.

Auto-allocate asks Spiral to re-place a stop freely and — crucially — to explain itself: right-click a stop row (or Ctrl+right-click its map marker) and choose Auto Allocate. Helix sends a force coerce with rid: 0 (recalculate the resource; did: 0 for desk assignment) and the tagged reply comes back as a Spiral reply dialog:

  • Warnings are translated through the domain’s helix.warning templates — the operator-facing reasons a placement was refused or penalised.
  • simpleSolns (Full/Developer only) is Spiral’s raw solution set — the candidate resources it considered with their solution data, shown as an expandable JSON tree. This is the primary cost-review surface: compare the candidates Spiral weighed and what separated them.

Per stop, the Schedule card in the stop editor shows what the current solution costs bought: dep / arv / fin, travel (tvl/dst), the solnTier the solution landed in, cbt (Full/Developer), and Spiral’s info messages. Developer mode additionally shows each tree node’s stop id (and flags #in≠out when an entity’s recorded stop id has drifted from the live document — useful when correlating with the raw stream).

The Developer-mode CRUD dialogs (every outgoing request and raw reply shown for confirmation) are useful when you want to see exactly what a UI action sends to Spiral.

4. Inspect the runtime domain in the JSON editor

Section titled “4. Inspect the runtime domain in the JSON editor”

Open the JSON Editor (☰ → JSON Editor). The entity buttons include the Define set — Stop Parameters, Resource Parameters, Customer Parameters, Contract Parameters, Topography — each seeded from the live reference.define of the running system. This is the runtime domain as Spiral currently sees it: resolved values, clone chains, the lot. The Dispatch Stream Viewer below it dumps the whole live in-memory database, reference included.

Use it to:

  • confirm what a parameter actually resolved to at runtime (clone chains can surprise),
  • copy the current stopParams block as the starting point for your tuned version.

Note — the Define verb does not apply live. The editor lets you modify the JSON, but an interactive define post is rejected by the CRUD (define not available in crud mode): the domain reaches a running Spiral only through file replay or a restart. Validation therefore happens by replay, not by posting the editor’s buffer — see the next step.

Two equivalent validation routes; both end with replaying the same run file and comparing decisions:

  1. Domain-file route (recommended): edit the client domain file (<CLIENT>.domain.json — e.g. adjust a delay.cost, a noSoln.costStop, an option t). In the dev environment the domain is read live from the mounted repo, so the change applies on the next load — reload the same run file and step to the same moment.
  2. Run-file route: for a self-contained experiment, copy the tuned define block (from the JSON editor) into a copy of the run file, ahead of the recorded commands — replay applies defines in-stream, so the recorded traffic runs under the modified domain without touching the real file.

Compare before/after: the same auto-allocate on the same stop — did the candidate ranking change as intended? Did solnTier improve? Did the warnings disappear? Single-stepping makes the comparison precise because you can halt at the identical tag in both runs.

Once the values are settled, make the domain-file edit permanent:

  • Dev: already done — the dev loop reads <CLIENT>.domain.json live from your repo (dev loop); commit it to your client repo.
  • Production: rebuild and ship the client bundle — publish-<client>.sh <version> packs the extension and the domain config, then helixctl deploy + run on the node (build & deploy).

Keep the run file you tuned against in the client’s tests/ tree — it becomes the regression baseline for the next tuning round.