Change, Approval, and Audit
The core of the product runtime is turning “I want to change the product” into a governable state machine.
State Machine
proposed / pending_consent
-> approved
-> applied
-> rolled_back
pending_consent
-> denied
Minor changes can go directly to approved; non-minor changes enter pending_consent by default.
Proposal Fields
ChangeProposal stores:
tenant_idkind:config,workflow,feature_flag,code_patch,experimenttargetsummaryrationaleexpected_delta_kaffected_usersreversibletierriskstatuscreated_at- approver and approval note
HTTP Operations
Submit the CRM sample proposal:
curl -X POST http://127.0.0.1:8765/api/product/propose-crm-followup \
-d 'tenant_id=acme&affected_users=30&expected_delta_k=0.04'
Approval:
curl -X POST http://127.0.0.1:8765/api/product/approve \
-d 'change_id=1&approver=sales_manager¬e=approved'
Apply:
curl -X POST http://127.0.0.1:8765/api/product/apply \
-d 'change_id=1'
Rollback:
curl -X POST http://127.0.0.1:8765/api/product/rollback \
-d 'change_id=1'
Query:
curl http://127.0.0.1:8765/api/product/runtime
curl http://127.0.0.1:8765/api/product/audit
Audit Events
The audit log includes:
kpi_refreshedchange_proposedconsent_decisionchange_appliedchange_rolled_back
Each record contains the timestamp, tenant, change id, and detail.
Current Boundaries
applyApproved currently only changes GHW internal state and writes an audit entry. In production a ProductAdapter must be wired in:
ChangeProposal
-> ProductAdapter.validate
-> ProductAdapter.apply
-> ProductAdapter.verify
-> Audit
This prevents the mismatch where “the audit says applied, but the host product did not actually change.”