PlanResult parity
Same review contract across CLI TTY, JSON PlanResult, AutopilotProposal store, and Slack/Discord alerts — actions, risk, blast/impact, proposal id, approve hint (IC-005).
kprompt’s review contract is the same idea everywhere: see what will change, see risk, then approve — never silent mutate. Surfaces differ in density. Slack is not a full TTY diff viewer; it carries proposal id, risk, and an apply hint so an engineer who knows the CLI can approve without a glossary.
| Field | CLI TTY | JSON PlanResult | AutopilotProposal | Slack / Discord |
|---|---|---|---|---|
| Actions / steps | Yes (ops + diff) | plan.actions[] | plan.summary + steps[] | Summary / recommendation only |
| Risk | Yes | risk.level / denied | risk | proposalRisk when attached |
| Blast / impact | Blast radius block | blastRadius optional | expectedImpact / why (text) | Not in alert body |
| Proposal id | N/A (laptop NL) | N/A | id | proposalId |
| Approve hint | [y/N] / --approve | requiresApproval | proposals apply --approve | proposalHint + ask approve <id> |
| Applied | Session | applied | applied + decision | Pre-apply alert |
| Verify / Learn | --wait / verify UX | verify optional | verifyStatus / outcome / learnNote | Not in alert |
Approve vocabulary (same gate everywhere): TTY Apply this plan? [y/N] → y; CI --approve; stored proposal agent proposals apply … --approve; Slack ask approve <proposal-id> (alias apply <id>). Discord is notify-only — use the CLI hint. Risk labels: low · medium · high · denied. Alerts may show a short Impact line; that is not a full blast-radius dump. AutopilotProposal is PlanResult-shaped, not byte-identical.