openmuse-agent 0.3.0a0__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.
- openmuse_agent-0.3.0a0/.devcontainer/devcontainer.json +6 -0
- openmuse_agent-0.3.0a0/.github/ISSUE_TEMPLATE/bug.yml +11 -0
- openmuse_agent-0.3.0a0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- openmuse_agent-0.3.0a0/.github/ISSUE_TEMPLATE/connector.yml +12 -0
- openmuse_agent-0.3.0a0/.github/ISSUE_TEMPLATE/feature.yml +12 -0
- openmuse_agent-0.3.0a0/.github/dependabot.yml +8 -0
- openmuse_agent-0.3.0a0/.github/pull_request_template.md +9 -0
- openmuse_agent-0.3.0a0/.github/workflows/ci.yml +20 -0
- openmuse_agent-0.3.0a0/.github/workflows/codeql.yml +19 -0
- openmuse_agent-0.3.0a0/.github/workflows/dependency-review.yml +10 -0
- openmuse_agent-0.3.0a0/.github/workflows/release.yml +21 -0
- openmuse_agent-0.3.0a0/.github/workflows/security.yml +18 -0
- openmuse_agent-0.3.0a0/.gitignore +11 -0
- openmuse_agent-0.3.0a0/CHANGELOG.md +35 -0
- openmuse_agent-0.3.0a0/CITATION.cff +10 -0
- openmuse_agent-0.3.0a0/CODE_OF_CONDUCT.md +2 -0
- openmuse_agent-0.3.0a0/CONTRIBUTING.md +33 -0
- openmuse_agent-0.3.0a0/GOVERNANCE.md +2 -0
- openmuse_agent-0.3.0a0/LICENSE +21 -0
- openmuse_agent-0.3.0a0/PKG-INFO +179 -0
- openmuse_agent-0.3.0a0/README.md +155 -0
- openmuse_agent-0.3.0a0/SECURITY.md +9 -0
- openmuse_agent-0.3.0a0/SUPPORT.md +3 -0
- openmuse_agent-0.3.0a0/docs/adr/0001-security-first-runtime.md +2 -0
- openmuse_agent-0.3.0a0/docs/adr/0002-scoped-connectors.md +39 -0
- openmuse_agent-0.3.0a0/docs/architecture.md +15 -0
- openmuse_agent-0.3.0a0/docs/assets/openmuse-demo.cast +20 -0
- openmuse_agent-0.3.0a0/docs/isolated-worker.md +42 -0
- openmuse_agent-0.3.0a0/docs/product-foundation.md +5 -0
- openmuse_agent-0.3.0a0/docs/roadmap.md +7 -0
- openmuse_agent-0.3.0a0/docs/security/review-checklist.md +31 -0
- openmuse_agent-0.3.0a0/docs/security/reviewer-brief.md +13 -0
- openmuse_agent-0.3.0a0/docs/threat-model.md +16 -0
- openmuse_agent-0.3.0a0/examples/e2e_demo.py +74 -0
- openmuse_agent-0.3.0a0/examples/isolated_worker_demo.py +17 -0
- openmuse_agent-0.3.0a0/examples/local_planner.py +9 -0
- openmuse_agent-0.3.0a0/examples/verify_audit.py +44 -0
- openmuse_agent-0.3.0a0/examples/worker_echo.py +17 -0
- openmuse_agent-0.3.0a0/pyproject.toml +27 -0
- openmuse_agent-0.3.0a0/src/openmuse/__init__.py +3 -0
- openmuse_agent-0.3.0a0/src/openmuse/approval_ui.py +14 -0
- openmuse_agent-0.3.0a0/src/openmuse/approvals.py +60 -0
- openmuse_agent-0.3.0a0/src/openmuse/audit.py +64 -0
- openmuse_agent-0.3.0a0/src/openmuse/broker.py +77 -0
- openmuse_agent-0.3.0a0/src/openmuse/browser_worker.py +24 -0
- openmuse_agent-0.3.0a0/src/openmuse/channels/__init__.py +4 -0
- openmuse_agent-0.3.0a0/src/openmuse/channels/base.py +17 -0
- openmuse_agent-0.3.0a0/src/openmuse/channels/web.py +21 -0
- openmuse_agent-0.3.0a0/src/openmuse/cli.py +27 -0
- openmuse_agent-0.3.0a0/src/openmuse/connectors.py +130 -0
- openmuse_agent-0.3.0a0/src/openmuse/core.py +65 -0
- openmuse_agent-0.3.0a0/src/openmuse/effects.py +39 -0
- openmuse_agent-0.3.0a0/src/openmuse/ephemeral.py +32 -0
- openmuse_agent-0.3.0a0/src/openmuse/evidence.py +31 -0
- openmuse_agent-0.3.0a0/src/openmuse/google_calendar_connector.py +112 -0
- openmuse_agent-0.3.0a0/src/openmuse/google_mail_connector.py +116 -0
- openmuse_agent-0.3.0a0/src/openmuse/google_oauth.py +166 -0
- openmuse_agent-0.3.0a0/src/openmuse/host_events.py +57 -0
- openmuse_agent-0.3.0a0/src/openmuse/isolated_worker.py +73 -0
- openmuse_agent-0.3.0a0/src/openmuse/keyring_keys.py +54 -0
- openmuse_agent-0.3.0a0/src/openmuse/memory.py +192 -0
- openmuse_agent-0.3.0a0/src/openmuse/models.py +32 -0
- openmuse_agent-0.3.0a0/src/openmuse/policy.py +33 -0
- openmuse_agent-0.3.0a0/src/openmuse/providers/__init__.py +3 -0
- openmuse_agent-0.3.0a0/src/openmuse/providers/openai_compatible.py +35 -0
- openmuse_agent-0.3.0a0/src/openmuse/registry.py +21 -0
- openmuse_agent-0.3.0a0/src/openmuse/scheduler.py +133 -0
- openmuse_agent-0.3.0a0/src/openmuse/secrets.py +72 -0
- openmuse_agent-0.3.0a0/src/openmuse/simulated_connectors.py +69 -0
- openmuse_agent-0.3.0a0/src/openmuse/subagents.py +105 -0
- openmuse_agent-0.3.0a0/src/openmuse/task_ui.py +16 -0
- openmuse_agent-0.3.0a0/src/openmuse/tasks.py +98 -0
- openmuse_agent-0.3.0a0/src/openmuse/tools.py +159 -0
- openmuse_agent-0.3.0a0/src/openmuse/validation.py +59 -0
- openmuse_agent-0.3.0a0/tests/test_approvals.py +115 -0
- openmuse_agent-0.3.0a0/tests/test_argument_validation.py +54 -0
- openmuse_agent-0.3.0a0/tests/test_audit_verify.py +18 -0
- openmuse_agent-0.3.0a0/tests/test_broker.py +98 -0
- openmuse_agent-0.3.0a0/tests/test_cli.py +22 -0
- openmuse_agent-0.3.0a0/tests/test_connectors.py +170 -0
- openmuse_agent-0.3.0a0/tests/test_core.py +43 -0
- openmuse_agent-0.3.0a0/tests/test_demo.py +29 -0
- openmuse_agent-0.3.0a0/tests/test_fetch_url_security.py +72 -0
- openmuse_agent-0.3.0a0/tests/test_google_calendar_connector.py +51 -0
- openmuse_agent-0.3.0a0/tests/test_google_mail_connector.py +54 -0
- openmuse_agent-0.3.0a0/tests/test_google_oauth.py +61 -0
- openmuse_agent-0.3.0a0/tests/test_host_events_and_streams.py +59 -0
- openmuse_agent-0.3.0a0/tests/test_isolated_worker.py +41 -0
- openmuse_agent-0.3.0a0/tests/test_isolated_worker_demo.py +21 -0
- openmuse_agent-0.3.0a0/tests/test_keyring_keys.py +31 -0
- openmuse_agent-0.3.0a0/tests/test_memory_verification.py +147 -0
- openmuse_agent-0.3.0a0/tests/test_openai_compatible.py +29 -0
- openmuse_agent-0.3.0a0/tests/test_packaging.py +8 -0
- openmuse_agent-0.3.0a0/tests/test_product_foundation.py +46 -0
- openmuse_agent-0.3.0a0/tests/test_safety_capabilities.py +43 -0
- openmuse_agent-0.3.0a0/tests/test_scheduler.py +83 -0
- openmuse_agent-0.3.0a0/tests/test_simulated_connectors.py +49 -0
- openmuse_agent-0.3.0a0/tests/test_subagents.py +105 -0
- openmuse_agent-0.3.0a0/tests/test_version.py +7 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "OpenMuse demo",
|
|
3
|
+
"image": "mcr.microsoft.com/devcontainers/python:3.12",
|
|
4
|
+
"postCreateCommand": "pip install -e '.[dev]'",
|
|
5
|
+
"postStartCommand": "printf '\nOpenMuse is ready. Run: python examples/e2e_demo.py\nThen verify: python examples/verify_audit.py\n'"
|
|
6
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a reproducible defect
|
|
3
|
+
body:
|
|
4
|
+
- type: textarea
|
|
5
|
+
attributes: {label: What happened?}
|
|
6
|
+
validations: {required: true}
|
|
7
|
+
- type: textarea
|
|
8
|
+
attributes: {label: Reproduction steps}
|
|
9
|
+
validations: {required: true}
|
|
10
|
+
- type: input
|
|
11
|
+
attributes: {label: OpenMuse and Python versions}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
name: Connector proposal
|
|
2
|
+
description: Propose a least-privilege integration
|
|
3
|
+
body:
|
|
4
|
+
- type: input
|
|
5
|
+
attributes: {label: Service and use case}
|
|
6
|
+
validations: {required: true}
|
|
7
|
+
- type: textarea
|
|
8
|
+
attributes: {label: Required scopes and data flow}
|
|
9
|
+
validations: {required: true}
|
|
10
|
+
- type: textarea
|
|
11
|
+
attributes: {label: Risks, revocation, and simulation mode}
|
|
12
|
+
validations: {required: true}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Propose a focused improvement
|
|
3
|
+
body:
|
|
4
|
+
- type: textarea
|
|
5
|
+
attributes: {label: Problem, description: What user problem should this solve?}
|
|
6
|
+
validations: {required: true}
|
|
7
|
+
- type: textarea
|
|
8
|
+
attributes: {label: Proposed behavior}
|
|
9
|
+
validations: {required: true}
|
|
10
|
+
- type: textarea
|
|
11
|
+
attributes: {label: Trust-boundary impact, description: Note new data, permissions, side effects, or say none.}
|
|
12
|
+
validations: {required: true}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on: [push, pull_request]
|
|
3
|
+
permissions: {contents: read}
|
|
4
|
+
jobs:
|
|
5
|
+
test:
|
|
6
|
+
runs-on: ubuntu-latest
|
|
7
|
+
strategy: {matrix: {python-version: ['3.11','3.12','3.13']}}
|
|
8
|
+
steps:
|
|
9
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
|
10
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
11
|
+
with: {python-version: '${{ matrix.python-version }}'}
|
|
12
|
+
- run: python -m pip install -e '.[dev]'
|
|
13
|
+
- run: ruff check src tests
|
|
14
|
+
- run: mypy src/openmuse
|
|
15
|
+
- run: pytest --cov=openmuse --cov-report=term-missing --cov-fail-under=85
|
|
16
|
+
- run: python examples/e2e_demo.py --auto-approve
|
|
17
|
+
- run: python examples/verify_audit.py
|
|
18
|
+
- run: python -m build
|
|
19
|
+
- run: python -m pip install --force-reinstall dist/*.whl
|
|
20
|
+
- run: python -c "import importlib.metadata, openmuse; assert openmuse.__version__ == importlib.metadata.version('openmuse-agent')"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: CodeQL
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
pull_request:
|
|
6
|
+
branches: [main]
|
|
7
|
+
schedule:
|
|
8
|
+
- cron: '17 4 * * 1'
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
security-events: write
|
|
12
|
+
jobs:
|
|
13
|
+
analyze:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
|
17
|
+
- uses: github/codeql-action/init@c20e34f438d671fc35777cc9820dd7adf8252874 # v3
|
|
18
|
+
with: {languages: python}
|
|
19
|
+
- uses: github/codeql-action/analyze@c20e34f438d671fc35777cc9820dd7adf8252874 # v3
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
name: Dependency review
|
|
2
|
+
on: [pull_request]
|
|
3
|
+
permissions:
|
|
4
|
+
contents: read
|
|
5
|
+
jobs:
|
|
6
|
+
review:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
steps:
|
|
9
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
|
10
|
+
- uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
tags: ['v*']
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
id-token: write
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
environment: release
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
|
14
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
15
|
+
with: {python-version: '3.12'}
|
|
16
|
+
- run: python -m pip install build
|
|
17
|
+
- run: python -m build
|
|
18
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
|
|
19
|
+
with: {name: dist, path: dist/}
|
|
20
|
+
- name: Publish to PyPI
|
|
21
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: Python security checks
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
pull_request:
|
|
6
|
+
branches: [main]
|
|
7
|
+
schedule:
|
|
8
|
+
- cron: '41 4 * * 2'
|
|
9
|
+
permissions: {contents: read}
|
|
10
|
+
jobs:
|
|
11
|
+
audit:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
|
15
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
16
|
+
with: {python-version: '3.12'}
|
|
17
|
+
- run: python -m pip install -e . pip-audit
|
|
18
|
+
- run: pip-audit
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes are recorded here. OpenMuse follows semantic versioning while using prerelease tags for alpha builds.
|
|
4
|
+
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
## v0.3.0-alpha - 2026-09-19
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Managed Google OAuth with authorization-code exchange, automatic refresh, encrypted token storage, and OS-keyring-backed master keys.
|
|
12
|
+
- Read-only Gmail and Google Calendar connectors built on scoped, least-privilege grants, plus credential-free local simulation connectors.
|
|
13
|
+
- Searchable and editable working/curated memory with hash-chained remember, promote, edit, and forget events, plus state verification against the audit chain.
|
|
14
|
+
- Five-field cron scheduling with atomic job claims across workers, and subagent grants that can only narrow tools, budgets, expiry, and argument constraints.
|
|
15
|
+
- A secrets broker that passes named secrets to tools through a scoped execution side channel without exposing plaintext to planner context, manifests, action arguments, or audit logs.
|
|
16
|
+
- A fresh-process isolated worker with bounded runtime, memory, file descriptors, output, environment, and workspace.
|
|
17
|
+
- An independent security-review packet with a reviewer brief and checklist.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- The approval demo now shows the exact tool, path, content preview, and SHA-256 being approved, then verifies that the approved action is the action executed.
|
|
22
|
+
- Connector revocation now clears cached clients and fails closed if cleanup does not complete.
|
|
23
|
+
- Tool arguments are validated before approval, policy checks, and execution.
|
|
24
|
+
- `FetchURL` now resolves once and pins connections to validated public addresses to prevent DNS-rebinding bypasses.
|
|
25
|
+
- Project metadata and runtime version are aligned for this prerelease.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Approval tokens are consumed atomically, preventing concurrent verification from using one approval twice.
|
|
30
|
+
- Approval expiry now rejects tokens at the exact expiry boundary (`now >= exp`).
|
|
31
|
+
- Scheduled jobs are claimed transactionally so parallel workers cannot run the same job twice.
|
|
32
|
+
|
|
33
|
+
### Known limitations
|
|
34
|
+
|
|
35
|
+
- OpenMuse remains alpha software for test accounts and non-sensitive data. Documentation drift in the security limits is being cleaned up separately.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use OpenMuse in research, please cite this software."
|
|
3
|
+
title: "OpenMuse"
|
|
4
|
+
type: software
|
|
5
|
+
authors:
|
|
6
|
+
- name: "tahodev"
|
|
7
|
+
repository-code: "https://github.com/tahodev/openmuse"
|
|
8
|
+
license: MIT
|
|
9
|
+
version: 0.3.0-alpha
|
|
10
|
+
date-released: 2026-09-19
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
We follow the [Contributor Covenant 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/). Be respectful, assume good intent, and avoid harassment. Report conduct concerns privately through a GitHub security advisory; maintainers will review them promptly and confidentially.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Set up
|
|
4
|
+
|
|
5
|
+
1. Fork the repository and branch from `main`.
|
|
6
|
+
2. Use Python 3.11 or newer.
|
|
7
|
+
3. Run `python -m venv .venv`, activate it, then `pip install -e '.[dev]'`.
|
|
8
|
+
4. Before opening a pull request, run:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
ruff check src tests
|
|
12
|
+
mypy src/openmuse
|
|
13
|
+
pytest --cov=openmuse --cov-fail-under=85
|
|
14
|
+
python examples/e2e_demo.py --auto-approve
|
|
15
|
+
python examples/verify_audit.py
|
|
16
|
+
python -m build
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Changes to trust boundaries
|
|
20
|
+
|
|
21
|
+
Open an issue before changing the permission model, approvals, audit format, connector scopes, data retention, or secret handling. Describe assets, attackers, failure modes, revocation, simulation behavior, and the tests that prove fail-closed behavior. Changes to these boundaries need an ADR in `docs/adr/`, threat-model updates, tests, and maintainer approval.
|
|
22
|
+
|
|
23
|
+
## Connectors
|
|
24
|
+
|
|
25
|
+
Start read-only, request the smallest scopes, document data flow and deletion/revocation, support simulation where possible, and never put credentials or private payloads in fixtures, logs, or issues.
|
|
26
|
+
|
|
27
|
+
## Pull requests
|
|
28
|
+
|
|
29
|
+
Keep changes small. Explain the user-visible behavior, trust-boundary impact, compatibility risk, and test evidence. Update docs with behavior changes and complete the pull-request checklist.
|
|
30
|
+
|
|
31
|
+
## Releases
|
|
32
|
+
|
|
33
|
+
Maintainers use semantic versioning with prerelease tags for alpha work. A release must pass CI, build from a clean checkout, match `openmuse.__version__`, include release notes, and be checked on TestPyPI before PyPI.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tahodev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: openmuse-agent
|
|
3
|
+
Version: 0.3.0a0
|
|
4
|
+
Summary: A local-first, auditable personal AI agent runtime
|
|
5
|
+
Project-URL: Homepage, https://github.com/tahodev/openmuse
|
|
6
|
+
Project-URL: Issues, https://github.com/tahodev/openmuse/issues
|
|
7
|
+
Author: tahodev
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: ai-agent,automation,local-first,personal-agent
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Requires-Python: >=3.11
|
|
15
|
+
Requires-Dist: cryptography>=43
|
|
16
|
+
Requires-Dist: keyring>=25
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
19
|
+
Requires-Dist: mypy>=1.11; extra == 'dev'
|
|
20
|
+
Requires-Dist: pytest-cov>=5; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
22
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# OpenMuse
|
|
26
|
+
|
|
27
|
+
[](https://github.com/tahodev/openmuse/actions/workflows/ci.yml)
|
|
28
|
+
[](LICENSE)
|
|
29
|
+
[](https://codespaces.new/tahodev/openmuse?quickstart=1)
|
|
30
|
+
|
|
31
|
+
A local-first, auditable personal AI agent runtime. OpenMuse separates untrusted planners from typed tools, host-issued approvals, durable tasks, encrypted secrets, and redacted audit history.
|
|
32
|
+
|
|
33
|
+
## Why OpenMuse is different
|
|
34
|
+
|
|
35
|
+
The goal is the smallest readable personal-agent runtime whose safety semantics are verified in code and tests:
|
|
36
|
+
|
|
37
|
+
- **Exact-action approval.** The host signs each approval token against one action's tool and arguments. Tokens expire and can be consumed exactly once. The planner cannot mint approvals, and approving one action never approves a similar-looking one.
|
|
38
|
+
- **Verifiable audit.** Every decision lands in a redacted, hash-chained local log that you can re-verify independently. Change one audited byte and verification fails.
|
|
39
|
+
- **Secrets never reach the model.** Tools receive decrypted secrets through a host callback at execution time. Secret values never appear in planner context, action arguments, tool manifests, or the audit log.
|
|
40
|
+
|
|
41
|
+
## See the safety boundary in 30 seconds
|
|
42
|
+
|
|
43
|
+
One simple story: the agent starts a task, pauses before one write, the user approves exactly that action, it runs, and the audit chain proves what happened.
|
|
44
|
+
|
|
45
|
+
[](https://asciinema.org/a/MYdPbeccAUeoC8uy)
|
|
46
|
+
|
|
47
|
+
This is a real terminal capture. Its raw, replayable cast is also [checked into the repository](docs/assets/openmuse-demo.cast).
|
|
48
|
+
|
|
49
|
+
## The approval boundary
|
|
50
|
+
|
|
51
|
+
The planner and everything it reads are untrusted. Only the trusted host can issue an approval, and it issues one for the exact action the user approved:
|
|
52
|
+
|
|
53
|
+
```mermaid
|
|
54
|
+
flowchart TD
|
|
55
|
+
U([User])
|
|
56
|
+
subgraph untrusted["Untrusted"]
|
|
57
|
+
P["Planner (model)"]
|
|
58
|
+
X["External content: pages, messages, files"]
|
|
59
|
+
end
|
|
60
|
+
subgraph host["Trusted host"]
|
|
61
|
+
POL["Policy"]
|
|
62
|
+
AUTH["Approval authority"]
|
|
63
|
+
VAULT["Secret vault"]
|
|
64
|
+
EXEC["Tool executor"]
|
|
65
|
+
AUD["Hash-chained audit log"]
|
|
66
|
+
end
|
|
67
|
+
X -.-> P
|
|
68
|
+
P -->|proposes one typed action| POL
|
|
69
|
+
POL -->|sensitive action: ask| U
|
|
70
|
+
U -->|approves this exact action| AUTH
|
|
71
|
+
AUTH -->|one-time, expiring, action-bound token| EXEC
|
|
72
|
+
POL -->|allow| EXEC
|
|
73
|
+
VAULT -->|decrypts via host callback| EXEC
|
|
74
|
+
EXEC -->|typed result| P
|
|
75
|
+
POL --> AUD
|
|
76
|
+
AUTH --> AUD
|
|
77
|
+
EXEC --> AUD
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Use a real model
|
|
81
|
+
|
|
82
|
+
`OpenAICompatiblePlanner` supports OpenAI-compatible chat-completions endpoints. Set `OPENAI_API_KEY` and pass the planner to `Agent.run()`. This is an alpha adapter: use a test key and non-sensitive data.
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
import os
|
|
86
|
+
from pathlib import Path
|
|
87
|
+
from openmuse.core import Agent
|
|
88
|
+
from openmuse.policy import Policy
|
|
89
|
+
from openmuse.providers import OpenAICompatiblePlanner
|
|
90
|
+
from openmuse.tools import ReadFile
|
|
91
|
+
|
|
92
|
+
agent = Agent([ReadFile(Path.cwd())], Policy(), Path(".openmuse/audit.jsonl"))
|
|
93
|
+
planner = OpenAICompatiblePlanner(api_key=os.environ["OPENAI_API_KEY"])
|
|
94
|
+
print(agent.run("Read README.md and stop", planner))
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The deterministic demo remains the recommended first run because it is free and reproducible.
|
|
98
|
+
|
|
99
|
+
**Current scope:** an alpha security-primitives runtime and reproducible demo, not a production personal assistant. Unlike [Digger's deployable OpenMuse assistant](https://github.com/diggerhq/openmuse), this project focuses on host-enforced exact-action approval and verifiable local audit trails. The Python distribution is named `openmuse-agent`.
|
|
100
|
+
|
|
101
|
+
> Independent project. Not affiliated with or endorsed by Meta. No Meta code, branding, or assets are used.
|
|
102
|
+
|
|
103
|
+
## Run it
|
|
104
|
+
|
|
105
|
+
The quickest path opens a ready Python environment. In the terminal, run `python examples/e2e_demo.py` so you can inspect and approve the exact write yourself:
|
|
106
|
+
|
|
107
|
+
[](https://codespaces.new/tahodev/openmuse?quickstart=1)
|
|
108
|
+
|
|
109
|
+
Or run locally with Python 3.11+ and Git:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
git clone https://github.com/tahodev/openmuse.git
|
|
113
|
+
cd openmuse
|
|
114
|
+
python -m venv .venv
|
|
115
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
116
|
+
pip install -e '.[dev]'
|
|
117
|
+
python examples/e2e_demo.py
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The deterministic demo needs no API key. It keeps the existing web-channel and durable-task flow, but makes the one sensitive write and its host-issued approval visible.
|
|
121
|
+
|
|
122
|
+
## Verify, don't trust
|
|
123
|
+
|
|
124
|
+
After the demo, independently recompute every audit hash and link:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
python examples/verify_audit.py
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Expected result:
|
|
131
|
+
|
|
132
|
+
```text
|
|
133
|
+
VERIFIED: 3 records form an intact hash chain
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Change any audited byte and verification fails. The verifier is intentionally small: [examples/verify_audit.py](examples/verify_audit.py) calls the public [`verify_chain`](src/openmuse/audit.py) function. The audit contains a blocked attempt, the approved action, and its execution result.
|
|
137
|
+
|
|
138
|
+
## Status
|
|
139
|
+
|
|
140
|
+
| Capability | Status |
|
|
141
|
+
|---|---|
|
|
142
|
+
| Typed, budgeted agent loop | Working |
|
|
143
|
+
| Exact-action, expiring, one-time approvals | Working |
|
|
144
|
+
| Workspace file tools + SSRF-resistant public fetch | Working |
|
|
145
|
+
| Redacted hash-chained audit | Working |
|
|
146
|
+
| SQLite task checkpoints/cancel/restart | Working |
|
|
147
|
+
| In-process web channel adapter | Experimental |
|
|
148
|
+
| Envelope-encrypted local secret vault | Experimental |
|
|
149
|
+
| Browser-worker policy envelope | Experimental |
|
|
150
|
+
| Persistent task threads + atomic cron job claims | Working |
|
|
151
|
+
| Credential-free read-only mail/calendar connectors | Working |
|
|
152
|
+
| Production-capable read-only Google Calendar and Gmail connectors | Working |
|
|
153
|
+
| Managed Google OAuth code exchange, refresh, encrypted storage, and OS-keyring master key | Working |
|
|
154
|
+
| [Resource-limited OS process worker](docs/isolated-worker.md) | Working |
|
|
155
|
+
| Kernel/network-isolated browser worker | Not yet |
|
|
156
|
+
| Ephemeral OTP grants + exact-total validation | Working |
|
|
157
|
+
| Searchable, tiered, provenance-verifiable memory + edit/forget | Working |
|
|
158
|
+
|
|
159
|
+
Do not use OpenMuse with sensitive production accounts yet. “Working” means covered by the current test suite, not externally audited.
|
|
160
|
+
|
|
161
|
+
## How it works
|
|
162
|
+
|
|
163
|
+
`Channel -> durable Task -> Planner -> typed Action -> Policy/Approval -> Tool -> typed Result`
|
|
164
|
+
|
|
165
|
+
The model cannot mint approval tokens. Secret decryption happens through a host callback, not planner context. See [architecture](docs/architecture.md), [threat model](docs/threat-model.md), [product foundation](docs/product-foundation.md), and [roadmap](docs/roadmap.md).
|
|
166
|
+
|
|
167
|
+
## What OpenMuse is and is not
|
|
168
|
+
|
|
169
|
+
| In scope today | Not yet |
|
|
170
|
+
|---|---|
|
|
171
|
+
| Typed local tools, bounded loops, exact-action approval, encrypted local vault, durable tasks, audit verification, simulated mail/calendar connectors | Production browser isolation, independently deployed OAuth callback, independent security review, unattended use with sensitive accounts |
|
|
172
|
+
|
|
173
|
+
## Contributing
|
|
174
|
+
|
|
175
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md), [governance](GOVERNANCE.md), and the [code of conduct](CODE_OF_CONDUCT.md). Starter work is tracked with [`good first issue`](https://github.com/tahodev/openmuse/labels/good%20first%20issue) and [`help wanted`](https://github.com/tahodev/openmuse/labels/help%20wanted) labels.
|
|
176
|
+
|
|
177
|
+
## License
|
|
178
|
+
|
|
179
|
+
MIT.
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# OpenMuse
|
|
2
|
+
|
|
3
|
+
[](https://github.com/tahodev/openmuse/actions/workflows/ci.yml)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://codespaces.new/tahodev/openmuse?quickstart=1)
|
|
6
|
+
|
|
7
|
+
A local-first, auditable personal AI agent runtime. OpenMuse separates untrusted planners from typed tools, host-issued approvals, durable tasks, encrypted secrets, and redacted audit history.
|
|
8
|
+
|
|
9
|
+
## Why OpenMuse is different
|
|
10
|
+
|
|
11
|
+
The goal is the smallest readable personal-agent runtime whose safety semantics are verified in code and tests:
|
|
12
|
+
|
|
13
|
+
- **Exact-action approval.** The host signs each approval token against one action's tool and arguments. Tokens expire and can be consumed exactly once. The planner cannot mint approvals, and approving one action never approves a similar-looking one.
|
|
14
|
+
- **Verifiable audit.** Every decision lands in a redacted, hash-chained local log that you can re-verify independently. Change one audited byte and verification fails.
|
|
15
|
+
- **Secrets never reach the model.** Tools receive decrypted secrets through a host callback at execution time. Secret values never appear in planner context, action arguments, tool manifests, or the audit log.
|
|
16
|
+
|
|
17
|
+
## See the safety boundary in 30 seconds
|
|
18
|
+
|
|
19
|
+
One simple story: the agent starts a task, pauses before one write, the user approves exactly that action, it runs, and the audit chain proves what happened.
|
|
20
|
+
|
|
21
|
+
[](https://asciinema.org/a/MYdPbeccAUeoC8uy)
|
|
22
|
+
|
|
23
|
+
This is a real terminal capture. Its raw, replayable cast is also [checked into the repository](docs/assets/openmuse-demo.cast).
|
|
24
|
+
|
|
25
|
+
## The approval boundary
|
|
26
|
+
|
|
27
|
+
The planner and everything it reads are untrusted. Only the trusted host can issue an approval, and it issues one for the exact action the user approved:
|
|
28
|
+
|
|
29
|
+
```mermaid
|
|
30
|
+
flowchart TD
|
|
31
|
+
U([User])
|
|
32
|
+
subgraph untrusted["Untrusted"]
|
|
33
|
+
P["Planner (model)"]
|
|
34
|
+
X["External content: pages, messages, files"]
|
|
35
|
+
end
|
|
36
|
+
subgraph host["Trusted host"]
|
|
37
|
+
POL["Policy"]
|
|
38
|
+
AUTH["Approval authority"]
|
|
39
|
+
VAULT["Secret vault"]
|
|
40
|
+
EXEC["Tool executor"]
|
|
41
|
+
AUD["Hash-chained audit log"]
|
|
42
|
+
end
|
|
43
|
+
X -.-> P
|
|
44
|
+
P -->|proposes one typed action| POL
|
|
45
|
+
POL -->|sensitive action: ask| U
|
|
46
|
+
U -->|approves this exact action| AUTH
|
|
47
|
+
AUTH -->|one-time, expiring, action-bound token| EXEC
|
|
48
|
+
POL -->|allow| EXEC
|
|
49
|
+
VAULT -->|decrypts via host callback| EXEC
|
|
50
|
+
EXEC -->|typed result| P
|
|
51
|
+
POL --> AUD
|
|
52
|
+
AUTH --> AUD
|
|
53
|
+
EXEC --> AUD
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Use a real model
|
|
57
|
+
|
|
58
|
+
`OpenAICompatiblePlanner` supports OpenAI-compatible chat-completions endpoints. Set `OPENAI_API_KEY` and pass the planner to `Agent.run()`. This is an alpha adapter: use a test key and non-sensitive data.
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
import os
|
|
62
|
+
from pathlib import Path
|
|
63
|
+
from openmuse.core import Agent
|
|
64
|
+
from openmuse.policy import Policy
|
|
65
|
+
from openmuse.providers import OpenAICompatiblePlanner
|
|
66
|
+
from openmuse.tools import ReadFile
|
|
67
|
+
|
|
68
|
+
agent = Agent([ReadFile(Path.cwd())], Policy(), Path(".openmuse/audit.jsonl"))
|
|
69
|
+
planner = OpenAICompatiblePlanner(api_key=os.environ["OPENAI_API_KEY"])
|
|
70
|
+
print(agent.run("Read README.md and stop", planner))
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The deterministic demo remains the recommended first run because it is free and reproducible.
|
|
74
|
+
|
|
75
|
+
**Current scope:** an alpha security-primitives runtime and reproducible demo, not a production personal assistant. Unlike [Digger's deployable OpenMuse assistant](https://github.com/diggerhq/openmuse), this project focuses on host-enforced exact-action approval and verifiable local audit trails. The Python distribution is named `openmuse-agent`.
|
|
76
|
+
|
|
77
|
+
> Independent project. Not affiliated with or endorsed by Meta. No Meta code, branding, or assets are used.
|
|
78
|
+
|
|
79
|
+
## Run it
|
|
80
|
+
|
|
81
|
+
The quickest path opens a ready Python environment. In the terminal, run `python examples/e2e_demo.py` so you can inspect and approve the exact write yourself:
|
|
82
|
+
|
|
83
|
+
[](https://codespaces.new/tahodev/openmuse?quickstart=1)
|
|
84
|
+
|
|
85
|
+
Or run locally with Python 3.11+ and Git:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
git clone https://github.com/tahodev/openmuse.git
|
|
89
|
+
cd openmuse
|
|
90
|
+
python -m venv .venv
|
|
91
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
92
|
+
pip install -e '.[dev]'
|
|
93
|
+
python examples/e2e_demo.py
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The deterministic demo needs no API key. It keeps the existing web-channel and durable-task flow, but makes the one sensitive write and its host-issued approval visible.
|
|
97
|
+
|
|
98
|
+
## Verify, don't trust
|
|
99
|
+
|
|
100
|
+
After the demo, independently recompute every audit hash and link:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
python examples/verify_audit.py
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Expected result:
|
|
107
|
+
|
|
108
|
+
```text
|
|
109
|
+
VERIFIED: 3 records form an intact hash chain
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Change any audited byte and verification fails. The verifier is intentionally small: [examples/verify_audit.py](examples/verify_audit.py) calls the public [`verify_chain`](src/openmuse/audit.py) function. The audit contains a blocked attempt, the approved action, and its execution result.
|
|
113
|
+
|
|
114
|
+
## Status
|
|
115
|
+
|
|
116
|
+
| Capability | Status |
|
|
117
|
+
|---|---|
|
|
118
|
+
| Typed, budgeted agent loop | Working |
|
|
119
|
+
| Exact-action, expiring, one-time approvals | Working |
|
|
120
|
+
| Workspace file tools + SSRF-resistant public fetch | Working |
|
|
121
|
+
| Redacted hash-chained audit | Working |
|
|
122
|
+
| SQLite task checkpoints/cancel/restart | Working |
|
|
123
|
+
| In-process web channel adapter | Experimental |
|
|
124
|
+
| Envelope-encrypted local secret vault | Experimental |
|
|
125
|
+
| Browser-worker policy envelope | Experimental |
|
|
126
|
+
| Persistent task threads + atomic cron job claims | Working |
|
|
127
|
+
| Credential-free read-only mail/calendar connectors | Working |
|
|
128
|
+
| Production-capable read-only Google Calendar and Gmail connectors | Working |
|
|
129
|
+
| Managed Google OAuth code exchange, refresh, encrypted storage, and OS-keyring master key | Working |
|
|
130
|
+
| [Resource-limited OS process worker](docs/isolated-worker.md) | Working |
|
|
131
|
+
| Kernel/network-isolated browser worker | Not yet |
|
|
132
|
+
| Ephemeral OTP grants + exact-total validation | Working |
|
|
133
|
+
| Searchable, tiered, provenance-verifiable memory + edit/forget | Working |
|
|
134
|
+
|
|
135
|
+
Do not use OpenMuse with sensitive production accounts yet. “Working” means covered by the current test suite, not externally audited.
|
|
136
|
+
|
|
137
|
+
## How it works
|
|
138
|
+
|
|
139
|
+
`Channel -> durable Task -> Planner -> typed Action -> Policy/Approval -> Tool -> typed Result`
|
|
140
|
+
|
|
141
|
+
The model cannot mint approval tokens. Secret decryption happens through a host callback, not planner context. See [architecture](docs/architecture.md), [threat model](docs/threat-model.md), [product foundation](docs/product-foundation.md), and [roadmap](docs/roadmap.md).
|
|
142
|
+
|
|
143
|
+
## What OpenMuse is and is not
|
|
144
|
+
|
|
145
|
+
| In scope today | Not yet |
|
|
146
|
+
|---|---|
|
|
147
|
+
| Typed local tools, bounded loops, exact-action approval, encrypted local vault, durable tasks, audit verification, simulated mail/calendar connectors | Production browser isolation, independently deployed OAuth callback, independent security review, unattended use with sensitive accounts |
|
|
148
|
+
|
|
149
|
+
## Contributing
|
|
150
|
+
|
|
151
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md), [governance](GOVERNANCE.md), and the [code of conduct](CODE_OF_CONDUCT.md). Starter work is tracked with [`good first issue`](https://github.com/tahodev/openmuse/labels/good%20first%20issue) and [`help wanted`](https://github.com/tahodev/openmuse/labels/help%20wanted) labels.
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
MIT.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
OpenMuse is alpha software with no production-supported release. Report vulnerabilities using a [private GitHub security advisory](https://github.com/tahodev/openmuse/security/advisories/new), never a public issue.
|
|
4
|
+
|
|
5
|
+
## Current limits
|
|
6
|
+
|
|
7
|
+
The local vault encrypts secret values with per-secret AES-256-GCM data keys wrapped by an AES-256-GCM master key. The master key can be stored in the OS keyring through `KeyringMasterKey`, which fails closed when no usable system credential backend exists; hardware-backed storage is not yet integrated, and tools still share the Python process. `FetchURL` resolves a destination once, rejects the entire DNS answer set if any address is non-public, and pins the connection to a validated address while preserving TLS hostname verification; redirects are blocked rather than followed. The hash-chained audit is not externally anchored, and the approval UI is experimental. Use test accounts and non-sensitive data.
|
|
8
|
+
|
|
9
|
+
See the [threat model](docs/threat-model.md) and [production gate](docs/roadmap.md).
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Support
|
|
2
|
+
|
|
3
|
+
Use [GitHub issues](https://github.com/tahodev/openmuse/issues) for usage questions and reproducible bug reports. Do not post secrets or vulnerability details publicly. Use a [private GitHub security advisory](https://github.com/tahodev/openmuse/security/advisories/new) for security reports.
|