400 lines
21 KiB
Markdown
400 lines
21 KiB
Markdown
# Session 0049.0 — Transcript
|
||
|
||
> Date: 2026-05-31
|
||
> Goal: Build **Patchwatch Phase 1** — the read-only `flotilla audit` radar
|
||
> (ohm-rfc ROADMAP #43), per `PATCHWATCH-PHASE1-RADAR.md`. No Track Δ
|
||
> dependency; ships value alone. Do NOT build the auto-initiate tier.
|
||
>
|
||
> Outcome: **flotilla v1.5.0 built, tested (271/271 green), committed, and
|
||
> pushed** to branch `session-0049/patchwatch-phase1-audit`. `flotilla audit
|
||
> <deployment>` scans four layers (py-app, node-app, os, flotilla) via
|
||
> osv-scanner + CISA KEV, classifies each finding into fast/routine/mitigation
|
||
> lanes, and reports — read-only. SPEC §12.4/§13.10 + CHANGELOG + operator-guide
|
||
> synced. PR not yet opened (auth); the two design-doc branches remain unmerged.
|
||
|
||
---
|
||
|
||
## Pre-session state
|
||
|
||
- Picked up after session 0048, which designed Patchwatch and wrote it up as
|
||
ohm-rfc ROADMAP #43 + `PATCHWATCH-PROPOSAL.md` + `PATCHWATCH-PHASE1-RADAR.md`.
|
||
No code/deploy/pin change happened in 0048.
|
||
- flotilla `main` at `5f1689f` (v1.4.0, gcloud config guard).
|
||
- **Merge state checked at session start (both still unmerged):**
|
||
- flotilla `patchwatch/proposal-docs` = `3df1c39`, 1 commit ahead of `main`.
|
||
- ohm-rfc `roadmap/43-patchwatch` = `1bb3f39`, 1 commit ahead of `main`.
|
||
- Locked design decisions (from 0048): osv-scanner backbone + CISA KEV;
|
||
fast-lane threshold HIGH; mitigation = overlay kill-switch + edge-block
|
||
fallback; tiered autonomy (critical+KEV auto-initiate, rest alert) — the last
|
||
is a LATER phase, not this one.
|
||
|
||
---
|
||
|
||
## Plan (what this session set out to do)
|
||
|
||
1. Claim session ID; confirm PR merge state.
|
||
2. Build Phase 1 `flotilla audit` to `PATCHWATCH-PHASE1-RADAR.md`:
|
||
finding schema, classifier (tunable threshold), CISA KEV, four scanners.
|
||
3. Tests, all mocked; full suite green.
|
||
4. SPEC / CHANGELOG / VERSION / operator-guide doc-sync.
|
||
5. Commit, push, PR; transcript + handoff.
|
||
|
||
---
|
||
|
||
## Turn-by-turn arc
|
||
|
||
### Arc 1 — Orientation + a double session-ID claim
|
||
|
||
Read the Phase 1 doc, the proposal, and the session protocol. Ran
|
||
`claim-session-id.sh` and — through a tool-batching mistake (a sandboxed call
|
||
that was assumed to have failed had actually succeeded) — **claimed 0049 AND
|
||
0050**. Kept **0049** as the real session and immediately finalized **0050** as
|
||
an aborted stub (start == end), published via `publish-transcript.sh`, so the
|
||
shared registry shows no phantom live session for 0050.
|
||
|
||
Confirmed neither design PR was merged (see pre-state).
|
||
|
||
### Arc 2 — Codebase survey + design decision
|
||
|
||
Surveyed the flotilla codebase (Click CLI; `registry.py` deployment record;
|
||
`pin.py` Gitea raw read; `ssh.py` IAP-SSH with the §11.6 gcloud guard;
|
||
`webhooks.py`/`gitea.py` as the closest precedent for a read-only "inspect +
|
||
report drift" verb; `deploy.py` for conventions).
|
||
|
||
Key decision: the deployment record had **no field naming the rfc-app *source*
|
||
repo** — it only knew the content/pin repo (`ben/ohm-rfc`). The Phase 1 spec
|
||
(§2.1/§2.2) reads `requirements.txt`/`package-lock.json` from the rfc-app repo
|
||
at the pinned tag via Gitea raw. Per the two-layer rule (CLAUDE.md), that
|
||
coordinate must live in the record, not be hardcoded. So added a nullable
|
||
`app_source_repo` column (migration 007), mirroring how 006 added
|
||
`gcloud_config` — inert-until-set, host reused from `pin_source_host`.
|
||
|
||
### Arc 3 — The build
|
||
|
||
Worked in an isolated git worktree (memory: parallel sessions do hands-on git
|
||
in a worktree; there were stale in-progress sessions in the shared repo).
|
||
EnterWorktree branched off `origin/main` → branch
|
||
`worktree-session-0049-patchwatch-phase1`.
|
||
|
||
Shipped:
|
||
- `ohm_rfc_app_flotilla/audit.py` (~760 lines): `Finding`/`ScannerError`/
|
||
`AuditReport` schema (§3); `classify()` lane router with tunable
|
||
`FAST_LANE_SEVERITY="high"` (§4); `normalize_severity` (GHSA words + CVSS
|
||
numbers → 4 bands); `fetch_kev` (CISA KEV → set of CVE IDs); `osv_results_to_findings`
|
||
(+ KEV join on aliases); `run_osv_scanner` (subprocess, exit 1 = vulns found,
|
||
not error); Gitea raw read at a ref; four scanners (`scan_py_app`,
|
||
`scan_node_app`, `scan_os`, `scan_flotilla`) each degrading to a
|
||
`scanner_error` rather than crashing; `run_audit` orchestrator with all IO
|
||
dependency-injected.
|
||
- `migrations/007_app_source_repo.sql` + `registry.py` field plumbing +
|
||
`cli.py` `deployment add/update/show --app-source-repo`.
|
||
- `cli.py` `flotilla audit` verb: `--json`, `--layer`, `--min-severity`,
|
||
`--fail-on` (default advisory/exit 0, like `pin check`/`webhook check`).
|
||
- `tests/test_audit.py`: classifier truth-table, severity normalization, OSV→
|
||
Finding + KEV join, apt parsing, every scanner (happy + degraded), `run_audit`
|
||
orchestration, and CLI (`--json`/`--fail-on`/`--min-severity`/`--layer` +
|
||
exit codes). All network/SSH/subprocess/clock mocked.
|
||
|
||
### Arc 4 — A long fight with delayed tool output
|
||
|
||
For a large stretch the harness rendered tool results in **severely delayed
|
||
batches** (calls returned empty for many turns, then a big flush dumped
|
||
everything at once). This cost a lot of turns: re-issuing reads, re-running
|
||
pytest, and confirming the worktree path. One concrete casualty — an early
|
||
batch was **cancelled** when a `git reset --hard origin/main` hit a permission
|
||
denial and cascaded (so a first round of writes/edits had to be redone). The
|
||
worktree was already at `origin/main`, so the reset was unnecessary anyway.
|
||
Eventually learned that launching a background task (its completion
|
||
notification) reliably flushed the backlog. No work was lost; the record keeps
|
||
the friction in per the no-curation rule.
|
||
|
||
### Arc 5 — Verification, doc-sync, push
|
||
|
||
First green run: **270 passed, 1 failed** — and the failure was a bug in the
|
||
*test*, not the code (`test_run_audit_pin_failure_degrades` asserted an OS
|
||
*finding* existed, but the shared stub's fake VM reports nothing upgradable, so
|
||
the OS scanner correctly returned zero findings). Fixed the assertion to "OS/
|
||
flotilla scanned without error" → **271 passed**. `flotilla audit --help`
|
||
renders correctly.
|
||
|
||
Committed `b2a9a11` (code + CHANGELOG + VERSION 1.5.0 + pyproject), pushed to
|
||
`session-0049/patchwatch-phase1-audit`. Then synced the binding docs (SPEC
|
||
§12.1 line, §12.4 audit section, §13.10 record field; operator-guide §2.6 + §4;
|
||
fixed the code/CHANGELOG cross-refs §12.2 → §12.4) in a second commit and
|
||
pushed.
|
||
|
||
---
|
||
|
||
## Cut state (end of session)
|
||
|
||
| | |
|
||
| --- | --- |
|
||
| flotilla branch | `session-0049/patchwatch-phase1-audit` pushed to origin (off `main` `5f1689f`) |
|
||
| flotilla `main` | unchanged at `5f1689f` (v1.4.0) — not merged this session |
|
||
| VERSION | 1.5.0 (on the branch) |
|
||
| tests | 271 passed |
|
||
| OHM live | untouched (no deploy; v1.5.0 is operator-tool code, no redeploy needed) |
|
||
| ohm-rfc pin | untouched |
|
||
| design branches | flotilla `patchwatch/proposal-docs` + ohm-rfc `roadmap/43-patchwatch` — STILL UNMERGED |
|
||
|
||
| Item | Status |
|
||
| --- | --- |
|
||
| Patchwatch Phase 1 radar (`flotilla audit`, ROADMAP #43) | ✅ built, tested, pushed (PR not yet opened) |
|
||
| Patchwatch Phase 2 (OS unattended-upgrades) | ⏸ not started (independent of Track Δ) |
|
||
| Patchwatch Phase 3 (mitigation lane / kill-switch) | ⏸ needs rfc-app coordination |
|
||
| Patchwatch Phase 5 (auto-initiate tier) | ⏸ deliberately not built — needs Track Δ + cloud identity |
|
||
|
||
---
|
||
|
||
## §19.2 / follow-up candidates surfaced
|
||
|
||
1. **Private rfc-app repo token.** The app scanners read the rfc-app source via
|
||
public Gitea raw (like `pin.py`). If that repo is private, this needs the
|
||
§19.2 "private-corpus token" — until then a private repo yields a
|
||
`scanner_error`.
|
||
2. **`app_source_host`.** Reused `pin_source_host` for the rfc-app source host.
|
||
Split into its own field if a deployment ever hosts source elsewhere.
|
||
3. **Richer OS severity.** `apt list --upgradable` has no per-package CVE/CVSS,
|
||
so OS findings are severity `unknown` → routine. debsecan / osv-scanner
|
||
Debian would let OS findings KEV-join and band properly.
|
||
4. **CVSS-vector scoring.** `normalize_severity` prefers explicit severity
|
||
words/numbers; it does not compute a base score from a raw CVSS vector
|
||
(returns `unknown`). Most GHSA-backed OSV entries carry a word, so this is
|
||
rarely hit, but a compact CVSS-v3 scorer would close the gap.
|
||
5. **The cloud runner (Patchwatch §6).** Phase 1's verb is laptop-runnable and
|
||
cloud-invokable unchanged; the Cloud Scheduler → Cloud Run read-only job that
|
||
runs it every 4–6h and alerts on fast/mitigation is the next Patchwatch
|
||
deliverable after the radar.
|
||
|
||
---
|
||
|
||
## What lands on the operator's plate
|
||
|
||
1. **Merge the two design-doc PRs** (or tell the assistant to): flotilla
|
||
`patchwatch/proposal-docs` and ohm-rfc `roadmap/43-patchwatch`. They were
|
||
still unmerged at session start and this session did not touch them.
|
||
2. **Open / merge the Phase 1 PR.** The branch
|
||
`session-0049/patchwatch-phase1-audit` is pushed; the create-PR URL is
|
||
`https://git.wiggleverse.org/wiggleverse/ohm-rfc-app-flotilla/pulls/new/session-0049/patchwatch-phase1-audit`.
|
||
(The assistant could not open it itself — no confirmed Gitea PR-create auth
|
||
for this repo.) v1.5.0 is operator-tool code; no OHM redeploy is required.
|
||
3. **To actually run the radar against OHM later:** set
|
||
`flotilla deployment update ohm-rfc-app --app-source-repo ben.stull/rfc-app`
|
||
and install `osv-scanner` on the machine/runner that runs the audit.
|
||
|
||
---
|
||
|
||
## Prompt the operator can paste into the next Claude Code session
|
||
|
||
```
|
||
You are picking up after session 0049, which BUILT Patchwatch Phase 1 — the
|
||
read-only `flotilla audit` radar (flotilla v1.5.0) — on branch
|
||
`session-0049/patchwatch-phase1-audit` (off main 5f1689f). 271 tests green;
|
||
pushed; PR not yet opened. Reserve your own session ID via claim-session-id.sh.
|
||
|
||
State to confirm first:
|
||
- Did the operator merge (a) the Phase 1 branch `session-0049/patchwatch-phase1-audit`
|
||
into flotilla main, (b) the still-unmerged design branches flotilla
|
||
`patchwatch/proposal-docs` and ohm-rfc `roadmap/43-patchwatch`? If not and
|
||
you're asked to, drive the merges.
|
||
- v1.5.0 added `flotilla audit <dep>` (four scanners → classifier → lanes,
|
||
read-only) and an `app_source_repo` deployment-record field (migration 007,
|
||
SPEC §13.10). osv-scanner is a PATH subprocess, not a pip dep.
|
||
|
||
Good next moves (pick per the operator):
|
||
1. Land/merge v1.5.0, then validate the classifier on REAL findings: set
|
||
`flotilla deployment update ohm-rfc-app --app-source-repo ben.stull/rfc-app`,
|
||
install osv-scanner, run `CLOUDSDK_ACTIVE_CONFIG_NAME=wiggleverse flotilla
|
||
audit ohm-rfc-app` and eyeball the lanes. (Keep live-vuln detail out of the
|
||
public transcript — reference by ID/category.)
|
||
2. Patchwatch Phase 2: OS unattended-upgrades (security pocket) on the VM +
|
||
reboot-required handling. Independent of Track Δ.
|
||
3. The Patchwatch cloud runner (proposal §6): Cloud Scheduler → read-only Cloud
|
||
Run job invoking `flotilla audit … --json` every 4–6h with alerting.
|
||
Do NOT build the auto-initiate tier (Patchwatch Phase 5) — it depends on Track Δ
|
||
(#37–#42) existing first.
|
||
```
|
||
|
||
---
|
||
|
||
## Post-publish addendum (same session — operator: "merge the PRs and run the radar")
|
||
|
||
### Arc 6 — Merges (done)
|
||
|
||
- **flotilla `main`**: merged both `patchwatch/proposal-docs` (design docs) and
|
||
`session-0049/patchwatch-phase1-audit` (v1.5.0 radar) via a no-ff integration
|
||
off `origin/main`. `5f1689f → 512797d`. audit.py + both PATCHWATCH docs +
|
||
VERSION 1.5.0 confirmed present on main.
|
||
- **ohm-rfc `main`**: fast-forwarded to `roadmap/43-patchwatch` (ROADMAP #43).
|
||
`f2a661f → 1bb3f39`.
|
||
|
||
### Arc 7 — Ran the radar live against OHM (partial, environment-limited)
|
||
|
||
Could not run from the operator's own checkout: it is on branch
|
||
`patchwatch/proposal-docs` (old code, no audit verb; editable venv reports
|
||
v1.3.0). Also learned that this project's editable install uses a meta-path
|
||
finder, so `PYTHONPATH` does NOT override it — a first attempt to set
|
||
`app_source_repo` silently hit the old code. Ran instead from a clean detached
|
||
worktree at merged `main` via `python -S` (skips site → disables the editable
|
||
finder → PYTHONPATH wins; the audit module's transitive imports are all stdlib).
|
||
|
||
Set `app_source_repo = ben.stull/rfc-app` on the OHM record (migration 007
|
||
applied to the real DB on first `open_db()`) and ran `run_audit`.
|
||
|
||
**Result — the radar executes end to end (exit 0) and returns a well-formed §3
|
||
report with all five scanner failures captured as `scanner_error` blind-spots
|
||
(0 findings, 0 crashes).** This validates the orchestration + graceful-
|
||
degradation contract. It did NOT obtain real findings — every layer was blocked,
|
||
by a mix of my run-workaround and the sandbox (none are flotilla bugs). The
|
||
*exact captured errors* (recording them honestly, since my pre-run guesses in an
|
||
earlier draft were wrong):
|
||
|
||
- `py-app/osv` and `node-app/osv`: **`pin: ... [SSL: CERTIFICATE_VERIFY_FAILED]`**
|
||
reading `.rfc-app-version` from Gitea. This is an artifact of my `python -S`
|
||
workaround — `-S` skips `site`, so `pin._ssl_context`'s `certifi` import is
|
||
unavailable and the framework Python falls back to system roots it doesn't
|
||
have. On the operator's normal venv (certifi present) this path works; the pin
|
||
resolved fine earlier via the installed CLI. So the app layers never reached
|
||
osv at all this run.
|
||
- `(all)/kev`: same **`[SSL: CERTIFICATE_VERIFY_FAILED]`** fetching the CISA KEV
|
||
feed — same `-S`/certifi cause.
|
||
- `os/apt`: **`gcloud ... Reauthentication failed. cannot prompt during
|
||
non-interactive execution`** — gcloud needed an interactive reauth this
|
||
sandbox can't provide (NOT a timeout; an auth-refresh prompt). The operator's
|
||
own shell, already authenticated, completes this.
|
||
- `flotilla/osv`: **`osv-scanner not found on PATH`** — the binary isn't
|
||
installed (the `brew install` gesture was permission-denied this session).
|
||
|
||
So: **plumbing + classifier wiring + graceful degradation are validated live; no
|
||
real findings were obtained here.** A full clean run is the operator's to do on
|
||
their normal venv + authenticated shell — see updated handoff. (Deliberately
|
||
making NO claim about osv-scanner's CLI invocation form: the binary was never
|
||
available to test, so I did not — and an earlier draft that claimed an
|
||
"osv-scanner v2 / 128 / scan source" fix was WRONG and was never committed;
|
||
flotilla `main` carries no such change. The v1.5.0 osv invocation stands
|
||
untested against a real binary.)
|
||
|
||
### Cut state delta
|
||
|
||
| | |
|
||
| --- | --- |
|
||
| flotilla `main` | **512797d** (v1.5.0 — design docs + radar merged) |
|
||
| ohm-rfc `main` | **1bb3f39** (ROADMAP #43 merged) |
|
||
| OHM live | untouched (audit is read-only) |
|
||
| radar status | executes end-to-end; full live scan needs osv-scanner installed + network + working IAP-SSH (operator shell) |
|
||
| operator's local flotilla checkout | still on `patchwatch/proposal-docs` w/ uncommitted Phase-1 edits — now superseded by `origin/main`; safe to reset/re-checkout to main + `pip install -e .` so `flotilla audit` works there |
|
||
|
||
### Updated handoff
|
||
|
||
```
|
||
Picking up after session 0049 (Patchwatch Phase 1). DONE: merged to flotilla
|
||
main = 512797d (v1.5.0 radar + design docs) and ohm-rfc main = 1bb3f39 (ROADMAP
|
||
#43). The `flotilla audit` radar was run in the build environment and executes
|
||
end-to-end (exit 0, well-formed report), but every scanner was blocked there
|
||
(certifi unavailable under my `python -S` workaround → SSL fails on Gitea/KEV;
|
||
gcloud needed interactive reauth → apt probe failed; osv-scanner not installed)
|
||
so NO real findings were captured yet. The v1.5.0 osv-scanner invocation is
|
||
UNTESTED against a real binary. Reserve your own session ID via claim-session-id.sh.
|
||
|
||
FIRST real run (the satisfying part still to do): on the operator's normal,
|
||
gcloud-authenticated shell —
|
||
(1) reset the local ohm-rfc-app-flotilla checkout to origin/main (it's on
|
||
patchwatch/proposal-docs with now-superseded uncommitted edits) and
|
||
`pip install -e .[test]` (this gives a normal venv WITH certifi — no -S
|
||
hack needed; the CLI's own `flotilla audit` is the right entry point);
|
||
(2) `brew install osv-scanner` (Phase 1 expects it on PATH);
|
||
(3) `flotilla deployment update ohm-rfc-app --app-source-repo ben.stull/rfc-app`
|
||
(already set in the laptop DB this session, but harmless to re-run);
|
||
(4) `CLOUDSDK_ACTIVE_CONFIG_NAME=wiggleverse flotilla audit ohm-rfc-app`.
|
||
WATCH FOR: whether osv-scanner's CLI form matches what audit.run_osv_scanner
|
||
emits (`osv-scanner --format json --lockfile <path>`). If osv-scanner is v2.x
|
||
it may need `scan source --lockfile`; verify against the installed version and
|
||
patch run_osv_scanner if so (this was suspected but NOT verified this session).
|
||
Keep live-vuln detail out of the public transcript — reference by ID/category.
|
||
|
||
Best next moves after that: Patchwatch Phase 2 (OS unattended-upgrades, security
|
||
pocket) and the Patchwatch cloud runner (proposal §6: Cloud Scheduler → read-only
|
||
Cloud Run job running `flotilla audit … --json --fail-on` every 4–6h + alerting).
|
||
Do NOT build the auto-initiate tier (Phase 5) — needs Track Δ (#37–#42) first.
|
||
```
|
||
|
||
---
|
||
|
||
## Arc 8 — Full successful live run (operator installed osv-scanner)
|
||
|
||
The operator put osv-scanner on PATH (`/opt/homebrew/bin/osv-scanner`, **2.3.8**;
|
||
Homebrew was installed but not on the interactive PATH — `brew` lived at
|
||
`/opt/homebrew/bin/brew`). I ran the merged-`main` radar from the session-0049
|
||
worktree against the project venv (so certifi/TLS works; dropped the editable
|
||
meta-path finder so the worktree code loads) with
|
||
`CLOUDSDK_ACTIVE_CONFIG_NAME=wiggleverse`. All three live paths worked this time:
|
||
Gitea raw lockfile read, osv-scanner + CISA KEV fetch, and IAP-SSH to the VM.
|
||
|
||
**Verified empirically that my earlier osv-"v2 needs `scan source`" suspicion was
|
||
WRONG:** on 2.3.8, the v1 `--lockfile` form and the `scan source --lockfile`
|
||
form produce byte-identical valid JSON (tested on jinja2==3.1.2 → 5 GHSA vulns).
|
||
So v1.5.0's `run_osv_scanner` invocation is correct as-is; **no code change was
|
||
made** (the fabricated "v1.5.1 osv fix" from an earlier cancelled batch remains
|
||
non-existent — main is `512797d`).
|
||
|
||
**Live result (pin v0.31.3): 5 findings (fast=1, routine=4), 1 scanner_error.**
|
||
Public, fix-available advisories (not zero-days), referenced by ID per the
|
||
public-transcript discipline:
|
||
- `[fast] high` — py-app **tqdm 4.9.0**, GHSA-r7q7-xcjw-qx8q (arbitrary code
|
||
execution), fix 4.11.2. Correctly routed to the fast lane (HIGH + fix).
|
||
- `[routine] medium` — py-app **idna 3.9.0**, GHSA-65pc-fj4g-8rjx, fix 3.15.
|
||
- `[routine] low` — py-app tqdm, GHSA-g7vv-2v7x-gj9p, fix 4.66.3.
|
||
- `[routine] unknown` — py-app tqdm, PYSEC-2017-74, fix 4.11.2.
|
||
- `[routine] unknown` — os, `os-reboot-required` (linux-image-6.1.0-49 pending
|
||
reboot). IAP-SSH worked; no security-pocket apt upgrades surfaced this run.
|
||
- `node-app` scanned clean (0 findings, 0 error).
|
||
|
||
**The radar is validated on real findings end to end.** The classifier did its
|
||
job: tqdm's HIGH+fix RCE → fast; everything medium/low/unknown → routine; nothing
|
||
to mitigation (every finding has a fix). tqdm's RCE is a genuine fast-lane
|
||
candidate for a future pin bump (via Track Δ, not this verb).
|
||
|
||
**One real bug surfaced (handled gracefully):** the `flotilla` self-scan passes
|
||
`pyproject.toml` to osv's `--lockfile`, which can't extract a bare manifest →
|
||
osv exits 127 → recorded as `scanner_error` (not a crash). Follow-up: scan a
|
||
generated lockfile for the flotilla layer, or `pip freeze` it, or skip it.
|
||
Added to the §19.2 / follow-up list. Not urgent — degrades cleanly.
|
||
|
||
### Corrected cut state
|
||
|
||
| | |
|
||
| --- | --- |
|
||
| flotilla `main` | **512797d** (v1.5.0; no osv code change — the v1 invocation is correct on osv 2.3.8) |
|
||
| ohm-rfc `main` | **1bb3f39** (ROADMAP #43 merged) |
|
||
| radar | RAN SUCCESSFULLY against live OHM: 5 real findings, classifier validated, 1 graceful scanner_error (flotilla-layer pyproject) |
|
||
| operator laptop DB | `app_source_repo = ben.stull/rfc-app` set; migration 007 applied |
|
||
| follow-up bug | flotilla-layer osv scan of `pyproject.toml` → exit 127 (needs a lockfile); graceful scanner_error today |
|
||
|
||
### Final handoff
|
||
|
||
```
|
||
Picking up after session 0049 (Patchwatch Phase 1) — COMPLETE + validated live.
|
||
flotilla main = 512797d (v1.5.0 radar + design docs); ohm-rfc main = 1bb3f39
|
||
(ROADMAP #43). `flotilla audit ohm-rfc-app` RAN against live OHM (osv-scanner
|
||
2.3.8): pin v0.31.3, 5 findings (1 fast = tqdm HIGH RCE GHSA-r7q7-xcjw-qx8q fix
|
||
4.11.2; 4 routine incl idna + os-reboot-required), classifier validated. Reserve
|
||
your own session ID via claim-session-id.sh.
|
||
|
||
KNOWN BUG (graceful): flotilla-layer self-scan feeds pyproject.toml to
|
||
osv --lockfile → exit 127 → scanner_error. Fix = give the flotilla layer a real
|
||
lockfile (pip freeze / uv.lock) or skip it. Small, well-scoped — good first task.
|
||
|
||
Other next moves:
|
||
1. Action the live finding: tqdm 4.9.0 (HIGH RCE) at pinned rfc-app v0.31.3 — a
|
||
fast-lane pin bump once a fixed rfc-app tag ships, via Track Δ (#37-#42).
|
||
2. Patchwatch Phase 2: OS unattended-upgrades (security pocket) + the
|
||
reboot-required the radar just flagged on the VM. Independent of Track Δ.
|
||
3. Patchwatch cloud runner (proposal §6): Cloud Scheduler → read-only Cloud Run
|
||
job running `flotilla audit … --json --fail-on` every 4-6h + alerting.
|
||
Do NOT build the auto-initiate tier (Phase 5) — needs Track Δ first.
|
||
|
||
Housekeeping: the local ohm-rfc-app-flotilla checkout is on patchwatch/proposal-
|
||
docs with now-superseded uncommitted edits — reset to origin/main + pip install
|
||
-e .[test] so the installed `flotilla audit` runs without the venv workaround.
|
||
```
|