Skip to main content

ChangeOps Reference

Operational details for the ChangeOps gate surface—CLI commands, API endpoints, and data storage—sourced from the Phase 4 release plan.

CLI commands

fleetforge-ctl wraps the ChangeOps API so pipelines and operators can drive gating flows:

CommandPurposeKey flags
fleetforge-ctl gates check --input change.json --output gate-decision.jsonEvaluate a change bundle and produce a decision (allow, follow_up, deny).--endpoint, --token, --input, --output
fleetforge-ctl gates followup --gate <ID> --note "<text>"Record acknowledgements or overrides for a follow-up decision.--gate, --note, --actor (optional override)
fleetforge-ctl gates list [--change-id <CHANGE>]List historical gate outcomes for auditing or dashboards.--change-id, --limit, `--format=json

fleetforge-ctl audit export --bundle-dir bundle/ writes a JSON bundle that includes the exported audit rows and any attestation identifiers referenced by those records, making it easier to hand evidence to compliance reviewers.

All commands respect the standard FleetForge environment variables (FLEETFORGE_API_HTTP, FLEETFORGE_API_TOKEN) and return JSON by default. Exit codes are non-zero on CLI errors; gates check itself succeeds even if the decision is deny, so pipelines should inspect the decision.effect field.

API endpoints

The runtime API exposes three RPCs (see RuntimeService):

RPCRequestResponseNotes
CheckChangeGateCheckChangeGateRequestCheckChangeGateResponseEvaluates the change bundle and returns the decision payload plus artifact IDs.
RecordGateFollowupRecordGateFollowupRequestRecordGateFollowupResponseStores acknowledgements or overrides tied to a gate.
ListChangeGatesListChangeGatesRequestListChangeGatesResponsePaginates stored decisions for dashboards and audits.

The TypeScript SDK (sdk/typescript/src/gen/fleetforge/runtime/v1/runtime_*) and Python SDK (sdk/python/fleetforge_proto/.../runtime_pb2.py) expose generated clients matching these endpoints.

Data model & storage

  • Tables: changeops_gates captures decision snapshots; changeops_followups records acknowledgements. Apply migration core/storage/migrations/0014_changeops_gates.sql via sqlx migrate run.
  • Artifacts: Every decision emits a JSON artifact tagged kind=change_gate_decision, containing the evaluated bundle, scores, and recommendations. When attestation evidence is available, the runtime also publishes a signed SCITT transparency entry (kind=scitt_entry) that links the decision to its attestation bundle. The SCITT artifact metadata now embeds a transparency object describing which backend handled the append (local vs scitt-http), whether it was a dry run, and any receipt payload returned by the remote log.
  • Transparency queue: Setting FLEETFORGE_TRANSPARENCY_WRITER=1 enables a background worker that scans the new transparency_jobs table and publishes SCITT entries asynchronously. Gate metadata records the queued job id (status=queued) until the worker writes the final receipt, so release pipelines no longer block on remote SCITT endpoints. The same worker honors FLEETFORGE_TRANSPARENCY_DRY_RUN=1 and writes the returned dry-run receipts to the metadata. Adjust the cadence with FLEETFORGE_TRANSPARENCY_WRITER_INTERVAL_SECS (defaults to 30s). The writer requires an Enterprise license (FLEETFORGE_LICENSE_TIER=enterprise); OSS/Pro deployments log a warning and continue without the SCITT feed. Use FLEETFORGE_TRANSPARENCY_SCOPE=gates|runs|artifacts to pick whether only gate decisions, whole runs, or every artifact enqueue SCITT jobs (default: gates).
  • Replay diff artifacts: When deterministic replays detect attestation or tool I/O drift, the executor fails fast and writes a compact replay_attestation_diff or replay_tool_diff artifact that summarizes the recorded vs current evidence (missing/unexpected attestation IDs, mismatched tool payloads). The error message includes the artifact SHA-256 so pipelines can fetch it via the artifact store.
  • Telemetry: Structured spans/logs use the fleetforge.changeops target so OTEL collectors and the UI can display gate activity.

Acceptance tests (First Green Bar)

The Status & Acceptance page now owns the ChangeOps readiness checklist. Its Hello Fleet walkthrough yields the exact capability tokens, attestations, C2PA manifest, replay telemetry, and SCITT receipt that gates require—extend that single scenario when adding new criteria.

Telemetry requirements

Gate evaluations now require two telemetry feeds supplied in the request:

  • telemetry.replays[] – Each critical replay must include attestation_match=true, tool_io_match=true, and token_drift <= 0.01. Any mismatch or missing replay evidence escalates to follow_up or deny.
  • telemetry.canary[] – Canary promotions must surface the attestation set they observed. Missing or mismatched attestation IDs deny the gate.

Gate responses include these structures in decision.scorecard.telemetry for downstream tooling.

Decision semantics

Outcome values and recommended actions:

EffectDescriptionTypical response
allowChange meets policy thresholds (novelty, evals, budgets).Merge or ship automatically; store the artifact.
follow_upAdditional review needed (e.g., missing eval coverage).Block merge until gates followup records acknowledgement.
denyChange violates policy thresholds.Fail the pipeline, address issues, re-run gates check.

Gate payloads include structured sections covering novelty scores, eval packs, replay parity, and budget impact so reviewers can trace the decision quickly.

Operational checklist

  • Keep ChangeOps migrations (0014_changeops_gates.sql) applied across environments.
  • Rotate the service account token used by CI and log gate IDs in release notes.
  • Export decision artifacts and telemetry to your observability stack for compliance audits.
  • Configure signing material for provenance and transparency feeds: FLEETFORGE_TRUST_SIGNING_KEY (or _PATH) signs policy attestations, while FLEETFORGE_SCITT_KEY (or _PATH) signs the emitted SCITT entries.
  • Select the transparency log backend via FLEETFORGE_TRANSPARENCY_BACKEND (local by default). When set to scitt-http, provide FLEETFORGE_TRANSPARENCY_ENDPOINT (and optionally FLEETFORGE_TRANSPARENCY_TOKEN). Use FLEETFORGE_TRANSPARENCY_DRY_RUN=1 to record pseudo-receipts without calling the remote log and FLEETFORGE_TRANSPARENCY_TIMEOUT_SECS to override the HTTP client timeout.