Repository navigation
M4 cockpit/background contract fixes, approval-scope honesty, and main CI Lore gate - #100
Merged
Merged
Conversation
Unmet acceptance criteria in the M4 operator-cockpit and background-lifecycle specs, schedulable under the DR-006 carve-out (dr-006-owner-decision-2026-06-22.md:35): - U-P1-9: cockpit memory/review/skill failures report zeros silently; model_route is hard-coded None - U-P1-10: background runs and orphans are not shown in the cockpit - U-P1-11: repeated stop rewrites stopped_at; run_id-less dead records are never marked orphaned Action: U-P1-9 Constraint: register rows and counts only Tested: validate_docs_consistency; docs regeneration Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
The `t` approval choice grants every workspace path for the session but its confirmation says "current directory", and the grant matcher falls back to `*` for a rejected (out-of-workspace) path instead of failing closed. Workspace containment already blocks those writes; the matcher change is defense in depth. Action: G-P1-9 Constraint: register row and counts only Tested: validate_docs_consistency; docs regeneration Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
Re-verified 2026-10-27: - TASK-DD2-006, TASK-DD2-009, TICKET-15: Complete (plan status was stale) - TASK-DD2-011, TASK-DD2-012: partial, held under DR-006 (index said Fixed) - TASK-DD2-004: in progress as G-P1-9 (index said Fixed) - TICKET-16 Phase 2: partial; observations are not rehydrated on resume and the plan requires human review (index said Fixed) Action: G-P1-9 Constraint: status text only; canonical labels per risk-issue-roadmap-workflow.md Tested: validate_docs_consistency (ticket index evidence coverage still verified); tests/test_docs_consistency.py Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
main CI has been red after every GitHub-UI merge (#96, #97, #98): on a push event the Lore-trailer gate read github.sha, the generated "Merge pull request" commit, which never carries Constraint/Tested/Confidence. The pull_request path already resolves to the PR head for the same reason. For a pushed merge commit, check its second parent (the merged PR head, which passed the gate on the PR). Single-parent pushes, including web-UI edits, are still checked on their own message. Simulated with the real history: 34b9643 (#99 merge) -> fc7dec8 and bf21c9e (#98 merge) -> afe37a9 both pass .githooks/commit-msg; the other cause of red main, the telemetry test (run 893), was fixed in #97. Action: G-P2-21 Gate: governance-gap (CI must evaluate the authored commit; red main hides real failures) Constraint: one workflow step; no gate weakened; merge commits only Tested: workflow YAML parses; tests/test_ci_governance_flow.py and workflow tests 79 passed; shell resolution simulated on merges 34b9643 and bf21c9e Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
…lent defaults build_control_cockpit silently substituted zeros/None when the memory, review, or skill source failed, so a broken memory load showed up as "total_entries: 0" (false data) with nothing in cockpit.errors and no log. Those three blocks now log via logger.exception and append a "<source> load failed" entry to errors, matching the run-context blocks. The fallback values are kept so the JSON shape stays stable. model_route was hard-coded to None. It now reads the latest run's model_route audit event (the same event run_evidence.extract_routes reads) and sets provider/model/source/reason/estimated_cost_cents. A run with no route yields None with no error; a read failure logs and reports "model route load failed". Action: U-P1-9 Gate: owner-override (co-maintainer dogfood; DR-006 M4 operator-cockpit carve-out, dr-006-owner-decision-2026-06-22.md:35) Constraint: Edited only the model-route, memory, review and skill regions of build_control_cockpit; no background-run code, no reordering of existing blocks. Review block fallback stays None (its review_ids field is never populated by the goal dict, so the failure path is not reachable from a test and is left structurally identical). Tested: pytest tests/test_control_cockpit.py tests/acceptance/test_cockpit_snapshot_flow.py tests/test_cockpit_acceptance_spec.py tests/test_silent_exception_cleanup.py -> 50 passed (new: memory/skill failure logged+reported, model route from latest run, no-route None, route read failure reported). All gates in gates.md exit 0. Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
The control cockpit now carries a `background` section built from
BackgroundRunStore (readonly) list(): running_count, orphaned_count and
up to 10 newest-first items {background_id, run_id, alive, orphaned,
liveness_stale}. The TUI [Control Cockpit] panel renders
"Background: N running, M orphaned" beside Undo/Last run. A store failure
records "background runs load failed" and renders "Background: unknown".
The `background list` TTY table gains Orphaned and Liveness Stale columns;
JSON output is unchanged.
Action: U-P1-10
Gate: owner-override (co-maintainer dogfood; DR-006 M4 operator-cockpit carve-out, dr-006-owner-decision-2026-06-22.md:35)
Constraint: Snapshot schema v1 top-level keys untouched; the new field sits inside the control section via the existing asdict() path (additive). Memory/review/skill/model_route regions of build_control_cockpit not modified. No push.
Tested: tests/test_cockpit_background.py (5 new, failed before the change with AttributeError, pass after); tests/test_control_cockpit.py, tests/test_cockpit_acceptance_spec.py, tests/acceptance/test_cockpit_snapshot_flow.py, tests/test_background_*.py, tests/tui/ -> 74 passed. Gates: check_public_docstrings, audit_config_access (68), check_complexity (62<=99), check_any_count (2176<=2177), ruff check, ruff format --check, mypy, audit_test_quality severe/untyped, check_test_assertion_regression, check_god_modules (18 exemptions) all exit 0.
Confidence: high
Roadmap-Status: unchanged
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
…d runs orphaned BackgroundRunStore.stop() rewrote stopped_at and stop_signal on every call, so a second stop replaced the first stop's record and could re-signal state. A repeated stop now returns the existing terminal record unchanged without sending any signal (BG-001 spec §3.6). Orphan derivation returned early when a record had no run_id, so a background process that died without ever writing its run_id was never marked orphaned. A dead, not-stopped record with a non-zero or unknown exit and no run_id is now marked orphaned (BG-001 spec §3.3). Live processes are never marked orphaned. Derived keys (alive, orphaned) are no longer persisted, so stopping an orphaned record does not store a stale orphan marker. Action: U-P1-11 Gate: owner-override (co-maintainer dogfood; DR-006 M4 background-lifecycle carve-out, dr-006-owner-decision-2026-06-22.md:35) Constraint: First-stop semantics unchanged (dead-process first stop still records SIGTERM, pinned by tests/lifecycle); no cockpit.py edits; no push. Tested: pytest tests/test_background_run.py tests/test_background_orphan_marker.py tests/lifecycle/ tests/acceptance/test_background_attach_resume_notify_flow.py tests/acceptance/test_cloud_background_parity_flow.py -> 60 passed, 1 skipped; new tests failed before fix (3 orphan/stop cases) and pass after; all pre-commit gates exit 0. Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
…l closed on rejected paths Answering "t" (always for this tool) at an approval prompt registers a session grant with path_globs=['*'], which matches every path in the workspace for 8h. Three confirmation messages still said "current directory", understating the grant to the operator. They now say "all paths in this workspace, this session, 8h". _path_matches also let a '*' grant match a path argument that was present but rejected by _normalize_and_validate_path (absolute paths outside the workspace, ../ traversal). The rejected value left path_value as None and the function fell back to "any '*' pattern matches", so such calls were covered by the grant. It now returns False when a path key was supplied and none validated. The '*' fallback is kept only when no path argument is present, so tool-scoped grants for tools without a path still work. Defense in depth, not a live bypass: workspace containment in teaagent/approval/manager.py already blocks destructive writes outside the workspace. This change makes the grant matcher agree with that. Constraint: no change to grant storage, TTL, or the '*' semantics for tools without a path argument. Empty-string path values now count as a supplied path key, so a '*' grant no longer covers them (previously it did); non-'*' grants are unaffected. Tested: tests/test_approval_grant_scope.py (new, 7 tests) fails 5 before the change and passes after; tests/acceptance/test_approval_root_cli_flow.py, tests/integration/test_destructive_approval_lifecycle.py, tests/approval/, tests/test_ergonomics.py, tests/test_tui.py -k approv, tests/test_smart_hitl.py, tests/test_policy.py all pass. tests/test_hybrid_approval_queue_performance.py::test_large_scale_queue_performance fails on a wall-clock budget (24-27s vs 15s) on this loaded machine; it exercises the subagent queue, not grant matching. All gates in gates.md exit 0. Action: G-P1-9 Gate: governance-gap (approval scope shown to the user must match the grant; TASK-DD2-004) Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
- action register: U-P1-9, U-P1-10, U-P1-11 and G-P1-9 done; summary recounted (74 done, G-P2-21 in progress) - TASK-DD2-004: Complete via G-P1-9; ticket index row updated - roadmap-status: dated entry for the four fixes and the main-CI merge fix, plus what stays unscheduled (TICKET-16 Phase 2 human review, the cockpit review section's dead `review_ids`, the background event taxonomy as an ADR-0032 schema change) Action: G-P1-9 Constraint: docs and generated files only Tested: validate_docs_consistency; docs/okf/aging/inventory/roadmap/acceptance-count tests 102 passed Confidence: high Roadmap-Status: updated with one dated 2026-10-27 entry; no horizon status moved Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
build_control_cockpit read cockpit.goal['review_ids'], but the goal dict
never carries that key and nothing in production writes GoalRecord.review_ids
or calls record_review_closed. The section therefore always reported
{review_ids_count: 0, latest_review_status: 'unknown'}, which reads as real
data ("0 reviews") when no review source was consulted.
Decision: option (b). No cheap recorded source exists for the latest run's
review status (run_review.review_run is an on-demand report, not a stored
record; review_closed has no production caller). cockpit.review is now None
("unavailable") and the field is kept. The TUI state panel renders None as
"Review: unavailable" instead of printing nothing.
Action: U-P1-14
Gate: owner-override (co-maintainer dogfood; DR-006 M4 operator-cockpit carve-out, dr-006-owner-decision-2026-06-22.md:35)
Constraint: Did not wire a review source (no recorded review event for a run exists to read); goal.review_ids is left as stored data and is not surfaced in the cockpit. Undo/background regions of cockpit.py untouched.
Tested: pytest tests/test_cockpit_review_section.py (2 new, failed before fix, pass after); tests/test_control_cockpit.py tests/test_cockpit.py tests/test_cockpit_run_status.py tests/test_cockpit_acceptance_spec.py tests/acceptance/test_cockpit_snapshot_flow.py tests/acceptance/test_daily_cockpit_parity_flow.py tests/tui/ -> 71 passed; all gates in gates.md exit 0; check_test_assertion_regression reports no weakening (assertion count preserved)
Confidence: high
Roadmap-Status: unchanged
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
Implements the four acceptance tests named in the operator cockpit contract (docs/specs/operator-cockpit-contract-2026-06-01.md) in a new tests/test_cockpit_contract.py: single source, shows blocked, no clear screen, and recoverable matches undo journal. The cockpit now carries undo_command, the exact command summarize_run produces for the latest run with an undo journal. It is set only when undo is available or partial, and the TUI Undo line renders it. Action: U-P1-12 Gate: owner-override (co-maintainer dogfood; DR-006 M4 operator-cockpit carve-out, dr-006-owner-decision-2026-06-22.md:35) Constraint: blocked_count is left hardcoded at 0 and the pending approval queue stays the blocked signal; defining blocked versus pending is a product decision, not changed here. The dashboard surface does not exist in this codebase and is not tested. Tested: pytest tests/test_cockpit_contract.py tests/test_control_cockpit.py tests/test_cockpit_acceptance_spec.py tests/acceptance/test_cockpit_snapshot_flow.py tests/acceptance/test_daily_cockpit_parity_flow.py tests/lifecycle/test_background_lifecycle_spec.py tests/test_cockpit.py tests/test_cockpit_run_status.py tests/test_silent_exception_cleanup.py tests/test_tui.py tests/tui/ -> all pass; all gates in gates.md exit 0 Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
Background records exposed process liveness (alive, liveness_stale, orphaned) but never the run outcome, so an operator could not tell a completed run from a failed or cancelled one without reading the audit log. BG-001 section 3.2 requires liveness, outcome and staleness to stay distinct and all be surfaced. BackgroundRunStore now derives run_outcome on every get/list from the last terminal audit event of the run: run_completed -> completed, run_failed -> failed (or cancelled when the message is the RunCancelledError text), run_paused -> pending_approval (the BG-001 §3.2 vocabulary), run_cancelled -> cancelled. A run with no terminal event is running while its process is alive and unknown otherwise; a record without a run_id is unknown. run_outcome joins alive and orphaned in the derived-key set and is stripped before any record write, so it is never persisted. The background list TTY table gains an Outcome column; JSON output gains the key (additive). build_agent_run_command also forwarded only the deprecated --approve-call-id, so --approve-scoped (the flag agent run actually consumes) never reached a background child. It is now forwarded, with a test asserting the child argv carries the parent's approval flags. Constraint: teaagent/cockpit.py untouched (another agent is editing it). Only the derived outcome is added; no change to orphan semantics or the audit taxonomy. No resume/no-re-execution test added: an existing suspension fixture with a checkpointed scoped approval was not available within the file scope. Tested: pytest tests/test_background_run_outcome.py (10 new tests: 10 failed before the change, all pass after; the guard test that run_outcome is never persisted passes before and after); pytest tests/test_background_*.py tests/lifecycle/ tests/acceptance/ -k "background or lifecycle or parity or outcome" (116 passed, 1 skipped); tests/test_cockpit*.py and test_ergonomics.py (102 passed across the background/cockpit set); all pre-commit gates exit 0. Confidence: high Roadmap-Status: unchanged Action: U-P1-13 Gate: owner-override (co-maintainer dogfood; DR-006 M4 background-lifecycle carve-out, dr-006-owner-decision-2026-06-22.md:35) Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
approval.blocked_count was hard-coded to 0, breaking the cockpit contract's "blocked is loud" rule; it now counts distinct runs with a pending approval. A failed approval-queue load is listed in errors instead of silently reporting zero. Action: U-P1-15 Gate: owner-override (DR-006 M4 cockpit carve-out, dr-006-owner-decision-2026-06-22.md:35) Constraint: no change to approval policy or the pending-approval store Tested: tests/test_cockpit_contract.py (blocked_count failed before the fix; new failure-path test); cockpit tests 53 passed Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
Adds the U-P1-12 (contract tests, undo_command), U-P1-13 (run_outcome, --approve-scoped forwarding), U-P1-14 (review unavailable) and U-P1-15 (blocked_count) rows to the action register, recounted from the rows (P1 33, total 83, done 78), and a dated roadmap-status entry. Generated docs regenerated. Action: U-P1-15 Gate: owner-override (DR-006 M4 cockpit carve-out, dr-006-owner-decision-2026-06-22.md:35) Constraint: ledger update only; no horizon or milestone status moved Tested: validate_docs_consistency.py passed; register totals recounted from ID rows Confidence: high Roadmap-Status: updated 2026-10-27 cockpit contract round entry (no horizon status moved) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
The cockpit background items exposed process liveness (alive, orphaned, liveness_stale) but dropped run_outcome, which BackgroundRunStore already derives from the run's audit log. BG-001 section 3.2 requires liveness, outcome and staleness to be rendered as distinct facts, so each item now carries run_outcome alongside them. Action: U-P1-16 Gate: owner-override (DR-006 M4 cockpit carve-out, dr-006-owner-decision-2026-06-22.md:35) Constraint: cockpit output only; background_run derivation unchanged Tested: python -m pytest -q tests/test_cockpit_background.py::test_cockpit_background_item_surfaces_run_outcome failed before the fix (KeyError 'run_outcome'); after the fix python -m pytest -q tests/test_cockpit_background.py tests/test_cockpit_contract.py tests/test_control_cockpit.py -> 40 passed; ruff check and ruff format --check clean; mypy teaagent/cockpit.py tests/test_cockpit_background.py --explicit-package-bases -> no issues Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
A failed _refresh_control_cockpit or _refresh_cockpit_state reset its attribute to None, so one transient failure wiped the [Control Cockpit] panel. Both except branches now keep the debug log and leave the previous state in place. The attributes are already initialized to None in __init__, so a first-ever failure still yields None. Action: U-P1-18 Gate: owner-override (DR-006 M4 cockpit carve-out, dr-006-owner-decision-2026-06-22.md:35) Constraint: refresh triggers and cockpit content unchanged Tested: python -m pytest -q tests/test_tui_cockpit_refresh_keeps_state.py tests/test_control_cockpit.py tests/test_tui*.py -> 326 passed. Before the fix the two regression tests (control cockpit and cockpit state) failed with the attribute reset to None; the first-failure test passes both before and after. ruff check and ruff format --check clean; mypy --explicit-package-bases clean; scripts/audit_test_quality.py --fail-on untyped exit 0. tests/test_cockpit_contract.py does not exist in this worktree, so it was not run. Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
When another waiter had already reaped the child, any terminal audit event (including run_failed and run_cancelled) filled a missing exit_code with 0, so a failed run read as a clean exit. The 0 stand-in is now used only when the last terminal event is run_completed, it is marked exit_code_derived, and it is never written to the record file (stop() used to persist it). Action: U-P1-17 Gate: owner-override (DR-006 M4 background-lifecycle carve-out, dr-006-owner-decision-2026-06-22.md:35) Constraint: no new supervisor; no audit-schema change; exit-code reaping unchanged Tested: tests/test_background_exit_code_fallback.py (4 tests, all failed before the fix); tests/test_background_*.py, test_cockpit_background.py, tests/lifecycle: 81 passed, 1 skipped Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
The --git-sandbox help and docs/api said the flag opts in to an isolated git branch. Runtime enables the sandbox automatically in any git repository (prompted when interactive, automatic when non-interactive or git_sandbox_consent=always), and nothing reads the flag. The help and the API docs now say the flag has no effect and describe the real default. Flag behavior is unchanged; honoring or removing it is left for human review. Action: U-P1-19 Gate: governance-gap (help claimed opt-in for the rollback sandbox while runtime auto-enables it; TASK-DD2-005 AC) Constraint: flag kept and runtime behavior unchanged; honoring or removing --git-sandbox left for human review Tested: new tests/test_git_sandbox_help_honesty.py failed first (AssertionError: old help "Run agent task in a git sandbox branch..."), then passed after the help change (1 passed). `pytest -q tests -k "parser or help or cli_api"`: 70 passed, 6843 deselected. ruff check and ruff format --check on changed .py files: clean. mypy --explicit-package-bases on changed .py files: no issues. `python scripts/audit_test_quality.py --fail-on untyped`: exit 0. `python scripts/validate_docs_consistency.py`: passed. Docs regeneration chain run in the specified order. Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
…ow-ups Adds action-register rows for U-P1-16 (cockpit run_outcome), U-P1-17 (exit-code fallback), U-P1-18 (TUI refresh keeps state) and U-P1-19 (git-sandbox help honesty), recounted from the rows (P1 37, total 87, done 82), plus a dated roadmap-status entry naming what stays open. Action: U-P1-19 Gate: governance-gap (ledger for the fixes above; no new behavior) Constraint: ledger update only; no horizon or milestone status moved Tested: validate_docs_consistency.py passed; register totals recounted from ID rows Confidence: high Roadmap-Status: updated 2026-10-27 cockpit and background follow-ups entry (no horizon status moved) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
The entry called the CLI cockpit budget a placeholder. The snapshot labels its cost unavailable rather than implying a value, the contract's "fake" budget was the TUI's (now real), and Q1-Q4 coverage is the owner walk-through's call per the acceptance spec amendment. Action: U-P1-19 Gate: governance-gap (correct a ledger claim contradicted by the spec) Constraint: ledger wording only; no code or status change Tested: validate_docs_consistency.py passed; claim checked against operator-cockpit contract and acceptance spec Confidence: high Roadmap-Status: updated 2026-10-27 cockpit and background follow-ups entry wording (no horizon status moved) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
johnteee
pushed a commit
that referenced
this pull request
Oct 27, 2026
pip-audit on main failed after the PR #100 merge: msgpack 1.2.1 carries CVE-2026-114613, fixed in 1.2.3. The lockfile now resolves 1.2.4 and the declared floor is raised to >=1.2.3 so unlocked installs cannot pick the vulnerable release. Action: S-P1-5 Gate: governance-gap (security: known-vulnerable dependency failing the pip-audit gate on main) Constraint: only msgpack moved in uv.lock; no other dependency upgraded Tested: pip-audit on the uv export of the old lockfile reproduced the CVE; base and dev exports of the new lockfile report no known vulnerabilities Confidence: high Roadmap-Status: unchanged Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq
11 of 13 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Why
Sweeps of the M4 operator-cockpit and background-lifecycle specs, the open ticket plans and the backlog compared each against the code. They found surfaces reporting values that were never loaded: zero counts for failed sources, a hard-coded
blocked_count: 0, a review section that nothing feeds, and a fabricated exit code 0 for failed runs. They also found two real bugs and help text that contradicts the runtime. Separately,mainCI went red after every GitHub-UI merge, because the Lore-trailer gate read the generated merge commit.What
errors.model_routecomes from the latest run.stopconverges. A dead record with norun_idis orphaned.orphanedis derived and never persisted.undo_commandfield.run_outcome; a paused run readspending_approval.--approve-scoped; only the deprecated--approve-call-idwas forwarded.approval.blocked_countcounts runs with a pending approval (contract: "blocked is loud"). A failed queue load is listed inerrors.run_outcome(BG-001 §3.2).exit_codefalls back to 0 only when its last terminal event isrun_completed. Before, a failed run showed exit code 0. The fallback value is markedexit_code_derivedand never persisted.stop()used to write the derived 0 to disk.--git-sandboxhelp and API docs claimed the sandbox is opt-in. In fact the runtime enables it automatically in git repositories, and nothing reads the flag. This is a wording fix only: whether to keep or remove the flag stays with TASK-DD2-005 human review.main.roadmap-status.mdentries added.How
Every code change was test-first: each new assertion failed before its fix. The DR-006 gate is
owner-overrideunder the M4 cockpit/background carve-out (dr-006-owner-decision-2026-06-22.md:35). The CI fix and U-P1-19 aregovernance-gap. There is no audit-schema or event-taxonomy change: BACKGROUND_SUBMITTED/STOPPED stays owner-blocked (ADR-0032).Done
8815edd9: 6930 passed, 34 skipped, 0 failed.check_public_docstrings,audit_config_access --max 68,check_complexity --max 99,check_any_count --fail-on-increase, ruff check/format, mypy (teaagent + tests), bandit,audit_test_quality(severe and untyped),check_test_assertion_regression,check_god_modules,check_circular_imports,validate_event_spine_wiring,check_root_module_count.teaagent selftestandteaagent tool lintpass.validate_docs_consistencyandreport_docs_aging --checkpass.check_high_risk_pathspasses: no high-risk path is touched.Open, not in this PR (owner decisions):
cost_state: 'unavailable'rather than implying a real value.v0.1.1tag (G-P2-21 R0-8) needs a tag push, with owner approval.Action ID
Risk Class
Risk class: medium
Self-Review Checklist
General (all PRs)
ruff check+ruff format --checkpassmypy teaagent/reports 0 issuespython3 scripts/run_test_tier.py --tier smokepasses (full suite run instead)check_root_module_count.py≤ 184check_complexity.py≤ 99Documentation
🤖 Generated with Claude Code
https://claude.ai/code/session_01JE5Q9zqTjf7w2PzjzAC2Qq