accountable-surface 0.3.1__tar.gz

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 (167) hide show
  1. accountable_surface-0.3.1/.gitignore +20 -0
  2. accountable_surface-0.3.1/AGENTS.md +48 -0
  3. accountable_surface-0.3.1/AUTHORS.md +3 -0
  4. accountable_surface-0.3.1/CHANGELOG.md +186 -0
  5. accountable_surface-0.3.1/CLAUDE.md +86 -0
  6. accountable_surface-0.3.1/CONTRIBUTING.md +10 -0
  7. accountable_surface-0.3.1/CREDO.md +23 -0
  8. accountable_surface-0.3.1/LICENSE +110 -0
  9. accountable_surface-0.3.1/PKG-INFO +350 -0
  10. accountable_surface-0.3.1/README.md +320 -0
  11. accountable_surface-0.3.1/THEORY.md +161 -0
  12. accountable_surface-0.3.1/THESIS.md +126 -0
  13. accountable_surface-0.3.1/USAGE.md +312 -0
  14. accountable_surface-0.3.1/docs/INTRODUCTION.md +138 -0
  15. accountable_surface-0.3.1/docs/RELEASE.md +117 -0
  16. accountable_surface-0.3.1/docs/SPEC-actuation.md +79 -0
  17. accountable_surface-0.3.1/docs/SPEC-interoception.md +56 -0
  18. accountable_surface-0.3.1/docs/SPEC-persistence.md +74 -0
  19. accountable_surface-0.3.1/docs/art/accountable-surface-header.svg +1 -0
  20. accountable_surface-0.3.1/docs/art/accountable-surface.art.json +214 -0
  21. accountable_surface-0.3.1/docs/art/actuation-lane.svg +19 -0
  22. accountable_surface-0.3.1/docs/art/journal-chain-lane.svg +19 -0
  23. accountable_surface-0.3.1/docs/art/verdict-composition.svg +17 -0
  24. accountable_surface-0.3.1/docs/brand/README.md +10 -0
  25. accountable_surface-0.3.1/docs/brand/accountable-surface-hero.png +0 -0
  26. accountable_surface-0.3.1/docs/design/2026-06-22-shared-world-surface.md +111 -0
  27. accountable_surface-0.3.1/docs/durable-authority.md +60 -0
  28. accountable_surface-0.3.1/docs/interop-mcp.md +114 -0
  29. accountable_surface-0.3.1/docs/native-control-bridge.md +146 -0
  30. accountable_surface-0.3.1/docs/superpowers/plans/2026-06-22-bilateral-eye-increment-1.md +642 -0
  31. accountable_surface-0.3.1/docs/superpowers/plans/2026-06-22-screen-capture-source.md +657 -0
  32. accountable_surface-0.3.1/docs/superpowers/specs/2026-06-22-actuation-certificate-design.md +110 -0
  33. accountable_surface-0.3.1/docs/superpowers/specs/2026-06-22-bilateral-eye-increment-1-design.md +149 -0
  34. accountable_surface-0.3.1/docs/superpowers/specs/2026-06-22-screen-capture-source-design.md +154 -0
  35. accountable_surface-0.3.1/examples/actuate_demo.py +79 -0
  36. accountable_surface-0.3.1/examples/demo.py +104 -0
  37. accountable_surface-0.3.1/examples/goal_demo.py +104 -0
  38. accountable_surface-0.3.1/examples/grounded_actuate_demo.py +74 -0
  39. accountable_surface-0.3.1/examples/grounding_demo.py +55 -0
  40. accountable_surface-0.3.1/examples/interop_mcp_demo.py +81 -0
  41. accountable_surface-0.3.1/examples/smoke_mcp.py +54 -0
  42. accountable_surface-0.3.1/examples/spa_actuate_demo.py +108 -0
  43. accountable_surface-0.3.1/examples/web_actuate_demo.py +109 -0
  44. accountable_surface-0.3.1/interop/README.md +86 -0
  45. accountable_surface-0.3.1/interop/claude-code.mcp.json +15 -0
  46. accountable_surface-0.3.1/interop/flywheel-lane.json +16 -0
  47. accountable_surface-0.3.1/interop/mcp-server.json +51 -0
  48. accountable_surface-0.3.1/project-docs/specs/SPEC-accountable-surface-forward-delivery.md +33 -0
  49. accountable_surface-0.3.1/project-docs/specs/SPEC-remote-effector-surface.md +255 -0
  50. accountable_surface-0.3.1/pyproject.toml +82 -0
  51. accountable_surface-0.3.1/src/accountable_surface/__init__.py +105 -0
  52. accountable_surface-0.3.1/src/accountable_surface/action_receipt.py +226 -0
  53. accountable_surface-0.3.1/src/accountable_surface/api_effector.py +287 -0
  54. accountable_surface-0.3.1/src/accountable_surface/api_transport.py +34 -0
  55. accountable_surface-0.3.1/src/accountable_surface/authority_cli.py +81 -0
  56. accountable_surface-0.3.1/src/accountable_surface/authority_state.py +278 -0
  57. accountable_surface-0.3.1/src/accountable_surface/authority_store.py +147 -0
  58. accountable_surface-0.3.1/src/accountable_surface/authorized_actuation.py +108 -0
  59. accountable_surface-0.3.1/src/accountable_surface/bounds.py +102 -0
  60. accountable_surface-0.3.1/src/accountable_surface/browser_effector.py +280 -0
  61. accountable_surface-0.3.1/src/accountable_surface/certify.py +54 -0
  62. accountable_surface-0.3.1/src/accountable_surface/credentials.py +44 -0
  63. accountable_surface-0.3.1/src/accountable_surface/effector.py +162 -0
  64. accountable_surface-0.3.1/src/accountable_surface/escalator.py +241 -0
  65. accountable_surface-0.3.1/src/accountable_surface/grant.py +43 -0
  66. accountable_surface-0.3.1/src/accountable_surface/http_driver.py +151 -0
  67. accountable_surface-0.3.1/src/accountable_surface/interop_mcp.py +283 -0
  68. accountable_surface-0.3.1/src/accountable_surface/interop_runtime.py +291 -0
  69. accountable_surface-0.3.1/src/accountable_surface/journal_chain.py +64 -0
  70. accountable_surface-0.3.1/src/accountable_surface/mcp.py +174 -0
  71. accountable_surface-0.3.1/src/accountable_surface/native_control_effector.py +294 -0
  72. accountable_surface-0.3.1/src/accountable_surface/os_effector.py +115 -0
  73. accountable_surface-0.3.1/src/accountable_surface/playwright_driver.py +153 -0
  74. accountable_surface-0.3.1/src/accountable_surface/preconditions.py +69 -0
  75. accountable_surface-0.3.1/src/accountable_surface/protected_paths.py +130 -0
  76. accountable_surface-0.3.1/src/accountable_surface/read_authority.py +260 -0
  77. accountable_surface-0.3.1/src/accountable_surface/read_scopes.py +161 -0
  78. accountable_surface-0.3.1/src/accountable_surface/reference.py +145 -0
  79. accountable_surface-0.3.1/src/accountable_surface/registry.py +246 -0
  80. accountable_surface-0.3.1/src/accountable_surface/remote_actuation.py +145 -0
  81. accountable_surface-0.3.1/src/accountable_surface/remote_durable.py +209 -0
  82. accountable_surface-0.3.1/src/accountable_surface/server.py +229 -0
  83. accountable_surface-0.3.1/src/accountable_surface/surface.py +495 -0
  84. accountable_surface-0.3.1/src/accountable_surface/uia.py +284 -0
  85. accountable_surface-0.3.1/src/accountable_surface/uia_effector.py +260 -0
  86. accountable_surface-0.3.1/src/accountable_surface/uia_transport.py +71 -0
  87. accountable_surface-0.3.1/src/accountable_surface/web_effector.py +198 -0
  88. accountable_surface-0.3.1/src/accountable_surface/world/__init__.py +9 -0
  89. accountable_surface-0.3.1/src/accountable_surface/world/pilot.py +235 -0
  90. accountable_surface-0.3.1/src/accountable_surface/world/prompts.py +100 -0
  91. accountable_surface-0.3.1/src/accountable_surface/world/reel.py +31 -0
  92. accountable_surface-0.3.1/src/accountable_surface/world/screen.py +55 -0
  93. accountable_surface-0.3.1/src/accountable_surface/world/server.py +404 -0
  94. accountable_surface-0.3.1/src/accountable_surface/world/session.py +144 -0
  95. accountable_surface-0.3.1/src/accountable_surface/world/sight.py +176 -0
  96. accountable_surface-0.3.1/src/accountable_surface/world/structure.py +81 -0
  97. accountable_surface-0.3.1/tests/read_authority_helpers.py +43 -0
  98. accountable_surface-0.3.1/tests/test_action_receipt.py +190 -0
  99. accountable_surface-0.3.1/tests/test_actuate.py +252 -0
  100. accountable_surface-0.3.1/tests/test_api_effector.py +332 -0
  101. accountable_surface-0.3.1/tests/test_authority_store.py +74 -0
  102. accountable_surface-0.3.1/tests/test_browser_effector.py +283 -0
  103. accountable_surface-0.3.1/tests/test_browser_integrity.py +166 -0
  104. accountable_surface-0.3.1/tests/test_certify.py +74 -0
  105. accountable_surface-0.3.1/tests/test_durable_authority_cli.py +70 -0
  106. accountable_surface-0.3.1/tests/test_durable_authority_remote.py +211 -0
  107. accountable_surface-0.3.1/tests/test_durable_authority_state.py +205 -0
  108. accountable_surface-0.3.1/tests/test_durable_protected_paths.py +143 -0
  109. accountable_surface-0.3.1/tests/test_effector.py +106 -0
  110. accountable_surface-0.3.1/tests/test_effector_bounds.py +222 -0
  111. accountable_surface-0.3.1/tests/test_escalator.py +222 -0
  112. accountable_surface-0.3.1/tests/test_false_success.py +337 -0
  113. accountable_surface-0.3.1/tests/test_goal.py +103 -0
  114. accountable_surface-0.3.1/tests/test_grounded_actuation.py +75 -0
  115. accountable_surface-0.3.1/tests/test_health.py +24 -0
  116. accountable_surface-0.3.1/tests/test_http_driver.py +161 -0
  117. accountable_surface-0.3.1/tests/test_integrity_redteam.py +689 -0
  118. accountable_surface-0.3.1/tests/test_interoception.py +82 -0
  119. accountable_surface-0.3.1/tests/test_interop_exclusions.py +126 -0
  120. accountable_surface-0.3.1/tests/test_interop_mcp.py +212 -0
  121. accountable_surface-0.3.1/tests/test_journal_chain_tamper.py +75 -0
  122. accountable_surface-0.3.1/tests/test_mcp_actuate.py +300 -0
  123. accountable_surface-0.3.1/tests/test_mcp_stdio.py +88 -0
  124. accountable_surface-0.3.1/tests/test_native_control_effector.py +190 -0
  125. accountable_surface-0.3.1/tests/test_native_control_live.py +49 -0
  126. accountable_surface-0.3.1/tests/test_os_effector.py +119 -0
  127. accountable_surface-0.3.1/tests/test_persistence.py +135 -0
  128. accountable_surface-0.3.1/tests/test_pilot.py +150 -0
  129. accountable_surface-0.3.1/tests/test_preconditions.py +59 -0
  130. accountable_surface-0.3.1/tests/test_read_authority.py +160 -0
  131. accountable_surface-0.3.1/tests/test_reel.py +32 -0
  132. accountable_surface-0.3.1/tests/test_reference.py +81 -0
  133. accountable_surface-0.3.1/tests/test_release_package.py +56 -0
  134. accountable_surface-0.3.1/tests/test_remote_read_authority.py +401 -0
  135. accountable_surface-0.3.1/tests/test_repo_art.py +300 -0
  136. accountable_surface-0.3.1/tests/test_screen.py +237 -0
  137. accountable_surface-0.3.1/tests/test_server.py +107 -0
  138. accountable_surface-0.3.1/tests/test_sight.py +147 -0
  139. accountable_surface-0.3.1/tests/test_surface.py +116 -0
  140. accountable_surface-0.3.1/tests/test_uia_effector.py +297 -0
  141. accountable_surface-0.3.1/tests/test_uia_structure.py +204 -0
  142. accountable_surface-0.3.1/tests/test_verify_journal_standalone.py +73 -0
  143. accountable_surface-0.3.1/tests/test_version_alignment.py +63 -0
  144. accountable_surface-0.3.1/tests/test_web_effector.py +214 -0
  145. accountable_surface-0.3.1/tests/test_world_server.py +96 -0
  146. accountable_surface-0.3.1/tests/test_world_session.py +83 -0
  147. accountable_surface-0.3.1/tools/check_repo_art.py +247 -0
  148. accountable_surface-0.3.1/tools/check_repo_card.py +288 -0
  149. accountable_surface-0.3.1/tools/check_repo_flow.py +83 -0
  150. accountable_surface-0.3.1/tools/face-metrics.json +51 -0
  151. accountable_surface-0.3.1/tools/render_repo_art.py +76 -0
  152. accountable_surface-0.3.1/tools/repo_art.py +276 -0
  153. accountable_surface-0.3.1/tools/repo_card.py +226 -0
  154. accountable_surface-0.3.1/tools/repo_flow.py +169 -0
  155. accountable_surface-0.3.1/verify_journal.py +89 -0
  156. accountable_surface-0.3.1/web/index.html +199 -0
  157. accountable_surface-0.3.1/web/overlay.js +50 -0
  158. accountable_surface-0.3.1/web/overlay.test.mjs +16 -0
  159. accountable_surface-0.3.1/web/recheck.js +22 -0
  160. accountable_surface-0.3.1/web/recheck.test.mjs +38 -0
  161. accountable_surface-0.3.1/web/screen.html +30 -0
  162. accountable_surface-0.3.1/web/screen.js +40 -0
  163. accountable_surface-0.3.1/web/together.html +131 -0
  164. accountable_surface-0.3.1/web/together.js +128 -0
  165. accountable_surface-0.3.1/web/watch.html +99 -0
  166. accountable_surface-0.3.1/web/watch.js +111 -0
  167. accountable_surface-0.3.1/web/world.js +165 -0
@@ -0,0 +1,20 @@
1
+ # secrets / env (never commit)
2
+ .env
3
+ .env.*
4
+ !.env.example
5
+ CLAUDE.local.md
6
+
7
+ # python
8
+ __pycache__/
9
+ *.py[cod]
10
+ *.egg-info/
11
+ build/
12
+ dist/
13
+ .pytest_cache/
14
+ .venv/
15
+ venv/
16
+
17
+ # IO-boundary cache + runtime operator journals (operator-supplied, not source)
18
+ .warden-safe-cache/
19
+ *.session.jsonl
20
+ journals/
@@ -0,0 +1,48 @@
1
+ # AGENTS.md -- Accountable Surface
2
+
3
+ ## Project Boundary
4
+
5
+ Accountable Surface is a public Python workbench for witnessed perception,
6
+ operator-granted action, verification, journals, and MCP integration. It is a
7
+ controlled local action surface: grants are loaded by the operator, actions are
8
+ bounded by effectors, and verification happens after each permitted action.
9
+
10
+ ## Public Delivery Rules
11
+
12
+ - Keep `README.md`, `USAGE.md`, `CHANGELOG.md`, `CONTRIBUTING.md`, `AUTHORS.md`,
13
+ `LICENSE`, `.github/FUNDING.yml`, `.github/workflows/ci.yml`, examples, docs,
14
+ web demos, and package metadata aligned.
15
+ - Public claims must be backed by tests, examples, specs, or reproducible
16
+ commands.
17
+ - Do not commit `.env` files, private grants, journals, local caches, raw
18
+ transcripts, credentials, or private corpus material.
19
+ - Keep the README clear for two audiences: public users deciding what the tool
20
+ does, and developers trying to run or extend it.
21
+
22
+ ## Developer Verification
23
+
24
+ From this repo, with sibling checkouts available:
25
+
26
+ ```powershell
27
+ $env:PYTHONPATH = "src;..\coherence-membrane\src;..\proof-surface\src"
28
+ python -m pip install -e ".[test]"
29
+ python -m pytest
30
+ node --test web/*.test.mjs
31
+ ```
32
+
33
+ If a change touches MCP serving, run the server smoke path with the `[server]`
34
+ extra. If a change touches actuation, add or update a test that proves the
35
+ grant, effect, verification, rollback, or refusal behavior.
36
+
37
+ If a change touches what a remote caller can reach, add or update a test in
38
+ `tests/test_mcp_actuate.py` proving the registry refuses an unexposed action kind
39
+ before any grant is read.
40
+
41
+ If a change touches the Windows escalation ladder (`uia.py`, `uia_effector.py`,
42
+ `uia_transport.py`), add or update a test proving verification re-reads the window
43
+ rather than reading the instrument's own report of its work. That instrument answers
44
+ `ok` for an act it merely dispatched.
45
+
46
+ If a change touches the escalator, add or update a test proving a rung that fell does
47
+ not set the answer. The perception a deeper rung returns carries a full digest and a
48
+ perceptual hash, which is exactly what makes it tempting to read as a result.
@@ -0,0 +1,3 @@
1
+ # Authors
2
+
3
+ - Zain Dana Harper
@@ -0,0 +1,186 @@
1
+ # Changelog
2
+
3
+ ## 0.3.1 - 2026-09-22
4
+
5
+ - Declares the runtime dependencies. The wheel previously installed cleanly and
6
+ then raised `ModuleNotFoundError` on first import, because `coherence-membrane`
7
+ and `proof-surface` were omitted while neither was published. Both are on PyPI
8
+ now, so both are declared. `mcp` stays optional under `[server]`.
9
+ - Adds an OIDC trusted-publishing release workflow with tag/version, artifact
10
+ digest, clean-venv entry-point resolution, and sdist-rebuild gates.
11
+ - Aligns the declared version with the repository's tag history. `pyproject.toml`
12
+ and `accountable_surface.__version__` both read `0.1.0` through the v0.1.0,
13
+ v0.2.1 and v0.3.0 tags, so the MCP `serverInfo` reported `0.1.0` to every
14
+ client regardless of which release was running. A new guard binds the two.
15
+
16
+ ## Unreleased
17
+
18
+ - Interoperable MCP server for the accountable-actuation core
19
+ (`accountable_surface.interop_mcp` + `interop_runtime`). A zero-third-party-dependency
20
+ JSON-RPC-over-stdio server (stdlib framing, no FastMCP) so other harnesses -- Claude
21
+ Code, Codex, Cursor, and the Flywheel bundled lane -- adopt one seam. Exposes the six
22
+ accountable primitives (`perceive`, `propose`/gate, `actuate`, `journal`, `receipt`)
23
+ plus the shipped read-only verb `device_ls`, and `status`/`doctor`. Console script
24
+ `accountable-surface-mcp`. Identity and health answer even where the runtime is not
25
+ installed; the action tools import it lazily and return a named error otherwise.
26
+ - Interop manifests under `interop/`: a Claude Code `.mcp.json` server entry, a generic
27
+ MCP server descriptor, a Flywheel lane entry, and an "add this to your harness" README
28
+ for Codex and Cursor. Concise overview and an evidence-bound comparison over ungated
29
+ computer use in `docs/interop-mcp.md`.
30
+ - Hard exclusions are enforced at the server boundary and asserted by test
31
+ (`tests/test_interop_exclusions.py`): CAPTCHA solving, anti-bot stealth / fingerprint
32
+ patching, reCAPTCHA token harvest, and mass or obfuscated authenticated outreach are
33
+ unreachable through any tool. The `SAFE_READ_VERBS` allowlist stays the boundary;
34
+ `EXCLUDED_CAPABILITIES` is the explicit second assertion of it. Shippable today: the
35
+ read-only `device ls` slice. Target, not shipped: write-class actuation and broad
36
+ browser / app / device breadth.
37
+ - Not a public capability release; prepared on a branch for review.
38
+
39
+ - Native-control bridge (first accountable-computer-use slice, capability-gated).
40
+ Gates one telos native-control verb, `device ls`, through the full loop: perceive,
41
+ preview, gate, act via a Node subprocess, re-perceive, verify, journal. New
42
+ modules `native_control_effector.py` (`NativeControlListEffector`,
43
+ `NativeControlRunner`, `FakeNativeControlRunner`, and a write-class contract stub
44
+ `NativeControlWriteEffector`) and `action_receipt.py` (`ActionReceiptReceptor`,
45
+ `receipt_from_outcome`, `verify_receipts`), the first runtime writer of a
46
+ `project-telos.action-receipt/v1` event.
47
+ - Independent-witness verify: the effector checks the actuator's directory listing
48
+ against the surface's own `os.scandir`, so a wrong or lying listing fails verify
49
+ (false-success control) rather than passing on the actor's own account.
50
+ - Offline receipt verifier `verify_action_receipts.py` (zero-dependency, stdlib
51
+ only): a receipt store re-derives to MATCH; any edited, deleted, or reordered
52
+ receipt yields DRIFT.
53
+ - Safe subset only. The runner refuses any verb outside a read allowlist by
54
+ construction; the evasion and mass-outreach verbs and the mutating device verbs
55
+ are unreachable through the bridge, asserted by test. See
56
+ `docs/native-control-bridge.md` for the wired-vs-target status and the write-class
57
+ compensation contract (defined, not yet exercised).
58
+ - Not a public capability release; prepared on a branch for review.
59
+
60
+ ## 0.2.0 - 2026-09-18
61
+
62
+ - Added optional SQLite authority state for remote MCP actuation: durable
63
+ revocation, atomic finite-use reservations, idempotency, and local recovery
64
+ commands. Unresolved reservations remain unavailable until operator recovery.
65
+ - With durable authority enabled, protected grant, journal, and state paths are
66
+ refused before access, including resolvable aliases and existing hardlinks.
67
+ This does not provide race-proof path access or rollback detection without an
68
+ external protected anchor. See `docs/durable-authority.md` for configuration
69
+ and the tested boundaries.
70
+ - Bug fix: remote `perceive`, `session_journal`, and `actuate` now require
71
+ explicit scoped read grants. Remote writes fail closed unless their required
72
+ before/backup/after/rollback read phases match a known filesystem or API
73
+ target contract, and grants are reloaded just before mutation.
74
+ - Bug fix: `actuate(expected_digest=...)` now refuses before effect when the
75
+ supplied precondition cannot be bound to an explicit observation identity, and
76
+ filesystem/API/browser preconditions reach the gate as state checks instead of
77
+ silently becoming `not-applicable`.
78
+ - Limit: this does not harden filesystem TOCTOU/symlink races, interrupt
79
+ revocation mid-method, or gate local `surface.actuate()` reads.
80
+
81
+ ## 2026-09-13 - First Release Recovery
82
+
83
+ - Refreshed the README verification block from the old `3e4b342` checkpoint to
84
+ current public `main` at `a0bafe6`.
85
+ - Added the first-release checklist in `docs/RELEASE.md`: it records the exact
86
+ test, build, Twine, and proof-install commands for a GitHub source release and
87
+ optional package-registry upload.
88
+ - Publication remains a separate reviewed action. This update prepares evidence
89
+ and documentation; it does not create a tag, GitHub release, PyPI project, or
90
+ registry upload.
91
+
92
+ ## 2026-09-05 - The Escalator That Records Why It Fell
93
+
94
+ - Added `escalator.py`: rungs are climbed in cost order and each fall is recorded with
95
+ the reason that justified paying for the next one. `Ascent.trace()` prints the whole
96
+ climb, one line per rung.
97
+ - A question travels the ladder, not a plan. Each probe restates it in its own nouns or
98
+ declines, which keeps the rungs from acquiring a shared verb vocabulary they do not
99
+ have.
100
+ - A rung that fell never sets the answer. When the ladder runs out the ascent is
101
+ NEEDS_HUMAN, carries `rederivable = "none"`, and hands over the perception from the
102
+ deepest rung that produced one.
103
+ - Added `StructureProbe` (rung 0) and `PixelProbe` (rung 3). A whole control tree
104
+ settles absence as a result; a clipped one falls instead. Pixels never resolve a
105
+ label, and the decline is the probe's honest outcome.
106
+ - Rungs 1 and 2 carry no probe. An escalator that acted to find something out would be
107
+ an actuation no grant authorized, and a test asserts a full climb sends nothing but
108
+ read verbs.
109
+ - Added a false-success control for the ladder: a rung-3 sight with a content digest, a
110
+ perceptual hash, and a coarse description reads like an answer and settles nothing.
111
+
112
+ ## 2026-09-05 - An Escalation Ladder For Windows Applications
113
+
114
+ - Added `UiaStructureOrgan` (rung 0): reads a window's control tree through a driver
115
+ and witnesses only what re-derives by name and role. A walk that had to clip the
116
+ tree reads UNVERIFIED, because a partial tree cannot establish that a control is
117
+ absent.
118
+ - Added `UiaEffector` (rung 1): invokes or sets one control inside one window, under
119
+ the same effector contract as the other five. The construction bound is the window
120
+ title, the journal records it, and a target naming a second window is refused
121
+ before anything is touched.
122
+ - An `invoke` cannot be undone, so the caller declares what should follow it
123
+ (`appears`, `disappears`, `value_is`) and a plan without one is refused at preview
124
+ time. `set_value` is the reversible intent: the prior value is read before the
125
+ write and put back when verification fails.
126
+ - Verification re-reads the window. The instrument answers `ok` for an act it
127
+ dispatched, which says nothing about what the application did with it, so its own
128
+ account is never consulted. Two false-success controls hold that line.
129
+ - Added `uia_transport.PowerShellUiaDriver`, which refuses the blind keystroke verbs
130
+ `input` and `type` by name before it spawns anything. Honest null: the subprocess
131
+ path has no test coverage; `FakeUiaDriver` drives the whole path offline instead.
132
+ - `uia` is refused by name over MCP. It acts on a window belonging to whoever is at
133
+ the machine, and reaching that from off the machine is a separate decision.
134
+ - `scope.allowed_bounds` now treats the window facet as a set, so a grant naming
135
+ several windows covers an effector built for any one of them.
136
+
137
+ ## 2026-09-05 - Actuation Over MCP Behind A Capability Registry
138
+
139
+ - Added the `actuate` MCP tool. A remote caller now closes the whole loop: perceive
140
+ the target, plan, check the operator's gate, act, re-perceive, verify against the
141
+ plan, and roll back a reversible action that did not verify.
142
+ - Added `registry.load_effectors`. The operator names a JSON spec file in
143
+ `ACCOUNTABLE_SURFACE_EFFECTORS` and gets exactly the effectors it lists. With the
144
+ variable unset nothing is actuable over MCP, whatever the grants say.
145
+ - The spec file refuses `command`, `browser`, and `web` by name, each with the
146
+ reason. `doctor` reports every entry it turned down, so an empty registry never
147
+ leaves a typo looking like a deliberate choice.
148
+ - The server reads the registry before the grants, so an action kind the operator
149
+ never exposed causes no grant read and no journal entry.
150
+ - A caller's receipt carries the journal entry for its own action and nothing else
151
+ from the journal. A refusal has the same shape as a success, so a caller cannot
152
+ read success out of the structure of the response.
153
+ - Honest null: when more than one loaded grant names the action kind, the first one
154
+ runs and the receipt says that it did.
155
+
156
+ ## 2026-09-05 - API Actuation And False-Success Controls
157
+
158
+ - Added `ApiEffector`: writes through one declared third-party API under the
159
+ effector contract, named by intent rather than by route. The service allowlist
160
+ bounds method, host, and path shape; the gate allow must be bound to the exact
161
+ plan; verification re-reads the resource instead of trusting the response.
162
+ - Added `credentials.require_secret` / `has_secret`: a credential is read from the
163
+ environment at call time, refused if it carries a newline, and never reaches a
164
+ Plan, an Observation, the journal, or an error message.
165
+ - Added `api_transport.UrllibApiDriver`, a stdlib transport with no policy of its
166
+ own. Honest null: it has no test coverage, because exercising it needs a network
167
+ and a real credential.
168
+ - Added `tests/test_false_success.py`: one control per shipped effector, each
169
+ deliberately producing a wrong result a passing verify could accept.
170
+ - Added `scope.allowed_bounds`, so a grant can bound an effector's reach and not
171
+ only the action kind.
172
+
173
+ ## 2026-06-29 - Public And Developer Delivery Contract
174
+
175
+ - Added `AGENTS.md`, `USAGE.md`, `CHANGELOG.md`, and a forward-delivery spec.
176
+ - Added GitHub Actions CI with sibling checkouts for `coherence-membrane` and
177
+ `proof-surface`, Python tests, and web JavaScript tests.
178
+ - Updated README developer guidance and package URLs.
179
+ - Normalized scanner-blocking dash punctuation across public docs, examples,
180
+ tests, source comments, and web strings.
181
+
182
+ ## Current Status
183
+
184
+ - Runtime: Python 3.10+ package with stdlib-first core and optional MCP server.
185
+ - Surfaces: Python API, examples, web demos, MCP server, docs, tests, and CI.
186
+ - Verification: pytest suite, Node web tests, public surface sweep.
@@ -0,0 +1,86 @@
1
+ # CLAUDE.md -- Accountable Surface
2
+
3
+ A live seam where a model perceives and acts only through accountability:
4
+ witnessed perception (coherence-membrane) + a pre-execution gate (proof-surface)
5
+ + a tamper-evident, durable journal -- under human stewardship.
6
+
7
+ ## Doctrine (non-negotiable)
8
+
9
+ - Perception is **witnessed** (provenance digest + a falsifiable selftest), never a screenshot.
10
+ - **Awareness is not authority** -- the model never supplies its own authorization;
11
+ only operator-loaded grants gate actions; no grant → default-deny.
12
+ - Actuation is **built and gated** (not inert): `propose` is advisory and never
13
+ executes, while `actuate` closes the loop through an effector that acts **only on
14
+ a gate `allow`** for that exact plan, bounded by the operator grant, and **verifies
15
+ its own work** by re-perceiving the result against the intended post-condition.
16
+ Shipped effectors: `FilesystemEffector`, `CommandEffector` (allowlist-only, argv,
17
+ `shell=False`), `WebEffector`, `BrowserEffector`, `ApiEffector` (one declared
18
+ service, intent-named operations, official API only), `UiaEffector` (one window,
19
+ one control named by its accessible label). An irreversible path (e.g. an
20
+ `os.run` that cannot be undone) escalates to `needs-human` unless the operator
21
+ explicitly passes `allow_irreversible`; the effector's construction-bound refuses
22
+ even on a gate `allow` it was not built for. `needs-human` maps to UNVERIFIABLE,
23
+ never rounded up.
24
+ - The **grant** can bound the effector's reach, not only the action kind. An
25
+ effector declares its construction bound through `bound()`, the journal records
26
+ that bound on every actuation, and a grant carrying `scope.allowed_bounds` refuses
27
+ an effector built wider than what the operator granted. Absent that field the grant
28
+ says nothing about reach, which is an honest null rather than enforcement.
29
+ - Reaching an effector from **off the machine** takes two operator decisions, and
30
+ both have to agree. The registry (`ACCOUNTABLE_SURFACE_EFFECTORS`) says which
31
+ effectors a remote caller can reach at all, and it is empty unless the operator
32
+ names a spec file. The grant says what may be done with one. Neither widens the
33
+ other, so an exposed effector with no matching grant still denies. The server reads
34
+ the registry first, so an action kind the operator never exposed is refused before
35
+ any grant is consulted and before any attempt reaches the journal. The registry
36
+ refuses `command`, `browser`, `web`, and `uia` by name, and `doctor` reports every
37
+ spec entry it turned down, so a typo cannot read as an operator who exposed nothing
38
+ on purpose. `allow_irreversible` is absent from the remote path by construction: no
39
+ argument a caller can pass reaches it. A caller's receipt carries the journal entry
40
+ for its own action and no other part of the journal.
41
+ - Reaching a Windows application runs through an **escalation ladder** rather than
42
+ straight to pixels. Rung 0 (`UiaStructureOrgan`) reads the window's control tree and
43
+ witnesses only what re-derives by name and role. Rung 1 (`UiaEffector`) acts on one
44
+ control by its accessible label. Rung 2 is the allowlisted argv of `CommandEffector`
45
+ and rung 3 is pixel perception in `world/sight.py`. Each rung has its own nouns, so a
46
+ plan written for one cannot be carried down to another. The ordering is proposed and
47
+ unmeasured: that rung 0 is cheaper than rung 3 is a claim about what each instrument
48
+ returns, not a timing. Two listings read UNVERIFIED and cannot establish that a
49
+ control is absent: a truncated tree, and an opaque one where the walk finished and
50
+ nothing it saw carried a name. The second is the dangerous case, since nothing
51
+ about it looks partial. `uia.ps1` states `settlesAbsence` and the organ derives the
52
+ same bit from the facts; the instrument's claim can veto a settled read and can
53
+ never grant one.
54
+ - The **escalator** (`escalator.py`) chooses between the rungs and records why it fell.
55
+ A QUESTION travels down the ladder, never a plan, and each probe restates it in its
56
+ own nouns or declines with a reason. A rung that fell never sets the answer: when the
57
+ ladder runs out, the ascent is NEEDS_HUMAN carrying the trace and whatever perception
58
+ the deepest rung produced. A negative is settled only from a listing that settles
59
+ absence, and the trace says which of the two ways it failed to. A rung-3 sight has
60
+ a content digest and a perceptual hash and still answers no structural question.
61
+ The escalator only reads; acting stays with the effectors and their grants.
62
+ - Every effector carries a **false-success control**: a test that deliberately
63
+ produces a wrong result a passing verify could accept, asserting the verdict is not
64
+ a pass (`tests/test_false_success.py`). Where a verify still reads the actor's own
65
+ account rather than an independent witness, that limit is written down beside it.
66
+ - A **credential** is named, never held. It lives in an environment variable, is read
67
+ by `require_secret` at the moment of the call, and travels in a request header. It is
68
+ refused if it would reach the URL, because the URL is what the journal witnesses. The
69
+ agent hands in an intent, so it cannot name a secret, set a header, choose a host, or
70
+ read a token back.
71
+ - Append-only journal; the self-view is content-addressed and cannot silently drift.
72
+
73
+ ## Boundaries
74
+
75
+ - No secrets in the repo. Operator grants/journals are paths supplied at runtime,
76
+ never committed.
77
+ - This repo does **not** touch released ORCA, and is **not** the quarantined
78
+ semantic-modulation corridor -- keep those separate.
79
+
80
+ ## Dev
81
+
82
+ - `PYTHONPATH="<cm>/src;<ps>/src" python -m pytest` (pytest adds `./src`) -- 504 tests (1 skipped).
83
+ - coherence-membrane must include `WebDocumentOrgan` (branch
84
+ `feat/web-and-external-organs` or later).
85
+ - Quality gates: no file > 300 lines, no function > 50 lines, every test asserts
86
+ something meaningful, all tests pass before committing.
@@ -0,0 +1,10 @@
1
+ # Contributing
2
+
3
+ This repository is part of the Project Telos public surface. Keep changes small, tested, and easy for public users and developers to verify.
4
+
5
+ Before sending a change:
6
+
7
+ - Read `README.md` and any local `AGENTS.md` instructions.
8
+ - Run the narrowest test or verification command that covers the change.
9
+ - Keep examples, package metadata, and public claims aligned with current behavior.
10
+ - Do not commit secrets, `.env` files, private corpus material, or generated caches.
@@ -0,0 +1,23 @@
1
+ # The Credo
2
+
3
+ One belief, held steady across every tool in the family. The canonical,
4
+ content-addressed copy is served by the Flywheel engine at `GET /api/credo`;
5
+ this file echoes it.
6
+
7
+ Flywheel and its tool family hold one belief steady across every surface:
8
+
9
+ 1. Knowledge is an open surface for anyone who can attain the means;
10
+ we build to lower the means.
11
+ 2. The work speaks for itself: an external check decides acceptance;
12
+ never reputation, never the model.
13
+ 3. Every result carries a receipt a stranger can re-run.
14
+ 4. No claim without its interval; the honest null is a first-class result.
15
+ 5. Ownership is earned by comprehension: you own what you can review,
16
+ explain, and defend.
17
+ 6. Learning is woven into the work: every flagged gap is a lesson about
18
+ your own system.
19
+ 7. The badge and the contribution were bundled; we rebundle them around
20
+ the work, not the worker.
21
+
22
+ Growth, learning, knowledge, application, ownership: in that order,
23
+ for everyone.
@@ -0,0 +1,110 @@
1
+ # Functional Source License, Version 1.1, MIT Future License
2
+
3
+ ## Abbreviation
4
+
5
+ FSL-1.1-MIT
6
+
7
+ ## Notice
8
+
9
+ Copyright 2026 Zain Dana Harper
10
+
11
+ ## Terms and Conditions
12
+
13
+ ### Licensor ("We")
14
+
15
+ The party offering the Software under these Terms and Conditions.
16
+
17
+ ### The Software
18
+
19
+ The "Software" is each version of the software that we make available under
20
+ these Terms and Conditions, as indicated by our inclusion of these Terms and
21
+ Conditions with the Software.
22
+
23
+ ### License Grant
24
+
25
+ Subject to your compliance with this License Grant and the Patents,
26
+ Redistribution and Trademark clauses below, we hereby grant you the right to
27
+ use, copy, modify, create derivative works, publicly perform, publicly display
28
+ and redistribute the Software for any Permitted Purpose identified below.
29
+
30
+ ### Permitted Purpose
31
+
32
+ A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
33
+ means making the Software available to others in a commercial product or
34
+ service that:
35
+
36
+ 1. substitutes for the Software;
37
+
38
+ 2. substitutes for any other product or service we offer using the Software
39
+ that exists as of the date we make the Software available; or
40
+
41
+ 3. offers the same or substantially similar functionality as the Software.
42
+
43
+ Permitted Purposes specifically include using the Software:
44
+
45
+ 1. for your internal use and access;
46
+
47
+ 2. for non-commercial education;
48
+
49
+ 3. for non-commercial research; and
50
+
51
+ 4. in connection with professional services that you provide to a licensee
52
+ using the Software in accordance with these Terms and Conditions.
53
+
54
+ ### Patents
55
+
56
+ To the extent your use for a Permitted Purpose would necessarily infringe our
57
+ patents, the license grant above includes a license under our patents. If you
58
+ make a claim against any party that the Software infringes or contributes to
59
+ the infringement of any patent, then your patent license to the Software ends
60
+ immediately.
61
+
62
+ ### Redistribution
63
+
64
+ The Terms and Conditions apply to all copies, modifications and derivatives of
65
+ the Software.
66
+
67
+ If you redistribute any copies, modifications or derivatives of the Software,
68
+ you must include a copy of or a link to these Terms and Conditions and not
69
+ remove any copyright notices provided in or with the Software.
70
+
71
+ ### Disclaimer
72
+
73
+ THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
74
+ IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
75
+ PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
76
+
77
+ IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
78
+ SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
79
+ EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
80
+
81
+ ### Trademarks
82
+
83
+ Except for displaying the License Details and identifying us as the origin of
84
+ the Software, you have no right under these Terms and Conditions to use our
85
+ trademarks, trade names, service marks or product names.
86
+
87
+ ## Grant of Future License
88
+
89
+ We hereby irrevocably grant you an additional license to use the Software under
90
+ the MIT license that is effective on the second anniversary of the date we make
91
+ the Software available. On or after that date, you may use the Software under
92
+ the MIT license, in which case the following will apply:
93
+
94
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
95
+ this software and associated documentation files (the "Software"), to deal in
96
+ the Software without restriction, including without limitation the rights to
97
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
98
+ of the Software, and to permit persons to whom the Software is furnished to do
99
+ so, subject to the following conditions:
100
+
101
+ The above copyright notice and this permission notice shall be included in all
102
+ copies or substantial portions of the Software.
103
+
104
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
105
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
106
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
107
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
108
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
109
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
110
+ SOFTWARE.