Stage a Sume Format change with no branches: second slug, If-Match

Sume Formats have no branches or revert. Test a change in a second Format slug, then promote it to the live one with a single If-Match PUT of the files.

4 min readSume
All posts

How do I test a Format change safely when there are no branches?

The contents API reads and writes a Format's files, but it has no branches, no revert, no blame and no history browser. A live Format has one current package. If you edit it in place and the change is bad, your weekly run uses the bad package.

The workaround is a second Format. POST /v1/formats creates one, and a slug that is already taken answers 409. In its SKILL.md, the frontmatter name must equal the slug, so copy the files and change that one line.

What are the steps?

  • Read the live Format's files with GET /v1/formats/{handle}/{slug}/contents and note its package_sha.
  • Create weekly-promo-next with POST /v1/formats, and set the name in its frontmatter to match.
  • Edit the copy and run it a few times with real inputs, comparing receipts.
  • Promote by sending the tested files to the live Format in one root PUT, with each existing path's live sha and If-Match set to the package_sha from step one.

How does the promote step stay safe?

A root PUT takes a files change set applied as one commit, with base64 content. For a path the live Format already has, each entry also needs that file's current sha; a new file sends none. The change set is not the whole package: paths you leave out stay as they are, and a removed file needs its own DELETE. With If-Match: <package_sha>, a write whose base is stale is refused with 409 format_package_sha_mismatch instead of overwriting someone else's edit. When you copy SKILL.md back, restore its name to the live slug, not weekly-promo-next.

A run reads the package it started with, so promoting a change never alters a run already in flight. The receipt's format.version tells you afterward which version each run used, and the version on the Format record rises by one for each commit. Keep the staging Format for the next change instead of deleting it; it is a cheap, permanent test bench and costs nothing until you run it.

import base64, os, requests

BASE = "https://api.sume.com/v1/formats/acme/weekly-promo/contents"
H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}

def promote(files: dict, package_sha: str):
    # files: path -> (text, live_file_sha or None for a new file)
    changes = []
    for path, (text, sha) in files.items():
        entry = {"path": path,
                 "content": base64.b64encode(text.encode()).decode()}
        if sha:
            entry["sha"] = sha
        changes.append(entry)
    r = requests.put(BASE, json={"files": changes}, timeout=30,
                     headers={**H, "If-Match": package_sha})
    if r.status_code == 409:
        raise RuntimeError("live Format changed; re-read and retry")
    r.raise_for_status()
    return r.json()

Sources

Related posts

More in Formats

All Formats posts

Written by Sume