Skip to content

fix(kernel): persist agent skill & MCP-server assignments to agent.toml#6046

Merged
houko merged 4 commits into
librefang:mainfrom
DaBlitzStein:fix/persist-skills-mcp-to-toml
Jun 23, 2026
Merged

fix(kernel): persist agent skill & MCP-server assignments to agent.toml#6046
houko merged 4 commits into
librefang:mainfrom
DaBlitzStein:fix/persist-skills-mcp-to-toml

Conversation

@DaBlitzStein

Copy link
Copy Markdown
Contributor

Summary

Closes #6045.

Assigning a skill or MCP server to an agent via the dashboard/API (PUT /api/agents/{id}/skills / .../mcp_servers) persisted only to the SQLite blob, not to agent.toml. Because boot reconciliation treats the on-disk manifest as authoritative, the assignment returned 200, showed as assigned in the API, then was silently wiped on the next daemon restart.

Root cause

set_agent_skills and set_agent_mcp_servers (crates/librefang-kernel/src/kernel/agent_state.rs) update the in-memory registry and call save_agent (DB) but never call persist_manifest_to_disk. The sibling setters all do: set_agent_model, set_agent_channels, set_agent_schedule, set_agent_tool_filters (tools). Skills and MCP were the only two missing it — structurally identical otherwise, so this was an oversight.

On boot, boot.rs loads each agent from the substrate, reads its agent.toml, and when the projection differs overwrites the DB with the disk manifest ("Agent TOML on disk differs from DB, updating"). Anything written only to the DB is therefore lost.

Change

  • Add self.persist_manifest_to_disk(agent_id); to set_agent_skills and set_agent_mcp_servers, after the successful save_agent, mirroring the sibling setters.
  • Placed in the kernel setter (not the API route handler) so it survives the routes/agents.rsroutes/agents/ module split (refactor(api): split routes/agents.rs into per-concern modules #5975) and any future API refactor.

Verification

  • cargo clippy -p librefang-kernel --all-targets -- -D warnings — clean.
  • New regression test test_set_agent_skills_persists_allowlist_to_agent_toml (kernel lib): boots a kernel, installs a skill, spawns an agent with a known source_toml_path, calls set_agent_skills, and asserts the on-disk agent.toml contains the assigned skill. Passes (1 passed).

@github-actions github-actions Bot added size/M 50-249 lines changed area/docs Documentation and guides area/kernel Core kernel (scheduling, RBAC, workflows) and removed size/M 50-249 lines changed labels Jun 9, 2026
houko

This comment was marked as duplicate.

@github-actions github-actions Bot added has-conflicts PR has merge conflicts that need resolution ready-for-review PR is ready for maintainer review and removed has-conflicts PR has merge conflicts that need resolution ready-for-review PR is ready for maintainer review labels Jun 11, 2026
@DaBlitzStein
DaBlitzStein force-pushed the fix/persist-skills-mcp-to-toml branch from c0eee65 to a5fb487 Compare June 11, 2026 17:25
@github-actions github-actions Bot added ready-for-review PR is ready for maintainer review size/M 50-249 lines changed and removed has-conflicts PR has merge conflicts that need resolution labels Jun 11, 2026

@houko houko left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Two CLAUDE.md style violations to fix before merge.


1. CHANGELOG.md — four sentences packed onto one continuation line

CLAUDE.md is explicit: "CHANGELOG.md bullets — one sentence per line within a bullet."

The new fix(kernel) entry's continuation line contains four sentences on a single line.
Split into one sentence per line:

- **fix(kernel): persist per-agent skill & MCP-server assignments to `agent.toml` so they survive a restart** (#6045) (@DaBlitzStein).
  `set_agent_skills` and `set_agent_mcp_servers` wrote only the SQLite blob and never called `persist_manifest_to_disk`, unlike the sibling setters (`set_agent_model` / `set_agent_channels` / `set_agent_schedule` / `set_agent_tool_filters`).
  Since boot reconciliation re-syncs each agent from its on-disk `agent.toml` and overwrites DB-only fields, a skill/MCP assigned via the dashboard returned `200`, showed as assigned in the API, then was silently wiped on the next daemon restart.
  Both setters now persist to disk.
  Regression test: `test_set_agent_skills_persists_allowlist_to_agent_toml`.

2. crates/librefang-kernel/src/kernel/agent_state.rs — two multi-line // comment blocks

CLAUDE.md: "Never write multi-paragraph docstrings or multi-line comment blocks — one short line max."

The first block (8 lines before set_agent_skills's persist_manifest_to_disk call) and the second (4 lines before the MCP one) both violate this.
The WHY is non-obvious and worth a comment, but it should fit in one line each.

Suggested replacements:

// Without this, boot reconciliation silently overwrites DB-only fields from the on-disk agent.toml on restart.
self.persist_manifest_to_disk(agent_id);
// Same persistence requirement as set_agent_skills: boot reconciliation overwrites DB-only fields from agent.toml.
self.persist_manifest_to_disk(agent_id);

The detailed mechanism (boot.rs log message, sibling list) belongs in the PR body — where it already appears — rather than in an inline comment that will rot as the codebase evolves.


Generated by Claude Code

@houko houko left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding during daily review pass:

Missing regression test for set_agent_mcp_servers

The PR adds persist_manifest_to_disk to both set_agent_skills (lines ~460–475 of agent_state.rs) and set_agent_mcp_servers (lines ~534–540), and correctly adds test_set_agent_skills_persists_allowlist_to_agent_toml for the skills path. But there is no parallel test for the MCP-servers path — a future regression in that setter could go undetected.

Please add test_set_agent_mcp_servers_persists_servers_to_agent_toml alongside the existing test, using the same pattern (spawn agent, call set_agent_mcp_servers, read_to_string the agent.toml, assert the server name appears). The two paths got identical fixes; they should have identical coverage.

No other issues found.

houko
houko previously requested changes Jun 15, 2026

@houko houko left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Requesting changes to consolidate the three unresolved review points so this doesn't merge with known gaps. All are small and the fix logic itself is correct — just needs the coverage and style cleanup before merge.

  1. Missing regression test for set_agent_mcp_servers (raised 06-10 and 06-12, still open). The PR fixes both set_agent_skills and set_agent_mcp_servers, but only the skills path has a test. Add test_set_agent_mcp_servers_persists_allowlist_to_agent_toml mirroring the existing one: boot kernel, spawn agent with a known source_toml_path, call set_agent_mcp_servers([<server>]), read the on-disk agent.toml, assert the server name is present. Two identical fixes should have identical coverage.

  2. CHANGELOG continuation packs four sentences on one line (raised 06-11). CLAUDE.md: "CHANGELOG.md bullets — one sentence per line within a bullet." Split the new fix(kernel) entry's continuation into one sentence per line.

  3. Two multi-line // comment blocks in agent_state.rs (raised 06-11). The 8-line block before set_agent_skills's persist_manifest_to_disk call and the 4-line block before the MCP one violate the kernel crate's one-line-per-comment convention. Keep the WHY but compress each to a single line; the detailed mechanism (boot.rs log, sibling list) already lives in the PR body.

None of these are logic blockers — the persist fix is correct and the breadth is complete (skills + mcp were the only two setters missing the call). Re-request review once they're addressed.

@github-actions github-actions Bot added needs-changes Changes requested by reviewer has-conflicts PR has merge conflicts that need resolution and removed ready-for-review PR is ready for maintainer review labels Jun 15, 2026
@DaBlitzStein
DaBlitzStein force-pushed the fix/persist-skills-mcp-to-toml branch from a5fb487 to 53eae21 Compare June 15, 2026 14:34
@github-actions github-actions Bot removed the has-conflicts PR has merge conflicts that need resolution label Jun 15, 2026
@DaBlitzStein
DaBlitzStein force-pushed the fix/persist-skills-mcp-to-toml branch from b921104 to ce83fa5 Compare June 17, 2026 09:06
DaBlitzStein added a commit to DaBlitzStein/librefang that referenced this pull request Jun 17, 2026
DaBlitzStein added a commit to DaBlitzStein/librefang that referenced this pull request Jun 17, 2026
DaBlitzStein added a commit to DaBlitzStein/librefang that referenced this pull request Jun 17, 2026
@DaBlitzStein
DaBlitzStein force-pushed the fix/persist-skills-mcp-to-toml branch from 6297ee5 to dc1a891 Compare June 17, 2026 14:55
DaBlitzStein added a commit to DaBlitzStein/librefang that referenced this pull request Jun 17, 2026
@DaBlitzStein
DaBlitzStein force-pushed the fix/persist-skills-mcp-to-toml branch from dc1a891 to 07f73b1 Compare June 17, 2026 16:51
DaBlitzStein added a commit to DaBlitzStein/librefang that referenced this pull request Jun 17, 2026
DaBlitzStein added a commit to DaBlitzStein/librefang that referenced this pull request Jun 17, 2026
@DaBlitzStein
DaBlitzStein force-pushed the fix/persist-skills-mcp-to-toml branch from 07f73b1 to c196392 Compare June 17, 2026 22:37
DaBlitzStein added a commit to DaBlitzStein/librefang that referenced this pull request Jun 17, 2026
…ml (librefang#6045)

set_agent_skills and set_agent_mcp_servers updated the in-memory registry and
the SQLite blob (save_agent) but never called persist_manifest_to_disk, unlike
the sibling setters (set_agent_model / set_agent_channels / set_agent_schedule /
set_agent_tool_filters). Boot reconciliation re-syncs each agent from its
on-disk agent.toml and overwrites DB-only fields, so a skill or MCP server
assigned via the dashboard returned 200, showed as assigned in the API, then
was silently wiped on the next daemon restart.

Both setters now call persist_manifest_to_disk after a successful save_agent,
so the allowlist lands in agent.toml and survives a restart. Placed in the
kernel setter (not the API route handler) so it is robust to the routes/agents
module split (librefang#5975).

Regression test: test_set_agent_skills_persists_allowlist_to_agent_toml spawns
an agent, assigns a skill, and asserts agent.toml on disk contains it.
…GELOG

Adds the missing regression test for set_agent_mcp_servers (modelled on
the existing set_agent_skills test) and splits the CHANGELOG entry into
one sentence per line per convention.
@DaBlitzStein
DaBlitzStein force-pushed the fix/persist-skills-mcp-to-toml branch from c196392 to d9a74b0 Compare June 20, 2026 13:35
DaBlitzStein added a commit to DaBlitzStein/librefang that referenced this pull request Jun 20, 2026
@houko
houko dismissed their stale review June 23, 2026 01:15

All three requested items (MCP test, CHANGELOG one-sentence-per-line, comment wrapping) were addressed in the 06-20 push; base merged up to current main. Re-reviewed and clean.

@houko houko removed the needs-changes Changes requested by reviewer label Jun 23, 2026
@houko
houko merged commit 70fefa5 into librefang:main Jun 23, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docs Documentation and guides area/kernel Core kernel (scheduling, RBAC, workflows) size/M 50-249 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(kernel): per-agent skill & MCP-server assignments don't survive restart (set_agent_skills/set_agent_mcp_servers skip persist_manifest_to_disk)

2 participants