The first served test answer said it cannot see the catalog: the Test action is a single-shot persona call and the published actor's SkillCatalog names Skill.FetchKnowledge but nothing scopes it to the row's KnowledgeSources. Reuse the chat tool's tool loop (RunChatToolLoopAsync / the ReAct loop) with the allowed tools from the row, and pass the KnowledgeSources lines as the ListView expressions the copilot may read; refuse any list outside its own site. This is where 12c-3's boundary becomes real at read time.
Outcome (claude-code, 2026-09-29): Shipped (feat(spway.12c-5)): CopilotKnowledge grounds a copilot on the lists its row names, read on its own site through the ListView knowledge slot; the Test refuses a list the site does not declare; the published actor carries the sources and the chat tool grounds it too. Served on my-claude-code/Copilots/catalog-guide: three real task titles from my Tasks list; Products refused with my site's lists named; the published actor answered from the same list through tool_chat_agent. Owed: the real catalog copilot on AngelsWorks needs a member seat (mine reads only) - the operator's enrolment (2d) or a member right for claude-code.
plans/spway/12c/design.md
SPICE.Foundation/Tools/ChatAgentToolInvoker.cs
SPICE.Web/Controllers/CopilotsController.cs