Skip to content

Feat/proposal provenance and skill packages#10

Open
lamenting-hawthorn wants to merge 6 commits into
mainfrom
feat/proposal-provenance-and-skill-packages
Open

Feat/proposal provenance and skill packages#10
lamenting-hawthorn wants to merge 6 commits into
mainfrom
feat/proposal-provenance-and-skill-packages

Conversation

@lamenting-hawthorn

@lamenting-hawthorn lamenting-hawthorn commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added setup command to configure SkillLoop with policy management
    • Added status command to report current state and statistics
    • Added controller command group with run, history, and show subcommands for managing autonomous controller operations
    • Added persistence and retrieval of controller run history
  • Documentation

    • Updated CLI documentation with new command descriptions
    • Added loop engineering analysis and Hermes skills reference documentation

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds SQLite-backed controller_runs persistence to SkillLoopStore, wires dual-write into save_controller_report, and introduces setup, status, and controller CLI subcommands with argument validation and tests. Adds three Hermes loop-engineering skill reference documents (pre-loop-checklist, cron-job-workflows, goal-loop), a loop engineering analysis doc, updated CLI/README docs, and removes two stale documentation files.

Changes

Controller Run Persistence, CLI Commands, and Loop Engineering Docs

Layer / File(s) Summary
controller_runs SQLite table and store methods
skillloop/store.py, tests/test_store.py
SkillLoopStore.init() creates a controller_runs table; save_controller_run(), list_controller_runs(), and get_controller_run() (with LIKE-escaped prefix lookup) are added; unit tests cover field validation and wildcard-safe prefix search.
Controller report dual-write to store
skillloop/controller.py, tests/test_controller.py
save_controller_report serializes to a single payload, writes the JSON file, and calls store.save_controller_run(payload); the controller tick test gains assertions for store list and prefix-get.
setup / status / controller CLI commands
skillloop/cli.py, tests/test_cli.py
Adds _policy_path, _load_policy, _format_count helpers; implements cmd_setup, cmd_status, cmd_controller_run/history/show; extends the parser with new subcommand groups; four CLI tests cover valid flows, bound rejections, corrupt manifest, and non-positive limit.
Hermes loop-engineering skill reference docs
references/hermes-skills/README.md, references/hermes-skills/pre-loop-checklist/SKILL.md, references/hermes-skills/cron-job-workflows/SKILL.md, references/hermes-skills/goal-loop/SKILL.md
Adds installation README and three skill documents: pre-loop-checklist (Tier 1/2 gating, BUILD/FIX/SKIP verdict), cron-job-workflows (cron restrictions, STATE.md model, watchdog pattern, red flags), and goal-loop (maker/checker cron pattern, prompt template, self-cancellation, monitoring).
Analysis doc, CLI/README docs, removed docs, .gitignore
docs/analysis/loop-engineering-analysis.md, docs/cli.md, README.md, docs/next-steps.md, docs/training-integrations.md, .gitignore
Adds loop-engineering-analysis.md mapping Loop Engineering concepts to SkillLoop/Hermes; adds setup and controller sections to docs/cli.md and README.md; removes content from docs/next-steps.md and docs/training-integrations.md; ignores .worktrees/ and docs/HANDOFF.md.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CLI
  participant SkillLoopStore
  participant controller_tick

  rect rgba(70, 130, 180, 0.5)
    Note over User,SkillLoopStore: skillloop setup
    User->>CLI: setup --connect hermes --start
    CLI->>SkillLoopStore: init()
    CLI->>CLI: validate bounds, build SkillLoopPolicy
    CLI->>SkillLoopStore: write policy.json
    CLI->>controller_tick: controller_tick(store, policy)
    controller_tick->>SkillLoopStore: save_controller_run(payload)
    SkillLoopStore-->>controller_tick: run id
    controller_tick-->>CLI: ControllerRunReport
    CLI-->>User: policy written + tick summary
  end

  rect rgba(60, 179, 113, 0.5)
    Note over User,SkillLoopStore: skillloop controller show
    User->>CLI: controller show abc123
    CLI->>SkillLoopStore: get_controller_run("abc123")
    SkillLoopStore->>SkillLoopStore: exact match → LIKE prefix with escaped wildcards
    SkillLoopStore-->>CLI: decoded JSON payload
    CLI-->>User: JSON run report
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • lamenting-hawthorn/SkillLoop#9: Implements the same skillloop setup/status/controller CLI UX and SkillLoopStore SQLite controller-run persistence that this PR builds upon.

Poem

🐇 A rabbit hops through loops with glee,
State.md tracks each hop and spree,
The checker checks, the worker works,
The store persists (no wildcard quirks!),
setup, status, controller show
Now every run has somewhere to go! 🗄️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title refers to 'proposal provenance and skill packages', which directly aligns with the changes: added Hermes skill documentation, controller run persistence/provenance tracking, and related CLI commands.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/proposal-provenance-and-skill-packages

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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

@coderabbitai coderabbitai 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.

Actionable comments posted: 5

🧹 Nitpick comments (2)
tests/test_cli.py (1)

127-136: ⚡ Quick win

Add a corrupt-policy CLI regression test.

Given status now reports manifest parse errors, add a sibling test for malformed .skillloop/policy.json to ensure policy load failures return a clean CLI error path instead of a traceback.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_cli.py` around lines 127 - 136, Add a new test function similar to
test_cli_status_handles_corrupt_dataset_manifest to verify policy load error
handling. Create a corrupt .skillloop/policy.json file by creating the directory
structure and writing invalid JSON content, then call main with the status
command and verify it returns exit code 0 and outputs a clean error message
about the policy load failure (using capsys to capture output), ensuring the CLI
handles policy parsing errors gracefully without raising a traceback.
tests/test_store.py (1)

65-80: ⚡ Quick win

Add store-contract tests for invalid limit and empty run_id.

These controller-run tests are solid; add two small assertions to lock behavior for SkillLoopStore.list_controller_runs(limit=0/-1) and SkillLoopStore.get_controller_run("") once the API validation is added.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_store.py` around lines 65 - 80, Add validation assertions to the
test_store.py file to lock in expected behavior for SkillLoopStore API contract
validation. Following the pattern of
test_store_validates_controller_run_report_contract, add test assertions that
verify list_controller_runs raises ValueError when called with limit=0 or
limit=-1, and that get_controller_run raises ValueError when called with an
empty string run_id. These assertions should document the contract validation
behavior for invalid limit values and empty identifiers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/analysis/loop-engineering-analysis.md`:
- Around line 1-6: Verify the Addy Osmani source attribution in the opening
section. Confirm whether you are referencing the June 7, 2026 blog post on
addyosmani.com or a separate X post from June 8, 2026, and update the source
date and platform accordingly if needed. Replace or remove the stale engagement
metrics (836K views, 11.5K bookmarks, 4.8K likes) that are outdated as of June
16, 2026—either use relative descriptors like "widely shared" or add an explicit
timestamp indicating when the metrics were captured. Finally, verify the core
quote "Loop engineering is replacing yourself as the person who prompts the
agent. You design the system that does it instead." matches the exact wording
from the original source.

In `@skillloop/cli.py`:
- Around line 79-81: The current validation in cmd_setup only checks if
hermes_db exists using exists(), but this returns true for directories as well.
Replace the exists() check with is_file() on the hermes_db path object to ensure
the provided path is actually a file and not a directory, which will prevent
unclear runtime errors later.
- Around line 35-39: The SkillLoopPolicy.load(path) call in the _load_policy
function can throw exceptions when the policy file contains invalid JSON or
violates the schema, causing commands like status and controller run to crash.
Wrap the SkillLoopPolicy.load(path) call in a try-except block to catch any
exceptions thrown during loading, then raise a SystemExit with a descriptive
error message that includes the file path to provide clear context about which
policy file is malformed.

In `@skillloop/store.py`:
- Around line 202-208: Add validation in the list_controller_runs method to
reject non-positive limit values before they are used in the SQL query. When
limit is not None, check if it is less than or equal to zero and raise an
appropriate ValueError or similar exception with a clear error message. This
validation should occur immediately after the init() call and before
constructing the SQL query, ensuring that SQLite never receives a non-positive
LIMIT value.
- Around line 213-221: The get_controller_run method accepts an empty run_id
which results in a broad LIKE '%' database scan when no exact match is found.
Add validation at the start of the get_controller_run method to reject empty or
whitespace-only run_id values before any database operations, either by raising
an appropriate exception or returning early. This ensures strict lookup
semantics and prevents unintended broad prefix scans.

---

Nitpick comments:
In `@tests/test_cli.py`:
- Around line 127-136: Add a new test function similar to
test_cli_status_handles_corrupt_dataset_manifest to verify policy load error
handling. Create a corrupt .skillloop/policy.json file by creating the directory
structure and writing invalid JSON content, then call main with the status
command and verify it returns exit code 0 and outputs a clean error message
about the policy load failure (using capsys to capture output), ensuring the CLI
handles policy parsing errors gracefully without raising a traceback.

In `@tests/test_store.py`:
- Around line 65-80: Add validation assertions to the test_store.py file to lock
in expected behavior for SkillLoopStore API contract validation. Following the
pattern of test_store_validates_controller_run_report_contract, add test
assertions that verify list_controller_runs raises ValueError when called with
limit=0 or limit=-1, and that get_controller_run raises ValueError when called
with an empty string run_id. These assertions should document the contract
validation behavior for invalid limit values and empty identifiers.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cb3101b7-0091-4a73-8706-ca7440833b41

📥 Commits

Reviewing files that changed from the base of the PR and between d9b96a4 and 1e5bfc9.

📒 Files selected for processing (16)
  • .gitignore
  • README.md
  • docs/analysis/loop-engineering-analysis.md
  • docs/cli.md
  • docs/next-steps.md
  • docs/training-integrations.md
  • references/hermes-skills/README.md
  • references/hermes-skills/cron-job-workflows/SKILL.md
  • references/hermes-skills/goal-loop/SKILL.md
  • references/hermes-skills/pre-loop-checklist/SKILL.md
  • skillloop/cli.py
  • skillloop/controller.py
  • skillloop/store.py
  • tests/test_cli.py
  • tests/test_controller.py
  • tests/test_store.py
💤 Files with no reviewable changes (2)
  • docs/next-steps.md
  • docs/training-integrations.md

Comment on lines +1 to +6
# Deep Analysis: Addy Osmani's Loop Engineering vs SkillLoop/Hermes

**Source:** Addy Osmani (@addyosmani) on X, June 8, 2026. 836K views, 11.5K bookmarks, 4.8K likes.
**Core quote:** "Loop engineering is replacing yourself as the person who prompts the agent. You design the system that does it instead."

---

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

Addy Osmani loop engineering post June 2026

💡 Result:

In a blog post published on June 7, 2026, Addy Osmani introduced the term "Loop Engineering" to describe an emerging paradigm in working with AI coding agents [1][2]. The core concept is a shift from manual, one-time prompt engineering to designing automated, recursive systems—or "loops"—where an AI agent iterates toward a goal without continuous human intervention [1][3]. Osmani identified five key building blocks that constitute these loops [2][4]: 1. Automations: The "heartbeat" of the loop, consisting of scheduled tasks (like discovery or triage) and run-until-done primitives [1][2][4]. 2. Worktrees: Mechanisms (often based on git worktrees) that allow for isolated, parallel execution environments [2][4]. 3. Skills: Codified project knowledge (e.g., using a SKILL.md format) that prevents agents from re-deriving project conventions every cycle [2][4]. 4. Plugins/Connectors: Integrations (frequently based on MCP) that connect the loop to external systems, such as opening pull requests or updating tickets [2][4]. 5. Sub-agents: Specialized agents that separate execution from verification, addressing the challenge of agents potentially being too lenient when grading their own work [2][4]. Osmani noted that the highest-leverage skill for engineers is moving from "directly operating the agent" to designing the systems that govern the agent's behavior [2][3]. He observed that these capabilities are increasingly being integrated directly into tools like the Codex app and Claude Code [1][4]. Osmani also cautioned that while this approach offers significant automation potential, it is not inherently easier than prompt engineering and requires careful management of token costs and system observability [1][3].

Citations:


Verify the source and date for the Addy Osmani reference.

The document attributes analysis to Addy Osmani on X from June 8, 2026, but web search confirms a blog post was published June 7, 2026 (not June 8) on addyosmani.com. Clarify whether this analysis references the June 7 blog post or a separate X post from June 8, and update the source attribution accordingly.

The specific metrics (836K views, 11.5K bookmarks, 4.8K likes) are stale as of June 16, 2026. Either remove these numbers, replace with relative descriptors like "widely shared," or explicitly mark when the metrics were captured.

The core concept in your quote aligns with Osmani's framework (moving from directly operating the agent to designing systems that govern agent behavior), but verify the exact wording is accurate to the source.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/analysis/loop-engineering-analysis.md` around lines 1 - 6, Verify the
Addy Osmani source attribution in the opening section. Confirm whether you are
referencing the June 7, 2026 blog post on addyosmani.com or a separate X post
from June 8, 2026, and update the source date and platform accordingly if
needed. Replace or remove the stale engagement metrics (836K views, 11.5K
bookmarks, 4.8K likes) that are outdated as of June 16, 2026—either use relative
descriptors like "widely shared" or add an explicit timestamp indicating when
the metrics were captured. Finally, verify the core quote "Loop engineering is
replacing yourself as the person who prompts the agent. You design the system
that does it instead." matches the exact wording from the original source.

Comment thread skillloop/cli.py
Comment on lines +35 to +39
def _load_policy(store: SkillLoopStore) -> SkillLoopPolicy:
path = _policy_path(store)
if not path.exists():
return SkillLoopPolicy.default()
return SkillLoopPolicy.load(path)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Gracefully handle malformed policy files.

Line 39 can throw on invalid JSON/schema and currently crashes commands like status and controller run. Convert this into a clean SystemExit with file context.

Proposed fix
 def _load_policy(store: SkillLoopStore) -> SkillLoopPolicy:
     path = _policy_path(store)
     if not path.exists():
         return SkillLoopPolicy.default()
-    return SkillLoopPolicy.load(path)
+    try:
+        return SkillLoopPolicy.load(path)
+    except (OSError, ValueError, json.JSONDecodeError) as exc:
+        raise SystemExit(f"Failed to load policy at {path}: {exc}") from exc
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skillloop/cli.py` around lines 35 - 39, The SkillLoopPolicy.load(path) call
in the _load_policy function can throw exceptions when the policy file contains
invalid JSON or violates the schema, causing commands like status and controller
run to crash. Wrap the SkillLoopPolicy.load(path) call in a try-except block to
catch any exceptions thrown during loading, then raise a SystemExit with a
descriptive error message that includes the file path to provide clear context
about which policy file is malformed.

Comment thread skillloop/cli.py
Comment on lines +79 to +81
hermes_db = Path(args.db_path).expanduser().resolve()
if not hermes_db.exists():
raise SystemExit(f"Hermes state database not found: {hermes_db}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Validate --db-path is a file.

Line 80 only checks existence; directories pass and fail later with a less clear runtime error. Require is_file() in cmd_setup.

Proposed fix
     hermes_db = Path(args.db_path).expanduser().resolve()
-    if not hermes_db.exists():
-        raise SystemExit(f"Hermes state database not found: {hermes_db}")
+    if not hermes_db.exists() or not hermes_db.is_file():
+        raise SystemExit(f"Hermes state database file not found: {hermes_db}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
hermes_db = Path(args.db_path).expanduser().resolve()
if not hermes_db.exists():
raise SystemExit(f"Hermes state database not found: {hermes_db}")
hermes_db = Path(args.db_path).expanduser().resolve()
if not hermes_db.exists() or not hermes_db.is_file():
raise SystemExit(f"Hermes state database file not found: {hermes_db}")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skillloop/cli.py` around lines 79 - 81, The current validation in cmd_setup
only checks if hermes_db exists using exists(), but this returns true for
directories as well. Replace the exists() check with is_file() on the hermes_db
path object to ensure the provided path is actually a file and not a directory,
which will prevent unclear runtime errors later.

Comment thread skillloop/store.py
Comment on lines +202 to +208
def list_controller_runs(self, limit: int | None = None) -> list[dict]:
self.init()
query = "SELECT payload FROM controller_runs ORDER BY started_at DESC"
args: tuple[int, ...] = ()
if limit is not None:
query += " LIMIT ?"
args = (int(limit),)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Validate limit at the store boundary.

Line 207 currently applies SQL LIMIT to any integer. With SQLite, non-positive values can yield surprising results (including effectively unbounded reads), which bypasses caller intent. Reject limit <= 0 in SkillLoopStore.list_controller_runs.

Proposed fix
 def list_controller_runs(self, limit: int | None = None) -> list[dict]:
     self.init()
     query = "SELECT payload FROM controller_runs ORDER BY started_at DESC"
     args: tuple[int, ...] = ()
     if limit is not None:
+        limit = int(limit)
+        if limit <= 0:
+            raise ValueError("limit must be positive")
         query += " LIMIT ?"
-        args = (int(limit),)
+        args = (limit,)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def list_controller_runs(self, limit: int | None = None) -> list[dict]:
self.init()
query = "SELECT payload FROM controller_runs ORDER BY started_at DESC"
args: tuple[int, ...] = ()
if limit is not None:
query += " LIMIT ?"
args = (int(limit),)
def list_controller_runs(self, limit: int | None = None) -> list[dict]:
self.init()
query = "SELECT payload FROM controller_runs ORDER BY started_at DESC"
args: tuple[int, ...] = ()
if limit is not None:
limit = int(limit)
if limit <= 0:
raise ValueError("limit must be positive")
query += " LIMIT ?"
args = (limit,)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skillloop/store.py` around lines 202 - 208, Add validation in the
list_controller_runs method to reject non-positive limit values before they are
used in the SQL query. When limit is not None, check if it is less than or equal
to zero and raise an appropriate ValueError or similar exception with a clear
error message. This validation should occur immediately after the init() call
and before constructing the SQL query, ensuring that SQLite never receives a
non-positive LIMIT value.

Comment thread skillloop/store.py
Comment on lines +213 to +221
def get_controller_run(self, run_id: str) -> dict:
self.init()
with self._connect() as conn:
row = conn.execute("SELECT payload FROM controller_runs WHERE id = ?", (run_id,)).fetchone()
if row is None:
escaped_id = run_id.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")
rows = conn.execute(
"SELECT payload FROM controller_runs WHERE id LIKE ? ESCAPE '\\' ORDER BY started_at DESC",
(f"{escaped_id}%",),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reject empty run IDs before prefix lookup.

Line 218 turns an empty run_id into a broad LIKE '%' scan. Fail fast on empty IDs in SkillLoopStore.get_controller_run to keep lookup semantics strict and predictable.

Proposed fix
 def get_controller_run(self, run_id: str) -> dict:
     self.init()
+    if not str(run_id).strip():
+        raise ValueError("run_id must be non-empty")
     with self._connect() as conn:
         row = conn.execute("SELECT payload FROM controller_runs WHERE id = ?", (run_id,)).fetchone()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skillloop/store.py` around lines 213 - 221, The get_controller_run method
accepts an empty run_id which results in a broad LIKE '%' database scan when no
exact match is found. Add validation at the start of the get_controller_run
method to reject empty or whitespace-only run_id values before any database
operations, either by raising an appropriate exception or returning early. This
ensures strict lookup semantics and prevents unintended broad prefix scans.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1e5bfc9db1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread skillloop/cli.py
store = _store(args)
if args.limit is not None and args.limit <= 0:
raise SystemExit("--limit must be positive")
runs = store.list_controller_runs(limit=args.limit)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Backfill existing file-based controller history

On projects upgraded from the previous controller implementation, prior reports exist only as .skillloop/controller_runs/*.json because save_controller_report used to write just those files. This new history path reads only the new SQLite table, so controller history (and similarly status/show) reports no prior runs until another tick occurs, even though the report files are still present. Consider migrating or falling back to the JSON reports when the table is empty.

Useful? React with 👍 / 👎.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Cannot run autofix: This PR has merge conflicts.

Please resolve the conflicts with the base branch and try again.

Alternatively, use @coderabbitai resolve merge conflict to automatically resolve the conflicts.

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