agentcam 0.1.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.
- agentcam-0.1.0/.github/workflows/ci.yml +47 -0
- agentcam-0.1.0/.gitignore +22 -0
- agentcam-0.1.0/CHANGELOG.md +156 -0
- agentcam-0.1.0/LICENSE +21 -0
- agentcam-0.1.0/PKG-INFO +313 -0
- agentcam-0.1.0/README.md +291 -0
- agentcam-0.1.0/ROADMAP.md +211 -0
- agentcam-0.1.0/SECURITY.md +122 -0
- agentcam-0.1.0/docs/design.md +588 -0
- agentcam-0.1.0/examples/risky-auth-change/README.md +58 -0
- agentcam-0.1.0/examples/risky-auth-change/expected-report.md +93 -0
- agentcam-0.1.0/pyproject.toml +47 -0
- agentcam-0.1.0/src/agentcam/__init__.py +4 -0
- agentcam-0.1.0/src/agentcam/cli.py +252 -0
- agentcam-0.1.0/src/agentcam/git_state.py +207 -0
- agentcam-0.1.0/src/agentcam/models.py +146 -0
- agentcam-0.1.0/src/agentcam/paths.py +102 -0
- agentcam-0.1.0/src/agentcam/redaction.py +259 -0
- agentcam-0.1.0/src/agentcam/report.py +407 -0
- agentcam-0.1.0/src/agentcam/runner.py +301 -0
- agentcam-0.1.0/src/agentcam/scanner.py +363 -0
- agentcam-0.1.0/tests/conftest.py +39 -0
- agentcam-0.1.0/tests/test_e2e.py +293 -0
- agentcam-0.1.0/tests/test_git_state.py +212 -0
- agentcam-0.1.0/tests/test_paths.py +109 -0
- agentcam-0.1.0/tests/test_redaction.py +312 -0
- agentcam-0.1.0/tests/test_report.py +384 -0
- agentcam-0.1.0/tests/test_runner.py +309 -0
- agentcam-0.1.0/tests/test_scanner.py +314 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
runs-on: ${{ matrix.os }}
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
19
|
+
python-version: ["3.11", "3.12"]
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
25
|
+
uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: ${{ matrix.python-version }}
|
|
28
|
+
|
|
29
|
+
- name: Install agentcam + dev deps
|
|
30
|
+
run: |
|
|
31
|
+
python -m pip install --upgrade pip
|
|
32
|
+
python -m pip install -e ".[dev]"
|
|
33
|
+
|
|
34
|
+
- name: Show environment
|
|
35
|
+
run: |
|
|
36
|
+
python --version
|
|
37
|
+
git --version
|
|
38
|
+
agentcam version
|
|
39
|
+
|
|
40
|
+
- name: Configure git identity (needed by tmp_git_repo fixture)
|
|
41
|
+
run: |
|
|
42
|
+
git config --global user.email "ci@example.com"
|
|
43
|
+
git config --global user.name "CI"
|
|
44
|
+
git config --global commit.gpgsign false
|
|
45
|
+
|
|
46
|
+
- name: Run pytest
|
|
47
|
+
run: python -m pytest -v --maxfail=5
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
*.pyo
|
|
4
|
+
*.pyd
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
*.egg-info/
|
|
7
|
+
.venv/
|
|
8
|
+
.venv*/
|
|
9
|
+
venv/
|
|
10
|
+
env/
|
|
11
|
+
dist/
|
|
12
|
+
build/
|
|
13
|
+
.coverage
|
|
14
|
+
.coverage.*
|
|
15
|
+
htmlcov/
|
|
16
|
+
.ruff_cache/
|
|
17
|
+
.mypy_cache/
|
|
18
|
+
.tox/
|
|
19
|
+
*.swp
|
|
20
|
+
*.swo
|
|
21
|
+
.DS_Store
|
|
22
|
+
Thumbs.db
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to agentcam are recorded here. Format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) loosely.
|
|
5
|
+
Versioning follows [SemVer](https://semver.org/) once 1.0.0 ships;
|
|
6
|
+
0.x is unstable on purpose.
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Renamed (2026-05-16)
|
|
11
|
+
|
|
12
|
+
- **Package + CLI renamed `agentbox` → `agentcam`** (PyPI name `agentbox`
|
|
13
|
+
was taken; `agentcam` is available on PyPI and free of prominent GitHub
|
|
14
|
+
collisions). Source dir `src/agentbox/` → `src/agentcam/`; CLI entry
|
|
15
|
+
`agentbox` → `agentcam`; artifact path `<git_dir>/agentbox/runs/` →
|
|
16
|
+
`<git_dir>/agentcam/runs/`. All 25 files updated; 171 tests still pass.
|
|
17
|
+
- GitHub repo renamed `agent-run-flight-recorder` → `agentcam`.
|
|
18
|
+
Old URL auto-redirects via GitHub.
|
|
19
|
+
|
|
20
|
+
### Hardening (post-source-review fixes, 2026-05-16)
|
|
21
|
+
|
|
22
|
+
- **report.py**: `cf.rename_from` now passes through secret-like-filename
|
|
23
|
+
redaction; `git diff --check` output now passes through a new
|
|
24
|
+
`_redact_filenames_in_diff_check` helper; report `Logs` and
|
|
25
|
+
`Local Artifacts` sections show paths relative to git_root instead of
|
|
26
|
+
absolute (no longer leaks username + repo location).
|
|
27
|
+
- **redaction.py**: `StreamingRedactor` now keeps a 1024-char reserve on
|
|
28
|
+
force-flush so a token straddling the SOFT_FLUSH boundary can reassemble;
|
|
29
|
+
`feed()` strips NUL bytes after decode (catches UTF-16LE / NUL-interleaved
|
|
30
|
+
output); added `URL_BASIC_AUTH` pattern to redact `https://user:pass@host`;
|
|
31
|
+
all secret-like patterns now case-insensitive.
|
|
32
|
+
- **scanner.py**: secret-like basename patterns all case-insensitive
|
|
33
|
+
(catches `.ENV`, `ID_RSA`, `.NPMRC` on case-insensitive filesystems).
|
|
34
|
+
- **runner.py**: `proc.wait()` wrapped in try/except KeyboardInterrupt /
|
|
35
|
+
finally — Ctrl+C now escalates wait→terminate→kill and always joins tee
|
|
36
|
+
threads (so logs flush). New `_escape_for_cmd_shim` helper caret-escapes
|
|
37
|
+
`& | < > ^` and doubles `%` for the Windows `.cmd` / `.bat` shim path.
|
|
38
|
+
- **+21 regression tests** covering each fix.
|
|
39
|
+
- **External confirm-review**: Codex confirmed all 9 fixes OK with NO
|
|
40
|
+
BLOCKERS (direct `codex exec`, after three attempts via the
|
|
41
|
+
`codex-rescue` subagent forwarder hung in session deadlocks).
|
|
42
|
+
- **Cross-platform validation (partial)**: pytest now passes on Linux
|
|
43
|
+
(WSL Ubuntu, Python 3.12.3) too — 172/172 (POSIX signal test runs there).
|
|
44
|
+
Total coverage: Windows 171/172 + Linux 172/172. macOS still untested
|
|
45
|
+
(no local hardware; CI yaml covers it pending future GH push).
|
|
46
|
+
- **POSIX risks documented for v0.2** (Codex cross-platform risk
|
|
47
|
+
assessment): SIGINT process-group leak, non-UTF8 filename decoding,
|
|
48
|
+
POSIX exec permission. See ROADMAP v0.2 "POSIX hardening" entry and
|
|
49
|
+
`docs/design.md` caveat 3.
|
|
50
|
+
- **GitHub Actions matrix green (6/6 jobs)** on push to main:
|
|
51
|
+
Linux / macOS / Windows × Python 3.11 / 3.12 all pass.
|
|
52
|
+
Repo: https://github.com/shihchengwei-lab/agentcam (renamed from agent-run-flight-recorder on 2026-05-16)
|
|
53
|
+
|
|
54
|
+
## [0.1.0] — 2026-05-16
|
|
55
|
+
|
|
56
|
+
First release. The whole point of v0.1 is "wrap one agent run, produce a
|
|
57
|
+
report, do not lie about what we don't know."
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
|
|
61
|
+
- **`agentcam version`** — print version and exit
|
|
62
|
+
- **`agentcam run -- <argv...>`** — wrap an argv-style command, record
|
|
63
|
+
before/after git state, tee stdout/stderr, generate Markdown report
|
|
64
|
+
|
|
65
|
+
#### What gets recorded per run
|
|
66
|
+
|
|
67
|
+
- `stdout.log` / `stderr.log` — raw bytes from the subprocess, preserved
|
|
68
|
+
for forensic review
|
|
69
|
+
- `stdout.redacted.log` / `stderr.redacted.log` — secrets stripped
|
|
70
|
+
(best-effort) via streaming buffer (handles tokens cut at chunk
|
|
71
|
+
boundaries and multi-line PEM blocks)
|
|
72
|
+
- `manifest.json` — machine-readable run metadata
|
|
73
|
+
- `AGENT_RUN_REPORT.md` — human-readable report
|
|
74
|
+
|
|
75
|
+
All artifacts live under `<git_dir>/agentcam/runs/<run_id>/` so git itself
|
|
76
|
+
cannot stage them.
|
|
77
|
+
|
|
78
|
+
#### Risk heuristics in this release
|
|
79
|
+
|
|
80
|
+
- **HIGH**: tracked file deletions; sensitive path segments (`auth`,
|
|
81
|
+
`login`, `oauth`, `session`, `jwt`, `permission`, `migration`, `secret`,
|
|
82
|
+
`credential`, `terraform`, `kubernetes`, `helm`, etc.); sensitive
|
|
83
|
+
basenames / extensions (`.env`, `.env.*`, `*.pem`, `*.key`, `id_rsa*`,
|
|
84
|
+
`schema.prisma`, `fly.toml`, `vercel.json`, `.tf`, `.tfvars`); GitHub
|
|
85
|
+
Actions workflow paths; output-pattern hits like `git reset --hard`,
|
|
86
|
+
`rm -rf /`, `chmod 777`, `curl ... | sh`, PowerShell
|
|
87
|
+
`Remove-Item -Recurse -Force`, `Invoke-Expression`, conflict markers,
|
|
88
|
+
`git push --force`.
|
|
89
|
+
- **MEDIUM**: dependency manifest changes (`package.json`, `pyproject.toml`,
|
|
90
|
+
`Dockerfile`, etc.); output mentions of `tests failed`, `lint error`,
|
|
91
|
+
`build failed`, `panic`, `segmentation fault`.
|
|
92
|
+
- No LOW level — filename-only heuristics for "trivial" changes are
|
|
93
|
+
unreliable.
|
|
94
|
+
|
|
95
|
+
#### Redaction
|
|
96
|
+
|
|
97
|
+
- Streaming redactor handles tokens split across read chunks and PEM
|
|
98
|
+
blocks split across multiple lines (PKCS#8 / RSA / EC / ED25519 /
|
|
99
|
+
ENCRYPTED / OPENSSH).
|
|
100
|
+
- Secret-like filenames (`.env`, `*.pem`, `id_rsa`, `*credential*`,
|
|
101
|
+
`*secret*`) are redacted in every Markdown surface (Changed Files, Risk
|
|
102
|
+
Flags evidence, Diff Stat, Rollback Notes, Command field).
|
|
103
|
+
- Argv redaction also runs on each argv element (catches
|
|
104
|
+
`--api-key sk-...` and `--config .env.production`).
|
|
105
|
+
|
|
106
|
+
#### Exit code
|
|
107
|
+
|
|
108
|
+
- Wrapper exits `0` iff subprocess returncode is `0`, `1` otherwise.
|
|
109
|
+
- Original returncode, platform, and a human interpretation (POSIX signal
|
|
110
|
+
name; common Windows NTSTATUS like `STATUS_ACCESS_VIOLATION`) all go to
|
|
111
|
+
`manifest.exit_detail` and the `Exit Code Detail` report section.
|
|
112
|
+
- Run-id collision (same millisecond, same slug, all hex retries
|
|
113
|
+
exhausted) exits with `2` — distinct from "subprocess failed" `1`.
|
|
114
|
+
|
|
115
|
+
### Tests
|
|
116
|
+
|
|
117
|
+
- 159 unit + e2e tests across 8 test modules
|
|
118
|
+
- Cross-platform: passes on Windows (POSIX-only signal test skipped)
|
|
119
|
+
- e2e suite uses real subprocesses + real git repos via
|
|
120
|
+
`tmp_git_repo` fixture
|
|
121
|
+
- Regression guards for every blocker found during two rounds of Codex
|
|
122
|
+
adversarial review (PEM cross-chunk, exit-code 256-not-zero, segment vs.
|
|
123
|
+
substring matching, staged-only diff visible, output evidence does not
|
|
124
|
+
echo raw matched text, etc.)
|
|
125
|
+
|
|
126
|
+
### Documentation
|
|
127
|
+
|
|
128
|
+
- `README.md` — quick start, install, threat model, known limitations,
|
|
129
|
+
hacking
|
|
130
|
+
- `docs/design.md` — 22 decisions in "decision / why / why not" format
|
|
131
|
+
- `examples/risky-auth-change/` — one committed sample report and scenario
|
|
132
|
+
description
|
|
133
|
+
- `SECURITY.md` — vulnerability disclosure policy, scope, threat model
|
|
134
|
+
|
|
135
|
+
### Known limitations (v0.1)
|
|
136
|
+
|
|
137
|
+
- Not a sandbox; not a pre-execution gate; not a compliance product.
|
|
138
|
+
- Best-effort redaction; new secret formats may slip through.
|
|
139
|
+
- No interactive TUI rendering guarantee.
|
|
140
|
+
- No submodule / sparse-checkout special handling.
|
|
141
|
+
- Windows console encoding fallback may degrade live terminal display
|
|
142
|
+
(raw log on disk is unaffected).
|
|
143
|
+
- `Tests / Build / Lint observed` always reports `unknown` — heuristic
|
|
144
|
+
detection deferred to a future release.
|
|
145
|
+
|
|
146
|
+
### Out of scope (deliberately, see `docs/design.md` "Out-of-scope reminders")
|
|
147
|
+
|
|
148
|
+
- Sandbox / process isolation
|
|
149
|
+
- Pre-execution blocking / approval gating
|
|
150
|
+
- Auto-rollback / `git clean -fd` suggestions
|
|
151
|
+
- Cloud upload / telemetry of any kind
|
|
152
|
+
- VS Code / IDE integration
|
|
153
|
+
- GitHub App / GitHub Action (deferred to v0.2 if v0.1 finds users)
|
|
154
|
+
- Custom YAML risk rules
|
|
155
|
+
- Multi-run dashboard
|
|
156
|
+
- Hosted SaaS dashboard
|
agentcam-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 shihchengwei
|
|
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.
|
agentcam-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentcam
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local-first CLI wrapper that records what your AI coding agent changed in your repo.
|
|
5
|
+
Author-email: shihchengwei <shihchengwei@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: claude-code,codex,coding-agent,flight-recorder,observability
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: pytest-timeout>=2.2; extra == 'dev'
|
|
20
|
+
Requires-Dist: pytest>=7.4; extra == 'dev'
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# agentcam
|
|
24
|
+
|
|
25
|
+
[](https://github.com/shihchengwei-lab/agentcam/actions/workflows/ci.yml)
|
|
26
|
+
|
|
27
|
+
> Local-first CLI wrapper that records what your AI coding agent changed in your repo and generates a Markdown run report after each run.
|
|
28
|
+
|
|
29
|
+
agentcam does **not** replace Claude Code, Codex, OpenHands, Aider, or any
|
|
30
|
+
other coding agent. It wraps them.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
agentcam run -- claude "fix the failing tests"
|
|
34
|
+
agentcam run -- codex "add input validation to login form"
|
|
35
|
+
agentcam run -- bash -lc "npm run build && npm test"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
After each run, you get an `AGENT_RUN_REPORT.md` answering three questions:
|
|
39
|
+
|
|
40
|
+
1. **What did the agent change?** — exact file list, diff stat, staged vs.
|
|
41
|
+
unstaged vs. untracked, before/after HEAD.
|
|
42
|
+
2. **Where should I look first?** — heuristic risk flags for auth paths,
|
|
43
|
+
secrets, deletions, dangerous shell strings (`rm -rf /`, `git reset
|
|
44
|
+
--hard`, conflict markers), dependency manifests.
|
|
45
|
+
3. **How do I roll back if something's wrong?** — situation-aware rollback
|
|
46
|
+
notes (no blanket `git reset --hard` suggestions).
|
|
47
|
+
|
|
48
|
+
See [`examples/risky-auth-change/expected-report.md`](examples/risky-auth-change/expected-report.md)
|
|
49
|
+
for what a report looks like when the agent touches a sensitive area.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## What this is NOT
|
|
54
|
+
|
|
55
|
+
This is a **flight recorder**, not a governance platform.
|
|
56
|
+
|
|
57
|
+
- Not a sandbox.
|
|
58
|
+
- Not a pre-execution gate. agentcam does not block dangerous commands; it
|
|
59
|
+
records that they happened and flags them for review *after*.
|
|
60
|
+
- Not a security scanner. The risk flags are heuristics ("look here"), not
|
|
61
|
+
verdicts ("this is bad").
|
|
62
|
+
- Not an audit / compliance tool. The Markdown report is for the developer
|
|
63
|
+
reviewing the diff, not for a SOC2 evidence pipeline.
|
|
64
|
+
- Not a SaaS. There is no account, no upload, no telemetry. Everything
|
|
65
|
+
stays under `.git/agentcam/runs/` on your machine.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Install
|
|
70
|
+
|
|
71
|
+
agentcam needs Python ≥ 3.11 and `git`.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pipx install agentcam
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
(Once published to PyPI. For now, install from source — see "Hacking"
|
|
78
|
+
below.)
|
|
79
|
+
|
|
80
|
+
Verify:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
agentcam version
|
|
84
|
+
# agentcam 0.1.0
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Quick start
|
|
90
|
+
|
|
91
|
+
Inside any git repository:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
agentcam run -- bash -lc "echo hello > demo.txt"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
agentcam will:
|
|
98
|
+
|
|
99
|
+
1. snapshot git state (HEAD, branch, staged / unstaged / untracked)
|
|
100
|
+
2. run your command, tee-ing stdout and stderr to logs (raw + redacted)
|
|
101
|
+
3. snapshot git state again
|
|
102
|
+
4. scan for risk flags (path patterns, output patterns, deletions)
|
|
103
|
+
5. write `AGENT_RUN_REPORT.md` and `manifest.json` under
|
|
104
|
+
`.git/agentcam/runs/<run_id>/`
|
|
105
|
+
6. exit with 0 if your command succeeded, 1 otherwise
|
|
106
|
+
|
|
107
|
+
stdout and stderr stream live to your terminal — agentcam does not buffer
|
|
108
|
+
them.
|
|
109
|
+
|
|
110
|
+
### Wrapping Claude Code
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
agentcam run --name claude-fix-tests -- claude "fix the failing tests"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Wrapping Codex
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
agentcam run --name codex-add-validation -- codex "add input validation to login form"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Wrapping anything (with shell features)
|
|
123
|
+
|
|
124
|
+
agentcam runs the command with `shell=False`. If you need pipes, redirects,
|
|
125
|
+
variable expansion, wrap your own shell explicitly:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
agentcam run -- bash -lc "npm run build 2>&1 | tee build.log"
|
|
129
|
+
agentcam run -- pwsh -Command "Get-Process | Out-File procs.txt"
|
|
130
|
+
agentcam run -- cmd /c "dir > files.txt"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
This is a deliberate constraint — see [`docs/design.md` § 4](docs/design.md).
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Where the artifacts live
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
.git/
|
|
141
|
+
└── agentcam/
|
|
142
|
+
└── runs/
|
|
143
|
+
└── 20260516-143000-451-claude-rate-limit-login/
|
|
144
|
+
├── AGENT_RUN_REPORT.md # human-readable, share-friendly
|
|
145
|
+
├── manifest.json # machine-readable
|
|
146
|
+
├── stdout.log # raw stdout (KEEP PRIVATE)
|
|
147
|
+
├── stderr.log # raw stderr (KEEP PRIVATE)
|
|
148
|
+
├── stdout.redacted.log # secrets stripped (best-effort)
|
|
149
|
+
└── stderr.redacted.log
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Output lives under `.git/` on purpose — git doesn't track its own
|
|
153
|
+
internals, so agent invocations of `git add .` cannot stage agentcam's
|
|
154
|
+
output by accident.
|
|
155
|
+
|
|
156
|
+
> **Warning about raw logs.** Raw logs preserve the original stdout /
|
|
157
|
+
> stderr for forensic review. They will *not* be picked up by `git push`,
|
|
158
|
+
> but they *will* travel with `.git/` if you:
|
|
159
|
+
>
|
|
160
|
+
> - sync your repo via OneDrive / Dropbox / iCloud Drive
|
|
161
|
+
> - back up your machine (Time Machine, Windows File History)
|
|
162
|
+
> - zip the entire repo to share with someone
|
|
163
|
+
>
|
|
164
|
+
> The `AGENT_RUN_REPORT.md` only links to the redacted logs.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Risk flags (heuristics)
|
|
169
|
+
|
|
170
|
+
Two levels: **HIGH** and **MEDIUM**. There is no LOW — filename-only
|
|
171
|
+
heuristics for "trivial" changes are unreliable, and we don't pretend.
|
|
172
|
+
|
|
173
|
+
**HIGH** — flagged for any of:
|
|
174
|
+
|
|
175
|
+
- A tracked file was deleted.
|
|
176
|
+
- File path contains a sensitive segment: `auth`, `login`, `oauth`,
|
|
177
|
+
`session`, `jwt`, `permission`, `middleware`, `migration`, `secret`,
|
|
178
|
+
`credential`, `terraform`, `kubernetes`, `helm`, etc.
|
|
179
|
+
- Sensitive basename / extension: `.env`, `.env.*`, `*.pem`, `*.key`,
|
|
180
|
+
`id_rsa*`, `schema.prisma`, `fly.toml`, `vercel.json`, `.tf`, `.tfvars`,
|
|
181
|
+
GitHub Actions workflows.
|
|
182
|
+
- stdout / stderr contains a high-risk command pattern:
|
|
183
|
+
`git reset --hard`, `rm -rf /...`, `chmod 777`, `curl ... | sh`,
|
|
184
|
+
PowerShell `Remove-Item -Recurse -Force ...`, `Invoke-Expression`,
|
|
185
|
+
conflict markers, `git push --force`.
|
|
186
|
+
|
|
187
|
+
**MEDIUM** — flagged for any of:
|
|
188
|
+
|
|
189
|
+
- Dependency manifest changed: `package.json`, `pyproject.toml`,
|
|
190
|
+
`requirements.txt`, `Dockerfile`, `docker-compose.*`, etc.
|
|
191
|
+
- stdout / stderr mentions `tests failed`, `lint error`, `build failed`,
|
|
192
|
+
`panic`, `segmentation fault`.
|
|
193
|
+
|
|
194
|
+
**Path matching is segment-based.** Segment `auth` matches
|
|
195
|
+
`src/auth/login.py` and `auth.ts`, but does NOT match `author.md` or
|
|
196
|
+
`authorization-docs/x.md`. See [`docs/design.md` § 7](docs/design.md).
|
|
197
|
+
|
|
198
|
+
**Evidence never includes raw matched text.** Risk Flags cite the pattern
|
|
199
|
+
name and a line number (`stdout.log line 42`), never the matched
|
|
200
|
+
substring. Secrets that happen to land near a risk pattern in output do
|
|
201
|
+
not leak through the report.
|
|
202
|
+
|
|
203
|
+
For the full rule list and rationale, see
|
|
204
|
+
[`docs/design.md` § 7, § 12, § 15](docs/design.md).
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Secret redaction (best-effort)
|
|
209
|
+
|
|
210
|
+
Patterns redacted in the redacted log:
|
|
211
|
+
|
|
212
|
+
- AWS access / secret keys (`AKIA…`, `aws_secret_access_key=…`)
|
|
213
|
+
- GitHub PAT (`ghp_…`, `gho_…`, etc.)
|
|
214
|
+
- OpenAI / Anthropic-shaped API keys (`sk-…`)
|
|
215
|
+
- Slack tokens (`xoxa-…`, `xoxb-…`, etc.)
|
|
216
|
+
- npm / GitLab tokens (`npm_…`, `glpat-…`)
|
|
217
|
+
- JWT (`eyJ…`)
|
|
218
|
+
- `Bearer …` headers
|
|
219
|
+
- env-style assignments where the key name looks like a secret
|
|
220
|
+
(`OPENAI_API_KEY=…`, `*_TOKEN=…`, `*_PASSWORD=…`, `*_CREDENTIAL=…`)
|
|
221
|
+
- PEM private key blocks — multi-line, including PKCS#8 / RSA / EC /
|
|
222
|
+
ED25519 / OPENSSH
|
|
223
|
+
|
|
224
|
+
We **do not** promise to catch every secret. New token formats appear all
|
|
225
|
+
the time. The raw log on disk is the forensic backstop: if redaction
|
|
226
|
+
missed something, you can find it there.
|
|
227
|
+
|
|
228
|
+
`Command:` field, `Changed Files`, `Diff Stat`, and `Risk Flags evidence`
|
|
229
|
+
in the markdown report also pass through redaction — a literal
|
|
230
|
+
`.env.production` in argv or in a diff stat shows up as
|
|
231
|
+
`<redacted-secret-filename>`.
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Local-only, no telemetry
|
|
236
|
+
|
|
237
|
+
agentcam makes no network calls. It does not phone home. There is no
|
|
238
|
+
account, no upload, no opt-in or opt-out toggle for telemetry — because
|
|
239
|
+
there is no telemetry to toggle.
|
|
240
|
+
|
|
241
|
+
If you ever observe an outbound connection from agentcam, that's a bug;
|
|
242
|
+
please file an issue.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Known limitations
|
|
247
|
+
|
|
248
|
+
- **Not a sandbox.** agentcam does not isolate the wrapped command from
|
|
249
|
+
your filesystem, network, or credentials.
|
|
250
|
+
- **Does not block.** High-risk patterns are recorded *after* they happen;
|
|
251
|
+
agentcam does not approve or deny commands.
|
|
252
|
+
- **Does not see inside the agent.** agentcam observes only what reaches
|
|
253
|
+
stdout / stderr and what changes in the git working tree. The agent's
|
|
254
|
+
internal tool calls (file reads, web requests, model calls) are
|
|
255
|
+
invisible.
|
|
256
|
+
- **Best-effort redaction.** New secret formats may slip through. Do not
|
|
257
|
+
rely on agentcam alone for credential hygiene.
|
|
258
|
+
- **No interactive TUI guarantee.** Agents that draw full-screen TUIs
|
|
259
|
+
(curses-style) may render imperfectly through the wrapper. Their
|
|
260
|
+
side-effects on the repo are still recorded correctly.
|
|
261
|
+
- **No submodule traversal.** Running inside a submodule treats it as an
|
|
262
|
+
independent repo. Superproject context is not analyzed.
|
|
263
|
+
- **No sparse-checkout special handling.** Reports reflect what
|
|
264
|
+
`git status --porcelain=v1 -z` shows.
|
|
265
|
+
- **Windows console encoding can degrade live terminal display.** Raw
|
|
266
|
+
bytes are always preserved on disk; only the live forwarding to the
|
|
267
|
+
terminal may fall back to UTF-8 lossy decode (recorded as
|
|
268
|
+
`terminal_forward_degraded` in the manifest).
|
|
269
|
+
|
|
270
|
+
For the full list of "things we deliberately did NOT do," see the
|
|
271
|
+
"Out-of-scope reminders" at the bottom of [`docs/design.md`](docs/design.md).
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Hacking
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
git clone <this repo>
|
|
279
|
+
cd flight_recorder
|
|
280
|
+
python -m venv .venv
|
|
281
|
+
|
|
282
|
+
# Windows (Git Bash / PowerShell)
|
|
283
|
+
.venv/Scripts/python -m pip install -e ".[dev]"
|
|
284
|
+
.venv/Scripts/python -m pytest
|
|
285
|
+
|
|
286
|
+
# macOS / Linux
|
|
287
|
+
.venv/bin/python -m pip install -e ".[dev]"
|
|
288
|
+
.venv/bin/python -m pytest
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
The codebase is intentionally small (one source module per concern):
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
src/agentcam/
|
|
295
|
+
├── cli.py # argparse + orchestrator
|
|
296
|
+
├── runner.py # threads-based tee + exit code interpretation
|
|
297
|
+
├── git_state.py # porcelain parser + git_dir resolver
|
|
298
|
+
├── paths.py # run_id + collision-safe directory creation
|
|
299
|
+
├── redaction.py # streaming secret redactor
|
|
300
|
+
├── scanner.py # path + output risk patterns
|
|
301
|
+
├── report.py # AGENT_RUN_REPORT.md generator
|
|
302
|
+
└── models.py # dataclass definitions
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Read [`docs/design.md`](docs/design.md) before changing anything — it
|
|
306
|
+
records why each module is shaped the way it is, including the "we
|
|
307
|
+
considered X and rejected it because Y" cases.
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## License
|
|
312
|
+
|
|
313
|
+
MIT. See [`LICENSE`](LICENSE).
|