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.
- accountable_surface-0.3.1/.gitignore +20 -0
- accountable_surface-0.3.1/AGENTS.md +48 -0
- accountable_surface-0.3.1/AUTHORS.md +3 -0
- accountable_surface-0.3.1/CHANGELOG.md +186 -0
- accountable_surface-0.3.1/CLAUDE.md +86 -0
- accountable_surface-0.3.1/CONTRIBUTING.md +10 -0
- accountable_surface-0.3.1/CREDO.md +23 -0
- accountable_surface-0.3.1/LICENSE +110 -0
- accountable_surface-0.3.1/PKG-INFO +350 -0
- accountable_surface-0.3.1/README.md +320 -0
- accountable_surface-0.3.1/THEORY.md +161 -0
- accountable_surface-0.3.1/THESIS.md +126 -0
- accountable_surface-0.3.1/USAGE.md +312 -0
- accountable_surface-0.3.1/docs/INTRODUCTION.md +138 -0
- accountable_surface-0.3.1/docs/RELEASE.md +117 -0
- accountable_surface-0.3.1/docs/SPEC-actuation.md +79 -0
- accountable_surface-0.3.1/docs/SPEC-interoception.md +56 -0
- accountable_surface-0.3.1/docs/SPEC-persistence.md +74 -0
- accountable_surface-0.3.1/docs/art/accountable-surface-header.svg +1 -0
- accountable_surface-0.3.1/docs/art/accountable-surface.art.json +214 -0
- accountable_surface-0.3.1/docs/art/actuation-lane.svg +19 -0
- accountable_surface-0.3.1/docs/art/journal-chain-lane.svg +19 -0
- accountable_surface-0.3.1/docs/art/verdict-composition.svg +17 -0
- accountable_surface-0.3.1/docs/brand/README.md +10 -0
- accountable_surface-0.3.1/docs/brand/accountable-surface-hero.png +0 -0
- accountable_surface-0.3.1/docs/design/2026-06-22-shared-world-surface.md +111 -0
- accountable_surface-0.3.1/docs/durable-authority.md +60 -0
- accountable_surface-0.3.1/docs/interop-mcp.md +114 -0
- accountable_surface-0.3.1/docs/native-control-bridge.md +146 -0
- accountable_surface-0.3.1/docs/superpowers/plans/2026-06-22-bilateral-eye-increment-1.md +642 -0
- accountable_surface-0.3.1/docs/superpowers/plans/2026-06-22-screen-capture-source.md +657 -0
- accountable_surface-0.3.1/docs/superpowers/specs/2026-06-22-actuation-certificate-design.md +110 -0
- accountable_surface-0.3.1/docs/superpowers/specs/2026-06-22-bilateral-eye-increment-1-design.md +149 -0
- accountable_surface-0.3.1/docs/superpowers/specs/2026-06-22-screen-capture-source-design.md +154 -0
- accountable_surface-0.3.1/examples/actuate_demo.py +79 -0
- accountable_surface-0.3.1/examples/demo.py +104 -0
- accountable_surface-0.3.1/examples/goal_demo.py +104 -0
- accountable_surface-0.3.1/examples/grounded_actuate_demo.py +74 -0
- accountable_surface-0.3.1/examples/grounding_demo.py +55 -0
- accountable_surface-0.3.1/examples/interop_mcp_demo.py +81 -0
- accountable_surface-0.3.1/examples/smoke_mcp.py +54 -0
- accountable_surface-0.3.1/examples/spa_actuate_demo.py +108 -0
- accountable_surface-0.3.1/examples/web_actuate_demo.py +109 -0
- accountable_surface-0.3.1/interop/README.md +86 -0
- accountable_surface-0.3.1/interop/claude-code.mcp.json +15 -0
- accountable_surface-0.3.1/interop/flywheel-lane.json +16 -0
- accountable_surface-0.3.1/interop/mcp-server.json +51 -0
- accountable_surface-0.3.1/project-docs/specs/SPEC-accountable-surface-forward-delivery.md +33 -0
- accountable_surface-0.3.1/project-docs/specs/SPEC-remote-effector-surface.md +255 -0
- accountable_surface-0.3.1/pyproject.toml +82 -0
- accountable_surface-0.3.1/src/accountable_surface/__init__.py +105 -0
- accountable_surface-0.3.1/src/accountable_surface/action_receipt.py +226 -0
- accountable_surface-0.3.1/src/accountable_surface/api_effector.py +287 -0
- accountable_surface-0.3.1/src/accountable_surface/api_transport.py +34 -0
- accountable_surface-0.3.1/src/accountable_surface/authority_cli.py +81 -0
- accountable_surface-0.3.1/src/accountable_surface/authority_state.py +278 -0
- accountable_surface-0.3.1/src/accountable_surface/authority_store.py +147 -0
- accountable_surface-0.3.1/src/accountable_surface/authorized_actuation.py +108 -0
- accountable_surface-0.3.1/src/accountable_surface/bounds.py +102 -0
- accountable_surface-0.3.1/src/accountable_surface/browser_effector.py +280 -0
- accountable_surface-0.3.1/src/accountable_surface/certify.py +54 -0
- accountable_surface-0.3.1/src/accountable_surface/credentials.py +44 -0
- accountable_surface-0.3.1/src/accountable_surface/effector.py +162 -0
- accountable_surface-0.3.1/src/accountable_surface/escalator.py +241 -0
- accountable_surface-0.3.1/src/accountable_surface/grant.py +43 -0
- accountable_surface-0.3.1/src/accountable_surface/http_driver.py +151 -0
- accountable_surface-0.3.1/src/accountable_surface/interop_mcp.py +283 -0
- accountable_surface-0.3.1/src/accountable_surface/interop_runtime.py +291 -0
- accountable_surface-0.3.1/src/accountable_surface/journal_chain.py +64 -0
- accountable_surface-0.3.1/src/accountable_surface/mcp.py +174 -0
- accountable_surface-0.3.1/src/accountable_surface/native_control_effector.py +294 -0
- accountable_surface-0.3.1/src/accountable_surface/os_effector.py +115 -0
- accountable_surface-0.3.1/src/accountable_surface/playwright_driver.py +153 -0
- accountable_surface-0.3.1/src/accountable_surface/preconditions.py +69 -0
- accountable_surface-0.3.1/src/accountable_surface/protected_paths.py +130 -0
- accountable_surface-0.3.1/src/accountable_surface/read_authority.py +260 -0
- accountable_surface-0.3.1/src/accountable_surface/read_scopes.py +161 -0
- accountable_surface-0.3.1/src/accountable_surface/reference.py +145 -0
- accountable_surface-0.3.1/src/accountable_surface/registry.py +246 -0
- accountable_surface-0.3.1/src/accountable_surface/remote_actuation.py +145 -0
- accountable_surface-0.3.1/src/accountable_surface/remote_durable.py +209 -0
- accountable_surface-0.3.1/src/accountable_surface/server.py +229 -0
- accountable_surface-0.3.1/src/accountable_surface/surface.py +495 -0
- accountable_surface-0.3.1/src/accountable_surface/uia.py +284 -0
- accountable_surface-0.3.1/src/accountable_surface/uia_effector.py +260 -0
- accountable_surface-0.3.1/src/accountable_surface/uia_transport.py +71 -0
- accountable_surface-0.3.1/src/accountable_surface/web_effector.py +198 -0
- accountable_surface-0.3.1/src/accountable_surface/world/__init__.py +9 -0
- accountable_surface-0.3.1/src/accountable_surface/world/pilot.py +235 -0
- accountable_surface-0.3.1/src/accountable_surface/world/prompts.py +100 -0
- accountable_surface-0.3.1/src/accountable_surface/world/reel.py +31 -0
- accountable_surface-0.3.1/src/accountable_surface/world/screen.py +55 -0
- accountable_surface-0.3.1/src/accountable_surface/world/server.py +404 -0
- accountable_surface-0.3.1/src/accountable_surface/world/session.py +144 -0
- accountable_surface-0.3.1/src/accountable_surface/world/sight.py +176 -0
- accountable_surface-0.3.1/src/accountable_surface/world/structure.py +81 -0
- accountable_surface-0.3.1/tests/read_authority_helpers.py +43 -0
- accountable_surface-0.3.1/tests/test_action_receipt.py +190 -0
- accountable_surface-0.3.1/tests/test_actuate.py +252 -0
- accountable_surface-0.3.1/tests/test_api_effector.py +332 -0
- accountable_surface-0.3.1/tests/test_authority_store.py +74 -0
- accountable_surface-0.3.1/tests/test_browser_effector.py +283 -0
- accountable_surface-0.3.1/tests/test_browser_integrity.py +166 -0
- accountable_surface-0.3.1/tests/test_certify.py +74 -0
- accountable_surface-0.3.1/tests/test_durable_authority_cli.py +70 -0
- accountable_surface-0.3.1/tests/test_durable_authority_remote.py +211 -0
- accountable_surface-0.3.1/tests/test_durable_authority_state.py +205 -0
- accountable_surface-0.3.1/tests/test_durable_protected_paths.py +143 -0
- accountable_surface-0.3.1/tests/test_effector.py +106 -0
- accountable_surface-0.3.1/tests/test_effector_bounds.py +222 -0
- accountable_surface-0.3.1/tests/test_escalator.py +222 -0
- accountable_surface-0.3.1/tests/test_false_success.py +337 -0
- accountable_surface-0.3.1/tests/test_goal.py +103 -0
- accountable_surface-0.3.1/tests/test_grounded_actuation.py +75 -0
- accountable_surface-0.3.1/tests/test_health.py +24 -0
- accountable_surface-0.3.1/tests/test_http_driver.py +161 -0
- accountable_surface-0.3.1/tests/test_integrity_redteam.py +689 -0
- accountable_surface-0.3.1/tests/test_interoception.py +82 -0
- accountable_surface-0.3.1/tests/test_interop_exclusions.py +126 -0
- accountable_surface-0.3.1/tests/test_interop_mcp.py +212 -0
- accountable_surface-0.3.1/tests/test_journal_chain_tamper.py +75 -0
- accountable_surface-0.3.1/tests/test_mcp_actuate.py +300 -0
- accountable_surface-0.3.1/tests/test_mcp_stdio.py +88 -0
- accountable_surface-0.3.1/tests/test_native_control_effector.py +190 -0
- accountable_surface-0.3.1/tests/test_native_control_live.py +49 -0
- accountable_surface-0.3.1/tests/test_os_effector.py +119 -0
- accountable_surface-0.3.1/tests/test_persistence.py +135 -0
- accountable_surface-0.3.1/tests/test_pilot.py +150 -0
- accountable_surface-0.3.1/tests/test_preconditions.py +59 -0
- accountable_surface-0.3.1/tests/test_read_authority.py +160 -0
- accountable_surface-0.3.1/tests/test_reel.py +32 -0
- accountable_surface-0.3.1/tests/test_reference.py +81 -0
- accountable_surface-0.3.1/tests/test_release_package.py +56 -0
- accountable_surface-0.3.1/tests/test_remote_read_authority.py +401 -0
- accountable_surface-0.3.1/tests/test_repo_art.py +300 -0
- accountable_surface-0.3.1/tests/test_screen.py +237 -0
- accountable_surface-0.3.1/tests/test_server.py +107 -0
- accountable_surface-0.3.1/tests/test_sight.py +147 -0
- accountable_surface-0.3.1/tests/test_surface.py +116 -0
- accountable_surface-0.3.1/tests/test_uia_effector.py +297 -0
- accountable_surface-0.3.1/tests/test_uia_structure.py +204 -0
- accountable_surface-0.3.1/tests/test_verify_journal_standalone.py +73 -0
- accountable_surface-0.3.1/tests/test_version_alignment.py +63 -0
- accountable_surface-0.3.1/tests/test_web_effector.py +214 -0
- accountable_surface-0.3.1/tests/test_world_server.py +96 -0
- accountable_surface-0.3.1/tests/test_world_session.py +83 -0
- accountable_surface-0.3.1/tools/check_repo_art.py +247 -0
- accountable_surface-0.3.1/tools/check_repo_card.py +288 -0
- accountable_surface-0.3.1/tools/check_repo_flow.py +83 -0
- accountable_surface-0.3.1/tools/face-metrics.json +51 -0
- accountable_surface-0.3.1/tools/render_repo_art.py +76 -0
- accountable_surface-0.3.1/tools/repo_art.py +276 -0
- accountable_surface-0.3.1/tools/repo_card.py +226 -0
- accountable_surface-0.3.1/tools/repo_flow.py +169 -0
- accountable_surface-0.3.1/verify_journal.py +89 -0
- accountable_surface-0.3.1/web/index.html +199 -0
- accountable_surface-0.3.1/web/overlay.js +50 -0
- accountable_surface-0.3.1/web/overlay.test.mjs +16 -0
- accountable_surface-0.3.1/web/recheck.js +22 -0
- accountable_surface-0.3.1/web/recheck.test.mjs +38 -0
- accountable_surface-0.3.1/web/screen.html +30 -0
- accountable_surface-0.3.1/web/screen.js +40 -0
- accountable_surface-0.3.1/web/together.html +131 -0
- accountable_surface-0.3.1/web/together.js +128 -0
- accountable_surface-0.3.1/web/watch.html +99 -0
- accountable_surface-0.3.1/web/watch.js +111 -0
- 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,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.
|