main
Colby Knox release.py: --publish/--stage require --source <commit you pulled> and refuse unless the wiki head is that commit (chec… 2e737a4 1d ago

Publishing altium-bridge

How a build of this bridge reaches users. The tool is scripts/release.py; the developer recipe with the wiki details is publish-skills/altium-bridge-publish/SKILL.md. Page: adom/altium-bridge.

Two tiers

Every publish goes to the INSIDERS tier. The PUBLIC tier moves only when a human says so.

Insiders Public
Manifest altium-bridge/version.json on the adom/insiders page adom-bridge-altium-manifest.json on adom/altium-bridge
Who follows it desktops whose login can read the insiders page (insidersManifestUrl in src/bridge.json) everyone else
Moved by --publish --promote / --rollback only

The release zip itself lives on the adom/altium-bridge releases for both tiers; the tiers differ only in which manifest points at which version.

python3 scripts/release.py                      # lint + cargo test + build, zip into dist/. Publishes nothing.
python3 scripts/release.py --publish "<one sentence for the release log>" --source <the commit you pulled>
python3 scripts/release.py --promote <ver>  --attest "<the human's exact words>" --by "<name>"
python3 scripts/release.py --rollback <ver> --attest "<the human's exact words>" --by "<name>"

--publish does, in order: the lints below, cargo test, the release build, the zip, the release and its asset on adom/altium-bridge, the insiders manifest plus a release-log entry on adom/insiders (a copy of the manifest is archived in scripts/releases/<ver>.json), the version stamps to the page repo, the skills pkg (adom-wiki pkg publish --org adom), and a final check that the insiders manifest is blocked for anonymous readers and serves the new version to a signed-in one. It never touches the public manifest.

--promote <ver> needs the archived manifest for that version, re-downloads the zip and compares its sha256 with the record, then writes the public manifest with promotion_attestation, promoted_by and promoted_at, pushes it, and marks the release-log entry.

--rollback <ver> re-points the public manifest at an older archived build the same way, and records rollback_attestation, rolled_back_by, rolled_back_at.

The promotion rule

An AI never promotes on its own judgment. --attest carries the words the human actually said, and --by names that human. The script refuses an attestation shorter than 8 characters or a placeholder ("ok", "yes", "promote", "ship it", "go", "approved", "test"), and refuses a missing --by. The words are stored in the public manifest, so do not paraphrase them.

Versions

src/bridge.json version is the single source. These must carry the same number:

File Checked by release.py
src/BRIDGE_VERSION yes
bridge-rs/src/main.rs (BRIDGE_VERSION const) yes
package.json yes
bridge-rs/Cargo.toml no, bump by hand
page.json no, bump by hand

One plain semver per build, the same in both tiers. Add the CHANGELOG.md entry in the same change.

What the release script refuses

Every mode runs these first, and any hit stops the build:

  • Version drift: a stamp in the checked files above that differs from src/bridge.json, or an insidersManifestUrl in src/bridge.json that is not the insiders manifest URL.
  • Verbs declared vs dispatchable: verbs[] in src/bridge.json must equal the KNOWN list in bridge-rs/src/verbs.rs. Both directions are printed: declared but not dispatchable, and dispatchable but not declared.
  • ENGINE_HALTING identifiers in src/agent/AdomAgent.pas.tmpl: identifiers measured to halt Altium's DelphiScript engine (.ImplementationCount, .Implementation[, BottomXSize, MidXSize, eProcessFreePrimitives, RunProcessWithParameters, .SuperClass :=, CreateOleObject). Comments and string literals are ignored. When a new one is found, add it to the list in release.py and to dev-skills/altium-bridge-dev. One case the regex cannot see: GroupIterator_Create on a board halts but is correct on a component, so review those by hand.
  • Raw StrToFloat( / StrToInt( anywhere in the agent template outside the AdomFloat / AdomInt helpers. A raw conversion raises on malformed input, and a raise is an Error box on the user's screen.

Then cargo test must pass before the release build, and every file in the zip must exist.

Not linted by the script: verbs[] entries must be plain strings, never objects (see section 0 of the publish skill for the one-line check).

Source changes need their own push

--publish pushes only CHANGELOG.md, src/bridge.json, src/BRIDGE_VERSION and package.json to the page repo. Changed source, skills or docs do not travel with it. Push them separately:

adom-wiki repo push adom/altium-bridge --files <changed files> -m "v<ver>: <what changed>"

A docs-only change (README, images) needs no version bump, only this push.

Before promoting to public

All of these, on the version being promoted:

  1. The verb battery (dev-skills/altium-bridge-test/run_verb_tests.py) is green, meaning exit code 0 with no FAIL and no uncovered verb, on at least two Altium builds. Altium Designer 26.x and Altium Designer Develop behave differently on script errors.
  2. It is green on a machine that is not the one the change was written on.
  3. altium_selftest_script_error answers netWorks: true on each of those builds. outcome may be halted_and_recovered or contained_by_agent; both are passes.
  4. Ideally one run on a from-scratch Windows install, since the battery assumes Altium is present.
  5. A human has asked for the promotion, and their exact words are in hand.

Never run the battery on a machine somebody is using. It raises Altium and flashes an error box. The runner refuses unless the target has had no keyboard or mouse input for 180 s (--min-idle); pass --user-is-away only when the human has told you the machine is free. Do not run it on two machines of the same Altium 365 workspace at once, and let it close Altium at the end so the Author seat is released.

Verify after a publish

  • The script's last lines: SHIPPED <ver> to INSIDERS; public tier still serves <old>.
  • adom-wiki release list shows the release with its zip attached.
  • After a promote: adom-wiki repo show adom/altium-bridge adom-bridge-altium-manifest.json shows the promoted version and the sha256 of the archived manifest.
  • Then check it the way a STRANGER would, with no bearer token: fetch the public manifest and download the zip anonymously, confirm the sha matches, and install from that manifest URL on a real box before you call the promotion done.

Someone else may be publishing this bridge too

Colby ships this bridge in parallel. Clone the page before you edit (adom-wiki repo clone adom/altium-bridge <dir>), work in that tree, and push only the files you changed — publishing from a stale checkout reverts whatever shipped while you were working. Before touching a tier, read adom-wiki repo log adom/altium-bridge and the insiders version.json: an insiders tier serving an OLDER version than the newest release may be a deliberate hold, not a fault. --rollback moves the PUBLIC tier only; an insiders hold is a direct push of altium-bridge/version.json on the insiders page. To live-test a held version without disturbing the tier, push a SEPARATE manifest file (a distinct name), install from it, and remove it when you are done.