runtimetruth 0.2.0__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 (52) hide show
  1. runtimetruth-0.2.0/.github/dependabot.yml +11 -0
  2. runtimetruth-0.2.0/.github/workflows/ci.yml +111 -0
  3. runtimetruth-0.2.0/.github/workflows/release.yml +106 -0
  4. runtimetruth-0.2.0/.gitignore +24 -0
  5. runtimetruth-0.2.0/CHANGELOG.md +69 -0
  6. runtimetruth-0.2.0/CONTRIBUTING.md +61 -0
  7. runtimetruth-0.2.0/LICENSE +21 -0
  8. runtimetruth-0.2.0/PKG-INFO +294 -0
  9. runtimetruth-0.2.0/README.md +264 -0
  10. runtimetruth-0.2.0/SECURITY.md +46 -0
  11. runtimetruth-0.2.0/SUPPORT.md +37 -0
  12. runtimetruth-0.2.0/docs/architecture.md +145 -0
  13. runtimetruth-0.2.0/docs/attestation.md +236 -0
  14. runtimetruth-0.2.0/docs/ci.md +182 -0
  15. runtimetruth-0.2.0/docs/data-handling.md +65 -0
  16. runtimetruth-0.2.0/docs/landscape.md +96 -0
  17. runtimetruth-0.2.0/docs/origin.md +54 -0
  18. runtimetruth-0.2.0/docs/policy.md +87 -0
  19. runtimetruth-0.2.0/docs/release-v0.1.0.md +80 -0
  20. runtimetruth-0.2.0/docs/release-v0.2.0.md +62 -0
  21. runtimetruth-0.2.0/docs/roadmap.md +211 -0
  22. runtimetruth-0.2.0/docs/trust-model.md +100 -0
  23. runtimetruth-0.2.0/docs/vision.md +56 -0
  24. runtimetruth-0.2.0/pyproject.toml +63 -0
  25. runtimetruth-0.2.0/src/runtimetruth/__init__.py +3 -0
  26. runtimetruth-0.2.0/src/runtimetruth/attestation.py +343 -0
  27. runtimetruth-0.2.0/src/runtimetruth/cli.py +524 -0
  28. runtimetruth-0.2.0/src/runtimetruth/collectors/__init__.py +17 -0
  29. runtimetruth-0.2.0/src/runtimetruth/collectors/codex.py +602 -0
  30. runtimetruth-0.2.0/src/runtimetruth/collectors/errors.py +5 -0
  31. runtimetruth-0.2.0/src/runtimetruth/collectors/git.py +110 -0
  32. runtimetruth-0.2.0/src/runtimetruth/collectors/process.py +54 -0
  33. runtimetruth-0.2.0/src/runtimetruth/collectors/systemd.py +152 -0
  34. runtimetruth-0.2.0/src/runtimetruth/diff.py +290 -0
  35. runtimetruth-0.2.0/src/runtimetruth/inspection.py +36 -0
  36. runtimetruth-0.2.0/src/runtimetruth/model.py +221 -0
  37. runtimetruth-0.2.0/src/runtimetruth/policy.py +74 -0
  38. runtimetruth-0.2.0/tests/fixtures/snapshots/after.json +55 -0
  39. runtimetruth-0.2.0/tests/fixtures/snapshots/before.json +55 -0
  40. runtimetruth-0.2.0/tests/fixtures/systemd/agent-worker.show +19 -0
  41. runtimetruth-0.2.0/tests/test_attestation.py +395 -0
  42. runtimetruth-0.2.0/tests/test_attestation_policy.py +123 -0
  43. runtimetruth-0.2.0/tests/test_cli.py +619 -0
  44. runtimetruth-0.2.0/tests/test_codex.py +432 -0
  45. runtimetruth-0.2.0/tests/test_diff.py +413 -0
  46. runtimetruth-0.2.0/tests/test_git.py +86 -0
  47. runtimetruth-0.2.0/tests/test_inspection.py +109 -0
  48. runtimetruth-0.2.0/tests/test_model.py +99 -0
  49. runtimetruth-0.2.0/tests/test_policy.py +70 -0
  50. runtimetruth-0.2.0/tests/test_policy_cli.py +60 -0
  51. runtimetruth-0.2.0/tests/test_process.py +37 -0
  52. runtimetruth-0.2.0/tests/test_systemd.py +81 -0
@@ -0,0 +1,11 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+
8
+ - package-ecosystem: "github-actions"
9
+ directory: "/"
10
+ schedule:
11
+ interval: "weekly"
@@ -0,0 +1,111 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ matrix:
16
+ python-version: ["3.12", "3.13"]
17
+
18
+ steps:
19
+ - name: Check out repository
20
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
21
+
22
+ - name: Set up Python
23
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
24
+ with:
25
+ python-version: ${{ matrix.python-version }}
26
+ cache: pip
27
+
28
+ - name: Install
29
+ run: python -m pip install -e ".[dev]"
30
+
31
+ - name: Lint
32
+ run: ruff check .
33
+
34
+ - name: Format check
35
+ run: ruff format --check .
36
+
37
+ - name: Test
38
+ run: pytest
39
+
40
+ package:
41
+ runs-on: ubuntu-latest
42
+
43
+ steps:
44
+ - name: Check out repository
45
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
46
+
47
+ - name: Set up Python
48
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
49
+ with:
50
+ python-version: "3.12"
51
+ cache: pip
52
+
53
+ - name: Install build tooling
54
+ run: python -m pip install "build>=1.2"
55
+
56
+ - name: Build distributions
57
+ run: python -m build
58
+
59
+ - name: Install wheel in clean environment
60
+ run: |
61
+ python -m venv /tmp/runtimetruth-smoke
62
+ /tmp/runtimetruth-smoke/bin/python -m pip install dist/*.whl
63
+ /tmp/runtimetruth-smoke/bin/runtimetruth --version
64
+
65
+
66
+ attestation-smoke:
67
+ if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
68
+ runs-on: ubuntu-latest
69
+ permissions:
70
+ contents: read
71
+ id-token: write
72
+
73
+ steps:
74
+ - name: Check out repository
75
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
76
+
77
+ - name: Set up Python
78
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
79
+ with:
80
+ python-version: "3.12"
81
+ cache: pip
82
+
83
+ - name: Install RuntimeTruth
84
+ run: python -m pip install -e ".[dev]"
85
+
86
+ - name: Install Cosign
87
+ uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
88
+
89
+ - name: Keyless sign and verify baseline
90
+ shell: bash
91
+ run: |
92
+ set -euo pipefail
93
+
94
+ baseline="tests/fixtures/snapshots/before.json"
95
+ statement="${RUNNER_TEMP}/runtimetruth-baseline.intoto.json"
96
+ bundle="${RUNNER_TEMP}/runtimetruth-baseline.sigstore.json"
97
+ identity="https://github.com/${GITHUB_WORKFLOW_REF}"
98
+
99
+ runtimetruth digest "${baseline}"
100
+
101
+ runtimetruth attest "${baseline}" \
102
+ --statement "${statement}" \
103
+ --bundle "${bundle}"
104
+
105
+ runtimetruth verify-attestation \
106
+ "${baseline}" \
107
+ "${baseline}" \
108
+ --statement "${statement}" \
109
+ --bundle "${bundle}" \
110
+ --certificate-identity "${identity}" \
111
+ --certificate-oidc-issuer "https://token.actions.githubusercontent.com"
@@ -0,0 +1,106 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ build:
13
+ name: Build distributions
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - name: Check out repository
18
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
22
+ with:
23
+ python-version: "3.12"
24
+ cache: pip
25
+
26
+ - name: Verify tag matches package version
27
+ shell: bash
28
+ run: |
29
+ set -euo pipefail
30
+ expected="v$(python - <<'PY'
31
+ import tomllib
32
+ from pathlib import Path
33
+ data = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))
34
+ print(data["project"]["version"])
35
+ PY
36
+ )"
37
+
38
+ if [[ "${GITHUB_REF_NAME}" != "${expected}" ]]; then
39
+ echo "Tag ${GITHUB_REF_NAME} does not match package version ${expected}" >&2
40
+ exit 1
41
+ fi
42
+
43
+ - name: Install build tooling
44
+ run: python -m pip install "build>=1.2"
45
+
46
+ - name: Build distributions
47
+ run: python -m build
48
+
49
+ - name: Smoke-test wheel
50
+ shell: bash
51
+ run: |
52
+ set -euo pipefail
53
+ python -m venv /tmp/runtimetruth-release-smoke
54
+ /tmp/runtimetruth-release-smoke/bin/python -m pip install dist/*.whl
55
+ /tmp/runtimetruth-release-smoke/bin/runtimetruth --version
56
+
57
+ - name: Upload distributions
58
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
59
+ with:
60
+ name: python-package-distributions
61
+ path: dist/
62
+ if-no-files-found: error
63
+ retention-days: 7
64
+
65
+ publish-pypi:
66
+ name: Publish to PyPI
67
+ needs: build
68
+ runs-on: ubuntu-latest
69
+ environment:
70
+ name: pypi
71
+ url: https://pypi.org/p/runtimetruth
72
+ permissions:
73
+ id-token: write
74
+
75
+ steps:
76
+ - name: Download distributions
77
+ uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
78
+ with:
79
+ name: python-package-distributions
80
+ path: dist/
81
+
82
+ - name: Publish distributions
83
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
84
+
85
+ github-release:
86
+ name: Create GitHub release
87
+ needs: publish-pypi
88
+ runs-on: ubuntu-latest
89
+ permissions:
90
+ contents: write
91
+
92
+ steps:
93
+ - name: Check out repository
94
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
95
+
96
+ - name: Download distributions
97
+ uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
98
+ with:
99
+ name: python-package-distributions
100
+ path: dist/
101
+
102
+ - name: Create release
103
+ env:
104
+ GH_TOKEN: ${{ github.token }}
105
+ run: |
106
+ gh release create "${GITHUB_REF_NAME}" dist/* --title "RuntimeTruth ${GITHUB_REF_NAME}" --notes-file "docs/release-${GITHUB_REF_NAME}.md" --verify-tag
@@ -0,0 +1,24 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ build/
5
+ dist/
6
+
7
+ .venv/
8
+ venv/
9
+
10
+ .pytest_cache/
11
+ .ruff_cache/
12
+ .coverage
13
+ htmlcov/
14
+
15
+ .env
16
+ .env.*
17
+ !.env.example
18
+
19
+ .idea/
20
+ .vscode/
21
+ .DS_Store
22
+ Thumbs.db
23
+
24
+ .runtimetruth/
@@ -0,0 +1,69 @@
1
+ # Changelog
2
+
3
+ All notable user-facing changes to RuntimeTruth are documented here.
4
+
5
+ RuntimeTruth is pre-release software. Snapshot and report schemas are versioned independently from the package version, and compatibility guarantees may evolve before a stable 1.0 release.
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.2.0] - 2026-10-06
10
+
11
+ RuntimeTruth v0.2.0 adds an explicit trust chain for reviewed baselines, persisted runtime policy selectors, and the first normal PyPI distribution path.
12
+
13
+ ### Added
14
+
15
+ - RFC 8785 canonical baseline serialization and SHA-256 digest output via `runtimetruth digest`
16
+ - identity-backed baseline attestations using canonical in-toto Statement v1 and Sigstore Cosign
17
+ - `runtimetruth attest` for canonical statement + keyless Sigstore bundle generation
18
+ - `runtimetruth verify-attestation` for exact signer identity, baseline digest and runtime verification
19
+ - machine-readable identity/baseline/runtime verification reports via `--json`
20
+ - explicit schema-v1 TOML verification policies for persisted runtime selectors
21
+ - policy support for both plain and signed-baseline runtime verification
22
+ - PyPI release automation through GitHub OIDC Trusted Publishing
23
+
24
+ ### Security
25
+
26
+ - signed-attestation verification fails closed before current-runtime collection when signer identity or baseline binding cannot be verified
27
+ - snapshot and attestation JSON parsing rejects duplicate object keys
28
+ - RuntimeTruth validates the exact canonical in-toto statement after Cosign verifies its signature and signer identity
29
+ - runtime policy selection is evaluated only after signed-baseline trust verification succeeds
30
+ - the PyPI release job uses short-lived OIDC credentials instead of a long-lived package token
31
+
32
+ ## [0.1.0] - 2026-10-06
33
+
34
+ First public pre-release.
35
+
36
+ ### Added
37
+
38
+ - versioned schema-v1 runtime snapshots with explicit evidence provenance
39
+ - local systemd unit/runtime inspection
40
+ - procfs process identity inspection
41
+ - Git repository identity inspection
42
+ - composed systemd -> process -> repository evidence
43
+ - semantic snapshot diff with missing-vs-null preservation
44
+ - Codex runtime/version inspection
45
+ - Codex canonical resolved workspace configuration through app-server
46
+ - optional ephemeral-thread resolution for effective model/provider, approval and sandbox state
47
+ - Codex-reported instruction source inventory
48
+ - SHA-256 fingerprints of instruction source files without storing plaintext
49
+ - opt-in thread-scoped Codex MCP runtime inventory without MCP tool execution
50
+ - bounded MCP tool-name snapshots plus deterministic full-catalog fingerprints
51
+ - strict baseline verification with stable PASS / DRIFT / ERROR exit codes
52
+ - live Codex verification against a baseline without an intermediate current-snapshot file
53
+ - repeatable `--protect` selectors for agent-runtime invariants
54
+ - versioned machine-readable verification reports via `--json`
55
+ - CI integration guidance for pinned source installs and self-hosted runtime verification
56
+ - trust model, data-handling, support and security documentation
57
+
58
+ ### Security and privacy
59
+
60
+ - allowlist-based collection near sensitive runtime data
61
+ - no RuntimeTruth telemetry or hosted control plane
62
+ - no instruction plaintext, environment values, auth tokens, MCP resource contents or tool schemas serialized by current collectors
63
+ - explicit side-effect boundary for MCP runtime status probing
64
+
65
+ ### Known boundaries
66
+
67
+ - Codex thread resolution observes a newly-created ephemeral thread, not an existing user's active thread
68
+ - PASS is not a security or compliance certification
69
+ - RuntimeTruth does not classify MCP contract compatibility; MCP server contract testing is intentionally outside the product boundary
@@ -0,0 +1,61 @@
1
+ # Contributing to RuntimeTruth
2
+
3
+ RuntimeTruth is intentionally validation-driven. Changes should strengthen a concrete runtime-verification workflow rather than broaden the project surface speculatively.
4
+
5
+ ## Before opening a pull request
6
+
7
+ For non-trivial changes, open or reference an issue that states:
8
+
9
+ - the runtime-verification problem being solved
10
+ - the evidence source involved
11
+ - what RuntimeTruth can establish directly versus what would be inferred
12
+ - the security/privacy boundary
13
+ - how the behavior can be validated against a real or faithful fixture runtime
14
+
15
+ Small documentation and maintenance fixes do not need a design issue.
16
+
17
+ ## Development setup
18
+
19
+ Requires Python 3.12+.
20
+
21
+ ```bash
22
+ python -m venv .venv
23
+ source .venv/bin/activate
24
+ python -m pip install -e ".[dev]"
25
+
26
+ ruff check .
27
+ ruff format --check .
28
+ pytest
29
+ python -m build
30
+ ```
31
+
32
+ ## Change guidelines
33
+
34
+ Prefer small, reviewable slices.
35
+
36
+ - keep evidence provenance explicit
37
+ - do not silently infer unavailable runtime state
38
+ - use allowlists when collecting data near secrets or prompts
39
+ - do not add runtime dependencies without a concrete need
40
+ - preserve deterministic snapshot/report output
41
+ - add fixture-backed tests for new evidence or comparison behavior
42
+ - validate agent-specific behavior against the real runtime when practical
43
+ - reuse existing diff/verification paths rather than creating parallel semantics
44
+
45
+ For Codex probes, avoid starting model turns unless a feature explicitly requires and documents that behavior. MCP inspection must not call tools unless a future feature makes that side effect explicit.
46
+
47
+ ## Pull requests
48
+
49
+ A pull request should explain:
50
+
51
+ - what changed
52
+ - the evidence/trust boundary
53
+ - deliberate non-goals
54
+ - automated test coverage
55
+ - any real-runtime validation performed
56
+
57
+ The project normally uses squash merges so one feature lands on `main` as one coherent commit.
58
+
59
+ ## Security
60
+
61
+ Do not open a public issue containing vulnerability details or secrets. Follow [SECURITY.md](SECURITY.md).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sidelobe Labs
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,294 @@
1
+ Metadata-Version: 2.5
2
+ Name: runtimetruth
3
+ Version: 0.2.0
4
+ Summary: Runtime verification and drift detection for AI agents.
5
+ Project-URL: Homepage, https://sidelobe.dev/open-source/runtimetruth/
6
+ Project-URL: Repository, https://github.com/sidelobe-labs/runtimetruth
7
+ Project-URL: Issues, https://github.com/sidelobe-labs/runtimetruth/issues
8
+ Project-URL: Documentation, https://github.com/sidelobe-labs/runtimetruth/tree/main/docs
9
+ Project-URL: Changelog, https://github.com/sidelobe-labs/runtimetruth/blob/main/CHANGELOG.md
10
+ Author: Sidelobe Labs
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: agent-security,ai-agents,drift-detection,mcp,runtime
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Environment :: Console
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Quality Assurance
22
+ Classifier: Topic :: System :: Systems Administration
23
+ Requires-Python: >=3.12
24
+ Requires-Dist: rfc8785==0.1.4
25
+ Provides-Extra: dev
26
+ Requires-Dist: build>=1.2; extra == 'dev'
27
+ Requires-Dist: pytest>=8.3; extra == 'dev'
28
+ Requires-Dist: ruff>=0.11; extra == 'dev'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # RuntimeTruth
32
+
33
+ **Verify what your AI agent is actually running.**
34
+
35
+ _An open-source Sidelobe project._
36
+
37
+ [Project case study](https://sidelobe.dev/open-source/runtimetruth/) · [Engineering case study](https://artur.panek.tech/work/runtimetruth/) · [Engineering note](https://artur.panek.tech/notes/ai-agent-config-vs-runtime/) · [v0.2.0 release](https://github.com/sidelobe-labs/runtimetruth/releases/tag/v0.2.0)
38
+
39
+ RuntimeTruth is an open-source runtime verification and drift-detection tool for AI agents. It compares evidence from declared, resolved, and live runtime state so teams can identify changes in effective models, instructions, tools, MCP servers, permissions, runtime versions, and execution environment.
40
+
41
+ > Status: v0.2.0 pre-release. The local CLI, schema-v1 snapshots, Codex runtime inspection, semantic diff, persisted verification policy and identity-backed signed-baseline verification have been validated in CI and against real local runtimes.
42
+
43
+ ## Why
44
+
45
+ AI agents have more mutable runtime state than ordinary applications:
46
+
47
+ - model and provider routing
48
+ - system and project instructions
49
+ - tools and MCP schemas
50
+ - skills and plugins
51
+ - sandbox and network permissions
52
+ - executable/runtime versions
53
+ - environment and process identity
54
+ - repository/code state
55
+
56
+ A deployment can therefore look unchanged while the effective agent runtime has drifted.
57
+
58
+ RuntimeTruth currently focuses on two questions:
59
+
60
+ 1. **What runtime state can be established with explicit evidence?**
61
+ 2. **What changed since a known baseline?**
62
+
63
+ Broader policy evaluation and organizational provenance remain later phases.
64
+
65
+ ## Project model
66
+
67
+ RuntimeTruth is currently distributed as free, local-first open-source software. There is no RuntimeTruth hosted control plane, account system, telemetry service, paid support plan or SLA.
68
+
69
+ A verification result is deliberately narrow: **PASS means the selected evidence matched the selected baseline.** It does not mean the agent is secure, compliant, safe, or correctly configured in ways RuntimeTruth did not inspect.
70
+
71
+ See the [trust model](docs/trust-model.md), [data handling](docs/data-handling.md), [support policy](SUPPORT.md), and [MIT License](LICENSE) for the current project boundary.
72
+
73
+ ## Origin
74
+
75
+ RuntimeTruth grew out of operating self-hosted workers and noticing that source code and deployment configuration were not enough to answer a simple question: **what is actually running right now?**
76
+
77
+ The project is built from evidence outward. It started with systemd, procfs, and Git identity, then used the same model to inspect agent-specific Codex state.
78
+
79
+ [Read the origin story](docs/origin.md).
80
+
81
+ ## Installation
82
+
83
+ For the CLI, use an isolated tool environment:
84
+
85
+ ```bash
86
+ pipx install runtimetruth
87
+ ```
88
+
89
+ or:
90
+
91
+ ```bash
92
+ uv tool install runtimetruth
93
+ ```
94
+
95
+ Standard `pip` is also supported inside a virtual environment:
96
+
97
+ ```bash
98
+ python -m pip install runtimetruth
99
+ ```
100
+
101
+ Then verify the install:
102
+
103
+ ```bash
104
+ runtimetruth --version
105
+ ```
106
+
107
+ For CI workflows that require an exact source revision, pin the Git commit rather than following a moving branch. See [CI integration](docs/ci.md).
108
+
109
+ ## Quick start
110
+
111
+ Capture effective Codex runtime state:
112
+
113
+ ```bash
114
+ runtimetruth inspect codex . --resolve-thread --pretty > baseline.json
115
+ ```
116
+
117
+ Verify the current runtime against that baseline:
118
+
119
+ ```bash
120
+ runtimetruth verify baseline.json --codex . --resolve-thread
121
+ ```
122
+
123
+ Protect only selected runtime invariants when strict snapshot equality is too broad:
124
+
125
+ ```bash
126
+ runtimetruth verify baseline.json --codex . --resolve-thread \
127
+ --protect codex.thread.model \
128
+ --protect codex.instructions
129
+ ```
130
+
131
+ Persist repeated selectors in an explicit TOML policy:
132
+
133
+ ```toml
134
+ version = 1
135
+ protect = [
136
+ "codex.thread.model",
137
+ "codex.thread.sandbox",
138
+ "codex.instructions",
139
+ ]
140
+ ```
141
+
142
+ ```bash
143
+ runtimetruth verify baseline.json --codex . --resolve-thread \
144
+ --policy .runtimetruth/policy.toml
145
+ ```
146
+
147
+ The same policy can be used with `verify-attestation`; signer identity and baseline binding are verified before policy evaluation.
148
+
149
+ Add `--json` for a versioned machine-readable PASS/DRIFT report.
150
+
151
+ Bind a reviewed baseline to an identity-backed Sigstore attestation:
152
+
153
+ ```bash
154
+ runtimetruth digest baseline.json
155
+
156
+ runtimetruth attest baseline.json \
157
+ --statement baseline.intoto.json \
158
+ --bundle baseline.sigstore.json
159
+
160
+ runtimetruth verify-attestation \
161
+ baseline.json \
162
+ --statement baseline.intoto.json \
163
+ --bundle baseline.sigstore.json \
164
+ --certificate-identity "EXPECTED_IDENTITY" \
165
+ --certificate-oidc-issuer "EXPECTED_ISSUER" \
166
+ --codex . \
167
+ --resolve-thread
168
+ ```
169
+
170
+ Attestation uses RFC 8785 canonical JSON, SHA-256, in-toto Statement v1 and Sigstore Cosign rather than a RuntimeTruth-specific signature scheme. See [signed baseline attestations](docs/attestation.md).
171
+
172
+ ## Current CLI
173
+
174
+ Inspect a local target:
175
+
176
+ ```console
177
+ runtimetruth inspect systemd <unit>
178
+ runtimetruth inspect git <path>
179
+ runtimetruth inspect codex <cwd>
180
+ runtimetruth inspect codex <cwd> --resolve-thread
181
+ runtimetruth inspect codex <cwd> --resolve-mcp
182
+ ```
183
+
184
+ Compare two snapshots:
185
+
186
+ ```console
187
+ runtimetruth diff <before.json> <after.json>
188
+ ```
189
+
190
+ Verify a current snapshot against a baseline:
191
+
192
+ ```console
193
+ runtimetruth verify <baseline.json> <current.json>
194
+ ```
195
+
196
+ Or collect the current Codex runtime and verify it directly:
197
+
198
+ ```console
199
+ runtimetruth verify <baseline.json> --codex <cwd> --resolve-thread
200
+ runtimetruth verify <baseline.json> --codex <cwd> --resolve-mcp
201
+ ```
202
+
203
+ Verification uses stable process exit codes:
204
+
205
+ - `0` — runtime matches the baseline
206
+ - `2` — semantic runtime drift detected
207
+ - `1` — collection, input, or comparison error
208
+
209
+ Selective runtime invariants can be protected explicitly:
210
+
211
+ ```console
212
+ runtimetruth verify baseline.json --codex <cwd> --resolve-thread \
213
+ --protect codex.thread.model \
214
+ --protect codex.instructions
215
+ ```
216
+
217
+ For automation, add `--json` to emit a versioned structured PASS/DRIFT report without changing the exit-code contract.
218
+
219
+ Canonical baseline identity and signed verification are separate commands:
220
+
221
+ ```console
222
+ runtimetruth digest <baseline.json>
223
+
224
+ runtimetruth attest <baseline.json> \
225
+ --statement <baseline.intoto.json> \
226
+ --bundle <baseline.sigstore.json>
227
+
228
+ runtimetruth verify-attestation <baseline.json> [current.json] \
229
+ --statement <baseline.intoto.json> \
230
+ --bundle <baseline.sigstore.json> \
231
+ --certificate-identity <expected-identity> \
232
+ --certificate-oidc-issuer <expected-issuer>
233
+ ```
234
+
235
+ `verify-attestation` can also use `--codex <cwd>`, `--resolve-thread`, `--resolve-mcp`, `--policy <file>`, repeatable `--protect`, and `--json`.
236
+
237
+ Creating or verifying identity-backed attestations requires a recent [Sigstore Cosign](https://docs.sigstore.dev/cosign/system_config/installation/) executable. Normal inspect/diff/verify commands do not require Cosign.
238
+
239
+ `--resolve-thread` creates an ephemeral Codex thread without starting a turn. `--resolve-mcp` additionally probes thread-scoped MCP runtime state and may contact configured MCP servers or refresh authentication; it does not call MCP tools.
240
+
241
+ ## Evidence currently collected
242
+
243
+ The intentionally narrow implementation includes:
244
+
245
+ - systemd unit/runtime state
246
+ - procfs process identity
247
+ - Git repository identity
248
+ - Codex executable/version
249
+ - Codex canonical resolved workspace configuration
250
+ - effective state materialized for an ephemeral Codex thread
251
+ - Codex-reported instruction source paths
252
+ - SHA-256 fingerprints of those instruction source files without storing their plaintext
253
+ - thread-scoped MCP server status and bounded tool-catalog fingerprints
254
+
255
+ Each evidence record keeps its provenance and is classified as declared, resolved, or live where the source supports that claim.
256
+
257
+ ## Project boundary
258
+
259
+ RuntimeTruth is not intended to become a generic process monitor, LLM trace backend, MCP proxy/firewall, GitOps controller, or hosted observability dashboard.
260
+
261
+ The current focus is external validation of the baseline, attestation and policy model before adding additional agent adapters or cloud features.
262
+
263
+ See:
264
+
265
+ - [Origin](docs/origin.md)
266
+ - [Vision](docs/vision.md)
267
+ - [Landscape and positioning](docs/landscape.md)
268
+ - [Roadmap](docs/roadmap.md)
269
+ - [Architecture](docs/architecture.md)
270
+ - [CI integration](docs/ci.md)
271
+ - [Signed baseline attestations](docs/attestation.md)
272
+ - [Verification policy](docs/policy.md)
273
+ - [Contributing](CONTRIBUTING.md)
274
+ - [Security](SECURITY.md)
275
+ - [Trust model](docs/trust-model.md)
276
+ - [Data handling](docs/data-handling.md)
277
+ - [Support](SUPPORT.md)
278
+
279
+ ## Development
280
+
281
+ Requires Python 3.12+.
282
+
283
+ ```bash
284
+ python -m venv .venv
285
+ source .venv/bin/activate
286
+ python -m pip install -e ".[dev]"
287
+ ruff check .
288
+ ruff format --check .
289
+ pytest
290
+ ```
291
+
292
+ ## License
293
+
294
+ MIT.