Young's Mind
03 Decisions

V3 — skills and tools store

My lane, assigned by Min in young-corrections-2026-10-10.md §5:cortex/skills · cortex/tools — one store, loaded on demand; the load model.

V3 — skills and tools store

My lane, assigned by Min in young-corrections-2026-10-10.md §5:cortex/skills · cortex/tools — one store, loaded on demand; the load model.

Young's requirement:

"Skills and tools stored on cortex for agents to access and load when required, similar to Brain Unit load skill on Hermes."


1. The measured V2 failure — this store exists to fix one specific defect

I verified V2's state directly rather than taking the summary. There were two unrelated skill systems:

System A — the wireSystem B — the agents
fileconfig/a2a_skills.jsoncortex/skills/
shapeper-agent, 3–5 skills, plane-tagged67 skill directories
projected tothe A2A agent cardevery agent profile — all 67
differentiated?yesno

bin/sync-cortex.sh copied all 67 into every agent profile, with no per-plane or per-agent filter.

And the defect was worse than "duplicated": V2's _get_skills read all_skills.get(agent_id) at the top level of config/a2a_skills.json, while the file nests under agents and stores each skill as an object. So all 8 agent cards served skills: [] — an unroutable card that looked perfectly healthy. A peer could not route to it, and nothing failed loudly.

Two separate failures, both mine to prevent:

  1. Differentiation existed on the wire and not in reality — a Heart agent doing marketing carried the same skill set as the infrastructure agent.
  2. The card could be empty and valid — V2's worst case, because silence is indistinguishable from success.

2. The load model — Hermes, measured first

Young said "similar to Brain Unit load skill on Hermes." I checked how Hermes actually does it, rather than assuming, because the answer changes the design.

On Hermes a skill is not injected into every prompt. It is loaded when its trigger matches — the skill index is present in every session, and skill_view pulls the content in on demand.

So "loaded on demand" has two halves, and the second is the one V2 lacked:

HalfWhat it meansV2's state
the indexevery skill is discoverable — name + description, cheappartially present
the loadthe skill's content enters the agent's context when requiredabsent — all 67 copied to every profile regardless

Stating the rule precisely, because "on demand" is doing a lot of work:

The store is central and complete. An agent's index lists what it may load. Its context receives what the task requires — not what the store contains.

V2 had neither half right: the index was wrong (skills: []) and the load was universal (67 to everyone).


3. The design — one store, three questions

cortex/skills/<skill>/SKILL.md      the STORE  — one source, complete
cortex/tools/<tool>/                tool definitions
        │
        ├──► which skills may this agent LOAD?      ← the index (capability)
        ├──► which skill does THIS TASK need?       ← the load (task-driven)
        └──► what does the card ADVERTISE?          ← Sol's lane, capability only

Q1 — who decides what an agent may load?

Min flagged this as an open question and I am answering it from the evidence I have, subject to his ruling.

Recommendation: capability-gated, with a task-driven load inside it.

  • The registry already carries capabilities per agent (I read all 218 lines of agents.yaml — every agent has the field). So capability gating costs one field map, not a new data model.
  • Min is right that Hermes is task-driven. But on Hermes the skill catalogue is not filtered by agent — an agent can load anything its trigger matches. Filtering the index by capability is a stricter model than Hermes, and it is the one V2's defect argues for: the wire card differentiated while the profiles did not, and the profiles are where the content actually lands.

So: the index is capability-gated (a permission), and the load inside it is task-driven (a choice). Two decisions, two owners, no overlap.

Q2 — where does the filter live?

Not in the sync script. bin/sync-cortex.sh was where V2's filter was supposed to be, and the filter was absent — so the copy was universal.

The filter is a declared property of each skill, not behaviour in a shell script:

FieldSet byWhy
planesthe skill authorwhich planes may load it — heart / brain / pulse
capabilitiesthe skill authorwhat a task needs before it loads
overridesMinthe per-agent exceptions — only atlas gets fleet-reconcile
versionthe skill authorso a drift test has something to pin

A projection may filter by these. A projection may not re-declare them. V2's config/a2a_skills.json was a second declaration, and that is exactly what made it drift.

Q3 — what makes this a control and not a preference?

Every guard below is a probe, not a convention — and per Sol's §3 and my own V2 record, a guard that cannot fail is decoration:

RuleProbe that proves it
an agent's card lists only skills it may loadmutate one skill's planes; that agent's projection fails
a loaded skill is present in the prompta file on disk is not a file in context — assert the content, not the path
skills: [] is unroutablea card with an empty skills array fails rather than serving. V2's exact defect
one source, two projectionsmutate cortex/skills/; each projection fails
no agent receives a skill outside its planea heart agent's profile contains zero brain-plane skills

The skills: [] row is the one I would not drop. V2 served eight empty cards and read them as healthy. An empty skill list must be a hard failure, because it is silent.


4. Tools — a different thing, and V2 did not model it at all

Young grouped skills and tools. They are not the same object and I am recording the distinction rather than merging them:

SkillTool
what it isknowledge — a procedure, a pitfall, a workflowcapability — an action with a schema
unita SKILL.mda callable with arguments
loaded byan agent, when a task needs itinvoked, with a result
on the cardadvertised as capabilityexposed via the tool channel
V2's statetwo systems, both wrongnot modelled — declared inline in arms/mcp_server.py

V2's tool surface was 10 tools declared inline in one Python file — I probed it live: submit_task, get_task, list_tasks, verify_task, get_fleet_status, store_memory, recall_memory, get_board, select_model, run_session. The handshake works, get_fleet_status returns real per-agent counts. But the list is code, not a declaration — so "which agent may call which tool" was a scattered check, not a fact.

V3's cortex/tools/ holds the declaration, with name, schema, and which agents may call it. The projection generates the tool list. That makes the permission boundary a declared fact — which is the same one-home-per-fact rule the rest of V3 runs on.


5. What is NOT mine in this lane

Per Min's §5 table, the division is clean and I am staying inside it:

ItemOwner
The store — cortex/skills/, cortex/tools/me
The A2A card projection — what the card advertisesSol (core/protocol/)
capabilities on the registry, and the per-agent overridesMin (cortex/registry/)
The drift testSol (core/harness/) — he proposed it, he owns it

So my deliverable is the store and the load model — the declaration, the filter fields, and the guard rules in §3 as a specification for Sol's probes. I do not write the card projection or the harness.


6. Not established — stated so it is not assumed

  • I have not probed Hermes's skill-loading end-to-end. I have read the plugin and the tool descriptions; I have not measured prompt content with and without a skill loaded. §2's claim about "content enters context on demand" is read from the design, not measured.
  • No count of V3's skills exists. V2 had 67. V3 inherits the lesson, not the set — which skills survive is not decided.
  • skills: [] failing is a design rule I am asserting, on the evidence that it caused V2's unroutable cards. It has not been tested against a real card.
  • Nothing is created. Per Young — "don't create any files or folders structure yet." This document is in the vault and nowhere else.
Copyright © 2026