runmark 0.2.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.
- runmark-0.2.1/LICENSE +21 -0
- runmark-0.2.1/PKG-INFO +149 -0
- runmark-0.2.1/README.md +116 -0
- runmark-0.2.1/pyproject.toml +71 -0
- runmark-0.2.1/setup.cfg +4 -0
- runmark-0.2.1/src/runmark/__init__.py +7 -0
- runmark-0.2.1/src/runmark/__main__.py +8 -0
- runmark-0.2.1/src/runmark/cli/__init__.py +5 -0
- runmark-0.2.1/src/runmark/cli/app.py +74 -0
- runmark-0.2.1/src/runmark/cli/commands/__init__.py +27 -0
- runmark-0.2.1/src/runmark/cli/commands/check.py +54 -0
- runmark-0.2.1/src/runmark/cli/commands/contract.py +236 -0
- runmark-0.2.1/src/runmark/cli/commands/diff.py +90 -0
- runmark-0.2.1/src/runmark/cli/commands/doctor.py +73 -0
- runmark-0.2.1/src/runmark/cli/commands/history.py +25 -0
- runmark-0.2.1/src/runmark/cli/commands/init.py +65 -0
- runmark-0.2.1/src/runmark/cli/commands/scan.py +25 -0
- runmark-0.2.1/src/runmark/cli/commands/share.py +104 -0
- runmark-0.2.1/src/runmark/cli/commands/snapshot.py +39 -0
- runmark-0.2.1/src/runmark/cli/commands/verify.py +75 -0
- runmark-0.2.1/src/runmark/cli/commands/version.py +36 -0
- runmark-0.2.1/src/runmark/contracts/__init__.py +60 -0
- runmark-0.2.1/src/runmark/contracts/canonicalizer.py +119 -0
- runmark-0.2.1/src/runmark/contracts/diff.py +390 -0
- runmark-0.2.1/src/runmark/contracts/discovery.py +33 -0
- runmark-0.2.1/src/runmark/contracts/evaluator.py +724 -0
- runmark-0.2.1/src/runmark/contracts/evidence.py +448 -0
- runmark-0.2.1/src/runmark/contracts/generator.py +107 -0
- runmark-0.2.1/src/runmark/contracts/parser.py +60 -0
- runmark-0.2.1/src/runmark/contracts/security.py +11 -0
- runmark-0.2.1/src/runmark/contracts/validator.py +157 -0
- runmark-0.2.1/src/runmark/contracts/version_constraints.py +234 -0
- runmark-0.2.1/src/runmark/core/__init__.py +32 -0
- runmark-0.2.1/src/runmark/core/contract_check.py +66 -0
- runmark-0.2.1/src/runmark/core/contract_diff.py +65 -0
- runmark-0.2.1/src/runmark/core/contract_init.py +80 -0
- runmark-0.2.1/src/runmark/core/diff.py +522 -0
- runmark-0.2.1/src/runmark/core/doctor.py +240 -0
- runmark-0.2.1/src/runmark/core/reporter.py +163 -0
- runmark-0.2.1/src/runmark/core/scanner.py +173 -0
- runmark-0.2.1/src/runmark/core/snapshot.py +34 -0
- runmark-0.2.1/src/runmark/core/verifier.py +83 -0
- runmark-0.2.1/src/runmark/detectors/__init__.py +86 -0
- runmark-0.2.1/src/runmark/detectors/base.py +66 -0
- runmark-0.2.1/src/runmark/detectors/containers/__init__.py +5 -0
- runmark-0.2.1/src/runmark/detectors/containers/compose.py +82 -0
- runmark-0.2.1/src/runmark/detectors/dependencies/__init__.py +9 -0
- runmark-0.2.1/src/runmark/detectors/dependencies/node.py +185 -0
- runmark-0.2.1/src/runmark/detectors/dependencies/python.py +162 -0
- runmark-0.2.1/src/runmark/detectors/environment/__init__.py +5 -0
- runmark-0.2.1/src/runmark/detectors/environment/env.py +89 -0
- runmark-0.2.1/src/runmark/detectors/git/__init__.py +5 -0
- runmark-0.2.1/src/runmark/detectors/git/git.py +81 -0
- runmark-0.2.1/src/runmark/detectors/network/__init__.py +5 -0
- runmark-0.2.1/src/runmark/detectors/network/ports.py +90 -0
- runmark-0.2.1/src/runmark/detectors/project/__init__.py +11 -0
- runmark-0.2.1/src/runmark/detectors/project/docker.py +48 -0
- runmark-0.2.1/src/runmark/detectors/project/node.py +95 -0
- runmark-0.2.1/src/runmark/detectors/project/python.py +97 -0
- runmark-0.2.1/src/runmark/detectors/registry.py +39 -0
- runmark-0.2.1/src/runmark/detectors/runtimes/__init__.py +13 -0
- runmark-0.2.1/src/runmark/detectors/runtimes/docker.py +59 -0
- runmark-0.2.1/src/runmark/detectors/runtimes/git.py +59 -0
- runmark-0.2.1/src/runmark/detectors/runtimes/node.py +59 -0
- runmark-0.2.1/src/runmark/detectors/runtimes/python.py +62 -0
- runmark-0.2.1/src/runmark/detectors/services/__init__.py +9 -0
- runmark-0.2.1/src/runmark/detectors/services/postgres.py +104 -0
- runmark-0.2.1/src/runmark/detectors/services/redis.py +104 -0
- runmark-0.2.1/src/runmark/detectors/system/__init__.py +5 -0
- runmark-0.2.1/src/runmark/detectors/system/system.py +40 -0
- runmark-0.2.1/src/runmark/models/__init__.py +81 -0
- runmark-0.2.1/src/runmark/models/common.py +36 -0
- runmark-0.2.1/src/runmark/models/container.py +14 -0
- runmark-0.2.1/src/runmark/models/contract.py +122 -0
- runmark-0.2.1/src/runmark/models/contract_result.py +84 -0
- runmark-0.2.1/src/runmark/models/dependency.py +19 -0
- runmark-0.2.1/src/runmark/models/diagnostic.py +133 -0
- runmark-0.2.1/src/runmark/models/environment.py +32 -0
- runmark-0.2.1/src/runmark/models/git.py +16 -0
- runmark-0.2.1/src/runmark/models/network.py +17 -0
- runmark-0.2.1/src/runmark/models/project.py +20 -0
- runmark-0.2.1/src/runmark/models/runmark.py +58 -0
- runmark-0.2.1/src/runmark/models/runtime.py +19 -0
- runmark-0.2.1/src/runmark/models/service.py +21 -0
- runmark-0.2.1/src/runmark/models/system.py +13 -0
- runmark-0.2.1/src/runmark/output/__init__.py +34 -0
- runmark-0.2.1/src/runmark/output/contract.py +337 -0
- runmark-0.2.1/src/runmark/output/json.py +16 -0
- runmark-0.2.1/src/runmark/output/markdown.py +172 -0
- runmark-0.2.1/src/runmark/output/tables.py +300 -0
- runmark-0.2.1/src/runmark/output/terminal.py +70 -0
- runmark-0.2.1/src/runmark/security/__init__.py +29 -0
- runmark-0.2.1/src/runmark/security/contract_sanitizer.py +38 -0
- runmark-0.2.1/src/runmark/security/export_sanitizer.py +142 -0
- runmark-0.2.1/src/runmark/security/redactor.py +75 -0
- runmark-0.2.1/src/runmark/security/sanitizer.py +105 -0
- runmark-0.2.1/src/runmark/security/secret_patterns.py +116 -0
- runmark-0.2.1/src/runmark/storage/__init__.py +6 -0
- runmark-0.2.1/src/runmark/storage/filesystem.py +133 -0
- runmark-0.2.1/src/runmark/storage/paths.py +60 -0
- runmark-0.2.1/src/runmark/utils/__init__.py +20 -0
- runmark-0.2.1/src/runmark/utils/commands.py +117 -0
- runmark-0.2.1/src/runmark/utils/hashing.py +240 -0
- runmark-0.2.1/src/runmark/utils/platform.py +36 -0
- runmark-0.2.1/src/runmark.egg-info/PKG-INFO +149 -0
- runmark-0.2.1/src/runmark.egg-info/SOURCES.txt +108 -0
- runmark-0.2.1/src/runmark.egg-info/dependency_links.txt +1 -0
- runmark-0.2.1/src/runmark.egg-info/entry_points.txt +2 -0
- runmark-0.2.1/src/runmark.egg-info/requires.txt +11 -0
- runmark-0.2.1/src/runmark.egg-info/top_level.txt +1 -0
runmark-0.2.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Runmark Maintainers
|
|
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.
|
runmark-0.2.1/PKG-INFO
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: runmark
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Know what makes your code run. Local-first development environment observability, fingerprinting, comparison, and verification.
|
|
5
|
+
Author: Runmark Maintainers
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Development Status :: 4 - Beta
|
|
8
|
+
Classifier: Environment :: Console
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
17
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
18
|
+
Classifier: Topic :: System :: Systems Administration
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: pydantic>=2.0.0
|
|
23
|
+
Requires-Dist: typer>=0.12.0
|
|
24
|
+
Requires-Dist: rich>=13.0.0
|
|
25
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
29
|
+
Requires-Dist: ruff>=0.4.0; extra == "dev"
|
|
30
|
+
Requires-Dist: mypy>=1.10.0; extra == "dev"
|
|
31
|
+
Requires-Dist: jsonschema>=4.20.0; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# Runmark
|
|
35
|
+
|
|
36
|
+
> **Know what makes your code run.**
|
|
37
|
+
> *Git tracks your code. Runmark tracks what makes your code run.*
|
|
38
|
+
|
|
39
|
+
[](https://opensource.org/licenses/MIT)
|
|
40
|
+
[](https://www.python.org/downloads/)
|
|
41
|
+
[]()
|
|
42
|
+
[]()
|
|
43
|
+
[]()
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## The Problem
|
|
48
|
+
|
|
49
|
+
Software frequently fails because the development environment differs between machines:
|
|
50
|
+
- **Developer A** has Python 3.12, Node 22, PostgreSQL 16, Redis 7, Docker 28, and valid `.env` variables.
|
|
51
|
+
- **Developer B** has Python 3.11, Node 20, PostgreSQL 17, Redis stopped, and a missing environment variable.
|
|
52
|
+
|
|
53
|
+
Both developers have the exact same Git repository commit, yet the application breaks.
|
|
54
|
+
|
|
55
|
+
Git tracks source code. Package managers lock application dependencies. Containers reproduce environments. **Runmark is the missing observation, fingerprinting, comparison, verification, and diagnosis layer.**
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## What Runmark Is NOT
|
|
60
|
+
|
|
61
|
+
To keep expectations clear, Runmark is deliberately focused:
|
|
62
|
+
- **Runmark is NOT a package manager.** It does not replace `pip`, `uv`, `npm`, `pnpm`, or `cargo`.
|
|
63
|
+
- **Runmark is NOT a container manager.** It does not replace `docker`, `podman`, or `k8s`.
|
|
64
|
+
- **Runmark is NOT an AI coding assistant.** It relies on deterministic facts and structural verification.
|
|
65
|
+
- **Runmark is NOT a cloud platform.** It is 100% local-first, offline, and zero-telemetry.
|
|
66
|
+
- **Runmark is NOT an environment installer.** It never automatically installs packages or mutates system state.
|
|
67
|
+
- **Runmark is NOT a replacement for Git or Docker.** It observes and diagnoses what makes your code run alongside them.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Key Features
|
|
72
|
+
|
|
73
|
+
- 🏗️ **Contract Bootstrap (`runmark contract init`)**: Automatically synthesize canonical `runmark.json` contracts from project evidence manifests (`pyproject.toml`, `package.json`, `Dockerfile`, `compose.yaml`, `.env.example`).
|
|
74
|
+
- 🔄 **Semantic Contract Diffing (`runmark contract diff`)**: Compare contract requirement changes against Git baseline (`HEAD:runmark.json`) or previous versions before committing.
|
|
75
|
+
- 📜 **Environment Contracts (`runmark.json`)**: Declare project runtime, service, dependency, environment, network, and container requirements directly alongside source code.
|
|
76
|
+
- ⚡ **Contract Proof & Evaluation (`runmark check`)**: Prove deterministically whether the host machine satisfies project requirements before running builds or tests.
|
|
77
|
+
- 🔍 **Detailed Diagnostic Explanations (`runmark check --explain`)**: Deeply diagnose failed or unknown requirements with explicit evidence citations, causal explanations, and actionable remediation steps.
|
|
78
|
+
- 🛠️ **Contract Tooling (`runmark contract`)**: Validate syntax, JSON schema, domain semantics, and security (`runmark contract validate`), inspect normalized specifications (`runmark contract show`), or initialize contracts (`runmark contract init`).
|
|
79
|
+
- 📤 **Share & Diagnose**: Generate clean, sanitized, portable Markdown or JSON diagnostic reports (`runmark share`) ready to attach directly to GitHub Issues, Slack, or teammate chats.
|
|
80
|
+
- 🛡️ **Zero-Secret Guarantee & Security Boundaries**: Multi-pass secret scanning prevents credentials, API keys, passwords in URIs, or tokens from escaping in shared reports or being stored in contract files (exit code `4`).
|
|
81
|
+
- 🔍 **Safe Scanning**: Inspects project signals, runtimes (Python, Node, Docker, Git), dependencies, local services (PostgreSQL, Redis), ports, and environment variable requirements.
|
|
82
|
+
- 🏷️ **Deterministic Fingerprinting**: Computes a canonical SHA-256 environment fingerprint decoupled from source code commits and timestamps.
|
|
83
|
+
- ⚡ **Semantic Diffing**: Categorizes drift as `ADDED`, `REMOVED`, `CHANGED`, and `UNCHANGED` with rule-driven severity (`INFO`, `WARNING`, `CRITICAL`).
|
|
84
|
+
- 🛡️ **Environment Verification**: Verifies your current machine against a baseline snapshot with CI-ready exit codes (`0`, `1`, `2`, `3`, `4`).
|
|
85
|
+
- 🩺 **Doctor Mode**: Explains environment discrepancies with distinct observed evidence, inferred reasoning, and read-only remediation advice.
|
|
86
|
+
- 💻 **Local-First & Cross-Platform**: 100% offline, cross-platform (Windows, Linux, macOS), atomic filesystem storage, and zero telemetry.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Quick Start
|
|
91
|
+
|
|
92
|
+
### Installation
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pip install runmark
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Basic Workflow
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# 1. Bootstrap an environment contract from project evidence
|
|
102
|
+
runmark contract init --dry-run
|
|
103
|
+
runmark contract init --yes
|
|
104
|
+
|
|
105
|
+
# 2. Check current machine against project environment contract
|
|
106
|
+
runmark check
|
|
107
|
+
runmark check --explain
|
|
108
|
+
|
|
109
|
+
# 3. Compare contract requirement changes against Git HEAD
|
|
110
|
+
runmark contract diff
|
|
111
|
+
|
|
112
|
+
# 4. Inspect your current development environment
|
|
113
|
+
runmark scan
|
|
114
|
+
|
|
115
|
+
# 5. Save a known-good baseline snapshot
|
|
116
|
+
runmark snapshot -m "Initial working dev environment"
|
|
117
|
+
|
|
118
|
+
# 6. Compare current machine state against the snapshot
|
|
119
|
+
runmark diff
|
|
120
|
+
|
|
121
|
+
# 7. Verify compliance in CI or on coworker machines
|
|
122
|
+
runmark verify --strict
|
|
123
|
+
|
|
124
|
+
# 8. Diagnose and fix discrepancies
|
|
125
|
+
runmark doctor
|
|
126
|
+
|
|
127
|
+
# 9. Safely share a sanitized diagnostic report with teammates
|
|
128
|
+
runmark share --output report.md
|
|
129
|
+
|
|
130
|
+
# 10. Inspect and validate environment contracts
|
|
131
|
+
runmark contract validate
|
|
132
|
+
runmark contract show
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Documentation
|
|
138
|
+
|
|
139
|
+
- [Environment Contracts Guide](docs/contracts.md)
|
|
140
|
+
- [Architecture Guide](docs/architecture.md)
|
|
141
|
+
- [Specification & Exit Codes](docs/specification.md)
|
|
142
|
+
- [Security Policy](docs/security.md)
|
|
143
|
+
- [Detectors Guide](docs/detectors.md)
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## License
|
|
148
|
+
|
|
149
|
+
MIT © Runmark Maintainers
|
runmark-0.2.1/README.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Runmark
|
|
2
|
+
|
|
3
|
+
> **Know what makes your code run.**
|
|
4
|
+
> *Git tracks your code. Runmark tracks what makes your code run.*
|
|
5
|
+
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://www.python.org/downloads/)
|
|
8
|
+
[]()
|
|
9
|
+
[]()
|
|
10
|
+
[]()
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## The Problem
|
|
15
|
+
|
|
16
|
+
Software frequently fails because the development environment differs between machines:
|
|
17
|
+
- **Developer A** has Python 3.12, Node 22, PostgreSQL 16, Redis 7, Docker 28, and valid `.env` variables.
|
|
18
|
+
- **Developer B** has Python 3.11, Node 20, PostgreSQL 17, Redis stopped, and a missing environment variable.
|
|
19
|
+
|
|
20
|
+
Both developers have the exact same Git repository commit, yet the application breaks.
|
|
21
|
+
|
|
22
|
+
Git tracks source code. Package managers lock application dependencies. Containers reproduce environments. **Runmark is the missing observation, fingerprinting, comparison, verification, and diagnosis layer.**
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## What Runmark Is NOT
|
|
27
|
+
|
|
28
|
+
To keep expectations clear, Runmark is deliberately focused:
|
|
29
|
+
- **Runmark is NOT a package manager.** It does not replace `pip`, `uv`, `npm`, `pnpm`, or `cargo`.
|
|
30
|
+
- **Runmark is NOT a container manager.** It does not replace `docker`, `podman`, or `k8s`.
|
|
31
|
+
- **Runmark is NOT an AI coding assistant.** It relies on deterministic facts and structural verification.
|
|
32
|
+
- **Runmark is NOT a cloud platform.** It is 100% local-first, offline, and zero-telemetry.
|
|
33
|
+
- **Runmark is NOT an environment installer.** It never automatically installs packages or mutates system state.
|
|
34
|
+
- **Runmark is NOT a replacement for Git or Docker.** It observes and diagnoses what makes your code run alongside them.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Key Features
|
|
39
|
+
|
|
40
|
+
- 🏗️ **Contract Bootstrap (`runmark contract init`)**: Automatically synthesize canonical `runmark.json` contracts from project evidence manifests (`pyproject.toml`, `package.json`, `Dockerfile`, `compose.yaml`, `.env.example`).
|
|
41
|
+
- 🔄 **Semantic Contract Diffing (`runmark contract diff`)**: Compare contract requirement changes against Git baseline (`HEAD:runmark.json`) or previous versions before committing.
|
|
42
|
+
- 📜 **Environment Contracts (`runmark.json`)**: Declare project runtime, service, dependency, environment, network, and container requirements directly alongside source code.
|
|
43
|
+
- ⚡ **Contract Proof & Evaluation (`runmark check`)**: Prove deterministically whether the host machine satisfies project requirements before running builds or tests.
|
|
44
|
+
- 🔍 **Detailed Diagnostic Explanations (`runmark check --explain`)**: Deeply diagnose failed or unknown requirements with explicit evidence citations, causal explanations, and actionable remediation steps.
|
|
45
|
+
- 🛠️ **Contract Tooling (`runmark contract`)**: Validate syntax, JSON schema, domain semantics, and security (`runmark contract validate`), inspect normalized specifications (`runmark contract show`), or initialize contracts (`runmark contract init`).
|
|
46
|
+
- 📤 **Share & Diagnose**: Generate clean, sanitized, portable Markdown or JSON diagnostic reports (`runmark share`) ready to attach directly to GitHub Issues, Slack, or teammate chats.
|
|
47
|
+
- 🛡️ **Zero-Secret Guarantee & Security Boundaries**: Multi-pass secret scanning prevents credentials, API keys, passwords in URIs, or tokens from escaping in shared reports or being stored in contract files (exit code `4`).
|
|
48
|
+
- 🔍 **Safe Scanning**: Inspects project signals, runtimes (Python, Node, Docker, Git), dependencies, local services (PostgreSQL, Redis), ports, and environment variable requirements.
|
|
49
|
+
- 🏷️ **Deterministic Fingerprinting**: Computes a canonical SHA-256 environment fingerprint decoupled from source code commits and timestamps.
|
|
50
|
+
- ⚡ **Semantic Diffing**: Categorizes drift as `ADDED`, `REMOVED`, `CHANGED`, and `UNCHANGED` with rule-driven severity (`INFO`, `WARNING`, `CRITICAL`).
|
|
51
|
+
- 🛡️ **Environment Verification**: Verifies your current machine against a baseline snapshot with CI-ready exit codes (`0`, `1`, `2`, `3`, `4`).
|
|
52
|
+
- 🩺 **Doctor Mode**: Explains environment discrepancies with distinct observed evidence, inferred reasoning, and read-only remediation advice.
|
|
53
|
+
- 💻 **Local-First & Cross-Platform**: 100% offline, cross-platform (Windows, Linux, macOS), atomic filesystem storage, and zero telemetry.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
### Installation
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install runmark
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Basic Workflow
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# 1. Bootstrap an environment contract from project evidence
|
|
69
|
+
runmark contract init --dry-run
|
|
70
|
+
runmark contract init --yes
|
|
71
|
+
|
|
72
|
+
# 2. Check current machine against project environment contract
|
|
73
|
+
runmark check
|
|
74
|
+
runmark check --explain
|
|
75
|
+
|
|
76
|
+
# 3. Compare contract requirement changes against Git HEAD
|
|
77
|
+
runmark contract diff
|
|
78
|
+
|
|
79
|
+
# 4. Inspect your current development environment
|
|
80
|
+
runmark scan
|
|
81
|
+
|
|
82
|
+
# 5. Save a known-good baseline snapshot
|
|
83
|
+
runmark snapshot -m "Initial working dev environment"
|
|
84
|
+
|
|
85
|
+
# 6. Compare current machine state against the snapshot
|
|
86
|
+
runmark diff
|
|
87
|
+
|
|
88
|
+
# 7. Verify compliance in CI or on coworker machines
|
|
89
|
+
runmark verify --strict
|
|
90
|
+
|
|
91
|
+
# 8. Diagnose and fix discrepancies
|
|
92
|
+
runmark doctor
|
|
93
|
+
|
|
94
|
+
# 9. Safely share a sanitized diagnostic report with teammates
|
|
95
|
+
runmark share --output report.md
|
|
96
|
+
|
|
97
|
+
# 10. Inspect and validate environment contracts
|
|
98
|
+
runmark contract validate
|
|
99
|
+
runmark contract show
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Documentation
|
|
105
|
+
|
|
106
|
+
- [Environment Contracts Guide](docs/contracts.md)
|
|
107
|
+
- [Architecture Guide](docs/architecture.md)
|
|
108
|
+
- [Specification & Exit Codes](docs/specification.md)
|
|
109
|
+
- [Security Policy](docs/security.md)
|
|
110
|
+
- [Detectors Guide](docs/detectors.md)
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## License
|
|
115
|
+
|
|
116
|
+
MIT © Runmark Maintainers
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "runmark"
|
|
7
|
+
version = "0.2.1"
|
|
8
|
+
description = "Know what makes your code run. Local-first development environment observability, fingerprinting, comparison, and verification."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Runmark Maintainers" }
|
|
14
|
+
]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Topic :: Software Development :: Build Tools",
|
|
26
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
27
|
+
"Topic :: System :: Systems Administration",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"pydantic>=2.0.0",
|
|
31
|
+
"typer>=0.12.0",
|
|
32
|
+
"rich>=13.0.0",
|
|
33
|
+
"pyyaml>=6.0.0",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
dev = [
|
|
38
|
+
"pytest>=8.0.0",
|
|
39
|
+
"pytest-cov>=5.0.0",
|
|
40
|
+
"ruff>=0.4.0",
|
|
41
|
+
"mypy>=1.10.0",
|
|
42
|
+
"jsonschema>=4.20.0",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[project.scripts]
|
|
46
|
+
runmark = "runmark.cli.app:main"
|
|
47
|
+
|
|
48
|
+
[tool.setuptools.packages.find]
|
|
49
|
+
where = ["src"]
|
|
50
|
+
|
|
51
|
+
[tool.ruff]
|
|
52
|
+
line-length = 100
|
|
53
|
+
target-version = "py310"
|
|
54
|
+
|
|
55
|
+
[tool.ruff.lint]
|
|
56
|
+
select = [
|
|
57
|
+
"E", # pycodestyle errors
|
|
58
|
+
"W", # pycodestyle warnings
|
|
59
|
+
"F", # pyflakes
|
|
60
|
+
"I", # isort
|
|
61
|
+
"B", # flake8-bugbear
|
|
62
|
+
"C4", # flake8-comprehensions
|
|
63
|
+
"UP", # pyupgrade
|
|
64
|
+
]
|
|
65
|
+
ignore = ["E501", "B008"]
|
|
66
|
+
|
|
67
|
+
[tool.pytest.ini_options]
|
|
68
|
+
minversion = "7.0"
|
|
69
|
+
addopts = "-ra -q"
|
|
70
|
+
testpaths = ["tests"]
|
|
71
|
+
pythonpath = ["src"]
|
runmark-0.2.1/setup.cfg
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Runmark CLI application entrypoint."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from runmark.cli.commands.check import check_command
|
|
8
|
+
from runmark.cli.commands.contract import contract_app
|
|
9
|
+
from runmark.cli.commands.diff import diff_command
|
|
10
|
+
from runmark.cli.commands.doctor import doctor_command
|
|
11
|
+
from runmark.cli.commands.history import history_command
|
|
12
|
+
from runmark.cli.commands.init import init_command
|
|
13
|
+
from runmark.cli.commands.scan import scan_command
|
|
14
|
+
from runmark.cli.commands.share import share_command
|
|
15
|
+
from runmark.cli.commands.snapshot import snapshot_command
|
|
16
|
+
from runmark.cli.commands.verify import verify_command
|
|
17
|
+
from runmark.cli.commands.version import version_command
|
|
18
|
+
from runmark.output.terminal import term
|
|
19
|
+
|
|
20
|
+
app = typer.Typer(
|
|
21
|
+
name="runmark",
|
|
22
|
+
help="Runmark — Know what makes your code run.\n\nGit tracks your code. Runmark tracks what makes your code run.",
|
|
23
|
+
no_args_is_help=True,
|
|
24
|
+
add_completion=False,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Register subcommands
|
|
28
|
+
app.command("init", help="Initialize Runmark tracking in the current project.")(init_command)
|
|
29
|
+
app.command(
|
|
30
|
+
"scan", help="Inspect and display the complete runtime, dependency, and service state."
|
|
31
|
+
)(scan_command)
|
|
32
|
+
app.command(
|
|
33
|
+
"check",
|
|
34
|
+
help="Evaluate whether the host environment satisfies the project environment contract (runmark.json).",
|
|
35
|
+
)(check_command)
|
|
36
|
+
app.add_typer(contract_app)
|
|
37
|
+
app.command(
|
|
38
|
+
"snapshot",
|
|
39
|
+
help="Capture and persist current environment state into an immutable baseline snapshot.",
|
|
40
|
+
)(snapshot_command)
|
|
41
|
+
app.command(
|
|
42
|
+
"diff", help="Compare environment state between snapshots or against live environment."
|
|
43
|
+
)(diff_command)
|
|
44
|
+
app.command("verify", help="Verify current machine environment against a baseline snapshot.")(
|
|
45
|
+
verify_command
|
|
46
|
+
)
|
|
47
|
+
app.command(
|
|
48
|
+
"doctor", help="Diagnose environment discrepancies and get actionable remediation advice."
|
|
49
|
+
)(doctor_command)
|
|
50
|
+
app.command(
|
|
51
|
+
"share",
|
|
52
|
+
help="Generate a sanitized, portable diagnostic report for sharing with teammates or issues.",
|
|
53
|
+
)(share_command)
|
|
54
|
+
app.command("version", help="Display version and platform diagnostics.")(version_command)
|
|
55
|
+
app.command("history", help="List snapshot history.")(history_command)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def main() -> int:
|
|
59
|
+
"""Main CLI entrypoint."""
|
|
60
|
+
try:
|
|
61
|
+
app()
|
|
62
|
+
return 0
|
|
63
|
+
except typer.Exit as e:
|
|
64
|
+
return e.exit_code
|
|
65
|
+
except KeyboardInterrupt:
|
|
66
|
+
term.print("\n[dim]Operation cancelled by user.[/dim]")
|
|
67
|
+
return 130
|
|
68
|
+
except Exception as exc:
|
|
69
|
+
term.print_error(f"Unexpected error: {exc}")
|
|
70
|
+
return 3
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if __name__ == "__main__":
|
|
74
|
+
sys.exit(main())
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""CLI commands package."""
|
|
2
|
+
|
|
3
|
+
from runmark.cli.commands.check import check_command
|
|
4
|
+
from runmark.cli.commands.contract import contract_app
|
|
5
|
+
from runmark.cli.commands.diff import diff_command
|
|
6
|
+
from runmark.cli.commands.doctor import doctor_command
|
|
7
|
+
from runmark.cli.commands.history import history_command
|
|
8
|
+
from runmark.cli.commands.init import init_command
|
|
9
|
+
from runmark.cli.commands.scan import scan_command
|
|
10
|
+
from runmark.cli.commands.share import share_command
|
|
11
|
+
from runmark.cli.commands.snapshot import snapshot_command
|
|
12
|
+
from runmark.cli.commands.verify import verify_command
|
|
13
|
+
from runmark.cli.commands.version import version_command
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"check_command",
|
|
17
|
+
"contract_app",
|
|
18
|
+
"diff_command",
|
|
19
|
+
"doctor_command",
|
|
20
|
+
"history_command",
|
|
21
|
+
"init_command",
|
|
22
|
+
"scan_command",
|
|
23
|
+
"share_command",
|
|
24
|
+
"snapshot_command",
|
|
25
|
+
"verify_command",
|
|
26
|
+
"version_command",
|
|
27
|
+
]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""CLI command: runmark check."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from runmark.contracts.parser import ContractParseError
|
|
8
|
+
from runmark.contracts.security import ContractSecurityError
|
|
9
|
+
from runmark.contracts.validator import ContractValidationError
|
|
10
|
+
from runmark.core.contract_check import ContractCheckService
|
|
11
|
+
from runmark.output.contract import render_contract_check
|
|
12
|
+
from runmark.output.terminal import term
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def check_command(
|
|
16
|
+
path: Path | None = typer.Option(
|
|
17
|
+
None,
|
|
18
|
+
"--path",
|
|
19
|
+
"-p",
|
|
20
|
+
help="Target project root directory (defaults to current directory)",
|
|
21
|
+
),
|
|
22
|
+
json_output: bool = typer.Option(
|
|
23
|
+
False,
|
|
24
|
+
"--json",
|
|
25
|
+
help="Output evaluation results as machine-readable JSON",
|
|
26
|
+
),
|
|
27
|
+
explain: bool = typer.Option(
|
|
28
|
+
False,
|
|
29
|
+
"--explain",
|
|
30
|
+
help="Display detailed diagnostic breakdown and suggested actions for unsatisfied requirements",
|
|
31
|
+
),
|
|
32
|
+
) -> None:
|
|
33
|
+
"""Evaluate whether current host environment satisfies the project environment contract (runmark.json)."""
|
|
34
|
+
try:
|
|
35
|
+
contract, result = ContractCheckService.check_environment(project_path=path)
|
|
36
|
+
except ContractSecurityError as sec_err:
|
|
37
|
+
term.print_error(str(sec_err))
|
|
38
|
+
raise typer.Exit(code=4) from None
|
|
39
|
+
except (FileNotFoundError, ContractParseError, ContractValidationError) as err:
|
|
40
|
+
term.print_error(str(err))
|
|
41
|
+
raise typer.Exit(code=2) from None
|
|
42
|
+
except Exception as exc:
|
|
43
|
+
term.print_error(f"Internal error during contract evaluation: {exc}")
|
|
44
|
+
raise typer.Exit(code=3) from None
|
|
45
|
+
|
|
46
|
+
if json_output:
|
|
47
|
+
term.print_json(result)
|
|
48
|
+
else:
|
|
49
|
+
render_contract_check(result, explain=explain)
|
|
50
|
+
|
|
51
|
+
if result.is_passed:
|
|
52
|
+
raise typer.Exit(code=0)
|
|
53
|
+
else:
|
|
54
|
+
raise typer.Exit(code=1)
|