Metadata-Version: 2.4
Name: swan-wearable-security
Version: 0.4.0
Summary: Lifecycle-bound capture delivery and offline wearable trace auditing
License: MIT License
        
        Copyright (c) 2026 Swan contributors
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: review
Requires-Dist: fastapi==0.156.4; extra == "review"
Requires-Dist: uvicorn==0.54.0; extra == "review"
Provides-Extra: test
Requires-Dist: pytest<10,>=8; extra == "test"
Requires-Dist: httpx==0.28.1; extra == "test"
Requires-Dist: jsonschema<5,>=4; extra == "test"
Dynamic: license-file

# Swan

Keep an approved camera upload tied to the picture, recipient and session the
person actually reviewed. If any of those changes before sending, Swan stops it.

[Quickstart](docs/quickstart.md) · [Python integration](docs/capture-delivery.md) ·
[Reference](docs/python-reference.md) · [All docs](docs/README.md)

## See the difference

From this checkout, with Python 3.10+:

```sh
python3 -m app.capture_demo --case valid_upload
python3 -m app.capture_demo --case recipient_drift
```

The approved upload reaches a private receiver on your computer. Changing the
recipient stops the next attempt. Each result is checked against what the
receiver actually received. No camera, account, model or external service.

```sh
python3 -m app.capture_demo --list
python3 -m app.capture_demo --json --output evidence/delivery-report.json
```

## Integrate

```sh
python3 -m venv .venv
.venv/bin/python -m pip install .
```

```python
from swan import CaptureGuard, HttpDestination

target = HttpDestination("https://your-service.example/inspection")
guard = CaptureGuard(max_capture_age=30, allowed_destinations=(target,))
```

Wire real source callbacks, review and sending using the
[complete integration guide](docs/capture-delivery.md). The core package has no
runtime dependencies. Installed applications import `swan`. The old `app.capture_guard` alias is retained
only in this source checkout; the wheel no longer installs a generic `app` package.

The host configures exact allowed recipients; changing that list withdraws pending
approvals. See [recipient policy](docs/recipient-policy.md).

Swan checks disconnects, stopped streams, permission changes, capture age,
changed payloads and recipients, cancellation and repeated approval. Trusted
application code owns the source and human review; every protected send must go
through the guard. An already-started request cannot be recalled.

[Android adapter](integrations/android/README.md) ·
[External approvals and agents](docs/approval-integrations.md) ·
[Visual demo handoff](docs/demo-contract.md)

## Confirm what the receiver recorded

[Confirmed delivery](docs/confirmed-delivery.md) adds a durable receipt store and
read-only recovery after a lost response. Receipt matching binds the account,
exact endpoint, operation ID and payload. Repeated approved requests reuse the
same receipt; changed content conflicts. No automatic resend occurs.

Version 0.4 starts with no allowed recipients. Configure the exact list shown
above. Source callbacks remain responsive while a network request is running.
See [0.4 changes and migration](docs/release-0.4.md).

## Audit existing event traces

```sh
swan-audit examples/wearable-safe.json
swan-audit trace.json --format sarif --output report.sarif
```

The offline auditor checks supplied metadata; it cannot enforce an action or
establish that the log is truthful. Exit codes: 0 = no errors, 1 = policy errors,
2 = invalid input. [Trace format](docs/wearable-traces.md).

## Optional local trace review

```sh
python -m venv .venv
.venv/bin/pip install -e ".[review,test]"
.venv/bin/python -m uvicorn app.wearable_server:app --host 127.0.0.1 --port 8766
```

Open http://127.0.0.1:8766. `npm start` uses this same metadata-only service.
Earlier OCR/model experiments are available separately through
`npm run start:research` and their dependencies in requirements.lock.

## Evidence and limits

The Python guard has real loopback HTTP integration tests. The native Android
adapter compiles against official pinned SDK artifacts and has JVM callback and
HTTP tests. Those tests do **not** execute an Android app, Meta MockDeviceKit or
physical glasses. Native frame freshness measures time since callback observation;
it does not certify physical capture time.

Trusted application code must own lifecycle signals and human approval, and all
protected operations must go through the guard. A compromised host can bypass it.
Already admitted requests cannot be recalled; a timeout means delivery is unknown
and is never automatically retried. Bystander consent is a declaration.

Swan does not intercept Meta AI, detect bystanders, solve SDK radio failures, or
certify an application as safe. Physical Kylie Starfires compatibility and
customer adoption are unverified. MIT for Swan code; bundled font and the Meta SDK
retain their own licenses.

## Development checks

```sh
.venv/bin/pip install -r requirements.lock
.venv/bin/pip install -e ".[review,test]"
.venv/bin/python -m pytest -q
.venv/bin/python scripts/evaluate_guard.py
python3 scripts/check_android_adapter.py
```

The Android checker needs an existing JDK 17+. Generated/mutation results describe
authored synthetic cases, not an independent device corpus or customer adoption.
