Commit graph

76 commits

Author SHA1 Message Date
443297e8e4 feat(secrev): confluence-doc Plane-1 Phase 4 doc-gap detector (recommend-only)
Scheduled, read-only documentation gap detector. Diffs the org repo set + an
optional read-only AWS inventory + the IT page-ID map (project_confluence_
migration) against Confluence and REPORTS doc gaps / stale pages / missing
runbooks into the mode-600 report. RECOMMEND-ONLY per D3/D7: NEVER auto-writes
Confluence; the on-demand SSH-invoked write path (incl. Mermaid edits via
~/.claude/scripts/confluence_mermaid.py) is a separate, gated provisioning path.

LIVE Confluence API reads need the gated confluence-bot service-account token
(D6); when creds are absent OR --no-api/--canary, the API checks are SKIPPED and
noted, NEVER reported as a gap on missing data (mirrors compliance-drift's
status-code-aware API-skip pattern: 200 parse, 404 real gap, else skip).

Offline --canary asserts the doc-gap count (3) against a fixture (repo list +
mock page-map + mock AWS inventory): a repo with no IT page, an AWS resource not
in the map, and a missing required runbook page; precision non-gaps (matched
repos/resources, doc-exempt repo, present required pages, skipped API) must not
inflate the count. shellcheck-clean (only the shared SC1091 substrate-source
info). PROVISIONING (confluence-bot account + 90-day rotation, page-1540098 live
dry-run expecting 16 weweave macros, systemd wiring, coordinator registry)
documented in the footer, deferred — gated.
2026-06-18 15:58:04 -04:00
19a57408d2 feat(secrev): plan-groomer Plane-1 Phase 4 planner (report-only)
Aggregates the OTHER Plane-1 checkers' latest reports (compliance-drift,
dependency-cve, doc-drift, confluence-doc) into one prioritized, deduped
"groomed weekly plan" written into the mode-600 report. REPORT-ONLY per
decision D3: posts NOTHING to Slack; auto-write to Notion/Jira is a later
toggle (inert --notify seam). Reuses lib/sweep_substrate.sh redact().

Offline --canary asserts the groomed-plan item count (5) against a fixture
report set, exercising latest-date selection, dedup, multi-source aggregation,
and no-data discipline (a missing source is noted, never invented as work).
shellcheck-clean (only the shared SC1091 substrate-source info, at parity with
compliance-drift/dependency-cve). PROVISIONING (auto-write toggle, systemd
wiring, coordinator registry) deferred — gated.
2026-06-18 15:51:45 -04:00
Adam Moussa
f09c94a821
feat(secrev): Plane-1 Phase 2 — coordinator + dependency-cve checker (#16)
* fix(agent-team): read SLACK_CHANNEL_ID, aligning code with deploy doc + systemd

run-team.py read os.environ['SLACK_CHANNEL'] while DEPLOY-R720.md and the
coordinator systemd unit both document SLACK_CHANNEL_ID; the mismatch would
silently default the live Slack transport channel to empty. Standardize on
SLACK_CHANNEL_ID (decision locked 2026-06-18).

* feat(secrev): dependency-cve Plane-1 Tier-1 checker (OSV, ALARM-only)

Read-only checker on the Phase-0 substrate: scans $MIRROR_DIR mirrors for
pinned deps (requirements/poetry/Pipfile/package-lock/yarn/csproj across
PyPI/npm/NuGet), cross-refs OSV querybatch (live) or an offline advisory
fixture (canary). Mode-600 reports, ALARM-only, --canary asserts 2 planted
vulns (jinja2 2.11.2, lodash 4.17.15). Complements Dependabot. Not provisioned.

* feat(secrev): Plane-1 checker coordinator (shared budget, rotation, dedup)

Coordinator (design §5/§6.7) orchestrating Tier-1 checkers under one shared
budget ledger + versioned rotation/coverage state (atomic write + schema/hash/
logical-consistency integrity, park-on-corrupt). Canary-suite-first
(COMPLACENCY skip), fan-out under the shared cap with defer-not-drop, COVERAGE
alarm past MAX_CYCLE_NIGHTS, cross-checker dedup/prioritize, ALARM-only routing.
--squeeze-dry-run proves deferral-not-drop + COVERAGE alarm. Not provisioned.

* fix(secrev): hide dependency-cve canary manifests from dependency-review

The canary fixtures intentionally pin known-vulnerable deps (jinja2 2.11.2,
lodash 4.17.15) so the checker has something to detect. GitHub's dependency
graph parsed those fixture manifests as real project deps, failing the
dependency-review PR gate (fail-on-severity: high). Store the manifests with a
.fixture suffix so the dependency graph ignores them; the --canary materializer
strips the suffix in its temp work area before scanning, so detection is
unchanged (still 2/2). No advisory allowlist, no change to the shared org
reusable workflow — the real gate stays strict for actual deps.
2026-06-18 15:08:58 -04:00
dependabot[bot]
75d9d6c3d4
build(deps): bump the minor-and-patch group across 1 directory with 6 updates (#11)
Bumps the minor-and-patch group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [langgraph](https://github.com/langchain-ai/langgraph) | `1.1.10` | `1.2.5` |
| [langchain-anthropic](https://github.com/langchain-ai/langchain) | `1.4.3` | `1.4.6` |
| [langchain-openai](https://github.com/langchain-ai/langchain) | `1.2.1` | `1.3.2` |
| [langchain-google-genai](https://github.com/langchain-ai/langchain-google) | `4.2.2` | `4.2.5` |
| [langchain-community](https://github.com/langchain-ai/langchain-community) | `0.4.1` | `0.4.2` |
| [composio-langgraph](https://github.com/ComposioHQ/composio) | `0.13.0` | `0.15.0` |



Updates `langgraph` from 1.1.10 to 1.2.5
- [Release notes](https://github.com/langchain-ai/langgraph/releases)
- [Commits](https://github.com/langchain-ai/langgraph/compare/1.1.10...1.2.5)

Updates `langchain-anthropic` from 1.4.3 to 1.4.6
- [Release notes](https://github.com/langchain-ai/langchain/releases)
- [Commits](https://github.com/langchain-ai/langchain/compare/langchain-anthropic==1.4.3...langchain-anthropic==1.4.6)

Updates `langchain-openai` from 1.2.1 to 1.3.2
- [Release notes](https://github.com/langchain-ai/langchain/releases)
- [Commits](https://github.com/langchain-ai/langchain/compare/langchain-openai==1.2.1...langchain-openai==1.3.2)

Updates `langchain-google-genai` from 4.2.2 to 4.2.5
- [Release notes](https://github.com/langchain-ai/langchain-google/releases)
- [Commits](https://github.com/langchain-ai/langchain-google/compare/libs/genai/v4.2.2...libs/genai/v4.2.5)

Updates `langchain-community` from 0.4.1 to 0.4.2
- [Release notes](https://github.com/langchain-ai/langchain-community/releases)
- [Commits](https://github.com/langchain-ai/langchain-community/compare/libs/community/v0.4.1...libs/community/v0.4.2)

Updates `composio-langgraph` from 0.13.0 to 0.15.0
- [Release notes](https://github.com/ComposioHQ/composio/releases)
- [Commits](https://github.com/ComposioHQ/composio/compare/py@0.13.0...py@0.15.0)

---
updated-dependencies:
- dependency-name: composio-langgraph
  dependency-version: 0.13.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: langchain-anthropic
  dependency-version: 1.4.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: langchain-community
  dependency-version: 0.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: langchain-google-genai
  dependency-version: 4.2.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: langchain-openai
  dependency-version: 1.3.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: langgraph
  dependency-version: 1.2.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 14:44:46 -04:00
Adam Moussa
beb5ad0807
Merge pull request #15 from Sea-Haven-Industries/feature/agent-team-medium-cleanup
cleanup(agent-team): clear 3 SAST mediums + refresh README to built state
2026-06-18 14:21:43 -04:00
fdaafac36f docs(agent-team): refresh README to current built state (P1-P4)
The README still described 'FOUNDATION modules only — no coordinator, no transports, no CI workflow'. Updated to reflect the built+merged pipeline (P1 human gate, P2 planner+review, live coordinator+transports+intake, P3-inert build/verify subgraph, P4) with the current layout, the pipeline diagram, key design points, and the deploy-gated/not-built items (P3 live CI, provisioning).
2026-06-18 14:19:00 -04:00
035c6e57e5 fix(agent-team): clear 3 non-blocking SAST mediums on main
clarifier_llm: sha1 -> sha256 for the non-security cache-discriminator (CWE-327 false positive). github_adapter + github_intake: inline nosemgrep on the urlopen lines (dynamic-urllib-use-detected) — the URL is built from a fixed https GitHub API base, dynamic part is the path only, no SSRF/file:// surface (extends the existing noqa:S310 trusted-host judgment to semgrep). Scanner now reports 0 mediums on the agent-team scope.
2026-06-18 14:16:31 -04:00
Adam Moussa
516cf18111
Merge pull request #14 from Sea-Haven-Industries/feature/agent-team-plane1-phase0
secrev/Plane-1: Phase 0 shared substrate + compliance-drift checker
2026-06-18 14:09:35 -04:00
28553d86f7 feat(secrev): compliance-drift Plane-1 Tier-1 checker (ALARM-only)
Read-only org compliance checker on the shared substrate (no re-clone; scans existing mirrors). Checklist grounded in handbook/github-standards: kebab repo name, README, CI/CD, Dependabot config+alerts, tracked-.env secrets, branch protection, merge settings; handbook exceptions (docs-only, compliance-exempt) honored. Mode-600 reports, ALARM-only (clean=silent). Includes planted-drift canary (asserts 6). Review fixes folded in: branch-protection + dependabot are status-code-aware (only a real 404 is drift; transient API failure -> skip, no false alarm); secrets-committed fires only on secret-shaped values (not benign config). NOT scheduled (provisioning gated).
2026-06-18 14:06:31 -04:00
1a1facd945 refactor(secrev): factor shared sweep substrate out of nightly_sweep.sh (Plane-1 Phase 0)
Extract discovery/mirror/budget-ledger/rotation/Slack-ALARM(redaction)/canary into security-review/lib/sweep_substrate.sh (sourceable, bash, stdlib only); nightly_sweep.sh (415->362) now sources it. Zero behavior change proven: shellcheck -x clean, offline two-tier dry-run byte-identical before/after, token discipline (read-only PAT, REST-only, no gh CLI, origin scrubbed) preserved, review.sh untouched. Revert point: 73e35f3. Foundation both planes' scheduled side reuses.
2026-06-18 14:06:31 -04:00
Adam Moussa
73e35f3acd
Merge pull request #13 from Sea-Haven-Industries/feature/agent-team-plane2-p3-p4
agent-team Plane-2: P4 live transports + intake, P3-inert build/verify subgraph
2026-06-18 13:40:48 -04:00
Adam Moussa
6711c69601
Merge branch 'main' into feature/agent-team-plane2-p3-p4 2026-06-18 13:29:18 -04:00
Adam Moussa
1aea314ee0
Merge pull request #12 from Sea-Haven-Industries/feature/agent-team-plane2-p1-p2
agent-team Plane-2: bind P1+P2 to real models, live transport, coordinator
2026-06-18 13:29:02 -04:00
e1208ee563 feat(agent-team): P3-inert build/verify subgraph topology (opt-in, no live CI)
build_verify_subgraph: BUILD->VERIFY nodes + route_after_verify. build_graph gains an opt-in build_verify param that repoints the review 'build' route at the subgraph (BUILD->VERIFY->{approved->END | loop->PLAN | parked->END}); default unchanged (P2). Coordinator build_verify_wiring composes it INERT (no ci_result -> ci_gate BLOCK -> PARKED; LLM is fix-proposer only, never declares green). NOT enabled in production: the live CI apply/verify + OIDC stays held for its /sh-security-review + GPT-4.1 cross-review gate. Also escapes untrusted intake text in logs (log-injection hygiene).
2026-06-18 13:23:03 -04:00
0842ff778b feat(agent-team): P4 live github/claude_code transports + GitHub-issue intake
Live github (issue-comment poster) and claude_code (file-drop) transports, plus GithubIntake (labeled issue -> coordinator.start_task, de-duped). run-team _build_transport now wires github/claude_code live (was SystemExit) + adds the intake-github subcommand. claude_code drop-path also neutralizes backslash (defense-in-depth).
2026-06-18 13:23:02 -04:00
8d9babe52e test(agent-team): make slack_live token test independent of slack_sdk presence
CI lacks slack_sdk, so the deferred-import-missing error fired before the no-token check and masked it. Stub slack_sdk into sys.modules so the token branch is deterministically exercised in both environments.
2026-06-18 13:00:34 -04:00
0f33fa6f24 docs(agent-team): R720 deploy runbook + coordinator systemd unit
P1c deploy artifacts: DEPLOY-R720.md (snapshot-first, rsync, venv deps, ~/secrev.env tokens incl. AGENT_TEAM_SLACK_OWNER_IDS, init-db, systemd, the 4-criteria live demo, rollback) and the long-running coordinator service unit.
2026-06-18 12:56:42 -04:00
22edd4143a feat(agent-team): P1/P2 graph wiring + coordinator daemon + run-team start/serve
build_graph gains injected live_plan_node/review_node/route_review: P1 = plan->END, P2 = clarify->plan->review->{build|loop-back|parked}. Coordinator composes clarifier->graph->ResumeWorker, wraps planner fail-safe, binds the GPT-4.1 review loop; run-team start/serve opt production into P2. Re-delivery uses a guarded CAS so a concurrently-answered row is never clobbered (closes RACE-REDELIVER).
2026-06-18 12:56:42 -04:00
253e31b0e8 feat(agent-team): live Slack transport + Socket Mode listener with owner allowlist
slack_live: real slack_sdk poster. slack_listener: Socket Mode inbound; trust boundary = app-token auth + an explicit owner allowlist on the sender (fail-closed, rejects all if AGENT_TEAM_SLACK_OWNER_IDS unset) + the open-status CAS as anti-replay. Closes the AUTHZ-01 missing-sender-authz finding from the security review.
2026-06-18 12:56:42 -04:00
4b17e8ebd4 feat(agent-team): bind planner/review/builder/verifier nodes to their models
review_loop_llm -> GPT-4.1 cross_reviewer (orchestrator run.py); builders_llm -> DeepSeek fast_coder (INERT, proposes diff text only); verifier_llm -> ci_gate is sole PASS authority, Claude is fix-proposer only. Hardens review_loop.parse_verdict to word-boundary matching, adds a fail-closed subprocess timeout, and bind_review_node (single-arg, no LangGraph config injection). All fail safe on untrusted model output.
2026-06-18 12:56:42 -04:00
270ce93b2a feat(agent-team): bind P1 clarifier to real Claude via subscription-OAuth invoker
Adds the billing-seam invoker (claude_agent_sdk subscription-OAuth, deferred import, API/Bedrock paths) and the Claude-backed clarifier callables (ConfidenceAssessor/QuestionGenerator, one call/turn memoized on (thread_id,len,content-hash), fail-safe to 0.0 so garbage never clears the 98% human gate).
2026-06-18 12:56:42 -04:00
Adam Moussa
b853598579
Merge pull request #10 from Sea-Haven-Industries/feature/adopt-org-conventions
Adopt org conventions: reusable-workflow CI, dependabot, labels
2026-06-17 18:00:32 -04:00
3d066e04e4 ci: add workflow permissions from GHAS notes 2026-06-17 17:56:32 -04:00
13f3d89c99 ci: retrigger workflows 2026-06-17 17:51:11 -04:00
d17427d3cc ci: remove temporary inline probe workflow 2026-06-17 17:46:42 -04:00
6adce96983 ci: temporary inline probe workflow 2026-06-17 17:41:55 -04:00
87cf449485 ci: retrigger workflows 2026-06-17 17:39:39 -04:00
fa25af8971 Adopt org CI conventions: thin wrappers over reusable workflows + dependabot
Replace the inlined CI with thin callers of the Sea-Haven-Industries/.github
reusable workflows (org convention — CI logic lives centrally in .github):
- ci.yaml -> ci-python-app.yaml (ruff + conventions + root collect-only +
  the agent-team/ subproject suite; emits the required `ci / ci`)
- dependency-review.yml -> callable-dependency-review.yaml
- labeler.yml -> callable-labeler.yaml (all three permissions granted)
Add .github/dependabot.yml (pip + github-actions, weekly, grouped).
2026-06-17 17:28:55 -04:00
Adam Moussa
367835ee29
Merge pull request #9 from amoussa1229/fix/checkov-surgical-cdk-exclusions
security-review: scan CDK synthesized templates, skip only asset bundles (A2)
2026-06-17 17:07:54 -04:00
b0d8b842e5 security-review: surgically exclude only cdk.out asset bundles from checkov (A2)
The prior exclusion (--skip-path cdk.out) stopped the CDK-repo stall but also
silenced checkov on cdk.out/<stack>.template.json — the actual deploy artifact —
losing real S3/IAM IaC coverage (CKV_AWS_53-56, CKV_AWS_111). Switch to skipping
only the cdk.out asset.<hash>/ dependency bundles (the stall cause) so the
synthesized templates are still scanned.

- --skip-path 'cdk\.out/asset\.' anchors to cdk.out so a source file literally
  named asset.* is not also excluded; keeps cdk.out/*.template.json scanned.
- venv/dist/build kept as bare names (match anywhere); .venv/.aws-sam escaped.

cfn-lint + semgrep already prune these trees (prior commit). gitleaks runs in
git-mode and respects .gitignore, so cdk.out is already skipped there.

Verified: shellcheck clean; synthetic cdk.out test confirms the stack template is
scanned while asset.* is skipped; the orchestrator's own --scanners-only gate
still exits 0 with suppressions (inert on non-CDK repos: A1==A2 findings here).
2026-06-17 17:06:05 -04:00
Adam Moussa
af6dd98783
Merge pull request #8 from amoussa1229/feature/r720-plane2-scaffold
R720 agent-team: Plane-2 SDLC pipeline scaffold (pre-deployment)
2026-06-17 15:21:27 -04:00
502828f75c Fix CI collection: isolate agent-team tests; add agent-team CI job
Repo-root 'pytest --collect-only' failed with ImportPathMismatchError because
agent-team/tests/ and the root tests/ are both the 'tests' package. Add a root
conftest.py that excludes agent-team from the root collection, and a dedicated
agent-team-tests CI job that runs the (API-key-free) agent-team suite in its own
working dir.
2026-06-17 15:19:51 -04:00
721cec5315 Resolve security-review BLOCK: CI-guard bypasses, denylist parity, force-resume
Addresses the confirmed findings from /sh-security-review + the GPT-4.1
cross-review of the Plane-2 scaffold. Full suite: 589 passed; ruff clean.

FIXED (proven-exploitable):
- CI-guard denylist bypass (HIGH): Python fnmatch '**/' is non-recursive, so
  root-level template.yaml/*.tf/cdk.json/*.pem/*.key/*-stack.* evaded the
  trust-control surface. Replaced fnmatch with a recursive, case-insensitive
  glob->regex matcher. (verified: fnmatch('template.yaml','**/template.yaml')==False)
- CI-guard scope bypass (HIGH): a '**' declared_scope made every path in-scope.
  Scope is now concrete-prefix confinement (reduces a glob to its leading
  metacharacter-free segments; '**' -> empty -> dropped -> unscoped reject).
- Box-side vs CI denylist divergence (MED): builders.py _DENY_PATTERNS now covers
  Terraform, *.pem/*.key, CDK stack files, .github/actions, *iam*, bare policy*.json
  (case-insensitive), matching the CI surface.
- force-resume was backwards (MED): it superseded the answered row recovery
  resumes from, making a stuck task permanently un-resumable while printing
  success. Now re-opens an EXPIRED (parked) question via a new reopen_question
  CAS helper; never supersedes an answered row; honest exit codes.
- operator attribution (MED): run-team.py --operator defaulted to "" -> now the
  OS login, so destructive actions are always attributable.
- audit-log append race (MED): replaced read-modify-rewrite (lost records under
  concurrent operators) with an O_APPEND single-line write, mode 600 enforced.
- lstrip("ab/") path-mangling in the symlink error path -> regex prefix strip.

Regression tests added across test_ci_gate_workflow / test_builders / test_run_team
/ test_schema. Design-level findings (resume-worker durability, egress breadth,
answered_at ordering, DB-swap TOCTOU, diff-hash threat-model) are pre-deployment
/ P1-build-proper and recorded with written justification in
agent-team/.security-review/suppressions.json; CI README diff-hash wording made
honest.
2026-06-17 15:16:12 -04:00
0eae5dbfc3 Prove P1 exit criteria against the real LangGraph graph; fix question_id stability
Reworks the P1 sim so the four §7.1 exit criteria are demonstrated against the
ACTUAL mechanic, not a model (resolves the verifier's "sim models the ledger,
not the LangGraph integration" finding).

- New tests/sim/test_p1_graph_integration.py drives the real agent_team.graph
  StateGraph (interrupt/Command(resume)) + the real langgraph SqliteSaver
  checkpointer + the committed pending_questions compare-and-set, proving:
  (a) suspend survives a simulated restart (drop saver/conn, rebuild over the
  same checkpoint DB) and resumes; (b) duplicate answer loses the CAS and the
  graph never double-advances; (c) a post-deadline answer loses to expire and
  the task is not resumed; (d) two concurrent tasks resume to the correct
  thread, with a turn-guarded no-double-apply check.
- graph.py: derive a STABLE question_id from uuid5(thread_id, turn). The
  clarifier node replays on resume, so the prior fresh-uuid id changed between
  the delivered/ledgered question and the qa_history entry — breaking the
  §3.3.1 identity contract. Now the delivered id == ledger key == history entry
  (unit-tested in test_graph.py).
- harness._connect() now uses the committed schema.connect() (WAL + busy_timeout)
  instead of a raw sqlite3.connect, so concurrent responders genuinely serialize;
  the criterion-(d) concurrency test no longer swallows OperationalError (it
  asserts zero errors + exactly one CAS winner).
- requirements.txt: pin langgraph-checkpoint-sqlite==3.1.0 (design D9 durable
  checkpointer), now exercised by the integration test.

Full suite: 564 passed; ruff + format clean.
2026-06-17 15:16:12 -04:00
8f28fbe6a5 Harden CI guard: symlink-escape reject, strict decode, scope canon; back with tests
Resolves the GPT-4.1 cross-review FIX items on the §3.3.2 CI apply/verify guard:
- Symlink-escape (Medium-High): reject any candidate diff that introduces a
  symlink (git mode 120000). A symlink can redirect a later in-diff write into a
  denied path that textual canonicalization cannot see; auto-built diffs have no
  legitimate symlinks, so this fails closed (exit 7).
- Diff-parse robustness (Medium): decode the diff as strict UTF-8 and fail closed
  (exit 8) instead of errors='replace', closing homoglyph/encoding evasion.
- Declared-scope canonicalization (Medium): drop parent-escaping scope globs so a
  malformed scope can only shrink coverage, never widen it past repo root.
- Egress allowlist (Low-Med): explicit DEPLOY marker to parameterize the
  build-test registries per target repo before enabling.

Backs the gate's correctness claim with a committed, runnable suite
(tests/test_ci_gate_workflow.py) that extracts the inline guard from the YAML and
exercises good + adversarial diffs (clean, hash mismatch, workflow delete,
copy-into-denied, symlink, non-UTF-8, out-of-scope, unscoped, escaping scope).
Corrects the README "Tests" section that claimed coverage that did not exist.
Full suite: 557 passed, 1 skipped; ruff clean.
2026-06-17 15:16:12 -04:00
3c29ce3fdb Fix verified P1 findings: denylist bypasses, CAS concurrency, operator CLI
Resolves three execution-proven verifier findings from the scaffold review.
Full suite: 548 passed, 1 skipped (stable across repeated runs); ruff clean.

builders denylist (§3.3.2 #2): scan was +++-only and missed header-only
sections. Now section-driven off `diff --git a/<src> b/<dest>`, catching the 4
proven bypasses — delete of a denied path, mode-change-only, `copy to` a denied
path, out-of-scope delete (regression tests for each).

§3.3.1 compare-and-set concurrency: BEGIN IMMEDIATE moved inside guarded retry;
each CAS now runs on its own connection (shared sqlite3.Connection cannot hold
two transactions, and is unsafe for concurrent use even for reads). connect()
stashes the db path on a Connection subclass so the path is derived by a
thread-safe attribute read, not a PRAGMA on the shared conn; busy_timeout set
before the WAL pragma. Added shared-connection concurrent regression tests
(distinct + same question) — previously raised "transaction within a
transaction".

operator CLI (run-team.py): added the design-named re-deliver and force-resume
verbs (were missing); audit now records the attempt BEFORE the mutation and the
outcome after, so a ledger mutation can never land without a trail; main()
catches OSError instead of leaving an uncaught traceback on audit-write failure.
2026-06-17 15:16:12 -04:00
15a416d31a Add Plane-2 leaf scaffold (pipeline graph, nodes, HITL, transports, CI)
Consolidates the 18 leaf modules from the r720-plane2-scaffold workflow onto
the foundation commit. Full suite: 535 passed, 1 skipped; ruff + format clean.

Built (pre-deployment scaffold only — nothing provisioned/enabled):
- LangGraph pipeline graph.py (INTAKE->CLARIFY->PLAN, interrupt()/resume, checkpointer-injectable)
- nodes: clarifier (98% gate), planner, review_loop (GPT-4.1), builders->candidate diff, verifier
- §3.3.1 HITL: ledger ops, resume_worker, deadline_timer, recovery sweep, responder
- transports: slack / github / claude_code adapters
- ci_gate (pure-code pass/fail), operator_cli, run-team.py entry, P1 sim harness
- ci/agent-team-apply-verify.yml (split untrusted/privileged jobs) — authored, disabled

KNOWN OPEN FINDINGS (verifier/cross-review, not yet fixed — see follow-up):
- builders denylist: 4 execution-proven bypasses (delete, mode-change, copy-to, out-of-scope delete)
- §3.3.1 CAS: BEGIN IMMEDIATE outside try/except; shared-connection txn nesting unsafe under concurrency
- operator_cli: missing re-deliver/force-resume; audit-after-mutate ordering gap
- ci yaml: GPT-4.1 cross-review PASS w/ 4 FIX items (symlink path escape, etc.)
- P1 sim harness models the ledger layer, not real LangGraph interrupt/resume; P1 exit criteria not yet truly proven

Deploy-gated (NOT done): IAM/step-ca/Roles Anywhere/confluence-bot provisioning,
/sh-security-review sign-off, live Slack/CI, rsync, live dry-runs, Adam approval.
2026-06-17 15:16:12 -04:00
dc2da449fd Plane 2 foundation: interfaces, SQLite schemas, state-store, billing seam 2026-06-17 15:16:12 -04:00
Adam Moussa
c7661460e9
Merge pull request #6 from amoussa1229/feature/security-review-two-tier-auto-discovery
Finalize security-review: repo-sourced hooks, two-tier nightly auto-discovery
2026-06-17 15:03:15 -04:00
c6ecc621be Prune generated/vendored trees from the scanners
cfn-lint, semgrep, and checkov were scanning synthesized/vendored output
(cdk.out, node_modules, .venv/venv, .aws-sam, dist, build). On CDK repos this
explodes the find/xargs arg list and stalls the scan, and flagging synthesized
templates is wrong. Prune those trees in the cfn-lint find, and pass
--exclude / --skip-path to semgrep / checkov.
2026-06-17 14:55:41 -04:00
dbe2f8c186 Raise nightly agentic budget $20 -> $120 for full per-night coverage
First-run data (2026-06-17) showed the $20 ceiling covered only the
canary + 5 of ~22 scannable repos before pausing the rotation, leaving
16 repos un-deep-scanned that night. Raise TOTAL_BUDGET_USD default to
$120 so every repo gets a deep agentic pass each night (~22 x ~$5 +
canary, with headroom). Spend draws on the Max subscription pool; the
per-target cap ($12) and round-robin rotation are unchanged, so this is
a ceiling raise, not a per-repo cost change. Updates README, DEPLOY, and
the systemd Environment example to match.
2026-06-17 13:18:46 -04:00
15a16f8b88 Tune nightly defaults from first-run data
First full VM run: canary recall 18 with the expanded Node/.NET corpus, and a real
agentic repo cost ~$3.50 (vs the $1.4 testbed). Raise CANARY_FLOOR 10->14 (catches a
language-blindness recall collapse to ~9 while keeping margin under 18) and MAX_CYCLE_NIGHTS
4->6 (at ~4-6 agentic repos/night a full 22-repo rotation takes ~4-5 nights; 4 would
false-fire the coverage alarm). Both stay env-overridable and re-tunable as data accrues.
2026-06-16 18:02:57 -04:00
f4bb2bce8a Make scan_scanners return 0 so a passing repo doesn't trip set -e
scan_scanners communicates results via globals (T1_BLOCK/T1_CRIT/T1_HIGH); its last
statement was a bare [ $rc -eq 1 ] && T1_BLOCK=1. On a PASS (rc=0) that test is false,
so the function returned non-zero and set -e killed the whole sweep at the first passing
repo in tier 1 (right after the unbound-variable fix let it get that far). Add an explicit
return 0. Audited the rest of the tier1/tier2/summary path; scan_agentic and the others
already end on a zero-status command.
2026-06-16 16:43:35 -04:00
6d65c54b58 Fix unbound-variable crash in the nightly sweep tier-1 loop
scan_scanners referenced ${slug} inside the SAME local statement that defines it
(local target=... slug=$2 result_json=...${slug}...). bash expands the local's
arguments before the builtin assigns them, so under set -u ${slug} is unbound and
the sweep died right after the canary, before tier 1 ever ran. Split the local so
slug exists first. Fix the same latent self-reference in mirror_repo (dir=...$name),
which only worked by accident because the discovery loop left a global $name.
2026-06-16 16:00:21 -04:00
86ad29dcc2 Pin direct dependencies to exact versions
requirements.txt used loose >= ranges; pin the 7 direct deps to the known-good installed
versions (Python 3.12.13) for a reproducible venv.
2026-06-16 15:55:01 -04:00
028c844c86 Move the May handoff doc under docs/
De-clutter the repo root; HANDOFF-2026-05-15.md now lives in docs/.
2026-06-16 15:55:01 -04:00
572ae3ca41 Move orchestrator gitleaks suppression out of repo history
Per the machine-level-suppressions policy, the .env.example FP suppression now lives at
~/.config/sea-haven/security-review/orchestrator/suppressions.json (resolved first by the
hooks), not a committed .security-review/suppressions.json. Gate still passes via the
machine-level file.
2026-06-16 15:55:01 -04:00
80d5391785 Document the security-review subsystem in the root README
The root README covered only the router and omitted the security-review/ subsystem
entirely (Path A skill, review.sh gate, Path B nightly sweep, global hooks). Add a
Security Review section summarizing both paths and linking the subsystem README +
DEPLOY-R720 runbook.
2026-06-16 15:55:01 -04:00
c217c5656d Add machine-level suppressions to the repo-sourced hooks
The live global pre-push hook was hand-edited to resolve suppressions from a
machine-level file (${SH_SECURITY_SUPPRESSIONS_DIR:-~/.config/sea-haven/security-review}/
<repo-basename>/suppressions.json) kept out of repo history, falling back to a
repo-local .security-review/suppressions.json. The repo-sourced hooks lacked it, so
install-hooks.sh --global would overwrite the live hook and lose the feature.

Port the prefer-machine/fallback-repo-local block into hooks/pre-push, align
hooks/pre-commit to the same (else a machine-suppressed finding passes at push but
blocks at commit), and document the path + SH_SECURITY_SUPPRESSIONS_DIR override +
basename-collision caveat in the README.
2026-06-16 15:33:43 -04:00
f4dd72ced9 Add headless detector fan-out + proof-or-kill verifier runner
run_headless.py is the Path B engine the nightly sweep calls: the 6 fresh-context
detectors + proof-or-kill verifier from /sh-security-review, run unattended via the
Claude Agent SDK on subscription OAuth (pops ANTHROPIC_API_KEY so the API key can't
silently win). Read-only tools, hermetic, per-call + total budget caps, fails toward
over-reporting. Emits the finding schema that review.sh --agent-findings consumes.
2026-06-16 15:00:10 -04:00