Expand description
BundleDeployment lifecycle helpers (B10 of plans/next-gen-deployment.md).
Owns the on-disk, versioned revenue-policy artifact. Every mutation of a
deployment’s revenue_share (gtc op bundles add writes v1; each
gtc op bundles update --revenue-share … writes v{N+1}) materializes a
new policy version under:
<env_dir>/billing-policies/<bundle_id>/<customer_id>/vN.json # the document
<env_dir>/billing-policies/<bundle_id>/<customer_id>/vN.json.sig # detached sidecarBundleDeployment.revenue_policy_ref is set to the env-relative path of
the latest sidecar.
Since PR-4.2g the storage-free half — version derivation, document +
predicate construction, DSSE signing, the trust-root refusal, and the
in-memory self-verify — lives in
greentic_operator_trust::revenue_policy, shared with the
operator-store-server (which persists the same bytes to its
revenue_policies table). This module keeps the file-backed half: the
env trust-root load, the atomic writes, and the on-disk re-read
self-verify.
§Signing posture (C2)
The .sig sidecar is a DSSE envelope (application/vnd.in-toto+json)
whose in-toto v1 Statement pins the canonical-JSON SHA-256 of the
corresponding vN.json and carries a greentic.revenue-policy-predicate.v1
predicate. The envelope is signed Ed25519 with the operator’s key (see
crate::operator_key) and verifiable via
greentic_distributor_client::signing::verify_artifact_dsse against the
env’s super::trust_root.
§Trust-root contract (Codex #1 — revocation durability)
The writer NEVER mutates the env trust root. It loads
<env_dir>/trust-root.json, refuses to sign if the operator’s key_id
is not already a trusted entry, and self-verifies the freshly-written
envelope against that same trust root before returning.
This makes gtc op trust-root remove a real revocation boundary:
after removal, every subsequent bundle add/update aborts with
BundleDeploymentError::OperatorKeyNotTrusted until an authorized
caller runs the explicit gtc op trust-root bootstrap verb (or
rotates the operator’s local key entirely). An earlier draft of this
writer auto-seeded the operator key on every write — that defeated
revocation because the next mutation always re-inserted the removed
key.
§Concurrency & partial-failure safety
write_revenue_policy_version derives the next version from the
deployment’s committed revenue_policy_ref (env.json), not from a
filesystem scan. Callers persist env.json only after this writer returns,
so a failed attempt (sidecar write or env save) leaves the committed ref
unchanged; a retry rewrites the same version, overwriting any orphan
files instead of advancing past them. Committed state therefore never
references an uncommitted or dangling version. Callers MUST still run inside
EnvironmentStore::transact so the file write and the env.json update
share one env flock.
Structs§
- Revenue
Policy Predicate - Predicate body recorded inside the DSSE Statement. Mirrors the
document’s identity fields so a reader of the
.sigenvelope alone can see what the signature covers without openingvN.json. - Revenue
Policy Version - What a successful policy-version write produced.
Enums§
Constants§
- REVENUE_
POLICY_ PREDICATE_ TYPE_ V1 - Predicate type discriminator for the revenue-policy DSSE statement.
Functions§
- write_
revenue_ policy_ version - Write the next revenue-policy version for
deploymentunderenv_dir, usingrevenue_shareas the version’s policy,created_atas its timestamp, andoperator_keyfor DSSE signing.