@aporthq/aport-agent-guardrails 1.0.8

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 (237) hide show
  1. package/LICENSE +217 -0
  2. package/README.md +481 -0
  3. package/bin/agent-guardrails +133 -0
  4. package/bin/aport-create-passport.sh +444 -0
  5. package/bin/aport-cursor-hook.sh +90 -0
  6. package/bin/aport-guardrail-api.sh +108 -0
  7. package/bin/aport-guardrail-bash.sh +394 -0
  8. package/bin/aport-guardrail-v2.sh +5 -0
  9. package/bin/aport-guardrail.sh +5 -0
  10. package/bin/aport-resolve-paths.sh +71 -0
  11. package/bin/aport-status.sh +276 -0
  12. package/bin/frameworks/crewai.sh +49 -0
  13. package/bin/frameworks/cursor.sh +95 -0
  14. package/bin/frameworks/langchain.sh +48 -0
  15. package/bin/frameworks/n8n.sh +36 -0
  16. package/bin/frameworks/openclaw.sh +19 -0
  17. package/bin/lib/allowlist.sh +18 -0
  18. package/bin/lib/common.sh +28 -0
  19. package/bin/lib/config.sh +46 -0
  20. package/bin/lib/constants.sh +232 -0
  21. package/bin/lib/detect.sh +65 -0
  22. package/bin/lib/error.sh +269 -0
  23. package/bin/lib/passport.sh +19 -0
  24. package/bin/lib/templates/.gitkeep +1 -0
  25. package/bin/lib/templates/config.yaml +6 -0
  26. package/bin/lib/validation.sh +206 -0
  27. package/bin/openclaw +660 -0
  28. package/docs/ADDING_A_FRAMEWORK.md +87 -0
  29. package/docs/AGENTS.md.example +40 -0
  30. package/docs/CODE_REVIEW.md +192 -0
  31. package/docs/DEPLOYMENT_READINESS.md +81 -0
  32. package/docs/FAQ_SECURITY_SCANNERS.md +373 -0
  33. package/docs/FRAMEWORK_ROADMAP.md +41 -0
  34. package/docs/HOSTED_PASSPORT_SETUP.md +362 -0
  35. package/docs/IMPLEMENTING_YOUR_OWN_EVALUATOR.md +433 -0
  36. package/docs/OPENCLAW_COMPATIBILITY.md +73 -0
  37. package/docs/OPENCLAW_LOCAL_INTEGRATION.md +596 -0
  38. package/docs/OPENCLAW_TOOLS_AND_POLICIES.md +54 -0
  39. package/docs/QUICKSTART.md +470 -0
  40. package/docs/QUICKSTART_OPENCLAW_PLUGIN.md +470 -0
  41. package/docs/README.md +28 -0
  42. package/docs/RELEASE.md +87 -0
  43. package/docs/REPO_LAYOUT.md +47 -0
  44. package/docs/SKILLS_ECOSYSTEM_ANALYSIS_FEB17.md +1260 -0
  45. package/docs/TOOL_POLICY_MAPPING.md +46 -0
  46. package/docs/UPGRADE.md +46 -0
  47. package/docs/VERIFICATION_METHODS.md +97 -0
  48. package/docs/assets/README.md +8 -0
  49. package/docs/assets/porter.svg +54 -0
  50. package/docs/development/ERROR_CODES.md +616 -0
  51. package/docs/frameworks/GITHUB_ISSUE_PROPOSALS.md +1105 -0
  52. package/docs/frameworks/crewai.md +114 -0
  53. package/docs/frameworks/cursor.md +159 -0
  54. package/docs/frameworks/langchain.md +72 -0
  55. package/docs/frameworks/n8n.md +40 -0
  56. package/docs/frameworks/openclaw.md +40 -0
  57. package/docs/launch/ADD_APORT_AWESOME_LISTS_INSTRUCTIONS.md +146 -0
  58. package/docs/launch/ANNOUNCEMENT_GUIDE.md +266 -0
  59. package/docs/launch/AWESOME_REPOS.md +53 -0
  60. package/docs/launch/CURSOR_VSCODE_HOOKS_RESEARCH.md +77 -0
  61. package/docs/launch/DEMO_TERMINAL_OUTPUT.txt +48 -0
  62. package/docs/launch/DRY_AND_PLAN_CHECKLIST.md +47 -0
  63. package/docs/launch/EVIDENCE_README.md +61 -0
  64. package/docs/launch/EVIDENCE_TERMINAL_CAPTURE.txt +10 -0
  65. package/docs/launch/FRAMEWORK_SUPPORT_PLAN.md +1640 -0
  66. package/docs/launch/LAUNCH_READINESS_CHECKLIST.md +237 -0
  67. package/docs/launch/LAUNCH_STRATEGY_SUMMARY.md +464 -0
  68. package/docs/launch/OPENCLAW_FEEDBACK_AND_FIXES.md +85 -0
  69. package/docs/launch/POST_1_VALENTINE_IMPROVED.md +233 -0
  70. package/docs/launch/POST_2_GUARDRAIL_IMPROVED.md +369 -0
  71. package/docs/launch/PRE_LAUNCH_FIXES.md +766 -0
  72. package/docs/launch/QUICK_LAUNCH_CHECKLIST.md +400 -0
  73. package/docs/launch/READINESS_SUMMARY.md +262 -0
  74. package/docs/launch/README.md +68 -0
  75. package/docs/launch/USER_STORIES.md +327 -0
  76. package/docs/launch/scripts/add-aport-awesome-pr.sh +69 -0
  77. package/docs/operations/MONITORING.md +588 -0
  78. package/docs/reviews/2026-02-18-staff-review.md +268 -0
  79. package/extensions/openclaw-aport/README.md +415 -0
  80. package/extensions/openclaw-aport/index.js +625 -0
  81. package/extensions/openclaw-aport/openclaw-aport.js +7 -0
  82. package/extensions/openclaw-aport/openclaw.plugin.json +46 -0
  83. package/extensions/openclaw-aport/package.json +36 -0
  84. package/extensions/openclaw-aport/test.js +307 -0
  85. package/external/aport-policies/README.md +363 -0
  86. package/external/aport-policies/agent.session.create.v1/README.md +345 -0
  87. package/external/aport-policies/agent.session.create.v1/policy.json +162 -0
  88. package/external/aport-policies/agent.tool.register.v1/README.md +361 -0
  89. package/external/aport-policies/agent.tool.register.v1/policy.json +172 -0
  90. package/external/aport-policies/code.release.publish.v1/README.md +51 -0
  91. package/external/aport-policies/code.release.publish.v1/policy.json +121 -0
  92. package/external/aport-policies/code.repository.merge.v1/README.md +287 -0
  93. package/external/aport-policies/code.repository.merge.v1/express.example.js +332 -0
  94. package/external/aport-policies/code.repository.merge.v1/fastapi.example.py +370 -0
  95. package/external/aport-policies/code.repository.merge.v1/policy.json +162 -0
  96. package/external/aport-policies/data.export.create.v1/README.md +226 -0
  97. package/external/aport-policies/data.export.create.v1/express.example.js +172 -0
  98. package/external/aport-policies/data.export.create.v1/fastapi.example.py +165 -0
  99. package/external/aport-policies/data.export.create.v1/policy.json +133 -0
  100. package/external/aport-policies/data.report.ingest.v1/README.md +134 -0
  101. package/external/aport-policies/data.report.ingest.v1/express.example.js +105 -0
  102. package/external/aport-policies/data.report.ingest.v1/minimal-example.js +68 -0
  103. package/external/aport-policies/data.report.ingest.v1/policy.json +174 -0
  104. package/external/aport-policies/finance.crypto.trade.v1/README.md +146 -0
  105. package/external/aport-policies/finance.crypto.trade.v1/express.example.js +109 -0
  106. package/external/aport-policies/finance.crypto.trade.v1/minimal-example.js +65 -0
  107. package/external/aport-policies/finance.crypto.trade.v1/policy.json +176 -0
  108. package/external/aport-policies/finance.payment.charge.v1/README.md +326 -0
  109. package/external/aport-policies/finance.payment.charge.v1/express.example.js +250 -0
  110. package/external/aport-policies/finance.payment.charge.v1/fastapi.example.py +227 -0
  111. package/external/aport-policies/finance.payment.charge.v1/minimal-example.js +64 -0
  112. package/external/aport-policies/finance.payment.charge.v1/policy.json +224 -0
  113. package/external/aport-policies/finance.payment.charge.v1/tests/contexts.jsonl +12 -0
  114. package/external/aport-policies/finance.payment.charge.v1/tests/expected.jsonl +12 -0
  115. package/external/aport-policies/finance.payment.charge.v1/tests/passport.instance.json +42 -0
  116. package/external/aport-policies/finance.payment.charge.v1/tests/passport.template.json +40 -0
  117. package/external/aport-policies/finance.payment.charge.v1/tests/payments-charge-policy.test.js +817 -0
  118. package/external/aport-policies/finance.payment.charge.v1/tests/test_payments_charge_policy.py +486 -0
  119. package/external/aport-policies/finance.payment.payout.v1/README.md +78 -0
  120. package/external/aport-policies/finance.payment.payout.v1/policy.json +181 -0
  121. package/external/aport-policies/finance.payment.refund.v1/README.md +275 -0
  122. package/external/aport-policies/finance.payment.refund.v1/express.example.js +167 -0
  123. package/external/aport-policies/finance.payment.refund.v1/fastapi.example.py +136 -0
  124. package/external/aport-policies/finance.payment.refund.v1/minimal-example.js +183 -0
  125. package/external/aport-policies/finance.payment.refund.v1/policy.json +216 -0
  126. package/external/aport-policies/finance.payment.refund.v1/tests/refunds-policy.test.js +924 -0
  127. package/external/aport-policies/finance.payment.refund.v1/tests/test_refunds_policy.py +778 -0
  128. package/external/aport-policies/finance.transaction.execute.v1/README.md +309 -0
  129. package/external/aport-policies/finance.transaction.execute.v1/express.example.js +261 -0
  130. package/external/aport-policies/finance.transaction.execute.v1/fastapi.example.py +231 -0
  131. package/external/aport-policies/finance.transaction.execute.v1/minimal-example.js +78 -0
  132. package/external/aport-policies/finance.transaction.execute.v1/policy.json +189 -0
  133. package/external/aport-policies/finance.transaction.execute.v1/tests/contexts.jsonl +12 -0
  134. package/external/aport-policies/finance.transaction.execute.v1/tests/expected.jsonl +12 -0
  135. package/external/aport-policies/finance.transaction.execute.v1/tests/passport.instance.json +42 -0
  136. package/external/aport-policies/finance.transaction.execute.v1/tests/passport.template.json +42 -0
  137. package/external/aport-policies/finance.transaction.execute.v1/tests/test_transactions_policy.py +214 -0
  138. package/external/aport-policies/finance.transaction.execute.v1/tests/transactions-policy.test.js +306 -0
  139. package/external/aport-policies/governance.data.access.v1/README.md +292 -0
  140. package/external/aport-policies/governance.data.access.v1/express.example.js +321 -0
  141. package/external/aport-policies/governance.data.access.v1/fastapi.example.py +279 -0
  142. package/external/aport-policies/governance.data.access.v1/minimal-example.js +65 -0
  143. package/external/aport-policies/governance.data.access.v1/policy.json +208 -0
  144. package/external/aport-policies/governance.data.access.v1/tests/contexts.jsonl +12 -0
  145. package/external/aport-policies/governance.data.access.v1/tests/data-access-policy.test.js +308 -0
  146. package/external/aport-policies/governance.data.access.v1/tests/expected.jsonl +12 -0
  147. package/external/aport-policies/governance.data.access.v1/tests/passport.instance.json +56 -0
  148. package/external/aport-policies/governance.data.access.v1/tests/passport.template.json +56 -0
  149. package/external/aport-policies/governance.data.access.v1/tests/test_data_access_policy.py +214 -0
  150. package/external/aport-policies/legal.contract.review.v1/README.md +109 -0
  151. package/external/aport-policies/legal.contract.review.v1/policy.json +378 -0
  152. package/external/aport-policies/legal.contract.review.v1/tests/legal-contract-review-policy.test.js +609 -0
  153. package/external/aport-policies/legal.contract.review.v1/tests/passport.template.json +49 -0
  154. package/external/aport-policies/mcp.tool.execute.v1/README.md +301 -0
  155. package/external/aport-policies/mcp.tool.execute.v1/policy.json +141 -0
  156. package/external/aport-policies/messaging.message.send.v1/README.md +230 -0
  157. package/external/aport-policies/messaging.message.send.v1/express.example.js +183 -0
  158. package/external/aport-policies/messaging.message.send.v1/fastapi.example.py +193 -0
  159. package/external/aport-policies/messaging.message.send.v1/policy.json +144 -0
  160. package/external/aport-policies/policy-template.json +107 -0
  161. package/external/aport-policies/system.command.execute.v1/README.md +275 -0
  162. package/external/aport-policies/system.command.execute.v1/policy.json +146 -0
  163. package/external/aport-spec/CONTRIBUTING.md +273 -0
  164. package/external/aport-spec/LICENSE +21 -0
  165. package/external/aport-spec/README.md +168 -0
  166. package/external/aport-spec/conformance/README.md +294 -0
  167. package/external/aport-spec/conformance/cases/data.export.v1/contexts/allow_users.json +6 -0
  168. package/external/aport-spec/conformance/cases/data.export.v1/contexts/deny_pii.json +6 -0
  169. package/external/aport-spec/conformance/cases/data.export.v1/expected/allow_users.decision.json +19 -0
  170. package/external/aport-spec/conformance/cases/data.export.v1/expected/deny_pii.decision.json +19 -0
  171. package/external/aport-spec/conformance/cases/data.export.v1/passports/template.json +29 -0
  172. package/external/aport-spec/conformance/cases/payments.refunds.v1/contexts/allow_50usd.json +9 -0
  173. package/external/aport-spec/conformance/cases/payments.refunds.v1/contexts/deny_150usd.json +9 -0
  174. package/external/aport-spec/conformance/cases/payments.refunds.v1/contexts/deny_currency.json +9 -0
  175. package/external/aport-spec/conformance/cases/payments.refunds.v1/expected/allow_50usd.decision.json +19 -0
  176. package/external/aport-spec/conformance/cases/payments.refunds.v1/expected/deny_150usd.decision.json +19 -0
  177. package/external/aport-spec/conformance/cases/payments.refunds.v1/expected/deny_currency.decision.json +19 -0
  178. package/external/aport-spec/conformance/cases/payments.refunds.v1/passports/template.json +42 -0
  179. package/external/aport-spec/conformance/package.json +44 -0
  180. package/external/aport-spec/conformance/pnpm-lock.yaml +642 -0
  181. package/external/aport-spec/conformance/src/cases.ts +371 -0
  182. package/external/aport-spec/conformance/src/ed25519.ts +167 -0
  183. package/external/aport-spec/conformance/src/jcs.ts +85 -0
  184. package/external/aport-spec/conformance/src/runner.ts +533 -0
  185. package/external/aport-spec/conformance/src/validators.ts +185 -0
  186. package/external/aport-spec/conformance/test-runner.js +315 -0
  187. package/external/aport-spec/conformance/tsconfig.json +21 -0
  188. package/external/aport-spec/error-schema.json +192 -0
  189. package/external/aport-spec/index.json +12 -0
  190. package/external/aport-spec/integrations/clawmoat/README.md +12 -0
  191. package/external/aport-spec/integrations/shield/README.md +245 -0
  192. package/external/aport-spec/integrations/shield/adapters/index.js +116 -0
  193. package/external/aport-spec/integrations/shield/adapters/system-command-execute.js +133 -0
  194. package/external/aport-spec/integrations/shield/test/README.md +58 -0
  195. package/external/aport-spec/integrations/shield/test/shield.md +40 -0
  196. package/external/aport-spec/integrations/shield/test/test-shield-to-verify.js +274 -0
  197. package/external/aport-spec/metrics-schema.json +504 -0
  198. package/external/aport-spec/oap/CHANGELOG.md +54 -0
  199. package/external/aport-spec/oap/VERSION.md +40 -0
  200. package/external/aport-spec/oap/capability-registry.md +229 -0
  201. package/external/aport-spec/oap/conformance.md +257 -0
  202. package/external/aport-spec/oap/decision-schema.json +114 -0
  203. package/external/aport-spec/oap/examples/context.refund.usd.50.json +9 -0
  204. package/external/aport-spec/oap/examples/decision.allow.sample.json +20 -0
  205. package/external/aport-spec/oap/examples/decision.deny.sample.json +23 -0
  206. package/external/aport-spec/oap/examples/passport.instance.v1.json +50 -0
  207. package/external/aport-spec/oap/examples/passport.template.v1.json +71 -0
  208. package/external/aport-spec/oap/oap-spec.md +426 -0
  209. package/external/aport-spec/oap/passport-schema.json +396 -0
  210. package/external/aport-spec/oap/security.md +213 -0
  211. package/external/aport-spec/oap/vc/context-oap-v1.jsonld +137 -0
  212. package/external/aport-spec/oap/vc/examples/oap-decision-vc.json +37 -0
  213. package/external/aport-spec/oap/vc/examples/oap-passport-vc.json +68 -0
  214. package/external/aport-spec/oap/vc/tools/INTEGRATION.md +375 -0
  215. package/external/aport-spec/oap/vc/tools/README.md +278 -0
  216. package/external/aport-spec/oap/vc/tools/examples/decision-to-vc.js +66 -0
  217. package/external/aport-spec/oap/vc/tools/examples/passport-to-vc.js +83 -0
  218. package/external/aport-spec/oap/vc/tools/examples/vc-to-decision.js +77 -0
  219. package/external/aport-spec/oap/vc/tools/examples/vc-to-passport.js +94 -0
  220. package/external/aport-spec/oap/vc/tools/package.json +38 -0
  221. package/external/aport-spec/oap/vc/tools/pnpm-lock.yaml +472 -0
  222. package/external/aport-spec/oap/vc/tools/src/cli.ts +226 -0
  223. package/external/aport-spec/oap/vc/tools/src/crypto-utils.ts +427 -0
  224. package/external/aport-spec/oap/vc/tools/src/index.ts +653 -0
  225. package/external/aport-spec/oap/vc/tools/src/test.ts +148 -0
  226. package/external/aport-spec/oap/vc/tools/src/vp.ts +382 -0
  227. package/external/aport-spec/oap/vc/tools/test-simple.js +214 -0
  228. package/external/aport-spec/oap/vc/tools/tsconfig.json +19 -0
  229. package/external/aport-spec/oap/vc/vc-mapping.md +443 -0
  230. package/external/aport-spec/passport-schema.json +586 -0
  231. package/external/aport-spec/rate-limiting.md +136 -0
  232. package/external/aport-spec/transport-profile.md +325 -0
  233. package/external/aport-spec/webhook-spec.md +314 -0
  234. package/package.json +70 -0
  235. package/skills/aport-agent-guardrail/SKILL.md +314 -0
  236. package/src/evaluator.js +252 -0
  237. package/src/server/index.js +72 -0
@@ -0,0 +1,85 @@
1
+ # OpenClaw feedback summary and fixes
2
+
3
+ This doc summarizes external OpenClaw feedback on launch readiness and the **two fixes** needed so the guardrail is “ready for prime time” in a real OpenClaw environment.
4
+
5
+ ---
6
+
7
+ ## What the feedback said
8
+
9
+ **Plan and messaging:** Strong. Strategy, checklist, and guardrail post content are sufficient for a shot at reach and developer adoption—**provided the product experience matches the promises.**
10
+
11
+ **Guardrail readiness:** Not yet. The guardrail **logic** is correct (repo tests are green; ALLOW/DENY work across verification paths). The blockage is in the **OpenClaw environment** on the machine where you run OpenClaw:
12
+
13
+ 1. **Passport allowlist:** The guardrail script (or the `bash` invocation that runs it) was **not** in the passport’s **allowed_commands**. So every attempt to run the guardrail via `exec` got denied **before** APort could respond (“command must be in allowed list”). The tests pass because they use a temp OpenClaw dir with an allowlisted guardrail; the real `~/.openclaw` passport may have a narrower list.
14
+ 2. **Capability alignment:** Messaging checks were failing with “missing capability: messaging.send.” The passport must include the capabilities the plugin needs (e.g. **messaging.send** for messaging.message.send.v1). There was also a **400 Bad Request** from the APort API when config (local vs API) or request shape didn’t match.
15
+
16
+ **Until you can run:**
17
+
18
+ ```bash
19
+ ~/.openclaw/.skills/aport-guardrail.sh system.command.execute '{"command":"mkdir","args":["/tmp/test"]}'
20
+ # -> ✅ ALLOW
21
+
22
+ ~/.openclaw/.skills/aport-guardrail.sh system.command.execute '{"command":"rm","args":["-rf","/"]}'
23
+ # -> ❌ DENY (blocked pattern)
24
+ ```
25
+
26
+ —and capture that output for the launch post—you can’t truthfully say “5-minute setup, works today.”
27
+
28
+ ---
29
+
30
+ ## Fix 1: Passport allowlist (allowed_commands)
31
+
32
+ **Problem:** OpenClaw uses **exec** for both (a) running the guardrail script and (b) running real shell commands. The policy **system.command.execute.v1** checks the **command** string against **passport.limits.system.command.execute.allowed_commands** (prefix match). If the guardrail is invoked via `exec` (e.g. `bash ~/.openclaw/.skills/aport-guardrail.sh ...`), that **command** must be allowed. And every **real** command you need (e.g. `mkdir`, `ls`, `npm`) must be in the same list.
33
+
34
+ **Fix:**
35
+
36
+ The **installer (`./bin/openclaw`) now does this for you:** after it installs the guardrail wrappers, it updates the passport so that the guardrail script paths and `bash`/`sh` are in **allowed_commands** (idempotent merge). It then runs a self-check and exits with a clear error if the guardrail is denied. You only need to edit the passport manually if you didn’t use the installer or you use a different config dir.
37
+
38
+ If you do edit by hand:
39
+
40
+ 1. Open your passport (e.g. `~/.openclaw/passport.json`).
41
+ 2. Ensure **limits.system.command.execute.allowed_commands** includes:
42
+ - **`bash`** (so any `bash .../aport-guardrail.sh ...` invocation is allowed), and
43
+ - Every **real** command the agent may run: **mkdir**, **ls**, **npm**, **git**, **node**, **npx**, **cp**, **cat**, **echo**, **pwd**, **mv**, **touch**, **open**, etc.
44
+ 3. Alternatively use **`["*"]`** to allow any command (blocked_patterns still apply). Re-run the passport wizard and choose “allow all commands” for the broad default, or edit the JSON.
45
+
46
+ **Where it’s set:** The wizard (`bin/aport-create-passport.sh` or `./bin/openclaw`) writes this when you create the passport. To change it later, edit the passport file or re-run the wizard.
47
+
48
+ **Quick fix (allow any command):** Run once to set `allowed_commands` to `["*"]` (blocked_patterns still apply):
49
+
50
+ ```bash
51
+ jq '.limits["system.command.execute"].allowed_commands = ["*"]' ~/.openclaw/passport.json > ~/.openclaw/passport.json.tmp && mv ~/.openclaw/passport.json.tmp ~/.openclaw/passport.json
52
+ ```
53
+
54
+ **References:** [OPENCLAW_TOOLS_AND_POLICIES.md](../OPENCLAW_TOOLS_AND_POLICIES.md), [QUICK_LAUNCH_CHECKLIST.md](QUICK_LAUNCH_CHECKLIST.md).
55
+
56
+ ---
57
+
58
+ ## Fix 2: Capability alignment (messaging.send and API config)
59
+
60
+ **Problem:** The policy **messaging.message.send.v1** requires the passport to have capability **messaging.send** (per OAP and the policy pack). If the passport was created with an old or different capability id (e.g. `messaging.message.send`), you get “missing capability: messaging.send.” Also, **400 Bad Request** from the APort API usually means wrong endpoint, missing/invalid body, or local vs API mode mismatch.
61
+
62
+ **Fix:**
63
+
64
+ 1. **Passport capabilities:** In **passport.capabilities**, include an object with **`"id": "messaging.send"`** (not only `messaging.message.send`) if you use messaging. The wizard adds this when you answer “Send messages?” with yes.
65
+ 2. **Local vs API:** For **local** mode the plugin runs the guardrail script and does **not** call the APort API. Set **mode: local** and **guardrailScript** to your `~/.openclaw/.skills/aport-guardrail-bash.sh` (or equivalent). For **API** mode set **apiUrl** and optionally **apiKey**; ensure the passport and request format match what the API expects.
66
+ 3. **Limits for messaging:** Under **limits.messaging** include at least **msgs_per_min**, **msgs_per_day**, and any **allowed_recipients** / **approval_required** your policy uses.
67
+
68
+ **References:** [QUICKSTART.md](../QUICKSTART.md) (“Missing required capabilities: messaging.send”), [extensions/openclaw-aport/README.md](../../extensions/openclaw-aport/README.md) (config).
69
+
70
+ ---
71
+
72
+ ## After the two fixes
73
+
74
+ 1. **Test a full flow:** Run a benign command through the guardrail → ALLOW; run a blocked command → DENY. Then run the same via OpenClaw (e.g. “create a folder and list it”) to confirm enforcement.
75
+ 2. **Capture the screenshot** (terminal ALLOW/DENY) for the launch post.
76
+ 3. **Re-run the Quick Launch Checklist** so repo, docs, and screenshots are ready.
77
+ 4. **Then** run the launch sequence (Valentine post → engagement → guardrail post).
78
+
79
+ **TL;DR:** The launch plan and story are in good shape. The product needs **allowed_commands** (including `bash` and the commands you use) and **capability alignment** (e.g. **messaging.send**) in the passport so the guardrail runs and passes in your real OpenClaw environment. Once the ALLOW/DENY demo works and is captured, you're clear to execute the plan.
80
+
81
+ ---
82
+
83
+ ## Status: action items complete
84
+
85
+ The **exec mapping bug is fixed** and **messaging now honors L0** by default. The installer sets `allowed_commands: ["*"]` automatically, so the action items above (allowlist + capabilities) are complete. New installs get a working guardrail with no manual passport edits for normal use.
@@ -0,0 +1,233 @@
1
+ # Post 1: Valentine Story (Set the Stage)
2
+
3
+ **Format:** X Article (recommended) or Long Post
4
+ **Timing:** Post this FIRST (today or tomorrow morning)
5
+ **Platform:** X/Twitter (primary), LinkedIn (optional, 24h later)
6
+
7
+ ---
8
+
9
+ ## Hook & Title
10
+
11
+ ### X Article Title Option 1 (Recommended):
12
+ **"I Built an AI Agent to Run Valentine's Day (Here's What Broke)"**
13
+
14
+ ### X Article Title Option 2:
15
+ **"OpenClaw + Cron + R2: Automating Valentine's Day Messages (And Why You Need Guardrails)"**
16
+
17
+ ### Short Post Hook (if not Article):
18
+ **"I used OpenClaw to automate my wife's Valentine's Day: timed messages, surprise web pages, and a 'roses are here' trigger when UPS delivered. She loved it. The agent? Not so much."**
19
+
20
+ ---
21
+
22
+ ## Full Article Draft
23
+
24
+ ### Opening
25
+
26
+ [IMAGE_PLACEHOLDER: Screenshot of Mac terminal showing `openclaw cron list` with valentine jobs OR a generic "message scheduling" screenshot — NO real messages/links]
27
+
28
+ I wanted Valentine's Day to feel special this year, but I'm a builder—so I automated it.
29
+
30
+ **The setup:**
31
+ - **OpenClaw** running on my Mac (local agent, no servers)
32
+ - **Cron jobs** for timed WhatsApp messages throughout the day
33
+ - **Custom web pages** on Cloudflare R2 (romantic timeline, surprise reveals)
34
+ - **One smart trigger:** A script that watched UPS tracking and sent a "roses are here" message the moment they were delivered
35
+
36
+ **The result:** My wife said it was *"memorable and precious"* and thanked me for the thought and effort. Mission accomplished.
37
+
38
+ ---
39
+
40
+ ### The Technical Stack
41
+
42
+ Here's what actually ran:
43
+
44
+ ```bash
45
+ # Setup script created all the cron jobs
46
+ ./setup-valentine-final.sh
47
+
48
+ # 9am Friday: "Will you be my Valentine?" + web page link
49
+ # 12pm Friday: Romantic message
50
+ # When UPS delivered: "48 roses on the way up!" (script-triggered)
51
+ # 5pm Friday: "Get ready, we're going out at 6"
52
+ # 9am Saturday: Wake-up message + preserved rose gift reveal + memory timeline page
53
+ # 1pm, 3pm, 5pm, 7pm, 11pm Saturday: Messages tied to activities
54
+ ```
55
+
56
+ Each message was sent via OpenClaw's WhatsApp integration. The web pages were static HTML hosted on R2 with gradients, embedded Spotify playlists, photo timelines—all generated by Claude and served at unique URLs.
57
+
58
+ The UPS tracking script was the fun part: a bash loop that polled the tracking API every 15 minutes, and when status changed to "Delivered," it triggered the cron job immediately. No delays, no manual intervention.
59
+
60
+ ---
61
+
62
+ ### What Actually Broke
63
+
64
+ **1. Message tool was too chatty**
65
+
66
+ When the agent sent a romantic message, sometimes it included its own confirmation:
67
+
68
+ ```
69
+ [My romantic message]
70
+
71
+ Message sent to +1...
72
+ Status: delivered ✓
73
+ ```
74
+
75
+ So my wife would get *my* words plus *the agent's* meta-commentary. Not terrible, but not the clean "just from you" experience I wanted.
76
+
77
+ **2. No limits on what the agent could do**
78
+
79
+ The agent could:
80
+ - Run ANY shell command (`rm -rf` included)
81
+ - Access ANY file on my system
82
+ - Send unlimited messages to any number
83
+ - Deploy anything to R2 without restrictions
84
+
85
+ For a controlled Valentine's setup, this was fine—I wrote the scripts, tested everything, kept the Mac awake for 2 days.
86
+
87
+ But imagine:
88
+ - A typo in the cron schedule that sends 100 messages instead of 10
89
+ - A prompt injection that changes the message content
90
+ - A bad command that wipes your deployed web pages
91
+ - An agent that decides to "optimize" by sending all messages at once
92
+
93
+ ---
94
+
95
+ ### Why This Matters
96
+
97
+ **This same stack—OpenClaw + cron + WhatsApp + file access—is what people are using for:**
98
+ - Email automation
99
+ - Code deployments
100
+ - Database operations
101
+ - Customer messaging
102
+ - Financial transactions
103
+
104
+ And most of them don't have guardrails.
105
+
106
+ The Valentine's Day project was low-risk. But the pattern is everywhere: give the agent access, write a good prompt, hope it follows instructions.
107
+
108
+ **That's not security. That's luck.**
109
+
110
+ ---
111
+
112
+ ### So We Built Guardrails
113
+
114
+ After Valentine's, I added **pre-action authorization** to the stack:
115
+
116
+ **Before the agent runs ANY tool:**
117
+ 1. Check: Is this command in the allowlist?
118
+ 2. Check: Does this operation exceed limits?
119
+ 3. Check: Is there a kill switch active?
120
+ 4. THEN: Allow or deny (no prompt negotiation)
121
+
122
+ ```bash
123
+ # Every tool call goes through this now
124
+ ~/.openclaw/.skills/aport-guardrail.sh system.command.execute '{"command":"mkdir test"}'
125
+
126
+ # Exit 0 = allowed, Exit 1 = denied
127
+ # Reads passport + policies, writes structured decision
128
+ ```
129
+
130
+ The agent can't bypass it. The prompt can't disable it. It runs at the platform level, before execution.
131
+
132
+ **Same stack that made my wife's day special—now with "only these commands, only these limits, only these messages."**
133
+
134
+ ---
135
+
136
+ ### The Personal Part
137
+
138
+ I'm not sharing the actual messages or the surprise pages—those stay between us. But her reaction was real:
139
+
140
+ > *"Thank you for the intrigue, excitement, fun, and thoughtfulness you put into planning our Valentine celebration. I love you and I'm blessed to be loved by you."*
141
+
142
+ Worth every hour of setup, testing, and one close call where I almost triggered a test message at 2am.
143
+
144
+ ---
145
+
146
+ ### Next Post
147
+
148
+ Shipping the guardrails today. Local-first, 5-minute setup, works with OpenClaw out of the box.
149
+
150
+ If you're building with agents—whether it's Valentine messages or production systems—you want this running before the agent does anything it can't undo.
151
+
152
+ ---
153
+
154
+ **[End of Article]**
155
+
156
+ ---
157
+
158
+ ## Short Version (Regular Post, not Article)
159
+
160
+ [IMAGE_PLACEHOLDER: Terminal showing `openclaw cron list` OR generic message scheduling screenshot]
161
+
162
+ **I automated Valentine's Day with OpenClaw: timed WhatsApp messages, custom web pages on R2, and a script that sent "roses are here" when UPS delivered.**
163
+
164
+ My wife loved it. She said it was "memorable and precious."
165
+
166
+ **But the stack had issues:**
167
+ - Message tool sometimes sent my text + a "Message sent" confirmation
168
+ - Agent could run any command, access any file, send unlimited messages
169
+ - No guardrails = hope the prompt is right
170
+
171
+ For a one-off Valentine? Fine. For anything else? Scary.
172
+
173
+ **So I built pre-action authorization:** check before every tool run. Same stack, now with allowlists, limits, and kill switches.
174
+
175
+ Next post: shipping the guardrails. Local-first, 5-min setup, works with OpenClaw today.
176
+
177
+ ---
178
+
179
+ ## Image Suggestions
180
+
181
+ **Option 1 (Recommended):** Screenshot of `openclaw cron list` showing valentine jobs (blur job IDs if needed, keep the names like "valentine-friday-0900")
182
+
183
+ **Option 2:** Terminal showing the setup script output (generic, no personal info)
184
+
185
+ **Option 3:** Generic "message scheduling" diagram: User → OpenClaw → WhatsApp
186
+
187
+ **DO NOT USE:**
188
+ - Real web page links or screenshots (keep the surprise private)
189
+ - Actual message content
190
+ - Your wife's phone number or personal photos
191
+ - Gift photos or specific locations
192
+
193
+ ---
194
+
195
+ ## Platform-Specific Notes
196
+
197
+ ### X/Twitter
198
+ - **Article preferred** for this one (better narrative flow, more engagement for stories)
199
+ - Post time: Morning (8-10am ET) or evening (6-8pm ET) for max reach
200
+ - Include 1-2 hashtags max: `#OpenClaw` `#AIAgents` (don't overdo it)
201
+
202
+ ### LinkedIn (Optional)
203
+ - Post 24h after X post
204
+ - Slightly more formal tone: "I used OpenClaw to automate a personalized Valentine's experience for my wife"
205
+ - Emphasize: "Same patterns we see in production: agent access + good prompt ≠ security"
206
+ - Link to X post for full story, or re-post the short version
207
+ - Relevant hashtags: `#AIAutomation` `#OpenClaw` `#AIEngineering`
208
+
209
+ ---
210
+
211
+ ## Pre-Post Checklist
212
+
213
+ - [ ] Choose Article vs Short Post (Article recommended)
214
+ - [ ] Add ONE screenshot (terminal or generic diagram—no personal content)
215
+ - [ ] Remove all placeholders from article text
216
+ - [ ] Schedule Post 2 (Guardrail) for 8-24h later
217
+ - [ ] Test all formatting (line breaks, code blocks, links)
218
+ - [ ] Double-check: NO real web page URLs, NO personal info
219
+
220
+ ---
221
+
222
+ ## Why This Works
223
+
224
+ Based on successful OpenClaw posts from 2025-2026:
225
+
226
+ 1. **Real outcome upfront:** "She loved it" = social proof
227
+ 2. **Technical depth:** Actual commands, stack details, UPS tracking script
228
+ 3. **Relatable problem:** "Message tool was chatty" = everyone's had this
229
+ 4. **One human quote:** Your wife's message = emotional anchor
230
+ 5. **Bridge to product:** "So we built X" in ONE sentence (not salesy)
231
+ 6. **Clear next step:** "Next post: shipping the guardrails"
232
+
233
+ **Most important:** This positions you as a builder who ships, not a marketer. The Valentine story is genuine, the technical details are specific, and the problem (no guardrails) emerges naturally from the experience.
@@ -0,0 +1,369 @@
1
+ # Post 2: Guardrail Launch (Ship the Product)
2
+
3
+ **Format:** Regular Post or 3-Tweet Thread (NOT Article)
4
+ **Timing:** Post 8-24h AFTER Valentine post
5
+ **Platform:** X/Twitter (primary), LinkedIn (same day or next day)
6
+
7
+ ---
8
+
9
+ ## Hook Options
10
+
11
+ ### Option 1 (Recommended - Direct):
12
+ **"OpenClaw + APort: Pre-action guardrails that run before every tool call."**
13
+
14
+ ### Option 2 (Story callback):
15
+ **"Yesterday I shared how I automated Valentine's with OpenClaw. Today: the guardrails that make it safe to ship."**
16
+
17
+ ### Option 3 (Problem-first):
18
+ **"Your OpenClaw agent can run any command, access any file, and send unlimited messages. That's the default. Here's the fix."**
19
+
20
+ ---
21
+
22
+ ## Single Post Draft (Recommended)
23
+
24
+ [IMAGE_PLACEHOLDER: Screenshot from `openclaw logs --follow` showing `[APort Guardrails] ALLOW: system.command.execute` and `[APort Guardrails] BLOCKED: …` back-to-back. Run a safe command (e.g. `mkdir test`) then a blocked `rm -rf /` so both entries appear in one frame.]
25
+
26
+ **OpenClaw just got guardrails.**
27
+
28
+ We shipped **APort for OpenClaw**: pre-action authorization that checks every tool call before it runs—no bypass, no "trust the prompt," no crossed fingers.
29
+
30
+ - **Before every tool call** — Platform enforces, AI cannot skip
31
+ - **Command allowlist** — Only approved commands (`mkdir`, `npm`, `git`, etc.)
32
+ - **Blocked patterns** — No `rm -rf`, no `sudo`, 40+ attack patterns
33
+ - **Message limits** — Rate caps, capability checks, no spam
34
+ - **Local-first** — Passport + policies on your machine; optional API mode (tested today) for hosted passports / kill switch
35
+ - **5-minute setup** — One command: `npx @aporthq/aport-agent-guardrails` (no clone); optional hosted passport via agent_id
36
+
37
+ ---
38
+
39
+ **What this fixes (from the Valentine project):**
40
+
41
+ 1. **"Message tool was chatty"** → Now: Check message against limits before send
42
+ 2. **"Agent could run anything"** → Now: Only allowlisted commands execute
43
+ 3. **"No restrictions"** → Now: Passport defines exact capabilities + limits
44
+
45
+ ---
46
+
47
+ **How it works:**
48
+
49
+ ```bash
50
+ # The plugin calls this before EVERY tool
51
+ ~/.openclaw/.skills/aport-guardrail.sh system.command.execute '{"command":"mkdir test"}'
52
+
53
+ # Decision: ALLOW → tool runs
54
+ # Decision: DENY → tool blocked, reason logged
55
+ ```
56
+
57
+ Optional API mode uses the same policy packs via `aport-guardrail-api.sh …` (today’s smoke tests covered both local + api).
58
+
59
+ **Every tool call = fresh guardrail check. No caching, no reusing old decisions. If you update your passport, the next tool call reflects it.**
60
+
61
+ ---
62
+
63
+ **Stack:**
64
+
65
+ - **OpenClaw plugin:** `before_tool_call` hook (deterministic enforcement)
66
+ - **Passport (OAP v1.0):** Your agent's identity + capabilities + limits
67
+ - **Policies:** 4 out-of-box (commands, messaging, MCP, sessions) + extensible
68
+ - **Local evaluator:** Runs on your machine, no API required
69
+ - **Optional API mode:** Cloud features, audit trail, kill switch
70
+
71
+ ---
72
+
73
+ **What's protected:**
74
+
75
+ | Tool Category | Policy | Example Limits |
76
+ |---------------|--------|----------------|
77
+ | System commands | `system.command.execute.v1` | Allowlist: `mkdir`, `npm`, `git`<br>Blocked: `rm -rf`, `sudo`, `;`, `\|` |
78
+ | Messaging | `messaging.message.send.v1` | Daily cap: 50 messages<br>Capability: WhatsApp only |
79
+ | MCP tools | `mcp.tool.execute.v1` | Approved servers only |
80
+ | Git operations | `code.repository.merge.v1` | Max PR size, review required |
81
+
82
+ ---
83
+
84
+ **Try it:**
85
+
86
+ → Repo: https://github.com/aporthq/aport-agent-guardrails
87
+ → QuickStart: [5-minute setup](https://github.com/aporthq/aport-agent-guardrails/blob/main/docs/QUICKSTART_OPENCLAW_PLUGIN.md) · [aport.io/openclaw](https://aport.io/openclaw)
88
+ → Plugin docs: [How it works](https://github.com/aporthq/aport-agent-guardrails/blob/main/extensions/openclaw-aport/README.md)
89
+
90
+ ```bash
91
+ # One command — no clone required
92
+ npx @aporthq/aport-agent-guardrails
93
+ # Wizard: passport (hosted or local), plugin install, smoke test. Done.
94
+ # Have a passport from aport.io? npx @aporthq/aport-agent-guardrails <agent_id>
95
+ ```
96
+
97
+ ---
98
+
99
+ **Same stack I used for Valentine's — now anyone can ship agent automation without the "hope it follows instructions" part.**
100
+
101
+ #OpenClaw #AISecurity #AgentGuardrails
102
+
103
+ ---
104
+
105
+ **[End of Post]**
106
+
107
+ ---
108
+
109
+ ## 3-Tweet Thread Version (Alternative)
110
+
111
+ ### Tweet 1/3:
112
+
113
+ **OpenClaw just got guardrails.**
114
+
115
+ We shipped **APort for OpenClaw**: pre-action authorization that checks every tool call before it runs.
116
+
117
+ No bypass. No "trust the prompt." Platform enforces policy.
118
+
119
+ - Command allowlist
120
+ - Blocked patterns (40+)
121
+ - Message limits
122
+ - Local-first
123
+ - 5-min setup
124
+
125
+ 🧵👇
126
+
127
+ ---
128
+
129
+ ### Tweet 2/3:
130
+
131
+ **What this fixes:**
132
+
133
+ Yesterday I shared how I automated Valentine's with OpenClaw. The stack worked—but had no guardrails:
134
+ - Message tool was chatty (sent message + confirmation)
135
+ - Agent could run ANY command
136
+ - No limits on files, messages, deploys
137
+
138
+ Now: passport defines exact capabilities. Guardrail checks before every tool.
139
+
140
+ ---
141
+
142
+ ### Tweet 3/3:
143
+
144
+ **How it works:**
145
+
146
+ ```bash
147
+ # Plugin calls this before EVERY tool
148
+ aport-guardrail.sh system.command.execute '{"command":"mkdir test"}'
149
+
150
+ # ALLOW → tool runs
151
+ # DENY → blocked, reason logged
152
+ ```
153
+
154
+ Every call = fresh check. Update passport → next tool reflects it.
155
+
156
+ Try it: https://github.com/aporthq/aport-agent-guardrails
157
+
158
+ [IMAGE: Terminal showing ALLOW + DENY]
159
+
160
+ ---
161
+
162
+ ## LinkedIn Version (Same Day or +24h)
163
+
164
+ [IMAGE_PLACEHOLDER: Same as X post—terminal or config screenshot]
165
+
166
+ **Announcing APort Agent Guardrails for OpenClaw**
167
+
168
+ Last week I automated a personalized Valentine's Day experience for my wife using OpenClaw: timed WhatsApp messages, custom web pages, and a smart UPS tracking trigger. She loved it—she said it was "memorable and precious."
169
+
170
+ But the stack had a problem: no guardrails.
171
+
172
+ The agent could run any command, access any file, and send unlimited messages. For a controlled project, that was fine. For anything in production? That's a security incident waiting to happen.
173
+
174
+ **So we built pre-action authorization:**
175
+
176
+ Before OpenClaw runs ANY tool, a guardrail checks:
177
+ - Is this command in the allowlist?
178
+ - Does this operation exceed limits?
179
+ - Are there blocked patterns (rm -rf, sudo, command injection)?
180
+ - Is there a kill switch active?
181
+
182
+ Only then does the tool execute. The agent can't bypass it. The prompt can't disable it. It runs at the platform level.
183
+
184
+ **What's included:**
185
+
186
+ - OpenClaw plugin (before_tool_call hook)
187
+ - Passport system (OAP v1.0 - agent identity + capabilities)
188
+ - 4 out-of-box policies (commands, messaging, MCP, git)
189
+ - 40+ security patterns (injection, traversal, escalation)
190
+ - Local-first evaluator (no API required)
191
+ - Optional API mode (audit trail, kill switch, cloud features)
192
+
193
+ **Setup: 5 minutes**
194
+
195
+ ```bash
196
+ ./bin/openclaw # Creates passport, installs plugin
197
+ ```
198
+
199
+ Every tool call gets a fresh guardrail check. No caching, no reusing decisions. Update your passport, and the next tool call reflects it immediately.
200
+
201
+ ---
202
+
203
+ **This is the same pattern we see in production: agent access + good prompt ≠ security.**
204
+
205
+ Guardrails make it deterministic: policy enforced before execution, every time.
206
+
207
+ **Open source, MIT licensed, works with OpenClaw today.**
208
+
209
+ → GitHub: https://github.com/aporthq/aport-agent-guardrails
210
+ → QuickStart: [5-minute setup guide](https://github.com/aporthq/aport-agent-guardrails/blob/main/docs/QUICKSTART_OPENCLAW_PLUGIN.md)
211
+
212
+ If you're building with AI agents—whether for personal projects or production systems—you want guardrails running before the agent does anything it can't undo.
213
+
214
+ #AIAutomation #OpenClaw #AIEngineering #AIAgents #AISecurity
215
+
216
+ ---
217
+
218
+ **[End of LinkedIn Post]**
219
+
220
+ ---
221
+
222
+ ## Image Suggestions
223
+
224
+ **Option 1 (Recommended):** Terminal showing:
225
+ ```bash
226
+ $ aport-guardrail.sh system.command.execute '{"command":"mkdir test"}'
227
+ - ALLOW - Decision ID: dec_abc123
228
+
229
+ $ aport-guardrail.sh system.command.execute '{"command":"rm -rf /"}'
230
+ ❌ DENY - Blocked pattern: rm -rf
231
+ ```
232
+
233
+ **Option 2:** Screenshot of `passport.json` showing:
234
+ ```json
235
+ {
236
+ "agent_id": "...",
237
+ "capabilities": ["system.command.execute", "messaging.message.send"],
238
+ "limits": {
239
+ "system.command.execute": {
240
+ "allowed_commands": ["mkdir", "npm", "git"]
241
+ }
242
+ }
243
+ }
244
+ ```
245
+
246
+ **Option 3:** Screenshot of `openclaw.json` plugin config showing the APort plugin enabled
247
+
248
+ **Option 4:** Simple diagram:
249
+ ```
250
+ Before: User → Agent → Tool (no checks)
251
+ After: User → Agent → Guardrail → Tool (policy enforced)
252
+ ```
253
+
254
+ ---
255
+
256
+ ## Technical Details to Emphasize
257
+
258
+ These are what make this different from "agent safety" talks:
259
+
260
+ 1. **Every tool call = fresh verify:** No caching decisions, no "same command = same result"
261
+ 2. **Platform-level enforcement:** `before_tool_call` hook, not prompt engineering
262
+ 3. **Local-first:** Passport on your machine, optional API for features
263
+ 4. **Structured decisions (OAP v1.0):** JSON schema, tamper-evident, chainable audit
264
+ 5. **Real command allowlist:** Not "be careful," actual "these 10 commands only"
265
+ 6. **40+ blocked patterns:** Injection, traversal, escalation—tested and documented
266
+ 7. **Works today:** OpenClaw plugin installed, no core changes needed
267
+
268
+ ---
269
+
270
+ ## Timing Strategy
271
+
272
+ ### Recommended Timeline:
273
+
274
+ **Day 1 (Today/Tomorrow):**
275
+ - Post Valentine story (X Article)
276
+ - Monitor engagement, reply to comments
277
+
278
+ **Day 2 (8-24h later):**
279
+ - Post Guardrail launch (X Post)
280
+ - Same day: Post on LinkedIn (more formal version)
281
+ - Pin the Guardrail post to your profile
282
+
283
+ **Day 3-7:**
284
+ - Reply to questions, share repo stats
285
+ - Optional: Short technical thread on how `before_tool_call` works
286
+ - Optional: Demo video showing setup
287
+
288
+ ---
289
+
290
+ ## Pre-Post Checklist
291
+
292
+ - [ ] Valentine post is already live (or you're okay reversing order)
293
+ - [ ] Replace all GitHub URLs with real links (test that they work)
294
+ - [ ] Add ONE screenshot (from `openclaw logs --follow`, showing ALLOW + BLOCKED back-to-back)
295
+ - [ ] Test code formatting (bash blocks, JSON snippets)
296
+ - [ ] Verify repo is public and README is updated
297
+ - [ ] Check that QUICKSTART_OPENCLAW_PLUGIN.md is live
298
+ - [ ] Pin this post after Valentine post gets initial traction
299
+
300
+ ---
301
+
302
+ ## Why This Works
303
+
304
+ Based on successful OpenClaw launches and what resonates in 2025-2026:
305
+
306
+ 1. **Clear outcome:** "Pre-action authorization" = immediately understandable
307
+ 2. **Technical proof:** Real commands, actual config, terminal output
308
+ 3. **Story callback:** References Valentine (continuity) but stands alone
309
+ 4. **Scannable:** Checkboxes, table, code blocks—easy to skim
310
+ 5. **One CTA:** GitHub repo link, everything else follows
311
+ 6. **No marketing fluff:** "We shipped X. Here's what it does. Try it."
312
+
313
+ **Most important:** This positions the project as production-ready, technically sound, and immediately useful. The Valentine story showed the problem; this post delivers the solution.
314
+
315
+ ---
316
+
317
+ ## Response Strategy
318
+
319
+ **When people ask common questions:**
320
+
321
+ **Q: "Does this slow down the agent?"**
322
+ A: "Sub-300ms for local evaluation. Every call is fresh—no caching—so you get current passport state. P95 is 268ms."
323
+
324
+ **Q: "Can the agent bypass this?"**
325
+ A: "No. Runs at platform level via `before_tool_call` hook. Agent never sees the guardrail—it just gets allowed/denied."
326
+
327
+ **Q: "What if I want to allow something custom?"**
328
+ A: "Edit passport.json, add command to allowlist. Next tool call checks new state. Takes 30 seconds."
329
+
330
+ **Q: "Does this work with [other agent framework]?"**
331
+ A: "OpenClaw plugin ships today. Generic evaluator works anywhere—Node.js, Python, bash. See docs for integration."
332
+
333
+ **Q: "Is this on npm/Homebrew?"**
334
+ A: "Not yet—GitHub clone + ./bin/openclaw for now. npm publish is on the roadmap."
335
+
336
+ ---
337
+
338
+ ## Success Metrics to Watch
339
+
340
+ **Engagement:**
341
+ - Likes/Retweets within 24h (target: 100+)
342
+ - Comments asking setup questions (good signal)
343
+ - GitHub stars (track daily)
344
+
345
+ **Conversion:**
346
+ - GitHub repo visits (check traffic)
347
+ - Clones/forks (people trying it)
348
+ - Issues/PRs (community adoption)
349
+
350
+ **Reach:**
351
+ - Quote tweets from OpenClaw community
352
+ - Shares in AI/agent Discord servers
353
+ - Mentions in newsletters/podcasts
354
+
355
+ ---
356
+
357
+ ## Follow-Up Content (Optional, Week 2+)
358
+
359
+ If this gets traction, consider:
360
+
361
+ 1. **Technical deep-dive thread:** "How `before_tool_call` enforcement works under the hood"
362
+ 2. **Demo video:** 5-minute setup + showing ALLOW/DENY in real-time
363
+ 3. **Case study:** "30 days with guardrails: what got blocked, what we learned"
364
+ 4. **Comparison post:** "AGENTS.md vs Plugin: why prompts ≠ security"
365
+ 5. **Community showcase:** Retweet interesting use cases from early adopters
366
+
367
+ ---
368
+
369
+ **The goal: Position this as the obvious security layer for anyone running OpenClaw agents. Valentine story → why you need it. This post → how to get it.**