iVendNextDevelopers Request a sandbox

The customer's release gate — the recipe

This recipe gives a customer's own team (or a partner's) one script for their pipeline. It says red or green before any change reaches a live shop, without us watching. A change can be an app, a manifest, or a price or tax rule. The sample to copy is samples/s12_release_gate/ (release_gate.sh, record_expect.py, an example pipeline file, the tests). The gate is the money kit (recipes/money_kit.md) and the self-check (tools/selfcheck/) with your own baskets, in one command.

When to use it: your team ships changes to a shop and wants a pass or fail before every release.

What it checks, in order — and shows all of it, red or green

  1. Self-check on your app folder (and manifest). It reads your files and runs nothing. If you ship no code into the shop, it is skipped, and says so.
  2. Baskets. You keep recorded baskets in a file shaped like the sample's baskets.json: a name, the lines, an optional sale discount, and the answer you expect (grand total and tax). The gate rings each one on the staging shop through the till's own calls: the till's preview, the booked sale, and the back-office invoice it is merged into. A basket is RED if its preview and its booking differ, or if its booked totals differ from your recorded answer. Each basket gets one line: the figure you expected, the figure booked, the figure previewed.
  3. Till days. Every day the gate opened must be closed. Any day left open is RED.

Exit 0 only if all three are green. Exit 1 if any is red. Exit 2 if the gate could not run (a baskets file in the wrong shape, a staging box it cannot reach, a console that rang nothing) — that is never a pass.

GATE   G002 RED "two leather cases, 10% markdown"  expected 2,339.20  booked 2,338.20  preview 2,338.20  <- diverged: grand_total: recorded answer 2339.20, booked 2338.20
GATE RESULT RED — do not release

Steps

  1. Record your baskets with their answers. Write the baskets without answers (baskets.norecord.json). Run the gate once with --record on a clean staging shop; it is green when preview = booking. Then fill the answers from that run's own record — never by hand arithmetic:

    python3 record_expect.py baskets.norecord.json runs/<run>.json > baskets.json

    Re-record only when a price or tax rule you control changes.

  2. Point the script at your staging box. Only the block marked HERE in release_gate.sh is yours. It names:

    • the staging box's container;
    • the command that runs a console script there;
    • where that script leaves its record;
    • the two commands that put your baskets file into the box and take it out (GATE_PUT, GATE_RM; Docker's cp and exec by default).

    The money kit itself (tools/moneykit/) must be on that box, pointed at your shop. GATE_KIT_SCRIPT names it as your console does. GATE_KIT_SETTINGS passes its settings (kit_dir:…;shop:…;record:… — only these three).

    ⚠ Staging only, one gate at a time on a box. The gate books real sales (with a simulated card) and closes real till days.

  3. Put it in the pipeline. samples/s12_release_gate/pipeline.example.yml is an example for a job on a runner that lives on the staging box. The job's exit code is the gate's.

  4. Read the lines. A RED basket names itself, with both figures and the kit's words ("grand total: till showed 2598.00, booked 2596.00"). A red self-check lists the finding with its file and line.

What it refuses, and why

Limits

Technical notes

Recording

On the bench the first three baskets recorded the same figures as the money kit's own recording a day earlier. The quoted RED line in step 4 ("grand total: till showed 2598.00, booked 2596.00") is the planted trap's own line on the bench.

What was proven where

This page in the kit