Commit d30e661
feat(authority): add "calm review" out-of-band approval channel; harden proposal/receipt/reconciliation integrity
Audit follow-up on the same-day WS3/WS2b work. Verified 5 findings + 2 gaps
against live source, fixed all of them, then found (and fixed) that
HIGH_RISK_REQUIRES_INDEPENDENT_REVIEW can silently dead-end even when
elicitation is enabled -- verified empirically that a connected MCP client
can complete the elicitation round-trip (no timeout, no capability error)
without ever showing the question to an actual human.
Audit fixes (CCK-29c/29d/30R/30R2/31R/05C):
- MRTR/declined-cache fingerprint now SHA-256 (was DefaultHasher, a public
64-bit hash with no cryptographic contract) -- ReviewAuthority's own
scope+risk-bound nature documented as a permanent, structural limit.
- Human elicitation message now shows a bounded, sanitized diff plus
base/proposed digests, not just path/risk/touched-symbols -- a receipt
can only back "this is what the reviewer was shown" if they were.
- approval_receipts.signature_provenance ("native" vs "legacy_unverified"),
folded into the signed payload so it can't be silently upgraded by
anyone with raw state.db write access. State.db v9->v10.
- WatchSupervisor::refresh now persists the Reconciled EvidenceSnapshot
AFTER the SCIP overlay pass, not before -- the old order recorded a
snapshot_id whose provider-state component the overlay immediately made
stale, defeating Human-tier minting on any project with scip-overlay
(a default-on feature) active.
- RiskVector.touches_uncovered_code wired at the one spend-time call site
with both a live diff and coverage data already loaded.
- RootedFilesystem::write_atomic_beneath's directory fsync return code is
no longer discarded -- WriteReceipt.durability distinguishes a confirmed
fsync from an unverified one instead of reporting unqualified success.
calm review (new): a durable, MCP-protocol-independent second channel for
independent review, alongside elicitation rather than replacing it.
edit_lines_impl_gated opens a pending_reviews row (state.db v11) when
refused with no working elicitation path; `calm review approve|decline`
requires a real interactive TTY (refuses on non-TTY stdin) and reuses the
same diff renderer the elicitation message uses; an agent's retry with a
matching approved review is treated as ElicitGate::Approved, with
ApprovalReceipt.mechanism honestly recording "cli_manual_review" rather
than "elicitation". Does not weaken the underlying invariant: risk=="high"
still always requires an independent reviewer through one of the two
channels, never self-attestation alone.
Full cargo test --workspace green (1232 calm-core + 395 calm-server + all
integration binaries, 0 failed), clippy --workspace --all-targets clean,
fmt clean.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>1 parent ebe4aa3 commit d30e661
12 files changed
Lines changed: 1855 additions & 97 deletions
File tree
- crates
- calm-cli/src
- calm-core/src
- authority
- db
- fs
- calm-server/src
- tools
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
315 | 315 | | |
316 | 316 | | |
317 | 317 | | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
318 | 333 | | |
319 | 334 | | |
320 | 335 | | |
| |||
347 | 362 | | |
348 | 363 | | |
349 | 364 | | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
350 | 397 | | |
351 | 398 | | |
352 | 399 | | |
| |||
1208 | 1255 | | |
1209 | 1256 | | |
1210 | 1257 | | |
| 1258 | + | |
| 1259 | + | |
| 1260 | + | |
| 1261 | + | |
| 1262 | + | |
| 1263 | + | |
| 1264 | + | |
| 1265 | + | |
| 1266 | + | |
| 1267 | + | |
| 1268 | + | |
| 1269 | + | |
| 1270 | + | |
| 1271 | + | |
| 1272 | + | |
| 1273 | + | |
| 1274 | + | |
| 1275 | + | |
| 1276 | + | |
| 1277 | + | |
| 1278 | + | |
| 1279 | + | |
| 1280 | + | |
| 1281 | + | |
| 1282 | + | |
| 1283 | + | |
| 1284 | + | |
| 1285 | + | |
| 1286 | + | |
| 1287 | + | |
| 1288 | + | |
| 1289 | + | |
| 1290 | + | |
| 1291 | + | |
| 1292 | + | |
| 1293 | + | |
| 1294 | + | |
| 1295 | + | |
| 1296 | + | |
| 1297 | + | |
| 1298 | + | |
| 1299 | + | |
| 1300 | + | |
| 1301 | + | |
| 1302 | + | |
| 1303 | + | |
| 1304 | + | |
1211 | 1305 | | |
1212 | 1306 | | |
1213 | 1307 | | |
1214 | 1308 | | |
1215 | 1309 | | |
| 1310 | + | |
| 1311 | + | |
| 1312 | + | |
| 1313 | + | |
| 1314 | + | |
| 1315 | + | |
| 1316 | + | |
| 1317 | + | |
| 1318 | + | |
| 1319 | + | |
| 1320 | + | |
| 1321 | + | |
| 1322 | + | |
| 1323 | + | |
| 1324 | + | |
| 1325 | + | |
| 1326 | + | |
| 1327 | + | |
| 1328 | + | |
| 1329 | + | |
| 1330 | + | |
| 1331 | + | |
| 1332 | + | |
| 1333 | + | |
| 1334 | + | |
| 1335 | + | |
| 1336 | + | |
| 1337 | + | |
| 1338 | + | |
| 1339 | + | |
| 1340 | + | |
| 1341 | + | |
| 1342 | + | |
| 1343 | + | |
| 1344 | + | |
| 1345 | + | |
| 1346 | + | |
| 1347 | + | |
| 1348 | + | |
| 1349 | + | |
| 1350 | + | |
| 1351 | + | |
| 1352 | + | |
| 1353 | + | |
| 1354 | + | |
| 1355 | + | |
| 1356 | + | |
| 1357 | + | |
| 1358 | + | |
| 1359 | + | |
| 1360 | + | |
| 1361 | + | |
| 1362 | + | |
| 1363 | + | |
| 1364 | + | |
| 1365 | + | |
| 1366 | + | |
| 1367 | + | |
| 1368 | + | |
| 1369 | + | |
| 1370 | + | |
| 1371 | + | |
| 1372 | + | |
| 1373 | + | |
| 1374 | + | |
| 1375 | + | |
| 1376 | + | |
| 1377 | + | |
| 1378 | + | |
| 1379 | + | |
| 1380 | + | |
| 1381 | + | |
| 1382 | + | |
| 1383 | + | |
| 1384 | + | |
| 1385 | + | |
| 1386 | + | |
| 1387 | + | |
| 1388 | + | |
| 1389 | + | |
| 1390 | + | |
| 1391 | + | |
| 1392 | + | |
| 1393 | + | |
| 1394 | + | |
| 1395 | + | |
| 1396 | + | |
| 1397 | + | |
| 1398 | + | |
| 1399 | + | |
| 1400 | + | |
| 1401 | + | |
| 1402 | + | |
| 1403 | + | |
| 1404 | + | |
| 1405 | + | |
| 1406 | + | |
| 1407 | + | |
| 1408 | + | |
| 1409 | + | |
| 1410 | + | |
| 1411 | + | |
| 1412 | + | |
| 1413 | + | |
| 1414 | + | |
| 1415 | + | |
| 1416 | + | |
| 1417 | + | |
| 1418 | + | |
| 1419 | + | |
1216 | 1420 | | |
1217 | 1421 | | |
1218 | 1422 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
13 | 19 | | |
14 | 20 | | |
15 | 21 | | |
| |||
0 commit comments