feat(agent-team): P5 cross-plane loop — checker finding -> pipeline task (opt-in) #18
No reviewers
Labels
No labels
app
bug
ci
compliance
content
dependencies
docs
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
infra
invalid
javascript
needs-triage
python
question
tests
wontfix
No milestone
No project
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set.
Reference: adam/orchestrator#18
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feature/agent-team-p5-crossplane"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Closes the Plane-1 -> Plane-2 cross-plane loop (P5): a confirmed Plane-1 checker FINDING becomes a Plane-2 human-gated pipeline TASK, so a high/critical drift or CVE finding can flow into the SDLC pipeline as a remediation task.
This is Plane-2 P5 (intake side), NOT the Plane-1 fixer. It is buildable now against the existing checker finding schema and the existing Plane-2 intake; the live end-to-end close needs the checkers provisioned (gated), so this ships the wiring + tests and stays OPT-IN / inert by default.
Files
agent-team/agent_team/transport/checker_intake.py— new intake module (mirrorsgithub_intake).agent-team/tests/test_checker_intake.py— 28 hermetic unit tests.agent-team/run-team.py— newintake-checkersubcommand (opt-in), plus docstring entry.Mechanism reused
Calls the same committed coordinator intake entry
github_intakeuses:Coordinator.start_task(*, task_text: str, transport_name: str) -> str.Per the documented gotcha,
task_textis coordinator-side intake metadata (logged, sanitized) — the graph builds its own INTAKE seed and takes onlythread_id/transport. We do not reach past that contract.Selection + de-dup
status == "confirmed"ANDseverity >= threshold(defaulthigh). Unverified/suppressed/below-threshold dropped; the schema'sunverifiedseverity marker never meets a real threshold; unknown threshold rejected.id(checkers mint<repo>-<slug>), else a content-hash of checker+repo+title+severity. Identity recorded only afterstart_taskreturns (no silent drop on a failing intake — retryable next pass).github_intakediscipline — it does NOT survive a restart. A ledger-backed table of ingested finding ids (mirroringpending_questions) is the known FOLLOW-UP and is intentionally not shipped here.Untrusted-input hygiene
Checker findings carry repo-controlled strings (title, proof summary, repo name). Every such field is run through
_sanitize(newline/CR/tab/C0-control escaped to visible form, length-bounded) before it reaches the rendered task text OR the operator log — mirroring the coordinator'sstart_tasklog-injection hardening. Tests assert a forged multi-line title cannot inject a fake task/log line.Opt-in confirmation
Exposed ONLY as the
intake-checkerrun-team subcommand (likeintake-github). NOT wired intoCoordinator.serveor_cmd_serve— a test asserts neither references the checker intake. The always-on default path is unchanged.Verify
ruff check .clean,ruff format --check .clean.python -m pytest -q-> 823 passed (28 new intest_checker_intake.py).Constraints honoured
requirements.txtNOT touched (no new dep — stdlib only: hashlib/json/logging/pathlib).checker_coordinator.shNOT touched.For a reviewer to scrutinise
github(findings are about org repos). Confirm that's the desired clarifier channel.{..., "findings":[...]}matching the bash checker emit (bare array + dir-of-*.jsonalso accepted). A malformed report file raises rather than silently skipping.xargs: command line cannot be assembled, too longdue to nested.claude/worktrees/copies (environment artifact). Scoped to this PR's three files the scanners report 0 semgrep/gitleaks findings in changed code; the only BLOCK is the known machine-suppressed.env.examplegitleaks false-positive in an untouched file. Pushed with--no-verifyper task guidance.