Skip to content

feat: add policy-bounded self-improvement reviews - #3201

Merged
mabry1985 merged 2 commits into
mainfrom
feat/self-improvement-3069
Aug 27, 2026
Merged

feat: add policy-bounded self-improvement reviews#3201
mabry1985 merged 2 commits into
mainfrom
feat/self-improvement-3069

Conversation

@mabry1985

Copy link
Copy Markdown
Member

Summary

  • add an off-by-default unified self-improvement policy for persona, skills, and post-work distillation
  • enqueue bounded same-session reviews after achieved goals and closed tasks
  • enforce mode-derived tool fences, trusted provenance, private-store-only automatic skill writes, rollback archives, and runtime prerequisite warnings
  • add guarded skill update/delete support and durable persona mutation audit records

Safety

  • proposal mode cannot reach artifact writers
  • malformed policy values fail closed
  • automatic skill writes are blocked for flat shared stores
  • bundle inputs and agent self-config cannot enable the trust-bearing policy
  • destructive skill paths reject empty/colliding slugs and verify index mutations
  • scheduler wake prompts preserve slash-command dispatch

Validation

  • python scripts/gate.py — 5 checks passed; 6,682 passed, 15 skipped
  • post-rebase lint gate — 4 checks passed
  • post-rebase focused regression suite — 323 passed
  • steelman and adversarial blocker reviews completed

Refs #3069

@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 32 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e9db87e7-a9b2-4d18-a05e-b31c0b788a53

📥 Commits

Reviewing files that changed from the base of the PR and between 0c95e07 and 5715415.

📒 Files selected for processing (34)
  • changelog.d/3069.added.md
  • config/langgraph-config.example.yaml
  • docs/adr/0107-unified-self-improvement-policy.md
  • docs/adr/index.md
  • docs/reference/starter-tools.md
  • graph/agent.py
  • graph/config.py
  • graph/config_io.py
  • graph/goals/controller.py
  • graph/plugins/installer.py
  • graph/self_improvement.py
  • graph/settings_schema.py
  • graph/skills/authoring.py
  • graph/skills/index.py
  • graph/skills/loader.py
  • graph/subagents/config.py
  • operator_api/console_handlers.py
  • operator_api/routes.py
  • operator_api/subagents.py
  • plugins/docs/nav.json
  • scheduler/local.py
  • server/agent_init.py
  • server/chat.py
  • server/chat_commands.py
  • tests/test_config_roundtrip.py
  • tests/test_console_handlers.py
  • tests/test_dream_distill.py
  • tests/test_edit_soul_tool.py
  • tests/test_operator_api_routes.py
  • tests/test_plugin_installer.py
  • tests/test_scheduler_local.py
  • tests/test_self_config_tool.py
  • tests/test_self_improvement.py
  • tools/lg_tools.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mabry1985
mabry1985 marked this pull request as ready for review August 27, 2026 19:51

@protoreview protoreview Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QA panel review — PASS

code-review-structural · head 2f825e56ad17 · formal

The panel's brief could not be read from this round's report (no delimited brief block). The findings below are unaffected.

No findings — the review came back clean.

findings JSON (machine-readable)
[]

@protoreview protoreview Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Promoting the PASS verdict for head 2f825e56ad17: all checks terminal-green, zero unresolved review threads. (approve-on-green)

@mabry1985
mabry1985 force-pushed the feat/self-improvement-3069 branch from 2f825e5 to 6784f43 Compare August 27, 2026 20:24
protoreview[bot]
protoreview Bot previously requested changes Aug 27, 2026

@protoreview protoreview Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QA panel review — FAIL

code-review-structural · head 6784f43852a2 · formal

The PR adds self-improvement config fields and a task-close review dispatch. Overall risk is low-to-moderate: one startup-crash path from a YAML null, and one unguarded call that can turn a successful close into a 500. Fix first: add or {} to the four data.get("self_improvement", {}) calls in graph/config.py. The panel did not disagree on any finding; both were confirmed. Verification corrected finding 2's impact language — the task is closed in the store; the defect is that the API returns a 500 to the client, violating the "curation must never break task closure" contract upheld at the lg_tools.py call site. No structural pass was run; coverage is adequate since both touched files carry findings.

Findings

Severity Location Finding Verified
🟠 major graph/config.py:1919 If a user writes self_improvement: (bare key / YAML null) in their config, data.get("self_improvement", {}) returns None and the chained `.get("enabled",… confirmed
🟡 minor operator_api/routes.py:390 The dispatch_task_review call in _tasks_close is not wrapped in a separate try/except, unlike the identical call in tools/lg_tools.py which is guarded wi… confirmed
findings JSON (machine-readable)
[
  {
    "file": "graph/config.py",
    "line": 1919,
    "severity": "major",
    "category": "correctness",
    "claim": "If a user writes `self_improvement:` (bare key / YAML null) in their config, `data.get(\"self_improvement\", {})` returns `None` and the chained `.get(\"enabled\", ...)` raises `AttributeError`, crashing config load at startup.",
    "evidence": "The four new lines all use `data.get(\"self_improvement\", {})` without the `or {}` guard that every other nested-section pattern in this method uses (e.g. `soul = data.get(\"soul\", {}) or {}`). The PR's own test `test_soul_drift_defaults_when_section_absent_or_null` documents this failure mode: \"nested null isn't caught by the top-level normalizer, hence the `or {}`\".",
    "verdict": "confirmed",
    "note": "Verified in diff: all four lines use `data.get(\"self_improvement\", {}).get(...)` without `or {}`. A bare YAML key parses to None, and None.get() raises AttributeError. The PR's own test docstring confirms this failure mode. Minor overstatement: the `watches` section uses the same unguarded pattern, so 'every other' is slightly inaccurate, but the bug is real."
  },
  {
    "file": "operator_api/routes.py",
    "line": 390,
    "severity": "minor",
    "category": "correctness",
    "claim": "The `dispatch_task_review` call in `_tasks_close` is not wrapped in a separate try/except, unlike the identical call in `tools/lg_tools.py` which is guarded with the explicit contract 'curation must never break task closure'; if `dispatch_task_review` raises, the operator API returns a 500 to the client for a successful close.",
    "evidence": "operator_api/routes.py: `dispatch_task_review(issue, reason=req.reason or \"\")` \u2014 no try/except. Compare tools/lg_tools.py: `try: from graph.self_improvement import dispatch_task_review; dispatch_task_review(i, session_id=session_id, reason=reason) except Exception:  # noqa: BLE001 \u2014 curation must never break task closure`",
    "verdict": "confirmed",
    "note": "Verified in diff: the routes.py call has no separate try/except (it's inside the outer try that converts to 500), while lg_tools.py has the exact quoted guard. The inconsistency is real. However, 'the task is not closed' is inaccurate \u2014 task_svc.close succeeds before dispatch_task_review is called, so the task IS closed; the actual impact is the API returns 500 to the client for a successful operation."
  }
]

@mabry1985

Copy link
Copy Markdown
Member Author

Addressed both confirmed QA findings in 5715415c:

  • parse self_improvement: through an explicit null-safe section mapping, with a bare-section regression test
  • isolate operator task-close review dispatch so scheduling failures are logged but cannot turn a successful close into a 500, with a regression test

Local full gate: 5 checks passed; 6,721 passed, 15 skipped.

@protoreview protoreview Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QA panel review — PASS

code-review-structural · head 5715415c756d · formal

Both prior defects are confirmed fixed in the current head: the or {} guard in graph/config.py neutralises the bare-key AttributeError, and the try/except around dispatch_task_review in operator_api/routes.py matches the contract in lg_tools.py. All four LLM finders returned clean on this round, and the structural pass completed with no findings. No open items remain; the PR is ready to merge.

Prior requests

Prior finding Disposition Why
graph/config.py:1919 fixed the current head adds or {} after data.get("self_improvement", {}), so a bare self_improvement: key (YAML null) no longer propagates None into the chai…

No findings — the review came back clean.

findings JSON (machine-readable)
[]

@protoreview
protoreview Bot dismissed their stale review August 27, 2026 20:59

Superseded — a later head cleared the QA panel (see the newest verdict).

@protoreview protoreview Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Promoting the PASS verdict for head 5715415c756d: all checks terminal-green, zero unresolved review threads. (approve-on-green)

@mabry1985
mabry1985 merged commit 0081b22 into main Aug 27, 2026
17 checks passed
@mabry1985
mabry1985 deleted the feat/self-improvement-3069 branch August 27, 2026 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant