Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9b0c62f
docs(fleet): freeze adversarial review c6c486 (Phase 0)
cursoragent Jul 8, 2026
720672f
fix(security): remove eval from install-community (SEC-001)
cursoragent Jul 8, 2026
dbbcc3a
fix(security): unshare network in Linux reviewer bwrap sandbox (SEC-003)
cursoragent Jul 8, 2026
de75eb1
fix(security): validate reviewer run-id before sandbox mounts (SEC-002)
cursoragent Jul 8, 2026
f8c62e1
merge: cursor/sec-001-eval-injection-256a into adversarial-review BAS…
cursoragent Jul 8, 2026
0750e53
merge: cursor/sec-002-runid-escape-256a into adversarial-review BASE …
cursoragent Jul 8, 2026
0792e5c
merge: cursor/sec-003-bwrap-net-256a into adversarial-review BASE (c6…
cursoragent Jul 8, 2026
e53b8aa
chore(fleet): mark wave1 SEC findings CLOSED in ledger (c6c486)
cursoragent Jul 8, 2026
0e1cf16
docs(security): sync SECURITY.md classifier examples with sandbox gua…
cursoragent Jul 8, 2026
380980b
fix(namespace): pin run_id regex to fleet_run.RUN_ID_PATTERN (BUG-003)
cursoragent Jul 8, 2026
94e8096
fix(campaign): refuse archived missions and surface readiness parse e…
cursoragent Jul 8, 2026
0c95244
fix(archive): enforce created_utc precedes file mtimes (BUG-001)
cursoragent Jul 8, 2026
f4de467
fix(verify): add sha-pin and reviewer-sandbox layers to fleet-verify …
cursoragent Jul 8, 2026
b776526
merge: cursor/sec-007-security-md-256a into adversarial-review BASE (…
cursoragent Jul 8, 2026
5bce8f3
merge: cursor/bug-003-namespace-regex-256a into adversarial-review BA…
cursoragent Jul 8, 2026
2af3be0
merge: cursor/arch-002-campaign-gate-256a into adversarial-review BAS…
cursoragent Jul 8, 2026
f7e85bd
merge: cursor/bug-001-created-utc-256a into adversarial-review BASE (…
cursoragent Jul 8, 2026
253e2f0
merge: cursor/arch-001-fleet-verify-256a into adversarial-review BASE…
cursoragent Jul 8, 2026
1d1deba
chore(fleet): mark wave2 findings CLOSED in ledger (c6c486)
cursoragent Jul 8, 2026
53c25f2
fix(verify): cap findings JSON load size (SEC-011)
cursoragent Jul 8, 2026
4f70a90
fix(preflight): timeout hung adapter auth checks (OPS-002)
cursoragent Jul 8, 2026
e384b95
fix(promotion): honor FLEET_LEDGER_DIR in mission_promotion (ARCH-003)
cursoragent Jul 8, 2026
01514b3
fix(recovery): increment resume count on table-format ledger rows (BU…
cursoragent Jul 8, 2026
01eb912
fix(headless): fail real runs when archive emit fails (OPS-001)
cursoragent Jul 8, 2026
14ac0c6
merge: cursor/bug-004-resume-table-256a into adversarial-review BASE …
cursoragent Jul 8, 2026
0db38b1
merge: cursor/arch-003-ledger-dir-256a into adversarial-review BASE (…
cursoragent Jul 8, 2026
1b01047
merge: cursor/ops-001-archive-emit-256a into adversarial-review BASE …
cursoragent Jul 8, 2026
1eb4dd6
merge: cursor/ops-002-preflight-timeout-256a into adversarial-review …
cursoragent Jul 8, 2026
6ed03ff
merge: cursor/sec-011-findings-cap-256a into adversarial-review BASE …
cursoragent Jul 8, 2026
ca8ffe3
chore(fleet): mark wave3 Lane A findings CLOSED in ledger (c6c486)
cursoragent Jul 8, 2026
9b2d6ed
docs(fleet): T-FINAL readiness for adversarial-review c6c486
cursoragent Jul 8, 2026
836292d
test(install-community): align dry-run assertions with argv display
cursoragent Jul 8, 2026
b22a692
test(install-community): drop redundant eval substring check from dry…
cursoragent Jul 8, 2026
223a410
chore(fleet): mark adversarial-review c6c486 VERIFY/DONE in ledger
cursoragent Jul 8, 2026
1254846
fix(ci): bump autonomous-fleet-core to 1.3.1 and refresh skills-lock
cursoragent Jul 8, 2026
77cccd9
fix(ci): sync substrate-manifest core_version to 1.3.1
cursoragent Jul 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .fleet/docs/DECISIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# DECISIONS — adversarial-review-and-fix c6c486

## Self-orientation

| Field | Value |
|-------|-------|
| repo | `ravidsrk/autonomous-fleet` |
| REPO_ROOT | `/workspace` |
| MAINTAINER | Cursor Agent `<cursoragent@cursor.com>` |
| BRANCH_PREFIX | `cursor/` |
| BASE | `cursor/adversarial-review-base-256a` off `main`@e9e541b |
| Adapter | `autonomous-fleet-adapter-grok` (same-vendor-instructed review) |
| LEDGER_DIR | `.fleet/docs/` (docs-site Starlight probe) |
| RUN_ID | `20260708T184204Z-adversarial-review-and-fix-c6c486` |
| RUN_SHORT | `c6c486` |
| SUBSTRATE | `/workspace/scripts` |
| AUTHORSHIP_MODE | `attributed` |
| reviewer_mode | `same-vendor-instructed` |

## ASSUMPTIONS

1. Scope = entire autonomous-fleet app (skills, scripts, substrate, CI, action, docs-site tooling).
2. Fresh-run: ignore prior review docs; write `docs/adversarial-review-fresh.md`.
3. Out of scope: BASE→main promotion, production deploy, secret rotation, load/prod verification.
4. SCM: `gh` authenticated as `cursor`; PRs merge into BASE with `--merge` (never squash).
5. Lane B findings open as draft `do-not-merge` PRs; never auto-merge.

## Skeptic decisions

- SEC-006 DO_NOT_FIX (version-tolerant auth probe).
- SEC-005/009/004/010/ARCH-004/ARCH-005 → Lane B (ask / human-gate or draft-both).
- OPS-001 narrowed: fatal only on real-run archive emit; dry-run cleanup stays non-fatal.
- Wave 1 Lane A: SEC-001, SEC-002, SEC-003, ARCH-001, ARCH-002, BUG-001 (FOUNDATION first).

## Lane B human gates (c6c486) — draft-both, do not auto-merge

Each finding below has two variants. Operator picks one; neither is auto-merged.

### SEC-004 — SHA-pin GitHub Actions
- **A:** Pin every `uses:` in `action.yml` + workflows to full commit SHAs; Dependabot for bumps.
- **B:** Vendor critical Actions locally (`uses: ./…`) for the composite entrypoint only.
- **Status:** HUMAN_GATED — policy/maintenance choice.

### SEC-005 — Reviewer fallback without real sandbox
- **A:** Refuse `--role reviewer` when neither sandbox-exec nor bwrap is present (unless `FLEET_SECURITY_OVERRIDE_ACK=1`).
- **B:** Keep fallback but emit `SECURITY=DEGRADED` in manifest and fail fleet-verify on that flag.
- **Status:** HUMAN_GATED — skeptic narrowed to low; documented degraded mode.

### SEC-009 — Registry-lint kill switch vs supply-chain pins
- **A:** Require `FLEET_SECURITY_OVERRIDE_ACK` for `FLEET_DISABLE_REGISTRY_LINT` (match sha-pin).
- **B:** Split lint: doc-drift remains disableable; pin/hash checks fail-closed.
- **Status:** HUMAN_GATED — intentional escape hatch today.

### ARCH-004 — Unregistered exploratory SKILL trees
- **A:** Add `MISSIONS` rows for scaffold-align / contract-first-build / agents-layer + lint on-disk ⊆ registry.
- **B:** Remove the three SKILL trees until promotion-ready.
- **Status:** HUMAN_GATED — handoff campaign currently archived/empty.

### ARCH-005 — Archive collector filter mismatch
- **A:** Unify both CLIs on `RUN_ID_PATTERN` via shared `collect_run_archives()`.
- **B:** Keep loose namespacing scan; WARN on non-canonical basenames.
- **Status:** HUMAN_GATED — gate inconsistency, lower blast radius.

### SEC-010 — Stop-verify fail-open on missing repo
- **A:** Opt-in `FLEET_STOP_VERIFY_STRICT=1` → BLOCK when repo missing.
- **B:** Always BLOCK on bad repo (breaking for path drift).
- **Status:** HUMAN_GATED — default allow is intentional operator escape.

### SEC-006 — DO_NOT_FIX (confirmed by skeptic)
Version-tolerant auth probe + timeout watchdog; fail-closed would break validated compatibility.

86 changes: 86 additions & 0 deletions .fleet/docs/arch-build-progress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# arch-build-progress — adversarial-review-and-fix

RUN_ID: 20260708T184204Z-adversarial-review-and-fix-c6c486
RUN_SHORT: c6c486
BASE: cursor/adversarial-review-base-256a
PHASE: VERIFY
LAST_UPDATE: wave1 SEC-001/002/003/008 merged into BASE
ADAPTER: autonomous-fleet-adapter-grok
REPO_ROOT: /workspace
MAINTAINER: Cursor Agent <cursoragent@cursor.com>
BRANCH_PREFIX: cursor/
AUTHORSHIP_MODE: attributed
SUBSTRATE: /workspace/scripts
LEDGER_DIR: .fleet/docs
reviewer_mode: same-vendor-instructed

## Runtime goal

Mission adversarial-review-and-fix DONE: `.fleet/docs/arch-build-progress.md` all task flags true,
`.fleet/docs/arch-build-readiness.md` with fleet-outcome.status done and mission metrics satisfied,
the readiness fleet-outcome validates, all PRs merged into BASE.

LAST_UPDATE: BOOTSTRAP complete — 15 Lane A + 6 Lane B; SEC-006 DO_NOT_FIX

## CLOSE-INDEX

| ID | lane | state |
|----|------|-------|
| SEC-001 | A | CLOSED via #135 |
| SEC-002 | A | CLOSED via #136 |
| SEC-003 | A | CLOSED via #137 |
| SEC-004 | B | HUMAN_GATED (see DECISIONS.md) |
| ARCH-001 | A | CLOSED via #138 |
| ARCH-002 | A | CLOSED via #139 |
| BUG-001 | A | CLOSED via #140 |
| SEC-005 | B | HUMAN_GATED (see DECISIONS.md) |
| SEC-007 | A | CLOSED via #141 |
| SEC-008 | A | CLOSED via #135 |
| SEC-009 | B | HUMAN_GATED (see DECISIONS.md) |
| BUG-002 | A | CLOSED via #139 |
| BUG-003 | A | CLOSED via #142 |
| BUG-004 | A | CLOSED via #143 |
| ARCH-003 | A | CLOSED via #144 |
| ARCH-004 | B | HUMAN_GATED (see DECISIONS.md) |
| OPS-001 | A | CLOSED via #145 |
| OPS-002 | A | CLOSED via #146 |
| ARCH-005 | B | HUMAN_GATED (see DECISIONS.md) |
| SEC-010 | B | HUMAN_GATED (see DECISIONS.md) |
| SEC-011 | A | CLOSED via #147 |
| SEC-006 | — | DO_NOT_FIX |

## Fix tasks

| TASK | finding | wave | flags |
|------|---------|------|-------|
| TASK SEC-001 | SEC-001 | 1 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK SEC-002 | SEC-002 | 1 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK SEC-003 | SEC-003 | 1 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK ARCH-001 | ARCH-001 | 1 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK ARCH-002 | ARCH-002 | 1 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK BUG-001 | BUG-001 | 1 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK SEC-007 | SEC-007 | 2 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK SEC-008 | SEC-008 | 2 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK BUG-002 | BUG-002 | 2 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK BUG-003 | BUG-003 | 2 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK BUG-004 | BUG-004 | 2 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK ARCH-003 | ARCH-003 | 2 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK OPS-001 | OPS-001 | 2 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK OPS-002 | OPS-002 | 2 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |
| TASK SEC-011 | SEC-011 | 2 | CODED=t EVID=t PR_OPEN=t REVIEWED=t MERGED=t ACCEPT=t WT_CLEAN=t |

## Lane B (HUMAN_GATED — draft do-not-merge)

SEC-004, SEC-005, SEC-009, ARCH-004, ARCH-005, SEC-010

## OPS / VERIFY-AT-SCALE

(none yet)

## CONTEXT HANDOFF

Wave 1 in flight next. Hot files: install-community.sh, run-sandboxed.sh, fleet_verify.py, run-campaign.sh, fleet_run.py.

## DONE

Lane A CLOSED; Lane B HUMAN_GATED; readiness + archive validated; BASE pushed.
82 changes: 82 additions & 0 deletions .fleet/docs/arch-build-readiness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
fleet-outcome:
schema_version: "1.0"
mission: adversarial-review-and-fix
status: done
repo: ravidsrk/autonomous-fleet
base_branch: cursor/adversarial-review-base-256a
prs_merged: 13
run_id: 20260708T184204Z-adversarial-review-and-fix-c6c486
archive_enabled: true
reviewer_mode: same-vendor-instructed
e2e_verified: true
metrics:
p0_open: 0
p1_open: 0
findings_open: 0
ops_queue_count: 0
verified_findings: 21
unverified_findings: 0
auto_applicable_findings: 15
human_gated_findings: 6
deferred_missions:
- doc-sync
---

# Arch-build readiness — adversarial-review-and-fix (c6c486)

Generated: 2026-07-08T19:19:41Z

## Summary

Code-grounded adversarial review of the entire autonomous-fleet app (scripts, substrate, CI, campaign orchestration, security surfaces). Phase 0 froze 21 confirmed findings (1 DO_NOT_FIX). Phase 1 closed all 15 Lane A findings via merge-commits into BASE `cursor/adversarial-review-base-256a`. Six Lane B findings are HUMAN_GATED with draft-both variants in `.fleet/docs/DECISIONS.md`.

## Finding status

### CLOSED (Lane A) — merged into BASE

| ID | PR | Notes |
|----|-----|-------|
| SEC-001 | #135 | eval removed; HOST allowlist; argv exec |
| SEC-008 | #135 | skills@1.5.12 pin (same PR) |
| SEC-002 | #136 | run_id validation + containment |
| SEC-003 | #137 | bwrap --unshare-net |
| SEC-007 | #138 | SECURITY.md classifier sync |
| BUG-003 | #139 | namespace regex = RUN_ID_PATTERN |
| ARCH-001 | #140 | fleet-verify sha-pin + reviewer-sandbox layers |
| BUG-001 | #141 | created_utc precedes file mtimes |
| ARCH-002 | #142 | archived mission exec gate |
| BUG-002 | #142 | remove \|\| true on blocked parse |
| BUG-004 | #143 | table-row resume increment |
| ARCH-003 | #144 | FLEET_LEDGER_DIR in promotion |
| OPS-001 | #145 | fatal real-run archive emit |
| OPS-002 | #146 | adapter auth timeout |
| SEC-011 | #147 | findings JSON byte cap |

### HUMAN_GATED (Lane B)

SEC-004, SEC-005, SEC-009, ARCH-004, ARCH-005, SEC-010 — see `.fleet/docs/DECISIONS.md`.

### DO_NOT_FIX

SEC-006 — intentional version-tolerant auth probe + timeout.

## OPS queue

None. Lane B items are human policy choices, not out-of-band ops.

## Recommended next missions

1. **doc-sync** — SECURITY.md already patched; remaining docs may drift after this wave.
2. Human review of Lane B variants (especially SEC-004 Action SHA pins and SEC-005 sandbox fail-closed).

## PRs

- Integration BASE: https://github.com/ravidsrk/autonomous-fleet/pull/134
- Fix PRs: #135–#147 (merged into BASE locally; GitHub merge may require human if token lacks merge)

## Validation notes

- Substrate: `scripts/sync_substrate_assets.py` re-run after merges.
- Reviewer mode: `same-vendor-instructed` (Grok/Cursor single-vendor host).
- `gh` GraphQL create/merge unavailable for integration token; PRs opened via ManagePullRequest; merges performed as local merge-commits into BASE then pushed.
29 changes: 18 additions & 11 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,13 @@ outward-facing actions before exec:

```
DENY (exit 2) force-push, remote-branch delete, rm -rf of a critical/system path,
git reset --hard to a remote ref, gh pr merge, gh repo delete
git reset --hard to a remote ref, gh pr merge, gh repo delete,
shred, dd of=/dev/*, chmod|chown|chgrp -R of an absolute system path,
find <abs-system-path> with -delete / -exec / -ok
ASK (exit 3) ordinary git push, gh release, rm -rf of a scoped path,
terraform|tofu|kubectl|helm|databricks apply|deploy|destroy|delete
terraform|tofu|kubectl|helm|databricks apply|deploy|destroy|delete,
npm|pnpm|yarn|cargo publish, aws|gcloud destructive verbs,
curl|wget piped into a shell
ALLOW everything else (reads, tests, edits, local git, and — by default —
any command the wrapper does not specifically inspect; see below)
```
Expand Down Expand Up @@ -103,15 +107,18 @@ Concretely, the framework does not protect you from:
every defense above is something you chose to wave through.
- Most destructive commands. The classifier is not an allowlist of safe commands — it is a small
best-effort blocklist of the most common destructive ones, and **everything it does not specifically
recognize is ALLOW by default**. Today the wrapper inspects only `rm`, `git push`/`git reset`, `gh`,
and a handful of infra tools (`terraform`/`tofu`/`kubectl`/`helm`/`databricks`). Plainly-written
destructive commands outside that set pass straight through — for example `curl … | bash`,
`find / -delete`, `dd of=/dev/sda`, and `chmod -R 000 /` all classify as ALLOW today. (Work is
underway to add several of these to the blocklist, but that does not change the shape: it is a
best-effort blocklist of common destructive commands, **NOT** a security boundary. Rely on OS-level
sandboxing — `container-use`, a VM, or a restricted account — for the boundary.) And even within the
set it inspects, it is a static heuristic over tokens: a command constructed at shell runtime
(command substitution, `eval` of a built string, base64 payloads) can evade it.
recognize is ALLOW by default**. Today the wrapper inspects `rm`, `git push`/`git reset`, `gh`,
infra tools (`terraform`/`tofu`/`kubectl`/`helm`/`databricks`), plus the catastrophic / outward
heads covered by the DENY/ASK matrix above (`shred`, `dd` to a device, recursive
`chmod`/`chown`/`chgrp` on a system path, `find` with `-delete`/`-exec` on a system path,
package `publish`, `aws`/`gcloud` destructive verbs, and `curl`/`wget` piped into a shell). Those
plainly-written forms classify DENY or ASK (and are refused) — they are **not** residual ALLOW
examples. What still slips through is everything outside that inspected set, plus constructions
the static token heuristic cannot see: runtime command substitution (`$(...)` / backticks),
`eval` of a built string, base64-decoded payloads, and unknown or renamed binaries the wrapper
does not specifically inspect — those still classify as ALLOW today. The shape does not change:
it is a best-effort blocklist of common destructive commands, **NOT** a security boundary. Rely
on OS-level sandboxing — `container-use`, a VM, or a restricted account — for the boundary.
- A compromised upstream agent CLI. The fleet drives Claude Code, Codex, Grok, and Orca. If one of
those binaries is backdoored, it runs with your privileges and the wrapper cannot see inside it.
- Supply-chain attacks on `npm` packages (the skills install path, your repo's own dependencies).
Expand Down
31 changes: 30 additions & 1 deletion docs/DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,33 @@ Decisions:
human-owned and out of scope.
- **Independent review:** each of the 6 fix branches was reviewed by a FRESH read-only reviewer
subagent (distinct instance from its coder) that re-ran the finding's proving commands and checked
test quality (non-tautology) before integration. All 6: VERDICT PASS.
test quality (non-tautology) before integration. All 6: VERDICT PASS.

## Adversarial review-and-fix (2026-07-08) — fresh run c6c486

Fresh-run: prior review docs / in-flight review branches are OUT OF SCOPE. Code-grounded only.
Outputs: `docs/adversarial-review-fresh.md`, `.fleet/runs/20260708T184204Z-adversarial-review-and-fix-c6c486/`.

| Field | Value |
|-------|-------|
| RUN_ID | `20260708T184204Z-adversarial-review-and-fix-c6c486` |
| RUN_SHORT | `c6c486` |
| REPO_ROOT | `/workspace` |
| PRODUCT | autonomous-fleet |
| MAINTAINER | Cursor Agent `<cursoragent@cursor.com>` |
| BRANCH_PREFIX | `cursor/` (cloud-agent host policy; suffix `-256a`) |
| BASE | `cursor/adversarial-review-base-256a` @ `e9e541b` |
| Adapter | `autonomous-fleet-adapter-grok` |
| LEDGER_DIR | `.fleet/docs` (Starlight docs-site probe) |
| SUBSTRATE | `/workspace/scripts` |
| AUTHORSHIP_MODE | `attributed` |
| reviewer_mode | `same-vendor-instructed` |
| Strict mode | Loose (Layer 2 Claude-Code-only; recorded) |

ASSUMPTIONS:
1. Entire-app adversarial review + fix of confirmed findings only.
2. Ignore existing adversarial-*.md / arch-build-* as inputs (fresh-run note).
3. Cloud PR/branch naming uses `cursor/*-256a`; merge into BASE not main.
4. No money/keys/custody surface; SAFETY RAILS = staging/fixtures only.
→ Proceeding.

Loading
Loading