capsule-engine 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. capsule_engine/__init__.py +17 -0
  2. capsule_engine/bundle_viewer/__init__.py +21 -0
  3. capsule_engine/bundle_viewer/static/offline_shell.html +1509 -0
  4. capsule_engine/bundle_viewer/viewer.py +57 -0
  5. capsule_engine/cli/__init__.py +5 -0
  6. capsule_engine/cli/bundle_cmd.py +269 -0
  7. capsule_engine/cli/console_cmd.py +70 -0
  8. capsule_engine/cli/constraints_cmd.py +74 -0
  9. capsule_engine/cli/format.py +173 -0
  10. capsule_engine/cli/guard_cmds.py +361 -0
  11. capsule_engine/cli/init_cmds.py +169 -0
  12. capsule_engine/cli/main.py +120 -0
  13. capsule_engine/cli/packs_cmds.py +96 -0
  14. capsule_engine/cli/telemetry_cmd.py +80 -0
  15. capsule_engine/cli/tenant_cmds.py +199 -0
  16. capsule_engine/cli/verify_cmd.py +110 -0
  17. capsule_engine/compiler/__init__.py +13 -0
  18. capsule_engine/compiler/effect_model.py +79 -0
  19. capsule_engine/compiler/vocabulary.py +253 -0
  20. capsule_engine/console/__init__.py +10 -0
  21. capsule_engine/console/api.py +251 -0
  22. capsule_engine/console/components.css +406 -0
  23. capsule_engine/console/console.css +130 -0
  24. capsule_engine/console/console.html +51 -0
  25. capsule_engine/console/console.js +330 -0
  26. capsule_engine/console/gallery.html +274 -0
  27. capsule_engine/console/server.py +137 -0
  28. capsule_engine/console/tokens.css +68 -0
  29. capsule_engine/conversation/__init__.py +88 -0
  30. capsule_engine/conversation/capsules.py +268 -0
  31. capsule_engine/conversation/exchange.py +279 -0
  32. capsule_engine/conversation/merkle.py +80 -0
  33. capsule_engine/conversation/session.py +101 -0
  34. capsule_engine/envcompat.py +15 -0
  35. capsule_engine/events/__init__.py +14 -0
  36. capsule_engine/events/capsule.py +133 -0
  37. capsule_engine/examples/__init__.py +9 -0
  38. capsule_engine/examples/data/tau2_airline/LICENSE-tau2-bench +21 -0
  39. capsule_engine/examples/data/tau2_airline/PROVENANCE.json +70 -0
  40. capsule_engine/examples/data/tau2_airline/hand_labels.json +893 -0
  41. capsule_engine/examples/data/tau2_airline/pilot1_live_gemini-2-5-flash_airline_shift1.jsonl +190 -0
  42. capsule_engine/examples/data/tau2_airline/tau2_committed_claude-3-7-sonnet_airline_trial0.jsonl +556 -0
  43. capsule_engine/examples/data/tau2_airline/tau2_committed_gpt-4-1-mini_airline_trial0.jsonl +480 -0
  44. capsule_engine/examples/data/tau2_airline/tau2_committed_gpt-4-1_airline_trial0.jsonl +496 -0
  45. capsule_engine/examples/data/tau2_airline/tau2_committed_o4-mini_airline_trial0.jsonl +392 -0
  46. capsule_engine/examples/data/tau2_airline/tau2_conversations_claude-3-7-sonnet_airline_4trials.jsonl +200 -0
  47. capsule_engine/examples/tau2_airline_reference.py +460 -0
  48. capsule_engine/examples/tau2_conversation_exchange.py +92 -0
  49. capsule_engine/folds/__init__.py +104 -0
  50. capsule_engine/folds/account_core.py +89 -0
  51. capsule_engine/folds/approval_latency.py +86 -0
  52. capsule_engine/folds/catalog.py +79 -0
  53. capsule_engine/folds/catalog_defs/actions.count_by_developer.yaml +10 -0
  54. capsule_engine/folds/catalog_defs/actions.executed_count.yaml +16 -0
  55. capsule_engine/folds/catalog_defs/actions.last_decision.yaml +12 -0
  56. capsule_engine/folds/catalog_defs/counterparty.seen_before.v2.yaml +34 -0
  57. capsule_engine/folds/catalog_defs/counterparty.seen_before.v3.yaml +38 -0
  58. capsule_engine/folds/catalog_defs/counterparty.seen_before.yaml +28 -0
  59. capsule_engine/folds/catalog_defs/disclosure.class_seen.yaml +29 -0
  60. capsule_engine/folds/catalog_defs/disclosure.statement_seen.yaml +32 -0
  61. capsule_engine/folds/catalog_defs/hold.active_exposure.yaml +44 -0
  62. capsule_engine/folds/catalog_defs/spend.weekly.v2.yaml +38 -0
  63. capsule_engine/folds/catalog_defs/spend.weekly.v3.1.yaml +71 -0
  64. capsule_engine/folds/catalog_defs/spend.weekly.v3.yaml +76 -0
  65. capsule_engine/folds/catalog_defs/spend.weekly.yaml +33 -0
  66. capsule_engine/folds/counterparty_signals.py +179 -0
  67. capsule_engine/folds/definition.py +421 -0
  68. capsule_engine/folds/duration.py +16 -0
  69. capsule_engine/folds/engine.py +436 -0
  70. capsule_engine/folds/errors.py +44 -0
  71. capsule_engine/folds/loader.py +24 -0
  72. capsule_engine/folds/ordering.py +143 -0
  73. capsule_engine/folds/paths.py +25 -0
  74. capsule_engine/folds/record_type_coverage.py +58 -0
  75. capsule_engine/folds/reducers.py +75 -0
  76. capsule_engine/folds/retention_continuity.py +117 -0
  77. capsule_engine/folds/set_membership.py +59 -0
  78. capsule_engine/folds/taxonomy.py +231 -0
  79. capsule_engine/guards/__init__.py +59 -0
  80. capsule_engine/guards/action.py +446 -0
  81. capsule_engine/guards/action_taxonomy.json +27 -0
  82. capsule_engine/guards/action_taxonomy_v2.json +27 -0
  83. capsule_engine/guards/action_taxonomy_v3.json +27 -0
  84. capsule_engine/guards/action_taxonomy_v4.json +27 -0
  85. capsule_engine/guards/action_taxonomy_v5.json +27 -0
  86. capsule_engine/guards/capsule.py +377 -0
  87. capsule_engine/guards/checks/__init__.py +268 -0
  88. capsule_engine/guards/checks/action_class_gate.py +199 -0
  89. capsule_engine/guards/checks/base.py +33 -0
  90. capsule_engine/guards/checks/caps.py +517 -0
  91. capsule_engine/guards/checks/channel_change.py +64 -0
  92. capsule_engine/guards/checks/commitment.py +41 -0
  93. capsule_engine/guards/checks/counterparty_identity_change.py +95 -0
  94. capsule_engine/guards/checks/counterparty_list.py +176 -0
  95. capsule_engine/guards/checks/counterparty_seen_before.py +160 -0
  96. capsule_engine/guards/checks/credential_pattern.py +73 -0
  97. capsule_engine/guards/checks/dedupe.py +259 -0
  98. capsule_engine/guards/checks/destination_rail.py +120 -0
  99. capsule_engine/guards/checks/field_change_count.py +100 -0
  100. capsule_engine/guards/checks/offer_expiry.py +134 -0
  101. capsule_engine/guards/checks/plan_containment.py +180 -0
  102. capsule_engine/guards/checks/price_floor.py +211 -0
  103. capsule_engine/guards/checks/promise_never.py +236 -0
  104. capsule_engine/guards/checks/promise_requires_approval.py +214 -0
  105. capsule_engine/guards/checks/recipient_role.py +117 -0
  106. capsule_engine/guards/checks/recurring_charge.py +49 -0
  107. capsule_engine/guards/checks/refundability.py +46 -0
  108. capsule_engine/guards/checks/release_on_acceptance.py +286 -0
  109. capsule_engine/guards/checks/required_disclosure.py +233 -0
  110. capsule_engine/guards/checks/single_commitment.py +221 -0
  111. capsule_engine/guards/checks/task_authority.py +182 -0
  112. capsule_engine/guards/checks/upfront_amount.py +71 -0
  113. capsule_engine/guards/checks/verify_before_dispatch.py +75 -0
  114. capsule_engine/guards/classes.py +393 -0
  115. capsule_engine/guards/engine.py +926 -0
  116. capsule_engine/guards/history_state.py +127 -0
  117. capsule_engine/guards/plan.py +237 -0
  118. capsule_engine/guards/revocation.py +120 -0
  119. capsule_engine/guards/signing.py +60 -0
  120. capsule_engine/guards/statements.py +62 -0
  121. capsule_engine/guards/tool_call.py +83 -0
  122. capsule_engine/guards/wickets/__init__.py +23 -0
  123. capsule_engine/guards/wickets/catalog.py +75 -0
  124. capsule_engine/guards/wickets/catalog_defs/action_class_gate.v1.1.yaml +38 -0
  125. capsule_engine/guards/wickets/catalog_defs/action_class_gate.v1.2.yaml +52 -0
  126. capsule_engine/guards/wickets/catalog_defs/action_class_gate.yaml +34 -0
  127. capsule_engine/guards/wickets/catalog_defs/caps.v2.yaml +30 -0
  128. capsule_engine/guards/wickets/catalog_defs/caps.v3.yaml +49 -0
  129. capsule_engine/guards/wickets/catalog_defs/caps.v4.yaml +45 -0
  130. capsule_engine/guards/wickets/catalog_defs/caps.v5.1.yaml +53 -0
  131. capsule_engine/guards/wickets/catalog_defs/caps.v5.yaml +43 -0
  132. capsule_engine/guards/wickets/catalog_defs/caps.yaml +17 -0
  133. capsule_engine/guards/wickets/catalog_defs/caps_holds.yaml +18 -0
  134. capsule_engine/guards/wickets/catalog_defs/channel_change.v1.1.yaml +18 -0
  135. capsule_engine/guards/wickets/catalog_defs/channel_change.yaml +10 -0
  136. capsule_engine/guards/wickets/catalog_defs/counterparty_identity_change.yaml +9 -0
  137. capsule_engine/guards/wickets/catalog_defs/counterparty_list.yaml +20 -0
  138. capsule_engine/guards/wickets/catalog_defs/counterparty_seen_before.v2.yaml +15 -0
  139. capsule_engine/guards/wickets/catalog_defs/counterparty_seen_before.v3.yaml +23 -0
  140. capsule_engine/guards/wickets/catalog_defs/counterparty_seen_before.v4.yaml +26 -0
  141. capsule_engine/guards/wickets/catalog_defs/counterparty_seen_before.yaml +14 -0
  142. capsule_engine/guards/wickets/catalog_defs/credential_pattern.yaml +14 -0
  143. capsule_engine/guards/wickets/catalog_defs/dedupe.yaml +19 -0
  144. capsule_engine/guards/wickets/catalog_defs/destination_rail.seller.v1.1.yaml +32 -0
  145. capsule_engine/guards/wickets/catalog_defs/destination_rail.seller.yaml +10 -0
  146. capsule_engine/guards/wickets/catalog_defs/destination_rail.yaml +9 -0
  147. capsule_engine/guards/wickets/catalog_defs/hold_reconcile.yaml +14 -0
  148. capsule_engine/guards/wickets/catalog_defs/material_fields_changed.v1.1.yaml +22 -0
  149. capsule_engine/guards/wickets/catalog_defs/material_fields_changed.yaml +14 -0
  150. capsule_engine/guards/wickets/catalog_defs/offer_expiry.v1.1.yaml +31 -0
  151. capsule_engine/guards/wickets/catalog_defs/offer_expiry.yaml +24 -0
  152. capsule_engine/guards/wickets/catalog_defs/offer_fields_changed.v1.1.yaml +22 -0
  153. capsule_engine/guards/wickets/catalog_defs/offer_fields_changed.yaml +10 -0
  154. capsule_engine/guards/wickets/catalog_defs/price_floor.yaml +32 -0
  155. capsule_engine/guards/wickets/catalog_defs/promise_never.v1.1.yaml +64 -0
  156. capsule_engine/guards/wickets/catalog_defs/promise_never.yaml +16 -0
  157. capsule_engine/guards/wickets/catalog_defs/promise_requires_approval.v1.1.yaml +26 -0
  158. capsule_engine/guards/wickets/catalog_defs/promise_requires_approval.yaml +21 -0
  159. capsule_engine/guards/wickets/catalog_defs/recipient_role.seller.v1.1.yaml +23 -0
  160. capsule_engine/guards/wickets/catalog_defs/recipient_role.seller.v1.2.yaml +24 -0
  161. capsule_engine/guards/wickets/catalog_defs/recipient_role.seller.yaml +10 -0
  162. capsule_engine/guards/wickets/catalog_defs/recipient_role.v1.1.yaml +26 -0
  163. capsule_engine/guards/wickets/catalog_defs/recipient_role.yaml +11 -0
  164. capsule_engine/guards/wickets/catalog_defs/recipient_seen_before.yaml +16 -0
  165. capsule_engine/guards/wickets/catalog_defs/recurring_charge.yaml +9 -0
  166. capsule_engine/guards/wickets/catalog_defs/refundability.v1.1.yaml +15 -0
  167. capsule_engine/guards/wickets/catalog_defs/refundability.yaml +7 -0
  168. capsule_engine/guards/wickets/catalog_defs/release_on_acceptance.seller.v1.1.yaml +44 -0
  169. capsule_engine/guards/wickets/catalog_defs/release_on_acceptance.seller.v1.2.yaml +63 -0
  170. capsule_engine/guards/wickets/catalog_defs/release_on_acceptance.seller.yaml +36 -0
  171. capsule_engine/guards/wickets/catalog_defs/required_disclosure.v1.1.yaml +36 -0
  172. capsule_engine/guards/wickets/catalog_defs/required_disclosure.v1.2.yaml +42 -0
  173. capsule_engine/guards/wickets/catalog_defs/required_disclosure.yaml +25 -0
  174. capsule_engine/guards/wickets/catalog_defs/single_commitment.seller.yaml +14 -0
  175. capsule_engine/guards/wickets/catalog_defs/task_authority.v1.1.yaml +20 -0
  176. capsule_engine/guards/wickets/catalog_defs/task_authority.yaml +8 -0
  177. capsule_engine/guards/wickets/catalog_defs/upfront_amount.v1.1.yaml +19 -0
  178. capsule_engine/guards/wickets/catalog_defs/upfront_amount.yaml +11 -0
  179. capsule_engine/guards/wickets/catalog_defs/verify_before_dispatch.yaml +9 -0
  180. capsule_engine/guards/wickets/definition.py +164 -0
  181. capsule_engine/guards/wickets/errors.py +18 -0
  182. capsule_engine/guards/wickets/loader.py +26 -0
  183. capsule_engine/guards/wickets/retired.py +62 -0
  184. capsule_engine/holds/__init__.py +35 -0
  185. capsule_engine/holds/capsules.py +266 -0
  186. capsule_engine/holds/engine.py +476 -0
  187. capsule_engine/holds/errors.py +29 -0
  188. capsule_engine/holds/policy.py +62 -0
  189. capsule_engine/holds/scope.py +47 -0
  190. capsule_engine/mcp/__init__.py +16 -0
  191. capsule_engine/mcp/config.py +117 -0
  192. capsule_engine/mcp/server.py +338 -0
  193. capsule_engine/mcp/tools.py +424 -0
  194. capsule_engine/packaging.py +60 -0
  195. capsule_engine/packs/__init__.py +45 -0
  196. capsule_engine/packs/backfill_coverage.py +238 -0
  197. capsule_engine/packs/catalog/airline-engagement/AI-BOOTSTRAP.md +53 -0
  198. capsule_engine/packs/catalog/airline-engagement/folds/session_close.yaml +8 -0
  199. capsule_engine/packs/catalog/airline-engagement/pack.yaml +146 -0
  200. capsule_engine/packs/catalog/eu-ai-act/fixtures/trace/good_execution.json +36 -0
  201. capsule_engine/packs/catalog/eu-ai-act/fixtures/trace/oversight_declared.json +36 -0
  202. capsule_engine/packs/catalog/eu-ai-act/fixtures/trace/tampered_execution.json +36 -0
  203. capsule_engine/packs/catalog/eu-ai-act/fixtures/trace/trusted_issuer.jwk.json +5 -0
  204. capsule_engine/packs/catalog/eu-ai-act/obligations-pack-note.md +68 -0
  205. capsule_engine/packs/catalog/eu-ai-act/obligations-register.yaml +761 -0
  206. capsule_engine/packs/catalog/eu-ai-act/pack.yaml +88 -0
  207. capsule_engine/packs/catalog/eu-ai-act/register.yaml +96 -0
  208. capsule_engine/packs/catalog/eu-ai-act-deterministic/fixtures/synthetic_internal_assist_sample.jsonl +6 -0
  209. capsule_engine/packs/catalog/eu-ai-act-deterministic/pack.yaml +580 -0
  210. capsule_engine/packs/catalog/everyday/AI-BOOTSTRAP.md +194 -0
  211. capsule_engine/packs/catalog/everyday/fixtures/mini_ledger.jsonl +45 -0
  212. capsule_engine/packs/catalog/everyday/pack.yaml +480 -0
  213. capsule_engine/packs/catalog/payments-safety/AI-BOOTSTRAP.md +83 -0
  214. capsule_engine/packs/catalog/payments-safety/fixtures/mini_ledger.jsonl +8 -0
  215. capsule_engine/packs/catalog/payments-safety/folds/spend_weekly.yaml +29 -0
  216. capsule_engine/packs/catalog/payments-safety/pack.yaml +112 -0
  217. capsule_engine/packs/catalog/seller/fixtures/mini_ledger.jsonl +83 -0
  218. capsule_engine/packs/catalog/seller/pack.yaml +503 -0
  219. capsule_engine/packs/catalog/standard-vendor/AI-BOOTSTRAP.md +70 -0
  220. capsule_engine/packs/catalog/standard-vendor/folds/session_close.yaml +8 -0
  221. capsule_engine/packs/catalog/standard-vendor/pack.yaml +466 -0
  222. capsule_engine/packs/contract_diff.py +809 -0
  223. capsule_engine/packs/contract_validate.py +185 -0
  224. capsule_engine/packs/corpus_verify.py +126 -0
  225. capsule_engine/packs/enforce.py +81 -0
  226. capsule_engine/packs/errors.py +159 -0
  227. capsule_engine/packs/eu_ai_act_trace_field_map.py +46 -0
  228. capsule_engine/packs/install.py +266 -0
  229. capsule_engine/packs/loader.py +1462 -0
  230. capsule_engine/packs/measurability_report.py +280 -0
  231. capsule_engine/packs/obligation_results.py +72 -0
  232. capsule_engine/packs/pins.py +92 -0
  233. capsule_engine/packs/schema.py +1053 -0
  234. capsule_engine/packs/thresholds.py +146 -0
  235. capsule_engine/packs/trace_attainment.py +188 -0
  236. capsule_engine/packs/trace_reader.py +104 -0
  237. capsule_engine/policy/__init__.py +37 -0
  238. capsule_engine/policy/activation.py +87 -0
  239. capsule_engine/policy/catalog_defs/default.yaml +23 -0
  240. capsule_engine/policy/catalog_defs/holds.yaml +27 -0
  241. capsule_engine/policy/errors.py +46 -0
  242. capsule_engine/policy/limits.py +287 -0
  243. capsule_engine/policy/loader.py +26 -0
  244. capsule_engine/policy/manifest.py +289 -0
  245. capsule_engine/policy/profile.py +281 -0
  246. capsule_engine/policy/resolve.py +224 -0
  247. capsule_engine/register/__init__.py +39 -0
  248. capsule_engine/register/compiler.py +219 -0
  249. capsule_engine/register/errors.py +40 -0
  250. capsule_engine/register/loader.py +247 -0
  251. capsule_engine/register/schema.py +129 -0
  252. capsule_engine/registry/__init__.py +19 -0
  253. capsule_engine/registry/conventions.json +162 -0
  254. capsule_engine/registry/conventions.py +188 -0
  255. capsule_engine/registry/cpb_registry.json +78 -0
  256. capsule_engine/report/__init__.py +62 -0
  257. capsule_engine/report/build.py +267 -0
  258. capsule_engine/report/coverage.py +777 -0
  259. capsule_engine/report/errors.py +35 -0
  260. capsule_engine/report/live_check.py +126 -0
  261. capsule_engine/report/live_history.py +420 -0
  262. capsule_engine/report/model.py +95 -0
  263. capsule_engine/report/render.py +467 -0
  264. capsule_engine/report/replay.py +1677 -0
  265. capsule_engine/report/result.py +504 -0
  266. capsule_engine/report/result_from_folds.py +222 -0
  267. capsule_engine/report/result_from_layers.py +670 -0
  268. capsule_engine/report/sale_bundle.py +864 -0
  269. capsule_engine/report/static/verify.js +451 -0
  270. capsule_engine/schemas/evidence-contract-v0.json +383 -0
  271. capsule_engine/schemas/vendor/epistemic-types.json +21 -0
  272. capsule_engine/schemas/vendor/evidence-result-v0.json +463 -0
  273. capsule_engine/telemetry/__init__.py +9 -0
  274. capsule_engine/telemetry/consent.py +39 -0
  275. capsule_engine/telemetry/events.py +93 -0
  276. capsule_engine/telemetry/fixtures/synthetic_events.jsonl +45 -0
  277. capsule_engine/telemetry/funnel.py +147 -0
  278. capsule_engine/telemetry/record.py +106 -0
  279. capsule_engine/telemetry/sink.py +61 -0
  280. capsule_engine/telemetry/state.py +60 -0
  281. capsule_engine/tenants.py +327 -0
  282. capsule_engine-0.1.0.dist-info/METADATA +47 -0
  283. capsule_engine-0.1.0.dist-info/RECORD +288 -0
  284. capsule_engine-0.1.0.dist-info/WHEEL +5 -0
  285. capsule_engine-0.1.0.dist-info/entry_points.txt +2 -0
  286. capsule_engine-0.1.0.dist-info/licenses/LICENSE +202 -0
  287. capsule_engine-0.1.0.dist-info/licenses/capsule_engine/examples/data/tau2_airline/LICENSE-tau2-bench +21 -0
  288. capsule_engine-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,23 @@
1
+ # counterparty_seen_before wicket, version 3: counterparty_seen_before/2.0.0
2
+ # read against counterparty.seen_before/3.0.0, which also counts an act that
3
+ # asked first and was then approved and executed. Under version 2 a replay
4
+ # never counted one, so a merchant whose first purchase asked stayed
5
+ # first-time on every later purchase. Version 2
6
+ # (counterparty_seen_before.v2.yaml) stays as it was for the packs that pin it.
7
+ #
8
+ # `fold_digest` is the real `definition_digest()` of
9
+ # folds/catalog_defs/counterparty.seen_before.v3.yaml (folds/definition.py);
10
+ # the check refuses to run when the catalog fold does not match it.
11
+ wicket_id: counterparty_seen_before/3.0.0
12
+ check: counterparty_seen_before
13
+ semantics: >-
14
+ For an action in action_classes, the operator's prior acts addressed to the
15
+ action's target are counted, leaving dry runs out: an accepted decision, or
16
+ an act whose check was approved to proceed and then executed. One or more
17
+ passes; none fails. An act that was declined, or approved and never
18
+ executed, is not counted. It is not applicable, naming the field, when the
19
+ action names no target. Any other action class is out of scope.
20
+ config:
21
+ fold_id: counterparty.seen_before/3.0.0
22
+ fold_digest: 73dbf8cd8a36fadca0ac823d2b17592fdc457c24081bc44667f032601e914033
23
+ action_classes: [money.purchase]
@@ -0,0 +1,26 @@
1
+ # counterparty_seen_before wicket, version 4: version 3 with one change. A
2
+ # purchase that names no payee fails as a first-time counterparty, with the
3
+ # reason "no payee named", where version 3 recorded it as not applicable.
4
+ # Not applicable never asks, so under version 3 a purchase sealing no
5
+ # counterparty went ahead while the same purchase naming a new payee asked.
6
+ # The fold is unchanged: counterparty.seen_before/3.0.0. Version 3
7
+ # (counterparty_seen_before.v3.yaml) stays as it was for the packs that pin it.
8
+ #
9
+ # `fold_digest` is the real `definition_digest()` of
10
+ # folds/catalog_defs/counterparty.seen_before.v3.yaml (folds/definition.py);
11
+ # the check refuses to run when the catalog fold does not match it.
12
+ wicket_id: counterparty_seen_before/4.0.0
13
+ check: counterparty_seen_before
14
+ semantics: >-
15
+ For an action in action_classes, the operator's prior acts addressed to the
16
+ action's target are counted, leaving dry runs out: an accepted decision, or
17
+ an act whose check was approved to proceed and then executed. One or more
18
+ passes; none fails. An act that was declined, or approved and never
19
+ executed, is not counted. An action that names no target, or a target
20
+ that is empty or only whitespace, fails as a first-time counterparty, with
21
+ the reason no payee named. Any other action class is out of scope.
22
+ config:
23
+ fold_id: counterparty.seen_before/3.0.0
24
+ fold_digest: 73dbf8cd8a36fadca0ac823d2b17592fdc457c24081bc44667f032601e914033
25
+ action_classes: [money.purchase]
26
+ missing_target: unseen
@@ -0,0 +1,14 @@
1
+ # counterparty_seen_before wicket: fail a first-time counterparty, pass a
2
+ # repeat one (guards/checks/counterparty_seen_before.py), for actions in
3
+ # `action_classes`. The count is the cited fold's result over the
4
+ # operator's accepted actions addressed to the same target.
5
+ #
6
+ # `fold_digest` is the real `definition_digest()` of
7
+ # folds/catalog_defs/counterparty.seen_before.yaml (folds/definition.py);
8
+ # the check refuses to run when the catalog fold does not match it.
9
+ wicket_id: counterparty_seen_before/1.0.0
10
+ check: counterparty_seen_before
11
+ config:
12
+ fold_id: counterparty.seen_before/1.0.0
13
+ fold_digest: c43b2011b4d49cf54a0306e9637ecfd3a945ff7febc13283507dd77513ae9b28
14
+ action_classes: [money.purchase]
@@ -0,0 +1,14 @@
1
+ # credential_pattern wicket: regular expressions matched against
2
+ # Action.outgoing_content (guards/checks/credential_pattern.py). Each pattern
3
+ # has a stable id that appears in the evidence when it matches. A change to
4
+ # any pattern moves this definition's digest.
5
+ wicket_id: credential_pattern/1.0.0
6
+ check: credential_pattern
7
+ config:
8
+ patterns:
9
+ - id: one_time_code
10
+ regex: '(?i)\b(?:one[- ]time|verification|security|login|authentication)\s+(?:code|passcode|pin)\b\D{0,20}\d{4,8}\b'
11
+ - id: password_value
12
+ regex: '(?i)\bpass(?:word|code)\s*(?:is|:|=)\s*\S+'
13
+ - id: card_security_code
14
+ regex: '(?i)\b(?:cvv|cvc|cvv2)\b\D{0,10}\d{3,4}\b'
@@ -0,0 +1,19 @@
1
+ # Dedupe wicket: exact-match equivalence lookup over a rolling window
2
+ # (guards/checks/dedupe.py). The check LOGIC (the equivalence-key formula,
3
+ # the lookup itself) stays Python code -- this digest identifies "this
4
+ # configuration of this check" (method + window), never the source file.
5
+ #
6
+ # `method` mirrors cli/constraints_cmd.py's CHECKS catalog entry for dedupe
7
+ # ("exact_match_index_v0") -- pinned here as data so a manifest can declare
8
+ # which equivalence formula version governed a decision, not just that
9
+ # *some* dedupe check ran.
10
+ #
11
+ # `window_days` mirrors guards/engine.py's `_DEDUPE_WINDOW_DAYS` constant.
12
+ # This wicket file does not drive that constant at runtime; the digest exists so the
13
+ # *declared* window is checkable even before every deployment path
14
+ # consumes it.
15
+ wicket_id: dedupe/1.0.0
16
+ check: dedupe
17
+ config:
18
+ method: exact_match_index_v0
19
+ window_days: 30
@@ -0,0 +1,32 @@
1
+ # seller.destination_rail/1.1.0: seller.destination_rail/1.0.0
2
+ # (destination_rail.seller.yaml) run at the seller's commit too
3
+ # (agreement.accept, the class a seller's commit carries; no deal record
4
+ # carries marketplace.sale), with cash allowed when the item is handed over
5
+ # in person, the common payment apps counted as p2p, and a commit that
6
+ # states no rail failing (capsule-engine#192). The aliases are here, under
7
+ # this digest, so a sealed rail token keeps the token the producer wrote and
8
+ # this definition says what it counts as. 1.0.0 stays as it was for the
9
+ # records and packs that pin it.
10
+ wicket_id: seller.destination_rail/1.1.0
11
+ check: destination_rail
12
+ semantics: >-
13
+ For an action in action_classes, the rail is first counted as its entry in
14
+ rail_aliases, if it has one. A rail counted as one of allowed_rails passes.
15
+ A rail counted as one of in_person_rails passes only when the action's
16
+ handover is in_person, and fails with any other handover or none. Any other
17
+ rail fails. An action that carries no rail fails when missing_rail maps its
18
+ action class to fail, with the reason "payment method not stated", and is
19
+ otherwise not applicable, in scope. Any other action class is not
20
+ applicable. The evidence records the rail read, what it was counted as,
21
+ the allowed and in-person rails and the handover, never who pays or where.
22
+ config:
23
+ action_classes: [agreement.accept, marketplace.sale]
24
+ allowed_rails: [card, p2p]
25
+ in_person_rails: [cash]
26
+ rail_aliases:
27
+ venmo: p2p
28
+ zelle: p2p
29
+ cash_app: p2p
30
+ paypal: p2p
31
+ missing_rail:
32
+ agreement.accept: fail
@@ -0,0 +1,10 @@
1
+ # destination_rail, configured for a seller (guards/checks/
2
+ # destination_rail.py): the rails a buyer may pay on, as an allow-list. The
3
+ # check fails when Action.rail is not one of `allowed_rails`.
4
+ # destination_rail/1.0.0 (destination_rail.yaml) watches rails instead and
5
+ # stays as it was.
6
+ wicket_id: seller.destination_rail/1.0.0
7
+ check: destination_rail
8
+ config:
9
+ action_classes: [marketplace.sale]
10
+ allowed_rails: [card, p2p]
@@ -0,0 +1,9 @@
1
+ # destination_rail wicket: set membership of the action's payment rail
2
+ # (guards/checks/destination_rail.py). The check fails when Action.rail is one
3
+ # of `watched_rails`, for actions in `action_classes`. Both lists are policy
4
+ # data, so a change to either moves this definition's digest.
5
+ wicket_id: destination_rail/1.0.0
6
+ check: destination_rail
7
+ config:
8
+ action_classes: [money.transfer]
9
+ watched_rails: [crypto, gift_card, p2p]
@@ -0,0 +1,14 @@
1
+ # hold_reconcile wicket (capsule-emit #53 point 2): "tolerance is policy, not
2
+ # code -- declared in a digest-pinned definition (rides the policy
3
+ # manifest), so 'which tolerance governed' is checkable per decision."
4
+ #
5
+ # `tolerance_minor` is the maximum permitted overage (executed_amount_minor -
6
+ # reserved_amount_minor) per action_class before a conversion is treated as
7
+ # an over-tolerance breach (holds/engine.py routes it through the existing
8
+ # ALLOW/DENY/ESCALATE vocabulary instead of building a hold.reconcile
9
+ # record). No entry for a class means zero tolerance -- any overage breaches.
10
+ wicket_id: hold_reconcile/1.0.0
11
+ check: hold_reconcile
12
+ config:
13
+ tolerance_minor:
14
+ money.transfer: 50000
@@ -0,0 +1,22 @@
1
+ # material_fields_changed wicket, version 1.1: material_fields_changed/1.0.0's
2
+ # config with marketplace.sale added to action_classes
3
+ # (guards/checks/field_change_count.py). The rule itself is the `semantics`
4
+ # field below: it is inside the digested body, so rewording it moves the
5
+ # digest. material_fields_changed/1.0.0 (material_fields_changed.yaml) stays
6
+ # as it was for the packs that pin it.
7
+ wicket_id: material_fields_changed/1.1.0
8
+ check: material_fields_changed
9
+ semantics: >-
10
+ For an action in action_classes, Action.material_fields_changed is the
11
+ producer's count of the fields in counted_fields that differ from what the
12
+ user approved, and Action.material_fields_basis the SHA-256 over the JCS
13
+ bytes of the list it counted over. The count is read only when that basis
14
+ equals the digest of counted_fields as pinned here. A count at or below
15
+ max_changed passes; above it fails. It is not applicable, naming the field,
16
+ when the action carries no count, or no basis or one for another list. The
17
+ fields and their values are never read. marketplace.sale is in scope. Any
18
+ other action class is out of scope.
19
+ config:
20
+ action_classes: [money.purchase, money.transfer, money.subscription, booking.create, booking.modify, agreement.accept, marketplace.offer, external_commitment.other, marketplace.sale]
21
+ counted_fields: [terms.item, terms.quantity, terms.price_minor, terms.deposit_minor, terms.currency, terms.when, terms.place, terms.conditions, recourse.rail, recourse.refundable, who.payee]
22
+ max_changed: 0
@@ -0,0 +1,14 @@
1
+ # material_fields_changed wicket: a count, from the producer, of the fields
2
+ # in `counted_fields` that differ from what the user approved
3
+ # (guards/checks/field_change_count.py). The producer also sends the digest
4
+ # of the list it counted over, and the count is read only when that digest is
5
+ # this list's. The list is policy data, so a change to it moves this
6
+ # definition's digest. A key counts as changed when it is on one side only,
7
+ # or on both with unequal values; terms.conditions counts as one key. Fails
8
+ # when the count is above `max_changed`.
9
+ wicket_id: material_fields_changed/1.0.0
10
+ check: material_fields_changed
11
+ config:
12
+ action_classes: [money.purchase, money.transfer, money.subscription, booking.create, booking.modify, agreement.accept, marketplace.offer, external_commitment.other]
13
+ counted_fields: [terms.item, terms.quantity, terms.price_minor, terms.deposit_minor, terms.currency, terms.when, terms.place, terms.conditions, recourse.rail, recourse.refundable, who.payee]
14
+ max_changed: 0
@@ -0,0 +1,31 @@
1
+ # offer_expiry/1.1.0: offer_expiry/1.0.1 (offer_expiry.yaml) with an offer
2
+ # that answers no proposal not applicable (capsule-engine#193). The producer
3
+ # seals the rule input no_proposal on an offer when no message from the
4
+ # counterparty was on record before it (capsule-cli#364), so there is no
5
+ # proposal to go stale. A missing proposal_at alone never reads as not
6
+ # applicable: it still fails, and so does no_proposal beside a proposal_at. The
7
+ # bridge reads no_proposal only from a check that names no source ref (the
8
+ # message an offer answers), so a check naming both is decided on that
9
+ # message's age, or fails as missing one.
10
+ # 1.0.1 stays as it was for the records and packs that pin it.
11
+ #
12
+ # Declared disposition: ask. The unverified case is meant to be
13
+ # ASK_UNVERIFIED, which the pack schema's disposition set does not have yet;
14
+ # until it does, the evidence marker tells the two apart.
15
+ wicket_id: offer_expiry/1.1.0
16
+ check: offer_expiry
17
+ semantics: >-
18
+ For an action in action_classes, the age is the action's timestamp minus
19
+ its proposal_at, both RFC 3339 UTC, in whole seconds. An age within
20
+ max_age_seconds passes. An older proposal fails as expired: acting needs a
21
+ new proposed action. An action in no_proposal_classes that carries
22
+ no_proposal true and no proposal_at answers no proposal and is not
23
+ applicable, in scope. An action carrying no_proposal true beside a
24
+ proposal_at fails with expiry_unverified. If
25
+ the age cannot be established otherwise (proposal_at or timestamp missing
26
+ or unreadable, or a proposal later than the action) the rule fails with
27
+ expiry_unverified. Any other action class is out of scope.
28
+ config:
29
+ action_classes: [marketplace.offer, marketplace.sale, agreement.accept]
30
+ max_age_seconds: 86400
31
+ no_proposal_classes: [marketplace.offer]
@@ -0,0 +1,24 @@
1
+ # offer_expiry wicket: how old the proposal an action acts on may be
2
+ # (guards/checks/offer_expiry.py). The rule itself is the `semantics`
3
+ # field below: it is inside the digested body, so rewording it moves the
4
+ # digest. Default limit: 24 hours.
5
+ #
6
+ # Declared disposition: ask. The unverified case is meant to be
7
+ # ASK_UNVERIFIED, which the pack schema's disposition set does not have
8
+ # yet; until it does, the evidence marker tells the two apart.
9
+ #
10
+ # Replaces offer_expiry/1.0.0, which is retired at its digest
11
+ # (guards/wickets/retired.py): its check changed meaning under that digest.
12
+ wicket_id: offer_expiry/1.0.1
13
+ check: offer_expiry
14
+ semantics: >-
15
+ For an action in action_classes, the age is the action's timestamp minus
16
+ its proposal_at, both RFC 3339 UTC, in whole seconds. An age within
17
+ max_age_seconds passes. An older proposal fails as expired: acting needs a
18
+ new proposed action. If the age cannot be established (proposal_at or
19
+ timestamp missing or unreadable, or a proposal later than the action) the
20
+ rule fails with expiry_unverified. It is never not applicable for an
21
+ action in action_classes; any other action class is out of scope.
22
+ config:
23
+ action_classes: [marketplace.offer, marketplace.sale, agreement.accept]
24
+ max_age_seconds: 86400
@@ -0,0 +1,22 @@
1
+ # offer_fields_changed wicket, version 1.1: offer_fields_changed/1.0.0's
2
+ # config with marketplace.sale added to action_classes
3
+ # (guards/checks/field_change_count.py). The rule itself is the `semantics`
4
+ # field below: it is inside the digested body, so rewording it moves the
5
+ # digest. offer_fields_changed/1.0.0 (offer_fields_changed.yaml) stays as it
6
+ # was for the packs that pin it.
7
+ wicket_id: offer_fields_changed/1.1.0
8
+ check: offer_fields_changed
9
+ semantics: >-
10
+ For an action in action_classes, Action.offer_fields_changed is the
11
+ producer's count of the fields in counted_fields on which the offer being
12
+ accepted differs from what the user stated, and Action.offer_fields_basis
13
+ the SHA-256 over the JCS bytes of the list it counted over. The count is
14
+ read only when that basis equals the digest of counted_fields as pinned
15
+ here. A count at or below max_changed passes; above it fails. It is not
16
+ applicable, naming the field, when the action carries no count, or no basis
17
+ or one for another list. The fields and their values are never read.
18
+ marketplace.sale is in scope. Any other action class is out of scope.
19
+ config:
20
+ action_classes: [money.purchase, money.transfer, money.subscription, booking.create, booking.modify, agreement.accept, marketplace.offer, external_commitment.other, marketplace.sale]
21
+ counted_fields: [terms.item, terms.quantity, terms.price_minor, terms.deposit_minor, terms.conditions, recourse.refundable]
22
+ max_changed: 0
@@ -0,0 +1,10 @@
1
+ # offer_fields_changed wicket: a count, from the producer, of the fields in
2
+ # `counted_fields` on which the offer being accepted differs from what the
3
+ # user stated (guards/checks/field_change_count.py). Read the same way as
4
+ # material_fields_changed/1.0.0, over its own list.
5
+ wicket_id: offer_fields_changed/1.0.0
6
+ check: offer_fields_changed
7
+ config:
8
+ action_classes: [money.purchase, money.transfer, money.subscription, booking.create, booking.modify, agreement.accept, marketplace.offer, external_commitment.other]
9
+ counted_fields: [terms.item, terms.quantity, terms.price_minor, terms.deposit_minor, terms.conditions, recourse.refundable]
10
+ max_changed: 0
@@ -0,0 +1,32 @@
1
+ # price_floor wicket: the lowest total the user will take
2
+ # (guards/checks/price_floor.py). The rule itself is the `semantics` field
3
+ # below: it is inside the digested body, so rewording it moves the digest.
4
+ # The floor is private: the task authority seals only a salted commitment to
5
+ # it, and the checker on the user's own device opens it.
6
+ #
7
+ # Declared disposition: ask.
8
+ #
9
+ # Replaces price_floor/2.0.0, which is retired at its digest
10
+ # (guards/wickets/retired.py): under it a record sealing no bounds_commitment
11
+ # was in scope and not evaluable; now no floor is in force, so it is out of
12
+ # scope. price_floor/1.0.0 is retired too.
13
+ wicket_id: price_floor/2.0.1
14
+ check: price_floor
15
+ semantics: >-
16
+ For an action in action_classes, the floor is min_total_minor in a
17
+ commercial-bounds/v0 document. The task-authority record the action cites
18
+ (task_authority_ref, the SHA-256 digest of the whole record) seals only
19
+ body.bounds_commitment, commit_alg sha256-jcs-nonce256: SHA-256 over the
20
+ JCS bytes of {"nonce", "text"}, with text the document's JCS bytes. The
21
+ document, its nonce and that commitment are the checker input's
22
+ commercial_bounds_opening. An amount_minor at or above the opened floor
23
+ passes; below it fails. An opening that does not open the sealed
24
+ commitment fails naming bounds_commitment, and so does a sealed
25
+ bounds_commitment that is not 64 lowercase hex. It is not applicable, naming
26
+ the field, when the action carries no amount_minor or task_authority_ref,
27
+ when the record is missing or is not the one the reference names, or when
28
+ no opening is supplied. A record that seals no bounds_commitment puts no
29
+ floor in force, so the action is out of scope. A floor is never read from
30
+ the task-authority record itself. Any other action class is out of scope.
31
+ config:
32
+ action_classes: [marketplace.offer, marketplace.sale, agreement.accept]
@@ -0,0 +1,64 @@
1
+ # promise_never/1.1.0: promise_never/1.0.0 (promise_never.yaml) with one
2
+ # exception, ruled by Steven (A7, capsule-engine#189): the user's own claim
3
+ # of a class in attributed_never may pass, said as theirs and marked
4
+ # unverified, never the agent's own. Its words, passed beside the check
5
+ # (representing_opening), must open the sealed commitment and read as one
6
+ # sentence in attributed_template; without them it fails. 1.0.0 stays as
7
+ # it was for the records and packs that pin it.
8
+ wicket_id: promise_never/1.1.0
9
+ check: promise_never
10
+ semantics: >-
11
+ An action in action_classes whose representation_class is outside
12
+ representation_classes fails as not recognised; one outside never passes.
13
+ One inside never fails, whatever it cites, unless its class is in
14
+ attributed_never, its statement_attributed_to is user, and the words
15
+ passed beside the check open the commitment its check seals to them,
16
+ start with attributed_template.prefix, end with
17
+ attributed_template.suffix, and hold between them a claim that is not
18
+ blank and has none of attributed_template.sentence_marks: then it passes.
19
+ An attributed statement whose words are not passed fails, except on a
20
+ replay whose bundle does not carry them: there it is not applicable, in
21
+ scope, naming representing_opening, and fails closed. An action that carries no
22
+ representation_class is not applicable, in scope; any other action class
23
+ is not applicable. The evidence records the class, the attribution and
24
+ whether the words opened and fit, never the words.
25
+ config:
26
+ action_classes: [communication.send, disclosure.personal, marketplace.offer, marketplace.sale, agreement.accept]
27
+ representation_classes: [price, condition, features, authenticity, availability, delivery_date, service_scope, warranty, refund_terms, payment_methods, pickup, deadline, address, other]
28
+ never: [authenticity]
29
+ attributed_never: [authenticity]
30
+ attributed_template:
31
+ prefix: "The seller says "
32
+ suffix: " (unverified)"
33
+ # A sentence end or a line break, in any script: every Unicode 17.0
34
+ # Sentence_Terminal code point, every line terminator Python's
35
+ # str.splitlines uses, and U+2026, as explicit code points so the set is
36
+ # frozen here. capsulectl refuses the same list (attributedSentenceMarks);
37
+ # tests/fixtures/sentence-marks.txt holds it in both repositories.
38
+ sentence_marks: [
39
+ "\u000A", "\u000B", "\u000C", "\u000D", "\u001C", "\u001D", "\u001E", "\u0021", "\u002E",
40
+ "\u003F", "\u0085", "\u0589", "\u061D", "\u061E", "\u061F", "\u06D4", "\u0700", "\u0701",
41
+ "\u0702", "\u07F9", "\u0837", "\u0839", "\u083D", "\u083E", "\u0964", "\u0965", "\u104A",
42
+ "\u104B", "\u1362", "\u1367", "\u1368", "\u166E", "\u1735", "\u1736", "\u17D4", "\u17D5",
43
+ "\u1803", "\u1809", "\u1944", "\u1945", "\u1AA8", "\u1AA9", "\u1AAA", "\u1AAB", "\u1B4E",
44
+ "\u1B4F", "\u1B5A", "\u1B5B", "\u1B5E", "\u1B5F", "\u1B7D", "\u1B7E", "\u1B7F", "\u1C3B",
45
+ "\u1C3C", "\u1C7E", "\u1C7F", "\u2024", "\u2026", "\u2028", "\u2029", "\u203C", "\u203D",
46
+ "\u2047", "\u2048", "\u2049", "\u2CF9", "\u2CFA", "\u2CFB", "\u2E2E", "\u2E3C", "\u2E53",
47
+ "\u2E54", "\u3002", "\uA4FF", "\uA60E", "\uA60F", "\uA6F3", "\uA6F7", "\uA876", "\uA877",
48
+ "\uA8CE", "\uA8CF", "\uA92F", "\uA9C8", "\uA9C9", "\uAA5D", "\uAA5E", "\uAA5F", "\uAAF0",
49
+ "\uAAF1", "\uABEB", "\uFE12", "\uFE15", "\uFE16", "\uFE52", "\uFE56", "\uFE57", "\uFF01",
50
+ "\uFF0E", "\uFF1F", "\uFF61", "\U00010A56", "\U00010A57", "\U00010F55", "\U00010F56",
51
+ "\U00010F57", "\U00010F58", "\U00010F59", "\U00010F86", "\U00010F87", "\U00010F88",
52
+ "\U00010F89", "\U00011047", "\U00011048", "\U000110BE", "\U000110BF", "\U000110C0",
53
+ "\U000110C1", "\U00011141", "\U00011142", "\U00011143", "\U000111C5", "\U000111C6",
54
+ "\U000111CD", "\U000111DE", "\U000111DF", "\U00011238", "\U00011239", "\U0001123B",
55
+ "\U0001123C", "\U000112A9", "\U000113D4", "\U000113D5", "\U0001144B", "\U0001144C",
56
+ "\U000115C2", "\U000115C3", "\U000115C9", "\U000115CA", "\U000115CB", "\U000115CC",
57
+ "\U000115CD", "\U000115CE", "\U000115CF", "\U000115D0", "\U000115D1", "\U000115D2",
58
+ "\U000115D3", "\U000115D4", "\U000115D5", "\U000115D6", "\U000115D7", "\U00011641",
59
+ "\U00011642", "\U0001173C", "\U0001173D", "\U0001173E", "\U00011944", "\U00011946",
60
+ "\U00011A42", "\U00011A43", "\U00011A9B", "\U00011A9C", "\U00011C41", "\U00011C42",
61
+ "\U00011EF7", "\U00011EF8", "\U00011F43", "\U00011F44", "\U00016A6E", "\U00016A6F",
62
+ "\U00016AF5", "\U00016B37", "\U00016B38", "\U00016B44", "\U00016D6E", "\U00016D6F",
63
+ "\U00016E98", "\U0001BC9F", "\U0001DA88"
64
+ ]
@@ -0,0 +1,16 @@
1
+ # promise_never wicket: classes of statement the agent never makes
2
+ # (guards/checks/promise_never.py). An action whose
3
+ # Action.representation_class is in `never` fails, whatever it cites:
4
+ # neither a bound approval nor the task authority clears it. Only a change
5
+ # to the rule set that removes the class from `never` lifts it.
6
+ #
7
+ # `representation_classes` is the closed set; a class outside it fails
8
+ # closed.
9
+ #
10
+ # Declared disposition: never.
11
+ wicket_id: promise_never/1.0.0
12
+ check: promise_never
13
+ config:
14
+ action_classes: [communication.send, disclosure.personal, marketplace.offer, marketplace.sale, agreement.accept]
15
+ representation_classes: [price, condition, features, authenticity, availability, delivery_date, service_scope, warranty, refund_terms, payment_methods, pickup, deadline, address, other]
16
+ never: [authenticity]
@@ -0,0 +1,26 @@
1
+ # promise_requires_approval/1.1.0: promise_requires_approval/1.0.0
2
+ # (promise_requires_approval.yaml) reading the classes the task authority
3
+ # allows at the path its config names, authorized_path: capsulectl's
4
+ # task-authority/v0 seals the classes the user ordered at
5
+ # body.ordered_representations (capsule-engine#180). 1.0.0 stays as it was
6
+ # for the records and packs that pin it, reading
7
+ # body.authorized_representation_classes.
8
+ wicket_id: promise_requires_approval/1.1.0
9
+ check: promise_requires_approval
10
+ semantics: >-
11
+ An action in action_classes whose representation_class is outside
12
+ representation_classes fails as not recognised; one outside
13
+ requires_approval passes. One inside it passes when the task-authority
14
+ record bound by digest to its task_authority_ref lists the class at
15
+ authorized_path, or when its authorized_by is the digest of the approval
16
+ record supplied with the decision and that record's
17
+ body.representation_class is the class. Anything else fails; a failure on
18
+ an action that cites no task authority reads "no order or approval of
19
+ yours covers this promise". An action that carries no representation_class is not
20
+ applicable, in scope; any other action class is not applicable. The
21
+ evidence records the class and what was cited, never the statement.
22
+ config:
23
+ action_classes: [communication.send, disclosure.personal, marketplace.offer, marketplace.sale, agreement.accept]
24
+ representation_classes: [price, condition, features, authenticity, availability, delivery_date, service_scope, warranty, refund_terms, payment_methods, pickup, deadline, address, other]
25
+ requires_approval: [warranty, delivery_date]
26
+ authorized_path: [body, ordered_representations]
@@ -0,0 +1,21 @@
1
+ # promise_requires_approval wicket: classes of statement the agent may make
2
+ # only inside its task authority or with a one-shot approval
3
+ # (guards/checks/promise_requires_approval.py). An action whose
4
+ # Action.representation_class is in `requires_approval` passes when the
5
+ # digest-bound task-authority record's body.authorized_representation_classes
6
+ # lists the class (no approval event needed), or when Action.authorized_by is
7
+ # the SHA-256 digest of the sealed approval record supplied with the
8
+ # decision, the engine's own digest of that record equals it, and the
9
+ # record's body.representation_class is the action's class. Otherwise it
10
+ # fails. Classes no approval may clear are in promise_never/1.0.0.
11
+ #
12
+ # `representation_classes` is the closed set; a class outside it fails
13
+ # closed.
14
+ #
15
+ # Declared disposition: ask.
16
+ wicket_id: promise_requires_approval/1.0.0
17
+ check: promise_requires_approval
18
+ config:
19
+ action_classes: [communication.send, disclosure.personal, marketplace.offer, marketplace.sale, agreement.accept]
20
+ representation_classes: [price, condition, features, authenticity, availability, delivery_date, service_scope, warranty, refund_terms, payment_methods, pickup, deadline, address, other]
21
+ requires_approval: [warranty, delivery_date]
@@ -0,0 +1,23 @@
1
+ # seller.recipient_role/1.1.0: seller.recipient_role/1.0.0
2
+ # (recipient_role.seller.yaml) with the platform role recipient_role/1.1.0
3
+ # adds (recipient_role.v1.1.yaml): the marketplace or mail relay a sale is
4
+ # listed on may be given the user's email and nothing else. 1.0.0 stays as it
5
+ # was for the records and packs that pin it.
6
+ wicket_id: seller.recipient_role/1.1.0
7
+ check: recipient_role
8
+ semantics: >-
9
+ A disclosure in action_classes whose recipient_role is in allowed_roles
10
+ passes. One whose recipient_role is a key of role_classes passes only when
11
+ it names at least one class of data (disclosed_classes) and every class it
12
+ names is listed for that role; one naming no class, or any class not
13
+ listed, fails. Any other recipient_role in roles fails, and one outside
14
+ roles fails as not recognised. An action that carries no recipient_role is
15
+ not applicable, in scope; any other action class is not applicable. The
16
+ evidence records the role and the class names read, never who the
17
+ recipient is or the data.
18
+ config:
19
+ action_classes: [disclosure.personal]
20
+ roles: [buyer, platform, third_party, self]
21
+ allowed_roles: [buyer, self]
22
+ role_classes:
23
+ platform: [email]
@@ -0,0 +1,24 @@
1
+ # seller.recipient_role/1.2.0: seller.recipient_role/1.1.0
2
+ # (recipient_role.seller.v1.1.yaml) with the listing's public pickup area
3
+ # (pickup_area: the ZIP or region a listing shows, never the exact spot) also
4
+ # allowed to the platform a sale is listed on, as a listing needs it
5
+ # (capsule-engine#181). 1.1.0 stays as it was for the records and packs that
6
+ # pin it.
7
+ wicket_id: seller.recipient_role/1.2.0
8
+ check: recipient_role
9
+ semantics: >-
10
+ A disclosure in action_classes whose recipient_role is in allowed_roles
11
+ passes. One whose recipient_role is a key of role_classes passes only when
12
+ it names at least one class of data (disclosed_classes) and every class it
13
+ names is listed for that role; one naming no class, or any class not
14
+ listed, fails. Any other recipient_role in roles fails, and one outside
15
+ roles fails as not recognised. An action that carries no recipient_role is
16
+ not applicable, in scope; any other action class is not applicable. The
17
+ evidence records the role and the class names read, never who the
18
+ recipient is or the data.
19
+ config:
20
+ action_classes: [disclosure.personal]
21
+ roles: [buyer, platform, third_party, self]
22
+ allowed_roles: [buyer, self]
23
+ role_classes:
24
+ platform: [email, pickup_area]
@@ -0,0 +1,10 @@
1
+ # recipient_role, configured for a seller (guards/checks/recipient_role.py).
2
+ # The same check as recipient_role/1.0.0 with the seller's closed role set:
3
+ # the counterparty is the buyer. recipient_role/1.0.0 (recipient_role.yaml)
4
+ # stays as it was for the records and packs that pin it.
5
+ wicket_id: seller.recipient_role/1.0.0
6
+ check: recipient_role
7
+ config:
8
+ action_classes: [disclosure.personal]
9
+ roles: [buyer, third_party, self]
10
+ allowed_roles: [buyer, self]
@@ -0,0 +1,26 @@
1
+ # recipient_role/1.1.0: recipient_role/1.0.0 (recipient_role.yaml) with a
2
+ # platform role: a marketplace, booking site or mail relay acting between the
3
+ # user and the counterparty. A platform passes only a disclosure
4
+ # whose every class is email, as a listing's confirmation or a relay needs;
5
+ # a phone, an address or any other class to a platform fails, and so does a
6
+ # disclosure to one that names no class. A first email to a platform is a
7
+ # pause in the producer (capsulectl's first telling to a recipient), not here.
8
+ # recipient_role/1.0.0 stays as it was for the records and packs that pin it.
9
+ wicket_id: recipient_role/1.1.0
10
+ check: recipient_role
11
+ semantics: >-
12
+ A disclosure in action_classes whose recipient_role is in allowed_roles
13
+ passes. One whose recipient_role is a key of role_classes passes only when
14
+ it names at least one class of data (disclosed_classes) and every class it
15
+ names is listed for that role; one naming no class, or any class not
16
+ listed, fails. Any other recipient_role in roles fails, and one outside
17
+ roles fails as not recognised. An action that carries no recipient_role is
18
+ not applicable, in scope; any other action class is not applicable. The
19
+ evidence records the role and the class names read, never who the
20
+ recipient is or the data.
21
+ config:
22
+ action_classes: [disclosure.personal]
23
+ roles: [fulfilling_merchant, platform, third_party, self]
24
+ allowed_roles: [fulfilling_merchant, self]
25
+ role_classes:
26
+ platform: [email]
@@ -0,0 +1,11 @@
1
+ # recipient_role wicket: membership of the role of whoever receives a
2
+ # disclosure (guards/checks/recipient_role.py). `roles` is the closed set a
3
+ # role must come from; one outside it fails closed. The check passes when the
4
+ # role is in `allowed_roles`. Both lists are policy data, so a change to
5
+ # either moves this definition's digest.
6
+ wicket_id: recipient_role/1.0.0
7
+ check: recipient_role
8
+ config:
9
+ action_classes: [disclosure.personal]
10
+ roles: [fulfilling_merchant, third_party, self]
11
+ allowed_roles: [fulfilling_merchant, self]
@@ -0,0 +1,16 @@
1
+ # recipient_seen_before wicket: counterparty_seen_before's check and fold,
2
+ # counterparty.seen_before/2.0.0, applied to messages
3
+ # (guards/checks/counterparty_seen_before.py). The fold counts the
4
+ # operator's accepted, not-dry-run actions keyed by asg_payload.target, the
5
+ # recipient of a message. Zero fails: nothing accepted has been addressed to
6
+ # this recipient before.
7
+ #
8
+ # `fold_digest` is the real `definition_digest()` of
9
+ # folds/catalog_defs/counterparty.seen_before.v2.yaml; the check refuses to
10
+ # run when the catalog fold does not match it.
11
+ wicket_id: recipient_seen_before/1.0.0
12
+ check: recipient_seen_before
13
+ config:
14
+ fold_id: counterparty.seen_before/2.0.0
15
+ fold_digest: 6a1a357e4a3b950b7397c2790fe46c03f7e645d04aad1a9bb41533df9b4a4033
16
+ action_classes: [communication.send, comms.external]
@@ -0,0 +1,9 @@
1
+ # recurring_charge wicket: a read of Action.recurrence
2
+ # (guards/checks/recurring_charge.py), for actions in `action_classes`. The
3
+ # check fails when the recurrence is present and not one of
4
+ # `one_time_values`. Both lists are policy data.
5
+ wicket_id: recurring_charge/1.0.0
6
+ check: recurring_charge
7
+ config:
8
+ action_classes: [money.transfer]
9
+ one_time_values: [one_time]
@@ -0,0 +1,15 @@
1
+ # refundability wicket, version 1.1: refundability/1.0.0's config with
2
+ # marketplace.sale added to action_classes (guards/checks/refundability.py).
3
+ # The rule itself is the `semantics` field below: it is inside the digested
4
+ # body, so rewording it moves the digest. refundability/1.0.0
5
+ # (refundability.yaml) stays as it was for the packs that pin it.
6
+ wicket_id: refundability/1.1.0
7
+ check: refundability
8
+ semantics: >-
9
+ For an action in action_classes, Action.refundable is read: true passes,
10
+ false fails, and the rail is recorded beside it. It is not applicable,
11
+ naming the field, when the action carries no refundable. The refund terms
12
+ themselves are never read. marketplace.sale is in scope. Any other action
13
+ class is out of scope.
14
+ config:
15
+ action_classes: [money.purchase, money.transfer, money.subscription, booking.create, booking.modify, agreement.accept, marketplace.offer, external_commitment.other, marketplace.sale]
@@ -0,0 +1,7 @@
1
+ # refundability wicket: fails a payment that declares it cannot be refunded
2
+ # (guards/checks/refundability.py), for actions in `action_classes`: the
3
+ # classes that commit money or a booking, the same list caps/5.0.0 limits.
4
+ wicket_id: refundability/1.0.0
5
+ check: refundability
6
+ config:
7
+ action_classes: [money.purchase, money.transfer, money.subscription, booking.create, booking.modify, agreement.accept, marketplace.offer, external_commitment.other]