#32 feat: plugin system (cost-report) + memory provider model (#39) - #42
Open
verkligheten wants to merge 30 commits into
Open
#32 feat: plugin system (cost-report) + memory provider model (#39)#42verkligheten wants to merge 30 commits into
verkligheten wants to merge 30 commits into
Conversation
…uivalence gate
Old test asserted git diff on agent_notes/dist/ was empty after build, but dist/
is gitignored so the diff is always empty — the gate could never fail.
New gate makes two real assertions:
a. rendering._plugin_include_skip(cfg) == legacy cost.render.include_skip(cfg)
for {}, {cost_report_enabled: True}, {cost_report_enabled: False} — collapses
to the legacy bridge when no manifest owns any include.
b. The installer plugin skill filter removes nothing when the registry owns no
skills (_disabled_owned is empty with an empty registry).
Proven red: adding skip.add("phantom_include") to _plugin_include_skip caused 3
failures (AssertionError: {'cost_reporting', 'phantom_include'} == {'cost_reporting'}).
Reverted; all 4 new tests pass green. Removes the now-unused state-local/state-none
fixture dirs. Full suite: 1800 passed, 15 deselected.
…ntries via registry
…gle onto plugins, polish plugins list
…or other agents
… the none option
… always-on minimum
…onditional (local steps aside)
This was referenced Jul 30, 2026
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.
Two related refactors on one branch (epic #32): a plugin system for agent-notes' own toggleable subsystems, and a memory provider model (rescoped #39). 20 commits, 59 files, +3050 / −303. Suite: 1867 passed, 15 deselected.
Plugin system — toggle subsystems like oh-my-zsh (#33–#37)
A subsystem becomes a plugin: a
data/plugins/<name>/plugin.yamlmanifest declaring what it contributes (skills, includes, hooks, allow-entries), aplugin_registry, and anagent-notes plugins list|enable|disable|infocommand. Enabled plugins are a{name: bool}map in user config; disable actually uninstalls, it does not no-op.Plugindomain type + registry +enabled_pluginsconfigagent-notes pluginscommand (list/enable/disable/info)backend.supports(...)— disable uninstallsdefault: off); enabling it adds the include + Stop hook, disabling strips both. Fixes a real bug: the Stop hook used to install unconditionally regardless of the cost-report toggle.Config-UX hardening + a real dist gate (#32)
config_path()now honors$XDG_CONFIG_HOMElikestate_storealready did — state and config no longer resolve differently. This also made hermetic testing possible.config cost-reportonto the plugins command (one source of truth).tests/functional/commands/test_plugins_cli.py, 25 tests) driving the real CLI in an isolatedXDG_CONFIG_HOME— proven not to touch the real user config.git diff --stat agent_notes/dist/— butdist/is gitignored, so that diff is always empty and the gate could never fail. Replaced with a real additive-equivalence unit gate (proven to fail on a broken invariant) plus a committedscripts/dev/verify_dist_equiv.shthat builds HEAD vs the branch point and sha256-compares the trees.leadorchestrator is allowed 500 lines (300 for every other agent), so enabling cost-report no longer trips the line limit.Skeptical-verification rule for the lead
Added a shared include (
data/agents/shared/skeptical_verification.md) referenced from both lead surfaces: doubt claims that look true, verify agent-report facts against the artifact, ask "what would make this check fail?", and dispatch thedevilagent to challenge non-trivial designs. (Distinct concern from the epic; cleanly revertible if you'd rather it live elsewhere.)Memory provider model — rescoped #39
The original "convert memory to a boolean plugin" framing was rejected after a
devilreview verified three blockers (obsidian-only skills would regress local users; a YAML-callable escape-hatch breaks "manifest is data"; a second flag fightsstate.memory.backend). Memory is not a toggle — it's a provider:local(default — the AI CLI's native memory) orobsidian. Nonone/disable; legacybackend: nonemigrates tolocalon load.single-brain(one shared vault) orper-project— both selectable. New notes are placed per the current strategy; switching never touches or converts existing notes, and reads span both layouts so nothing is hidden.noneoption is gone.localsteps aside entirely. agent-notes injects no memory instructions for local — the AI CLI handles memory its default way. This required making the orchestrator memory protocol backend-conditional:{{MEMORY_INSTRUCTIONS}}now carries the full protocol for obsidian and a one-line step-aside for local, the hardcoded## Memory protocol (HARD RULE)blocks were removed fromglobal-claude.md/lead.md, and the guardrails Done Gate is backend-neutral. Verified: a local build'sCLAUDE.mdhas 0agent-notes memory add; an obsidian build has the full protocol.Verification
uv run pytest tests/→ 1867 passed, 15 deselectedscripts/dev/verify_dist_equiv.sh(NOTgit diffon the gitignored dist) at every plugin/memory task boundary; the only intentional dist diffs are cost-report-enabled and the local memory step-aside, both reviewed.Delivers / remains
Delivers #33, #34, #35, #36, #37, #39. Epic #32 is not fully closed — remaining: #38 (credential-guard as a plugin), #40 (wizard plugin-selection consolidation), #41 (docs). Targets
develop, so these issues close whendevelopreachesmain.