Skip to content

App Delivery Pack

The App Delivery Pack (@hellmai/lumenflow-packs-app-delivery) defines three jobs any project runs when it ships an app: build a binary, submit it to a store track, and ship an update. The build service and the store sit behind a connector, so a self-hosted project and a hosted service run the same jobs against the same contract.

JobParamsResult and refusals
Buildapp_id, tenant_subject, version, platform, profile, source_archivebuild_id, status, artifact_url, install_url, cost_usd, cost_basis, fingerprint, runtime_version, reused_build, error_code
Submitapp_id, tenant_subject, build_id, trackA track the manifest marks human-only, or does not list, is refused with unsupported_track
Updateaction (publish or rollback), channel, version, source_archive, approval (plus app and tenant)Guard codes no_baseline, runtime_mismatch, config_changed, approval_required

Build status moves queued to running to succeeded, failed or canceled; the last three are terminal. A succeeded build of the same app and tenant with the same fingerprint, platform and profile is reused: the result carries reused_build: true and cost_usd: 0.

Every platform, profile, track, human-only track and channel name is read from the connector’s ConnectorManifest; none is a literal in the contract. A channel with requires_approval: true makes a principal approval mandatory for publish and rollback.

A guard proves compatibility: the candidate runs on the baseline’s runtime and carries the baseline’s build-affecting configuration. It proves approval: the principal approval reference resolves, through your host, to a granted record bound to this action, app, tenant, channel and version. A caller’s assertion alone never satisfies approval_required.

A guard does not prove intent. It cannot tell whether the change is the one anyone meant to ship or whether the approver understood it.

Params are strict schemas. A key naming a secret, token, key id, bundle id or account id, and a value shaped like a private key, bearer token, JWT or provider access key, is rejected with credential_material_rejected. A connector reaches credentials only through the host’s opaque credential_ref.

cost_basis is reported, estimated or usage_based. Prices are read from a PriceConfig you supply; a missing price is an error, not a default.

Implement ProviderConnector (validateCredentials, fingerprint, build, submit, publish, status), publish a manifest, and run runConformance from the /conformance subpath. It drives the connector through build, reuse, a refused human-only submit, one refusal per update guard code, publish and rollback. createFakeConnector from /testing is a template.