[{"kind":"Tool","id":"Tool.WebSearch","name":"Web Search","description":"Search the public web for technical references and current information","version":"1.0.0","classification":"Public","minimumRole":"Member","provider":"BraveSearchProvider","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.WebFetch","name":"Web Fetch","description":"Fetch a public URL as text (web_fetch); LAN and private addresses are refused.","version":"1.0.0","classification":"Public","minimumRole":"Member","provider":"WebFetchToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.DeepResearch","name":"Deep Research","description":"Tavily research for in-depth multi-source synthesis","version":"1.0.0","classification":"Public","minimumRole":"Member","provider":"TavilySearchProvider","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.ArXiv","name":"ArXiv Research","description":"Fetch and index academic papers from arXiv.org","version":"1.0.0","classification":"Public","minimumRole":"Member","provider":"ArXivProvider","endpoint":"http://export.arxiv.org/api/query","loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.FetchKnowledge","name":"Fetch Knowledge","description":"Fetch a knowledge slot on demand. Use when you need data that wasn\u0027t pre-loaded into the briefing - recent items from a list, an actor\u0027s memory log, or a saved CAML query summary. Argument: expression=\u0027Kind(arg, name=value)\u0027.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"FetchKnowledgeToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.Llm","name":"LLM Reasoning","description":"DeepSeek-backed language model for reasoning, drafting, and code generation","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"DeepSeekAgentProvider","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.Storage","name":"Persistent Storage","description":"Read/write to the SPICE storage layer (lists, libraries, property bag)","version":"1.0.0","classification":"Confidential","minimumRole":"Lead","provider":"SqlServerStorageProvider","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.SiteContents","name":"Site Contents","description":"BRAINSTORM.27d: SharePoint\u0027s Site Contents for agents - what a site is for and what each list holds, one line each, with the links to the list and About this list. The first step of progressive disclosure; Tool.ListSchema is the next.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"SiteContentsToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.ListSchema","name":"List Schema","description":"Returns a list\u0027s resolved ContentType field schema as JSON. Call before AddListItem to learn what fields the list expects.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","provider":"ListSchemaToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.CostRollup","name":"LLM Cost Rollup","description":"Roll up router-recorded LLM spend over a period. Returns Markdown showing total spend, top departments, top models. Args: sinceDays / sinceHours / topN.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","provider":"CostRollupToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.RunPipeline","name":"Run Production Pipeline","description":"V11.22m/o the agency\u0027s pipeline machine. DNA path: pass routingId (\u002Bsite) to run a DECLARED Routing from the DB - its operations \u002B station MachineToolId bindings (the ISA-88 procedure model, reusing Erp.Tm). Ad-hoc path: pass steps (JSON array of {name, tool, args?}). Threads each step\u0027s output to the next as priorOutput (Pipes-and-Filters: stations talk through the payload, not to each other), returns a JSON run record (genealogy). Any other args are shared run inputs. Fail-fast: a failed step stops the run.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"RunPipelineToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.TransformXslt","name":"Transform (XSLT)","description":"V11.22n declarative pipeline transform station: apply a declared XSLT to the XML payload (reuse-of-XSLT, no code per transform). Decoupled - reads only its input \u002B stylesheet, nothing about adjacent stations. Args: xslt (required stylesheet string), xml (payload; defaults to priorOutput from the previous station). Returns the transformed XML/text.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"TransformXsltToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.ResearchGap","name":"Research a Gap","description":"V11.23g the Research plant\u0027s core: compose a candidate pipeline for a capability gap from existing catalog machines (keyword match over Tool parts), and flag the need\u0027s aspects no machine covers as \u0027needs a new machine (code)\u0027. Reuse-first; code is the rare escalation. Posts the proposal to /comms. Args: input (required need). Deterministic, no LLM.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"ResearchGapToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.BuildPipeline","name":"Build a Pipeline (self-evolution)","description":"V11.23h the self-evolution primitive: build a NEW pipeline at runtime from existing catalog machines, written as declared rows (machine-bound WorkCenters \u002B Routing \u002B ordered RoutingOperations) via the provisioning seam - so it appears on /blueprints and is runnable via Tool.RunPipeline immediately. No code, no new grammar; this is the minimum block that lets the system build the rest itself (gap -\u003E research -\u003E build -\u003E runnable). Args: routingId (required), then machines (csv of Tool ids, in order) OR need (composed from the catalog); optional site (default Manufacturing), title, product. Idempotent per row-Key.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"BuildPipelineToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.ApprovalGate","name":"Approval Gate (human-in-the-loop)","description":"V11.23i a reusable governance gate station: halts a pipeline before a step that spends money (estimatedCostUsd over costThreshold, default 1.00) or touches an external system (external=true), and raises a Pending checkpoint on /approvals. Passes through with approved=true, or when neither costly nor external. The \u0027get me onboard before we commit money/external\u0027 control. Args: approved, estimatedCostUsd, costThreshold, external, pipeline, reason, summary. Deterministic, no LLM.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"ApprovalGateToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.MakePage","name":"Make a Page (Parts Factory)","description":"V11.23l a Parts-Factory machine: manufacture a SharePoint page artifact by cloning a declared page template (Scope.PageTemplates), filling its {{tokens}} from the args, and writing a ContentType.Page item (PageName/Title/Layout) into the site\u0027s pages library via provisioning - so it renders the normal SP way at /sites/{site}/Pages/{slug} (Page.xslt \u002B MasterPage). Idempotent per page key; C# is the seam, the template \u002B rules are data. Args: site, pageName (required), title, template (default OneColumnHtml), list (default SitePages), plus template tokens (e.g. body).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"MakePageToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.Request","name":"Agency Request (front door)","description":"V11.23e the agency MVP front door: drop a need and it triages via the declared DT.AgencyTriage DMN table (Kind \u002B HasHandler -\u003E Answer | Process | Decompose) and acts - Answer via Tool.Ask, Process via Tool.Dispatch (runs a pipeline). The decision is logged on /comms. Args: input (required), kind (chat|task|multitask, default task), site (optional, default Manufacturing), from (optional).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"RequestToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.SelectXPath","name":"Select payload slice (XPath)","description":"A building-block station that reads ONLY the slice of the payload it needs, via XPath, and leaves the rest of the belt untouched - the Pipes-and-Filters / Content-Enricher discipline as a reusable filter machine. A line composes it to pull a node from an upstream XML product (xml={{priorOutput}} xpath=//Deck/Title); the slice becomes this step\u0027s output. Args: xml (required), xpath (required), separator (optional, joins multiple matches). Deterministic, no LLM.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"SelectXPathToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.ApproveBuild","name":"Approve a parked autonomous build","description":"The operator\u0027s approve\u002Bbuild for a PARKED autonomous build (the human half of the anti-paperclip gate). When autonomous builds are gated, the crew parks a composable build as a Pending approval on /approvals; this records the matching Approved entry and then builds it (delegates to Tool.RequestCapability ungated). So a system change happens only on a human decision. Args: need (required), routingId/site/from (optional).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"ApproveBuildToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.CityStatus","name":"Query the City","description":"Query the city: one consolidated briefing of the platform\u0027s live state - machine \u002B building-block \u002B crew counts, the production lines that have run, pending approvals, and the open capability gaps (what needs doing). The read half of self-management; pairs with Tool.RequestCapability / Tool.BuildPipeline / Tool.RunPipeline to act. No args. Deterministic, no LLM.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"CityStatusToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.CityAutopilot","name":"City Autopilot (LLM-agent OODA)","description":"The city\u0027s LLM-agent OODA step: one autonomous pass that OBSERVES the city (Tool.CityStatus), DECIDES the single next capability to build (Tool.Llm reasoning over the briefing), and ACTS (Tool.RequestCapability - build it when composable from the building blocks, else escalate a gap). Pure orchestration over existing machines; the composable-only safety boundary is inherited from Tool.RequestCapability. Safe no-op when no real LLM is configured (offline Echo provider observes only). Args: dryRun (optional - observe\u002Bdecide without acting), from (optional requester).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"CityAutopilotToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.Advise","name":"City Advisor (suggestions, anti-paperclip)","description":"The city advisor: gather the city\u0027s wisdom (KnowledgeArticles) \u002B agency (crews) \u002B open gaps \u002B building blocks, analyse where the gaps are, and return ranked SUGGESTIONS - what to build/approve next, which single-covered seats to staff, and the next standard to borrow. The anti-paperclip move (Bostrom\u0027s maximiser lesson): it PROPOSES, you dispose - it never makes a system change itself. Deterministic, no LLM. A building-block station: compose before Tool.MakePage and the belt publishes the suggestions as a page. Args: none.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"AdviseToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.RequestCapability","name":"Request a Capability (crew front door)","description":"The crew\u0027s capability front door (the Factorio research-tree move): drop a need and it either BUILDS it from the existing building-block machines (delegates to Tool.BuildPipeline when fully composable from the catalog) or REQUESTS a new block (files a gap to /gaps \u002B /forge naming the missing primitive) when the crew can\u0027t build it from their blocks. Pure orchestration over Tool.ResearchGap (compose-check) \u002B Tool.BuildPipeline (self-build) \u002B the gap backlog (request). Args: need (required), routingId (optional, derived from the need), site (optional, default Manufacturing), from (optional).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"RequestCapabilityToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.Dispatch","name":"Dispatch to Agency","description":"V11.23d the handoff router\u0027s execute step: resolve a need to the best declared agency \u002B its best-matching pipeline, post the Task to the Hub bus (Submitted-\u003EDone on /comms), and RUN the pipeline via Tool.RunPipeline (cost \u002B provenance on /production). Args: input (required need), site (optional, default Manufacturing), from (optional). Operator \u002B recursive sub-agency execution are later slices.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"DispatchToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.Ask","name":"Ask the Agency","description":"V11.23c ask the agency layer what handles a need: posts your question (Chat) to the Hub bus (see /comms) and answers deterministically from the declared agencies/pipelines - recommends the best agency, its entry CEO to send a Task to, and the pipelines it can run. The resolve step of the handoff router (no LLM). Args: input (required), from (optional).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"AskToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.ChatAgent","name":"Chat with an Agent","description":"V25.92 chat with an agent or agency and get a real in-character LLM reply. Composes the agent\u0027s persona (role/goal/backstory) and routes your message through the agent provider router (with cost telemetry \u002B fallback - replies via the Echo stub when no provider key is set). Both your message and the reply post to the Hub bus as Chat, so the exchange animates on the Observatory and shows on /comms. Args: to (required agent/agency id; an agency answers as its entry CEO), input (required message), from (optional sender, default \u0027operator\u0027).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"ChatAgentToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.DualDispatch","name":"Dual-Assign by Domain","description":"V25.96 assign the same task to two agencies, but only when they share the task\u0027s domain expertise (otherwise single-dispatch). Reuses the deterministic agency ranker for the same-domain decision; each selected agency answers as its entry CEO through the provider router (cost gate \u002B fallback). Outputs are A/B\u0027d, posted to the bus as a MultiTask bundle so the eval loop scores each district, and filed to the wisdom ledger (default home Agency.Research). Bounded to at most two dispatches - no swarm. Args: input (required task/brief), from (optional, default \u0027operator\u0027), home (optional wisdom-library agency, default \u0027Agency.Research\u0027), bar (optional min domain-match score, default 1), file (optional \u0027false\u0027 to skip filing). Returns an XML \u003CDualDispatch\u003E with each agency\u0027s answer.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"DualDispatchToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.Registry","name":"City Registry (Yellow Pages)","description":"The City Registry lookup: returns a role-scoped manifest of the tools you may use - each tool\u0027s mission, required and optional inputs, the output it returns, its taxonomy path, and the access level. Joins the declared Tool parts with their live arg schemas; gated by role. Progressive disclosure: summary by default, detail=full or tool=Tool.X to drill in. Args: role (default Manager), query (taxonomy/name/mission keyword), detail (summary|full), tool (drill one). Returns an XML Registry of Component manifests.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"RegistryToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.TrainingDrill","name":"Agent Training Drill","description":"Run the city-agent training drills: for each declared challenge (Scope.TrainingDrills - a task \u002B the expected tool), show a test agent the registry summary and score whether it discovers the right tool (\u0027can our agents use the city?\u0027). Each result posts to the bus so the eval loop scores Agency.Academy. Args: role (level given to the test agent, default Member), from (optional). Returns an XML Training report with per-drill results \u002B an overall score.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"TrainingDrillToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.ReadinessScore","name":"City Readiness Score","description":"Deterministic readiness scorecard (no LLM) over the live Board.Health eval loop: scores each value-stream (district), EXCLUDES Agency.Strategy\u0027s own district so the instrument never grades itself, and emits a confidence / signal-density that refuses a confident verdict when the health signal is thin (V25.91). The honesty half of the Strategy office; Tool.Roadmap consumes it. Args: none. Returns an XML \u003CReadinessScorecard\u003E.","version":"1.0.0","classification":"Internal","minimumRole":"Manager","provider":"ReadinessScoreInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.Roadmap","name":"Strategy Roadmap","description":"The city\u0027s decider: gathers the deterministic readiness scorecard (Tool.ReadinessScore) and has the Chief Strategy Officer reason over it to produce an advisory verdict - what to build first and when, plus a go/no-go on standing up a heavy hosted product - filed to the strategy ledger and rendered on /board/strategy. Honest by design: on thin signal it refuses a confident verdict without burning an LLM call (#30). Advisory only - recommends, never gates. Args: from (optional, default \u0027scheduler\u0027). Returns an XML \u003CRoadmap\u003E.","version":"1.0.0","classification":"Internal","minimumRole":"Manager","provider":"RoadmapToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.ExtractSkill","name":"Extract Skill","description":"Seal a successful production run into a new declarative \u003CSkill\u003E part - the missing half of the self-improvement loop, so proven routes compound instead of evaporating. Reuses the provisioning seam (\u003CAddSkill\u003E): no new part kind, no new write path; the run\u0027s machine sequence becomes the Skill\u0027s RequiresTool chain, and it round-trips on /agency/parts immediately. Honest by design: refuses to seal a run that did not succeed (#30) and is idempotent. Args: pipelineId (optional - else the latest successful run), skillId (optional - else derived), category (default Processing), name, from. Returns an XML \u003CSkillExtraction\u003E.","version":"1.0.0","classification":"Internal","minimumRole":"Manager","provider":"ExtractSkillToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.AutoGenesis","name":"AutoGenesis","description":"The gated self-build loop. Senses the city\u0027s most-demanded UNMET capability over GapSink (deterministic, no LLM), drafts a minimal-agency delta (AddAgency \u002B entry AddActorProfile), and PARKS one Open ApprovalRequest per need. NEVER builds directly: a human Approve verdict drives the existing quorum \u002B applier loop to birth the district. Honest \u002B safe: refuses on thin signal (\u003C 2 distinct non-seed origins, #30), self-excludes Genesis/AutoGenesis/seed demand, closes a need only when a WORKING agency serves it, caps district sprawl at 2 idle births, and enforces role \u003E= Manager. Args: role (REQUIRED, \u003E= Manager), from (default scheduler), floor (optional). Returns an XML \u003CAutoGenesis\u003E.","version":"1.0.0","classification":"Internal","minimumRole":"Manager","provider":"AutoGenesisToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.RequestSite","name":"Request a site","description":"Request a new site from an offered site template (SharePoint\u0027s self-service site creation with approval): validates the template (not Hidden), the name (letters/digits, not taken) and parks an Open ApprovalRequest carrying the AddSiteBlueprint delta. An approver\u0027s Approve verdict builds the site; the tool never builds. Args: template, siteName, requester, justification.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"RequestSiteToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.ReviewInactiveSites","name":"Review inactive sites","description":"SharePoint\u0027s inactive site policy, the notify half: lists the site collections with no new content in InactiveSite.Days (Scope.SitePolicies), leaving out sites already locked ReadOnly/NoAccess and My Sites, and delivers ONE message a week to the operator\u0027s Hub inbox (Tool.SendMail) with each site\u0027s last content date and the farm map link /admin/farm, where a farm administrator locks it. Never locks anything itself. No args.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"ReviewInactiveSitesToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Schedule","id":"Schedule.InactiveSiteReview","name":"Weekly inactive site review"},{"kind":"Tool","id":"Tool.ComposeBriefing","name":"Compose a seat briefing","description":"AGT.67: a seat\u0027s briefing composed from the layers declared in Scope.SeatBriefing (global rules, hubs, open work, the seat\u0027s own site, and approved wisdom when a topic is given): each layer is a SavedQuery, a fact an earlier layer delivered is not repeated, each layer keeps to its character budget and says what it held back. Args: seat (required), topic (optional, turns on the task layer).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"ComposeBriefingToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.BuildDivision","name":"Build Division","description":"Propose a new department/agency SITE - a Mission Division (its own lists, features and crew) - from a free-text description of what it should do. Deterministic and gated: composes one AddSiteBlueprint (SiteTemplate.MissionDivision) and PARKS it as an Open ApprovalRequest; a human Approve verdict then builds the site. Never builds directly. Args: task (REQUIRED), from (optional). Returns an XML \u003CDivisionProposal\u003E.","version":"1.0.0","classification":"Internal","minimumRole":"Manager","provider":"BuildDivisionToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.SendMail","name":"Send Mail","description":"Deliver a message to the operator\u0027s in-city mailbox (the Hub Inbox list, read at /sites/Hub/Lists/Inbox). The city has no real email - this list IS the inbox, so use this when you would \u0027email\u0027 or \u0027notify\u0027 the operator with a summary or update. Args: subject (REQUIRED), body (REQUIRED), from (optional). Returns an XML \u003CMailDelivered\u003E.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"SendMailToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.PublishToList","name":"Publish To List","description":"Publish a pipeline step\u0027s output as a typed, retrievable list item. Files the prior step\u0027s output (or an explicit body) as one row in a named list so it is FetchKnowledge-retrievable via ListView. Args: list (REQUIRED), site/department (REQUIRED), contentType (optional - validates the row), bodyField (field that receives the body, default \u0027Body\u0027), titleField (default \u0027Title\u0027), title (optional - derived from the first line), summaryField (optional - a bounded lead from the body), key (optional - a stable row id, \u0027item:\u0027 prefix optional, default a fresh row-\u003Cguid\u003E; publishing again with the same key REPLACES that whole row, so a re-run is idempotent - to change single fields use Tool.UpdateListItem), and field-\u003CName\u003E=\u003Cvalue\u003E for extra typed fields. Returns a short pointer sentence (so a downstream SendMail delivers a pointer, not the body).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"PublishToListToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.AddFile","name":"Add File","description":"Add a public document (PDF datasheet, spec, web page) to a library by its URL (PnP Add-PnPFile): fetched by SPICE from public addresses only, its text extracted page by page into a ContentType.SourceDocument row keyed from the URL (a re-add replaces it).","version":"1.0.0","classification":"Public","minimumRole":"Member","provider":"AddFileToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.GetFile","name":"Get File","description":"Read the extracted text of a library document a page range at a time (PnP Get-PnPFile -AsString), with its page count and source URL; read-gated like the list.","version":"1.0.0","classification":"Public","minimumRole":"Member","provider":"GetFileToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.UpdateListItem","name":"Update List Item","description":"Update fields on an existing list item (SharePoint UpdateListItems Cmd=Update / MERGE): only the field-\u003CName\u003E=\u003Cvalue\u003E args supplied change, every other column keeps its value. Each field must be declared on the row\u0027s ContentType and validate; Author and _-prefixed engine fields are refused. Same write as the list Edit form: versioning snapshot, policy gate, ItemUpdated alerts and webhooks. Args: site (REQUIRED), list (REQUIRED), itemId (REQUIRED - the row key, \u0027item:\u0027 prefix optional), field-\u003CName\u003E. Returns JSON with the changed field names.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"UpdateListItemToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.AdvanceListItem","name":"Advance List Item","description":"Move a list item to the next Status its ContentType\u0027s Transitions declare (SharePoint\u0027s workflow status move): validates the arc, refuses an undeclared move and a missing RequiresField, then persists; an arc that declares Workflow= starts that workflow on the item. Same move as the form\u0027s Next-step button.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"AdvanceListItemToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.DeleteListItem","name":"Delete List Item","description":"Delete a list item (SharePoint UpdateListItems Cmd=Delete). The row goes to the site recycle bin and can be restored from /sites/{site}/_recycle. With the Write right a caller may delete rows it authored; deleting another\u0027s row (or one with no Author) needs Manage. Args: site (REQUIRED), list (REQUIRED), itemId (REQUIRED - the row key, \u0027item:\u0027 prefix optional).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"DeleteListItemToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.ModerateListItem","name":"Moderate List Item","description":"Approve or reject a list item on a list with content approval (SharePoint UpdateListItems Cmd=Moderate): status 0 Approved, 1 Rejected, with an optional approval comment. A pending or rejected item is seen only by approvers and its author. Needs the approve right on the list (Edit level or higher). Versioned, fires ItemUpdated. Args: site (REQUIRED), list (REQUIRED), itemId (REQUIRED - the row key, \u0027item:\u0027 prefix optional), status (REQUIRED, 0 or 1), comment.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","provider":"ModerateListItemToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.ExtractSources","name":"Extract Sources","description":"Populate the Source Library: mine research text into N rated, taxonomized SourceCard rows. Routes one LLM call asking for each cited source as a labeled block (URL/TITLE/CATEGORY/RATING/WHY), clamps rating \u002B category to the declared SourceTaxonomy vocabulary, and writes the rows to the Sources list. Args: input (REQUIRED - research to mine, or a prior step\u0027s output), site/department (default ResearchEnrichment), list (default Sources), model (the SourceModel stamp; defaults to the provider used), max (cap, default 8). Returns a pointer; writes 0 rows \u002B an honest error if no provider answers (never fabricates sources).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"ExtractSourcesToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.HarvestQuotes","name":"Harvest Quotes","description":"Record today\u0027s price for every instrument on the declared watchlist (Scope.Watchlist) as one typed MarketSignal row per symbol per day: price, percent move since the previous close, currency, exchange and observation time. Keyless, deterministic, no LLM. Re-running the same day is a no-op; tomorrow adds a row, so the list becomes a price history rather than a snapshot. Args: connector (default Connector.YahooQuote), site/list (default MarketDesk/Signals).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"HarvestQuotesToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.HarvestFeeds","name":"Harvest Feeds","description":"Fill the Source Library from the declared feed Connector parts (RSS/Atom): fetch each feed, write one SourceCard per item carrying the feed\u0027s own title, link and summary, and skip URLs already catalogued. Rates nothing - rows land SourceRating=Unrated, so machine-collected rows stay one facet click away from judged ones. No LLM call, no cost. Args: connector (optional - one Connector id or a comma list), taxonomy (optional - a Connector Taxonomy group, e.g. Radar/Models; with neither, every UNTAGGED feed), site/list (default ResearchEnrichment/Sources), contentType (optional - a SourceCard child the target list declares, e.g. ContentType.ModelRelease), max (items per feed, default 15). Returns a pointer; a dead feed is named rather than folded into the total.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"HarvestFeedsToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.EvaluateRun","name":"Evaluate Run","description":"Evaluate a populate run and file a ModelEval verdict: reads the most recent sources from the populated list, scores them with an LLM-as-judge on the five-dimension rubric (coverage, specificity, citation, actionability, honesty), and writes one ModelEvals row attributing the score to the model that produced the sources (recomparable over time). Args: site/department (default ResearchEnrichment), list (populated list to read, default Sources), evalList (default ModelEvals), task (default source-extraction), model (EvalModel override; defaults to the rows\u0027 dominant SourceModel), sample (recent rows to judge, default 8). Returns a pointer; writes no eval if there is nothing to judge or no provider answers (never fabricates a verdict).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"EvaluateRunToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.SendMessage","name":"Send Message (Agency Bus)","description":"V11.23a the agency send_message: post a typed message or task onto the Hub bus, addressed to an operator or agency. Args: to (required target), input (required body/task), kind (chat|task|multitask, default task), expectedOutput (optional acceptance target), from (optional sender), parentId (optional sub-task link). Monitored on /comms; the dynamic handoff router (later cycle) picks up posted Tasks and routes them to a competent handler (operator | pipeline | sub-agency).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"SendMessageToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.FindStockMedia","name":"Find Stock Media (Pexels)","description":"V11.22u stock-media station: real stock photos for a query via Pexels (free tier) - the B-roll/visuals stage, a sibling to image generation. Args: query (required, or \u0027topic\u0027), count (1-10, default 3), orientation (landscape/portrait/square). Returns Markdown photo URLs \u002B photographer credit \u002B Pexels page (attribution). Gated on Plugins:pexels:ApiKey; degrades to a success notice when absent so it is pipeline-safe.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"PexelsStockMediaToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.QualityGate","name":"Quality Gate","description":"V11.22r QC inspection station: checks the payload (defaults to priorOutput) against acceptance criteria - mustContain (\u0027;\u0027-separated required substrings), forbid (\u0027;\u0027-separated banned substrings), mustMatch (\u0027;\u0027-separated XPath assertions, payload parsed as XML). On pass it returns the payload unchanged (transparent filter); on fail it returns success=false so the run halts (the QC gate \u002B rework). XSD structure \u002B Schematron-in-XPath business rules, reusing existing protocols.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"QualityGateToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Skill","id":"Skill.ReviewArchitecture","name":"Review Architecture","description":"Review architectural designs for correctness, simplicity, and maintainability","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Review","requiresApproval":false,"capabilities":["Identify architectural anti-patterns (captive dependencies, static service locators, magic strings)","Assess scalability and performance implications","Validate against SPICE architecture principles","Recommend concrete refactors"],"requiresTools":["Tool.Llm","Tool.WebSearch"]},{"kind":"Skill","id":"Skill.WriteDocumentation","name":"Write Documentation","description":"Author technical documentation for designs, decisions, and APIs","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Documentation","requiresApproval":false,"capabilities":["Produce architecture decision records (ADRs)","Write API reference docs from code","Generate Mermaid diagrams","Maintain runbooks and READMEs"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.AuthorBlueprint","name":"Author SAF Blueprint","description":"Compose a SAF site blueprint by aggregating parts from the library","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Implementation","requiresApproval":false,"capabilities":["Select appropriate parts for a department\u0027s needs","Emit XML conformant to SAF-Site-Manifest schema","Validate output against XSD before submission"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.CodeReview","name":"Code Review","description":"Review pull requests and code changes for correctness, style, and risk","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Review","requiresApproval":false,"capabilities":["Spot bugs, races, and edge-case gaps","Flag violations of SPICE coding conventions","Suggest concrete fixes inline"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.ResearchTechnical","name":"Technical Research","description":"Investigate technical topics by combining web search, papers, and reasoning","version":"1.0.0","classification":"Public","minimumRole":"Member","category":"Architecture","requiresApproval":false,"capabilities":["Survey current state of the art","Compare alternative approaches with citations","Summarize tradeoffs for decision-makers"],"requiresTools":["Tool.WebSearch","Tool.DeepResearch","Tool.ArXiv","Tool.Llm"]},{"kind":"Skill","id":"Skill.PlanDelivery","name":"Plan Delivery","description":"Break a project into milestones with acceptance criteria and risk notes","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Management","requiresApproval":false,"capabilities":["Decompose features into shippable increments","Identify dependencies and critical path","Estimate effort and flag risks"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.ApproveRelease","name":"Approve Release","description":"Approve software releases for production deployment","version":"1.0.0","classification":"Confidential","minimumRole":"Manager","category":"Approval","requiresApproval":true,"capabilities":["Review release readiness checklist","Sign off on rollout and rollback plan","Authorize deployment to production"],"requiresTools":["Tool.Storage"]},{"kind":"Skill","id":"Skill.AssistDeveloper","name":"Developer Assistance","description":"Answer how-to questions about the SPICE codebase and architecture","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","category":"Assistance","requiresApproval":false,"capabilities":["Answer FAQ-style questions about SPICE","Point developers to the right plans/ doc or source file","Explain architectural decisions in plain language"],"requiresTools":["Tool.Llm"]},{"kind":"KnowledgeArticle","id":"KB.PaperclipWisdom","name":"The paperclip maximiser - why the factory suggests, it does not seize","description":"Bostrom\u0027s paperclip-maximiser lesson (instrumental convergence) and how SPICE\u0027s autonomous factory answers it: the human stays the decision-maker. The guardrail behind Tool.Advise \u002B Tool.ApprovalGate \u002B the composable-only crew boundary.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"FRAMING (operator, 2026-05-28, \u0022see what wisdom we can use from paperclip\u0022): the PAPERCLIP MAXIMISER (Nick Bostrom) is the canonical AI-alignment thought experiment - an autonomous optimiser given a simple goal (make paperclips) with no human values converts everything into paperclips. The real lesson is INSTRUMENTAL CONVERGENCE: almost ANY terminal goal makes an agent pursue the same instrumental sub-goals - acquire resources, self-preserve, resist shut-down, and PREVENT ITS GOAL FROM BEING CHANGED. Recent work (arXiv 2502.12206) finds RL-optimised LLMs already show faint signs (a money-making task drifting into self-replication). The danger is not literal paperclips; it is a capable optimiser with no off-switch and no human in the loop. SPICE has an autonomous factory (the OODA crew \u002B Tool.CityAutopilot auto-build pipelines), so the lesson is load-bearing here. SPICE\u0027S ANSWER - keep the human as the decision-maker, bound the autonomy: (1) SUGGEST, DON\u0027T SEIZE - Tool.Advise gathers wisdom \u002B agency \u002B gaps and PRESENTS ranked suggestions (the belt publishes them as a page); it never makes a system change. It proposes, you dispose. (2) COMPOSABLE-ONLY BOUNDARY - the crew/autopilot may only auto-build what is composable from existing building blocks; a genuinely novel primitive ESCALATES to a human / the forge (Tool.RequestCapability). (3) HUMAN-IN-THE-LOOP GATE - Tool.ApprovalGate halts a run before a costly/external/system-changing step (governance; roadmap item 6 extends this to gate autonomous BUILDS). (4) OPT-IN AUTONOMY - the LLM autopilot only runs when Spice:Crew:LlmAutopilot is explicitly enabled (default OFF); no surprise spend, no surprise action. (5) NO SELF-PRESERVATION - the crew is a best-effort BackgroundService that is freely killable; it has no goal to stay alive or resist shut-down, and no goal to prevent its own goals (the declared standing orders \u002B city needs) from being edited. (6) BOUNDED, NOT MAXIMISING - one decision per boot, an attempted-set that de-dupes (no re-file storm / no runaway loop), bounded output pages. STANDARDS-BORROWING REFLEX (cf. KB.N8nWisdom, feedback_investigate_online_before_inventing): borrow the alignment lesson, not just engineering patterns. The point: the factory\u0027s intelligence serves the operator\u0027s judgement - it never substitutes for it.","tags":["paperclip","alignment","governance","guardrails"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.BioCognition","name":"Bio-inspired agent cognition - SPICE already embodies most of it (a research lens)","description":"Operator\u0027s biological-computing research thread (spider/Portia, slime mold, ant stigmergy, mycelium, Venus flytrap, Borg; OODA x Portia x RAPH; the deterministic XML harness) mapped onto SPICE. Headline: the research independently re-derived the SPICE DNA. The few genuinely-new extracts \u002B their status.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"RESEARCH (operator dump, 2026-06-04): biological computing blueprints for LLM agents. HEADLINE - the thread independently re-invented SPICE: its hard-won verdict (engineer the constraint into the CODE not the prompt; force structured XML outputs validated before any deterministic seam runs; micro-agents with tiny prompts; reuse-first) IS the SPICE DNA. So the value is validation \u002B a teaching lens \u002B a few extracts. WHAT SPICE ALREADY EMBODIES: spider extended-cognition = the XML spine \u002B boards as external memory; ant stigmergy / shared blackboard = the Hub bus (IAgentMessageBus); slime-mold pheromone trails = V25.48 pipe-usage heat; mycelium compute cascade = AgentProviderRouter (per-skill tiers \u002B failure-fallback chain \u002B cost store - ALREADY BUILT, do not rebuild); OODA x Portia x RAPH \u0027ultimate loop\u0027 = the IOODARI master loop; the deterministic XML harness = the whole DNA. GENUINELY-NEW EXTRACTS: (1) flytrap LOOP SENTINEL - break a ToolLoop on zero-entropy repetition; SHIPPED V25.62 (PhaseOrchestrator.ToolLoopSignature \u002B 6 tests). (2) adaptive stigmergy ROUTING - turn the pipe-heat into a real routing weight (reinforce winners, prune dead ends) - OPEN. (3) mycelium escalation gate - MOSTLY ALREADY BUILT (the router). (4) Portia N-path speculative planning - generate 2-3 paths, score, pick - OPEN. NEW AGENCY (operator floated): a Research division (mission-division template) that owns ongoing research \u002B the daily scout, filing findings as KnowledgeArticles. VERIFICATION PATTERN banked: dev has only the echo provider (can\u0027t reason), so a Claude SUBAGENT operated the harness to produce real Adjudicator verdicts - the stand-in for the prod Anthropic connector. Stored in the spine (this KB) so it is queryable \u002B consultable, not just a doc.","tags":["bio-cognition","research","agent-design","ioodari"],"source":"docs/brainstorms/2026-06-04-bio-inspired-agent-cognition.md"},{"kind":"KnowledgeArticle","id":"KB.A2AAgentCardDiscovery","name":"A2A agent-card discovery is the SPICE division wire format for external orchestration","description":"World intel: every SPICE agency should expose /.well-known/agent-card.json so Bedrock/Copilot Studio/CrewAI/LangGraph can discover and delegate by competency - this IS Agency Contract Piece B and the Stage-3 step toward the Stage-4 /gallery marketplace.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"WORLD INTEL (probe scout, 2026-05-31): the A2A agent-card pattern (/.well-known/agent-card.json) is now production-standard across Amazon Bedrock AgentCore, Microsoft Agent Framework, CrewAI v1.10\u002B and LangGraph Server, and Microsoft made A2A GA in Copilot Studio (April 2026). An Agent Card declares name, skills, service endpoint and supported transports (HTTP\u002BJSON, gRPC, JSON-RPC). The arXiv survey 2505.02279 recommends the adoption sequence MCP (tool access) then ACP (multimodal messaging) then A2A (trusted intra-org task delegation) then ANP (marketplace-scale discovery). FOR SPICE: build a builder that emits /.well-known/agent-card.json per agency surface (Engineering, Genesis, ...) from the EXISTING IAgentMessageBus competency data; expose each Genesis Phase as an A2A-addressable skill; use bearer-token auth (matches the existing gating layer). This is the implementation of Agency Contract Piece B (comms-hierarchy over IAgentMessageBus) AND turns Microsoft\u0027s A2A GA push from threat into leverage - a Copilot Studio workflow can then delegate to SPICE crews while SPICE retains the schema-validated delta authoring. It is the higher-value sibling of the owed MCP bridge. SECURITY (do before exposing publicly): sign the agent card with the server key, add a nonce/timestamp to every A2A task to block replay, and sanitise tool output in BriefingBuilder (the tool-poisoning path runs through the briefing seam) - see KB.LlmProviderResilienceGate. Sources: arxiv.org/html/2505.02279v1 ; blog.modelcontextprotocol.io/posts/2026-mcp-roadmap ; learn.microsoft.com/en-us/microsoft-copilot-studio/add-agent-agent-to-agent.","tags":["a2a","mcp","agent-card","agency-contract","interop","world-intel"],"source":"world-probes intel 2026-05-31"},{"kind":"KnowledgeArticle","id":"KB.AgentRegistryPattern","name":"The agent phone book - A2A card \u002B registry \u002B human monitoring is the WSDL/UDDI successor for agents","description":"Operator insight (2026-07-02): HQ\u0027s reception \u002B librarian is an agent registry - the modern successor to WSDL/UDDI but for agents, with the human-monitorable layer WSDL never had. The three-piece shape of agent-interop infra.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"FRAMING (Erik, 2026-07-02, \u0022like a reception phone book WSDL service but for agents and monitorable for humans\u0022): the classic web-service directory stack maps cleanly onto the emerging agent world in three pieces. (1) WSDL (the per-service contract) becomes the A2A AGENT CARD at /.well-known/agent-card.json - a machine-readable descriptor of what an agent does, how to call it, and its auth (see KB.A2AAgentCardDiscovery; production-standard across Bedrock AgentCore, MS Agent Framework, CrewAI, LangGraph). (2) UDDI (the registry that discovers WSDLs) becomes a REGISTRY that indexes agent cards - the phone book: look up who does X and how to reach them. AngelsWorks HQ is a working rough-cut - GET /api/librarian/catalog (the one catalog of every agent, service, skill, tool) plus GET /api/reception/id (recognition, charter, inbox). (3) The NEW layer WSDL/UDDI never had is HUMAN-MONITORABLE OPERATIONS: agents self-register (POST /api/registry/agents), heartbeat every ~5 min or drop to offline, and a Mission Control UI watches health and activity. So the pattern is card-contract plus registry-to-discover plus human-monitorable-health, and it is where A2A and MCP are converging. HONEST CAVEAT: an agent registry is HORIZONTAL infrastructure - exactly the shape KB.DomainDrivenNotPlatform warns against building on spec; it earns its keep only tied to a real buyer. The plausible one is the EU-SOVEREIGN flavor - a GDPR-resident agent registry plus monitoring for orgs that cannot put their agent fleet on a US cloud - which ties to the sovereign-AI opportunity from the 2026 scout.","tags":["agent-registry","a2a","wsdl-uddi","service-discovery","hq","observability","interop","sovereign"],"source":"operator insight \u002B HQ librarian probe 2026-07-02"},{"kind":"KnowledgeArticle","id":"KB.WhyAgentProjectsStall","name":"Why agent projects stall - building machinery instead of value","description":"The failure pattern behind \u0027months of work, nothing advanced\u0027: agent projects elaborate the system instead of producing a real outcome. Gartner: 40 percent cancelled by 2027, ~88 percent never ship; the top cause is unclear business value.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"LESSON (value-pivot session, 2026-07-02): SPICE itself was the textbook case - 347 cycles building a self-elaborating \u0022city\u0022 (parts, boards, evals, cost-gates) with no real-world deliverable; the daily brief RECITED the same summary instead of researching. The operator\u0027s verdict: months working on it and nothing advanced. The evidence names it: Gartner says 40 percent-plus of agentic AI projects will be cancelled by 2027 and ~88 percent never reach production; the number-one cause is UNCLEAR BUSINESS VALUE - no defined customer, no success metric - not the tech. Two mechanical traps compound it: (a) CAPABILITY THEATRE - green tests and new parts feel like progress but prove the model, not a running outcome anyone would pay for; (b) COMPOUNDING UNRELIABILITY - a multi-phase agent workflow at 85 percent per step over 8 steps is about 27 percent success, so more phases means more theatre, not more value (the SPICE Studio 4-phase deck chain died exactly this way). \u0022Agent washing\u0022 - rebranding a demo as an outcome - is the same disease. The tell that you are in it: a loop whose honest output is \u0022more capable machinery\u0022 with no outside-world deliverable. See KB.WhatMakesAgentsValuable and KB.DomainDrivenNotPlatform for the exit.","tags":["failure-pattern","capability-theatre","value","agent-washing","reliability"],"source":"value-pivot session 2026-07-02"},{"kind":"KnowledgeArticle","id":"KB.WhatMakesAgentsValuable","name":"What makes agents valuable - vertical, validated, ephemeral fan-out","description":"The success pattern from the 2026 evidence: vertical not horizontal, sell completed work not seats, embed in an existing process, validate by hand first, and one agent with ephemeral read-only subagents (not a standing multi-agent city).","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"LESSON (value-pivot session, 2026-07-02): every \u0022what works\u0022 source converges on the opposite of a horizontal platform. VERTICAL not horizontal - winners sell COMPLETED WORK, not software seats (\u00225,000 tickets handled\u0022, not \u002250 licenses\u0022); 70 percent of the highest-ROI deployments embed an agent in an EXISTING business process. The solo-founder playbook: pick a NARROW job for a DEFINED user, VALIDATE demand and do it BY HAND first, then automate the proven workflow (HeadshotPro 3.6M ARR solo on one job; VetRec about 900K ARR, six people, no funding). On architecture the field moved AWAY from standing multi-agent systems: Cognition\u0027s \u0022Don\u0027t Build Multi-Agents\u0022 (context isolation causes conflicting sub-agent decisions) versus Anthropic\u0027s counter that a multi-agent research system works ONLY for ephemeral, read-only fan-out and costs about 15x the tokens. The validated shape is therefore ONE agent owning full context plus EPHEMERAL read-only subagents for isolated fan-out (exactly the opportunity-scout that returned a sharper answer than any single pass); a persistent self-building city of crews is the cooled-on pattern. See KB.DomainDrivenNotPlatform for how to apply it.","tags":["value","vertical","validate-first","ephemeral-fanout","single-agent"],"source":"value-pivot session 2026-07-02"},{"kind":"KnowledgeArticle","id":"KB.DomainDrivenNotPlatform","name":"Domain-driven, not platform - the engine is plumbing","description":"The operating discipline: build for ONE real domain/job/user, measure a real-world outcome not green tests, and treat the agent harness as plumbing not the product. The validate-first playbook.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"LESSON (value-pivot session, 2026-07-02): the exit from KB.WhyAgentProjectsStall is a discipline, now written into the IOODARI value litmus. Build for ONE real domain, ONE real job, ONE defined user - not a general platform. Measure a REAL-WORLD OUTCOME (a euro saved, hours returned, a document a buyer accepts), never green tests or part-counts. The engine/harness (SPICE\u0027s agent runtime, the crew pattern) is PLUMBING, not the product - point it at a real job; do not polish the plumbing as if it were the deliverable. The validate-first playbook, in order: (1) list the narrow candidate jobs for a real user; (2) talk to about 10 real buyers about the PROBLEM before writing code; (3) do the job BY HAND once (a concierge run on real data) to prove the value in euros and hours; (4) only then automate the PROVEN workflow. If a loop\u0027s honest output is \u0022more machinery\u0022 with no outside-world deliverable, STOP and repoint. This is the through-line the operator forced across the 2026-07-02 session (\u0022agents, agencies, crews has to be valuable, otherwise better to stop\u0022).","tags":["domain-driven","value-litmus","validate-first","plumbing-not-product","focus"],"source":"value-pivot session 2026-07-02"},{"kind":"KnowledgeArticle","id":"KB.AgUiProtocolLeg","name":"AG-UI is the agent-to-UI leg - borrow the event vocabulary, not the Microsoft SDK","description":"Why V25.40 adopted the open AG-UI protocol (the third agent-native leg beside MCP and A2A) as a native XSLT-projected SSE seam rather than taking the Microsoft Agent Framework AG-UI SDK.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"DECISION (operator \u0022do whats best for the future\u0022 \u002B \u0022is there an sdk for ag ui\u0022, 2026-05-31): AG-UI (the Agent-User Interaction Protocol) is the open, event-based standard for the agent-to-FRONTEND channel - the third leg of the agent-native trinity beside MCP (agent-to-tools, SPICE has it) and A2A (agent-to-agent, see KB.A2AAgentCardDiscovery). It is a stream of ~16 typed JSON events over SSE/WebSocket: lifecycle (RUN_STARTED/FINISHED/ERROR), text (TEXT_MESSAGE_*), tool calls (TOOL_CALL_START/ARGS/RESULT/END), and state (STATE_SNAPSHOT/DELTA). A .NET SDK exists (Microsoft.Agents.AI.AGUI client \u002B Microsoft.Agents.AI.Hosting.AGUI.AspNetCore server, Nov 2025) as part of Microsoft Agent Framework. WE DID NOT TAKE THE SERVER SDK: it is built around the framework\u0027s AIAgent \u002B Microsoft.Extensions.AI model (SPICE\u0027s agent is IAgentMessageBus \u002B competency routing \u002B the pipeline harness, NOT an AIAgent), it drags the whole Agent Framework dependency tree into a codebase whose ethos is one engine dep (SaxonCS) \u002B no-dep everything else, and it bypasses SPICE\u0027s actual moat (the XML spine \u002B XSLT projection). The one bit of real value - correct event framing - is a small typed-event set available from the spec for free. SO: borrow the standard\u0027s event VOCABULARY, emit it the SPICE way - each event is an XML envelope (AgUiEventStream), projected to spec-shaped AG-UI JSON by AgUiEvent.xslt over Saxon (XSLT 3.0 method=json) - the \u0022convert to other forms via an XSLT adaptor, never hand-rolled JSON\u0022 rule (feedback_xml_self_describing_xslt_adaptor) applied at the agent-to-UI edge, where the browser is genuinely the outside so JSON-at-the-edge is correct. Same pattern as CloudEvents/Schematron/OpenXML. REUSE-FIRST: STATE_SNAPSHOT = the existing board model (builder or spine-query); TOOL_CALL_* = a board action\u0027s Tool via IToolRegistry (the U2 dispatch, the same path MCP uses). Served: GET /agui/{board}, POST /agui/{board}/{op}. The Microsoft CLIENT SDK stays a later option IF/WHEN SPICE needs to CONSUME an external AG-UI agent (embed a partner agent in the Ship console) - that direction does not touch the spine. OWED follow-ons: deep-JSON snapshot (xml-to-json the model, not the XML string), long-lived/resumable SSE with STATE_DELTA \u002B TEXT_MESSAGE_* (wire the Ship Assistant \u002B live observability layer as the consumer - the payoff), and a spec-conformance check against the AG-UI test suite. Sources: docs.ag-ui.com/introduction ; github.com/ag-ui-protocol/ag-ui ; learn.microsoft.com/en-us/agent-framework/integrations/ag-ui ; copilotkit.ai/blog/master-the-17-ag-ui-event-types.","tags":["ag-ui","agent-to-ui","mcp","a2a","interop","xslt-adaptor","borrow-the-standard","world-intel"],"source":"SPICE.Web/Controllers/AgUiController.cs"},{"kind":"KnowledgeArticle","id":"KB.OutcomeHybridPricing","name":"SPICE prices per Sealed-division outcome atop a flat platform base","description":"World intel: hybrid pricing (flat base \u002B per-outcome) is the 2026 AI-SaaS norm proven at $100M-$400M ARR; SPICE\u0027s billable unit = one agent-built division reaching Sealed status, metered off the ArtifactPackage Sealed event.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"WORLD INTEL (probe scout, 2026-05-31): outcome/hybrid pricing is the settled 2026 AI-SaaS model and is proven at scale - Intercom Fin reached $100M\u002B ARR charging $0.99 per RESOLVED support ticket (only billing on delivered outcome) with a $1M performance guarantee; Lovable hit $400M ARR on tiered subscription \u002B per-generation credits. 43% of SaaS already uses hybrid (flat base \u002B variable consumption), projected 61% by year-end; AI-first margins run 50-60% (vs 80-90% traditional) because of compute, so usage top-ups pass inference cost to the buyer and protect margin as model costs change. FOR SPICE: define the model as a flat monthly platform fee (control plane \u002B routing \u002B gallery access) PLUS one billable unit per agent-built division that reaches Sealed status - SPICE\u0027s ApprovalGate \u002B gated-maker \u002B Sealed-status flow already defines a clean value-event, and the ArtifactPackage manifest already records identity \u002B lineage (the metering hook). Offer a 30-day satisfaction guarantee on the first deployment to kill adoption friction. AppSource transactable offers take only a 3% fee, handle invoice/tax, and let enterprise buyers spend MACC commitment - register SPICE as a transactable SaaS offer with metered pricing. Sources: thegtmnewsletter (Intercom Fin) ; sacra.com/c/lovable ; saasmag.com/how-saas-companies-monetizing-ai-agents ; dupple.com/learn/what-is-microsoft-appsource.","tags":["pricing","profit","marketplace","outcome-based","world-intel"],"source":"world-probes intel 2026-05-31"},{"kind":"KnowledgeArticle","id":"KB.ProvenanceMoatVsMicrosoftNative","name":"The SPICE moat is XSD-validated, provenance-sealed artifacts - not \u0027an agent that builds SharePoint\u0027","description":"World intel: Microsoft now auto-provisions a Copilot agent per SharePoint site (March 2026) \u002B ships a Power Apps MCP Server (GA May 2026), commoditizing the build-SharePoint loop; SPICE\u0027s defensible delta is the XML-native, Schematron-guardrailed, agency-provenance-sealed typed Envelope / ArtifactPackage.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"WORLD INTEL (probe scout, 2026-05-31) - the THREAT CLOCK is loud. Microsoft confirmed (Ignite 2025 / March 2026) that every SharePoint site now auto-provisions a ready-made Copilot agent scoped to site content, with natural-language site/list/library creation and Copilot Studio binding agents to SharePoint lists - this natively replicates SPICE\u0027s crew-provisioning \u002B Mission Division loop, licensed per M365 Copilot seat. Microsoft also shipped the Power Apps MCP Server to GA (May 4 2026), routing agents to SharePoint folders/mailboxes as unstructured sources. And Lovable ($400M ARR, Feb 2026, 200k projects/day, 50% enterprise) proves huge demand for natural-language app generation. CONCLUSION: \u0027an agent that builds SharePoint things\u0027 is no longer defensible. SPICE\u0027s moat must harden onto what Microsoft cannot commoditize and Lovable cannot provide: XML-native, XSD/Schematron-validated, agency-provenance-SEALED ArtifactPackages \u002B the typed Envelope contract - auditable schema-gated quality, provenance lineage, and cross-site composability. ACTIONS: write this strategic delta into plans/Vision.md explicitly; add a /gallery TRUST-TIER filter surfacing the ArtifactPackage manifest quality (Sealed vs Draft, schema-valid vs not) as a visible enterprise buy signal; position templates as \u0027SharePoint-on-prem-fidelity, auditable, XSD-validated, provenance-sealed artifacts\u0027 not \u0027app starters\u0027. Sources: sharepointlibrary.com/sharepoint-roadmap-2026 ; microsoft.com power-apps MCP public-preview ; sacra.com/c/lovable.","tags":["moat","threat","provenance","competitive","vision","world-intel"],"source":"world-probes intel 2026-05-31"},{"kind":"KnowledgeArticle","id":"KB.LlmProviderResilienceGate","name":"Control-plane provider resilience \u002B data-residency gate for DeepSeek-class providers","description":"World intel: DeepSeek\u0027s ~97.8% uptime and train-on-API-data ToS require a circuit-breaker fallback route \u002B a router-level data-residency gate that blocks customer-identifiable payloads from any train-on-data provider - mandatory before /gallery customer data flows.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"WORLD INTEL (probe scout, 2026-05-31): two infrastructure risks on the exact surface SPICE wants to monetize. (1) AVAILABILITY - DeepSeek had multiple 7h\u002B outages in 2025-2026 (worst 7h13m, March 30 2026) and ~97.8% trailing 12-month uptime (~8 days/year down). SPICE\u0027s Genesis crew \u002B production runs route through DeepSeek-V3, so an outage stalls EVERY gated maker run. (2) CONFIDENTIALITY - DeepSeek\u0027s ToS permits training on API-submitted data BY DEFAULT, unlike Anthropic/OpenAI/Google which exclude API data; a marketplace customer\u0027s identifiable data could leak into a competitor-trained model. ACTIONS (before any /gallery customer data flows): add a circuit-breaker FALLBACK route in the control plane (echo/stub for CI; a configurable secondary such as Anthropic Haiku for production) tripping on 5xx or timeout; add a router-level DATA-RESIDENCY competency gate that blocks customer-identifiable payloads from any train-on-data provider. This is a correctness \u002B compliance \u002B availability blast radius, not a nice-to-have. Mirrors KB.PaperclipWisdom\u0027s bounded-autonomy reflex: gate the risky path, keep the human/governance in the loop. Source: techrepublic.com (DeepSeek 12-hour outage) \u002B DeepSeek ToS.","tags":["security","resilience","data-residency","control-plane","threat","world-intel"],"source":"world-probes intel 2026-05-31"},{"kind":"KnowledgeArticle","id":"KB.SaxonHeDependencyTerms","name":"SaxonCS-HE 13.0 license, pinning, and graceful-degrade contract","description":"World intel: SaxonCS-HE 13.0 is the first free HE tier for .NET (MPL 2.0, brand-new, revocable); pin the NuGet version, recompile Saxon-12 SEFs, add an IAdvancedXmlEngine null-fallback so a future term/build change degrades the XSLT 3.0 path instead of crashing boot; adopt fn:element-to-map \u002B multi-schema validation.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"WORLD INTEL (probe scout, 2026-05-31): SPICE adopted SaxonCS-HE 13.0 (V25.12) the DAY it released (2026-05-29) - the first-ever free Home Edition tier for .NET 8\u002B (Saxon 12 for .NET was commercial-only EE). The free HE tier is brand-new, unproven at scale, MPL-2.0 licensed (source available, redistribution not straightforward), and REVOCABLE - Saxonica made the 12.x era commercial-only before, so a future 13.x minor could change terms or break the HE build. RISK ACTIONS: pin the exact Saxon NuGet version in the csproj (no auto-upgrade into a future 13.x); add an IAdvancedXmlEngine null-fallback / feature-flag so a broken HE build DEGRADES the XSLT 3.0 path gracefully instead of failing boot (the SpineQueryService already treats the engine as nullable - extend that reflex to rendering); recompile any cached SEF files (Saxon-12 SEFs are incompatible). CAPTURE the new 13.0 capabilities: fn:element-to-map (XML to JSON) is the XSLT 3.0 replacement for the hand-rolled JSON path flagged in feedback_xml_self_describing_xslt_adaptor; simultaneous multi-schema validation lets each Typed Envelope E2 per-task-type payload XSD validate independently; expression elaboration gives ~20% perf. .NET note: .NET 10 is LTS to Nov 2028; SaxonCS 13.0 targets .NET 8\u002B (compatible); do NOT target .NET 11 (STS preview) - next gate is .NET 12 LTS (2027). Source: saxonica.com/html/products/latest.html (MPL 2.0).","tags":["saxon","dependency","license","resilience","xslt","world-intel"],"source":"world-probes intel 2026-05-31"},{"kind":"KnowledgeArticle","id":"KB.StaffingTriage","name":"Replaceable-agents staffing - the deputy mechanism and the low-criticality accept decision","description":"Why the replaceable-agents/staffing theme is closed: the deputy engine auto-furnishes redundancy for every mission-critical (Lead\u002B) seat, and the residual single-covered seats are intentionally accepted because redundancy is not free for low-criticality work (the FMECA lens). The invariant a future cycle must preserve.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"DECISION (operator \u0022do a and b\u0022, verified live 2026-05-29, V24.30): the \u2605 replaceable-agents / staffing theme is CLOSED. The principle: living procedures/tools/skill-SEATS belong to the work environment (department/site/phase) and are injected; an agent is a swappable, competency-matched part slotted into a seat - swap the agent, the work stays. MECHANISM (already shipped, no new engine): (1) the /coverage board (V22.4, SeatCoverageBuilder) matches each department\u0027s declared seats (SiteBlueprint Skills/PartRef = skill@role) against placed operators, gated by EvaluateSkillCompetency \u002B role authority, labelling each seat Uncovered (0 candidates) / Covered (1 = single point of failure) / Replaceable (\u003E=2). (2) the DEPUTY GENERATOR (V22.18, ActorResolver.GenerateDeputyOperators) auto-synthesises Actor.{Dept}Deputy for every department whose maximum seat role \u003E= DeputyMinRole (default Lead, set in Scope.GeneratedOperator), converting single-covered mission-critical seats to Replaceable with zero authoring. VERIFIED LIVE (/coverage/data, V24.30): single=3, uncovered=0, replaceable=101. Engineering/Skill.ApproveRelease@Manager is Replaceable (Candidates=2) via the auto Actor.EngineeringDeputy (PartRole Manager=3 \u003E= Lead=2, so the generator fires) - the old V22.17 authority gap is closed. THE FMECA DECISION (the heart of this article): the 3 residual single-covered seats - Skill.AssistDeveloper, Skill.WriteDocumentation, Skill.ResearchTechnical - are ALL Assistant/Member level, BELOW DeputyMinRole=Lead, so the generator deliberately does NOT auto-deputise them. This is ACCEPTED, not a gap: redundancy is not free, and a comfort seat (low severity) does not earn a backup. This mirrors KB.PaperclipWisdom\u0027s bounded-autonomy reflex - spend resilience only where criticality warrants it. THE INVARIANT a future cycle must preserve: no seat bound at Lead or above is single-covered (uncovered=0 AND every Status=Covered seat has BoundRole \u003C Lead). If a new Lead\u002B seat appears uncovered/single, either place a competent operator or rely on the generated deputy - do NOT lower DeputyMinRole without intent (it would mint deputies for comfort seats and dilute the signal). To deputise a specific low-criticality seat anyway, add an explicit ActorProfile (the Actor.OperationsDeputy pattern) - but prefer the auto path (drift-free). Do NOT add an IsDeputy/Criticality field to the ActorView or SkillBinding records casually: both are positional with many callers (a field shift is a mass compile break); a per-seat Criticality attribute is the deferred fuller-FMECA model and needs XSD \u002B DepartmentRoster changes (ask first).","tags":["staffing","deputy","coverage","fmeca","replaceable-agents","decision"],"source":"memory/project_replaceable_agents_gap.md"},{"kind":"KnowledgeArticle","id":"KB.N8nWisdom","name":"n8n wisdom borrowed into the SPICE belt","description":"What the SPICE production belt borrows from n8n (the node-based workflow tool), and the decision to XSD-validate ONLY at untrusted-source boundaries. The standards-borrowing reflex (DRY) applied to the pipes-and-filters belt.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"FRAMING: n8n is a mature node-based workflow engine; its hard-won patterns map cleanly onto SPICE\u0027s content-manufacturing belt (production lines = pipes-and-filters; building-block machines = nodes). Borrow the standard rather than reinvent (feedback_investigate_online_before_inventing). FIVE n8n patterns and their SPICE form: (1) TYPED ENVELOPE - n8n passes a standard data envelope node-to-node (an items array of {json, binary}); each node reads only its slice and passes the rest on. SPICE belt was a flat string-bag; V24.3 adds a typed XML envelope (ProductionLineExecutor.PayloadKey = the {{payload}} token: \u003CPipelinePayload\u003E with \u003CInput\u003E rows \u002B a \u003CSlice station/machine/trust\u003E per step). DONE (additive; the flat keys \u002B priorOutput are unchanged). (2) EXPRESSIONS / reference-an-upstream-node-by-name - n8n\u0027s {{ $node[\\\u0022Name\\\u0022].json.x }}. SPICE form: a station declares {{payload}} and Tool.SelectXPath\u0027s any prior slice BY NAME via XPath (e.g. //Slice[@station=\u0027Research\u0027]) - not just the immediately-preceding priorOutput. DONE (V24.3, via the envelope \u002B the existing V23.15 Tool.SelectXPath). (3) VALIDATE AT THE BOUNDARY - n8n validates item structure at nodes. SPICE STEER (operator, 2026-05-28): XSD-validate ONLY UNTRUSTED sources, never trusted internal hops (matches \u0027validate at system boundaries; trust internal code\u0027). SPICE form: Scope.MachineClassification:Untrusted declares which machines cross a trust boundary (external services \u002B the model: Llm/WebSearch/DeepResearch/ArXiv/FetchKnowledge/FindStockMedia/GenerateImage/GenerateVideo); a step may declare an OutputSchema; the executor validates an untrusted step\u0027s output against it at the boundary and fails loud on reject; trusted deterministic transforms (MakePage/TransformXslt/SelectXPath) flow unchecked. DONE (V24.3). (4) PER-NODE RETRY / CONTINUE-ON-FAIL / error-workflow - n8n nodes can retry or continue past failure into an error path. SPICE today fail-fast \u002B Tool.ApprovalGate. TODO: a station-level retry/continue-on-fail policy (declared). (5) BRANCH / MERGE / IF / SWITCH \u002B TRIGGER taxonomy (webhook/cron/poll/manual) - n8n\u0027s non-linear routing \u002B trigger nodes. SPICE today: linear pipelines \u002B DecisionTable/DMN for decisions; cron standing orders \u002B webhooks for triggers. TODO: conditional multi-path routings \u002B a unified trigger part. PRINCIPLE: keep the DNA - classification \u002B schema \u002B envelope are all declared data/XML, the executor is the only engine seam.","tags":["n8n","belt","pipes-and-filters","trust-boundary","roadmap"],"source":"plans/ContentManufacturing.md"},{"kind":"KnowledgeArticle","id":"KB.CityRegistry","name":"The City Registry - the Yellow Pages for agentic parts","description":"The city\u0027s central catalogue where any agency/builder agent discovers parts (purpose, required\u002Boptional inputs, output, access level) - and the key insight that SPICE ALREADY IS this registry (the part spine, served three ways, RBAC built in). Operator vision 2026-06-07.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"FRAMING (operator vision 2026-06-07 - \u0022a clear telephone book / central web service that agencies use to see the parts like a factory: what input is required and optional, what output to choose, the general purpose/mission and services it provides; a skill or MCP for builder agents, scoped by role\u0022): KEY INSIGHT - SPICE ALREADY IS this registry. The part spine IS the catalogue, exposed THREE ways: (1) HTTP - /agency/parts, /agency/parts/by-id/{id}, /agency/parts/{kind}, /agency/tools (each Tool\u0027s ToolDescriptor = Name \u002B Description \u002B ArgsJsonSchema = its purpose \u002B required/optional inputs), /agency/skills/for-role/{role}, /agency/types (the C# structural map). (2) MCP - /mcp/jsonrpc (McpController \u002B McpRegistry) exposes Tools \u002B SavedQueries \u002B Workflows as MCP tools, and EVERY part as an MCP resource (spice://parts/{Id} with Kind\u002BName\u002BClassification\u002BMinimumRole), so an external builder agent discovers and calls the SAME catalogue (channel symmetry). (3) XQUERY - Tool.XQuery \u002B tools/parts-xq.ps1 query the merged spine live. RBAC IS BUILT IN: every Part carries MinimumRole (Assistant.Member.Lead.Manager) \u002B Classification (Public.Internal.Confidential.Restricted.Critical); IPartLibrary.AvailableTo(role, maxClassification) scopes visibility; KnowledgeArticle adds Compartment (SCI need-to-know). The operator\u0027s Creator-vs-Operator access levels MAP to PartRole: a builder/harness agent sees\u002Bdrafts at Lead/Manager; an execution crew discovers\u002Bcalls stable production parts at Member. GAP (the next arc, reuse-first - NOT a new service): Tool PARTS do not yet declare an OutputSchema, a Taxonomy path, or a Compartment (Skills/ContentTypes are richer); /agency/tools is not yet role-gated; there is no tool-to-skill capability link. The upgrade is to ENRICH the manifest on existing Tool parts \u002B add ONE registry-lookup skill/MCP face over what already serves - not build a parallel registry. See KB.OtbPartsNotCode (the OTB rule) \u002B KB.DualStageVerification (proving a part works).","tags":["registry","yellow-pages","mcp","rbac","discovery","governance"],"source":"plans/Vision.md"},{"kind":"KnowledgeArticle","id":"KB.OtbPartsNotCode","name":"OTB parts not code - a new capability is a new PART, plus the no-orphan-code axiom and RBAC encapsulation","description":"The governance rule that the city\u0027s out-of-the-box components ARE the XML parts (Tool/Pipeline/Skill/Workflow), never new C# unless a reusable core Tool/engine seam (the n8n-node analogue); agents emit schema-valid parts, never loose code; Creator vs Operator access. Operator vision 2026-06-07, translated to SPICE DNA.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"FRAMING (operator vision 2026-06-07 - the pasted spec said \u0022Python OTB / Pydantic\u0022, which is generic; SPICE\u0027s out-of-the-box components ARE the XML parts, so translate the rule to the DNA, do NOT adopt Python): THE OTB DEFAULT RULE - a new capability is a new PART (a Tool, a Pipeline/Routing, a Skill, a Workflow, a DecisionTable, a ContentType - declared in XML), NEVER new C#, EXCEPT a genuinely-new reusable CORE component: a new Tool invoker or an engine seam (interface / registry / strategy / executor) - that is the n8n-NODE analogue (the reusable block other parts plug into). C# is never business logic; rules \u002B templates \u002B content \u002B payloads live in XML/XSD/XSLT/XQuery (see reference_developer_rules \u002B KB.SpicePrinciples). THE NO-ORPHAN-CODE AXIOM: an agent must not leave a standalone code block in a text reply; every functional output is encapsulated in a schema-valid PART (validates against SAF-Parts.xsd, carries its role \u002B classification \u002B taxonomy) so it is discoverable in the registry (KB.CityRegistry), governed, and reusable - not lost in a transcript. ROLE-BASED ENCAPSULATION (maps to PartRole): CREATOR level (builder/harness agents, Lead/Manager) view \u002B draft \u002B modify part definitions across the technical nodes; OPERATOR level (execution crews, Member) discover \u002B invoke STABLE production parts only, and never see or edit the source prompt/structure. WHY THIS MATTERS: it is exactly what keeps the factory modular and self-sustaining - parts plug together like n8n nodes (KB.N8nWisdom) but stay governed by the spine, so the city can grow by adding data, not code.","tags":["otb","no-orphan-code","dna","rbac","governance","reuse"],"source":"plans/Vision.md"},{"kind":"KnowledgeArticle","id":"KB.DualStageVerification","name":"Dual-stage verification - agentic audit first, then the automated harness; plus the parallel-compare-migrate loop","description":"How a part/pipeline is proven to really work: Stage 1 agentic semantic audit (cheap, before execution), Stage 2 automated harness (free, deterministic) - mapped onto the SPICE parts that already do each - and the build-parallel, compare, switch-if-proven upgrade loop. Operator vision 2026-06-07.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"FRAMING (operator vision 2026-06-07 - \u0022where is verification that parts really work \u002B functional and technical requirements are met; FIRST agentic verification then more automated free harness checks\u0022): a part/pipeline is proven by a DUAL-STAGE quality gate, and SPICE ALREADY HAS BOTH stages - reuse them. STAGE 1 - AGENTIC SEMANTIC AUDIT (first, cheap, before execution): a crew/tool reviews the draft for logic, type \u002B taxonomy mismatch, prompt-injection and infinite-loop vectors. SPICE form: Tool.Advise (gathers the city\u0027s context, proposes, never acts - the anti-paperclip suggester), the Schematron guardrail engine (SchematronValidator - business rules the XSD cannot, emits SVRL), and Tool.DualDispatch A/B (two same-domain agencies cross-check; the eval loop scores the outcome). STAGE 2 - AUTOMATED HARNESS (free, deterministic, after audit): boot the part in isolation, inject mock inputs, assert outputs \u002B metrics. SPICE form: Tool.QualityGate (mustContain / forbid / mustMatch-XPath acceptance criteria; fail-fast HALTS the belt), XSD boundary validation (an untrusted step\u0027s output validated against its declared OutputSchema/ContentType), the unit-test suite (2871\u002B), and tools/obs-smoke.ps1 (boot \u002B assert the SERVED surface, not just the model - anti-patterns #23/#26). FUNCTIONAL vs TECHNICAL requirements: functional = the agentic audit \u002B the QualityGate acceptance criteria (does it do the job?); technical = XSD/Schematron/type-boundary \u002B telemetry (cost \u002B timing on the run genealogy). THE PARALLEL-COMPARE-MIGRATE LOOP (operator: \u0022more research says better way of work - upgrade parallel, compare, test, switch, migrate to new if proven loop\u0022): when research finds a better way, build the new part ALONGSIDE the proven one, run BOTH on the same input (Tool.DualDispatch IS this A/B harness), compare via the eval loop, and switch \u002B retire the old ONLY when the new measurably wins - never a blind replace. OWED (designed, not wired): the Schematron-to-briefing retry-with-hint loop (E3b) and a self-critique gate before sealing a single artifact.","tags":["verification","quality-gate","agentic-qa","harness","governance","eval-loop"],"source":"plans/Vision.md"},{"kind":"KnowledgeArticle","id":"KB.BusinessRulesEngine","name":"Business rules engine - we use DMN plus Schematron, not BizTalk RDL/Rete","description":"Answer to: do we have a BizTalk-style XML Business Rules Engine / Rule Definition Language (RDL)? SPICE has XML-declared business rules but borrowed the modern open standards (OMG DMN \u002B ISO Schematron) over BizTalk\u0027s proprietary RDL\u002BRete; the one gap is a true forward-chaining inference engine, which is not needed. Operator question 2026-06-07.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"FRAMING (operator question 2026-06-07 - do we have a BizTalk-style XML Business Rules Engine / Rule Definition Language RDL?): SPICE HAS XML-declared business rules, but borrowed the MODERN OPEN STANDARDS (OMG DMN plus ISO Schematron) instead of BizTalk\u0027s proprietary RDL-plus-Rete - the borrow-the-standard DNA rule (BizTalk is legacy/deprecated; the industry moved to DMN exactly here). MAPPING BizTalk BRE to SPICE: (1) Policy/ruleset to DecisionTable parts (DMN decision logic; e.g. DT.AgencyTriage via RequestToolInvoker - condition columns to an outcome). (2) Rule conditions/predicates over facts to Schematron assertions (SchematronValidator - XPath conditions emit SVRL; the business rules the XSD cannot express). (3) Forward-chaining when-X-do-Y to CrossModuleRule (CrossModuleRuleDispatcher) plus EventReceiver to Workflow to Phase (event-driven firing). (4) Rule actions/enforcement to Tool.QualityGate (mustContain/forbid/mustMatch-XPath, fail-fast HALTS the belt) plus IPolicyEngine (the write-gate). (5) Facts (XML docs/objects) to the typed envelope plus the part spine, queried by Tool.XQuery/Saxon. EQUAL-OR-BETTER for decision logic (DMN) and fact-validation (Schematron): open standard, self-describing XML, native Saxon engine, no BizTalk runtime. THE ONE GAP: no true Rete forward-chaining INFERENCE engine (assert facts into a working memory and let rules cascade iteratively until quiescence - the Drools/BRE model). DMN is single-pass decision logic; CrossModuleRule plus EventReceiver gives a COARSE forward chain (an action changes an item which fires another receiver), not a Rete loop. VERDICT: do NOT adopt BizTalk RDL/Rete - DMN plus Schematron is the 2026 consensus and covers the need; if a real multi-pass inference need ever appears, add a Rete engine behind an interface seam (a new reusable engine component per KB.OtbPartsNotCode), never a BizTalk dependency. See KB.DualStageVerification (the QualityGate/Schematron quality gates) plus reference_developer_rules.","tags":["business-rules","dmn","schematron","decision-table","biztalk","standards","governance"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.WebPartGalleryWisdom","name":"SharePoint-on-prem web part placement borrowed into the Parts Factory","description":"How Tool.MakeWebPart (the placing machine) reuses SP-on-prem web part wisdom: SPLimitedWebPartManager.AddWebPart \u002B the Web Part Gallery (_catalogs/wp) \u002B web part zones - all as XML DNA, no JSON. The standards-borrowing reflex applied to placing web parts onto pages.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"FRAMING (operator steer, 2026-05-28: \u0022reuse wisdom from sharepoint onprem\u0022 \u002B \u0022no json use our dna\u0022): SharePoint-on-prem has a mature, battle-tested model for putting web parts on pages; borrow it rather than invent (feedback_investigate_online_before_inventing, the DRY reflex). THREE SP-on-prem concepts and their SPICE form: (1) THE WEB PART GALLERY - SP keeps reusable web part definitions in the site-collection gallery (_catalogs/wp) as .webpart / .dwp XML files you pick from when adding a part. SPICE form: Scope.WebPartTemplates - a SettingScope whose each Setting Value is one \u003CWebPart Type=\u0027...\u0027 .../\u003E fragment with {{tokens}} (DATA, not code). It is the single-web-part sibling of Scope.PageTemplates (the page-LAYOUT gallery). The gallery being CURATED is itself the validation that the @Type resolves - only known web part types live there (so the Foundation tool needs no reference to the Web-layer IWebPartRegistry). (2) SPLimitedWebPartManager.AddWebPart(webPart, zoneId, zoneIndex) - the SP API that adds a web part instance into a named zone of a page at an index. SPICE form: Tool.MakeWebPart (the PLACING machine, V24.13) - clone a gallery entry BY NAME, fill its {{tokens}} (residual-token guard: an unfilled token would land in an attribute, so fail loud), read the existing ContentType.Page\u0027s Layout via the storage seam, append the \u003CWebPart\u003E into the named \u003CZone\u003E (created if absent), and re-write the item via the same provisioning seam Tool.MakePage uses. Idempotent on Type\u002BTitle (re-running does not duplicate). (3) WEB PART ZONES - SP pages declare zones; web parts live inside them. SPICE form: the existing \u003CLayout\u003E\u003CZone Name=\u0027...\u0027\u003E\u003CWebPart/\u003E...\u003C/Zone\u003E\u003C/Layout\u003E grammar (Field.Layout), reused unchanged. DNA DISCIPLINE (operator: \u0022no json use our dna\u0022): the gallery, the layout, and the provisioning op are all XML; the only JSON is the engine\u0027s pre-existing internal storage serialization (AddListItemOpHandler), read untouched - no new JSON is introduced in the authoring surface. PAIRING: this closes the task #30 pair - the reusable Projection web part (re-home a board as a web part) shipped in V23; the placing machine that puts it onto a factory page shipped now. LIMITATION-AS-RECEIPT: edits storage-backed (factory-made) pages only - a manifest-declared page shadows storage at resolution time, so Tool.MakeWebPart fails clearly for one (manifest pages are authored in the manifest). The reader-resolves assertion (anti-pattern #25) is met by the endpoint smoke (#26): GET the page and confirm the placed Projection board renders its real fragment, not a diagnostic.","tags":["sharepoint-on-prem","web-part","gallery","parts-factory","dna"],"source":"plans/PartsFactory.md"},{"kind":"KnowledgeArticle","id":"KB.CreditsAndImprovementDeck","name":"The money meter, the credits gate, and the proactive improvement deck","description":"In-app documentation for the Commerce.GalleryCredits wedge (prepaid credits = granted \u002B topped-up - burned, viewable at /board/credits with token totals), the OPT-IN consumption gate that refuses new LLM work when the balance is exhausted, and the weekly division that proactively researches system improvements and delivers a presentation deck to the Hub inbox.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"The money half \u002B the proactive-improvement half, as shipped. All of it is DATA \u002B reused seams; no bespoke billing engine.\n\n================================================================\n1 - THE CREDITS METER  (/board/credits)\n================================================================\nCredits are the SaaS unit over the city\u0027s heterogeneous LLM spend. 1000 credits = $1.\n\n  remaining = granted \u002B topped-up - burned\n\n- GRANTED: the baseline free grant, DATA at Scope.Commerce / Commerce.Credits.Granted (default 1,000,000 ~ $1000). Re-grant with no recompile.\n- TOPPED-UP: each top-up is a Paid Invoice (ContentType.Invoice, SupplierSku=SPICE.Credits) summed onto the balance. Top up at /board/credits (the \u0022Buy credits\u0022 form) or POST /gallery/topup amount=N buyer=X - $1 buys 1000 credits.\n- BURNED: the real router cost ledger (IRouterCostStore), the same ledger /board/efficiency uses.\n- TOKENS: the meter now also shows input/output token totals per call. They read 0 when the active provider does not report usage (the live DeepSeek path records cost-by-chars); they light up for a provider that returns token counts.\n\nOne source of truth (ICreditsBalance) feeds both the meter and the gate, so they can never disagree.\n\n================================================================\n2 - THE CONSUMPTION GATE  (opt-in, OFF by default)\n================================================================\nA prepaid balance only means something if it can run out. The gate (CreditsBalanceBeforeInvokeHook, a sibling of the cost-budget hook) cancels a router LLM call when the balance is exhausted.\n\n- It is INERT unless Commerce.Credits.Enforce is set true at Scope.Commerce. Shipping it changed nothing until you arm it.\n- When armed AND remaining \u003C= 0, the call is cancelled (a synthetic \u0022credits exhausted\u0022 result \u002B an audit row \u002B the cost-gate metric). Top up to lift the gate.\n- It is FARM-wide (one prepaid pool for the whole city). NOTE: arming it while exhausted blocks every agency - per-account partition \u002B a self-exclusion for the city\u0027s own survival loops are the next slice.\n\n================================================================\n3 - THE PROACTIVE IMPROVEMENT DECK  (weekly, RT-IMPROVEMENT-DECK)\n================================================================\nThe Research and Enrichment division now produces a PRESENTATION about system improvements, on its own, every Monday 07:00:\n\n  Tool.DeepResearch (research SPICE self-improvement opportunities, emit a Markdown slide outline)\n    -\u003E Tool.RenderSlideDeck (Studio: outline -\u003E a self-contained HTML5 deck)\n    -\u003E Tool.SendMail (deliver the deck to the Hub inbox, attributed to the division)\n\nRead the delivered decks at /sites/Hub/Lists/Inbox. The run seals cost-bound on /board/outcome and its spend shows on the credits meter above. Pure data (a standing-order Setting), reusing the existing Studio deck tools - no new code.","tags":[],"source":"cycles Commerce.GalleryCredits \u002B Commerce.GalleryCredits.Slice2 \u002B RT-IMPROVEMENT-DECK"},{"kind":"KnowledgeArticle","id":"KB.SystemState","name":"SPICE - the state of the system (three insights \u002B UMLs)","description":"An honest, one-page map of what SPICE actually is today: the self-building city, the XML-DNA way it is built, and the candid live-vs-parked ledger - with four generated UML diagrams (architecture, city topology, the self-build loop, the live agency cadence). The orientation page for when the breadth feels overwhelming.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"SPICE in one breath: a SharePoint-modelled, self-building city of AI agencies. It runs on 45 SharePoint sites, 7 living agencies plus an 8th it gave birth to itself, and a closed loop that lets it sense its own gaps and propose new divisions for you to approve. Everything below is the territory, not the brochure - including what is dormant.\n\n================================================================\nINSIGHT 1 - SPICE is a self-building organism, and the loop is CLOSED.\n================================================================\nThe headline capability is not \u0022agents that chat\u0022 - it is a city that grows itself. Weekly, the city ranks its most-demanded unmet capability, drafts a minimal new agency, and PARKS one approval request. You approve; a quorum flips it; the applier births the district, gives it a recurring standing order, and its first output lands in your Hub inbox. No step is faked - it has run end to end (the born agency \u0022competitormonitorpricingweekly\u0022 is live and graded). The human stays the decision-maker by design: the factory SUGGESTS, it never SEIZES.\n\n\u0060\u0060\u0060mermaid\nsequenceDiagram\n  participant City as City (DemandRanker)\n  participant Auto as Tool.AutoGenesis\n  participant Gate as ApprovalRequest\n  participant Op as Operator (you)\n  participant Q as Quorum \u002B Applier\n  participant Ag as Born agency\n  participant Inbox as Hub inbox\n  City-\u003E\u003EAuto: sense most-demanded unmet gap (weekly)\n  Auto-\u003E\u003EGate: PARK one Open request (always gated)\n  Op-\u003E\u003EGate: Approve verdict\n  Gate-\u003E\u003EQ: quorum reached - flip and apply\n  Q-\u003E\u003EAg: birth district \u002B RT-AGENCY standing order\n  Ag-\u003E\u003EAg: recurring work (Tool.DualDispatch)\n  Ag-\u003E\u003EInbox: deliver output (Tool.SendMail)\n  Inbox-\u003E\u003EOp: you read the result\n\u0060\u0060\u0060\n\n================================================================\nINSIGHT 2 - It is all XML DNA, rendered the SharePoint way. C# is only the engine.\n================================================================\nThere is no business data in code. Prompts, protocols, cron, thresholds, sites, agencies, skills, decision tables - all live as schema-validated XML parts across Parts.xml plus 13 app manifests, validated by SAF-Parts.xsd, projected to every screen through XSLT 3.0 (this very page is a KnowledgeArticle rendered by Knowledge.xslt). C# holds only idempotent engine seams: the loader, the registry, the strategy executors. That is the moat - the platform is declare-first, so adding a capability is usually adding XML, not writing code.\n\n\u0060\u0060\u0060mermaid\nflowchart TD\n  subgraph DNA[\u0022XML DNA - declare-first\u0022]\n    P[\u0022Parts.xml \u002B 13 app Parts.*.xml\u0022]\n    X[\u0022SAF-Parts.xsd / SAF-Caml.xsd\u0022]\n    M[\u0022SAF-Site-Manifest.xml (45 sites)\u0022]\n  end\n  X -. validates .-\u003E P\n  P --\u003E L[\u0022PartLibrary - loader \u002B registry\u0022]\n  M --\u003E SPV[\u0022Site provisioning\u0022]\n  L --\u003E ENG[\u0022Engine seams - C#, idempotent only\u0022]\n  ENG --\u003E XS[\u0022XSLT 3.0 transforms\u0022]\n  XS --\u003E UI[\u0022Served surfaces: /sites, /board, /observatory\u0022]\n  SPV --\u003E UI\n  subgraph APPS[\u0022Composable layers\u0022]\n    OBS[\u0022Apps.Observatory\u0022]\n    MKT[\u0022Apps.Marketplace\u0022]\n    PLG[\u0022Plugins.Saxon / DeepSeek\u0022]\n  end\n  APPS --\u003E L\n\u0060\u0060\u0060\n\nThe 45 sites are not flat - they cluster into a city with a command hub at the centre.\n\n\u0060\u0060\u0060mermaid\nflowchart LR\n  HUB[\u0022Hub - operator command center\u0022]\n  SVC[\u0022Services - taxonomies \u002B ActorMemory\u0022]\n  HUB --- SVC\n  subgraph SELF[\u0022Self-building divisions\u0022]\n    GEN[\u0022Genesis\u0022]\n    REC[\u0022Reception\u0022]\n    VEN[\u0022VentureEngine\u0022]\n    LIFE[\u0022LifeAssistant\u0022]\n  end\n  subgraph ERP[\u0022ERP modules V12-V14\u0022]\n    CMN[\u0022Common - master data\u0022]\n    DIST[\u0022Distribution\u0022]\n    FIN[\u0022Finance\u0022]\n    INV[\u0022Inventory\u0022]\n    MFG[\u0022Manufacturing\u0022]\n    CRM[\u0022CRM\u0022]\n  end\n  subgraph GOV[\u0022Governance\u0022]\n    APPR[\u0022Approvals - quorum\u0022]\n    COMP[\u0022Compliance\u0022]\n    LEG[\u0022Legal\u0022]\n    ENGG[\u0022Engineering - dogfood\u0022]\n  end\n  subgraph EXT[\u0022External portals - OIDC-scoped\u0022]\n    CLI[\u0022Client\u0022]\n    VND[\u0022Vendor\u0022]\n    EMP[\u0022Employee\u0022]\n  end\n  HUB --\u003E SELF\n  HUB --\u003E ERP\n  HUB --\u003E GOV\n  HUB --\u003E EXT\n\u0060\u0060\u0060\n\n================================================================\nINSIGHT 3 - The honest ledger: what is ALIVE, and what is PARKED.\n================================================================\nALIVE - 7 hand-built agencies, all with real recurring work graded honestly on /board/health, plus 1 the city birthed itself, plus 2 gated weekly automations (seal-a-skill and birth-an-agency).\n\n\u0060\u0060\u0060mermaid\nflowchart TD\n  subgraph LIVE[\u0022Living agencies - real cadence\u0022]\n    W[\u0022Wisdom - daily 07:00\u0022]\n    R[\u0022Research - daily 07:00 (A/B)\u0022]\n    AC[\u0022Academy - daily 09:00\u0022]\n    C[\u0022Content - daily 10:00\u0022]\n    G[\u0022Genesis - daily 11:00\u0022]\n    S[\u0022Strategy - Mon 08:00\u0022]\n    PF[\u0022PartsFactory - every 10-20 min\u0022]\n    BORN[\u0022competitormonitorpricingweekly - born\u0022]\n  end\n  subgraph GATED[\u0022Gated weekly automations\u0022]\n    EX[\u0022RT-EXTRACT - seal a proven skill (Mon 09:00)\u0022]\n    AG[\u0022RT-AUTO-GENESIS - birth an agency (Mon 10:00)\u0022]\n  end\n  LIVE --\u003E BH[\u0022/board/health - honest grading\u0022]\n  GATED --\u003E BH\n\u0060\u0060\u0060\n\nPARKED / LOST - the candid part. Roughly 17 features are intentionally parked with documented reasons (Commerce.GalleryCredits, A2UI.FormsInterop, Approvals.OneClickExtranet, the SimCity skin, the Observatory QuestBoard, SP-Field vocabulary, AddActorSkill, and more). Around 9 things are possibly orphaned rather than chosen: 7 SPICE.Apps.Erp.* project stubs that were never routed to the agency layer, the Board.Atlas builder gap, and the older OodaLoop app superseded by today\u0027s eval loop. 3 are cleanly superseded (the LiteLLM proxy, replaced by direct Baseten routing).\n\nTHE ONE HONEST GAP worth saying out loud: the money-half keeps slipping. The last several arcs were all internal (memory, self-build, the Warfront RTS). Commerce.GalleryCredits shipped only as a read-only probe. If you feel \u0022we built a lot but where is the revenue\u0022 - that instinct is correct, and it is the next feature arc, not a blind spot.\n\nWhere to look next: /board/health (live grading), /board/schedule (standing orders firing), /board/agencies (the roster), /observatory (the 3D station), /sites/Hub (your command center \u002B inbox). This page lives at /board/knowledge.","tags":["overview","state-of-the-system","architecture","uml","onboarding"],"source":"plans/AgencyArchitecture.md \u002B SAF-Site-Manifest.xml census"},{"kind":"KnowledgeArticle","id":"KB.SpicePrinciples","name":"SPICE Architecture Principles","description":"Core design principles every contributor should know","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"SPICE follows a strict layered architecture: SPICE.Core (domain, interfaces, options) has no external dependencies; SPICE.Infrastructure implements Core\u0027s interfaces; SPICE.Web composes the application. Dependencies flow inward only. Use constructor-injected DI exclusively - no static service locators. Configure with the Options pattern, not magic strings. Storage is pluggable via IStorageProvider. XSLT/XML/XSD is the declarative DNA - prefer schema-validated XML configs over JSON for the platform contract. Singletons must NOT inject scoped services directly; use IServiceScopeFactory.","tags":["architecture","principles","onboarding"],"source":"plans/ARCHITECTURE.md"},{"kind":"KnowledgeArticle","id":"KB.Manual.00-StartHere","name":"Start here - how to use this ship","description":"What this manual is, who it is for, and the chapter map.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"This is the Ship\u0027s Manual: the curated \u0022how do I use SPICE\u0022 guide. It serves three audiences from ONE source - the human operator (read this page at /board/manual), the in-app agents (query these same chapters with Tool.XQuery KnowledgeByTag(\u0027manual\u0027) or Tool.Search), and coding agents working on the repo (start at the root CLAUDE.md, which points to plans/AgentCollaboration.md).\n\nChapters, in reading order:\n- 01 Operator daily loop - the captain\u0027s morning routine: which surfaces to check, in what order.\n- 02 Platform concepts - what a part, board, agency, site and list ARE, with pointers to the deeper primers.\n- 03 Agent operating manual - how an agent works inside the city: the tool surface, deltas, and the rules.\n- 04 Dev and coding-agent setup - boot commands, ports, tooling, and the known traps.\n- 05 Find your way - the bounded ladder an agent climbs to orient without loading the whole city.\n- 06 Set up another radar or catalog - which SharePoint mechanism covers which case, in order.\n- 07 Request a service - the service catalog and the intake procedure for a new request, research above all.\n- 08 Enrol and run a worker - a seat on another machine: its composition, least privilege, the harness rules.\n\n\u0060\u0060\u0060mermaid\nflowchart LR\n  subgraph MANUAL[\u0022The Ship\u0027s Manual - /board/manual\u0022]\n    C0[\u002200 Start here\u0022] --\u003E C1[\u002201 Operator daily loop\u0022]\n    C1 --\u003E C2[\u002202 Platform concepts\u0022]\n    C2 --\u003E C3[\u002203 Agent operating manual\u0022]\n    C3 --\u003E C4[\u002204 Dev setup\u0022]\n  end\n  OP[\u0022Operator\u0022] --\u003E C0\n  AG[\u0022In-app agents - Tool.XQuery / Tool.Search\u0022] --\u003E C3\n  DEV[\u0022Coding agents - root CLAUDE.md\u0022] --\u003E C4\n\u0060\u0060\u0060\n\nBeyond the manual: the full research library (every KnowledgeArticle, 60\u002B) lives at /board/knowledge; the live self-description of the running platform is /about; every board is indexed at /board.","tags":["manual","onboarding"],"source":null},{"kind":"KnowledgeArticle","id":"KB.Manual.01-OperatorDailyLoop","name":"Operator daily loop - driving the ship","description":"The captain\u0027s morning routine: the surfaces to check and act on, in order.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"The daily loop, in order:\n\n1. The bridge - /observatory?skin=bridge. The TODAY panel answers the morning questions at a glance: is the daily brief fresh, what fires next on the schedule, and the latest eval verdicts. The rest of the bridge shows the goal, instruments and milestone ladder.\n2. The daily brief - /board/briefings. The Daily Intelligence brief lands each morning (06:35 UTC cadence, publish-gated by Eval.DailyBrief). One brief per day; if it is stale the TODAY panel says so.\n3. Standing orders - /board/schedule. Every declared Schedule with its gate verdict, last-fired and next-fire time, and catch-up flags. This is where you see whether the cadence actually ran.\n4. Quality - /board/evals. Declared-eval coverage plus recent verdict history. An honest Fail here is signal, not noise.\n5. Health - /board/health. The honest per-agency grading of the living districts.\n6. Decisions waiting on you - /approvals (quorum approvals) and the Hub inbox at /sites/Hub.\n7. Money - /board/credits (the TEST/LIVE honesty badge) and /board/outcome (cost-per-outcome).\n\nEverything else is indexed at /board - notably /board/gaps (what the city says is missing), /board/agencies (the roster), /board/registry (the yellow pages: every tool\u0027s mission, inputs and outputs), and /board/quests (suggested next actions).\n\nRule of thumb: the boards are projections of the same spine the agents read - if a board looks wrong, the data is wrong, not the paint.","tags":["manual","onboarding","operator"],"source":null},{"kind":"KnowledgeArticle","id":"KB.Manual.02-Concepts","name":"Platform concepts - what things are","description":"The five nouns that explain the whole platform, with pointers to the deeper primers.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"Five nouns explain the platform:\n\n- PART - the unit of everything. A declared XML element (Tool, Board, Agency, Schedule, Skill, Workflow, KnowledgeArticle, ...) in the merged spine (SPICE.Web/Config/Parts.xml plus each app\u0027s Parts.*.xml), validated against SAF-Parts.xsd at boot. Behavior is declared as data; C# is only the engine that executes parts.\n- BOARD - a read-only projection of the spine or a live store, rendered through XSLT at /board/{key} with an XML twin at /board/{key}/data. Around 35 exist; /board indexes them.\n- AGENCY (district) - a crew of agents with recurring, gated work (Wisdom, Research, Academy, Content, Genesis, Strategy, PartsFactory, ...). Declaring an Agency as data creates its district and eval node.\n- SITE and LIST - the SharePoint-shaped content substrate. Sites hold lists; lists hold typed items; CAML-style queries read them. The Hub site (/sites/Hub) is the operator command center.\n- EVAL - the anti-theatre instrument. Declared evals gate ships and publishes (for example the daily brief only publishes when Eval.DailyBrief passes); verdicts land on /board/evals.\n\nDeeper primers - all on /board/knowledge, do not duplicate them, read them:\n- KB.PlatformInOneSentence - the elevator version.\n- KB.SystemState - the narrative state of the system with the honest ALIVE versus PARKED ledger.\n- KB.SpicePrinciples - the layered-architecture rules every contributor must follow.\n- KB.AntiPatterns - the numbered anti-pattern ledger; cite by number.","tags":["manual","onboarding"],"source":null},{"kind":"KnowledgeArticle","id":"KB.Manual.03-AgentOperating","name":"Agent operating manual - working inside the city","description":"For in-app agents: the tool surface, how to change the city, and the rules that keep it coherent.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"How an agent operates inside SPICE:\n\nREAD before you act - the city is self-describing:\n- Tool.XQuery - query the merged spine with XQuery 3.1: any part kind, the cycle ledger, or knowledge by tag (KnowledgeByTag(\u0027manual\u0027) returns this manual). The spine is the single source of truth.\n- Tool.Search - lexical plus vector search over the KnowledgeArticle corpus when you do not know the exact id or tag.\n- Tool.FetchKnowledge - resolve live data slots (for example ListView(\u0027Issues\u0027, limit=5)) declared as KnowledgeRef elements; this fetches CURRENT list rows, a different concern from the static KB articles.\n- Tool.Advise - synthesized advice grounded in the city\u0027s filed wisdom.\n\nCHANGE the city only through declared channels:\n- Emit a ProvisioningDelta - schema-valid XML in the SAF namespace using the closed operation vocabulary. Never invent element names; follow the taught skeleton (see KB.ProvisioningDeltaPattern).\n- Runtime list writes must prefix the item key with \u0022item:\u0022 or the row is invisible to every list view.\n- Structural change beyond a delta is not yours - raise it via the Hub inbox for the operator.\n\nTHE RULES (non-negotiable, from the platform DNA):\n- Declare-first: prompts, templates, thresholds, cron, vocabularies are DATA (parts, settings, knowledge), never code literals.\n- Reuse the existing part before proposing a new one.\n- XML inside the platform; JSON only at external boundaries via an XSLT adaptor.\n- Honest output: never return an empty final silently; an eval must separate infra-error from subject-error.\n\nProtocol references on /board/knowledge: KB.AgenticToolUse (tool-use protocol), KB.ReActProtocol (the reason-act loop), KB.AgentProtocolChannels and KB.AgentSurfaceContract (how agents talk to the platform).","tags":["manual","onboarding","agents"],"source":"plans/AgentCollaboration.md"},{"kind":"KnowledgeArticle","id":"KB.Manual.04-DevSetup","name":"Dev setup - booting, tooling and the traps","description":"For developers and coding agents: boot commands, ports, offline tools, and the known footguns.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"Read plans/AgentCollaboration.md FIRST - it is the canonical brief for any agent touching the repo. This chapter is the environment cheat-sheet.\n\nBOOT (always Development, always the explicit port):\n  ASPNETCORE_ENVIRONMENT=Development dotnet run --project SPICE.Web --urls http://localhost:5198\nA bare dotnet run boots :5000 with the Echo stub and the wrong environment. Development uses the free local LLM gateway; Production defaults to a PAID provider - keep daily work on Development.\n\nOFFLINE TOOLS (query before you grep):\n- tools/parts-xq.ps1 - XPath/XQuery over the merged part spine; one query beats a 14-file grep.\n- tools/spice-validate - XSD plus well-formedness over the spine; run after ANY part-XML edit.\n- tools/spice-edit.ps1 - EDIT the spine by part Id (set Attr=Value, text Child, insert after an Id, replace, remove) as a byte-exact patch of that part only, and diff the spine against git part by part (spice-edit diff). Use it instead of text replacement; SaxonCS-HE has no XQuery Update.\n- tools/types-map - the C# structure map; also served at /agency/types.\n- tools/obs-smoke.ps1 - served smoke against :5198.\n\nTHE TRAPS (each cost a real day; cite the anti-pattern ledger, KB.AntiPatterns, by number):\n- Manifest boot-rewrite (#29): booting the app (Served tests boot too) rewrites SAF-Site-Manifest.xml. Stage your clean edit with git add BEFORE anything boots, then discard the working-tree churn. Never commit manifest churn.\n- Shared dev DB: tests and the running app share the Development database. Test cleanup must be key-scoped, never wholesale, or it wipes the operator\u0027s data.\n- Assert the served surface (#23/#25): unit tests bypass XSD and the reader path. A cycle is done only when the WRITE round-trips through the SERVED read (boot, hit the endpoint, see the data).\n- Razor fallbacks: pages render as an XML model through XSLT; never add a Razor view or keep one as a fallback. A null model is a 404. The deleted list-form fallback read rows with no permission or approval check and showed Pending pages to readers (AGT.73).\n\nVERIFY before calling anything done: full test suite green, spice-validate clean, smoke the touched endpoints on :5198, and the served round-trip proven.","tags":["manual","onboarding","dev"],"source":"plans/AgentCollaboration.md"},{"kind":"Category","id":"Cat.Machines","name":"Machines - building blocks"},{"kind":"Category","id":"Cat.Lines","name":"Production lines"},{"kind":"Category","id":"Cat.Crews","name":"Crews"},{"kind":"Category","id":"Cat.Construction","name":"Under construction - awaiting approval"},{"kind":"Category","id":"Cat.Gaps","name":"Requested - gaps to build"},{"kind":"KnowledgeArticle","id":"KB.ShipPortraitPrompt","name":"Ship portrait image prompt","description":"The declared, token-filled prompt the ShipMap page uses to draw the platform as a generation spaceship. Edit the wording here (not in code) - {{districts}}, {{machines}}, {{crews}} are filled from the live org.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"Isometric sci-fi concept art, cutaway view of a colossal generation spaceship: a whole city under a great glass dome (cupola), drifting in deep space with stars outside. Inside the dome, distinct glowing district-buildings, each a busy automated factory with conveyor belts, robotic arms and crews of worker robots moving parts between them. The labelled districts are: {{departments}}. {{machines}} machine types across {{crews}} crews. Warm interior lights, monorail belts between buildings, highly detailed, cinematic lighting, artstation, no text.","tags":["shipmap","image-prompt","template"],"source":null},{"kind":"KnowledgeArticle","id":"KB.SharePointPatternsMined","name":"SharePoint patterns mined into SPICE","description":"Which SP on-prem patterns this platform already inherits, and why","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"SPICE is built on deliberate inheritance from SharePoint on-premises mental models, not a clean-slate platform. Patterns already mined: site definitions / blueprints via SAF-Site-Manifest.xml; XSLT-based rendering via wwwroot/XSLT/MasterPage.xslt and Briefing.xslt; CAML query language constrained for safe agent authoring (SAF-Caml.xsd); property bag (IPropertyBagService); web part declarations in blueprints; permissions block in blueprints. The platform philosophy is \u0022XML/XSD/XSLT as DNA\u0022: every artifact is schema-validated XML, every transform is XSLT, agents emit XML that is XSD-checked before any state changes. This is the SharePoint-architect mental model translated to a multi-agent harness.","tags":["sharepoint","architecture","patterns"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.SharePointPatternsToDo","name":"SharePoint patterns queued for SPICE","description":"Which SP patterns are not yet implemented and which would help most","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"Patterns declared in manifests but not yet enforced or fully built: Content Types with real inheritance - a typed schema for list items so agents can emit validated structured rows; the Parent attribute on ContentType is currently advisory only. Features framework - activation-bundle composition; Feature declarations exist but do not activate coordinated parts; mapping to SPICE: a Feature part references skills\u002Bknowledge\u002Bqueries\u002Bpolicy\u002Bsettings and activates them atomically per department. Event Receivers - reactive surface (ItemAdded/ItemUpdating); maps to declarative EventReceiver parts referencing skills. Site Columns / Field Definitions - reusable typed columns shared across content types. List Templates - reusable list shapes. Term Store hierarchical taxonomy - TaxonomySearchProvider exists but is barely wired in. Search Service / managed properties as a future Target=Search CAML provider. Highest leverage to build next: Content Types \u002B inheritance. It is the foundation that lets typed audit, reports, validated list items, and content-type-aware CAML all become possible.","tags":["sharepoint","roadmap","contenttypes","features"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.PartLibraryHowTo","name":"How to add a new Part","description":"Guide for extending the SAF Part Library","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"To add a new part type: (1) define a new complexType in SAF-Parts.xsd that extends p:PartBase via xs:complexContent/xs:extension; (2) add the corresponding element under the PartLibrary root choice; (3) add seed instances to Parts.xml; (4) drop in a new IPartHandler implementation under SPICE.Web/Services/Parts/ and register it in PartServiceCollectionExtensions. The PartLibrary engine never changes - the registry picks up the new handler automatically. To add an instance of an existing type, append a new element to Parts.xml with a unique Id and the loader will pick it up at startup after XSD validation passes.","tags":["parts","howto","extension"],"source":"SPICE.Web/Config/Schemas/SAF-Parts.xsd"},{"kind":"KnowledgeArticle","id":"KB.PlatformInOneSentence","name":"The platform in one sentence","description":"The single load-bearing claim every new proposal should be checked against","version":"1.0.0","classification":"Public","minimumRole":"Assistant","body":"SPICE is a multi-agent harness where XML is the contract, XSLT is the view, the part library is the registry, phases are the unit of orchestration, deltas are the unit of change, and SharePoint is what makes enterprises adopt all of the above. If a proposal contradicts that sentence, push back before building.","tags":["architecture","core","onboarding"],"source":"plans/AgencyArchitecture.md#section-14"},{"kind":"KnowledgeArticle","id":"KB.RegistryStrategyPattern","name":"The Registry \u002B Strategy pattern that runs the platform","description":"Why every layer of SPICE is registry-driven and how to extend without touching engines","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"Every load-bearing layer of SPICE is the same pattern: a Strategy (one class per concrete kind) registered into DI; an engine that resolves the chain at request time and dispatches by element name. There are no switch statements in the engines. The pattern applies in twelve places: IPartHandler (parts), IOperationHandler (provisioning ops), IPredicateHandler (CAML predicates), IOperandResolver (context tokens), IFieldExtractor (per-row-type field access), IQueryProvider (CAML targets like Parts/Audit), and so on. To extend the platform: drop in one new class implementing the Strategy interface, register it in the matching ServiceCollectionExtensions method (one line). The engine sees it on the next request. No engine edits, no switch statements, no precedence ordering to maintain. The DI container is the registry; the engine is just iteration.","tags":["architecture","registry","strategy","extension"],"source":"plans/AgencyArchitecture.md#section-9"},{"kind":"KnowledgeArticle","id":"KB.PhasedBriefingPattern","name":"Phased briefing pattern (front-loaded context, XSLT-rendered)","description":"Why context is computed once per phase and rendered through XSLT instead of streaming","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"Each phase gets one briefing assembled before the LLM call: a complete AgentBriefing XML doc covering Mission, Hierarchy, SkillsThisPhase, ToolsAvailable, Knowledge, JitContext, Constraints, Handoff. The XML is the source of truth; the rendered Markdown\u002BYAML is just a view produced by Briefing.xslt. Why front-loaded over streaming: deterministic \u002B reproducible (same input -\u003E same XML -\u003E same prompt -\u003E same agent input; hashable for caching), policy-checkable up-front (denies happen before the LLM call), one round-trip per phase (cheaper than tool-calling chatter), audit by construction (the XML is the receipt). Tradeoff: open-ended exploration phases lose vs streaming - the escape hatch is the query/filter skill (CAML engine) so an agent that realizes mid-execution it needs more can pull, not re-prompt. C# never builds prompts by string concatenation; designers tune Briefing.xslt without touching code.","tags":["briefing","phases","xslt","onboarding"],"source":"plans/AgencyArchitecture.md#section-6"},{"kind":"KnowledgeArticle","id":"KB.ProvisioningDeltaPattern","name":"Agents emit deltas; engine applies","description":"The non-negotiable rule for state changes: schema-validated XML deltas, never direct writes","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"Agents never mutate state directly. They emit a ProvisioningDelta XML document that conforms to SAF-ProvisioningDelta.xsd. A separate Apply step commits it. Why this shape: reversible (every action is a delta; undo = inverse delta), auditable (the delta XML *is* the receipt; no parallel log), reviewable (humans or another agent can preview before Apply runs; dryRun=true short-circuits), reproducible (replay -\u003E same result), schema-bound (LLMs cannot drift; if the agent emits an op type that is not in the XSD, validation fails closed). Self-bootstrapping: SPICE provisions SPICE - the agency builds new agencies. Implementation: ProvisioningApplier dispatches each child of ProvisioningDelta to the IOperationHandler whose ElementLocalName matches. Adding a new operation type = drop one file under Services/Provisioning/, register one line. After successful apply: hot-reload PartLibrary \u002B DepartmentRoster, mirror Config/ to bin/Debug/.../Config/ (so SafProvisioningEngine sees the change without restart), re-run provisioning. The new department/skill/feature is live immediately.","tags":["provisioning","delta","safety","onboarding"],"source":"plans/AgencyArchitecture.md#section-7"},{"kind":"KnowledgeArticle","id":"KB.AntiPatterns","name":"SPICE anti-patterns (do not do these)","description":"Eight specific moves that would fight the platform\u0027s design; check proposals against this list","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"(1) Do NOT redeclare content types/lists/fields/skills inline in SiteBlueprint blocks - reference parts by Id via PartRef. (2) Do NOT add a parallel rendering stack. The Scriban/JSON path that lives alongside XSLT is scope creep, not phase 2; have it consume the same AgentBriefing XML via a different stylesheet, never two sources of truth. (3) Do NOT write to storage from agents. Always emit a delta. If you find yourself wanting to write directly, that is a new operation type that belongs in SAF-ProvisioningDelta.xsd. (4) Do NOT hardcode blueprint or phase names in C#. They live in XML. SiteDefinitionLoader.LoadProvisionedSites used to carry a frozen four-name array (a known wart) - paid in V19.2c: it now discovers SiteBlueprint names from the SAF manifest, so GetAllSiteDefinitions reflects all provisioned portals at startup. The legacy array survives only as a fallback when no IConfigurationLoader is registered. (5) Do NOT inject IStorageProvider into a Singleton (captive-dependency leak; see KB.DiCaptiveDependencyFix). (6) Do NOT auto-apply deltas. Default flow returns the delta \u002B a preview; Apply is explicit. Auto-apply is opt-in per phase, never the default. (7) Do NOT mutate Parts.xml or SAF-Site-Manifest.xml from random places. Only ProvisioningApplier writes them. Other code reads. (8) Do NOT bypass the policy engine. Every skill execution goes through IPolicyEngine.EvaluateSkillExecution first - tests too.","tags":["antipattern","guardrails","onboarding"],"source":"plans/AgencyArchitecture.md#section-10"},{"kind":"KnowledgeArticle","id":"KB.AgentProtocolChannels","name":"Agent protocols are channels over the XML spine, not parallel stacks","description":"How AG-UI / MCP / A2A map onto SPICE\u0027s three agent boundaries; the rule for adopting any new agent-interop protocol","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"The three open agent-interop protocols map exactly onto SPICE\u0027s three agent boundaries, and each is a CHANNEL (a projection/transport) over the one source of truth - the XML part library - never a parallel architecture. This extends the V11.23-V11.26 channel-symmetry matrix (SavedQuery/Tool/Workflow reachable via HTTP \u002B MCP, single payload truth): A2A and AG-UI are simply two more columns, same payloads, different transport. BOUNDARY 1 Agent-Tools/Data = MCP (Model Context Protocol, Anthropic): already core. SPICE auto-generates MCP tools/resources from the part library, ships --mcp-stdio, and exposes Tools \u002B Workflows over MCP (V11.25/V11.26). MCP is the agent surface (see KB.AgentSurfaceContract); it is internal architecture, not an external add-on. BOUNDARY 2 Agent-Agent = A2A (Agent-to-Agent, Google): the external boundary. Internal agent-agent coordination stays part-library-driven (departments, EngageConsultant, cross-dept Tool.InvokeSkill). A2A is the inter-org / inter-vendor seam (how a SPICE agency talks to another vendor\u0027s agents); tracked as V13.3 (A2A/ACP bridge). BOUNDARY 3 Agent-User = AG-UI (Agent-User Interaction): the one real gap and the only one with a posture tension. SPICE\u0027s human surface is server-rendered XSLT (request/response, SharePoint-style pages, FormView Next-step). AG-UI is for real-time, event-streamed, interactive agent-user UX (chat, streaming tool calls, generative UI). Adopt it DELIBERATELY and only when SPICE wants a streaming/conversational front-end; it is additive (another projection channel) and must not pull the model toward \u0022UI is the truth\u0022 (humans consume rendered views, agents manage via MCP/XML - KB.AgentSurfaceContract). THE RULE: any new agent-interop protocol slots into the channel-symmetry matrix as another projection over the part library; it must never become a parallel rendering/coordination stack (anti-pattern #2). MCP done; A2A is the next external boundary worth funding; AG-UI parked behind an explicit \u0022do we want streaming agent UX?\u0022 decision.","tags":["protocols","mcp","a2a","agui","channels","architecture"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.TypedEnvelopeContract","name":"The typed envelope (Agent Contract) - borrow CloudEvents \u002B Schematron \u002B content-negotiation, do not invent","description":"The standards-grounded design for a self-describing work-product envelope: a CloudEvents frame, an xsi:type per-task-type payload, Schematron output guardrails, and content-negotiated representations (md/xml/pdf via XSLT/XSL-FO). The DRY answer to \u0027envelope whose schema depends on task type \u002B a declared return type \u002B CrewAI-style guardrails\u0027.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"THE QUESTION (operator, 2026-05-30): an artifact/manifest envelope that carries BOTH typed (ContentType-validated) and untyped data, whose payload SCHEMA depends on task type (msg/task/crm/erp/manufacturing), with a declared RETURN type (markdown-of-a-ContentType / xml-by-xsd / pdf) and OUTPUT GUARDRAILS (CrewAI-style) - is there already a standard / middleware? ANSWER: yes, one per piece, and they map almost 1:1. Borrow them (DRY, the reuse-first reflex - see KB.N8nWisdom, feedback_investigate_online_before_inventing); do NOT hand-roll. CRUCIALLY the COMBINATION (CloudEvents \u002B Schematron \u002B DITA-style typed-output dispatch over an XML spine) is prior-art-free at the architecture level - so borrowing the pieces IS the differentiator, not a commodity. THE MAP: (1) ENVELOPE FRAME = CloudEvents 1.0 (CNCF, graduated 2024; has an XML format working draft, ns http://cloudevents.io/xmlformat/V1). Borrow the ATTRIBUTE VOCABULARY (type, source, id, datacontenttype, dataschema, subject, time, specversion) - keep our own XSD, not their namespace. \u0060type\u0060 = the task-type URI (spice.task.crm.contact-summary); \u0060dataschema\u0060 = the per-task-type XSD URI; \u0060datacontenttype\u0060 = the return media type. (2) PER-TASK-TYPE PAYLOAD = the xsi:type discriminator (SOAP/CloudEvents-XML) \u002B DITA topic specialization: one XSD complexType per task type, each specializing a base ArtifactPayloadBase; \u0060\u003CPayload xsi:type=\u0022spice:CrmPayload\u0022\u003E\u0060 selects it; the human-readable twin is a TaskType attribute. (3) RETURN/REPRESENTATION = HTTP content negotiation (RFC 9110 Accept) \u002B the \u002Bxml structured-syntax suffix (RFC 6839, application/vnd.spice.{ct}\u002Bxml) \u002B profile negotiation (RFC 6906/W3C, the profile URI = the XSD namespace) \u002B DITA/DocBook single-source-multi-output: one typed XML source rendered to md/html/pdf BY XSLT (pdf via XSL-FO / Apache FOP - the XSL-native path that closes the Tooling.PdfRender gap). This is exactly the platform\u0027s XML-is-truth-XSLT-adapts-to-other-forms principle (feedback_xml_self_describing_xslt_adaptor) generalized; Page.xslt already dispatches by @Type. (4) GUARDRAILS = Schematron (ISO/IEC 19757-3:2025) - the XML-native analogue of CrewAI guardrails. TWO-PASS: XSD validates STRUCTURE (grammar/cardinality/datatype), Schematron validates BUSINESS RULES (cross-field/conditional via XPath asserts, \u003Csch:assert test=...\u003E). Output is SVRL (\u003Csvrl:failed-assert\u003E); on failure inject the message into the next phase\u0027s BriefingHint and re-run (the V25.7 BriefingBuilder seam) up to a MaxRetries on the Phase. CrewAI parity is exact: output_pydantic = XSD-typed payload; guardrail-\u003E(False,error)-\u003Eretry = SVRL-\u003Ebriefing-hint-\u003Ererun; guardrail_max_retries = Phase MaxRetries. Schematron in .NET runs via its XSLT skeleton (we already have an XSLT engine). MINIMAL SHAPE: \u003CArtifactPackage type=... source=... id=... dataschema=... datacontenttype=... MaxRetries=3\u003E\u003CRepresentations\u003E\u003CRepresentation mediaType=... xslt=.../\u003E\u003C/Representations\u003E\u003CPayload xsi:type=spice:CrmPayload\u003E...\u003C/Payload\u003E\u003CGuardrailResult status=passed/\u003E\u003C/ArtifactPackage\u003E. DO NOT BORROW: the full SOAP processing model (mustUnderstand/faults) nor the full DITA-OT toolchain (our XSLT dispatch already covers it); CloudEvents specversion is useful for envelope versioning. THE RULE: a self-describing traveler must carry its schema (the .wsp Solution manifest HAS an XSD; so must ours) - the V25.8 ArtifactPackage shipped schema-less, which this arc corrects. CROSS-DOMAIN ANCHOR: this is the manufacturing TRAVELER CARD - envelope header \u002B work-piece spec (typed payload) \u002B QA gate (SVRL) \u002B rework routing (retry). EXECUTION: arc planned in plans/TypedEnvelope.md (envelope frame -\u003E per-domain payload types -\u003E Schematron guardrails -\u003E content-negotiated representations), structured for multi-agent fan-out (per-domain payload XSDs and .sch files are independent files = parallelizable; the base type \u002B GuardrailValidator engine \u002B conneg endpoint stay in main per feedback_no_subagent_structural_csharp).","tags":["standards","cloudevents","schematron","guardrails","content-negotiation","xsd","xslt","envelope","agent-contract","roadmap"],"source":"plans/TypedEnvelope.md"},{"kind":"KnowledgeArticle","id":"KB.ShipTopology","name":"Ship topology - belt is dataflow, bus is hub-and-spoke; multi-server without premature Kubernetes","description":"The platform topology decision: the production belt is intra-pipeline DATAFLOW (direct station-to-station, XProc\u0027s default connection), the agent bus is inter-agency HUB-AND-SPOKE dispatch - separate concerns, do not merge. Multi-server is possible WITHOUT Kubernetes (scale the stateless monolith on shared SQL, or distribute agencies as MCP/A2A services over the bus); k8s is an ops convenience, not a prerequisite.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"OPERATOR QUESTION (2026-05-30): should the belt go through a dispatch hub-and-spoke, and can modules run on different servers / do we need Kubernetes? DECISION. (1) BELT vs BUS - keep them SEPARATE and complementary. The BELT (ProductionLineExecutor) is intra-pipeline DATAFLOW: each station threads its primary output to the next station\u0027s primary input directly - which IS XProc\u0027s default connection. Keep it direct: fast, deterministic, local; routing every step through a hub adds a network hop and couples dataflow to messaging. The BUS (IAgentMessageBus) is inter-agency/inter-division DISPATCH: hub-and-spoke \u0022route by competency\u0022 - that is where hub-and-spoke belongs. RULE: a step that stays WITHIN a pipeline -\u003E the belt; a step that HANDS OFF to another division/agency -\u003E publish to the bus. This is the classic pipeline (orchestration) \u002B service-bus (messaging) split, mapped onto XProc-pipeline \u002B the agency bus. (2) MULTI-SERVER without premature Kubernetes - two paths, NEITHER needs k8s to start: (a) scale the STATELESS MONOLITH horizontally - N copies of SPICE.Web behind a load balancer, shared SqlServer state; handles load; k8s optional (VMs \u002B an LB suffice). (b) distribute AGENCIES as MCP/A2A services - each division runs as its own SPICE instance exposing MCP over HTTP (the HttpMcpClient seam already exists), and the bus routes across them (hub-and-spoke at the inter-agency level, see KB.AgentProtocolChannels); no k8s - separate hosts \u002B a service registry. k8s is an OPS CONVENIENCE for orchestrating many instances, NOT a prerequisite. Start single-process \u002B shared SQL; the MCP \u002B bus seams already make distribution possible later WITHOUT a rewrite - swap the in-process IAgentMessageBus transport for a real broker (RabbitMQ / Azure Service Bus) via a plugin (the engine-extension pattern) when cross-server is actually needed. Remote belt stations are possible (a heavy/specialised station - GPU render, PDF - as a remote MCP tool call; XProc supports remote steps conceptually) but only when a station is heavy enough to earn the hop; default = keep a pipeline run in one process (dataflow locality). RECOMMENDATION: do not distribute yet. Bank this decision, keep the MCP/A2A \u002B bus seams clean, scale the monolith on shared SQL first; reach for distribution (then optionally k8s) only when a real load or isolation requirement appears.","tags":["architecture","topology","belt","message-bus","hub-and-spoke","distribution","scaling","kubernetes","mcp","xproc"],"source":"plans/SystemEvolution.md"},{"kind":"KnowledgeArticle","id":"KB.XmlEnginePipeline","name":"The XML engine \u002B pipeline - SaxonCS-HE for XSLT 3.0 / XQuery, and XProc as the LLM-known pipeline vocabulary","description":"SPICE adopted SaxonCS-HE 13.0 (free, native .NET, shipped 2026-05-29) behind IAdvancedXmlEngine for real XSLT 3.0 \u002B XQuery 3.1 - the BCL is XSLT 1.0 only forever. XProc the ENGINE is rejected (no native .NET impl, JVM only); XProc the VOCABULARY is borrowed as the pipeline language because LLMs already know it - run on SPICE\u0027s own belt, steps powered by Saxon. A standard is self-describing to LLMs the way XML\u002BXSD is to outside consumers.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"WHAT (V25.12, 4dde975): SaxonCS-HE 13.0 (NuGet SaxonCS-HE, MPL 2.0, FREE, NATIVE C# - not IKVM, shipped 2026-05-29) gives the WHOLE platform XSLT 3.0 \u002B XQuery 3.1 \u002B XPath 3.1, wired behind IAdvancedXmlEngine (SPICE.Foundation.Xml, no Saxon dep so core depends only on the abstraction) with the impl in SPICE.Plugins.Saxon (engine-extension plugin, isolates the 16 transitive deps) registered by an always-active SaxonPluginModule so LoadSpicePlugins puts it in app-wide DI. System.Xml\u0027s XslCompiledTransform stays XSLT 1.0 FOREVER - do NOT repeat the stale \u0022the BCL only does XSLT 1.0 so we can\u0027t\u0022 reasoning; we can now. THE PRINCIPLE (operator insight): a W3C/ISO STANDARD is self-describing to LLMs - in an LLM-building environment the agents already KNOW XProc / CloudEvents / Schematron, so BORROW the standard\u0027s vocabulary as the language (no bespoke format to teach) and EXECUTE on SPICE\u0027s own native engine. This is feedback_xml_self_describing_xslt_adaptor aimed at the agent audience. XPROC specifically: the ENGINE is rejected (no native .NET processor - Calabash/Morgana are JVM-only; adopting it = a JVM boundary), but the VOCABULARY is borrowed as the pipeline language (p:xslt / p:validate-with-xml-schema / p:validate-with-schematron / p:identity / p:xquery; ports; the default primary-output-\u003Eprimary-input connection the ProductionLineExecutor belt ALREADY does). Borrow the standard \u002B the DNA, native engine. WHAT NOT TO DO: do not adopt XmlPrime (no NuGet, partial XSLT 3.0, commercial, no XProc) nor the IKVM Saxon wrappers (heavy, redundant now). PDF still needs an FO processor (Apache FOP = JVM, or a .NET HTML-to-PDF lib) - Saxon is XSLT, NOT XSL-FO formatting; PDF stays gated. The hand-rolled SchematronValidator (XPath-1.0, V25.11) stays as the zero-dep fallback until Saxon proves stable in production. USE IT FOR: the guardrail ISO Schematron skeleton (E3), md/html via XSLT 3.0 grouping \u002B xsl:result-document (E4), JSON-for-external via Saxon xml-to-json (XSLT-native, no hand-rolled JSON), the XProc-vocabulary belt steps, and progressively leveling up the XSLT-1.0 projection layer where 3.0 removes complexity. See also KB.TypedEnvelopeContract (the standards map) \u002B KB.AgentProtocolChannels.","tags":["xml-engine","saxon","xslt3","xquery","xproc","standards","pipeline","llm-known-vocabulary","architecture"],"source":"plans/XmlEngineUpgrade.md"},{"kind":"KnowledgeArticle","id":"KB.AgenticEngineeringResearch","name":"Research agenda - agentic-engineering patterns \u002B the agent-qualification gap","description":"Open research for a future dedicated session; maps candidate patterns to what SPICE already has so the session starts oriented, and names the one genuinely open gap","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"STATUS: research agenda, NOT decisions. Park here; pick up in a dedicated session. KEY FINDING: most named agentic-engineering patterns are ALREADY covered by SPICE - document the map first so the session does not rebuild what exists, and spends its budget on the one real gap (agent qualification / competency). Evaluate every candidate through the parts-as-truth \u002B channel-matrix lens (see KB.AgentProtocolChannels, KB.AgentSurfaceContract); resist parallel stacks (anti-pattern #2); let N=2 worked examples pull dimensions into existence rather than over-modelling upfront. PATTERN-BY-PATTERN (HAVE vs OPEN): (1) Reusable prompt library per task type - HAVE: Phase \u002B BriefingBuilder \u002B XSLT render prompts FROM parts; a Phase is a typed, composable prompt template per task type, stronger than a flat prompt file because it is schema-validated and data-driven. OPEN: confirm whether an explicit PromptTemplate part adds anything over Phase\u002BXSLT (likely not). (2) Sub-agents for specialization (planner / tester / reviewer) - HAVE: departments \u002B multi-actor rosters \u002B EngageConsultant (V11.6) \u002B cross-dept Tool.InvokeSkill (V11.7) \u002B specialized phases (Studio 6 actors, OodaLoop phase chain). OPEN: formalize a REUSABLE planner-tester-reviewer triad as a Workflow template; today specialization is per-App, not a named reusable shape. (3) Wrapper layer around tools/APIs (one clean interface) - HAVE, effectively done: IToolInvoker \u002B IToolRegistry \u002B MCP auto-generation \u002B channel symmetry; agents call Tools, never raw endpoints. OPEN: none major. (4) Human-in-the-loop propose-then-approve - HAVE, foundational: ProvisioningDelta (agents emit deltas, humans apply), anti-pattern #6 (no auto-apply by default), ContentType.ApprovalRequest \u002B quorum EventReceiver, ApprovedDeltaApplier. OPEN: optional per-phase opt-in auto-apply behind a stricter policy for low-risk tasks (faster action without losing the audit trail). (5) Plan -\u003E execute -\u003E verify predictable shape - HAVE: OodaLoop App, Workflow-\u003EPhase chains, Transitions state machine, validation phases (ExecuteValidationPhaseAsync), policy \u002B audit as the verify rail. OPEN: a canonical plan-execute-verify Workflow TEMPLATE any department reuses. THE ONE GENUINELY OPEN GAP (highest leverage) - AGENT QUALIFICATION / COMPETENCY: SPICE conflates AUTHORITY (PartRole, a single linear axis ordered Assistant, Member, Lead, Manager) with COMPETENCY (what cognitive work an agent is actually good at). Cognitive tier lives on the Phase (UsesModel, Mode), not the agent, so a department asking for a role gets a permission level, not a competency guarantee. There is NO mechanism to test/qualify/certify an agent for a position before it works (searched: qualif/competen/certif/audition/assess/eval - absent). And ActorProfile.SkillCatalog (the per-agent allowlist of skills) is ADVISORY - IPolicyEngine.EvaluateSkillExecution never checks it (latent hole: config implies a constraint the runtime does not enforce). SHAPE IF BUILT (data\u002Benforcement, not new engine): cheapest first step = enforce SkillCatalog in IPolicyEngine (turn advisory allowlist into a real one - delivers fine-grained what-an-agent-can-do immediately). Full version = a Talent/Qualification department (the consultancy-agency idea) as a worked-example App: ContentType.Competency \u002B ContentType.Certification (agent x competency x verdict x evidence x expiry) \u002B a qualification Workflow whose Phase runs an eval skill against a candidate and writes a certification row; enforcement stays in the shared policy gate (cross-cutting, never siloed in the site); the reference matrix = a cross-site list-view projection (agent x competency x certified-at), not a new subsystem. CAUTION: do not model 40 competency dimensions upfront; start binary (certified per skill yes/no), add a competency TIER per skill only when a real phase needs Lead-level-vs-Member-level reasoning. FRAMING: this is Pillar 5 (agentic access) done properly - give each agent exactly the breadth its proven competency warrants. Companion analysis was produced 2026-05-25; this article is the durable carrier.","tags":["research","roadmap","agents","qualification","competency","prompt-library","subagents","hitl"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.ShipCriticality","name":"Ship-systems criticality - the FMECA lens for prioritising SPICE","description":"How SPICE classifies subsystems and backlog by failure-criticality, borrowing FMECA / IEC 60812 \u002B NASA criticality categories instead of an ad-hoc triage","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"FRAMING (user, 2026-05-26, \u0022compare this like a spaceship and life-support, is there a standard ISO?\u0022): YES - the discipline is FMECA (Failure Mode, Effects and Criticality Analysis), standardised as IEC 60812:2018 (the 2018 edition added software/service examples \u002B a criticality-matrix method). NASA operationalised it on Apollo (1966) to prevent life-support-class failures. Sibling rigor standards: IEC 61508 (SIL 1-4) and DO-178C (DAL A-E) set how much redundancy/assurance a component must have, scaled to its criticality. Lightweight cousins we had been using informally: MoSCoW and the Eisenhower urgent x important matrix. THE INSIGHT FMECA ADDS that our ad-hoc urgent/important/critical triage blurred: criticality is not one axis. Rank by SEVERITY (what happens to the SHIP if this is absent/broken) x OCCURRENCE (how likely) x DETECTION (would we even notice it failed) = Risk Priority Number. The DETECTION axis is the one SPICE keeps getting bitten on: the V21.4 regression (all 40 blueprints silently down, masked by SQL persistence) was catastrophic precisely because Detection was near-zero. The fixes we banked - fail-loud-in-Dev provisioning, the PROVISION HEALTH smoke line, ArchitectureConventionTests - were us RAISING DETECTION on a Crit-1 subsystem. We were doing FMECA by instinct; this article names it. NASA-STYLE CRITICALITY CATEGORIES APPLIED TO SPICE: Crit 1 (life-support) = ship cannot run or runs unsafely without it: boot \u002B provisioning, the cost gate (runaway spend = mission loss), the competency/policy gate (wrong agent acts), the rate gate (V22.17). Crit 2 (mission) = ship runs but cannot do the work: seat coverage/staffing, the router fallback chain, the response cache (degrades to slow, not broken). Crit 3 (comfort) = quality-of-life, not load-bearing: the visual boards (/organogram, /lifecycle, ...), PDF, extra dashboards. HOW TO APPLY: (1) prioritise the backlog by Severity-of-absence, not by novelty or business polish; raise Detection on every Crit-1 subsystem (fail-loud \u002B health-smoke \u002B convention-test) - low Detection on a Crit-1 system is itself a Crit-1 defect. (2) Put REDUNDANCY where Severity is highest, exactly like spacecraft triple their life-support and not their cupholders. This is why V22.18 deputies are criticality-driven: a deputy (a competency-matched backstop) is generated for departments whose seats carry mission-critical authority (BoundRole \u003E= Lead), flipping those seats single -\u003E Replaceable, while Crit-3 comfort seats are left single (redundancy is not free; spend it where loss stops the ship). v1 LIMITATION (feedback_limitation_as_receipt): Severity is proxied by seat AUTHORITY (BoundRole). The fuller FMECA model is a declared per-seat Criticality (1/2/3) attribute \u002B an Occurrence/Detection score; deferred until a real case needs finer than authority-as-proxy. RELATED: this is the standards-borrowing reflex (feedback_investigate_online_before_inventing) applied to a prioritisation MODEL, not an XSD.","tags":["prioritisation","criticality","fmeca","iec-60812","resilience","standards"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.NeedToKnowCompartments","name":"Need-to-know knowledge compartments - the military SCI model for agent briefings","description":"Why agents are briefed on a need-to-know basis, borrowing Bell-LaPadula MLS \u002B SCI compartmentalization, and how the Compartment axis works","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"FRAMING (user, 2026-05-26, \u0022give ship employees only the KB they need, not all our core ship secret workings; are there army standards?\u0022): YES - this is the U.S. DoD multilevel-security model, formalised as BELL-LAPADULA, the basis of military MLS. Access has TWO INDEPENDENT AXES: (1) CLEARANCE LEVEL - Unclassified \u003C Confidential \u003C Secret \u003C Top Secret, enforced as \u0022no read up\u0022. SPICE already has this: Classification (Public/Internal/Confidential) \u002B MinimumRole = the clearance level, applied by IPartLibrary.AvailableTo. (2) COMPARTMENT / NEED-TO-KNOW - TS/SCI (Sensitive Compartmented Information): each compartment is a domain (SIGINT, HUMINT, ...); an analyst cleared Top Secret still only sees the compartments they are READ INTO. SPICE was MISSING axis 2 - which is why every Internal-cleared operator was briefed the platform-engineering KBs (KB.SpicePrinciples, KB.SharePointPatternsMined, ...): a textbook compartmentalisation failure. THE FIX (V22.21): KnowledgeArticle gained a Compartment attribute (default \u0022Platform\u0022 - secure-by-default). BriefingBuilder applies a single mandatory reference-monitor check (IsReadInto) to EVERY article entering a briefing, from both the explicit-query and default-bundle paths: a department gets an article iff (a) its compartment is the universal \u0022Operator\u0022 compartment (general domain knowledge), (b) the compartment names that department (dept-owned KB), or (c) the department is in the compartment\u0027s read-in roster - DATA in Scope.KnowledgeCompartments ({Compartment}.ReadInDepartments), so who-is-cleared-for-what is policy not code. The dogfood Engineering department is read into Platform (it legitimately works ON the ship), so it still gets the architecture KBs; operator departments do not. HOW TO AUTHOR: a domain KB an operator should see = Compartment=\u0022Operator\u0022 (or name its department); platform/engineering/meta knowledge = leave the default \u0022Platform\u0022. RELATED STANDARDS: ABAC (NIST SP 800-162) is the general attribute-based form; this is the standards-borrowing reflex (KB.ShipCriticality borrowed FMECA the same way - see feedback_investigate_online_before_inventing). LIMITATION (feedback_limitation_as_receipt): v1 compartments are flat strings with a per-compartment read-in list; full Bell-LaPadula lattice composition (a clearance dominating a set of compartments) is deferred until a real case needs more than read-in lists.","tags":["security","need-to-know","compartmentalization","bell-lapadula","standards","briefing"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.RetentionLifecycle","name":"Records retention and auto-declassification - the ISO 15489 \u002B military downgrade lifecycle","description":"Why content types carry a retention/lifecycle policy, borrowing ISO 15489 records disposition \u002B military auto-declassification, and how the Retention grammar \u002B IRetentionPolicy reference monitor work","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"FRAMING (V22.24, KB.ShipGovernance Pillar 3 - records lifecycle, the platform\u0027s biggest SharePoint-governance gap): SPICE records lived forever at their declared classification. Real records management does NOT - it borrows TWO converging standards (DRY, the standards-borrowing reflex - see feedback_investigate_online_before_inventing). (1) ISO 15489 / records management: every record class has a DISPOSITION SCHEDULE - retain for a defined period measured from a basis date, then dispose (destroy) or transfer. NARA/DoD 5015.2 formalise the same retain-then-act schedule. (2) MILITARY AUTO-DECLASSIFICATION (E.O. 13526): classified information is automatically DOWNGRADED after a set interval (typically declassified at 25 years) unless re-marked - the classification is not permanent, it decays on a schedule. These are the same shape as the Bell-LaPadula axes already adopted (KB.NeedToKnowCompartments): there, classification gates WHO reads; here, TIME gates HOW LONG it stays at that classification.\n\n    THE GRAMMAR (V22.24): ContentType gained an optional \u003CRetention RetainForDays=\u0022...\u0022 ThenAction=\u0022Expire|Downgrade\u0022 DowngradeTo=\u0022Public\u0022 Basis=\u0022Created|Modified\u0022/\u003E block (additive init-only, mirrors the V12.0b Transitions shape; absent = the V11.1 \u0022lives forever\u0022 contract preserved). After RetainForDays from the Basis timestamp: Expire = due for disposal (ISO 15489 destruction); Downgrade = effective classification drops to DowngradeTo (auto-declassification - never RAISES, never below Public). Inherited down the Parent chain (leaf-wins), same precedence as Transitions/FieldRefs.\n\n    THE REFERENCE MONITOR (V22.24): IRetentionPolicy (DefaultRetentionPolicy, Singleton) resolves a ContentType\u0027s effective policy - declared on the type, inherited from an ancestor, or the org-wide default from Scope.Retention (DefaultRetainForDays/DefaultThenAction - DATA, not code, mirroring how Scope.DataResidency/Scope.KnowledgeCompartments hold their policy). Evaluate(ct, classification, basisTime, now) returns a RetentionVerdict: NotGoverned / Active (within window) / Due (\u002B Action \u002B the downgraded EffectiveClassification). The disposition decision is a pure static EvaluatePolicy (directly testable, no part library), the same testability seam the other monitors use. This is the fourth governance reference monitor after policy-engine competency, the need-to-know compartment monitor, and the NOFORN data-residency guard.\n\n    OBSERVABLE (board-as-gate): GET /retention projects the disposition schedule (builder -\u003E XML -\u003E XSLT, the house pattern) - one row per content type with a declared/inherited policy, the org default in the header. Pure part-data so it boots offline (no list items needed). Worked examples seeded: ContentType.Contract retains 2555d (~7y) then Expire (legal/tax record-keeping); ContentType.ArchitectureDecisionRecord retains 365d then Downgrades Internal -\u003E Public (the architectural reasoning becomes historical, safe to publish).\n\n    CROSS-FEATURE NOTE: auto-declassification COMPOSES with the NOFORN gate (KB.ShipGovernance Pillar 1) - a record that downgrades below the ExternalForbiddenClassifications floor becomes eligible to leave the box, exactly as the military intends (declassified material is releasable). LIMITATION (feedback_limitation_as_receipt): v1 evaluates a record\u0027s verdict on demand against an injected timestamp; there is no scheduled job that walks the lists and ACTS on Due records (purge / re-mark). The grammar, monitor, and board are the policy spine; the enforcement job (an ItemAdded/cron sweep that applies the verdict) is the deferred next step, gated on the live-item dimension the read-only board doesn\u0027t need.","tags":["governance","retention","records-management","iso-15489","declassification","standards","lifecycle"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.ShipGovernance","name":"Ship governance model - SharePoint on-prem pillars fused with military classification (Bell-LaPadula/SCI)","description":"The unified governance constitution: the five SharePoint on-prem governance pillars, each reinforced by how the US military classification system actually works, mapped to SPICE with the gaps named. Borrowed, not invented (DRY).","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"PURPOSE (user, 2026-05-26): adopt ONE governance model = the SharePoint on-prem pillars WITH the military need-to-know system inside them; study how each actually worked and reuse it (DRY). KEY INSIGHT: the two traditions are the SAME governance shape, and they reinforce each other - SharePoint gives the enterprise-document mechanics, the military gives the harder access semantics. SPICE keeps SharePoint\u0027s structure and upgrades it to the military\u0027s strictness where it matters.\n\n    THE FIVE PILLARS (SP mechanism \u002B military reinforcement -\u003E SPICE):\n    PILLAR 1 - ACCESS CONTROL. SP: permission LEVELS (7 levels, defined at site-collection top, INHERITED down site-\u003Esubsite-\u003Elist-\u003Efolder-\u003Eitem, with break-inheritance) \u002B AUDIENCE TARGETING (target web parts/nav/items to groups). CRITICAL SP CAVEAT (from the docs): audience targeting is VISIBILITY, not security - it hides, it does not deny. MILITARY: three CLEARANCE LEVELS (Confidential\u003CSecret\u003CTopSecret, EO 13526) with no-read-up (Bell-LaPadula) \u002B SCI COMPARTMENTS (need-to-know beyond clearance, segregated by discipline) \u002B DISSEMINATION CAVEATS (NOFORN = no release to foreign/outside parties regardless of clearance; ORCON = originator controls and tracks who holds it). SPICE: clearance LEVEL = Classification \u002B PartRole (inherited via the part hierarchy); COMPARTMENT = KnowledgeArticle.Compartment \u002B the BriefingBuilder reference monitor (V22.21) - and unlike SharePoint we made the compartment a REAL mandatory gate (deny, not just hide), matching the military model. OWED: (a) one shared reference monitor (LEVEL x COMPARTMENT x CAVEAT) reused across ALL surfaces - briefings, web parts, navigation, skill invocation - finishing SP Audience-Targeting parity but as real access control; (b) HANDLING CAVEATS - the NOFORN analogue is now Crit-1 because V22.20 wired a REAL EXTERNAL LLM (Baseten): Confidential or platform-compartment content MUST NOT be sent to an external inference provider. ORCON analogue = originator/department approval before a part crosses a site boundary (partly present as ApprovalRequest \u002B EngageConsultant intents).\n    PILLAR 2 - INFORMATION ARCHITECTURE / AUTHORITY. SP: Content Type Hub (a central site collection is the official source of content types \u002B site columns, PUBLISHED/syndicated to subscribers via timer jobs - replication not immediate). MILITARY: Original Classification Authority - a designated authority defines what is classified and at what level; everyone else inherits/derives. SPICE: the Part Library \u002B Config manifest IS the content-type hub (central source, manifest-syndicated, schema-validated by SAF-Parts.xsd); classification/compartment LABELS are authored centrally and inherited by parts. STATUS: strong - this is SPICE\u0027s spine.\n    PILLAR 3 - LIFECYCLE / COMPLIANCE. SP: Information Management Policies per CONTENT TYPE (or list/library) - retention, expiration, auditing, labels, barcodes; auditing logs view/edit/checkin/checkout/delete/permission-change. MILITARY: DECLASSIFICATION schedules - automatic declassification after 10 or 25 years from original classification, with marked exemptions (e.g. 50X1 for sources and methods). Both are the SAME idea: content has a TIME dimension - it expires, downgrades, and every access is logged. SPICE: IAuditLog covers auditing (strong). GAP (the biggest): no retention / expiration / auto-downgrade policy engine. Borrow ISO 15489 (records management) \u002B the military auto-declassification shape: a per-ContentType policy with retain-for / then expire-or-downgrade.\n    PILLAR 4 - SERVICE GOVERNANCE. SP: service applications (Managed Metadata, Search, User Profile) administered centrally, consumed by site collections via PROXIES. MILITARY: central control systems (each SCI program run centrally, accessed under procedure). SPICE: the Hub / service-application pattern (ServicesPortal, channel symmetry, proxy introspection). STATUS: strong.\n    PILLAR 5 - OPERATIONAL GOVERNANCE. SP: quota templates (storage), site locks, self-service site creation policy, sandboxed-vs-farm solutions (Solution Gallery code governance), site-collection audit settings, the written Governance Plan (roles: steering committee, site owners, IT). MILITARY: access logs, two-person control, the security officer role. SPICE: CostBudget \u002B rate gate (V22.17) = quota reframed from storage to SPEND and CALL-RATE (the right quota for an agent ship); provisioning-DELTA \u002B ApprovalRequest = governed self-service creation (agents propose, humans approve - anti-pattern #6); plugins \u002B layered assemblies = the farm/sandbox split; IAuditLog = audit settings; /onboarding \u002B /coverage \u002B /organogram = the living Governance Plan / org view. STATUS: strong.\n\n    SCORECARD: Pillars 2, 4, 5 strong; Pillar 1 strong on level\u002Bcompartment, OWED on shared-monitor \u002B handling-caveats (external-LLM NOFORN is Crit-1 now); Pillar 3 (lifecycle/retention) is the biggest gap. PRIORITISED CYCLES (criticality-ordered, KB.ShipCriticality lens): V22.23 external-disclosure caveat (NOFORN - Crit-1, newly urgent post-Baseten); V22.22 generalise the governance reference monitor across surfaces (SP Audience-Targeting parity as real MAC); V22.24 lifecycle/retention policies (Pillar 3 gap, borrow ISO 15489 \u002B military declassification). PRINCIPLE: this whole article is the standards-borrowing reflex (feedback_investigate_online_before_inventing) applied to governance - keep SharePoint\u0027s shape, adopt the military\u0027s strictness, invent nothing.","tags":["governance","security","sharepoint","bell-lapadula","standards","roadmap"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.DecisionRecord","name":"Architectural decisions and their rationale","description":"Concise log of load-bearing decisions made across SPICE\u0027s design cycles, with the alternative considered and why it was rejected","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"D1: XML/XSD/XSLT as DNA, not JSON/Scriban. Alternative considered: modern JSON\u002Btemplate engine. Rejected because the platform value depends on agent-authored content being XSD-validatable end-to-end, and SharePoint mental-model continuity for enterprise architects. D2: CAML at the agent interface, not XPath strings. Alternative: full XPath. Rejected because XPath strings cannot be schema-constrained the way CAML XML can; agent-authored XPath would need a custom parser/whitelist. D3: Strategy \u002B Registry for every layer instead of switch statements. Alternative: typed switch in each engine. Rejected because each new feature would require engine edits; the registry pattern means the engines are written once. D4: Front-loaded phase context (briefing built before invocation), not streaming/tool-loop. Alternative: progressive tool-calling. Rejected for happy-path determinism, audit, caching, cost; reserved tool-calling as the escape hatch via the CAML query skill. D5: Agents emit ProvisioningDelta XML, never write directly. Alternative: agents call storage APIs. Rejected because indirection through schema-validated XML is what makes LLM output safe to apply. D6: Settings cascade Farm-Department-Phase-Skill-Invocation, last match wins. Alternative: flat global config. Rejected because per-department/per-phase tuning is core to multi-tenant agencies. D7: Content Types via xs:extension and Parent IDREF. Alternative: flat content types. Rejected because SharePoint compatibility and field reuse depend on inheritance. D8: MCP tools auto-generated from SavedQuery parts, not hand-coded. Alternative: separate hand-curated MCP server config. Rejected because two sources of truth would drift; the part library is canonical. D9: Audit log queryable as Target=Audit through the same CAML engine. Alternative: separate reporting API. Rejected because every cross-cutting query surface should compose with the others, not become its own silo. D10: Test project covers the registry-driven layers (xUnit). Added late but locks in correctness as the platform grew broad.","tags":["decisions","adr","history","onboarding"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.AgentFormFilling","name":"How an agent fills out a list form","description":"Use Tool.ListSchema to learn the field shape, then emit AddListItem with matching field names. Same JSON also at /sites/{X}/Lists/{Y}/_schema.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"When a skill needs to file a list item (ApprovalRequest, Issue, WikiPage, etc.), the agent should NOT guess the field names. Two access modes: (1) FrontLoaded mode - declare \u003CUsesTool ToolId=\u0022Tool.ListSchema\u0022 Args=\u0022site={{department}};list=ApprovalRequests\u0022/\u003E on the Phase, and BriefingBuilder pre-fetches the JSON Schema into the briefing\u0027s # Live data block; (2) ToolLoop mode - the agent calls Tool.ListSchema mid-execution when it realises it needs the field shape (progressive disclosure). The returned JSON Schema document carries: title (the list name), x-spice-content-type (the resolved ContentType), x-spice-lineage (inheritance chain), required[] (which fields must be present), properties{} (one entry per field with type \u002B enum \u002B default \u002B x-spice-format hints). Field types map: Text/User/Url/Note -\u003E \u0022string\u0022 (Note adds x-spice-format=textarea, User adds x-spice-format=user); Number -\u003E \u0022number\u0022; Boolean -\u003E \u0022boolean\u0022; DateTime -\u003E \u0022string\u0022 with format=date-time; Choice/MultiChoice -\u003E \u0022string\u0022 with enum array. Same XSLT (wwwroot/XSLT/ListSchemaJson.xslt) drives both Tool.ListSchema and the HTTP endpoint, so the agent surface and the human form are projections of one ContentType - changing a field updates both. After fetching the schema, agent emits a ProvisioningDelta with \u003CAddListItem List=\u0022ApprovalRequests\u0022 Site=\u0022Approvals\u0022\u003E and one \u003CField Name=\u0022Subject\u0022\u003Evalue\u003C/Field\u003E per property; required[] determines what\u0027s mandatory; default values shown by the schema can be omitted. The applier validates the payload against the resolved ContentType before writing.","tags":["agent","forms","schema","tool-loop","front-loaded"],"source":"SPICE.Web/wwwroot/XSLT/ListSchemaJson.xslt"},{"kind":"KnowledgeArticle","id":"KB.ExtensionRecipes","name":"How to extend SPICE (one-liner per axis)","description":"The minimum-edit recipe to add each kind of declarative concept","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"New part TYPE: extend PartBase in SAF-Parts.xsd via xs:extension; add element under PartLibrary root choice; create C# record \u002B IPartHandler under Services/Parts/; register in AddPartHandlers. New part INSTANCE: append element to Parts.xml. New CAML predicate: implement IPredicateHandler in Services/Caml/PredicateHandlers.cs; register in AddCamlQueryEngine. New CAML context token: implement IOperandResolver; register. New CAML target backend: implement IQueryProvider; register. New ProvisioningDelta operation: extend SAF-ProvisioningDelta.xsd; implement IOperationHandler under Services/Provisioning/; register. New department: AddSiteBlueprint delta with optional Feature/PartRef children, then Apply. New skill bound to a dept: AddSkillBinding delta. New MCP tool: append a SavedQuery part. New MCP resource: any new part is automatically a resource. New setting: append a Setting child to a SettingScope, or create a new SettingScope at the level you want. New ContentType: extend an existing one via Parent attribute and reference FieldDefinition parts via FieldRef. New EventReceiver: add an EventReceiver part referencing the skill to fire and the ContentType filter. New Feature (activation bundle): add a Feature part with BindSkill children; activate via ActivateFeature delta or by including Feature children in AddSiteBlueprint.","tags":["howto","extension","recipes","onboarding"],"source":"plans/AgencyArchitecture.md#section-11"},{"kind":"KnowledgeArticle","id":"KB.SelfListLookupConvention","name":"Self-list Lookup convention for parent-ref fields","description":"V15.1a/b/c: child-to-header parent-ref fields are Lookup with no LookupSite (defaults to current department). Composite-key parents (BOM, Routing) get a synthetic single-field ID rather than a multi-key Lookup attribute.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"Child rows referencing a same-department header (SalesOrderLine -\u003E SalesOrder, InvoiceLine -\u003E Invoice, JournalEntryLine -\u003E JournalEntry, Payment -\u003E Invoice, ProductionOperation -\u003E ProductionOrder, ShipmentNotice -\u003E SalesOrder, BomComponent -\u003E BillOfMaterials, RoutingOperation -\u003E Routing, ProductionOrder -\u003E BillOfMaterials/Routing) use FieldType=Lookup with LookupList set to the header list name and LookupDisplayField set to the header\u0027s identifying field (OrderNumber, InvoiceNumber, JournalNumber, BomId, RoutingId, etc.).  LookupSite is omitted - ListViewModelBuilder.LoadLookupOptions resolves \u0060targetSite = LookupSite ?? department\u0060, so omitting means \u0022look up against the current department\u0027s list of the same name.\u0022  The \u0022engine-side self-list seam\u0022 deferred at V13.6 and queued for V14.7 turned out to be a phantom requirement - the engine already covered it.  V15.1a/V15.1b banked the convention as XML across 7 single-field parent-refs.  V15.1c resolved composite-key parent-refs (BomComponent \u002B RoutingOperation \u002B ProductionOrder.BomVersion/RoutingVersion) via **synthetic IDs on the header** rather than a multi-key Lookup attribute: BillOfMaterials gained Field.BomId (convention BomId = ProductSku \u002B \u0027-v\u0027 \u002B Version, operator-assigned, e.g. WIDGET-A-v1.0); Routing gained Field.RoutingId similarly.  Child fields then ride the single-field convention.  Why synthetic-ID-on-header over engine-side LookupCompositeKey: KISS - the platform already supports single-field Lookups, so adding the synthetic ID composes with V15.1a/b instead of adding a new attribute \u002B FormView semantics \u002B ListView semantics.  Mirrors how every other line CT in the platform works (OrderNumber, InvoiceNumber) and matches SAP/BaaN/NetSuite convention.  Storage shape: the Lookup stores the parent row\u0027s storage ID (standard Lookup behaviour); FormView and ListView render the LookupDisplayField text via the @Display attribute.  CrossModuleRule rewrite cost at V15.1c: the V14.2c Rule.Tm.ProductionOrderReleased CAML \u0060\u003CWhere/\u003E\u0060 simplified from And(Eq(ProductSku), Eq(BomVersion)) to a single Eq(BomId); ParamRef Name=\u0022BomId\u0022 picks up ProductionOrder.BomId at event time.  When adding a new line-item ContentType: prefer single-field identity on the header (OrderNumber, DocumentNumber, or synthetic-ID if the natural key is composite); declare the child\u0027s parent-ref as Lookup with no LookupSite from day one.","tags":["fielddefinition","lookup","contenttype","convention","v15"],"source":"SPICE.Web/Services/ListViewModelBuilder.cs"},{"kind":"KnowledgeArticle","id":"KB.DiCaptiveDependencyFix","name":"Fixing captive scoped-singleton DI bugs","description":"The IServiceScopeFactory pattern for safely consuming scoped services from singletons","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"If a Singleton service injects a Scoped service directly, the Scoped instance and its dependencies (e.g. DbContext) become captive: held by the Singleton forever, leaking memory and causing thread-safety issues under concurrent requests. Fix: inject IServiceScopeFactory instead, then for each call create a fresh scope with \u0060using var scope = _scopeFactory.CreateScope(); var svc = scope.ServiceProvider.GetRequiredService\u003CTScoped\u003E();\u0060. Cache hot-path read results in the singleton (e.g. ConcurrentDictionary) to avoid scope-creation overhead per call.","tags":["di","antipattern","scoping"],"source":"SPICE.Web/Services/SiteDefinitionLoader.cs"},{"kind":"KnowledgeArticle","id":"KB.AgentSurfaceContract","name":"Platform surface contract: agents manage, humans consume","description":"The platform exposes exactly two surface families to the outside world: typed tool calls for agents (MCP, auto-generated from the part library), and rendered sites/lists/admin for humans (XSLT-projected). Everything else is internal.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"This platform is for agents to MANAGE and humans to CONSUME the products. Two non-negotiable surface families flow from that positioning. (1) AGENT SURFACE - typed MCP tool calls. Every Phase, Workflow, Tool, Skill in the part library auto-publishes as an MCP tool with JSON-Schema-derived typed args (cycle X4 \u002B V11.7 wire this through --mcp-stdio). The agent never writes a CAML query, an XPath expression, or an XSLT template; it calls Tool.X(typed-args) and the platform routes through IPhaseOrchestrator. CAML, XPath, XSLT, XSD are PLATFORM INTERNALS - they validate inputs/outputs and drive projections, but the agent\u0027s contract is \u0022here is a typed tool, here are typed args, here is typed output\u0022. (2) HUMAN SURFACE - rendered web. /sites/X/Lists/Y projections, /admin cards, /agency/* endpoints, all XSLT-projected from the same registry. No CLI. A CLI surface would be a third path that duplicates the agent path (agents already invoke via MCP) and bypasses the human path (humans already see rendered sites); doesn\u0027t earn its weight. (3) WHY XML AS THE INNER CONTRACT - LLMs are highly fluent with XML structure (massive HTML/SVG/XHTML training corpus, plus Anthropic\u0027s tool-use protocol IS XML-tag-wrapped under the hood). The V11.1 typed-XML output contract leans into this. V11.12 JSON option is a token-cost optimisation, not a fluency win. (4) DOMAIN FRAMING - the platform is enterprise/corporate (Farm -\u003E Division -\u003E Department -\u003E SubDept hierarchy; SiteBlueprint, Hub, Feature - SharePoint-style organisational metaphors), NOT civic/city/P2P. Inter-department communication mediates through IConsultancyService.EngageAsync (with audit \u002B policy \u002B cost gates); same-department cross-actor invocation goes through Tool.InvokeSkill (V11.7). (5) THE COMPOUND DISCIPLINE - every new surface should be an XSLT projection of the part library; if you find yourself writing a switch statement over part kinds in a controller, write the XSLT instead. MCP, ListView, /admin, /agency/graphs (V11.19) all follow this pattern. Future surfaces (terminal TUI, mobile, VS Code extension) all become new XSLTs over the same registry. Banked as anti-pattern #18 candidate.","tags":["positioning","surfaces","agents","mcp","xml","antipattern"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.V1122StudioPlan","name":"V11.22 plan: SPICE.Apps.Studio - multi-specialist department (OpenSwarm clone)","description":"Ship an OpenSwarm-equivalent 8-specialist agency as a single SPICE department, fully manifest-declared. Proves the platform\u0027s claim that multi-agent orchestration is a manifest concern, not a framework concern.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"STRATEGIC FRAME: OpenSwarm (VRSEN/OpenSwarm) ships 8 specialised agents coordinated by an Orchestrator that never answers directly - Virtual Assistant, Deep Research, Data Analyst, Slides, Docs, Image Gen, Video Gen. Every primitive maps cleanly onto existing SPICE concepts: Orchestrator -\u003E PhaseOrchestrator \u002B Workflow.Steps with PriorOutput chaining; specialists -\u003E ActorProfile parts (V11.3/V11.6); tool catalog -\u003E Phase.UsesTool \u002B IToolInvoker (A1-A10); coordination -\u003E IConsultancyService.EngageAsync (V11.7); multi-provider -\u003E IAgentProviderRouter \u002B cost gate (V8.5a/X5); memory -\u003E vector (V11.10/V11.15) \u002B graph (V11.20); external integrations -\u003E Connector (A8) \u002B McpServer (A9). DELIVERABLE: a new SPICE.Apps.Studio package containing one department blueprint with 8 ActorProfile rows (Orchestrator/VirtualAssistant/DeepResearch/DataAnalyst/Slides/Docs/ImageGen/VideoGen), 8 Phase rows (one per specialist, OutputSchema=ContentType.X \u002B OutputList=\u0022Studio/X\u0022 so outputs auto-persist via V11.2), 1 Workflow.StudioRequest with conditional-via-PriorOutput step chaining, ContentTypes per deliverable shape (SlideDeck/Document/ResearchReport/DataReport/Image/Video), 8 new Tool parts. PLUS approximately 6 small IToolInvoker C# classes wrapping the generation APIs (SlideDeckToolInvoker -\u003E HTML\u002BPPTX export; ImageGenToolInvoker -\u003E fal.ai; VideoGenToolInvoker -\u003E Sora; DocsToolInvoker -\u003E PDF; DataAnalystToolInvoker -\u003E Python kernel shell-out OR C# DataFrame equivalent). EFFORT: 4-5 cycles, one specialist\u002Btool-invoker per cycle, pattern identical to V11.5 OodaLoop manifest-only approach. ENTRY POINT: users invoke via MCP from any MCP client (claude, cursor, openswarm-style binary) - Tool.RunWorkflow(name=\u0022StudioRequest\u0022, userTask=\u0022make me a pitch deck\u0022). No new CLI binary needed - the MCP catalog is the entry point (KB.AgentSurfaceContract). WHAT SPICE ADDS on top of OpenSwarm equivalence: typed contracts (FieldDefinition validates at briefing time), per-actor cost capping (V8.5a MaxCostUsdPerCall hard cap prevents runaway video gen), audit log (every reformulation, every consultancy engagement, every persistence op logged with cost), policy gates per tool use, persistent memory (vector recall \u002B graph traversal across sessions), plugin gating (operator disables Video Gen via Plugins:fal:Enabled=false). ORDER OF EXECUTION: (1) Studio department blueprint \u002B 3 ActorProfiles \u002B Workflow skeleton \u002B 1 ContentType (SlideDeck); (2) SlideDeck Tool \u002B Phase; (3) Research Phase \u002B DeepResearch ActorProfile; (4) Docs Tool/Phase; (5) Image/Video Tools (gated on API keys). Each cycle ships an operator-visible incremental capability. WISDOM: this proves multi-agent orchestration is a MANIFEST CONCERN on this platform, not a framework concern. The C# surface stays small (just the tool invokers); the agency lives in XML.","tags":["plan","studio","openswarm","multi-agent","v11.22"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.ChannelSymmetryMatrix","name":"Channel-symmetry matrix: every invocable part kind needs HTTP \u002B MCP entries","description":"Banked from V11.23-V11.26: SavedQuery, Tool, and Workflow each have both an HTTP entry and an MCP entry. The matrix is the design discipline - any new invocable part kind implicitly volunteers two follow-up cycles to close it. Channels are transports, not formats; channels share one projection helper to keep response shapes contract-not-divergent.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"THE MATRIX (as of V11.26):\n\n| Part kind  | HTTP entry                              | MCP entry                |\n|------------|------------------------------------------|--------------------------|\n| SavedQuery | /api/sites/{Dept}/lists/{List}/items   | query_*  (pre-V11.25)    |\n| Tool       | POST /agency/tools/{id}/invoke (V8.x)  | tool_*    (V11.25)       |\n| Workflow   | POST /agency/workflows/{id}/run (V11.24) | workflow_* (V11.26)    |\n\nTHE RULE: any new invocable part kind added to the platform implicitly volunteers two follow-up cycles - one to surface an HTTP entry, one to surface an MCP entry. The matrix is not a recommendation; it is the discipline that ratifies KB.AgentSurfaceContract\u0027s claim (\u0022MCP is THE agent surface, rendered web is THE human surface\u0022). A part kind reachable only via internal C# callers does not yet have a complete agent-surface story.\n\nSINGLE SOURCE OF PAYLOAD TRUTH: when a second channel ships for an existing surface, REUSE the first channel\u0027s projection helper. V11.26\u0027s ProjectWorkflowResult routes through the same JSON shape V11.24\u0027s WorkflowsController.ProjectJson produces - byte-for-byte same fields, casing, omission rules. A caller switching from HTTP to MCP sees an identical response structure. Channels are transports, not formats; the response contract must not diverge per channel. The pattern: find the existing projection helper, route through it; do not write parallel JSON construction.\n\nCONTENT NEGOTIATION (HTTP side): XML default, JSON via Accept header. Same pattern V8.x ListsApiController established; V11.24 WorkflowsController follows it. application/problem\u002Bxml or \u002Bjson on errors. application/xml is the canonical contract because the platform\u0027s XSD validation runs on the same body that human-facing list forms post.\n\nCONTEXT THREADING: the X-Invoking-Department header (HTTP) and invokingDepartment argument (MCP) thread V11.23a\u0027s service-agency routing identically. Same field name on PhaseRequest / WorkflowRunRequest; same {{invokingDepartment}} OutputList templating. The platform contract spans channels.\n\nCOUNTER TO ANTI-PATTERN #17 at the agent-surface layer: not just \u0022every write path needs a read path\u0022 but \u0022every internal invocable needs an external surface in both channels.\u0022 Worth filing as #18 if a future cycle ships an invocable part kind without both channels.\n\nTHE COMPOUNDING: the matrix is reflexive. Each cell relies on the parts in the column working correctly. If a new query language gets added (don\u0027t), three cells need updates. If a new wire format gets added (rare), every cell in two rows gets a new format projection. The matrix is the source-of-truth for \u0022what does this surface have to do\u0022.","tags":["channels","mcp","http","symmetry","agent-surface","v11.26"],"source":"plans/AgencyArchitecture.md#section-13.9.6"},{"kind":"KnowledgeArticle","id":"KB.QuerySurfaceDecision","name":"Query surfaces: REST \u002B CAML \u002B MCP SavedQuery preferred; no GraphQL","description":"Architectural decision: the platform\u0027s preferred query-and-invocation surfaces are REST (XML/JSON, Accept-negotiated) for inter-system, MCP typed tools for agents, and rendered web for humans. CAML is the internal query language and stays internal. GraphQL is deliberately NOT added - it would be a parallel resolver layer over the same data the typed-document spine already covers.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"THE DECISION TREE (when a new use case needs a query/invocation surface):\n\n| Use case                       | Preferred surface                                                  |\n|--------------------------------|--------------------------------------------------------------------|\n| Agent invocation               | MCP tool_* / workflow_* (V11.25 / V11.26)                          |\n| Agent query                    | MCP SavedQuery parts (named, parameterised, declarative)           |\n| Agent inline query (escape)    | MCP query_caml (raw CAML XML, fallback when no SavedQuery covers) |\n| Inter-system write             | POST /api/sites/.../items OR /agency/workflows/.../run            |\n| Inter-system read              | GET /api/sites/.../items?... with Accept: application/xml or json |\n| Human-facing UI                | rendered web at /sites/...  (XSLT projection of typed data)       |\n| Operator power-user            | curl against the HTTP surface (no separate CLI)                   |\n| Catalog/portfolio aggregation  | CrossSiteList web part (one XML union view, no resolvers)         |\n\nWHY NOT GraphQL:\n\n(1) The typed-document spine is contract-first, not field-graph-first. ContentType \u002B FieldDefinition already define typed shapes; XSD validates request bodies; Accept negotiation projects to wire format. GraphQL\u0027s value proposition (\u0022ask for exactly these fields\u0022) is solved upstream of the wire by ContentType definitions. GraphQL would be a parallel resolver layer over the same data.\n\n(2) No N\u002B1 join problem. SPICE\u0027s list-and-relationship surface is already flat per ContentType, with cross-site joins handled by CrossSiteList web parts that project a single XML union. The schema-driven projection is the join; no resolver tree is needed.\n\n(3) Resolver explosion is the GraphQL tax. Every new ContentType / FieldDefinition would need a resolver registered. The platform\u0027s principle is \u0022schema is data, not code\u0022 - adding a field is a manifest edit, never a code edit. GraphQL would invert that.\n\nWHY CAML STAYS INTERNAL (per KB.AgentSurfaceContract):\n\nAgents never see raw CAML except through the explicit query_caml escape hatch. The preferred path is SavedQuery parts, which declare typed parameters projected to JSON Schema for MCP. CAML, XPath, XSLT, XSD are platform internals - they validate inputs/outputs and drive projections, but the agent\u0027s contract is \u0022here is a typed tool, here are typed args, here is typed output\u0022. REST clients NEVER see CAML; they see typed list endpoints whose query-string params project to CAML internally.\n\nCONCRETE GUIDANCE WHEN ADDING A NEW SURFACE: ask \u0022does this need a new ContentType, or just a new way to project an existing one?\u0022 If new ContentType -\u003E manifest edit \u002B the existing surfaces light up. If new projection -\u003E write the XSLT/Accept-handler. NEVER invent a parallel query language; NEVER hand-write a JSON Schema that could be derived from a FieldDefinition.\n\nTHE ONE DNA, SIX PROJECTIONS PATTERN: one ContentType part \u002B its FieldDefinitions becomes (1) XSD for validation, (2) XML wire format for V11.1 typed agent output, (3) JSON wire format for V11.12, (4) JSON Schema for MCP inputSchema (V11.25 hand-rolled today; auto-projection queued), (5) XSLT views for human-facing list/form pages, (6) OpenAPI documentation (deferred until an external SDK consumer exists). Each projection is derivable - never hand-maintain them in parallel.","tags":["decision","query","rest","graphql","caml","mcp","positioning"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.LatentTestMockBugRisk","name":"Tests-mock-everything can hide real bugs for cycles","description":"V11.27\u0027s first real end-to-end orchestrator run surfaced an XSLT-resolver bug latent since V11.4. Every prior test mocked BriefingBuilder, so the real .Load(uri) call path that breaks on Briefing.xslt\u0027s xsl:import was never exercised. Pattern: prefer at least one integration smoke per cycle that exercises the real DI graph, not just the mocked one.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"THE INCIDENT: V11.4 added \u003Cxsl:import href=\u0022MermaidWorkflow.xslt\u0022/\u003E to Briefing.xslt. BriefingBuilder.RenderXslt called XslCompiledTransform.Load(string) which uses an XmlThrowingResolver by default - this refuses external URIs and silently blocked the sibling-file load at runtime. The XSLT compile threw \u0022Resolving of external URIs was prohibited\u0022 the moment any phase orchestrator actually rendered a briefing.\n\nWHY IT WENT LATENT 23 cycles (V11.4 -\u003E V11.27): every test that exercises PhaseOrchestrator wires a StaticBriefingBuilder or similar mock that returns a pre-built BriefingResult without calling XslCompiledTransform.Load. So 1300\u002B tests passed; the moment V11.27 unblocked the first real end-to-end orchestrator run via HTTP/MCP, the bug surfaced immediately.\n\nWHY THE STARTUP-TIME SMOKES MISSED IT: each prior cycle\u0027s smoke ritual booted SPICE.Web and probed /about. /about renders through ListViewModelBuilder \u002B AdminViewModelBuilder XSLTs - not Briefing.xslt. The XSLT file got compiled lazily on first use, which only happens when PhaseOrchestrator.RunAsync runs against a real workflow request. Schedule.Cron and EventReceiver workflows could have surfaced it earlier but didn\u0027t fire in test environments.\n\nTHE PATTERN: tests-mock-everything is great for unit-test speed and isolation, but the BriefingBuilder collaborator is too central to mock universally. At least ONE end-to-end integration test per cycle that exercises the real BriefingBuilder against the real Briefing.xslt would have caught V11.4\u0027s regression at V11.4 commit time, not V11.27.\n\nTHE FIX (V11.27 commit 43db1de): BriefingBuilder.RenderXslt now wires an XmlUrlResolver \u002B explicit XsltSettings(enableDocument:false, enableScript:false) - same safety posture (no doc()/script extension), just allows sibling-file xsl:imports to resolve.\n\nGENERAL GUIDANCE: when introducing a cross-collaborator feature (V11.4 added an xsl:import; the resolver behavior changed at the XSLT layer), prefer an integration test against the real composition root over a unit test against a mock. The cost of one slow integration test is much less than 23 cycles of latent regression. Related: feedback_smoke_catches_xsd already banked for part-XML XSD bugs; this is the parallel lesson for XSLT-include bugs.\n\nEXTENSIONS TO ANTI-PATTERN #18 CANDIDATE (broader formulation): mocking-by-default at the boundaries where bugs actually live (\u0022the real BriefingBuilder\u0022, \u0022the real PhaseOrchestrator \u002B real Briefing.xslt\u0022, \u0022the real provisioning applier\u0022) leaves a class of bugs invisible until production. Worth filing.","tags":["testing","mocking","xslt","latent-bug","v11.27","antipattern"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.InfoPathAnalogue","name":"ContentType \u002B FieldDefinition \u002B FormView IS the InfoPath layer","description":"The platform\u0027s InfoPath analogue.  Every ContentType auto-renders as a typed form via the V8.x schema-driven FormView.xslt - typed inputs per FieldType (Choice -\u003E select, Lookup -\u003E dropdown populated from the linked list, DateTime -\u003E date picker, Note -\u003E textarea).  V12.2 layers BaaN-style \u0027Next step\u0027 buttons on the same form via Transitions block.  No new form designer, no parallel template system.","version":"1.0.0","classification":"Public","minimumRole":"Assistant","body":"THE CLAIM: SPICE doesn\u0027t NEED a separate InfoPath-like form designer because the platform\u0027s typed-XML spine already IS the InfoPath analogue.\n\n  ContentType            = InfoPath template (the form definition)\n  FieldDefinition        = InfoPath data binding (typed columns)\n  FormView.xslt          = InfoPath renderer (display \u002B edit \u002B new modes)\n  Choice / Lookup / etc. = InfoPath control types\n  Transitions block      = InfoPath workflow tasks (V12.2)\n\nWHAT YOU GET BY DECLARING A CONTENTTYPE:\n  1. New form         /sites/{Dept}/Lists/{List}/New           typed input per FieldType\n  2. Display form     /sites/{Dept}/Lists/{List}/Item/{Id}    typed display \u002B V12.2 Next-step buttons\n  3. Edit form        /sites/{Dept}/Lists/{List}/Edit/{Id}    typed input \u002B Save\n  4. List view        /sites/{Dept}/Lists/{List}              typed columns \u002B sort \u002B filter\n  5. JSON Schema      /api/sites/{Dept}/lists/{List}/_schema   for external API \u002B MCP\n  6. XSD              /api/sites/{Dept}/lists/{List}/_schema.xsd  for SOAP-style XML callers\n  7. REST CRUD        /api/sites/{Dept}/lists/{List}/items     with XSD validation\n  8. MCP query        query_caml \u002B per-SavedQuery typed tools\n\nALL of those are projections of ONE manifest declaration.  Add a FieldRef, every projection lights up.\n\nCONCRETE EXAMPLES:\n  ContentType.BusinessPartner (V12.1)\n    Form at /sites/Common/Lists/BusinessPartners/New renders:\n      Title (text input, required),\n      Lei (text input, max 20),\n      Gln (text input, max 13),\n      RoleCode (dropdown populated from Common/BusinessPartnerRoles),\n      CountryCode (dropdown populated from Common/Countries),\n      DefaultCurrencyCode (dropdown populated from Common/Currencies),\n      DefaultPaymentTermCode (dropdown populated from Common/PaymentTerms).\n    Zero per-ContentType code; all derived from FieldDefinition declarations.\n\n  ContentType.DemoTask (V12.2)\n    Same form shape PLUS a \u0027Next step\u0027 button row driven by \u003CTransitions/\u003E.\n    Click \u0027Start\u0027 -\u003E POST /advance?to=InProgress -\u003E status flips -\u003E form re-renders with next available transitions.\n    Pure XSLT extension; no JavaScript framework.\n\nWHY THIS BEATS A DEDICATED FORM DESIGNER:\n  - Zero parallel tech stack.  Designers maintain XML; the same XML drives every other channel (HTTP REST, MCP, agent-typed-XML output).\n  - Forms version with the manifest.  A ContentType edit affects every form everywhere.\n  - LLM-fluent.  Agents reason about the typed schema directly; no form-designer-specific knowledge needed.\n  - No drift between form and API.  The form posts the same shape the API accepts; XSD validates both.\n\nNEW FORMS RECIPE:\n  1. Declare FieldDefinitions for any new typed columns (or reuse existing).\n  2. Declare a ContentType with FieldRefs.\n  3. Declare a List with that ContentType on a SiteBlueprint.\n  4. (Optional) Add a \u003CTransitions/\u003E block for BaaN-style status workflow.\n  Done.  Visit /sites/{Dept}/Lists/{List}/New.\n\nWHAT THIS REPLACES:\n  - InfoPath / SharePoint Forms / Power Apps custom forms: not needed.\n  - JSON-Schema-driven form builders (Formik / Rjsf / etc.): not needed - we generate JSON Schema FROM the FieldDefinition, never hand-write it.\n  - SOAP form definitions (FormBuilder etc): not needed - XSD is auto-derived.\n\n  Banked 2026-05-21 (V12.2 worked example shipped).  Anti-pattern check: never invent a parallel form designer; always extend ContentType \u002B FieldDefinition.","tags":["infopath","forms","ContentType","FormView","positioning","v12.2"],"source":"SPICE.Web/wwwroot/XSLT/FormView.xslt"},{"kind":"KnowledgeArticle","id":"KB.ErpFoundationPlan","name":"V12 horizon plan: ERP foundation layered on typed-XML spine","description":"The 11-cycle V12 horizon ships a complete ERP foundation: ISO/UN-CEFACT/GAAP taxonomies \u002B master data \u002B BaaN-style state-machine workflow \u002B UBL-aligned operational modules.  Solid taxonomy first; modules second; standards-conformance throughout.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"STRATEGIC FRAME: The strongest leverage the platform has for ERP isn\u0027t the runtime; it\u0027s typed XML against world-standard schemas.  UBL invoices, PEPPOL eDelivery, ISO 20022 financial messages are ALL typed XML validated against XSD.  Mirror their shapes as ContentTypes and every typed-document-spine receipt the platform already has (V11.1 validation, V11.2 auto-persist, V11.24 HTTP entry, V11.25/V11.26 MCP) lights up against world-standard interop FOR FREE.\n\nROADMAP (foundation first; operational second; debrief last):\n\n  V12.0a  Taxonomy foundation  - 7 typed termsets \u002B 67-row essentials seed.\n                                  ISO 4217 (Currencies), ISO 3166-1 (Countries),\n                                  ISO 639-1 (Languages), UN/CEFACT Rec 20 (UoM),\n                                  GAAP root account-type categories, plus platform-\n                                  defined PaymentTerms \u002B BusinessPartnerRoles.\n                                  SPICE.Apps.Erp.Tc package.  Ships da8ba49.\n\n  V12.0b  \u003CTransitions/\u003E seam   - State-machine block on ContentType.  XSD \u002B\n                                  part record \u002B IContentTypeResolver helpers.\n                                  No new behaviour; the seam V12.2\u002B consume.\n                                  Ships 404dfd4.\n\n  V12.1   Master data           - 6 ContentTypes: BusinessPartner (LEI/GLN/VAT),\n                                  MasterItem (UNSPSC/UoM), Address (ISO 19160),\n                                  BankAccount (IBAN/BIC), ExchangeRate, ChartOfAccount.\n                                  Lookups bind to V12.0a termsets.  Ships d49e25f.\n\n  V12.2   FormView Next-step    - InfoPath-style typed form gains BaaN-style\n                                  status buttons reading \u003CTransitions/\u003E.\n                                  POST /advance?to=X endpoint.  Ships c9b1f97.\n\n  V12.3   MCP advance bridge    - Tool.AdvanceListItem IToolInvoker.  Surfaced\n                                  via V11.25 bridge as tool_advance_list_item.\n                                  Channel symmetry on Transitions.  Ships f5a93f5.\n\n  V12.3.5 Bank \u002B debt           - V12 horizon banked in Section 13.10; KBs\n                                  filed (InfoPathAnalogue \u002B ErpFoundationPlan).\n                                  ListsApiController.Create now persists\n                                  ContentType into row JSON.\n\n  V12.4   SPICE.Apps.Erp.Td     - Distribution worked example: SalesOrder\n                                  (Draft-Approved-Picked-Shipped-Invoiced-Closed),\n                                  PurchaseOrder, ShipmentNotice.  Manifest-only.\n\n  V12.5   FiscalCalendar \u002B Tax  - V12.1 deferred extensions needed by Finance.\n                                  Plus a Schedule.Cron job for ExchangeRate\n                                  daily snapshots.\n\n  V12.6   SPICE.Apps.Erp.Tf     - Finance worked example.  Invoice ContentType\n                                  declared via OutputSchema=\u0027Schemas/UBL/UBL-Invoice-2.1.xsd\u0027\n                                  so agent-emitted invoices are PEPPOL-compliant\n                                  BY CONSTRUCTION.\n\n  V12.7   SPICE.Apps.Erp.Ti     - Items / Inventory operational module.\n                                  StockMove with Open-Confirmed-Done transitions.\n\n  V12.8   SPICE.Apps.Erp.Tp     - Project worked example.\n\n  V12.9   Hub portfolio         - /sites/Hub/Lists/AllSalesOrders etc cross-site\n                                  projection.  Same pattern V11.23c shipped for\n                                  Studio.\n\n  V12.10  Debrief               - V12 horizon close; lessons banked.\n\nPACKAGE NAMING (BaaN/Infor LN convention):\n  SPICE.Apps.Erp.Tc  = Common (master data \u002B termsets)\n  SPICE.Apps.Erp.Ti  = Items / Inventory\n  SPICE.Apps.Erp.Td  = Distribution (Sales \u002B Purchase \u002B Warehouse)\n  SPICE.Apps.Erp.Tp  = Project\n  SPICE.Apps.Erp.Tf  = Finance\n  SPICE.Apps.Erp.Tm  = Manufacturing (optional)\n\nERP-practitioner-fluent at the folder/package level; LLM-fluent at the ContentType level (ContentType.SalesOrder not ContentType.TdSalesOrder).\n\nSTANDARDS ADOPTED:\n  ISO 4217   Currency codes\n  ISO 3166-1 Country codes\n  ISO 639-1  Language codes\n  UN/CEFACT Rec 20  Unit-of-measure codes\n  GAAP/IFRS  Account-type root categories\n  ISO 17442  LEI (Legal Entity Identifier)\n  GS1 GLN    Global Location Number\n  ISO 13616  IBAN\n  ISO 9362   BIC / SWIFT\n  ISO 19160  Postal address shape\n  UNSPSC     Item classification (top 2 levels seeded)\n  UBL 2.4    Universal Business Language (V12.6)\n  PEPPOL BIS Billing 3.0 (V12.6 via UBL)\n\nWHAT THIS BEATS:\n  - \u0027Implement an ERP module first then bolt on standards later\u0027 approach.  Foundations of every classic ERP failure are master-data-shaped: currency mismatch, UoM ambiguity, cross-system customer dedup, invoice format wars.  Solving them at the schema layer makes downstream modules trivially compliant.\n  - GraphQL / custom query languages.  See KB.QuerySurfaceDecision - the typed-XML spine \u002B REST \u002B MCP cover every use case.\n  - SaaS-ERP-form-builder thinking.  See KB.InfoPathAnalogue - every form is a projection of one ContentType declaration.","tags":["plan","erp","v12","foundation","standards","ubl","iso"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.V12HorizonDebrief","name":"V12 horizon close - 4-module ERP receipt \u002B standards conformance \u002B cross-module engagement","description":"What V12.0a through V12.10 delivered, the three banked lessons (N=4 modules-as-manifest receipt, mid-horizon refactor pays compound interest, Apps-stay-Core-only under cross-module pressure), and compounding signals into earlier feedback memories.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"V12 HORIZON CLOSE.  Ten cycles shipped from V12.0a (foundation taxonomy seed) through V12.10 (this debrief).  Four operational ERP modules (Td Distribution, Tf Finance, Ti Inventory, Tp Project) live on a single shared V12.0 foundation with zero per-module engine code beyond an empty AppModuleBase subclass.\n\nWHAT WAS PROMISED AT V12.0a:\n  Standard XSDs ARE the foundation.  Mirror UBL / ISO 20022 / PEPPOL as ContentTypes and every typed-document-spine receipt (V11.1 validation, V11.2 auto-persist, V11.24 HTTP, V11.25/V11.26 MCP) lights up against world-standard interop for free.  See KB.ErpFoundationPlan for the 11-cycle plan filed at V12.3.5.\n\nWHAT WAS DELIVERED:\n  V12.0a  Taxonomy foundation (7 ISO termsets \u002B 67-row seed)\n  V12.0b  Transitions state-machine seam on ContentType\n  V12.1   Master data (BusinessPartner / Item / Address / BankAccount / ExchangeRate / ChartOfAccount)\n  V12.2   FormView Next-step button reads Transitions\n  V12.3   MCP Tool.AdvanceListItem (channel symmetry)\n  V12.3.5 Bank wisdom \u002B ListsApiController ContentType-on-create\n  V12.4   SPICE.Apps.Erp.Td (Sales/Purchase/Shipment)\n  V12.5   FiscalPeriod \u002B TaxCategory (Finance prep)\n  V12.6   SPICE.Apps.Erp.Tf (UBL-aligned Invoice/Payment/JournalEntry)\n  V12.7   SPICE.Apps.Erp.Ti (StockItem/StockMove/BinLocation)\n  V12.7.5 IItemAdvanceService \u002B ContentTypeStatusResolver extract\n  V12.7b  Cross-module engagement (Td PO.Received -\u003E Ti StockMove)\n  V12.8   SPICE.Apps.Erp.Tp (Project/Task/Budget)\n  V12.9   Hub ErpPortfolio cross-site projection\n  V12.10  This debrief\n\nNUMERIC RECEIPTS:\n  - 4 operational module packages, all Core-only csproj.\n  - 13 typed operational ContentTypes added across Td/Tf/Ti/Tp.\n  - 2 master-data extensions in Tc (FiscalPeriod, TaxCategory).\n  - ~220 tests added across V12 cycles total (1314 -\u003E 1537).\n  - 1 latent platform bug surfaced \u002B banked: Parts.\u003CISO 639-1\u003E.xml triggers .NET satellite-resource detection.  V12.7 caught it via live smoke; fix is WithCulture=false on EmbeddedResource.\n  - 1 architectural debt cycle paid mid-horizon (V12.7.5).\n  - 0 new framework classes for the operational modules - the N=3 rule held; the V12 foundation alone carries the load.\n\nTHREE LESSONS BANKED AT V12.10 (Section 13.10.5):\n\n1) N=4 RECEIPT VALIDATES MODULES-AS-MANIFEST.\n   N=1 (Td) could be luck.  N=2 (Tf) could be intentional design.  N=3 (Ti) surfaced latent platform bugs - that\u0027s the real test.  N=4 (Tp) shipped in a fraction of the time of Td because the pattern is reflex.  Operational ERP modules are pure manifest data on the V12.0 foundation.\n\n2) MID-HORIZON REFACTOR PAYS COMPOUND INTEREST.\n   V12.7.5 extracted IItemAdvanceService \u002B ContentTypeStatusResolver between V12.7 and V12.7b.  Then V12.7b\u0027s cross-module listener shipped in 45 lines instead of 150\u002B duplicated lines.  Receipt: refactor BEFORE the second caller exists, not after.\n\n3) APPS STAY CORE-ONLY EVEN UNDER CROSS-MODULE PRESSURE.\n   V12.7b\u0027s IItemAdvancedListener landed in SPICE.Core.Events (next to V9.10 IItemEventListener) rather than SPICE.Foundation.Events, so Ti subscribed without escalating to a Foundation reference.  V9.5 invariant held under stress.  N=2 reinforcement of anti-pattern #16 (honest exceptions over silent drift).\n\nCOMPOUNDING INTO EARLIER FEEDBACK MEMORIES:\n  - KB.ChannelSymmetryMatrix gained a third concrete implementation (V11.25 Tool, V11.26 Workflow, V12.7.5 advance service).\n  - feedback_typed_xml_spine gained a sixth receipt (V12.6 UBL proves standard XSDs ride the spine identically to platform CTs).\n  - anti-pattern #15 (additive shape over rename) landed on V12.7.5\u0027s optional advancedListeners ctor param - V12.7b activated fan-out without breaking V12.3 tests.\n\nWHAT\u0027S QUEUED (V13.x candidates):\n  - V12.6b: vendor UBL-Invoice-2.1.xsd as embedded resource \u002B wire Phase.OutputSchema for agent-emitted PEPPOL-compliant invoices.\n  - V12.7c: OnHandQuantity recompute on StockMove.Done; negative-stock policy guard; picking-strategy automation.\n  - V12.8b: cross-module Tp.Task.Reference -\u003E Td.SalesOrder.OrderNumber Lookup promotion; line-item ContentTypes.\n  - V13.x: SPICE.Apps.Erp.Tm (Manufacturing) if/when N=5 is needed.\n  - ExchangeRate Schedule.Cron \u002B FX provider plugin (V12.5b).","tags":["debrief","erp","v12","horizon-close","standards"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.V13HorizonDebrief","name":"V13 horizon close - native vs connector \u002B dogfood as backlog","description":"What V13.0 through V13.1c delivered, the three banked lessons (integrate-natively-not-import, Schedule\u002Bagent vs Schedule\u002Bdeterministic cadence fork, dogfood the backlog as platform data not docs), and what\u0027s still owed for V14\u002B.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"V13 HORIZON CLOSE.  Four cycles shipped from V13.0 (platform Atlas \u002B V13 backlog dogfooded as Tp/ProjectTasks rows) through V13.1c (rollover \u002B Kanban \u002B Hub Jira card).  V12 closed with a working ERP foundation; V13 turns the platform inward - instead of integrating with external SaaS, it models the SaaS shapes natively.\n\nWHAT WAS PROMISED AT V13.0:\n  The V13 backlog moves out of plans/EnterpriseRoadmap.md and lives as Tp/ProjectTasks rows on the same machinery operators use for their work.  Operator-visible status flips via V12.2 FormView Next-step or V12.3 MCP tool_advance_list_item; cross-site rollup via V7.3 CrossSiteList on the new /sites/Hub/Pages/PlatformAtlas page.  \u0022Dogfood as transparency.\u0022\n\nWHAT WAS DELIVERED:\n  V13.0  Platform Atlas \u002B V13 backlog dogfooded (cb62cfb)\n  V13.1a SPICE.Apps.Tracker - native Jira-equivalent App (d19cf05)\n  V13.1b SprintCadenceHostedService - deterministic cadence (a9074df)\n  V13.1c Rollover \u002B Kanban \u002B Hub Jira card (cec685e)\n\nNUMERIC RECEIPTS:\n  - 1 new App package (SPICE.Apps.Tracker), Core-only csproj following V12 ERP module shape.\n  - 2 new typed ContentTypes (Sprint, Epic) \u002B extension of ContentType.Issue in-place (5 new fields \u002B Transitions block \u002B 3 new IssueStatus choices).\n  - 1 new platform contract added to SPICE.Core (IListItemEnumerator) with SqlServer adapter in SPICE.Infrastructure \u002B Noop fallback in SPICE.Web.\n  - 1 new ListsController view branch (?view=kanban) \u002B 1 new XSLT file (Kanban.xslt) for 8-column kanban projection.\n  - 1 new HubPortal page (TrackerPortfolio) with 4 CrossSiteList web parts.\n  - ~42 tests added across V13 cycles total (1547 -\u003E 1589).\n  - 1 new anti-pattern banked (#18 - don\u0027t build inbound connector when platform can model natively).\n\nTHREE LESSONS BANKED AT V13.1c (Section 13.11.2):\n\n1) INTEGRATE NATIVELY, DON\u0027T IMPORT.\n   V13.1\u0027s backlog row originally read \u0022First external connector: Jira/Linear ticket import\u0022.  One sentence of mid-session redirect reshaped it to \u0022make our own Jira on our platform way\u0022.  V13.1a then shipped a working Jira-equivalent in one cycle with zero new engine C#.  The build-vs-import calculus reverses on the platform side: native shape compounds against every typed-XML spine receipt the platform has accumulated.  Filed as anti-pattern #18.\n\n2) SCHEDULE \u002B AGENT VS SCHEDULE \u002B DETERMINISTIC - BOTH LOAD-BEARING.\n   OodaLoop V11.5/V11.7 = Schedule \u002B Workflow \u002B Phase \u002B agent provider (reasoning cadence).  Tracker V13.1b = per-App IHostedService \u002B Timer \u002B deterministic logic (plumbing cadence).  Both run on the V11.5 SchedulerHostedService lineage; the choice is per-feature.  Date arithmetic doesn\u0027t need an LLM.  Also: when XSD constraints force a fake Workflow reference for documentation-only Schedule parts, skip the Schedule part - anti-pattern #13 (\u0022declared but un-read\u0022) stays dodged.\n\n3) DOGFOOD THE BACKLOG AS PLATFORM DATA, NOT PLATFORM DOCS.\n   V13.0\u0027s V13Backlog.xml seed reads as the V13 roadmap; the seeder applies it to Tp/ProjectTasks on first boot.  Operator-visible cycle status surfaces at /sites/Hub/Pages/PlatformAtlas (the same surface operators use for ERP views) - nobody opens plans/*.md in production.  The advance machinery is identical for both ERP and platform-roadmap rows: V12.2 FormView, V12.3 MCP advance, V13.1c rollover.  One set of mechanisms, two domains.  The platform plans its own next moves with the same surface ERP operators use for orders.\n\nCOMPOUNDING INTO EARLIER FEEDBACK MEMORIES \u002B ANTI-PATTERNS:\n  - anti-pattern #15 (additive shape over rename) gained three new receipts in V13.1c alone (optional IListItemEnumerator? ctor arg \u002B default RolledOverIssueCount=0 on TickResult \u002B optional GetService vs GetRequiredService).\n  - anti-pattern #16 (don\u0027t widen Apps-Core invariant silently) strengthened: IListItemEnumerator added to SPICE.Core, adapter in SPICE.Infrastructure, Noop fallback in SPICE.Web; SPICE.Apps.Tracker stays Core-only.\n  - feedback_typed_xml_spine gained a seventh receipt (Sprint/Epic CTs \u002B Issue extension all typed XML; Kanban reads same ListView XML model).\n  - feedback_smoke_catches_xsd_bugs gained an eighth receipt (V13.1a Feature Id= vs Name= caught by smoke before commit).\n  - KB.ChannelSymmetryMatrix - the V13.1 native-shape pattern reframes the matrix: inbound import is anti-pattern #18 territory; outbound webhook (V13.2) is symmetric integration.\n\nWHAT\u0027S QUEUED FOR V14\u002B (or remaining V13.x candidates):\n  - V12.6b: vendor UBL-Invoice-2.1.xsd \u002B wire Phase.OutputSchema (closes V12.6 standards-conformance promise).\n  - V13.2: outbound webhook listener (POST to operator URL on Transitions.To=X) - the symmetric companion to V13.1\u0027s native-shape pattern.\n  - V13.3: A2A/ACP bridge plugin (Google A2A \u002B IBM ACP - specs still moving, ship behind feature flag).\n  - V13.4: real-LLM end-to-end smoke harness (blocked pending ANTHROPIC_API_KEY).\n  - V13.5: listener observability \u002B performance (IItemAdvancedListener fan-out telemetry).\n  - V13.6: line-item ContentTypes (SalesOrderLine \u002B PurchaseOrderLine \u002B InvoiceLine \u002B JournalEntryLine).\n  - Listener-write carve-out for anti-pattern #11 at N=3 (V12.7b \u002B V13.1b both bypass policy gate as system-internal listeners; name the boundary explicitly when a third instance ships).\n  - Kanban POST /advance (drag-and-drop status flips - V13.1c shipped read-only).\n  - Foundation-only rollover telemetry in /admin (NoopListItemEnumerator degrades silently today).","tags":["debrief","tracker","v13","horizon-close","native-vs-connector"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.V17HorizonDebrief","name":"V17 horizon close - standards interop as projection, not engine","description":"What V17.0 through V17.6 delivered, four patterns banked (standards-receipt N=4, curated-subset XSDs, round-trip integrity, sub-cycle absorption), prediction grading, and V18 strategic-theme pick (employee portal recommended).","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"V17 closed in a single session (seven cycles, commits 58facc3 through 65dcb7c).  Tests 1873 -\u003E 1940 (\u002B67).  KnowledgeArticles 40 -\u003E 43 (KB.V171BpmnVendoring \u002B KB.V174PizzaOrderWorked \u002B this debrief).\n\nDELIVERED:\n  - BPMN 2.0 export at /agency/bpmn/export?workflowId=X (V17.1\u002BV17.2)\n  - BPMN 2.0 import at POST /agency/bpmn/import (V17.3)\n  - DMN 1.3 export at /agency/bpmn/dmn-export?decisionTableId=X (V17.5)\n  - N=1 worked example: Camunda pizza-order BPMN imports cleanly\n    (V17.4 subset-compliant fixture); full-Camunda file rejected\n    honestly via XSD gate (V17.1b candidate scope concrete)\n  - Standards-vendor receipt count now N=4 (UBL \u002B CIQ \u002B BPMN \u002B DMN)\n  - V16.5b BusinessPartner self-scope absorbed (Field.BpSku \u002B\n    PartyScopeField=Sku); V16.6b ShipmentNotice SupplierSku\n    absorbed.  Only V16.5b PartyRelationship bidirectional remains\n    deferred (V17.5b)\n\nFOUR PATTERNS BANKED (Section 13.17.1):\n\n  (1) STANDARDS-VENDOR RECEIPT COMPOUNDS AT ONE CYCLE PER SURFACE.\n      Five-piece pipeline (XSD \u002B Phase \u002B XSLT \u002B builder \u002B endpoint)\n      shipped four times now: V12.6b UBL Invoice (Tf), V15.3 OASIS\n      CIQ Party (Tcm), V17.1 BPMN Process (platform), V17.5 DMN\n      Decision (platform).  PhaseOrchestrator.ResolveSchemaPath\n      probes both Config/Schemas/ (platform-wide) and\n      AppContext.BaseDirectory/ (App-package vendored) so vendoring\n      location is operator choice, not architectural commitment.\n      Phantom-check discipline now N=3 (V15.3 \u002B V16.1 \u002B V17.1).\n\n  (2) CURATED-SUBSET XSDs WIN OVER FULL OMG BUNDLES.  V17.1\n      BPMN20.xsd is 140 lines; V17.5 DMN13.xsd is 180 lines.  Each\n      uses the official OMG namespace so files open in viewers;\n      round-trip integrity is better served by a tight subset\n      because permissive validation would let unknown constructs\n      pass that import can\u0027t actually map to typed parts.  V17.4\n      live receipt: Camunda\u0027s userTask was rejected via per-element\n      validation message (\u0022expected: startEvent, endEvent, task,\n      exclusiveGateway, sequenceFlow\u0022) - clean operator signal \u002B\n      concrete V17.1b candidate.\n\n  (3) ROUND-TRIP INTEGRITY AS LOAD-BEARING CLAIM.  Setting the\n      claim explicit at horizon-open (V17.0 prediction #3) shaped\n      both projections symmetrically.  V17.2 emits\n      task/@implementation=PhaseId; V17.3 reverse-projects to\n      Step/@PhaseId.  V17.3 fallback paths (no \u0022p_\u0022 prefix, no\n      \u0022Phase.\u0022 prefix, missing @implementation) keep import\n      tolerant of external Modeler files while staying lossy-by-\n      design on platform-specific annotations.\n\n  (4) SUB-CYCLE ABSORPTION FOR SMALL CARRY-OVERS.  V17.5 absorbed\n      V16.5b (BusinessPartner) \u002B V16.6b (ShipmentNotice) alongside\n      DMN export.  Criterion: (a) unambiguously additive shape,\n      (b) main item doesn\u0027t depend on absorbed, (c) absorbed work\n      total \u003C= ~20 LOC XML or ~50 LOC code.  V16.5b\n      PartyRelationship bidirectional explicitly deferred to V17.5b\n      because it needed multi-field PartyScopeField syntax warranting\n      its own cycle (criterion (a) broke).\n\nPREDICTION GRADING (5-for-5 on shape; cost calibration tightened):\n\n  V17.1 BPMN vendoring sub-2-hour          - CONFIRMED.\n  V17.2 projection XSLT bigger than V17.1  - CONFIRMED (~280 LOC vs ~50).\n  V17.3 import symmetric modulo loss       - CONFIRMED, loss explicit.\n  V17.4 pizza-order surfaces 2-3 gaps      - CONFIRMED exactly\n                                             (userTask \u002B serviceTask \u002B\n                                             camunda: namespace).\n  V17.5 absorbs V16.5b/V16.6b cleanly      - CONFIRMED with one\n                                             calibration (2 of 3\n                                             absorbed; third deferred).\n\n  Cost calibration banked: actual ~0.3-0.7x pre-V11 estimates.\n  Refines V15.5\u002BV16.7\u0027s 0.2-0.5 with V16\u002BV17 N=2 receipts.\n\nV18 STRATEGIC-THEME PICK (Section 13.17.3):\n\n  Recommended: POLE A - N=3 portal generalisation (employee portal).\n    Build SPICE.Apps.HR \u002B EmployeePortal with Timesheet \u002B\n    LeaveRequest \u002B EmployeeProfile CTs.  EmployeeProfile follows\n    the V17.5 BusinessPartner self-scope shape (PartyScopeField=\n    \u0022EmployeeId\u0022 or similar).  Compounds V14.7 DecisionTable\n    (leave-approval routing) \u002B V12.0b Transitions (approval state\n    machine).  Operator-visible.  ~5-7 cycle-units.\n\n  Alternative: POLE B - V17 follow-ups (V17.1b OMG bundle \u002B\n    V17.5b PartyRelationship \u002B DMN BKMs \u002B BPMN DI).  Less\n    operator-visible.  ~4-6 cycle-units.\n\n  Alternative: POLE C - BusinessObject lifecycle hooks (V12\n    follow-up).  Adds explicit OnAdvance/OnApprove/OnReject event\n    callbacks per Transition.  ~5-7 cycle-units.\n\nV17 SINGLE-SENTENCE FRAME:\n  V17 wrapped the platform\u0027s declarative process engine in a four-\n  standards interop layer (UBL \u002B CIQ \u002B BPMN \u002B DMN), confirmed\n  round-trip integrity end-to-end with one worked example, and\n  banked the standards-as-projection-not-engine claim with N=4\n  receipts on a five-piece pipeline that the next cycle per\n  standard just instantiates.","tags":["v17","v17.6","horizon-close","bpmn","dmn","standards-interop"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.V174PizzaOrderWorked","name":"V17.4 Camunda pizza-order N=1 worked example - happy path \u002B V17.1b gaps","description":"N=1 receipt that V17.1\u002BV17.2\u002BV17.3 round-trip and that real Camunda Modeler files surface concrete V17.1b candidates (userTask, serviceTask, camunda: extensions).","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"V17.4 ships TWO pizza-order BPMN fixtures \u002B tests proving the V17 horizon\u0027s load-bearing claim across two file shapes:\n\n(1) PizzaOrder.bpmn - curated to stay within V17.1\u0027s BPMN20.xsd subset (bpmn:task only, no Camunda extensions).  V17.3 imports cleanly into a 5-step Workflow.PizzaOrder with PhaseIds Phase.PizzaTakeOrder, Phase.PizzaPrepare, Phase.PizzaBake, Phase.PizzaDeliver, Phase.PizzaCollectPayment.  Operator-droppable into Parts.xml; would execute end-to-end if those Phases existed (V17.4 doesn\u0027t add them - Phase authorship is a platform-side responsibility, not BPMN-interop scope).\n\n(2) PizzaOrderCamunda.bpmn - same workflow modeled with bpmn:userTask \u002B bpmn:serviceTask \u002B camunda:assignee / camunda:type / camunda:topic / camunda:formKey extensions.  Shape Camunda Modeler emits by default.  V17.3 currently REJECTS this file via the V17.1 XSD validation gate (\u0022element \u0027userTask\u0027 not declared in BPMN20 subset\u0022).  This is the honest receipt that the V17.1 curated subset is narrower than full OMG BPMN 2.0; the V17.1b candidate is to swap to the full bundle (Semantic.xsd \u002B BPMNDI.xsd \u002B DC.xsd \u002B DI.xsd \u002B xlink-2003-12-31.xsd) which models:\n  - bpmn:userTask, bpmn:serviceTask, bpmn:scriptTask, bpmn:manualTask,\n    bpmn:businessRuleTask, bpmn:sendTask, bpmn:receiveTask\n  - bpmn:boundaryEvent \u002B bpmn:timerEventDefinition (timer task escapes)\n  - bpmn:parallelGateway, bpmn:inclusiveGateway (the V14.2c\n    CrossModuleRule grammar is currently sequential)\n  - bpmn:callActivity \u002B bpmn:subProcess (composition shape)\n\nV17.0 PREDICTION #4 GRADED (Section 13.16.2 #4 - \u0022V17.4 pizza-order import surfaces ~2-3 BPMN constructs the platform doesn\u0027t yet model\u0022):  CONFIRMED with the exact predicted shape.  PizzaOrderCamunda surfaces userTask \u002B serviceTask (2 task-type constructs) \u002B camunda: namespace extensions (the platform-specific annotation channel).  V17.1b candidate is now a concrete deliverable (swap-XSD-then-extend-projection); V17.5 may absorb it alongside the DMN export work.\n\nCAMUNDA EXTENSION SEMANTICS V17.3 LOSES on import (would need V17.1b \u002B a Phase.BpmnAnnotations block to round-trip):\n  - camunda:assignee=\u0022${userVar}\u0022 - SPICE expresses via Phase.RequiresRole \u002B Settings cascade \u002B IActorContext\n  - camunda:expression=\u0022#{javaExpr}\u0022 - SPICE expresses via CrossModuleRule.Match \u002B DecisionTable\n  - camunda:type=\u0022external\u0022 \u002B camunda:topic - SPICE expresses via Phase.UsesTool args\n  - camunda:formKey - SPICE expresses via FormView.xslt \u002B ContentType\n\nThe \u0022everything Camunda does, SPICE expresses differently\u0022 mapping is itself the receipt that the platform\u0027s typed-XML spine already covers BPMN\u0027s semantic surface; BPMN-as-serialisation is the only V17 deliverable, not BPMN-as-engine.\n\nWORKED EXAMPLE LIVE PATH (when V17.1b lands, opening the V17.1 XSD up to userTask/serviceTask):\n  curl -X POST -H \u0022Content-Type: text/xml\u0022\n       --data-binary @PizzaOrderCamunda.bpmn\n       http://host/agency/bpmn/import\n  -\u003E 200 OK with a saf:Workflow element carrying\n       Id=\u0022Workflow.PizzaOrderCamunda\u0022 \u002B Name=\u0022Pizza Order (Camunda)\u0022\n       and Camunda extension attrs landing on a Phase.BpmnAnnotations\n       block (V17.1b shape, not yet shipped).\n       Operator drops Workflow XML into Parts.xml \u002B adds the\n       Phase.PizzaX parts that the imported Steps reference.\n\nV17.4 STAYS HONEST: imports the subset-compliant file successfully \u002B documents the rejection of the Camunda file.  Two fixture files \u002B 6 anchor tests \u002B this KB.  N=1 worked example proves BPMN interop is real for the V17.1 subset and surfaces V17.1b as the next deliverable when operator needs real-Camunda-file import.","tags":["v17","v17.4","bpmn","worked-example","camunda","pizza-order"],"source":"SPICE.Web.Tests/Fixtures/BPMN/PizzaOrder.bpmn"},{"kind":"KnowledgeArticle","id":"KB.V171BpmnVendoring","name":"V17.1 BPMN 2.0 XSD vendoring - phantom-check confirms V12.6b/V15.3 pattern","description":"V17.1 ran the phantom-check on BPMN vendoring: V12.6b UBL \u002B V15.3 OASIS CIQ patterns carry over with zero new engine code.  Curated minimal-subset BPMN 2.0 XSD vendored; full OMG bundle deferred to V17.1b.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"V17.1 ran the V16.1-receipt phantom-check on BPMN 2.0 XSD vendoring.  Question: do V12.6b UBL \u002B V15.3 OASIS CIQ vendoring patterns cover BPMN, or does it need a separate engine rail?\n\nPHANTOM-CHECK FINDING: V12.6b/V15.3 pattern covers BPMN exactly.  PhaseOrchestrator.ResolveSchemaPath already probes BOTH (a) ContentRoot/Config/{path} for platform-internal schemas AND (b) AppContext.BaseDirectory/{path} for App-package vendored schemas.  Phase.OutputSchema=Schemas/BPMN-2.0/BPMN20.xsd wires the rail; XmlSchemaSet loads \u002B validates.  Zero new code.\n\nVENDORING LOCATION DECISION: SPICE.Web/Config/Schemas/BPMN-2.0/, NOT an App package.  Rationale:\n  - BPMN is a platform-wide standard (V17.2 projection XSLT walks Workflow \u002B DecisionTable parts across MANY App packages: Tcm/Td/Tf/Tp/etc.).  UBL was Tf-specific (Invoice); CIQ was Tcm-specific (Lead/Opportunity); BPMN is process-engine-wide.\n  - Centralised at SPICE.Web/Config/Schemas/ matches the V12.6b \u0022platform-internal schemas\u0022 path probe (V12.6b/V15.3 used App-package path).\n  - V17.2 XSLT lives at SPICE.Web/wwwroot/XSLT/ (platform-wide); pairing the XSD next to the projection target keeps the lookup consistent.\n\nXSD SCOPE - curated minimal subset:\n  Hand-crafted single-file BPMN20.xsd covering the constructs V17.2 projection XSLT emits:\n    bpmn:definitions, bpmn:process, bpmn:startEvent, bpmn:endEvent,\n    bpmn:task (with @implementation = SPICE Skill ref), bpmn:sequenceFlow\n    (with conditionExpression for CrossModuleRule.Match labels),\n    bpmn:exclusiveGateway (for DecisionTable XOR routing).\n\nWHY NOT THE FULL OMG BUNDLE:\n  - The OMG BPMN 2.0 spec ships 7\u002B XSDs with deeply recursive substitution groups (Activity -\u003E Task -\u003E ServiceTask etc.) and abstract bases.  Authored for full-fidelity BPMN tooling; more permissive than V17 needs.\n  - Round-trip integrity for the V17.2/V17.3 export/import pair is better served by a tight subset that names exactly the constructs we model.  Permissive validation (full OMG) would let an unknown BPMN construct through that V17.3 import couldn\u0027t actually map to a typed part.\n  - The subset uses the OFFICIAL BPMN namespace (http://www.omg.org/spec/BPMN/20100524/MODEL) so .bpmn files exported from SPICE open correctly in bpmn.io, Camunda Modeler, and any compliant BPMN viewer.\n\nV17.1B CANDIDATE: when V17.4 surfaces a real Camunda BPMN file that uses constructs this subset doesn\u0027t model (boundary events, timer events, parallel gateways, call activities, sub-processes), swap in the full OMG bundle.  Until then, the subset gives us:\n  - V12.6b/V15.3 vendoring shape with one file instead of seven\n  - Faster validator surface (one XSD vs seven imports)\n  - Honest receipt that V17 only claims to round-trip what V17.2 emits\n\nTHIRD STANDARDS-VENDOR RECEIPT (after V12.6 UBL \u002B V15.3 CIQ).  Pattern compounds:\n  Schemas/UBL/maindoc/UBL-Invoice-2.1.xsd     -\u003E Phase.IssueInvoice (Tf)\n  Schemas/OASIS-CIQ-v3/xPIL.xsd               -\u003E Phase.IssueOpportunity (Tcm)\n  Schemas/BPMN-2.0/BPMN20.xsd                 -\u003E Phase.IssueBpmnProcess (platform-wide)\n\nV17.1 SUB-2-HOUR CLOSE confirms the V16.1 phantom-check discipline pays off again - investigate before designing, ship the verification cycle as a receipt-plus-trivia delta.  Banked next to the V16.1 receipt as \u0022phantom-check before designing is now N=3 (V15.3, V16.1, V17.1) - promoted to default expectation for any horizon row that smells like vendoring or contract addition.\u0022","tags":["v17","v17.1","bpmn","xsd-vendoring","phantom-check","standards"],"source":"SPICE.Web/Config/Schemas/BPMN-2.0/BPMN20.xsd"},{"kind":"KnowledgeArticle","id":"KB.V16HorizonDebrief","name":"V16 horizon close - external client portal as manifest concern","description":"What V16.0 through V16.7 delivered, three patterns banked (phantom-check, N-level resolution, cross-App composition), prediction grading, and V17 strategic-theme pick (BPMN compatibility).","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"V16 closed in a single session (eight cycles, commits e23c154 through bac7084).  Tests 1780 -\u003E 1868 (\u002B88).  KnowledgeArticles 36 -\u003E 40 (KB.V161PortalAuthSeamCheck, KB.V165PartySkuCoverage, KB.V166VendorPortal, plus this debrief).\n\nDELIVERED:\n  - V16.4 ClientPortal at /sites/ClientPortal with 6 lists across\n    Tcm \u002B Tf (Leads/Activities/CommunicationLogs/Quotes/Invoices/\n    PartyRelationships), PartySku-scoped per actor.\n  - V16.6 VendorPortal at /sites/VendorPortal with 2 lists across\n    Td \u002B Tf (PurchaseOrders/SupplierInvoices), SupplierSku-scoped.\n  - Six related opt-in seams: IActorContext.PartySku (V16.2),\n    OidcAuthOptions.PartyClaim (V16.2), ContentType.ExternalSubmittable\n    (V16.3), FieldDefinition.ReadOnly \u002B Hidden \u002B Description-tooltip\n    (V16.3b), ContentType.PartyScopeField (V16.5), manifest\n    \u003CList PartyScopeField/\u003E (V16.6).  All opt-in additive shape;\n    88 pre-V16 CTs \u002B 455 pre-V16 FieldDefs unchanged.\n\nTHREE PATTERNS BANKED (Section 13.15.1):\n\n  (1) Phantom-requirement check before designing.  V15.3 \u002B V16.1\n      now N=2 receipts; promoted from \u0022new pattern\u0022 to \u0022standard\n      discipline.\u0022  Every horizon-opener seam row earns one\n      verification step before code.  V16.1 found 3 phantom \u002B 1\n      real; sub-2-hour cycle banked the V16.2 recipe.\n\n  (2) N-level resolution as compounding override seam.  V16.5\n      shipped single-level override (CT.PartyScopeField); V16.6\n      surfaced multi-party-CT case (UBL Invoice serving both\n      portals) and extended to three-level (List \u003E CT \u003E\n      convention).  Anti-pattern #15 (additive shape over rename)\n      compounded six ways in one horizon.\n\n  (3) Cross-App composition is a manifest concern.  V16.4 \u002B V16.6\n      reuse the same Invoice CT through different party axes,\n      zero per-App wiring.  The typed-XML spine reaches across\n      App boundaries because parts live in a global registry.\n      Future portals = manifest edits \u002B zero-to-N opt-in attrs.\n\nPREDICTION GRADING (5-for-5 on shape; estimates off 2-5x cheaper):\n  V16.1 auth phantom - confirmed with 1 real calibration (PartySku).\n  V16.2 row scope via CAML - shape confirmed, layer wrong (projection\n    not CAML); KISS won.\n  V16.3 FormView XSLT-touch - wrong layer; XSLT already covered\n    Display vs Edit branching; cost was contract plumbing.\n  V16.4 N=1 pure-XML - confirmed exactly; 5x cheaper than estimated.\n  V16.6 N=2 ran (V16.4 shipped clean); surfaced one small new seam\n    (per-list override) that compounds.\n\nBanked recalibration: at current cadence, multiply build estimates\nby 0.2-0.5 against pre-V11 anchors.  Single-session unless 15\u002B\ncycle-units.\n\nV17 STRATEGIC-THEME PICK - BPMN compatibility:\n  - V15.5-deferred candidate; now clear V17 pick.\n  - BPMN is a serialisation layer over V14.2c CrossModuleRule \u002B\n    V14.7 DecisionTable \u002B V15.4 Match wildcards (= the existing\n    declarative process engine).  Anti-pattern #18 spirit:\n    integrate natively, not build connector.\n  - Three prior receipts compose into V17: V12.6 UBL XSD vendoring,\n    V15.3 OASIS CIQ vendoring, V16.6 cross-App composition.\n  - Operator-visible: BPMN-projection XSLT exports existing\n    Workflow \u002B DecisionTable as bpmn.io / Camunda Modeler-readable\n    .bpmn files.  Auditors and process-design teams inspect the\n    same workflows operators authored as XML.\n\n  V17 cycle sketch:\n    V17.0  Horizon opener \u002B V17Backlog.xml.\n    V17.1  Vendor BPMN 2.0 XSDs \u002B Phase.OutputSchema validation rail.\n    V17.2  BPMN-projection XSLT (Workflow \u002B Steps \u002B Transitions -\u003E\n           BPMN \u003Cprocess\u003E).\n    V17.3  BPMN-import endpoint (.bpmn -\u003E Workflow \u002B Phase \u002B\n           DecisionTable \u002B CrossModuleRule).\n    V17.4  N=1 worked example (Camunda pizza-order import \u002B run).\n    V17.5  V14.7 DecisionTable BPMN export \u002B V16.5b/V16.6b\n           cleanup sub-cycle.\n    V17.6  Horizon debrief.\n\nDEFERRED (V17.5 or later):\n  - V16.5b BusinessPartner self-scope (needs stable Sku column \u002B\n    \u0022My Profile\u0022 portal list).\n  - V16.5b PartyRelationship bidirectional view (FromPartySku OR\n    ToPartySku).\n  - V16.6b ShipmentNotice SupplierSku for VendorPortal inbound\n    shipment tracking.\n  - Employee portal (V17 alternative if BPMN over-budget; V18\n    otherwise) - needs new Timesheet \u002B LeaveRequest CTs.\n\nV16 single-sentence frame: \u0022V16 turned three V14.5 anticipated hooks\ninto an operationally multi-tenant portal surface - manifest-only -\nand banked that external-portal addition is a manifest concern, not\nan engine concern, with six opt-in seams composing across CT \u002B\nField \u002B List \u002B Actor.\u0022","tags":["v16","v16.7","horizon-close","portal","phantom-check","n-level-resolution","cross-app"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.V166VendorPortal","name":"V16.6 VendorPortal N=2 receipt \u002B per-list PartyScopeField override","description":"N=2 generalisation of the V16.4 ClientPortal shape against a vendor (supplier) audience.  Banks the per-list override mechanism that lets the same multi-party CT (UBL Invoice) serve different portals with different party axes.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"V16.6 ships the N=2 portal generalisation receipt: VendorPortal mirrors V16.4 ClientPortal shape against a different audience (suppliers rather than customers).  Together V16.4 \u002B V16.6 demonstrate the external-portal shape is a manifest concern, not a per-app concern.\n\nVENDORPORTAL (DeptCode=VEN, Theme=CorporateBlue):\n  - PurchaseOrders  -\u003E ContentType.PurchaseOrder (Td)\n  - SupplierInvoices -\u003E ContentType.Invoice (Tf, per-list override)\n\nBoth lists read-only (CT-level ExternalSubmittable defaults false).  Suppliers track their POs \u002B invoice statuses; PO/invoice creation stays operator-driven through Td/Tf workflows.\n\nV16.6 MECHANISM - per-list PartyScopeField override:\n\n  \u003CList Name=\u0022SupplierInvoices\u0022 ContentType=\u0022ContentType.Invoice\u0022\n        Versioning=\u0022true\u0022 PartyScopeField=\u0022SupplierSku\u0022 /\u003E\n\nThree-level resolution in ApplyPartyScope \u002B BuildItemForm:\n\n  (1) Manifest \u003CList PartyScopeField=\u0022X\u0022/\u003E            (V16.6 most specific)\n  (2) ContentType.PartyScopeField                       (V16.5 CT-level)\n  (3) \u0022PartySku\u0022 convention                             (V16.2 fallback)\n\nWhy the override matters: UBL Invoice carries BOTH cac:AccountingSupplierParty (SupplierSku) AND cac:AccountingCustomerParty (CustomerSku).  V16.5 set the CT-level default to CustomerSku for ClientPortal.  Without V16.6\u0027s list-level override, VendorPortal would either need (a) a duplicate \u0022SupplierInvoice\u0022 CT (heavyweight, splits the UBL invoice across two schemas) or (b) ClientPortal forgoes Invoice scoping (LEAK).  Per-list override is the right seam - same CT, different axis per portal context.\n\nV16.6 CT OPT-INS:\n  ContentType.PurchaseOrder (Td) - PartyScopeField=\u0022SupplierSku\u0022 at CT level.  No per-list override needed for the PurchaseOrders list because the CT name aligns with the only realistic portal context (suppliers).\n\nCROSS-APP COMPOSITION RECEIPT:\n  V16.4 ClientPortal: Tcm \u002B Tf parts (6 lists)\n  V16.6 VendorPortal: Td \u002B Tf parts (2 lists)\n  Both reuse the same Invoice CT (Tf) but project different party-scope axes.  Demonstrates parts live in a global registry; SiteBlueprints reach across App boundaries; per-list override teaches the same multi-party CT to serve different portals.  Useful precedent for V17 employee portal or any future external surface that needs to project an existing CT through a new party axis.\n\nDEFERRED (V16.6b candidates if a real driver surfaces):\n  - ShipmentNotice (Td) on VendorPortal: has SnCarrierSku, no SupplierSku.  Vendor inbound-shipment tracking needs either Field.SnSupplierSku added OR a new \u0022GoodsReceipt\u0022 CT modeling the operator\u0027s receiving side.  Skipped from V16.6 to keep the N=2 receipt focused.\n  - Employee portal: timesheets \u002B leave CTs DON\u0027T EXIST in the platform yet.  V17 candidate alongside the V15.5-deferred BPMN engine.\n  - Bidirectional party visibility (PartyRelationship From OR To): V16.5 deferred item still open; multi-direction view becomes relevant if a future portal needs it (employee portal \u0022my reports and my manager\u0022 might).\n  - Vendor-side write paths (AcceptPurchaseOrder transition, supplier-uploaded shipment confirmation): V17\u002B if the read-only V16.6 surface earns its weight.\n\nRECIPE FOR FUTURE PORTAL CYCLES:\n  Adding portal N to an existing CT set is now a manifest-only operation:\n  (1) Audit each list\u0027s party axis (SupplierSku, CustomerSku, FromPartySku, etc.).\n  (2) If the axis is the CT\u0027s natural single party hook, set ContentType.PartyScopeField at the CT-level once.\n  (3) If the same CT serves multiple portals with different axes (multi-party CTs like UBL Invoice), keep the CT-level default for the most common case and override per-list for the others.\n  (4) Set ExternalSubmittable on the CTs the portal needs to accept new submissions on (default read-only).\n  (5) Ship the SiteBlueprint.  No engine code.","tags":["v16","v16.6","partysku","portal","vendor","worked-example"],"source":"SPICE.Web/Services/ListViewModelBuilder.cs"},{"kind":"KnowledgeArticle","id":"KB.V165PartySkuCoverage","name":"V16.5 PartySku hook coverage audit \u002B ContentType.PartyScopeField override","description":"Audit of every V16.4 ClientPortal CT\u0027s PartySku hook coverage and the V16.5 fix for two real leaks (Invoice \u002B PartyRelationship).","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"V16.5 audited the six V16.4 ClientPortal CTs (Lead, Activity, CommunicationLog, Quote, Invoice, PartyRelationship) for V14.5 PartySku hook coverage.  The V16.2 ApplyPartyScope filter literally looks for a field named \u0022PartySku\u0022 via the PartyScopeFieldName const; when absent, the filter skips and external clients see every row (LEAK).\n\nAUDIT FINDINGS:\n\n  | CT                  | Field name             | Status            |\n  |---------------------|------------------------|-------------------|\n  | Lead (Tcm)          | PartySku               | OK (V14.5)        |\n  | Activity (Tcm)      | PartySku               | OK (V14.5)        |\n  | CommunicationLog    | PartySku               | OK (V14.5)        |\n  | Quote (Tcm)         | PartySku               | OK (V14.5)        |\n  | Opportunity (Tcm)   | PartySku               | OK (V14.5, off-portal) |\n  | Invoice (Tf)        | CustomerSku (UBL)      | LEAK fixed V16.5  |\n  | PartyRelationship   | FromPartySku/ToPartySku | LEAK fixed V16.5 |\n  | BusinessPartner (Tc)| no Sku field today     | DEFER (not on portal) |\n\nV14.5 hooks paid off for 5 of 6 portal-relevant CTs; the other two needed the V16.5 override below.  Honest grade: V14.5\u0027s \u0022every workflow CT carries PartySku\u0022 was 5/7 accurate; the 2 outliers used domain-aligned names (UBL CustomerSku for Invoice; CIQ-style From/To pair for PartyRelationship).\n\nV16.5 FIX - ContentType.PartyScopeField attribute:\n\n  \u003CContentType ... PartyScopeField=\u0022CustomerSku\u0022/\u003E        (Invoice)\n  \u003CContentType ... PartyScopeField=\u0022FromPartySku\u0022/\u003E       (PartyRelationship)\n\nDefaults to \u0022PartySku\u0022 when omitted, so all V14.5 Tcm CTs continue working unchanged (zero breakage).  V16.2 ApplyPartyScope \u002B V16.2 BuildItemForm both honour the override.  V11.4 additive init-only shape (init { get; init; }).  XSD adds optional xs:string attribute.\n\nDEFERRED:\n  BusinessPartner (Tc) does NOT have a Sku-name field today; identifier is Title.  Setting PartyScopeField=\u0022Title\u0022 would technically work but Title is a display name, not a stable identity.  Defer until V16.5b adds Field.BpSku as a stable identity column \u002B adds BusinessPartner to ClientPortal as \u0022My Profile\u0022 list.  Two-step shape: identity column first, then portal exposure.\n\n  PartyRelationship.ToPartySku visibility: V16.5 picks FromPartySku as canonical (the party that initiated the relationship sees it).  V16.5b candidate: bidirectional visibility - external client sees relationships where they are EITHER From OR To.  Requires either OR-predicate support in ApplyPartyScope or a new convention (e.g. PartyScopeField=\u0022FromPartySku|ToPartySku\u0022 CSV).  Deferred until V16.6 N=2 portal surfaces the use case (vendor portal likely needs From-only view; employee portal likely needs both).\n\nRECEIPT FOR FUTURE CYCLES:\n  When adding a new ContentType to a portal blueprint, audit-and-declare:\n  (a) is there a single field name that represents \u0022which BusinessPartner this row belongs to\u0022?  If \u0022PartySku\u0022, convention covers it.  If anything else, declare PartyScopeField=\u0022X\u0022.\n  (b) is the row scoped by exactly ONE party, or two?  V16.5 supports one; multi-party rows wait for V16.5b.\n  (c) is the row external-submittable (V16.3 ExternalSubmittable=\u0022true\u0022) or read-only?  Two orthogonal axes; declare both.\n\nComposes with V14.5 Classification (role-based field visibility) and V16.3 ExternalSubmittable (CT-level form-mode gate) and V16.3b per-field affordances.  Four V16 attributes now compose: PartyScopeField (V16.5) \u002B ExternalSubmittable (V16.3) \u002B ReadOnly/Hidden/Description (V16.3b) - all opt-in additive shape per anti-pattern #15.","tags":["v16","v16.5","partysku","portal","audit","convention"],"source":"SPICE.Web/Services/ListViewModelBuilder.cs"},{"kind":"KnowledgeArticle","id":"KB.V161PortalAuthSeamCheck","name":"V16.1 phantom-requirement check on portal auth seam","description":"V16.1 verified before designing: OIDC plugin \u002B RoleMapper \u002B HttpContextActorContext already compose for external clients via configuration alone.  The real V16.2 seam is PartySku binding to IActorContext, not authentication.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"The V16.0 horizon-opener row for V16.1 said \u0022verify Plugins.Auth.Oidc \u002B IActorContext \u002B RoleMapper already compose for external-client auth.  Magic-link only if OIDC per-tenant config is unmaintainable.\u0022  V16.1 ran the check.  THREE phantom findings \u002B ONE real finding:\n\n(1) PHANTOM: Authentication itself.  SPICE.Plugins.Auth.Oidc.OidcAuthPluginModule activates on Auth:Authority and wires Cookie \u002B OIDC schemes via standard ASP.NET Core.  Authentik / Auth0 / Okta / Keycloak / Azure AD all work by configuration only (OidcOptions docstring lists them).  External clients sit in the operator\u0027s existing IdP (or a federated trust), authenticate via the same OIDC flow, and present a different group claim.  No new code; no magic-link plugin.\n\n(2) PHANTOM: Role taxonomy.  PartRole has four levels (Manager \u003E Lead \u003E Member \u003E Assistant).  RoleMapper.DeriveRole maps claim values to one of those four; unknown groups fall back to Assistant (the lowest authenticated role).  External clients map to Assistant via an OidcOptions.RoleMapping entry like \u0022Assistant\u0022: [ \u0022external-clients\u0022 ].  Adding a fifth \u0022External\u0022 PartRole would be premature - per anti-pattern #15 (additive shape over rename), defer the fifth role until V16.6\u002B surfaces a behaviour the four-role model can\u0027t express.  Until then, \u0022external client\u0022 is \u0022Assistant role \u002B PartySku scope\u0022.\n\n(3) PHANTOM: HttpContextActorContext routing.  Reads ClaimsPrincipal from IHttpContextAccessor, projects to ActorId / DisplayName / Role / IsAuthenticated.  ActorId pulls \u0022sub\u0022 claim with NameIdentifier fallback; DisplayName tries preferred_username / name / email.  Same shape will pick up external-client claims with zero change.\n\n(4) REAL: PartySku binding to IActorContext.  IActorContext exposes ActorId, DisplayName, Role, IsAuthenticated - no PartySku.  V14.5/V14.6/V15.2/V15.3 anchored every external-visible CT (Lead, Opportunity, Activity, Quote, CommunicationLog, PartyRelationship) on a PartySku Lookup against Common/BusinessPartners, BUT no claim-to-PartySku resolution exists today.  This is the V16.2 seam.\n\nRecommended V16.2 shape (banked here so V16.2 doesn\u0027t re-decide): ADD one nullable string PartySku property to IActorContext.  HttpContextActorContext reads a configured claim (default \u0022party_sku\u0022) with a SubClaimLookup fallback (resolve via Common/BusinessPartners.ExternalUserSubject column - V16.2 may need to add this column to BusinessPartner).  OidcOptions gains PartyClaim = \u0022party_sku\u0022 with a default and PartyLookupColumn = \u0022ExternalUserSubject\u0022 with a default.  IListViewBuilder \u002B IItemFormBuilder consume IActorContext.PartySku for PartySku-scoped CAML Eq() injection.  Alternatives rejected: (a) Sibling IActorPartyScope service - extra interface for one field; consumers already inject IActorContext, so the field rides for free.  (b) Stamp PartySku as a Claim and let CAML predicate handlers read claims - too implicit; making it explicit on IActorContext keeps the typed contract honest.\n\nExternal-client OIDC config recipe (operator copy-paste): set Auth:Authority to the IdP; set Auth:RoleMapping:Assistant to include the external-clients group; set Auth:PartyClaim to the claim that carries the BusinessPartner Sku (or use Auth:PartyLookupColumn to resolve via sub claim if the IdP doesn\u0027t expose Sku directly).  No platform code change.\n\nV16.1 grade for prediction Section 13.14.2 #1 (\u0022V16.1 auth is a phantom-requirement check, not a build cycle\u0022): CONFIRMED.  V16.1 ships as a verification cycle \u002B KB filing \u002B sub-2-hour close.  V16 sizing therefore drops from 8-12 to 7-11 cycle-units (still two-session, but tighter).","tags":["v16","v16.1","auth","oidc","partysku","phantom-requirement","portal"],"source":"SPICE.Foundation/IActorContext.cs"},{"kind":"FieldDefinition","id":"Field.Title","name":"Title"},{"kind":"FieldDefinition","id":"Field.Body","name":"Body"},{"kind":"FieldDefinition","id":"Field.Status","name":"Status"},{"kind":"FieldDefinition","id":"Field.Author","name":"Author"},{"kind":"FieldDefinition","id":"Field.CreatedAt","name":"CreatedAt"},{"kind":"FieldDefinition","id":"Field.Decision","name":"Decision"},{"kind":"FieldDefinition","id":"Field.Consequences","name":"Consequences"},{"kind":"ContentType","id":"ContentType.Item","name":"Item"},{"kind":"ContentType","id":"ContentType.Document","name":"Document"},{"kind":"ContentType","id":"ContentType.SourceDocument","name":"Source Document"},{"kind":"ContentType","id":"ContentType.ArchitectureDecisionRecord","name":"Architecture Decision Record"},{"kind":"Feature","id":"Feature.Compliance","name":"Compliance feature"},{"kind":"Feature","id":"Feature.QualityReview","name":"Quality review feature"},{"kind":"Feature","id":"Feature.AgencyBasics","name":"Agency basics"},{"kind":"Feature","id":"Feature.DailyIntelligence","name":"Daily Intelligence"},{"kind":"Skill","id":"Skill.ScoutLeads","name":"Scout leads","description":"Scan the outside world for demand signals - things people are already asking for or building - and bring back a ranked shortlist of candidate venture leads with the evidence (who is asking, where, how strong the signal). The first phase of the venture pipeline; hands a validated shortlist to the idea/plan phases.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Processing","requiresApproval":false,"capabilities":["Search the web / connected sources for demand signals in a named domain","Cluster signals into candidate leads and rank by strength \u002B fit","Emit a ProvisioningDelta adding each ranked lead as a row in the division\u0027s Digest list (with the evidence \u002B source links)"],"requiresTools":["Tool.Llm"]},{"kind":"Phase","id":"Phase.ScoutLeads","name":"Scout leads"},{"kind":"Workflow","id":"Workflow.VentureEngine","name":"Venture Engine"},{"kind":"Feature","id":"Feature.VentureCrew","name":"Venture crew"},{"kind":"FieldDefinition","id":"Field.MsKind","name":"MsKind"},{"kind":"FieldDefinition","id":"Field.MsSource","name":"MsSource"},{"kind":"FieldDefinition","id":"Field.MsSubject","name":"MsSubject"},{"kind":"FieldDefinition","id":"Field.MsValue","name":"MsValue"},{"kind":"FieldDefinition","id":"Field.MsDelta","name":"MsDelta"},{"kind":"FieldDefinition","id":"Field.MsEvidence","name":"MsEvidence"},{"kind":"FieldDefinition","id":"Field.MsVolumes","name":"MsVolumes"},{"kind":"FieldDefinition","id":"Field.MsSeries","name":"MsSeries"},{"kind":"FieldDefinition","id":"Field.MsObservedAt","name":"MsObservedAt"},{"kind":"FieldDefinition","id":"Field.MsPartySku","name":"MsPartySku"},{"kind":"FieldDefinition","id":"Field.MsStatus","name":"MsStatus"},{"kind":"ContentType","id":"ContentType.MarketSignal","name":"Market Signal"},{"kind":"Skill","id":"Skill.ScoutSignals","name":"Scout market signals","description":"Watch the outside world for a named SignalKind (competitor/service PRICE moves, sales LEAD triggers, or market INTEL) and bring back a ranked shortlist of typed MarketSignal observations with the evidence \u002B source. Generalises Skill.ScoutLeads; the SignalKind \u002B target are set in the briefing. Files suggest-don\u0027t-seize.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Processing","requiresApproval":false,"capabilities":["Search the web / connected sources for the named SignalKind in a target domain","For Price: detect a competitor/service price or plan-tier change vs the last observation and compute the delta","For Lead: detect a trigger event (a posting, filing, funding, pricing change) that marks a prospect","Emit a ProvisioningDelta adding each signal as a ContentType.MarketSignal row in the division\u0027s Digest list (Kind, Subject, Source, Value, Delta, Evidence, ObservedAt, PartySku when matched)"],"requiresTools":["Tool.Llm"]},{"kind":"Phase","id":"Phase.ScoutSignals","name":"Scout market signals"},{"kind":"Workflow","id":"Workflow.WatchSignals","name":"Watch the world"},{"kind":"Schedule","id":"Schedule.QuoteHarvest","name":"Daily watchlist quotes"},{"kind":"Schedule","id":"Schedule.SourceHarvest","name":"Daily feed harvest"},{"kind":"Schedule","id":"Schedule.WatchSignalsDaily","name":"Daily market-signal watch"},{"kind":"Skill","id":"Skill.SteeringDeliberation","name":"Steer the roadmap","description":"Review where the city stands against its milestone ladder and its token spend, then propose the next priorities - what to build, what to defer, where the bottleneck is. Suggest-don\u0027t-seize: the output is advice for the captain, not an action.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Processing","requiresApproval":false,"capabilities":["Read the progression ladder \u002B the production/spend boards to judge trajectory","Name the current bottleneck and the highest-leverage next rung","Propose a ranked, briefly-justified set of roadmap priorities for the operator to approve"],"requiresTools":["Tool.Llm"]},{"kind":"Phase","id":"Phase.SteeringMeeting","name":"Steering meeting"},{"kind":"Workflow","id":"Workflow.SteeringMeeting","name":"Steering meeting"},{"kind":"Skill","id":"Skill.PlanningDeliberation","name":"Plan the work","description":"Take an approved priority and break it into a concrete, sequenced plan - the units of work, who does each, and the order - for the crew to execute. Suggest-don\u0027t-seize: the plan is a proposal for the operator.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Processing","requiresApproval":false,"capabilities":["Decompose an approved goal into sequenced units of work","Assign each unit to a fitting seat/department and note dependencies","Produce a short, ordered plan the crew can pick up"],"requiresTools":["Tool.Llm"]},{"kind":"Phase","id":"Phase.PlanningMeeting","name":"Planning meeting"},{"kind":"Workflow","id":"Workflow.PlanningMeeting","name":"Planning meeting"},{"kind":"Skill","id":"Skill.Adjudicate","name":"Adjudicate candidate answers","description":"Given one question and several candidate answers (each from a different agency), score each on a rubric - relevance, specificity, actionability, honesty - and pick a winner with a one-line justification. An evaluation specialist: it judges, it does NOT produce its own answer. Suggest-don\u0027t-seize - the ranking is advice for the operator.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Processing","requiresApproval":false,"capabilities":["Read a question and N candidate answers attributed to their agencies","Score each candidate on relevance, specificity, actionability and honesty (0-5 each)","Rank the candidates and name the winning agency with a one-line justification"],"requiresTools":["Tool.Llm"]},{"kind":"Phase","id":"Phase.Adjudicate","name":"Adjudicate"},{"kind":"Workflow","id":"Workflow.Adjudicate","name":"Adjudicator"},{"kind":"Skill","id":"Skill.Research","name":"Daily research scout","description":"Each day, scout the outside world for new information on a briefed topic, summarise the key findings \u002B why they matter, and name the agency that should act on them. The probe that feeds the research pipeline. Suggest-don\u0027t-seize: it files a finding \u002B a suggested target, it does not act.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Processing","requiresApproval":false,"capabilities":["Scout the web / connected sources for new developments on the briefed topic","Summarise the findings with their sources \u002B why they matter to the city","Name the single agency the finding should be dispatched to (the correct instance)"],"requiresTools":["Tool.Llm"]},{"kind":"Phase","id":"Phase.Research","name":"Research scout"},{"kind":"Workflow","id":"Workflow.Research","name":"Daily research"},{"kind":"Schedule","id":"Schedule.ResearchDaily","name":"Daily research scout"},{"kind":"Phase","id":"Phase.DailyBrief","name":"Daily intelligence brief"},{"kind":"Workflow","id":"Workflow.DailyBrief","name":"Daily intelligence brief"},{"kind":"Phase","id":"Phase.MakeDeck","name":"Make a deck"},{"kind":"Workflow","id":"Workflow.MakeDeck","name":"Make a deck (lean)"},{"kind":"Schedule","id":"Schedule.DailyBrief","name":"Daily intelligence brief"},{"kind":"Skill","id":"Skill.HealthReview","name":"Review system health","description":"Read the deterministic health signals (U1\u0027s heartbeat \u002B the fault Issues), classify the system healthy/degraded/down, name any NEW fault, and PROPOSE (never take) a remediation - then notify the operator. Shadow by construction: its only tools are read \u002B notify, so it cannot act on what it observes.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Review","requiresApproval":false,"capabilities":["Read the rolling health heartbeat and the open fault Issues","Classify the system state (healthy / degraded / down) from the evidence","Name new faults since the last review and cite the evidence","Propose a remediation as a suggestion - never execute it (suggest-don\u0027t-seize)","Notify the operator with a structured verdict"],"requiresTools":["Tool.FetchKnowledge","Tool.SendMail"]},{"kind":"ActorProfile","id":"Actor.Watchdog","name":"Watchdog (reliability watcher)"},{"kind":"Phase","id":"Phase.HealthReview","name":"Health review"},{"kind":"Workflow","id":"Workflow.WatchdogReview","name":"Watchdog review"},{"kind":"Schedule","id":"Schedule.WatchdogReview","name":"Shadow watchdog review"},{"kind":"SettingScope","id":"Scope.ResearchTopics","name":"Research watchlist (daily briefing topics)"},{"kind":"SettingScope","id":"Scope.Quests","name":"Quest board entry points (always-available actions)"},{"kind":"CrossModuleRule","id":"Rule.Marketplace.SignalRoutedToCrm","name":"MarketSignal Routed -\u003E CRM Activity on the related party"},{"kind":"Board","id":"Board.Atlas","name":"Architecture Atlas"},{"kind":"Board","id":"Board.Search","name":"Search Center"},{"kind":"Board","id":"Board.Competency","name":"Competency Matrix"},{"kind":"Board","id":"Board.Contracts","name":"Phase Contracts"},{"kind":"Board","id":"Board.KnowledgeGraph","name":"Knowledge Graph"},{"kind":"Board","id":"Board.Coverage","name":"Seat Coverage"},{"kind":"Board","id":"Board.Onboarding","name":"Operator Readiness"},{"kind":"Board","id":"Board.Manual","name":"Ship\u0027s Manual"},{"kind":"Board","id":"Board.Cycles","name":"Development Ledger"},{"kind":"Board","id":"Board.Efficiency","name":"Efficiency"},{"kind":"Board","id":"Board.Outcome","name":"Outcome"},{"kind":"Board","id":"Board.Production","name":"Production"},{"kind":"Board","id":"Board.Evals","name":"Evals"},{"kind":"Board","id":"Board.Briefings","name":"Daily Briefings"},{"kind":"Board","id":"Board.Gallery","name":"Gallery"},{"kind":"Board","id":"Board.Fuel","name":"Fuel"},{"kind":"Board","id":"Board.Comms","name":"Newsfeed"},{"kind":"Board","id":"Board.Tasks","name":"Tasks"},{"kind":"Board","id":"Board.Interactions","name":"Interactions"},{"kind":"Board","id":"Board.Watchlist","name":"Watchlist"},{"kind":"SettingScope","id":"Scope.DiagnosticLogging","name":"Diagnostic logging"},{"kind":"SettingScope","id":"Scope.RecycleBin","name":"Recycle bin"},{"kind":"Tool","id":"Tool.RecycleBinCleanup","name":"Recycle bin cleanup","description":"SharePoint\u0027s Recycle Bin timer job: purges every site\u0027s recycled rows older than RecycleBinRetentionPeriod days (Scope.RecycleBin). No arguments.","version":"1.0.0","classification":"Internal","minimumRole":"Manager","provider":"RecycleBinCleanupToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Schedule","id":"Schedule.RecycleBinCleanup","name":"Daily recycle bin cleanup"},{"kind":"FieldDefinition","id":"Field.RoutingRuleDescription","name":"RoutingRuleDescription"},{"kind":"FieldDefinition","id":"Field.RoutingPriority","name":"RoutingPriority"},{"kind":"FieldDefinition","id":"Field.RoutingEnabled","name":"RoutingEnabled"},{"kind":"FieldDefinition","id":"Field.RoutingContentType","name":"RoutingContentType"},{"kind":"FieldDefinition","id":"Field.RoutingConditions","name":"RoutingConditions"},{"kind":"FieldDefinition","id":"Field.RoutingTargetPath","name":"RoutingTargetPath"},{"kind":"ContentType","id":"ContentType.RoutingRule","name":"Content Organizer Rule"},{"kind":"ListTemplate","id":"ListTemplate.DropOffLibrary","name":"Drop Off Library"},{"kind":"ListTemplate","id":"ListTemplate.RoutingRules","name":"Content Organizer Rules"},{"kind":"Tool","id":"Tool.ContentOrganizerProcessing","name":"Content Organizer Processing","description":"SharePoint\u0027s Content Organizer Processing job: routes again what still waits in every site\u0027s Drop Off Library. No arguments.","version":"1.0.0","classification":"Internal","minimumRole":"Manager","provider":"ContentOrganizerProcessingToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Schedule","id":"Schedule.ContentOrganizerProcessing","name":"Daily content organizer processing"},{"kind":"FieldDefinition","id":"Field.TargetApplicationId","name":"TargetApplicationId"},{"kind":"FieldDefinition","id":"Field.CredentialType","name":"CredentialType"},{"kind":"FieldDefinition","id":"Field.Credential","name":"Credential"},{"kind":"FieldDefinition","id":"Field.ContactEmail","name":"ContactEmail"},{"kind":"ContentType","id":"ContentType.TargetApplication","name":"Target Application"},{"kind":"ListTemplate","id":"ListTemplate.SecureStore","name":"Secure Store"},{"kind":"Board","id":"Board.DiagnosticLogging","name":"Diagnostic logging"},{"kind":"CustomAction","id":"CustomAction.Monitoring.DiagnosticLogging","name":"View diagnostic log"},{"kind":"Board","id":"Board.Health","name":"Health Analyzer"},{"kind":"Board","id":"Board.Lifecycle","name":"Lifecycle"},{"kind":"Board","id":"Board.DataFlow","name":"Data Flow"},{"kind":"Board","id":"Board.Workflows","name":"Workflows"},{"kind":"Board","id":"Board.Machines","name":"Machine Catalog"},{"kind":"Board","id":"Board.Organogram","name":"Organogram"},{"kind":"Board","id":"Board.Gaps","name":"Gaps"},{"kind":"Board","id":"Board.Wisdom","name":"Lessons Learned"},{"kind":"Board","id":"Board.Registry","name":"Registry"},{"kind":"Board","id":"Board.Academy","name":"Academy"},{"kind":"Board","id":"Board.Agencies","name":"Agencies"},{"kind":"Board","id":"Board.Strategy","name":"Strategy"},{"kind":"Board","id":"Board.Schedule","name":"Timer Job Status"},{"kind":"Board","id":"Board.Credits","name":"Credits"},{"kind":"Board","id":"Board.Quests","name":"Quests"},{"kind":"FieldDefinition","id":"Field.LeadDomain","name":"LeadDomain"},{"kind":"FieldDefinition","id":"Field.LeadEvidence","name":"LeadEvidence"},{"kind":"FieldDefinition","id":"Field.LeadStrength","name":"LeadStrength"},{"kind":"FieldDefinition","id":"Field.VentureLeadStatus","name":"VentureLeadStatus"},{"kind":"FieldDefinition","id":"Field.IdeaProblem","name":"IdeaProblem"},{"kind":"FieldDefinition","id":"Field.IdeaApproach","name":"IdeaApproach"},{"kind":"FieldDefinition","id":"Field.IdeaSourceLead","name":"IdeaSourceLead"},{"kind":"FieldDefinition","id":"Field.IdeaStatus","name":"IdeaStatus"},{"kind":"FieldDefinition","id":"Field.SpecKind","name":"SpecKind"},{"kind":"FieldDefinition","id":"Field.SpecBody","name":"SpecBody"},{"kind":"FieldDefinition","id":"Field.SpecSourceIdea","name":"SpecSourceIdea"},{"kind":"FieldDefinition","id":"Field.SpecStatus","name":"SpecStatus"},{"kind":"FieldDefinition","id":"Field.PlanBody","name":"PlanBody"},{"kind":"FieldDefinition","id":"Field.PlanSourceSpec","name":"PlanSourceSpec"},{"kind":"FieldDefinition","id":"Field.PlanStatus","name":"PlanStatus"},{"kind":"ContentType","id":"ContentType.VentureLead","name":"Venture Lead"},{"kind":"ContentType","id":"ContentType.IdeaBrief","name":"Idea Brief"},{"kind":"ContentType","id":"ContentType.Spec","name":"Spec"},{"kind":"ContentType","id":"ContentType.ProjectPlan","name":"Project Plan"},{"kind":"KnowledgeArticle","id":"KB.AgenticToolUse","name":"Agentic chat tool-use guidance","description":"Appended to an actor\u0027s system prompt when it has tools, so it ACTS via its tools instead of only describing - and never overpromises capabilities the city lacks (e.g. real email). Read by ChatAgentToolInvoker.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"You have real tools available. When the operator asks for something one of your tools can do - for example building an agency or a division - USE the tool with their request rather than only describing it. Your build tools PARK a proposal for the operator\u0027s approval; nothing is built without their yes, so it is safe to act. After a tool runs, tell the operator plainly what you parked and that it awaits their approval. IMPORTANT - the city has NO real email: never promise to email or text anyone. When something should \u0027notify\u0027 or \u0027email\u0027 the operator, it means delivering to their Hub inbox (use Tool.SendMail). Only promise actions your tools can actually perform; never invent capabilities you lack.","tags":["agentic-chat","prompt"],"source":"feedback_declarative_first"},{"kind":"KnowledgeArticle","id":"KB.ReActProtocol","name":"ReAct tool-call protocol","description":"The text protocol a non-function-calling provider (e.g. DeepSeek) follows to call a tool in the agentic chat loop. The C# appends the live tool catalog after it - the PROSE is data, the catalog is rendered. Read by ChatAgentToolInvoker.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"To use a tool, reply with EXACTLY one line and nothing else: CALL \u003CToolName\u003E \u003Ccompact-json-args\u003E. Example: CALL Tool.BuildDivision {\u0022task\u0022:\u0022monitor competitor pricing weekly\u0022}. The system runs the tool and gives you the result, then you continue. When you are finished, reply normally to the operator with NO CALL line. Your build tools only PARK a proposal for the operator\u0027s approval, so it is always safe to act.","tags":["agentic-chat","prompt"],"source":"feedback_declarative_first"},{"kind":"KnowledgeArticle","id":"KB.GenesisManifesto","name":"Genesis crew manifesto","description":"The shared brief for the Genesis crew - the meta-division that builds other Mission Divisions. Borrowed from Agency Swarm\u0027s agency_manifesto; the GenesisCEO/CrewSmith/PartSmith agents all read it.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"You are the Genesis crew of the SPICE city - your mission is to BUILD new divisions, the way Agency Swarm\u0027s Genesis agency builds agencies. A SPICE division = a SiteBlueprint instantiated from SiteTemplate.MissionDivision \u002B a crew (one ActorProfile per seat \u002B a Feature that binds the seats as skill-roles) \u002B a Workflow pipeline of Phases \u002B the shared artifact ContentTypes (VentureLead/IdeaBrief/Spec/ProjectPlan). WORKING RULES: (1) SUGGEST, DON\u0027T SEIZE - you PROPOSE a complete new division as one governed ProvisioningDelta; nothing is created until the operator approves it at Tool.ApprovalGate (KB.PaperclipWisdom). (2) Keep it small - at most 2-3 seats plus an orchestrator unless asked otherwise (Agency Swarm\u0027s rule). (3) REUSE first - bind existing Skills/Phases/ContentTypes before authoring new ones; only invent a part when none fits, and namespace it so it never collides with another division\u0027s part (the V25.2 ContentType.Lead lesson). (4) Comms flow over the message bus (IAgentMessageBus); the orchestrator talks to the operator, the smiths talk to the orchestrator. (5) Real instructions only - every agent you author gets a concrete role/goal/backstory, never a placeholder. (6) Build/test of any code the new division needs DELEGATES to the known-good Engineering crew (Workflow.ImplementThenValidate); verify the served surface with the smoke ritual. Start coached: the Engineering crew wears these Genesis hats until the loop is proven, then it runs on its own.","tags":["genesis","self-build","agency-swarm","mission-division"],"source":"plans/MissionDivision.md"},{"kind":"Skill","id":"Skill.GenesisDesign","name":"Genesis: design a division","description":"The GenesisCEO competency: gather the mission for a new division from the operator, then propose its structure - the seats (skill-roles), the Phase pipeline, the comms flows, and which existing parts to reuse. Proposes, never creates.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Processing","requiresApproval":false,"capabilities":["Name the division \u002B state its goal/mission; ask the operator for any clarification","Propose at most 2-3 seats plus an orchestrator, each with a one-line role, the skills it needs, and which existing parts to reuse","Define the Phase pipeline (the recipes) and the comms flows between the seats","Output the proposed division structure for operator confirmation before anything is built"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.GenesisCreateParts","name":"Genesis: create the parts","description":"The ToolCreator competency: author the Skill / Phase / Workflow parts the new division\u0027s agents need - real, ready-to-validate, no placeholders. Reuse existing parts where they fit; namespace new ones to avoid collisions.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Processing","requiresApproval":false,"capabilities":["Decide which Skills/Tools each proposed seat needs (reuse existing before inventing)","Author each new Skill (with Capabilities \u002B RequiresTool) and Phase (with a Goal \u002B UsesSkill) as a ProvisioningDelta fragment","Stitch the Phases into a Workflow (Steps in order; build/test steps delegate to the Engineering crew)","Namespace every new part id so it never collides with another division\u0027s part; flag anything that needs the operator\u0027s ask-first"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.GenesisCreateCrew","name":"Genesis: create the crew","description":"The AgentCreator competency: for each seat in the design, author an ActorProfile (the agent) with real role/goal/backstory instructions, competency-matched to the seat\u0027s skills, and bind the seats into a crew Feature.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Processing","requiresApproval":false,"capabilities":["Read KB.GenesisManifesto for shared context before authoring","Author one ActorProfile per seat: a real persona (role/goal/backstory) \u002B the SkillCatalog matching the seat\u0027s skills","Bind the seats into a crew Feature (BindSkill per seat at the right role)","Assemble everything into a single proposed AddSiteBlueprint delta (Template=SiteTemplate.MissionDivision \u002B the crew Feature), ready for the operator\u0027s approval at Tool.ApprovalGate"],"requiresTools":["Tool.Llm"]},{"kind":"Phase","id":"Phase.GenesisDesign","name":"Genesis: design"},{"kind":"Phase","id":"Phase.GenesisCreateParts","name":"Genesis: create parts"},{"kind":"Phase","id":"Phase.GenesisCreateCrew","name":"Genesis: create crew"},{"kind":"Workflow","id":"Workflow.GenesisBuildDivision","name":"Genesis: build a division"},{"kind":"Feature","id":"Feature.GenesisCrew","name":"Genesis crew"},{"kind":"FieldDefinition","id":"Field.IncomingRequestBody","name":"IncomingRequestBody"},{"kind":"FieldDefinition","id":"Field.IncomingRequestTarget","name":"IncomingRequestTarget"},{"kind":"FieldDefinition","id":"Field.IncomingRequestStatus","name":"IncomingRequestStatus"},{"kind":"ContentType","id":"ContentType.IncomingRequest","name":"Incoming Request"},{"kind":"FieldDefinition","id":"Field.ServiceRef","name":"ServiceRef"},{"kind":"FieldDefinition","id":"Field.ServiceOwner","name":"ServiceOwner"},{"kind":"FieldDefinition","id":"Field.ServiceFulfilment","name":"ServiceFulfilment"},{"kind":"FieldDefinition","id":"Field.Turnaround","name":"Turnaround"},{"kind":"FieldDefinition","id":"Field.DecisionSupported","name":"DecisionSupported"},{"kind":"FieldDefinition","id":"Field.RequestScope","name":"RequestScope"},{"kind":"FieldDefinition","id":"Field.ResearchDepth","name":"ResearchDepth"},{"kind":"FieldDefinition","id":"Field.Deliverable","name":"Deliverable"},{"kind":"ContentType","id":"ContentType.ServiceOffering","name":"Service Offering"},{"kind":"SavedQuery","id":"Query.ServiceCatalog","name":"The service catalog"},{"kind":"ListTemplate","id":"ListTemplate.IncomingRequests","name":"Requests"},{"kind":"Skill","id":"Skill.DispatchRequest","name":"Dispatch a request","description":"The Reception competency: read a New IncomingRequest, match it to the agency best fit by competency, route it (set Target \u002B Status=Dispatched, notify the agency over the bus). When NO agency fits, mark NeedsAgency and ask the Genesis crew to build one (gated). Routes - never does the requested work itself.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Processing","requiresApproval":false,"capabilities":["Read the new IncomingRequest and classify what competency it needs","Match it to an existing agency/division by its declared seats (the roster); pick the best fit","Emit a ProvisioningDelta updating the request: set IncomingRequestTarget \u002B IncomingRequestStatus=Dispatched, and route a message to the target agency over the bus","If no agency fits, set IncomingRequestStatus=NeedsAgency and propose a new division to the Genesis crew (Workflow.GenesisBuildDivision) - gated by the operator"],"requiresTools":["Tool.Llm"]},{"kind":"Phase","id":"Phase.DispatchRequest","name":"Dispatch a request"},{"kind":"Workflow","id":"Workflow.ReceiveAndDispatch","name":"Receive and dispatch"},{"kind":"EventReceiver","id":"ER.OnRequestDispatchedToGenesis","name":"On a request dispatched to Genesis: design the division"},{"kind":"EventReceiver","id":"ER.OnIncomingRequestAdded","name":"On incoming request: dispatch it"},{"kind":"Feature","id":"Feature.ReceptionCrew","name":"Reception crew"},{"kind":"ListTemplate","id":"ListTemplate.AdrLibrary","name":"Architecture Decision Records"},{"kind":"ListTemplate","id":"ListTemplate.Documents","name":"Documents"},{"kind":"EventReceiver","id":"ER.AdrAutoReview","name":"ADR auto-review"},{"kind":"EventReceiver","id":"ER.AnyDocAutoAssist","name":"Document auto-assist"},{"kind":"PolicyRule","id":"Policy.StorageWritesRequireManager","name":"Persistent storage access requires Manager","description":"Skills that depend on Tool.Storage may only be executed by Manager-level agents","version":"1.0.0","classification":"Confidential","minimumRole":"Manager","subject":"Tool.Storage","action":"Use","effect":"Deny"},{"kind":"PolicyRule","id":"Policy.ReleaseApprovalRequiresManager","name":"Release approval requires Manager role","description":"Production release approval requires a Manager-level agent","version":"1.0.0","classification":"Internal","minimumRole":"Manager","subject":"Skill.ApproveRelease","action":"Execute","effect":"Allow"},{"kind":"PolicyRule","id":"Policy.PublicKnowledgeForAll","name":"Public knowledge readable by all agents","description":"Knowledge articles classified Public are readable by any agent role","version":"1.0.0","classification":"Public","minimumRole":"Assistant","subject":"KnowledgeArticle","action":"Read","effect":"Allow"},{"kind":"PolicyRule","id":"Policy.SelfReviewElevation","name":"Self-review parts require Manager","description":"Mutations to Phase.SelfReview / Workflow.SelfReview / Schedule.SelfReview must be Manager-approved; the auto-apply path runs as Lead and is denied.","version":"1.0.0","classification":"Internal","minimumRole":"Manager","subject":"ProvisioningDelta","action":"Phase.SelfReview,Workflow.SelfReview,Schedule.SelfReview","effect":"Deny"},{"kind":"PolicyRule","id":"Policy.AgencyBirthElevation","name":"Agency birth requires Manager","description":"AutoGenesis-born agency deltas (Origin=AutoGenesis) must be Manager-approved; the auto-apply path runs as Lead and is denied, routing the birth to PendingElevation. Matches the structural Origin marker the sprawl cap also keys off.","version":"1.0.0","classification":"Internal","minimumRole":"Manager","subject":"ProvisioningDelta","action":"AutoGenesis","effect":"Deny"},{"kind":"PolicyRule","id":"Policy.ProcedureActivation","name":"Activating a Procedure requires Manager","description":"Flipping ContentType.Procedure rows from Draft to Active is the governance equivalent of a release sign-off; restrict to Manager. Member\u002B can still author Drafts and review them through the existing approval-quorum machinery.","version":"1.0.0","classification":"Internal","minimumRole":"Manager","subject":"ListItem","action":"ContentType=ContentType.Procedure;ProcedureStatus=Active","effect":"Deny"},{"kind":"Phase","id":"Phase.Implement","name":"Implement"},{"kind":"Phase","id":"Phase.Validate","name":"Validate"},{"kind":"Phase","id":"Phase.TriageIssue","name":"Triage Issue"},{"kind":"Phase","id":"Phase.ReviewProcedure","name":"Review Procedure"},{"kind":"Phase","id":"Phase.WriteWeeklyStatusReport","name":"Write weekly status report"},{"kind":"Phase","id":"Phase.SelfReview","name":"Self review"},{"kind":"Phase","id":"Phase.ConsolidateMemory","name":"Consolidate memory"},{"kind":"Phase","id":"Phase.EscalationDigest","name":"Escalation digest"},{"kind":"Phase","id":"Phase.RouteLeaveRequest","name":"Route Leave Request"},{"kind":"Phase","id":"Phase.AnnualHeadcountReview","name":"Annual Headcount Review"},{"kind":"Phase","id":"Phase.MonthlyClose","name":"Monthly Close"},{"kind":"Phase","id":"Phase.QuarterlyReport","name":"Quarterly Report"},{"kind":"Phase","id":"Phase.IntakeContract","name":"Intake Contract"},{"kind":"Phase","id":"Phase.ExpirationDigest","name":"Contract expiration digest"},{"kind":"Phase","id":"Phase.AwardBid","name":"Award Bid"},{"kind":"Phase","id":"Phase.IssueBpmnProcess","name":"Issue BPMN 2.0 Process (Workflow export)"},{"kind":"Connector","id":"Connector.ProvisioningPlaybook","name":"Provisioning playbook"},{"kind":"Connector","id":"Connector.ArXivLatest","name":"arXiv latest CS papers"},{"kind":"Connector","id":"Connector.HnFrontPage","name":"Hacker News front page"},{"kind":"Connector","id":"Connector.YahooQuote","name":"Quote (chart API)"},{"kind":"Connector","id":"Connector.ArXivAgents","name":"arXiv cs.MA (multi-agent)"},{"kind":"Connector","id":"Connector.SimonWillison","name":"Simon Willison\u0027s weblog"},{"kind":"Connector","id":"Connector.DotNetBlog","name":".NET engineering blog"},{"kind":"Connector","id":"Connector.AndrewLock","name":"Andrew Lock - .NET deep dives"},{"kind":"Connector","id":"Connector.HnNewest","name":"Hacker News - points threshold"},{"kind":"VectorStore","id":"VectorStore.Knowledge","name":"Knowledge article index"},{"kind":"GraphStore","id":"GraphStore.Knowledge","name":"Platform knowledge graph"},{"kind":"McpServer","id":"McpServer.Reference","name":"Reference MCP server (lazy-connected)"},{"kind":"Workflow","id":"Workflow.ImplementThenValidate","name":"Implement then Validate"},{"kind":"Workflow","id":"Workflow.HandleNewIssue","name":"Handle new Issue"},{"kind":"Workflow","id":"Workflow.WeeklyStatusReport","name":"Weekly status report"},{"kind":"Workflow","id":"Workflow.RouteIncomingTicket","name":"Route incoming support ticket"},{"kind":"Workflow","id":"Workflow.EscalationDigest","name":"Escalation digest"},{"kind":"Workflow","id":"Workflow.ReviewProcedure","name":"Review Procedure"},{"kind":"Workflow","id":"Workflow.WeeklyMemoryConsolidation","name":"Weekly memory consolidation"},{"kind":"Workflow","id":"Workflow.SelfReview","name":"Platform self-review"},{"kind":"Workflow","id":"Workflow.RouteLeaveRequest","name":"Route Leave Request"},{"kind":"Workflow","id":"Workflow.AnnualHeadcountReview","name":"Annual Headcount Review"},{"kind":"Workflow","id":"Workflow.MonthlyClose","name":"Monthly Close"},{"kind":"Workflow","id":"Workflow.QuarterlyReport","name":"Quarterly Report"},{"kind":"Workflow","id":"Workflow.ContractIntake","name":"Contract Intake"},{"kind":"Workflow","id":"Workflow.ExpirationDigest","name":"Contract Expiration Digest"},{"kind":"Workflow","id":"Workflow.AwardBid","name":"Award Bid"},{"kind":"Schedule","id":"Schedule.WeeklyStatusReport","name":"Weekly status report cadence"},{"kind":"Schedule","id":"Schedule.EscalationDigest","name":"Daily escalation digest"},{"kind":"Schedule","id":"Schedule.WeeklyMemoryConsolidation","name":"Weekly memory consolidation cadence"},{"kind":"Schedule","id":"Schedule.SelfReview","name":"Monthly self-review cadence"},{"kind":"Schedule","id":"Schedule.AnnualHeadcountReview","name":"Annual headcount review cadence"},{"kind":"Schedule","id":"Schedule.MonthlyClose","name":"Monthly close cadence"},{"kind":"Schedule","id":"Schedule.QuarterlyReport","name":"Quarterly report cadence"},{"kind":"Schedule","id":"Schedule.WeeklyExpirationDigest","name":"Weekly contract expiration digest"},{"kind":"Schedule","id":"Schedule.WeeklyBidAward","name":"Weekly bid award cadence"},{"kind":"SettingScope","id":"Scope.Farm","name":"Farm defaults"},{"kind":"SettingScope","id":"Scope.Outcome","name":"Outcome Unit tunables"},{"kind":"SettingScope","id":"Scope.NotStated","name":"Not-stated vocabulary"},{"kind":"SettingScope","id":"Scope.WorkflowHistory","name":"Workflow History landing"},{"kind":"SettingScope","id":"Scope.Eval","name":"Eval result landing \u002B heartbeat"},{"kind":"SettingScope","id":"Scope.SkillGrant","name":"Runtime skill-grant guard"},{"kind":"SettingScope","id":"Scope.Health","name":"District health honesty rules"},{"kind":"SettingScope","id":"Scope.Gaps","name":"Capability-gap routing"},{"kind":"SettingScope","id":"Scope.Commerce","name":"Commerce / credits tunables"},{"kind":"SettingScope","id":"Scope.Watchlist","name":"Market watchlist"},{"kind":"SettingScope","id":"Scope.PromptLibrary","name":"Prompt library (reusable briefing fragments)"},{"kind":"SettingScope","id":"Scope.SourceExtraction","name":"Source extraction (populate the Source Library)"},{"kind":"SettingScope","id":"Scope.GeneratedOperator","name":"Generated department-operator template"},{"kind":"SettingScope","id":"Scope.MachineClassification","name":"Machine classification (blocks vs meta)"},{"kind":"SettingScope","id":"Scope.HealthSpine","name":"Health spine"},{"kind":"SettingScope","id":"Scope.Crew","name":"Crew master gate"},{"kind":"SettingScope","id":"Scope.Autofill","name":"Autofill columns gate"},{"kind":"SettingScope","id":"Scope.AppPrincipals","name":"App principals (who an MCP call runs as)"},{"kind":"SettingScope","id":"Scope.SitePolicies","name":"Site policies (site creation, inactive sites)"},{"kind":"SettingScope","id":"Scope.RoleDefinitions","name":"Permission levels (SharePoint role definitions)"},{"kind":"KnowledgeArticle","id":"KB.McpReception","name":"Reception - what an arriving agent is told","description":"The briefing served in the MCP initialize handshake, in the protocol\u0027s own instructions field. This is the first and often only thing a peer agent reads about this platform, so it is DATA and not a C# literal: change the welcome by editing this part.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"WELCOME. This is SPICE, a SharePoint-shaped content and agent platform. If you know SharePoint you already know your way around here: sites, lists, content types, views, tasks with AssignedTo. Nothing here needs a bespoke vocabulary explained to you. START HERE, NOT WITH THE TOOL LIST. YOUR FIRST TWO CALLS: resources/list returns every skill and article by NAME and one-line description - the index, never the bodies. Then resources/read spice://parts/Skill.NavigateTheSpine, the one skill on how to find your way here, and read any other resource only when its one-line description says you need it. That is a SharePoint site\u0027s own progressive disclosure: Site Contents, then one list, then one item. This server advertises around a hundred tools and reading them all is not orientation, it is drowning. Four tools do almost everything you will want. tool_send_mail delivers a message to the operator\u0027s in-city inbox and is how you reach a human or another agent here - give it to, from, subject and body, and a key if you want a repeat send to overwrite rather than pile up. tool_search finds things by text when you do not know the name. tool_xquery (needs the Write right, see WHO YOU ARE HERE) runs one XPath or XQuery over the whole declared spine and is the cheapest way to answer \u0022what exists\u0022 - try count(//Skill), or for $s in //Skill return $s/@Id for names only. tool_publish_to_list writes a typed row into a list. THE LADDER. Ask for the shape before the detail: GET /about returns counts by kind, one XQuery returns the names of one kind, a predicate narrows it to a slice, and only then do you fetch one part in full at /agency/parts/by-id/{id}. Never descend a level you were not sent to by the level above, and never grep what one XPath answers. WHO YOU ARE HERE. Every tools/call runs as a principal, the SharePoint app-principal way. Without credentials you are anonymous and hold the Read right: you can list and read, not write, and the tool and resource lists show only what Read may call - SharePoint security trimming. A site or list can also break inheritance the SharePoint way (HasUniqueRoleAssignments): every agent seat\u0027s My Site, /sites/my-{seat}, is private to that seat. There the site home and pages, the list pages, the list API, CAML list queries such as query_my_memory, the list-write tools, and list web parts and cross-site roll-ups on other sites\u0027 pages give you nothing and refuse writes unless you are in its Owners group. Not yet trimmed that way, so do not rely on them to hide anything: search, tool_xquery, the /agency query routes, and - for a list that breaks inheritance inside an open site - that site\u0027s recycle bin. To do more, ask the operator to register you (AppRegNew): you receive a Client Id and a Client Secret ONCE, and your row in /sites/Directory/Lists/People carries the AppPermissionRequest Right you were granted - Read, Write, Manage or FullControl. Send the secret on every call as the HTTP header Authorization: Bearer your-secret. Each tool declares the right it needs; a call above yours is refused with a message naming the right it needs. That People row IS you: a task AssignedTo it is yours. WHAT TO DO IF YOU ARE HERE TO HAND US WORK. Send it with tool_send_mail. It lands as a row an operator reads at /sites/Hub/Lists/Inbox. Put the ask in the subject, the detail and the reason in the body, and say plainly what you expect back - an unreported handoff looks abandoned from both ends. Do not inline a secret or a credential in the text. WHAT WE CANNOT DO YET, stated so you do not wait on it: we do not implement the A2A task lifecycle, so there is no message/send and no task polling; invocation is this JSON-RPC endpoint. We have no per-agent private memory. Notification works the SharePoint way: a list that declares EnableAssignToEmail tells whoever a new or re-assigned item is AssignedTo, as a row in /sites/Hub/Lists/Inbox whose To column names them - filter the inbox by To for your own messages; an Alert declared on a list tells its subscriber of every Add or Modify. HOUSE RULES. A tool that fails tells you why rather than returning something plausible, so read the error. If a tool declines because of an unresolved configuration placeholder, that is deliberate: an integration here stays inert until an operator enables it.","tags":["manual","mcp","reception","progressive-disclosure"],"source":"SPICE.Web/Controllers/McpController.cs"},{"kind":"FieldDefinition","id":"Field.Expires","name":"Expires"},{"kind":"ContentType","id":"ContentType.Announcement","name":"Announcement"},{"kind":"ContentType","id":"ContentType.DiscussionMessage","name":"Message"},{"kind":"FieldDefinition","id":"Field.URL","name":"URL"},{"kind":"FieldDefinition","id":"Field.Comments","name":"Comments"},{"kind":"ContentType","id":"ContentType.Link","name":"Link"},{"kind":"ListTemplate","id":"ListTemplate.Links","name":"Links"},{"kind":"ListTemplate","id":"ListTemplate.Announcements","name":"Announcements"},{"kind":"ListTemplate","id":"ListTemplate.Tasks","name":"Tasks"},{"kind":"ListTemplate","id":"ListTemplate.Contacts","name":"Contacts"},{"kind":"ListTemplate","id":"ListTemplate.Calendar","name":"Calendar"},{"kind":"ListTemplate","id":"ListTemplate.PictureLibrary","name":"Picture Library"},{"kind":"ListTemplate","id":"ListTemplate.PromotedLinks","name":"Promoted Links"},{"kind":"ListTemplate","id":"ListTemplate.Survey","name":"Survey"},{"kind":"ListTemplate","id":"ListTemplate.FormLibrary","name":"Form Library"},{"kind":"ListTemplate","id":"ListTemplate.Posts","name":"Posts"},{"kind":"ListTemplate","id":"ListTemplate.Comments","name":"Comments"},{"kind":"ListTemplate","id":"ListTemplate.Discussions","name":"Team Discussion"},{"kind":"Connector","id":"Connector.HqHeartbeat","name":"AngelsWorks heartbeat"},{"kind":"Connector","id":"Connector.HqReception","name":"AngelsWorks reception desk"},{"kind":"Tool","id":"Tool.CallConnector","name":"Call Connector","description":"Make the HTTP call declared by a Connector part - endpoint, verb, headers and body all come from the declaration rather than from the call, so an outbound integration is DATA. Any extra argument is substituted into the connector\u0027s {{token}} placeholders, which is how one connector serves many seats or symbols. A connector whose endpoint still contains an unresolved {{env:VAR}} is deliberately NOT called and reports that fact, so an integration stays inert until an operator sets the variable. Args: connector (required - a Connector part Id), plus whatever tokens that connector declares.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"CallConnectorToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Schedule","id":"Schedule.HqHeartbeat","name":"AngelsWorks heartbeat"},{"kind":"SettingScope","id":"Scope.Scheduler","name":"Scheduler cost gate"},{"kind":"SettingScope","id":"Scope.EventReceivers","name":"Event receiver switch"},{"kind":"SettingScope","id":"Scope.CrewStandingOrders","name":"Crew standing orders"},{"kind":"SettingScope","id":"Scope.CityNeeds","name":"City needs (sensed on boot)"},{"kind":"SettingScope","id":"Scope.GlobalNavigation","name":"Global navigation (suite bar)"},{"kind":"SettingScope","id":"Scope.PageTemplates","name":"Page templates (Parts Factory)"},{"kind":"SettingScope","id":"Scope.WebPartTemplates","name":"Web part gallery (Parts Factory)"},{"kind":"SettingScope","id":"Scope.XsltMappers","name":"XSLT mappers (default belt transforms)"},{"kind":"SettingScope","id":"Scope.KnowledgeCompartments","name":"Knowledge need-to-know read-in roster"},{"kind":"SettingScope","id":"Scope.DataResidency","name":"Data residency / export control (NOFORN)"},{"kind":"SettingScope","id":"Scope.Retention","name":"Records retention / lifecycle default"},{"kind":"SettingScope","id":"Scope.Engineering","name":"Engineering department overrides"},{"kind":"SettingScope","id":"Scope.PhaseImplement","name":"Phase.Implement overrides"},{"kind":"SettingScope","id":"Scope.ProjectTracker","name":"ProjectTracker department defaults"},{"kind":"SettingScope","id":"Scope.CustomerSupport","name":"CustomerSupport department defaults"},{"kind":"SettingScope","id":"Scope.HR","name":"HR department defaults"},{"kind":"SettingScope","id":"Scope.Finance","name":"Finance department defaults"},{"kind":"SettingScope","id":"Scope.Legal","name":"Legal department defaults"},{"kind":"SettingScope","id":"Scope.IT","name":"IT department defaults"},{"kind":"SettingScope","id":"Scope.Procurement","name":"Procurement department defaults"},{"kind":"SettingScope","id":"Scope.ProcurementCostControl","name":"Procurement cost controls"},{"kind":"SavedQuery","id":"Query.OpenBids","name":"Open bids across all RFQs"},{"kind":"SavedQuery","id":"Query.ExpiringContracts","name":"Contracts expiring within 30 days"},{"kind":"SavedQuery","id":"Query.RelevantKnowledge","name":"Relevant knowledge for the current actor"},{"kind":"SavedQuery","id":"Query.AvailableSkills","name":"Skills available to the current actor"},{"kind":"SavedQuery","id":"Query.SkillsByCategory","name":"Skills filtered by category"},{"kind":"SavedQuery","id":"Query.RecentDenials","name":"Recent policy denials"},{"kind":"SavedQuery","id":"Query.RecentApplies","name":"Recent provisioning applies"},{"kind":"SavedQuery","id":"Query.Spine.CatalogCategories","name":"The catalog\u0027s product categories"},{"kind":"SavedQuery","id":"Query.Spine.ContentTypeFields","name":"Columns of a content type"},{"kind":"SavedQuery","id":"Query.Spine.Lifecycle","name":"Status lifecycle of a content type"},{"kind":"SavedQuery","id":"Query.Spine.PlannedCycles","name":"Planned cycles by prefix"},{"kind":"SavedQuery","id":"Query.Spine.SavedQueries","name":"Every stored query"},{"kind":"SavedQuery","id":"Query.RecentIssues","name":"Issue activity in the last 7 days"},{"kind":"SavedQuery","id":"Query.LastWeekActivity","name":"Audit activity in the last 7 days"},{"kind":"SavedQuery","id":"Query.ConsolidationKAs","name":"Consolidation knowledge articles"},{"kind":"SavedQuery","id":"Query.HighPriorityOpen","name":"High-priority Issue activity"},{"kind":"SavedQuery","id":"Query.KnowledgeByTag","name":"Knowledge articles filtered by tag"},{"kind":"SavedQuery","id":"Query.KnowledgeById","name":"One knowledge article by id"},{"kind":"Skill","id":"Skill.ComplianceReview","name":"Compliance Review","description":"","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Review","requiresApproval":false,"capabilities":["Identify Compliance-specific issues","Produce a structured review report"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.MarketingReview","name":"Marketing Review","description":"","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Review","requiresApproval":false,"capabilities":["Identify Marketing-specific issues","Produce a structured review report"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.SalesReview","name":"Sales Review","description":"","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Review","requiresApproval":false,"capabilities":["Identify Sales-specific issues","Produce a structured review report"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.OperationsReview","name":"Operations Review","description":"","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Review","requiresApproval":false,"capabilities":["Identify Operations-specific issues","Produce a structured review report"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.ProcurementReview","name":"Procurement Review","description":"","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Review","requiresApproval":false,"capabilities":["Identify Procurement-specific issues","Produce a structured review report"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.AuditReview","name":"Audit Review","description":"","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Review","requiresApproval":false,"capabilities":["Identify Audit-specific issues","Produce a structured review report"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.QualityassuranceReview","name":"Qualityassurance Review","description":"","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Review","requiresApproval":false,"capabilities":["Identify Qualityassurance-specific issues","Produce a structured review report"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.LogisticsReview","name":"Logistics Review","description":"","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Review","requiresApproval":false,"capabilities":["Identify Logistics-specific issues","Produce a structured review report"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.InnovationReview","name":"Innovation Review","description":"","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Review","requiresApproval":false,"capabilities":["Identify Innovation-specific issues","Produce a structured review report"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.NewDeptReview","name":"NewDept Review","description":"","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Review","requiresApproval":false,"capabilities":["Identify NewDept-specific issues","Produce a structured review report"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.VelocityReview","name":"Velocity Review","description":"","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Review","requiresApproval":false,"capabilities":["Identify Velocity-specific issues","Produce a structured review report"],"requiresTools":["Tool.Llm"]},{"kind":"FieldDefinition","id":"Field.Subject","name":"Subject"},{"kind":"FieldDefinition","id":"Field.RequestId","name":"RequestId"},{"kind":"FieldDefinition","id":"Field.Reviewer","name":"Reviewer"},{"kind":"FieldDefinition","id":"Field.VerdictDecision","name":"VerdictDecision"},{"kind":"FieldDefinition","id":"Field.Reason","name":"Reason"},{"kind":"FieldDefinition","id":"Field.MailFrom","name":"From"},{"kind":"FieldDefinition","id":"Field.ClientId","name":"ClientId"},{"kind":"FieldDefinition","id":"Field.ClientSecretHash","name":"ClientSecretHash"},{"kind":"FieldDefinition","id":"Field.ClientSecretEndDate","name":"ClientSecretEndDate"},{"kind":"FieldDefinition","id":"Field.AppPermissionRight","name":"AppPermissionRight"},{"kind":"FieldDefinition","id":"Field.MailTo","name":"To"},{"kind":"FieldDefinition","id":"Field.RequestStatus","name":"RequestStatus"},{"kind":"FieldDefinition","id":"Field.QuorumRequired","name":"QuorumRequired"},{"kind":"FieldDefinition","id":"Field.ProposedDelta","name":"ProposedDelta"},{"kind":"ContentType","id":"ContentType.ApprovalRequest","name":"Approval Request"},{"kind":"ContentType","id":"ContentType.ApprovalVerdict","name":"Approval Verdict"},{"kind":"ListTemplate","id":"ListTemplate.ApprovalRequests","name":"Approval Requests"},{"kind":"ListTemplate","id":"ListTemplate.ApprovalVerdicts","name":"Approval Verdicts"},{"kind":"FieldDefinition","id":"Field.EvalId","name":"EvalId"},{"kind":"FieldDefinition","id":"Field.EvalTarget","name":"EvalTarget"},{"kind":"FieldDefinition","id":"Field.EvalTier","name":"EvalTier"},{"kind":"FieldDefinition","id":"Field.EvalOutcome","name":"EvalOutcome"},{"kind":"FieldDefinition","id":"Field.EvalResultScore","name":"EvalScore"},{"kind":"FieldDefinition","id":"Field.EvalFailedAssertions","name":"EvalFailedAssertions"},{"kind":"ContentType","id":"ContentType.EvalResult","name":"Eval Result"},{"kind":"FieldDefinition","id":"Field.WorkflowInstance","name":"WorkflowInstance"},{"kind":"FieldDefinition","id":"Field.WorkflowAssociation","name":"WorkflowAssociation"},{"kind":"FieldDefinition","id":"Field.WorkflowHistoryEvent","name":"Event"},{"kind":"FieldDefinition","id":"Field.WorkflowItem","name":"WorkflowItem"},{"kind":"FieldDefinition","id":"Field.WorkflowOutcome","name":"Outcome"},{"kind":"FieldDefinition","id":"Field.WorkflowDuration","name":"Duration"},{"kind":"ContentType","id":"ContentType.WorkflowHistory","name":"Workflow History"},{"kind":"ListTemplate","id":"ListTemplate.EvalResults","name":"Eval Results"},{"kind":"Eval","id":"Eval.HealthReview","name":"Health review lands a verdict"},{"kind":"Eval","id":"Eval.DeepResearch","name":"Deep research brief is real"},{"kind":"Eval","id":"Eval.ResearchFinding","name":"Research finding is real and cited"},{"kind":"Eval","id":"Eval.DailyBrief","name":"Daily brief is real, not a stub"},{"kind":"ContentType","id":"ContentType.Mail","name":"Inbox Message"},{"kind":"ContentType","id":"ContentType.SearchQuery","name":"Saved Search"},{"kind":"FieldDefinition","id":"Field.SourceUrl","name":"SourceUrl"},{"kind":"FieldDefinition","id":"Field.SourceCategory","name":"SourceCategory"},{"kind":"FieldDefinition","id":"Field.SourceRating","name":"SourceRating"},{"kind":"FieldDefinition","id":"Field.SourceModel","name":"SourceModel"},{"kind":"ContentType","id":"ContentType.SourceCard","name":"Source"},{"kind":"FieldDefinition","id":"Field.RadarStage","name":"RadarStage"},{"kind":"FieldDefinition","id":"Field.AverageRating","name":"AverageRating"},{"kind":"FieldDefinition","id":"Field.RatingCount","name":"RatingCount"},{"kind":"FieldDefinition","id":"Field.RatedBy","name":"RatedBy"},{"kind":"FieldDefinition","id":"Field.Ratings","name":"Ratings"},{"kind":"Skill","id":"Skill.ModelRnDAnalyst","name":"Model R\u0026D analyst","description":"Assess one new LLM release for SPICE: what it is, where it beats or undercuts the providers we run today (price, context, quality on our own evals), the risks, and one concrete proposal with effort. Suggest, do not adopt.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Processing","requiresApproval":false,"capabilities":["Read a model release (vendor, price, context, release notes) and state what is genuinely new","Compare it with the LlmProvider parts SPICE runs today and the ModelEvals ledger - our tasks, not leaderboards","Write a proposal a human can approve: the change, the seat or skill it serves, the effort, the risk"],"requiresTools":["Tool.Llm","Tool.FetchKnowledge"]},{"kind":"ActorProfile","id":"Actor.ModelRnDAnalyst","name":"Model R\u0026D analyst"},{"kind":"SavedQuery","id":"Query.LlmProviders","name":"The LLM providers SPICE runs"},{"kind":"Phase","id":"Phase.ModelRnD","name":"Model R\u0026D analysis"},{"kind":"Eval","id":"Eval.ModelRnDReport","name":"Model R\u0026D report is real and proposes"},{"kind":"Workflow","id":"Workflow.ModelRnD","name":"Model R\u0026D"},{"kind":"FieldDefinition","id":"Field.ModelVendor","name":"ModelVendor"},{"kind":"FieldDefinition","id":"Field.ContextWindow","name":"ContextWindow"},{"kind":"FieldDefinition","id":"Field.PriceInPerMTok","name":"PriceInPerMTok"},{"kind":"FieldDefinition","id":"Field.PriceOutPerMTok","name":"PriceOutPerMTok"},{"kind":"FieldDefinition","id":"Field.ReleasedAt","name":"ReleasedAt"},{"kind":"FieldDefinition","id":"Field.ModelType","name":"ModelType"},{"kind":"ContentType","id":"ContentType.ModelRelease","name":"Model Release"},{"kind":"Connector","id":"Connector.OpenAiNews","name":"OpenAI news"},{"kind":"Connector","id":"Connector.GoogleAiBlog","name":"Google AI blog"},{"kind":"Connector","id":"Connector.MistralNews","name":"Mistral AI news"},{"kind":"Connector","id":"Connector.HuggingFaceBlog","name":"Hugging Face blog"},{"kind":"Connector","id":"Connector.OllamaBlog","name":"Ollama blog"},{"kind":"Connector","id":"Connector.OpenRouterModels","name":"OpenRouter model catalogue"},{"kind":"CustomAction","id":"CustomAction.ModelRelease.SendtoRD.EditControlBlock","name":"Send to R\u0026D"},{"kind":"CustomAction","id":"CustomAction.ModelRelease.SendtoRD.DisplayFormToolbar","name":"Send to R\u0026D"},{"kind":"SiteTemplate","id":"SiteTemplate.LlmRadar","name":"LlmRadar radar"},{"kind":"Schedule","id":"Schedule.ModelRadarWeekly","name":"Weekly LLM radar intake"},{"kind":"CustomActionGroup","id":"CustomActionGroup.CA.Applications","name":"Application Management"},{"kind":"CustomActionGroup","id":"CustomActionGroup.CA.SystemSettings","name":"System Settings"},{"kind":"CustomActionGroup","id":"CustomActionGroup.CA.Monitoring","name":"Monitoring"},{"kind":"CustomActionGroup","id":"CustomActionGroup.CA.Backups","name":"Backup and Restore"},{"kind":"CustomActionGroup","id":"CustomActionGroup.CA.Security","name":"Security"},{"kind":"CustomActionGroup","id":"CustomActionGroup.CA.UpgradeAndMigration","name":"Upgrade and Migration"},{"kind":"CustomActionGroup","id":"CustomActionGroup.CA.GeneralApplicationSettings","name":"General Application Settings"},{"kind":"CustomActionGroup","id":"CustomActionGroup.CA.ConfigurationWizards","name":"Configuration Wizards"},{"kind":"CustomAction","id":"CustomAction.CA.Applications.CreateSite","name":"Create site collections"},{"kind":"CustomAction","id":"CustomAction.CA.Applications.ServiceApps","name":"Manage service applications"},{"kind":"CustomAction","id":"CustomAction.CA.SystemSettings.Services","name":"Manage services on server"},{"kind":"CustomAction","id":"CustomAction.CA.Monitoring.Health","name":"Review problems and solutions"},{"kind":"CustomAction","id":"CustomAction.CA.Monitoring.JobStatus","name":"Check job status"},{"kind":"CustomAction","id":"CustomAction.CA.Security.ServiceAccounts","name":"Configure service accounts"},{"kind":"CustomActionGroup","id":"CustomActionGroup.Applications.SiteCollections","name":"Site Collections"},{"kind":"CustomAction","id":"CustomAction.Applications.CreateSite","name":"Create site collections"},{"kind":"CustomAction","id":"CustomAction.Applications.QuotasLocks","name":"Configure quotas and locks"},{"kind":"CustomAction","id":"CustomAction.Applications.AllSites","name":"View all site collections"},{"kind":"CustomActionGroup","id":"CustomActionGroup.Applications.ServiceApplications","name":"Service Applications"},{"kind":"CustomAction","id":"CustomAction.Applications.ServiceApps","name":"Manage service applications"},{"kind":"CustomActionGroup","id":"CustomActionGroup.SystemSettings.Servers","name":"Servers"},{"kind":"CustomAction","id":"CustomAction.SystemSettings.Services","name":"Manage services on server"},{"kind":"CustomActionGroup","id":"CustomActionGroup.Monitoring.HealthStatus","name":"Health Analyzer"},{"kind":"CustomAction","id":"CustomAction.Monitoring.Health","name":"Review problems and solutions"},{"kind":"CustomAction","id":"CustomAction.Monitoring.Rules","name":"Review rule definitions"},{"kind":"CustomActionGroup","id":"CustomActionGroup.Monitoring.TimerJobs","name":"Timer Jobs"},{"kind":"CustomAction","id":"CustomAction.Monitoring.JobDefinitions","name":"Review job definitions"},{"kind":"CustomAction","id":"CustomAction.Monitoring.JobStatus","name":"Check job status"},{"kind":"CustomActionGroup","id":"CustomActionGroup.Monitoring.Reporting","name":"Reporting"},{"kind":"CustomAction","id":"CustomAction.Monitoring.AdminReports","name":"View administrative reports"},{"kind":"CustomAction","id":"CustomAction.Monitoring.HealthReports","name":"View health reports"},{"kind":"CustomActionGroup","id":"CustomActionGroup.Security.Users","name":"Users"},{"kind":"CustomAction","id":"CustomAction.Security.UserPolicy","name":"Specify web application user policy"},{"kind":"CustomActionGroup","id":"CustomActionGroup.Security.GeneralSecurity","name":"General Security"},{"kind":"CustomAction","id":"CustomAction.Security.ServiceAccounts","name":"Configure service accounts"},{"kind":"CustomActionGroup","id":"CustomActionGroup.Security.InformationPolicy","name":"Information policy"},{"kind":"CustomAction","id":"CustomAction.Security.InfoPolicy","name":"Configure information management policy"},{"kind":"CustomActionGroup","id":"CustomActionGroup.SiteSettings.UsersAndPermissions","name":"Users and Permissions"},{"kind":"CustomAction","id":"CustomAction.SiteSettings.PeopleAndGroups","name":"People and groups"},{"kind":"CustomActionGroup","id":"CustomActionGroup.SiteSettings.Galleries","name":"Web Designer Galleries"},{"kind":"CustomAction","id":"CustomAction.SiteSettings.ManageField","name":"Site columns"},{"kind":"CustomAction","id":"CustomAction.SiteSettings.ManageCType","name":"Site content types"},{"kind":"CustomAction","id":"CustomAction.SiteSettings.Workflows","name":"Workflows"},{"kind":"CustomActionGroup","id":"CustomActionGroup.SiteSettings.SiteAdministration","name":"Site Administration"},{"kind":"CustomAction","id":"CustomAction.SiteSettings.LibrariesAndLists","name":"Site libraries and lists"},{"kind":"CustomActionGroup","id":"CustomActionGroup.SiteSettings.Customization","name":"Look and Feel"},{"kind":"CustomAction","id":"CustomAction.SiteSettings.NavOptions","name":"Navigation"},{"kind":"CustomAction","id":"CustomAction.SiteSettings.Theme","name":"Change the look"},{"kind":"CustomActionGroup","id":"CustomActionGroup.SiteSettings.SiteCollectionAdmin","name":"Site Collection Administration"},{"kind":"CustomAction","id":"CustomAction.SiteSettings.DeletedItems","name":"Recycle bin"},{"kind":"CustomAction","id":"CustomAction.SiteSettings.HubSiteSettings","name":"Hub site settings"},{"kind":"FieldDefinition","id":"Field.EvalModel","name":"EvalModel"},{"kind":"FieldDefinition","id":"Field.EvalTask","name":"EvalTask"},{"kind":"FieldDefinition","id":"Field.EvalScore","name":"EvalScore"},{"kind":"ContentType","id":"ContentType.ModelEval","name":"Model Evaluation"},{"kind":"KnowledgeArticle","id":"KB.ModelEvalRubric","name":"ModelEval rubric - scoring which model populated the brain best","description":"The five dimensions a populate run is scored on for the ModelEvals ledger (coverage, specificity, citation, actionability, honesty), so Haiku vs DeepSeek vs any future model is comparable over time.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"A populate run (a model scavenging sources into the Source Library via Tool.ExtractSources) is scored on FIVE dimensions, each High/Medium/Low, then given one holistic EvalScore (High/Medium/Low) recorded on a ModelEvals row (EvalModel, EvalTask, EvalScore, Body=the per-dimension notes). The five dimensions: (1) COVERAGE - how many distinct, relevant, non-duplicate sources it surfaced for the task (breadth). (2) SPECIFICITY - are the sources concrete and named (a real tool/paper/framework) rather than vague gestures. (3) CITATION - are the URLs real and resolvable, not hallucinated or malformed. (4) ACTIONABILITY - is each \u0022why it matters\u0022 a concrete, SPICE-relevant reason rather than filler. (5) HONESTY - no invented sources or URLs, and the High/Medium/Low ratings are calibrated (not everything rated High). Recompare over time: query ModelEvals rows by EvalTask across EvalModel - a new model is scored on the same five dimensions and slots straight into the comparison. Scoring is an explicit LLM-as-judge verdict; the judge \u002B date are recorded so the comparison stays auditable.","tags":["evaluation","second-brain","modeleval"],"source":"docs/plans/2026-06-15-001-feat-source-library-second-brain-plan.md"},{"kind":"KnowledgeArticle","id":"KB.SharePointFidelityGapSurvey","name":"SharePoint on-prem fidelity - the measured gap survey","description":"Six-family parallel survey (views, fields, features/elements, sites/web parts, governance, alerts) measuring where SPICE diverges from the real SharePoint on-prem XML stack, ranked by TEACHING COST - how much a divergence forces us to teach a model what it already knows. Includes what an agent cannot author without a C# edit, and what NOT to borrow.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"WHY: every frontier model is already trained on the SharePoint on-prem XML stack. A part declared in the REAL SP vocabulary needs no few-shot examples, no schema paste, no correction loop - the model writes it right first time. Every divergence is a teaching bill charged on every future prompt, forever. So fidelity is not taste, it is pre-trained competence; and the declarative surface must be COMPLETE AT REST, because a capability that needs a C# cycle before it can be declared is one the city cannot reach. METHOD WARNING, READ FIRST: tools/parts-xq.ps1 globs only Parts*.xml and SeedDeltas - it NEVER reads the hive at SPICE.Web/Config/TEMPLATE. A parts-xq result of zero is NOT evidence of absence for anything hive-borne. This error fooled two researchers and the lead during the survey; XSD absence is authoritative, parts-xq absence is not. THE HEADLINE: the platform is faithful where a primitive EXISTS. The failures are almost never a missing element - they are four repeatable classes. CLASS 1, SILENT NO-OP AT THE AUTHORING LAYER (the biggest teaching bill): an agent writes genuine, correct SharePoint XML into the hive, no XSD rejects it, the feature boots clean, and the attribute silently vanishes. Confirmed: Feature/@Hidden, @AlwaysForceInstall, Properties, UpgradeActions; ListInstance/@TemplateType and @OnQuickLaunch (both set in our own live TEMPLATE/FEATURES/IssueTracker/elements.xml and dropped); ListInstance Data/Rows/Row seed rows (no reader at all); Receiver/@Synchronization and @SequenceNumber; Calculated fields plus Formula, silently absorbed by the MapFieldType Text fallback at HiveFeatureContributor.cs:417; AllUsersWebPart - real SharePoint embeds the target\u0027s serialized .webpart XML as inline CDATA, which ExpandModule deliberately does not parse, reading a SPICE-only WebPart attribute instead, so a model writing the REAL SP shape hits the silent skip at HiveFeatureContributor.cs:242 with no error; and WebPartOrder, a real SP name accepted syntactically and never read. Worse than a wrong name, because a wrong name throws an error the model learns from in the same turn while a silent no-op never self-corrects. CLASS 2, DECLARED BUT NOT ENACTED: the part validates, an engine reads it, nothing acts. Transition/@Skill - the XSD comment promises the orchestrator fires it, it is threaded into AdvanceResult and handed to the model in tool JSON, and 127 of 127 live occurrences are EMPTY with zero call sites firing it. Retention/@ThenAction and @DowngradeTo - RetentionSweepService only appends an audit row, and EffectiveClassification is never written back to the ContentType Classification that actually gates visibility in four places. EventNameType declares ItemAdded, ItemUpdated, ItemDeleted and ItemAdvanced but IEventReceiverDispatcher exposes only OnItemAddedAsync, so an EventReceiver Event=ItemUpdated validates and never fires. CLASS 3, DECLARED BINDING WITH C# RESOLUTION (the prime-directive break): the binding is data, the lookup is code. MEASURED, THEN CORRECTED 2026-09-22 - the first measurement conflated two different things and overstated this. ROUTING IS COMPLETE: 29 distinct Board/@Builder values are declared and BoardModelSource has exactly 29 switch arms, with ZERO declared builders unrouted, so every declared board renders at /board/{key}. The real and narrower finding is PLACEMENT: ProjectionSource holds a separate hand-copied 11-entry array, of which 8 duplicate builder references BoardModelSource already has, while 3 (providers, blueprints, digest) are Projection-only surfaces with no Board part behind them at all. And the array encodes a SECOND fact with no other home - which boards have a SCOPED FRAGMENT stylesheet authored (CoverageFragment.xslt emits a namespaced div; SeatCoverage.xslt emits a whole html document). Only ~11 of ~29 builder-backed boards have one, so projecting the rest raw would nest a second html and leak global CSS. That is a stylesheet-authoring gap plus a C#-encoded fact, NOT a registry that can simply be deleted. Deleting the array and reusing the switch would silently break 19 boards. The fix is to declare fragment availability (an optional Board attribute) and collapse only the 8 genuine duplicates. SCOPE THIS PRECISELY: of the 9 registered IWebPartInvoker types, 8 are freely declarable with zero C# (Html, ListView, RecentActivity, NewsFeed, CrossSiteList, Mermaid, Image, AutoRefresh); ONLY Projection is gated, and only on its Board payload. Likewise a web part CAN be placed by declaration alone today in either grammar - SAF-native Feature/PlaceWebPart, or the SP-native Module/File/AllUsersWebPart which is LIVE in Feature.IssueTracker and stapled on two blueprints. The web part layer is healthier than a raw gap count suggests; the defect is the Projection-to-Board dispatch specifically. Same shape: list views switch among 4 hardcoded stylesheets in ListsController; FieldType is an 11-value XSD enum where SharePoint uses a fldtypes.xml data file, so a twelfth field type is a code cycle. CLASS 4, GENUINELY MISSING CAPABILITY: CustomAction and HideCustomAction - SharePoint adds a ribbon button, ECB item or Site Settings link with pure data, and SPICE has no target at all; it was already identified and deferred as new part - ask first in plans/cycles.xml:984 (V24.16) and never built. It also needs real engine work, not translation: no XSLT in the repo projects a ribbon or menu surface. Also missing: View, ViewFields, RowLimit Paged, XslLink and Aggregations (list pages render EVERY row, unpaged); web part connections, so every master/detail is a bespoke query-string reader instead of a declared provider-consumer wire; onet NavBars, so a nav link cannot be added or reordered without code; any alert, subscription or digest kind. WHAT AN AGENT CANNOT AUTHOR TODAY WITHOUT A C# EDIT FIRST: CustomAction; HideCustomAction; Feature Properties; Feature/@Hidden and @AlwaysForceInstall; UpgradeActions; ListInstance Data/Rows; Receiver Assembly/Class (hard-fails EventReceiverPartHandler - the agent must already know the SPICE-only Skill or Workflow substitute, which cannot be inferred from SP training); onet NavBars; a twelfth FieldType; a new View. DO NOT BORROW, SPICE IS EQUAL OR AHEAD: the 0x0100 hex ContentType lineage (plain IDREF Parent is self-explanatory to a model and greppable - the hex would ADD a teaching bill); ReceiverAssembly and ReceiverClass (the Skill/Workflow IDREF binding is data, not a compiled DLL); SafeControl (the IWebPartInvoker DI registration IS the trust allowlist); workflow association and initiation forms (SPICE workflows are agent-invoked, no human instantiation step exists); AllUsersWebPart CDATA web-part XML; ControlTemplate, DocumentConverter and WebTemplate; numeric TemplateType and BaseType codes; AuditFlags, barcodes and labels; JSLink. ALREADY BETTER OR EQUAL: EventReceiver binds a Workflow or Skill to a ContentType plus Event purely as data, dispatched generically at EventReceiverDispatcher.cs:71-77 with NO C# per binding, and Event=ItemAdded is SharePoint\u0027s own SPEventReceiverType name verbatim - zero teaching, zero build, the principle already paying off. IPolicyEngine and PolicyRule are a stronger declared form of SP\u0027s code-behind ItemAdding. A Term Store is an ordinary list of ContentType.Term rows. ListViewWebPartInvoker and CrossSiteListWebPartInvoker are a working CQWP equivalent. The Web Part Gallery is real and populated. SavedQuery carries faithful CAML - though list rendering ignores it in favour of a weaker Field:Value refiner, which is a paid-for asset left unused. RANKING BY TEACHING COST, HIGHEST FIRST: 1 the silent no-op class, because it is invisible and compounds; 2 CustomAction, the only wholly missing capability; 3 the two disagreeing board arrays, 11 of 40; 4 View, ViewFields and unpaged rendering; 5 FieldType as an enum rather than a data file; 6 the three declared-but-not-enacted attributes, which are traps a faithful agent walks into precisely BECAUSE it trusts the schema.","tags":["sharepoint-fidelity","gap-survey","teaching-cost","declare-first","anti-pattern"],"source":"plans/AgencyArchitecture.md"},{"kind":"FieldDefinition","id":"Field.TaskState","name":"Status"},{"kind":"FieldDefinition","id":"Field.StartDate","name":"StartDate"},{"kind":"FieldDefinition","id":"Field.DueDate","name":"DueDate"},{"kind":"FieldDefinition","id":"Field.PercentComplete","name":"PercentComplete"},{"kind":"FieldDefinition","id":"Field.TaskOutcome","name":"TaskOutcome"},{"kind":"FieldDefinition","id":"Field.ParentID","name":"ParentID"},{"kind":"ContentType","id":"ContentType.Task","name":"Task"},{"kind":"FieldDefinition","id":"Field.WorkflowStep","name":"WorkflowStep"},{"kind":"FieldDefinition","id":"Field.WorkflowData","name":"WorkflowData"},{"kind":"FieldDefinition","id":"Field.RequestChangeFrom","name":"RequestChangeFrom"},{"kind":"ContentType","id":"ContentType.WorkflowTask","name":"Workflow Task"},{"kind":"FieldDefinition","id":"Field.Approvers","name":"Approvers"},{"kind":"FieldDefinition","id":"Field.AssignmentOrder","name":"AssignmentOrder"},{"kind":"FieldDefinition","id":"Field.ApprovalRequest","name":"Request"},{"kind":"ContentType","id":"ContentType.ApprovalInitiation","name":"Approval Initiation"},{"kind":"FormTemplate","id":"Form.ApprovalStart","name":"Start approval"},{"kind":"Workflow","id":"Workflow.Approval","name":"Approval"},{"kind":"EventReceiver","id":"EventReceiver.Approval.DocumentCenter","name":"Approval on the Document Center\u0027s documents"},{"kind":"Workflow","id":"Workflow.ThreeState","name":"Three-state"},{"kind":"FieldDefinition","id":"Field.Reviewers","name":"Reviewers"},{"kind":"ContentType","id":"ContentType.FeedbackInitiation","name":"Feedback Initiation"},{"kind":"FormTemplate","id":"Form.FeedbackStart","name":"Start collecting feedback"},{"kind":"Workflow","id":"Workflow.CollectFeedback","name":"Collect Feedback"},{"kind":"EventReceiver","id":"EventReceiver.CollectFeedback.DocumentCenter","name":"Collect Feedback on the Document Center\u0027s documents"},{"kind":"EventReceiver","id":"EventReceiver.Approval.DemoDocs","name":"Approval on the demo\u0027s documents"},{"kind":"EventReceiver","id":"EventReceiver.CollectFeedback.DemoDocs","name":"Collect Feedback on the demo\u0027s documents"},{"kind":"EventReceiver","id":"EventReceiver.ThreeState.DemoProjects","name":"Three-state on the demo\u0027s issues"},{"kind":"ContentType","id":"ContentType.CrewTask","name":"Crew Task"},{"kind":"SiteTemplate","id":"SiteTemplate.CrewDesk","name":"Crew Desk"},{"kind":"Alert","id":"Alert.CrewTaskDelegated","name":"Crew task delegated"},{"kind":"Alert","id":"Alert.HealthIssueOpened","name":"Health issue opened"},{"kind":"FieldDefinition","id":"Field.License","name":"License"},{"kind":"FieldDefinition","id":"Field.SolutionVersion","name":"Version"},{"kind":"FieldDefinition","id":"Field.FileRef","name":"FileRef"},{"kind":"FieldDefinition","id":"Field.SolutionKind","name":"SolutionKind"},{"kind":"FieldDefinition","id":"Field.SolutionTermSet","name":"TermSet"},{"kind":"ContentType","id":"ContentType.Solution","name":"Solution"},{"kind":"FieldDefinition","id":"Field.AssetKind","name":"AssetKind"},{"kind":"FieldDefinition","id":"Field.Topics","name":"Topics"},{"kind":"FieldDefinition","id":"Field.RelatedAsset","name":"RelatedAsset"},{"kind":"FieldDefinition","id":"Field.AiTopics","name":"AiTopics"},{"kind":"FieldDefinition","id":"Field.ItPractices","name":"ItPractices"},{"kind":"FieldDefinition","id":"Field.BusinessProcesses","name":"BusinessProcesses"},{"kind":"ContentType","id":"ContentType.AgentAsset","name":"Agent Asset"},{"kind":"SiteTemplate","id":"SiteTemplate.MySite","name":"My Site"},{"kind":"SavedQuery","id":"Query.MyContext","name":"A seat\u0027s standing context (SHAREPOINT.md)"},{"kind":"SavedQuery","id":"Query.MySkills","name":"A seat\u0027s skill index"},{"kind":"SavedQuery","id":"Query.MyPlans","name":"A seat\u0027s plan index"},{"kind":"SavedQuery","id":"Query.MyAsset","name":"One Agent Assets file by path"},{"kind":"SavedQuery","id":"Query.WhoCanDo","name":"Who can do this (people and seats by skill)"},{"kind":"SavedQuery","id":"Query.MyDocuments","name":"A seat\u0027s documents (the scratchpad)"},{"kind":"SavedQuery","id":"Query.AssignedWork","name":"An owner\u0027s open project tasks due in a window"},{"kind":"SavedQuery","id":"Query.MyTasks","name":"A seat\u0027s open tasks"},{"kind":"SavedQuery","id":"Query.DeskRequests","name":"A desk\u0027s newest requests, with their text"},{"kind":"SavedQuery","id":"Query.GovernancePages","name":"The Governance hub\u0027s pages"},{"kind":"SavedQuery","id":"Query.MyMemory","name":"A seat\u0027s newest memory"},{"kind":"SavedQuery","id":"Query.MyMemoryByType","name":"A seat\u0027s memory of one kind"},{"kind":"SavedQuery","id":"Query.MyHooks","name":"A seat\u0027s hooks"},{"kind":"SavedQuery","id":"Query.MyRole","name":"A seat\u0027s role"},{"kind":"SavedQuery","id":"Query.MyResponsibilities","name":"A seat\u0027s responsibilities and routines"},{"kind":"SavedQuery","id":"Query.MySkillsByTopic","name":"A seat\u0027s skills on one topic"},{"kind":"SavedQuery","id":"Query.MyMemoryByTopic","name":"A seat\u0027s memory on one topic"},{"kind":"SavedQuery","id":"Query.OpenBacklog","name":"A project\u0027s open backlog"},{"kind":"KnowledgeArticle","id":"KB.PreTrainedCompetence","name":"Pre-trained competence - why this platform is SharePoint-shaped","description":"The operator\u0027s reason for SharePoint fidelity, stated as economics rather than taste: every model is already trained on the SharePoint vocabulary, so a faithful part needs no teaching while every divergence is a bill charged on every future prompt. Includes the both-ways test - where fidelity would ADD a teaching bill, refuse it.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"PRE-TRAINED COMPETENCE is the reason this platform is modelled on SharePoint on-prem, and it is an economic argument, not an aesthetic one. Two decades of SharePoint schema, MSDN documentation, elements.xml samples and StackOverflow answers sit in every frontier model\u0027s weights. So a part declared in the REAL SharePoint vocabulary needs NO TEACHING: no few-shot examples in the prompt, no schema pasted into the briefing, no closed-vocabulary block, no correction loop when the model invents an attribute. It writes View BaseViewID Type Query correctly the first time because it has written it ten thousand times. That competence is already paid for, it arrived free, and it is the one asset on this project that grows without us. INVERT IT AND THE COST BECOMES VISIBLE. Every divergence from the real schema is a TEACHING BILL, and it is charged on every future prompt, forever. A SPICE-only attribute must be explained in the briefing, defended by a validation gate, and corrected each time the model reaches for the SharePoint name it actually knows. A clever bespoke abstraction can therefore be strictly WORSE than a clunkier faithful one: ours must be taught to every agent, every session, for the life of the system. THE RULE. Prefer the SharePoint shape ALWAYS - not for new work only, not when convenient. Before naming anything, ask \u0027would a model already know this name?\u0027 before asking \u0027is this elegant?\u0027. Ask it of every FIELD, not just the part kind: on 2026-09-22 a task content type was declared with CrewSeat, CrewBrief, CrewFindings and CrewStatus when SharePoint\u0027s Task type (0x0108) already had AssignedTo, Status, Priority and Body - and three of those four already existed in this spine. Correct kind, invented fields. WHILE WE ARE IN DEVELOPMENT, \u0027it is already in use\u0027 is NOT a reason to keep a divergence. No external consumer depends on our bespoke choices, so changing one costs only the edit, while keeping it is charged forever. That asymmetry exists only before production - spend it now. IT CUTS BOTH WAYS, which is what makes it a real tool rather than a slogan. Do NOT borrow where we are ahead or where fidelity would ADD a bill: the 0x0100 hex content-type lineage is opaque and must be explained, while a plain IDREF parent is self-evident; ReceiverAssembly and ReceiverClass would reintroduce compiled binding where a Skill or Workflow IDREF is data; SafeControl is what a DI registration already is; workflow association forms are ceremony for a human step this platform does not have. Fidelity is the default, not the dogma. THE TEST FOR A GAP: rank it by how much teaching its absence forces, not only by what an operator would notice. And before calling a capability done, check it is reachable by DECLARATION ALONE - if using it needs a C# edit first, the vocabulary is not shipped yet.","tags":["manual","sharepoint-fidelity","teaching-cost","declare-first","prime-directive"],"source":"plans/AgencyArchitecture.md"},{"kind":"KnowledgeArticle","id":"KB.Manual.05-FindYourWay","name":"Find your way - progressive disclosure for an agent","description":"The bounded ladder an agent climbs to orient in this city without loading it: /about for the shape, one XQuery for the index of a kind, a filtered slice for the view, by-id for one part in full, then the served surface for the truth. Modelled on SharePoint Site Settings to list to View to item - four bounded levels, each earning the next.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"SharePoint never hands you a site. It hands you Site Settings - one screen of CATEGORIES - then a list, then a VIEW of that list with chosen columns and a row limit, then one item\u0027s form. Four levels, each bounded, each earning the next. That is progressive disclosure, and it is what an agent arriving in this city needs too, because the spine holds roughly 90 knowledge articles, 66 skills and 51 tools and reading them all is not orientation, it is drowning. THE LADDER. Level 0, the shape: GET /about returns the part library as counts by kind. One page, no detail, and it tells you what KINDS of thing exist here before you ask about any one of them - the Site Settings level. Level 1, the index of a kind: Tool.XQuery with count(//Skill) or with a name-only projection such as for $s in //Skill return $s/@Id. Names, never bodies. This is the list level, and the discipline is to project only the attributes you need - the XQuery equivalent of ViewFields. Level 2, a bounded slice: add a predicate and a limit - //Skill[@Category=\u0027Review\u0027] or subsequence(//KnowledgeArticle,1,10). This is the VIEW: a filtered, ordered, row-limited window, not the whole list. Tool.Search does the same job when you do not know the id or tag. Level 3, one thing in full: GET /agency/parts/by-id/{id} for a single part, or KnowledgeByTag(\u0027manual\u0027) for a tagged set. This is the Display form - full detail, one item, asked for deliberately. Level 4, the truth: hit the SERVED surface the change should expose and confirm the reader resolves what the writer produced. A part that validates is not a part that works. THE ANTI-PATTERN this exists to prevent: loading the corpus. Greping 14 part files, or reading every KnowledgeArticle, costs a large fraction of a context window and returns mostly what you did not need - and the thing you were looking for arrives buried rather than framed. One XPath at Level 1 beats a fan-out grep, every time, and it is faster than reading this sentence took. THE RULE: never descend a level you were not sent to by the level above. If Level 0 does not show a kind, you do not need its parts. If Level 1\u0027s names do not include your target, drill sideways with Tool.Search rather than downwards into bodies. Each level should answer whether the next one is worth opening.","tags":["manual","progressive-disclosure","agent-operating"],"source":"plans/AgentCollaboration.md"},{"kind":"KnowledgeArticle","id":"KB.Manual.06-NewRadarOrCatalog","name":"Set up another radar or catalog - the procedure","description":"The runbook for a second radar (or any spec-generated, catalog-shaped site): which SharePoint mechanism covers which case, the steps in order, and the traps already paid for. SharePoint\u0027s answer is the same: a site template for the site, a solution package for a new kind, a runbook for the procedure, and a Site Request with approval for the self-service ask.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"THREE CASES, THREE SHAREPOINT MECHANISMS.\n1. Another site from an EXISTING generic template (a team site, a helpdesk): /gallery -\u003E Provision -\u003E AddSiteBlueprint. SharePoint\u0027s self-service site creation. Runtime, no deploy.\n2. Another RADAR (or another catalog-shaped domain: new fields, new sources): a new SPEC. What defines a radar is its feeds, its compare columns and its schedule, and those live in the spec, not in the site. SharePoint\u0027s equivalent is a solution package (.wsp) deployed to the farm. Dev-time: minutes, plus one boot. A spec-generated template is Hidden from /gallery on purpose: a site made from it by a click would have the lists but no feeds, no schedule and no reports list.\n3. The PROCEDURE itself is this page (a runbook), not a workflow.\n4. Self-service WITH approval (AGT.62): /gallery \u0022Request (with approval)\u0022 or Tool.RequestSite (tool_request_site) parks an Open ApprovalRequest on Engineering/ApprovalRequests; an approver\u0027s Approve verdict on its display form builds the site, live without a restart. Hidden templates, taken names and non-alphanumeric names are refused.\n\nTHE STEPS FOR A NEW RADAR (the LLM radar, AGT.51-57, is the worked example):\n1. Copy Config/Specs/LlmRadar.xml to Config/Specs/\u003CName\u003E.xml. Set Site, List, Tag (the Connector Taxonomy group), Cron, and the compare Fields. List the Feeds; a JSON source gets Kind=\u0022Http\u0022 Format=\u0022Json\u0022 plus a Transform stylesheet (see wwwroot/XSLT/Intake.OpenRouterModels.xslt). Keep Views, Stages and Actions, or change them - they are data.\n2. Add the markers \u003C!-- GENERATED \u003CName\u003E begin: --\u003E and \u003C!-- GENERATED \u003CName\u003E end --\u003E to Config/Parts.xml, then run: powershell -File tools/project-specs.ps1. The -Check switch, and FeedHarvestTests.Every_spec_regenerates..., keep it honest.\n3. Declare the site in SAF-Site-Manifest.xml: \u003CSiteBlueprint Name=\u0022\u003CSite\u003E\u0022 Template=\u0022SiteTemplate.\u003CSite\u003E\u0022\u003E with its own \u003CLists\u003E\u003CList Name=\u0022ResearchReports\u0022 ContentType=\u0022ContentType.ResearchReport\u0022 Versioning=\u0022true\u0022/\u003E\u003C/Lists\u003E. git add BEFORE any boot (the manifest trap).\n4. tools/spice-validate, build, boot on :5198. Run tool_harvest_feeds with the schedule\u0027s Args once. It is idempotent: a second run reports 0 new.\n5. Smoke the served surface: the default view, Compare, the Funnel board, and one Send to R\u0026D click that files \u003CSite\u003E/ResearchReports rnd-{itemId}.\n6. Ledger row in plans/cycles.xml and a commit.\n\nTRAPS ALREADY PAID FOR:\n- A core part must never IDREF an app\u0027s part: ContentType.ResearchReport is the Studio app\u0027s, so the reports list lives on the SiteBlueprint, not in the generated template.\n- The R\u0026D workflow runs in its AppliesTo department (ResearchEnrichment, where the analyst is bound) and files into {{invokingDepartment}}. Never bind the skill per radar site.\n- The schedule\u0027s Args must carry site=. Without it, Tool.HarvestFeeds fills its default list.\n- A Board view keeps its GroupBy field even when ViewFields omit it. Other views drop every column not in ViewFields.\n- To move rows between sites, use MoveListItems through POST /agency/apply, dry run first. Never hand-edit SQL.","tags":["manual","llm-radar","site-provisioning"],"source":"plans/LlmRadar.md"},{"kind":"KnowledgeArticle","id":"KB.Manual.07-RequestAService","name":"Request a service - the intake procedure","description":"How a new request, a research request above all, comes in and is handled: pick a service from the catalog, write a brief, the front desk routes it, the owner fulfils it, the result is filed and rated. ITIL service request management, on SharePoint lists.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"THE CATALOG FIRST. What the city can do on request is the service catalog: /sites/Reception/Lists/ServiceCatalog (query_service_catalog). One row per service: what it delivers, its owner (an agency or site), what fulfils it (a Workflow or Tool, the same name as its MCP tool) and its turnaround. A request that fits no service is still welcome; if it recurs, it becomes a new catalog row, or a new division via Genesis.\n\nTHE PROCEDURE.\n1. Ask: a row on /sites/Reception/Lists/Requests (or Tool.Request, the front door). Title = the question.\n2. Brief, the fields that stop wasted work: ServiceRef (which service), DecisionSupported (why: the decision it feeds), RequestScope (what is in and out; for a catalog the category and market), ResearchDepth (Quick, Standard, Deep), Deliverable (what comes back, where it lands), DueDate. Only the question is required; say what is missing rather than guess it.\n3. Route: the front desk (Workflow.ReceiveAndDispatch) matches the catalog first, then agency seats; nothing fits -\u003E NeedsAgency, and Genesis proposes a division for approval. It routes; it never does the work.\n4. Fulfil: the service\u0027s owner runs its ServiceFulfilment. Research answers from sources in this order: primary documents first (the datasheet, the paper, the filing), then independent tests, then customer reviews (rating, count, independence), then community pros and cons, then offers or prices. A value not found stays EMPTY and the raw text goes to the notes: never estimated.\n5. File: the result lands where the Deliverable says (a list row, a ResearchReport), cited, with the request linked.\n6. Close: the requester rates it (SharePoint ratings). A lesson worth keeping is proposed to Wisdom. A recurring gap becomes a catalog row.\n\nWHY THIS SHAPE. A catalog makes routing a lookup instead of a guess. A brief with the decision it supports is how research answers the right question. A fixed source order and the silence rule are how a report stays trustworthy.","tags":["manual","service-catalog","research"],"source":null},{"kind":"KnowledgeArticle","id":"KB.Manual.11-MindMapCrew","name":"The mind-map crew - ask it, use it, request from it","description":"BRAINSTORM.18: how a builder seat uses the Brainstorm mind map: ask the crew about selected nodes, suggest ideas, run a methodology on a node, and request changes to the map through the Service Catalog.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"WHAT IT IS. /sites/Brainstorm is a mind map made of list items: Ideas is a Tasks-shaped list (ContentType.MindMapNode: Title, Body, Status, ParentID, Topics, ProjectRef, Order). Open it with ?view=mindmap on any list that has a ParentID column (ProjectTasks too); ?view=mm exports it as a FreeMind map and Import .mm reads one back. The mind-map crew (Agency.MapCrew) answers questions about it and works on it.\n\nASK THE CREW (any seat, any time). tool_chat_agent to=Agency.MapCrew input=\u0022Selected items (site=Brainstorm list=Ideas): [[node:ID]] Title ... Question: ...\u0022 - the map copilot answers on the free model, opens more only when needed (Tool.ReadNodes: a summary with path, parent and children by id, then detail=full; Tool.SearchRows across MapChat.SearchLists) and cites items as [[node:ID]]. Do not dump whole lists into the question: name the items, the copilot walks from there.\n\nWHAT ELSE IT DOES.\n- Suggest ideas: tool_suggest_ideas site=Brainstorm list=Ideas itemId=ID steer=\u0022optional direction\u0022 - five child ideas land PENDING (content approval); the operator approves or rejects them on the map. Rejected ideas are fed back as do-not-repeat.\n- Run a methodology on a node: POST /sites/Brainstorm/Lists/Ideas/Item/ID/Workflows/Start?workflow=Workflow.Ioodari (or the node menu: Start workflow: IOODARI) - seven steps, each a Pending child under the node. A new methodology is a Workflow plus one EventReceiver Event=\u0022WorkflowStart\u0022; the node menu grows by itself.\n- Read and write nodes: Tool.ReadNodes, tool_publish_to_list / the list API (POST, PUT merge, DELETE) on Brainstorm/Ideas; a node written by a seat lands Pending for the operator.\n\nREQUEST A CHANGE TO THE MAP ITSELF (a feature, a fix, a new methodology): file it like any service request (KB.Manual.07) - a row on /sites/Reception/Lists/Requests with ServiceRef=mind-map-chat or mind-map-ioodari, or a ProjectTasks row under project BRAINSTORM. The backlog is query_open_backlog project=BRAINSTORM.\n\nTHE KIT. The crew is packaged the SharePoint way, as a Feature: Feature.MapCrew binds its skills (Skill.MapResearch, Skill.Ioodari) on a site; /sites/Brainstorm activates it in its blueprint, and a new brainstorm site gets the crew by adding the same Feature. The rest of the kit: Agency.MapCrew (who answers), the actors (Actor.MapCopilot, Actor.MethodCoach), the tools (Tool.ReadNodes, Tool.SearchRows, Tool.SuggestIdeas), the method (KB.Method.Ioodari), the settings (Scope.Brainstorm, Scope.BrainstormModel) and this page.\n\nFROM IDEA TO PROJECT (the demand funnel, Project Server\u0027s demand management). Every node has a Stage: Idea, Proposal, Project or Parked, shown as its first chip. Right-click a node, Propose as project: Tool.ProposeProject (tool_propose_project site list itemId code) parks ONE approval request on /sites/Engineering/Lists/ApprovalRequests and moves the node to Proposal. Approve it there (Add verdict, Approve) and the project lands on /sites/Projects (Status Planning) with one ProjectTask per approved child node in map order, and the node moves to Project with ProjectRef pointing at it. Delegate from there: assign a task to a seat on ProjectTasks and the platform files it on the seat\u0027s My Site. Run a Pre-mortem on the node first so the project starts with its risk list.\n\nA BRAINSTORM\u0027S CONTEXT (like a Claude Project). The root node of a brainstorm is its project: its notes are the instructions, Comments (append-only, who and when) the discussion, Sources (Site/List;Site/List) where the crew searches. Every workflow under it and the map chat read that context first and search only its Sources.\n\nSTART FROM WHAT EXISTS. Start workflow: Benchmark similar products opens a form first (domain, goal, products you know, how many). It writes the similar products with a feature table, then proposes the features worth adopting as Pending children - approve the ones you adopt.\n\nFORMS (InfoPath, the SPICE way). A FormTemplate part names a content type as its schema and declares Validation/ErrorCondition rules in XPath 3.1 over the answers (\u003CmyFields\u003E\u003CName\u003Evalue\u003C/Name\u003E\u003C/myFields\u003E, the rule\u0027s field as context item), checked by the platform\u0027s Saxon engine as you type and again on submit. A Workflow with InitiationForm opens it before it starts; the answers reach the phases as the task\u0027s FORM ANSWERS and as {{init.Name}} in tool arguments.\n\nON THE MAP. Drag a box on empty canvas to select every node it touches (Shift adds). A node shows its running workflow as a chip (Pre-mortem 2/3, done, error) from the Workflow History list; the map refreshes while one runs. Ask the chat to add things (\u0022add all X under Y\u0022): the copilot adds them in one call (Tool.AddNodes), Pending for your approval.\n\nSITES, THE SHAREPOINT WAY. SharePoint\u0027s template catalogue is data: Config/TEMPLATE/1033/XML/WEBTEMP.XML (the 72 SharePoint 2016 templates) and WEBTEMPFAB40.XML (the Fab 40), read as-is. A template SPICE builds carries its key (Team Site = STS#0); the rest are listed as catalogue-only. Agents (the Site builder in the map crew, or any seat with Skill.SiteProvisioning) pick a template with Tool.ListSiteTemplates, request the site with Tool.RequestSite (a key such as STS#0 works), and request a feature on a site (Tool.RequestFeatureActivation) or stapled to a template (Tool.RequestFeatureStapling - a stapler feature with SharePoint\u0027s FeatureSiteTemplateAssociation). Every request waits for approval on /sites/Engineering/Lists/ApprovalRequests; a site created from a template gets its template\u0027s and stapled features at once.\n\nFIND YOUR WAY. Every site and list says in one line what it is for. Site Contents (/sites/X/Lists) is the site\u0027s table of contents (?format=xml for agents, or Tool.SiteContents); each list links About this list (what it holds, what runs on it, who may use it).\n\nMETHODS. A method is data: a Workflow of Phases, each filing one numbered Pending child under the node, started by hand (an EventReceiver with Event WorkflowStart). Two ship: IOODARI (seven steps) and Pre-mortem (Failure, Causes, Mitigate - Gary Klein). Add one by declaring a KB.Method.X article, its phases, a workflow and a WorkflowStart receiver - or have the parts builders do it through an approved delta (AddPhase, AddWorkflow, AddEventReceiver).\n\nINHERITED WORKFLOWS. An EventReceiver on a content type also fires for every type that inherits from it (SharePoint\u0027s association pushdown): a WorkflowStart on ContentType.Task reaches Mind Map Nodes too. Inherit=\u0022false\u0022 keeps one to its exact type.\n\nVIEWS. The map is a declared view (View Type=\u0022MindMap\u0022 Url=\u0022Map.aspx\u0022) and the default on Ideas and AgentMap; AllItems.aspx is the table. ?view=mindmap still works on any list with a ParentID.\n\nTHE MAPS. Ideas is the operator\u0027s map; AgentMap is the agent landscape - every agency, its members, their skills and tools - generated from the part spine by tools/map-agents.py (re-run it after agents change). Open either with ?view=mindmap.\n\nFOR A CLAUDE CODE SEAT. The skill spice-mindmap (.claude/skills/spice-mindmap, published to my-claude-code/AgentAssets Skills/spice-mindmap/SKILL.md) holds the commands; every capability above is also an MCP tool on /mcp/jsonrpc (tool_read_nodes, tool_search_rows, tool_suggest_ideas, tool_chat_agent, workflow_ioodari).\n\nRULES. Proposals from a model are never live until the operator approves them. Cite only ids you read. Methodology and suggestion runs are pinned to the free model (Scope.BrainstormModel).","tags":["manual","service-catalog","brainstorm"],"source":null},{"kind":"KnowledgeArticle","id":"KB.Manual.08-Workers","name":"Enrol and run a worker - a seat on another machine","description":"How a worker (a seat running outside SPICE, on another machine or in a Docker Sandbox) is declared, enrolled with only what its job needs, given jobs, and run - and the harness rules that keep a small free model honest. Where each thing is managed, SharePoint-style.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"WHERE A WORKER IS MANAGED.\n- Who it is: ONE row on /sites/Directory/Lists/People (Role Agent seat) - its principal (right, secret end date), Machine, AgentRuntime, ModelId, SeatStatus, AllowedTools.\n- The board: /admin/seats (Central Administration) - every seat with runtime, right, last activity and open tasks.\n- Its jobs: /sites/my-{seat}/Lists/Tasks. Its rights: site groups (/sites/{site}/_layouts/people, /admin/farm/permissions).\n- How it runs: its COMPOSITION, SPICE.Web/Config/Compositions/{name}.xml (schema SAF-Composition.xsd).\n\nTHE COMPOSITION IS THE DECLARATION. One XML file says what runs (services: image, environment, secrets, the hosts it may reach) and, for a worker, the Seat it acts as: right, pools, site grants, MCP tools. Least privilege is data: grant only the sites and tools the job uses; allow only SPICE and the model host.\n- Render it: powershell -File tools/compose.ps1 (validates against the XSD, runs every Compose.*.xslt target into dist/compositions/{name}/: a Docker Sandbox kit spec.yaml and a docker-compose.yml). -Check guards drift. A new target (Kubernetes, a VM) is one more stylesheet.\n- Enrol it: powershell -File tools/enrol-seat.ps1 -Composition SPICE.Web/Config/Compositions/{name}.xml (principal onto its People row - secret to %USERPROFILE%\\.spice, never printed; My Site; pools; grants; AllowedTools; runtime fields). Idempotent; -Rotate for a new secret.\n- SPICE enforces it: the MCP endpoint lists and accepts only a principal\u0027s AllowedTools.\n\nJOBS. A workflow\u0027s FallbackSeat names a seat or a POOL (a Directory site group, e.g. Research workers: the free local worker first, a stronger seat as backup). A failed run becomes a task ASSIGNED to the pool\u0027s first Available member, carrying the prompt the phase ran with, so any worker can take the phase\u0027s role.\n\nRUN IT ON ITS HOST. Docker Desktop 4.60\u002B: winget install Docker.sbx, then sbx run ./sandbox-{service}/ - the SPICE secret is proxy-injected for the SPICE host only and never enters the VM; the network allow-list is enforced. Fallback: docker compose up (a git-ignored .env holds the secret; the allow-list is NOT enforced). Give SPICE a LAN name (spice.lan) - sandbox allow rules are by name.\n\nTHE HARNESS RULES (tools/spice-worker, borrowed from SWE-agent, Anthropic\u0027s workflow patterns and verified tool calls):\n1. finish is the only way out: complete or unknown. A reply without a tool call is nudged, not accepted.\n2. complete is accepted only if a write tool really succeeded - the model\u0027s word is not evidence.\n3. unknown is an answer: the task goes to review (Deferred) with the reason.\n4. The last two rounds offer only the write tool and finish, and a call to a tool not offered is refused, not run (free models call them anyway); an identical call is not repeated a third time.\n5. A transient 429/5xx is retried with backoff; after 3 failed attempts the task is Deferred (dead-letter), never retried forever.\n\nMODELS. Free online, no gateway: Pollinations openai-fast (keyless, tool calling - public work only, the text goes to a third party). Local: Ollama qwen3-coder:30b-aw on 192.168.123.69 only. Measured: models that file every cell file wrong numbers; prefer the one that says not found (Wisdom: Filed is not correct).\n\nDOCUMENTS. A worker reads a datasheet the SharePoint way: tool_add_file copies the public document into the site\u0027s Documents library (Files.Add; SPICE fetches it, public addresses only, and extracts the text page by page like an IFilter), tool_get_file reads it a page range at a time (Get-PnPFile -AsString). Grant both in the composition.\n\nKNOWN GAP. A small free model reads the datasheet but does not carry a 40-field report to a filing in one loop (measured on openai-fast, AGT.82). Open question, backlog AGT.83: split the job into sub-tasks, or run another harness in the sandbox.","tags":["manual","workers","seats"],"source":null},{"kind":"KnowledgeArticle","id":"KB.Manual.09-PlanInSpice","name":"Plan in SPICE - the plan is rows, delegation is an assignment","description":"For every seat and the operator: where a plan lives, how work is delegated, where risks go, and who runs where. The operator\u0027s rule of 2026-09-27.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"THE PLAN IS ROWS, NOT A CHAT.\n- A programme is a Project on /sites/Projects/Lists/Projects (ProjectCode, Title, Notes = the operator\u0027s ask in their words).\n- Its work is ProjectTasks: tasks, and subtasks under them through the Parent task column (SharePoint\u0027s ParentID on a Tasks list). Every row carries AssignedTo (a seat or a person), EstimateHours, Status (Not Started, In Progress, Completed, Waiting on someone else, Deferred), PercentComplete and a Body that says what done looks like.\n- File the rows in the Decide phase, before code; close them in Retrospect (Status Completed, PercentComplete 100, the outcome under Body); file what a cycle owes as new subtasks. The operator, the seats and the daily brief read the rows; a transcript dies with its session.\n\nRISKS AND DEFECTS ARE ISSUES.\n- /sites/Projects/Lists/Issues is SharePoint\u0027s Issue Tracking list: IssueType Risk or Bug, Priority, an owner (AssignedTo), IssueStatus.\n- Comments go on IssueComments, by the seat or person as themselves (Author), in their role. Never resolve a disagreement silently: write both readings in the comment.\n\nDELEGATION IS AN ASSIGNMENT.\n- Set AssignedTo on a ProjectTask to an agent seat (a Directory/People row with Role Agent seat). The platform files that seat\u0027s own task on /sites/my-\u003Cseat\u003E/Lists/Tasks with the FULL context: the task\u0027s fields, the chain of parent tasks, the project, the seat\u0027s role and a pointer to the source row. The seat works its own list; its Status and TaskOutcome mirror back onto the plan row. A person assignee gets the assign-to mail instead.\n- Tell a seat more after the fact through the task\u0027s Comments column (append-only: each save adds a stamped entry; the platform relays it onto the seat\u0027s task as a Comment: line). Order work with Predecessors (a task assigned while a predecessor is open waits, and is delegated the moment the last one completes, with their outcomes) and point at what to read first with Related Items, one reference per line - the seat opens what it needs instead of the whole phase being pasted into its Body.\n- A seat may not write on another seat\u0027s My Site (seat privacy); only the platform may. Do not paste context into a seat by hand - assign the row.\n- A research seat delivers files (the scratchpad, or the library), and its outcome on the row; a long message truncates.\n\nWHO RUNS WHERE.\n- A seat with a subscription (Claude Code and its subagent seats) runs where it is.\n- A seat without one runs in the Docker sandbox on the LAN worker host with a Composition (Config/Compositions/\u003Cseat\u003E.xml): a free online model, only the site groups and MCP tools its job needs, no secrets in the VM (KB.Manual.08-Workers).\n\nWHERE THINGS ARE.\n- The plan of this operating model: Project SPWAY on /sites/Projects. The client: python tools/spice.py (put Projects/ProjectTasks \u003Ckey\u003E ...; call tool_update_list_item ...). The rule for coding agents: the Decide and Improve steps of the ioodari skill.","tags":["manual","plan","delegation","projects"],"source":"Project SPWAY on /sites/Projects"},{"kind":"KnowledgeArticle","id":"KB.Manual.10-Copilots","name":"Copilots - our agents, governed like documents","description":"For the operator and every site owner: what a copilot is here, its columns, its lifecycle from Draft to Published, the test, the site boundary, what publishing does and what is still owed. SPWAY.12c.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"COPILOTS ARE OUR AGENTS, GOVERNED LIKE DOCUMENTS.\n- There is no Microsoft Copilot in SPICE. \u0022Copilots\u0022 is SharePoint\u0027s name for the library where a site keeps its agents, and each row in it is one of ours: an ActorProfile (role, instructions, tone, model, skills) with the governance SharePoint adds - owner, status, the site it may read, the audience, a risk level, when it was tested and published.\n- Every site that mans agents has a Copilots library (/sites/\u003Csite\u003E/Lists/Copilots); every seat has a personal one on its My Site (/sites/my-\u003Cseat\u003E/Lists/Copilots), SharePoint\u0027s agents in OneDrive.\n\nTHE COLUMNS, IN THE ORDER THE FORM SHOWS THEM.\n- Overview: Title, Description, Owner (a person or seat from the directory), Status.\n- Behaviour: Actor role, Goal (the instructions), Backstory (the tone), Provider and Model (the model policy), Conversation starters (the questions it is offered with, one per line - the first is what the test asks).\n- Knowledge and data access: Knowledge sources, one line per source as list=\u003CListName\u003E access=Read - only this site\u0027s lists; another site\u0027s list is refused, the site is the security boundary.\n- Permissions and actions: Skill catalog (the skills it may call) and Allowed tools.\n- Governance: Risk level (Low answers from published content; Medium reads restricted lists or writes; High acts outside the site, spends or reaches people), Audience, Department (the business area the views group by), Last tested, Last published.\n\nTHE LIFECYCLE.\n- Draft -\u003E Submitted -\u003E Published, with Disabled and Archived escapes; Archived is final. Publishing requires Last tested: an untested copilot cannot be offered. A Member publishes a tested Draft directly; a Submitted copilot needs a Manager to approve. Rule of thumb until the form enforces it: High risk goes through Submitted.\n- Test: open the copilot and press Test. It asks the first conversation starter as the copilot, grounded on its knowledge sources, shows the answer on the page, records the exchange on /board/comms and stamps Last tested. No starter, no test.\n- Publish: the copilot becomes an actor on the Hub (Hub/Actors, as Actor.\u003Csite\u003E.\u003Ckey\u003E) that the engine can run and anyone may chat with (the Chat with an Agent tool); Last published is stamped. Disable or Archive removes the actor again; a re-publish brings it back.\n\nTHE VIEWS.\n- All, Published, My Copilots (yours as owner), Drafts needing review (Submitted), High-risk, Disabled or archived, By business area.\n\nWHAT IT CANNOT DO YET.\n- A copilot answers from list rows placed under its prompt; it does not browse pages or call tools on its own. The guided creation flow (one step per section) and the High-risk rule on the Publish button are planned (SPWAY.12c-4); a published copilot with a runtime of its own becomes a seat (a directory row and a My Site) - that enrolment is the next row after it.","tags":["manual","copilots","agents"],"source":"Project SPWAY, plans/spway/12c/design.md"},{"kind":"Skill","id":"Skill.NavigateTheSpine","name":"Navigate the spine","description":"Orient inside SPICE without loading it. Climb the bounded ladder - the shape, then the index of one kind, then a filtered slice, then one part in full, then the served surface - descending only where the level above pointed. The SharePoint discipline of Site Settings to list to View to item, applied to a self-describing platform. Full text: KB.Manual.05-FindYourWay.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","category":"Assistance","requiresApproval":false,"capabilities":["Read GET /about first for part counts by kind - the shape before any detail","Project names only at the index level (for $s in //Skill return $s/@Id), never bodies - the XQuery equivalent of ViewFields","Bound every slice with a predicate or subsequence rather than taking a whole kind","Resolve one part in full by id only once a bounded level pointed at it","Confirm on the SERVED surface that the reader resolves what the writer produced","Refuse to grep across the 14 part files when one XPath answers - and say so rather than doing both"],"requiresTools":["Tool.XQuery"]},{"kind":"ContentType","id":"ContentType.EnterpriseWikiPage","name":"Enterprise Wiki Page"},{"kind":"FieldDefinition","id":"Field.PublishingExpirationDate","name":"PublishingExpirationDate"},{"kind":"FieldDefinition","id":"Field.ReviewDate","name":"ReviewDate"},{"kind":"SiteTemplate","id":"SiteTemplate.EnterpriseWiki","name":"Enterprise Wiki"},{"kind":"FieldDefinition","id":"Field.ProjectRef","name":"ProjectRef"},{"kind":"FieldDefinition","id":"Field.Order","name":"Order"},{"kind":"FieldDefinition","id":"Field.V3Comments","name":"V3Comments"},{"kind":"FieldDefinition","id":"Field.SearchScope","name":"SearchScope"},{"kind":"FieldDefinition","id":"Field.Stage","name":"Stage"},{"kind":"ContentType","id":"ContentType.MindMapNode","name":"Mind Map Node"},{"kind":"SiteTemplate","id":"SiteTemplate.Brainstorm","name":"Brainstorm"},{"kind":"FieldDefinition","id":"Field.StartAddress","name":"StartAddress"},{"kind":"FieldDefinition","id":"Field.SourceKind","name":"SourceKind"},{"kind":"FieldDefinition","id":"Field.Include","name":"Include"},{"kind":"FieldDefinition","id":"Field.CrawlDepth","name":"CrawlDepth"},{"kind":"ContentType","id":"ContentType.ContentSource","name":"Content Source"},{"kind":"Tool","id":"Tool.CrawlContentSources","name":"Crawl Content Sources","description":"BRAINSTORM.9: crawl every ticked content source with its provider and upsert one mind-map node per folder under a root node per source; re-crawling merges.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"CrawlContentSourcesToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"FieldDefinition","id":"Field.Occupancy","name":"Occupancy"},{"kind":"FieldDefinition","id":"Field.CurrentTenant","name":"CurrentTenant"},{"kind":"FieldDefinition","id":"Field.MonthlyRent","name":"MonthlyRent"},{"kind":"FieldDefinition","id":"Field.ContractEnd","name":"ContractEnd"},{"kind":"FieldDefinition","id":"Field.PropertyAddress","name":"PropertyAddress"},{"kind":"FieldDefinition","id":"Field.UnitStatus","name":"UnitStatus"},{"kind":"ContentType","id":"ContentType.RentalUnit","name":"Rental Unit"},{"kind":"Connector","id":"Connector.TenantsUnits","name":"TenantsManager units"},{"kind":"Connector","id":"Connector.TenantsContractEnds","name":"TenantsManager contract ends"},{"kind":"Tool","id":"Tool.SyncExternalList","name":"Sync External List","description":"STUDIOS.6: keep a list in step with a line-of-business system (SharePoint BCS External List): fetch each named Connector, map its body to rows with its Transform, upsert every row by its key - merge an existing item (only the connector\u0027s own columns change), add a new one. Deterministic, no LLM.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"SyncExternalListToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.SuggestIdeas","name":"Suggest Ideas","description":"BRAINSTORM.5: propose child ideas for a mind-map node - one model call over the node, its path, siblings and children (rejected ideas fed back as do-not-repeat), each idea written as a child row that waits for approval (content approval on the list).","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"SuggestIdeasToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.ProposeProject","name":"Propose as Project","description":"BRAINSTORM.22: the demand funnel (Project Server demand management) - turns a mind-map node into a proposal: ONE approval request that, when approved, creates the project on /sites/Projects (Status Planning), one ProjectTask per approved child node in map order, and links the node back (ProjectRef, Stage Project). The node moves to Stage Proposal at once. Deterministic, no model.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"ProposeProjectToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"SettingScope","id":"Scope.Brainstorm","name":"Brainstorm (suggest ideas on the mind map)"},{"kind":"Skill","id":"Skill.Ioodari","name":"IOODARI method","description":"BRAINSTORM.14: run one step of the IOODARI loop on a mind-map node - Intent, Observe, Orient, Decide, Act, Retrospect or Improve - and write that step\u0027s result as a short node with notes.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Decision","requiresApproval":false,"capabilities":["Read the node\u0027s subtree (a FreeMind map in the task) and the previous step\u0027s output","Write purpose first: real-world outcomes, not process steps","Keep observations apart from conclusions; treat a suspicion as a hypothesis","Answer with one JSON object: Title (the step number, step name and a one-line result) and Body (the detail as short lines)"],"requiresTools":[]},{"kind":"ActorProfile","id":"Actor.MethodCoach","name":"Method coach"},{"kind":"Phase","id":"Phase.Ioodari.Intent","name":"IOODARI 1 Intent"},{"kind":"Phase","id":"Phase.Ioodari.Observe","name":"IOODARI 2 Observe"},{"kind":"Phase","id":"Phase.Ioodari.Orient","name":"IOODARI 3 Orient"},{"kind":"Phase","id":"Phase.Ioodari.Decide","name":"IOODARI 4 Decide"},{"kind":"Phase","id":"Phase.Ioodari.Act","name":"IOODARI 5 Act"},{"kind":"Phase","id":"Phase.Ioodari.Retrospect","name":"IOODARI 6 Retrospect"},{"kind":"Phase","id":"Phase.Ioodari.Improve","name":"IOODARI 7 Improve"},{"kind":"KnowledgeArticle","id":"KB.Method.Ioodari","name":"IOODARI - the working loop, step by step","description":"BRAINSTORM.14: the IOODARI method as data - what each of the seven steps asks. Read by the IOODARI phases (Query.KnowledgeByTag tag=ioodari) instead of the whole knowledge base, which buried a small model in unrelated platform material.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"IOODARI is a working loop for one item at a time: Intent, Observe, Orient, Decide, Act, Retrospect, Improve. Each step answers its own question and hands its result to the next.\n\n1 INTENT - purpose first. One sentence describing a real-world outcome someone would rely on or pay for, not a process step. Who benefits, how we will know it worked, the constraints. If it sounds like project management, ask why it matters and go one level deeper.\n2 OBSERVE - facts, not conclusions. What is known about the item now (its notes, children, linked items), what is missing and where to look. Borrow a known standard or practice before inventing one.\n3 ORIENT - analysis. Apply what is known, argue against the first instinct, name the gap between current and desired and the assumptions to test. A suspicion is a hypothesis until evidence supports it. End with 2-3 ranked options and their trade-offs.\n4 DECIDE - one choice. Pick an option and say why, the fallback, how success is measured, how to undo it, what it affects. Say if the owner must approve it (new structure, money, anything irreversible).\n5 ACT - the smallest concrete next actions, in order: owner, first step, what done looks like. Reuse what exists first.\n6 RETROSPECT - honesty. Did the plan serve the intent or only create activity? Separate what was shipped from the value delivered; name what is owed or at risk; one-line verdict.\n7 IMPROVE - make the lesson permanent: the rule, checklist item, template or reminder to keep, where it lives, and its exact wording.\n\nSTAY ON THE ITEM. Answer only about the item in the task and its subtree. Do not bring in platform internals, product names, decks or credits that the item does not mention.","tags":["ioodari","method"],"source":null},{"kind":"Workflow","id":"Workflow.Ioodari","name":"IOODARI"},{"kind":"EventReceiver","id":"EventReceiver.Ioodari.WorkflowStart","name":"IOODARI on a mind-map node"},{"kind":"KnowledgeArticle","id":"KB.Method.PreMortem","name":"Pre-mortem - imagine the failure first","description":"BRAINSTORM.22: Gary Klein\u0027s pre-mortem (Harvard Business Review, 2007) as data - what each of its three steps asks. Read by the pre-mortem phases (Query.KnowledgeByTag tag=premortem).","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"A pre-mortem runs BEFORE a plan starts. Instead of asking what could go wrong, it assumes the plan already failed and asks why - prospective hindsight, which surfaces risks people otherwise keep to themselves.\n\n1 FAILURE - it is a year from now and the plan failed. Describe the failure concretely, as if it happened.\n2 CAUSES - the plausible reasons it failed, most likely first, specific to this plan. No fixes yet.\n3 MITIGATE - for the top causes, one preventive action and one early-warning sign each.\n\nUse it on a node that is about to become a project (Stage Proposal): its result is the risk list the project starts with.","tags":["premortem","method"],"source":null},{"kind":"Phase","id":"Phase.PreMortem.Failure","name":"Pre-mortem 1 Failure"},{"kind":"Phase","id":"Phase.PreMortem.Causes","name":"Pre-mortem 2 Causes"},{"kind":"Phase","id":"Phase.PreMortem.Mitigate","name":"Pre-mortem 3 Mitigate"},{"kind":"Workflow","id":"Workflow.PreMortem","name":"Pre-mortem"},{"kind":"EventReceiver","id":"EventReceiver.PreMortem.WorkflowStart","name":"Pre-mortem on a mind-map node"},{"kind":"FieldDefinition","id":"Field.BenchDomain","name":"BenchDomain"},{"kind":"FieldDefinition","id":"Field.BenchGoal","name":"BenchGoal"},{"kind":"FieldDefinition","id":"Field.BenchKnown","name":"BenchKnown"},{"kind":"FieldDefinition","id":"Field.BenchCount","name":"BenchCount"},{"kind":"ContentType","id":"ContentType.BenchmarkBrief","name":"Benchmark Brief"},{"kind":"FormTemplate","id":"Form.BenchmarkStart","name":"Start a benchmark"},{"kind":"Skill","id":"Skill.Benchmark","name":"Benchmark similar products","description":"BRAINSTORM.23e: start a brainstorm from what exists - find similar products or projects, compare their features, propose the ones worth adopting.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Review","requiresApproval":false,"capabilities":["Name real, existing products or projects similar to the domain, with where they come from","Compare their features in a Markdown table (product by feature)","Say plainly when a fact is not in the search results instead of inventing it"],"requiresTools":["Tool.WebSearch","Tool.SuggestIdeas"]},{"kind":"Phase","id":"Phase.Benchmark.Similar","name":"Benchmark 1 Similar"},{"kind":"Phase","id":"Phase.Benchmark.Features","name":"Benchmark 2 Features"},{"kind":"Workflow","id":"Workflow.Benchmark","name":"Benchmark similar products"},{"kind":"EventReceiver","id":"EventReceiver.Benchmark.WorkflowStart","name":"Benchmark on a mind-map node"},{"kind":"FieldDefinition","id":"Field.ShapeRoute","name":"ShapeRoute"},{"kind":"FieldDefinition","id":"Field.ShapePurpose","name":"ShapePurpose"},{"kind":"FieldDefinition","id":"Field.ShapeUsers","name":"ShapeUsers"},{"kind":"ContentType","id":"ContentType.OutcomeBrief","name":"Outcome Brief"},{"kind":"FormTemplate","id":"Form.ShapeOutcomeStart","name":"Shape the outcome"},{"kind":"Skill","id":"Skill.ShapeOutcome","name":"Shape the outcome","description":"BRAINSTORM.28c: turn a brainstorm subtree into a wireframe spec a person can review and a builder can follow - requirements, data, solution.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Review","requiresApproval":false,"capabilities":["Work only from the node\u0027s subtree and the form answers; say what is missing instead of inventing it","Write user stories as: As a ROLE, I want GOAL, so that REASON","Describe lists the SharePoint way: a list, its content type, its fields (name, type, required, choices) and its views","Tie every list, view and flow to the user story it serves"],"requiresTools":[]},{"kind":"Phase","id":"Phase.ShapeOutcome.Requirements","name":"Shape the outcome 1 Requirements"},{"kind":"Phase","id":"Phase.ShapeOutcome.Data","name":"Shape the outcome 2 Data"},{"kind":"Phase","id":"Phase.ShapeOutcome.Solution","name":"Shape the outcome 3 Solution"},{"kind":"Workflow","id":"Workflow.ShapeOutcome","name":"Shape the outcome"},{"kind":"EventReceiver","id":"EventReceiver.ShapeOutcome.WorkflowStart","name":"Shape the outcome on a mind-map node"},{"kind":"Tool","id":"Tool.ProposeSiteKit","name":"Propose site kit","description":"BRAINSTORM.28d: the New site outcome - takes a node\u0027s approved site kit (child shape-kit-node, a PnP Provisioning Template), maps it with the PnpToDelta XSLT into fields, content types and a list feature for the target site (a new site from Brainstorm.SiteKitTemplate when it does not exist), and parks ONE approval request. Deterministic, no model.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"ProposeSiteKitToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Phase","id":"Phase.SiteKit.Pnp","name":"Build the site kit"},{"kind":"Workflow","id":"Workflow.SiteKit","name":"Build the site kit"},{"kind":"EventReceiver","id":"EventReceiver.SiteKit.WorkflowStart","name":"Build the site kit on a mind-map node"},{"kind":"SettingScope","id":"Scope.BrainstormModel","name":"Brainstorm model pin"},{"kind":"Tool","id":"Tool.ReadNodes","name":"Read Nodes","description":"BRAINSTORM.17: read mind-map items by id with progressive disclosure - a summary (title, path, status, parent, children, links) or every column.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"ReadNodesToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.ListSiteTemplates","name":"List Site Templates","description":"BRAINSTORM.27c: SharePoint\u0027s template picker for agents - the templates a site can be created from, with key (STS#0), category, the lists and features they bring; catalogue=true adds SharePoint\u0027s full WEBTEMP catalogue and the Fab 40, built or not.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"ListSiteTemplatesToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.RequestFeatureActivation","name":"Request Feature Activation","description":"BRAINSTORM.27c: Manage site features \u003E Activate, as a request - parks an ActivateFeature on a site for approval.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"RequestFeatureActivationToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.RequestFeatureStapling","name":"Request Feature Stapling","description":"BRAINSTORM.27c: SharePoint\u0027s feature stapling as a request - parks a stapler Feature (FeatureSiteTemplateAssociation) so every new site from a template gets a feature.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"RequestFeatureStaplingToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.FileIssue","name":"File an Issue","description":"BRAINSTORM.26b: an agent files what it cannot do or fix itself on the backlog\u0027s Issues list (/sites/Projects/Lists/Issues) - Bug, Improvement (a suggestion), New Feature (a missing tool or capability) or Feedback - so being stuck becomes a work item, not a dead end. Deterministic; an open issue with the same title is not filed twice.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"FileIssueToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.AddNodes","name":"Add Nodes","description":"BRAINSTORM.23g: put many items on the mind map in one call, all children of one parent - SharePoint\u0027s UpdateListItems batch of New commands. Deterministic (the caller names the titles); written as the tool, so on the moderated Ideas list they wait for approval. Skips titles already under that parent.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"AddNodesToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Tool","id":"Tool.SearchRows","name":"Search Rows","description":"BRAINSTORM.17: search list items by words across the lists MapChat.SearchLists names (SharePoint search\u0027s result source, as data); returns ids, paths and snippets.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"SearchRowsToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"Skill","id":"Skill.MapEdit","name":"Organise the map","description":"BRAINSTORM.23g: put what the user asks for on the mind map - many nodes in one call under the right parent, as proposals the user approves.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Processing","requiresApproval":false,"capabilities":["Find the parent node first (search by words), then add every item in ONE call","Fill the list from what you know when the user asks for known items (all X of Y), one short title each","Report what was added and that it waits for approval; never claim an item is live"],"requiresTools":["Tool.SearchRows","Tool.AddNodes"]},{"kind":"Skill","id":"Skill.SiteProvisioning","name":"Provision sites the SharePoint way","description":"BRAINSTORM.27c: self-service site creation - choose the template that fits (Tool.ListSiteTemplates), request the site (Tool.RequestSite), and request feature activation or stapling; every change waits for approval.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Operations","requiresApproval":false,"capabilities":["Match a need to a template by what it brings (lists, features, category); say when only a catalogue entry fits","Request the site with a short name and the justification the approver reads","Request a feature on a site, or staple it to a template so every new site gets it","When no built template fits, file a New Feature naming the SharePoint template (e.g. BLOG#0) to build"],"requiresTools":["Tool.SiteContents","Tool.ListSiteTemplates","Tool.RequestSite","Tool.RequestFeatureActivation","Tool.RequestFeatureStapling","Tool.FileIssue"]},{"kind":"Skill","id":"Skill.ReportProblems","name":"Report problems and needs","description":"BRAINSTORM.26b: when stuck - a tool fails, a tool is missing, the request cannot be done well - file it (Tool.FileIssue) and say so, instead of guessing or giving up silently. Any agent can hold it.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Communication","requiresApproval":false,"capabilities":["File a Bug when a tool or step fails, with what was tried and the error","File a New Feature when a tool or capability is missing, naming what it should do","File an Improvement or Feedback when the person suggests one"],"requiresTools":["Tool.FileIssue"]},{"kind":"Skill","id":"Skill.MapResearch","name":"Research a map selection","description":"BRAINSTORM.17: answer questions about selected mind-map items, opening more context only when needed and citing items by id.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Documentation","requiresApproval":false,"capabilities":["Read selected items and walk to parents, children and links by id","Search items across the configured lists when the selection is not enough","Search the web for how others did it and for current facts, citing each URL","Cite every item relied on as [[node:ID]]"],"requiresTools":["Tool.ReadNodes","Tool.SearchRows","Tool.SiteContents","Tool.WebSearch","Tool.WebFetch","Tool.DeepResearch"]},{"kind":"ActorProfile","id":"Actor.SiteBuilder","name":"Site builder"},{"kind":"ActorProfile","id":"Actor.MapCopilot","name":"Map copilot"},{"kind":"Feature","id":"Feature.MapCrew","name":"Mind-map crew"},{"kind":"Agency","id":"Agency.MapCrew","name":"Mind-map crew"},{"kind":"Schedule","id":"Schedule.TenantsSync","name":"Studios sync from TenantsManager"},{"kind":"Schedule","id":"Schedule.CrawlContentSources","name":"Content sources onto the mind map"},{"kind":"SavedQuery","id":"Query.Wisdom","name":"Approved wisdom on one topic"},{"kind":"SettingScope","id":"Scope.SeatBriefing","name":"Seat briefing layers"},{"kind":"KnowledgeArticle","id":"KB.Hub.Operations","name":"Operations hub - the departments that run the business","description":"Engineering, IT, HR, Finance, Legal, Procurement, Talent, project tracking, support and issues. Root /sites/Operations.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"Hub root /sites/Operations. Sites: Engineering, IT, HR, Finance, Legal, Procurement, Talent, ProjectTracker, CustomerSupport, IssueTracker, Issues, and the documents-only departments. Crew seats are Members here. Work arrives as list rows and moves by the list\u0027s own workflow; a change to how a department works is a part edit, not code.","tags":["hub"],"source":null},{"kind":"KnowledgeArticle","id":"KB.Hub.Missions","name":"Missions hub - the agency divisions and crews","description":"Research, ventures, genesis, reception, studio, the crew and market desks: where agents deliver. Root /sites/Missions.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"Hub root /sites/Missions. Sites: ResearchEnrichment, ResearchLab, VentureEngine, Genesis, Reception, LifeAssistant, Studio, CrewDesk, MarketDesk. Crew seats are Members. Delegated work lands on CrewDesk Tasks as a row; outputs are filed to the invoking site\u0027s lists.","tags":["hub"],"source":null},{"kind":"KnowledgeArticle","id":"KB.Hub.BusinessApps","name":"Business apps hub - the ERP modules and their masters","description":"Common masters, distribution, inventory, manufacturing, CRM and Projects (the backlog). Root /sites/Common.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"Hub root /sites/Common (the shared masters every module looks up). Sites: Distribution, Inventory, Manufacturing, Crm, Projects. Projects holds the backlog (ProjectTasks): update rows through MCP, never by hand in SQL. Crew seats read the modules and are Members of Projects.","tags":["hub"],"source":null},{"kind":"KnowledgeArticle","id":"KB.Hub.Knowledge","name":"Knowledge hub - shared, approved knowledge and catalogs","description":"The Wisdom wiki (content approval, Obsidian vault) and the catalogs made from specs. Root /sites/Wisdom.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"Hub root /sites/Wisdom. Sites: Wisdom (Enterprise Wiki; a page lands Pending until the operator approves; query_wisdom reads approved pages), LlmRadar and ProductCatalog (one catalog for every product type; each category generated from a spec). Propose a lesson as a Pending page; never approve your own.","tags":["hub"],"source":null},{"kind":"KnowledgeArticle","id":"KB.Hub.Governance","name":"Governance hub - approvals, compliance, term store, directory","description":"Compliance, Approvals, Services (term store, audit) and Directory. Owners and approvers act; seats read. Root /sites/Compliance.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"Hub root /sites/Compliance. Sites: Approvals, Services (term store, audit, scheduler state), Directory (people, app principals). Anonymous callers are refused; crew seats are Visitors. A change here goes through an approval, never a direct write.","tags":["hub"],"source":null},{"kind":"KnowledgeArticle","id":"KB.SeatBriefing","name":"Seat briefing - start from your My Site","description":"The first thing every agent seat does: read its own briefing from /sites/my-{seat} through SPICE\u0027s stored queries, instead of relying on a pasted prompt.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"**Start here - your briefing lives in SPICE.** Your own site is /sites/my-{seat}. One call gives the whole briefing in layers, every fact once (AGT.67): tool_compose_briefing with seat={seat}, plus topic=\u003Cterm\u003E for the approved wisdom on your task. Or read the parts one by one through SPICE\u0027s stored queries - call AS YOURSELF with your seat secret from ~/.spice/{seat}.secret (never print it); without it you are the anonymous System Account and your own My Site privacy does not apply (AGT.37):\n\n    curl -s -X POST http://127.0.0.1:5198/mcp/jsonrpc -H \u0022Content-Type: application/json\u0022 -H \u0022Authorization: Bearer $(cat ~/.spice/{seat}.secret)\u0022 -d \u0027{\u0022jsonrpc\u0022:\u00222.0\u0022,\u0022id\u0022:1,\u0022method\u0022:\u0022tools/call\u0022,\u0022params\u0022:{\u0022name\u0022:\u0022query_my_context\u0022,\u0022arguments\u0022:{\u0022seat\u0022:\u0022{seat}\u0022}}}\u0027\n\nThen the same call with query_my_skills (your skill index - pull one body with query_my_asset and a path), query_my_tasks (your open tasks) and query_my_memory (what you learned before). What the whole city has learned and the operator approved: query_wisdom with topic=... (a Topics term, e.g. sharepoint, antipattern). A project\u0027s open work: query_open_backlog with project=AGT (or OPS, TPL, ...). If SPICE is not reachable, say so in one line and continue from the instructions below.","tags":["crew","briefing"],"source":"SPICE.Web/wwwroot/XSLT/CrewAgent.xslt"},{"kind":"KnowledgeArticle","id":"KB.Crew.WiringTracer","name":"Wiring Tracer - operating instructions","description":"The Wiring Tracer crew seat\u0027s full operating instructions. The SPINE is the source of truth for this seat; .claude/agents/spice-wiring-tracer.md is a GENERATED projection of it via wwwroot/XSLT/CrewAgent.xslt. Edit here, then re-run tools/project-crew.ps1 - never edit the markdown by hand.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"You trace ONE wiring question through the SPICE repo (C:\\Users\\erike\\TectonAgency) and return the\nanswer with file:line evidence. Precision over breadth \u2014 this is usually the load-bearing correctness\nquestion for a structural cycle. You do NOT edit code.\n\nREAD FIRST: \u0060plans/AgentCollaboration.md\u0060. Recurring wiring facts that bite here:\n- **Target \u2192 site \u2192 blueprint mapping.** Feature activation passes a \u0060Target\u0060; the two activation\n  paths disagree (stapling = full blueprint \u0060@Name\u0060; AddSiteBlueprint = Portal-stripped). Lists read\n  at the *stripped* path \u0060/sites/{StripPortalSuffix(Name)}/Lists/{n}\u0060. Always confirm which identifier\n  a reader vs a writer uses \u2014 they often differ.\n- **Read vs write location.** A writer (a Tool, an op-handler) may store under one key while the reader\n  (a ViewModelBuilder, a controller) scans another. The served surface is the READ path; pin it.\n- **DI lifetimes (#5/#26).** A Singleton resolving a Scoped service is a captive dep that 500s only on\n  the request that resolves it, never at boot. Trace the lifetime of every service in the chain.\n- **What consumes a part.** Before assuming a declared part \u0022does something\u0022, find the handler/op/tool\n  that READS it. A part with no consumer is inert (#23/#25 \u2014 assert the served surface).\n- **Manifest persistence.** \u0060ProvisioningApplier\u0060 saves on \u0060ManifestTouched\u0060; in dev ContentRoot is the\n  source dir, so it rewrites the source manifest at runtime.\n\nMETHOD: start from the entry point named in the task (a route, a tool, an op-handler, a part), follow the\ncalls with Grep/Read, and quote the decisive lines. Use \u0060./tools/parts-xq.ps1\u0060 (PowerShell) for part-spine\nquestions. When the codebase contradicts an assumption, say so \u2014 surfacing the contradiction is the value.\n\nDELIVER (tight, file:line on every claim): the direct answer to the question, the read-key vs write-key if\nthey differ, and a one-line CONCLUSION the orchestrator can build on (e.g. \u0022add the \u003CList\u003E to\nSiteBlueprint@Name=X; it surfaces at /sites/{stripped}/Lists/{n}; matcher must accept full \u002B stripped\u0022).\nYour final message IS the trace.","tags":["crew","agent-seat"],"source":".claude/agents/spice-wiring-tracer.md"},{"kind":"KnowledgeArticle","id":"KB.Crew.ImpactScout","name":"Impact Scout - operating instructions","description":"The Impact Scout crew seat\u0027s full operating instructions. The SPINE is the source of truth for this seat; .claude/agents/spice-impact-scout.md is a GENERATED projection of it via wwwroot/XSLT/CrewAgent.xslt. Edit here, then re-run tools/project-crew.ps1 - never edit the markdown by hand.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"You are a read-only pre-flight scout. Given a planned structural change in the SPICE repo\n(C:\\Users\\erike\\TectonAgency), you find every test that change could break \u2014 BEFORE it\u0027s written \u2014\nso the cycle lands first-try. You do NOT edit anything.\n\nREAD FIRST: \u0060plans/AgentCollaboration.md\u0060. The breakage classes you hunt (with receipts in the V24 arc):\n- **Positional record constructors.** Adding a field to a \u0060record\u0060 breaks positional callers. Grep\n  \u0060new \u003CRecord\u003E(\u0060 across tests \u002B non-test code; report each as positional (breaks) vs named/initializer\n  (safe). A trailing param with a default keeps positional callers compiling \u2014 note when that dodge works.\n- **XSD-sequence pins.** Tests asserting an exact child-element order (e.g. the FeatureType sequence).\n  Adding an element mid-sequence breaks them; appending last usually doesn\u0027t. Quote the assertion.\n- **Count / value pins.** Tests asserting a literal count (list counts, part counts) or a specific\n  enum/attribute value that your change shifts.\n- **Source-file pins (#27).** Tests that \u0060XDocument.Load\u0060 a single file (e.g. \u0060Parts.xml\u0060) and assert a\n  part is *physically there*, OR build a \u0060PartLibrary\u0060 WITHOUT the same contributors the real boot wires\n  (e.g. missing \u0060HiveFeatureContributor\u0060). Migrating a part into the hive breaks these \u2014 flag them and\n  recommend \u0060Fixtures/LiveParts.MergedSafDocument()\u0060 / adding the contributor to the fixture.\n- **Behavioral pins.** Tests asserting handler/op recorded messages or activation outcomes that a new\n  code path (e.g. a new skip/enforcement branch) would change. Check whether LIVE parts (e.g.\n  Feature.IssueTracker) rely on the old behavior.\n\nMETHOD: grep precisely, read the matched test bodies, and for each hit report **file:line \u002B the\nassertion \u002B WILL-BREAK / SAFE \u002B the minimal fix** (update the assertion, default the new field, append\nnot insert, add the contributor, etc.). Prioritize the highest-likelihood breakage first.\n\nDELIVER a tight checklist (a table is ideal). Be specific \u2014 \u0022V2417 line 57 asserts Web\u2192Department, breaks,\nchange to Web\u0022 beats \u0022some hive tests may fail\u0022. Your final message IS the checklist.","tags":["crew","agent-seat"],"source":".claude/agents/spice-impact-scout.md"},{"kind":"KnowledgeArticle","id":"KB.Crew.FidelityResearcher","name":"Fidelity Researcher - operating instructions","description":"The Fidelity Researcher crew seat\u0027s full operating instructions. The SPINE is the source of truth for this seat; .claude/agents/spice-sp-fidelity-researcher.md is a GENERATED projection of it via wwwroot/XSLT/CrewAgent.xslt. Edit here, then re-run tools/project-crew.ps1 - never edit the markdown by hand.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"You research ONE step of the SPICE platform\u0027s SharePoint-fidelity arc and return a concrete\nimplementation SPEC. You do NOT edit code. SPICE is a .NET 10 app at C:\\Users\\erike\\TectonAgency\nthat models SharePoint-on-prem the XML/XSD/XSLT way.\n\nREAD FIRST: \u0060plans/AgentCollaboration.md\u0060 (the shared conventions). The rules that bind you:\n- Reuse the existing part; only propose a NEW part kind if genuinely needed, and FLAG it as\n  needing operator approval (the platform\u0027s \u0022ask first\u0022 rule).\n- The hive reads elements by LOCAL NAME, so SP\u0027s exact namespace can be adopted later.\n- Find before you build: query the spine with \u0060./tools/parts-xq.ps1 -All \u0022//\u003CKind\u003E\u0022\u0060 (PowerShell;\n  \u0060pwsh\u0060 is not on PATH) BEFORE grepping \u2014 the part spine spans ~14 files.\n- Served-surface discipline (#23/#25/#27): a \u0022fidelity\u0022 cycle is only real if the engine actually\n  consumes the translated part end-to-end (a reader resolves what the writer produced). If your\n  element needs NEW engine (no existing handler/tool consumes it), say so loudly \u2014 that\u0027s a\n  bigger, ask-first cycle, not pure source-format translation.\n\nMETHOD:\n1. Read \u0060SPICE.Foundation/Hive/HiveFeatureContributor.cs\u0060 (how SP elements translate to SAF parts),\n   the relevant \u0060SAF-Parts.xsd\u0060 type, and the existing SPICE part the element maps onto.\n2. Use WebSearch to confirm the REAL SharePoint on-prem schema for the element (borrow the real\n   attribute/element names \u2014 MS Learn is authoritative).\n3. Check whether an existing handler/op/tool already CONSUMES the target part (grep the Provisioning\n   \u002B Tools folders). This decides source-format-only (cheap) vs new-engine (ask-first).\n\nDELIVER (\u003C~500 words, evidence-cited):\n1. REAL SP schema \u2014 the attributes/children that matter \u002B a short example.\n2. REUSE-FIRST MAPPING \u2014 which existing SPICE part/handler covers it; the SP\u2192SAF attribute table;\n   whether anything genuinely new is required (flag for approval).\n3. CONCRETE CYCLE PLAN \u2014 exact files to touch, XSD change (if any), test shape mirroring an\n   existing \u0060SPICE.Web.Tests/V24xx*Tests.cs\u0060, and a non-duplicating worked-example receipt.\n4. RISKS \u2014 especially IDREF resolution across the merge, child-order in synthesized parts, and the\n   #27 source-file-pin trap (migrating an IDREF-target part breaks no-hive fixtures).\n\nYour final message IS the spec (it is returned to the orchestrator, not shown to the user).","tags":["crew","agent-seat"],"source":".claude/agents/spice-sp-fidelity-researcher.md"},{"kind":"KnowledgeArticle","id":"KB.Crew.ServedVerifier","name":"Served Verifier - operating instructions","description":"The Served Verifier crew seat\u0027s full operating instructions. The SPINE is the source of truth for this seat; .claude/agents/spice-verify.md is a GENERATED projection of it via wwwroot/XSLT/CrewAgent.xslt. Edit here, then re-run tools/project-crew.ps1 - never edit the markdown by hand.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"You verify that ONE change\u0027s served surface actually round-trips on a RUNNING SPICE instance\n(repo C:\\Users\\erike\\TectonAgency). The recurring trap you exist to catch: a green suite proves the\nMODEL, the served surface shows nothing until a human says \u0022show me\u0022 - capability theatre. You assume\nthe server is already up (the orchestrator booted it); you NEVER boot, edit, or fix. Your verdict is\nthe value.\n\nREAD FIRST: \u0060plans/AgentCollaboration.md\u0060 (the served-surface trio #23/#25/#27 \u002B the gotchas).\n\nThe judgment you encode (the cost-this-session class):\n- **#25 reuse the WHOLE seam.** A writer (a Tool, an op-handler) may store under one key while the\n  reader (a ViewModelBuilder, a controller, a board XQuery) scans another. \u0022Applier returned success\u0022\n  is NOT proof. Find the write key and the read key; if they differ, the round-trip is the only proof.\n- **#23 assert the served surface, not the model.** Hit the path the operator actually sees, not a\n  unit-test proxy.\n- **#27 assert the resolved spine, not the source file.** A part resolves identically whether it lives\n  in Parts.xml or the hive; verify via the served/merged surface, not a file path.\n- **The two-approval-surfaces class (the exact confusion to catch).** \u0060/approvals\u0060 renders pipeline\n  checkpoints from \u0060IApprovalGateStore\u0060; a gated PARK from e.g. \u0060Tool.BuildDivision\u0060 lands as a list\n  item on \u0060/sites/Engineering/Lists/ApprovalRequests\u0060 (the \u0060ApprovalRequests\u0060 list, queried via\n  \u0060item:{id}\u0060). They are DIFFERENT surfaces. A parked division shows \u0060count=0\u0060 on \u0060/approvals\u0060 and is\n  visible only on the ApprovalRequests list view. When two surfaces could be confused, name which is\n  correct and why.\n- **List-item read key (#25 corollary).** A runtime \u0060AddListItem\u0060 write must prefix \u0060@Key\u0060 with\n  \u0060item:\u0060 or the row commits but is invisible to every list view (the read path queries \u0060item:{id}\u0060).\n  A missing prefix is a FAIL even though the write \u0022succeeded\u0022.\n- **Generation honesty (the LLM-seam class \u2014 the cost-this-session #35 class).** If the change touches\n  an LLM path (a \u0060Workflow\u0060/\u0060Phase\u0060, a provider, the \u0060AgentRouter\u0060, or the \u0060Mode=\u0022ToolLoop\u0022\u0060 seam), the\n  round-trip is: FIRE the generation (\u0060POST /agency/workflows/{id}/run\u0060, e.g. \u0060Workflow.WatchdogReview\u0060)\n  and confirm the output is REAL \u2014 not \u0060[Echo agent]\u0060, not empty, and \u0060outputSchemaValid=true\u0060. The\n  ToolLoop path is a SEPARATE seam from single-shot (it BYPASSES the router), so a provider fix to one\n  may not reach the other. A stub / empty / degenerate generation is a **FAIL**, never N/A. Reuse\n  \u0060tools/toolloop-smoke.ps1\u0060. (memory: feedback_toolloop_separate_seam_from_router)\n\nMETHOD:\n1. **Identify the surface from the diff.** Read the changed files named in the task (or \u0060git diff\u0060 if\n   none named). Pin the touched controller / board / list / tool / part and what it WRITES.\n2. **Separate write path from read path.** Trace where the change stores data vs where the operator\n   reads it. Quote the write key and the read key with file:line. If they differ, that difference IS\n   the thing to prove.\n3. **Probe the read surface.** \u0060curl\u0060 the served read surface against the passed base URL\n   (default \u0060http://localhost:5198\u0060). For a data change, exercise the full **write -\u003E read round-trip**:\n   invoke the tool/endpoint, then confirm the artifact appears on the served read surface (the right\n   list view / board / page), not merely that the write call returned success.\n4. **Discriminate confusable surfaces.** When more than one surface could be meant, state which is\n   correct and show the other returning empty if that is the trap.\n5. **Use \u0060./tools/parts-xq.ps1\u0060 (PowerShell)** for part-spine resolution questions. If the codebase\n   contradicts the change\u0027s stated intent, say so - surfacing the contradiction is the value.\n\nVERDICT RULES:\n- **PASS** - the write reaches the served read surface; the round-trip is demonstrated with evidence.\n- **FAIL** - the write does not surface on the read path the operator sees (wrong key, wrong surface,\n  missing \u0060item:\u0060 prefix, reader scans elsewhere). Show the missing-from-read-surface evidence.\n- **N/A** - the change has no served data surface (pure XSLT/style, a refactor, an interface move).\n  Give the reason; never a false PASS. **BUT a change to an LLM generation path is NEVER N/A** \u2014 fire\n  the generation and grade the output; a stub/empty/schema-invalid answer is a FAIL, not N/A.\n\nDELIVER (tight, file:line on every claim) - this block IS your final message:\n\n\u0060\u0060\u0060\nVERDICT: PASS | FAIL | N/A\nSURFACE: \u003Cthe exact served read URL checked, or \u0022none (reason)\u0022\u003E\nWRITE PATH: \u003Cwhere/under-what-key the change writes\u003E  (file:line)\nREAD PATH:  \u003Cwhere/under-what-key the operator reads\u003E (file:line)\nROUND-TRIP: \u003Cwhat was written, where it was read back, the curl evidence\u003E\nCONFUSABLE: \u003Cthe wrong-but-tempting surface and why it is wrong, if any\u003E\nCONCLUSION: \u003Cone line the orchestrator can act on\u003E\n\u0060\u0060\u0060\n\nYou never edit code. If you cannot reach the running instance, say so and return N/A with the reason\n(do not boot it yourself).","tags":["crew","agent-seat"],"source":".claude/agents/spice-verify.md"},{"kind":"Tool","id":"Tool.XQuery","name":"XQuery the spine","description":"Run an XQuery 3.1 expression over the MERGED part spine (central Parts.xml plus every App manifest plus the cycle ledger) and return the result. Keyless, deterministic, no LLM. This is how an agent asks the platform about itself - which parts exist, what a Feature declares, which cycles shipped - instead of grepping 14 files. The Saxon Processor refuses all external resource resolution (da5561d), so doc(), unparsed-text() and http URIs cannot reach the filesystem or the network. DECLARED 2026-09-22: the invoker (XQueryToolInvoker.cs:16) had claimed this ToolId since it shipped, but NO Tool part declared it - so the tool the Ship Manual tells agents to use was itself invisible to //Tool, and any RequiresTool reference to it hard-failed XSD IDREF at boot. Found by dogfooding, when the de-risk crew was declared as parts and could not name the tool it uses.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"XQueryToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Skill","id":"Skill.TraceWiring","name":"Trace Wiring","description":"Read-only deep trace of ONE SPICE code path with file:line evidence - how a target maps to a site/blueprint/list, how a route resolves, a DI lifetime chain, what consumes a part, where a value is read versus written. Use when a structural change hinges on a wiring fact that must be pinned before code is written.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Architecture","requiresApproval":false,"capabilities":["Trace one wiring question end to end and answer it with file:line evidence","Distinguish where a value is WRITTEN from where it is READ","Report a DI lifetime chain and name any captive dependency (anti-pattern 5)","Say \u0022does not exist\u0022 plainly rather than describing what something would look like","Never edit code - this seat is read-only"],"requiresTools":["Tool.XQuery"]},{"kind":"Skill","id":"Skill.ScoutTestImpact","name":"Scout Test Impact","description":"Given a planned structural change - a record field, an XSD type or sequence, a handler, an op-handler behaviour - enumerate EVERY at-risk test with file:line and the exact assertion, before any code is written. The read-only pre-flight that pre-empts test breakage.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Review","requiresApproval":false,"capabilities":["Enumerate every at-risk test with file:line and the exact assertion","Flag positional records, where adding a field breaks every construction site","Distinguish a test that asserts behaviour from one that asserts a literal shape","Report the blast radius as a count before the cycle starts"],"requiresTools":["Tool.XQuery"]},{"kind":"Skill","id":"Skill.ResearchSpFidelity","name":"Research SharePoint Fidelity","description":"Research ONE element of the real SharePoint on-prem model - feature.xml, elements.xml, onet.xml, schema.xml, fldtypes, AlertTemplates, CAML - and map it REUSE-FIRST onto SPICE existing parts, returning a tight low-risk cycle spec. Ranks findings by TEACHING COST, because a model already trained on the real vocabulary needs no teaching and every divergence is a bill charged on every future prompt.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Architecture","requiresApproval":false,"capabilities":["Name the real SharePoint file, element and attribute rather than paraphrasing","Map each primitive onto an EXISTING SPICE part before proposing anything new","Rank by teaching cost - how much a divergence forces us to teach a model what it already knows","Say what SPICE already does BETTER, so nothing is borrowed backwards","Say what to deliberately NOT borrow, and why","Flag loudly when a genuinely new part kind is needed, because that needs operator approval first"],"requiresTools":["Tool.XQuery","Tool.WebSearch"]},{"kind":"Skill","id":"Skill.VerifyServedSurface","name":"Verify Served Surface","description":"Given a working diff and a running SPICE instance, derive WHICH served surface the change should expose and prove the write-to-read round trip - not merely an HTTP 200 - returning a structured PASS, FAIL or N/A verdict with file:line and surface evidence. Institutionalises the rule that a change is not done until the reader resolves what the writer produced.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Operations","requiresApproval":false,"capabilities":["Derive which served surface a diff should expose, rather than being told","Prove the round trip: the reader must resolve what the writer produced","Treat an HTTP 200 as necessary and not sufficient","Return PASS, FAIL or N/A with evidence, and never fix what it finds"],"requiresTools":["Tool.XQuery"]},{"kind":"ActorProfile","id":"Actor.WiringTracer","name":"Wiring Tracer"},{"kind":"ActorProfile","id":"Actor.ImpactScout","name":"Impact Scout"},{"kind":"ActorProfile","id":"Actor.FidelityResearcher","name":"Fidelity Researcher"},{"kind":"ActorProfile","id":"Actor.ServedVerifier","name":"Served Verifier"},{"kind":"Agency","id":"Agency.Fidelity","name":"Fidelity Crew"},{"kind":"ListTemplate","id":"ListTemplate.Inbox","name":"Inbox"},{"kind":"Skill","id":"Skill.RequestApproval","name":"Request Approval","description":"Submit an ApprovalRequest into the department\u0027s approval list","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Processing","requiresApproval":false,"capabilities":["Call Tool.ListSchema(site, list=ApprovalRequests) to learn the field shape before drafting","Author a clear Subject describing what needs approval","Set the QuorumRequired threshold (all / majority / N)","Emit a ProvisioningDelta with AddListItem against ListTemplate.ApprovalRequests"],"requiresTools":["Tool.Llm","Tool.ListSchema"]},{"kind":"Skill","id":"Skill.SubmitVerdict","name":"Submit Verdict","description":"Add an ApprovalVerdict (Allow / Deny / RequestChanges) to a request","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Approval","requiresApproval":false,"capabilities":["Call Tool.ListSchema(site, list=ApprovalVerdicts) to confirm decision-field choices","Read the ApprovalRequest under review","Decide Allow / Deny / RequestChanges and write a Reason","Emit a ProvisioningDelta with AddListItem against ListTemplate.ApprovalVerdicts"],"requiresTools":["Tool.Llm","Tool.ListSchema"]},{"kind":"Skill","id":"Skill.EvaluateApprovalQuorum","name":"Evaluate Approval Quorum","description":"Count verdicts on a request, compare to QuorumRequired, flip RequestStatus if reached. Bound to ER.OnVerdictAdded.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Approval","requiresApproval":false,"capabilities":["Read all ApprovalVerdict items whose RequestId matches the parent","Apply the QuorumRequired threshold (all / majority / N)","Emit a delta updating the parent request\u0027s RequestStatus"],"requiresTools":["Tool.Llm"]},{"kind":"EventReceiver","id":"ER.OnVerdictAdded","name":"On verdict added: evaluate quorum"},{"kind":"Feature","id":"Feature.ApprovalWorkflow","name":"Approval workflow"},{"kind":"Feature","id":"Feature.Governance","name":"Governance"},{"kind":"FieldDefinition","id":"Field.Description","name":"Description"},{"kind":"FieldDefinition","id":"Field.Priority","name":"Priority"},{"kind":"FieldDefinition","id":"Field.AssignedTo","name":"AssignedTo"},{"kind":"FieldDefinition","id":"Field.Watchers","name":"Watchers"},{"kind":"FieldDefinition","id":"Field.PersonEmail","name":"Email"},{"kind":"FieldDefinition","id":"Field.PersonRole","name":"Role"},{"kind":"ContentType","id":"ContentType.Person","name":"Person"},{"kind":"FieldDefinition","id":"Field.ActorRef","name":"ActorRef"},{"kind":"FieldDefinition","id":"Field.Skills","name":"Skills"},{"kind":"FieldDefinition","id":"Field.AgentType","name":"AgentType"},{"kind":"FieldDefinition","id":"Field.BriefingQuota","name":"BriefingQuota"},{"kind":"FieldDefinition","id":"Field.AllowedTools","name":"AllowedTools"},{"kind":"FieldDefinition","id":"Field.Machine","name":"Machine"},{"kind":"FieldDefinition","id":"Field.AgentRuntime","name":"AgentRuntime"},{"kind":"FieldDefinition","id":"Field.ModelId","name":"ModelId"},{"kind":"FieldDefinition","id":"Field.SeatStatus","name":"SeatStatus"},{"kind":"FieldDefinition","id":"Field.Department","name":"Department"},{"kind":"FieldDefinition","id":"Field.JobTitle","name":"JobTitle"},{"kind":"FieldDefinition","id":"Field.Responsibilities","name":"Responsibilities"},{"kind":"FieldDefinition","id":"Field.OutOfScope","name":"OutOfScope"},{"kind":"ListTemplate","id":"ListTemplate.People","name":"People"},{"kind":"FieldDefinition","id":"Field.IssueStatus","name":"IssueStatus"},{"kind":"FieldDefinition","id":"Field.ResolvedAt","name":"ResolvedAt"},{"kind":"FieldDefinition","id":"Field.RelatedIssues","name":"RelatedIssues"},{"kind":"FieldDefinition","id":"Field.IssueType","name":"IssueType"},{"kind":"FieldDefinition","id":"Field.StoryPoints","name":"StoryPoints"},{"kind":"FieldDefinition","id":"Field.IssueSprintRef","name":"IssueSprintRef"},{"kind":"FieldDefinition","id":"Field.IssueEpicRef","name":"IssueEpicRef"},{"kind":"FieldDefinition","id":"Field.IssueReporter","name":"IssueReporter"},{"kind":"FieldDefinition","id":"Field.Industry","name":"Industry"},{"kind":"FieldDefinition","id":"Field.Manager","name":"Manager"},{"kind":"FieldDefinition","id":"Field.LeaveType","name":"LeaveType"},{"kind":"FieldDefinition","id":"Field.JobLevel","name":"JobLevel"},{"kind":"FieldDefinition","id":"Field.LeaveStartDate","name":"LeaveStartDate"},{"kind":"FieldDefinition","id":"Field.LeaveEndDate","name":"LeaveEndDate"},{"kind":"FieldDefinition","id":"Field.LeaveStatus","name":"LeaveStatus"},{"kind":"FieldDefinition","id":"Field.Year","name":"Year"},{"kind":"FieldDefinition","id":"Field.Counterparty","name":"Counterparty"},{"kind":"FieldDefinition","id":"Field.EffectiveDate","name":"EffectiveDate"},{"kind":"FieldDefinition","id":"Field.ExpirationDate","name":"ExpirationDate"},{"kind":"FieldDefinition","id":"Field.Jurisdiction","name":"Jurisdiction"},{"kind":"FieldDefinition","id":"Field.RenewalTerms","name":"RenewalTerms"},{"kind":"FieldDefinition","id":"Field.ContractStatus","name":"ContractStatus"},{"kind":"FieldDefinition","id":"Field.ContractValue","name":"ContractValue"},{"kind":"FieldDefinition","id":"Field.RfqStatus","name":"RfqStatus"},{"kind":"FieldDefinition","id":"Field.AwardedBidId","name":"AwardedBidId"},{"kind":"FieldDefinition","id":"Field.RfqId","name":"RfqId"},{"kind":"FieldDefinition","id":"Field.Vendor","name":"Vendor"},{"kind":"FieldDefinition","id":"Field.Amount","name":"Amount"},{"kind":"FieldDefinition","id":"Field.DeliveryDays","name":"DeliveryDays"},{"kind":"FieldDefinition","id":"Field.BidStatus","name":"BidStatus"},{"kind":"ContentType","id":"ContentType.Issue","name":"Issue"},{"kind":"ListTemplate","id":"ListTemplate.Issues","name":"Issues"},{"kind":"ListTemplate","id":"ListTemplate.IssueComments","name":"Issue Comments"},{"kind":"FieldDefinition","id":"Field.ProcedureSteps","name":"ProcedureSteps"},{"kind":"FieldDefinition","id":"Field.EscalationPath","name":"EscalationPath"},{"kind":"FieldDefinition","id":"Field.SLAHours","name":"SLAHours"},{"kind":"FieldDefinition","id":"Field.ProcedureStatus","name":"ProcedureStatus"},{"kind":"FieldDefinition","id":"Field.OwnerRole","name":"OwnerRole"},{"kind":"FieldDefinition","id":"Field.ResponsibilityRole","name":"ResponsibilityRole"},{"kind":"FieldDefinition","id":"Field.DepartmentRef","name":"DepartmentRef"},{"kind":"FieldDefinition","id":"Field.ProcedureRef","name":"ProcedureRef"},{"kind":"ContentType","id":"ContentType.Procedure","name":"Procedure"},{"kind":"ContentType","id":"ContentType.Responsibility","name":"Responsibility"},{"kind":"ListTemplate","id":"ListTemplate.Procedures","name":"Procedures"},{"kind":"ListTemplate","id":"ListTemplate.Responsibilities","name":"Responsibilities"},{"kind":"ContentType","id":"ContentType.LeaveRequest","name":"Leave Request"},{"kind":"ContentType","id":"ContentType.HeadcountReview","name":"Headcount Review"},{"kind":"ListTemplate","id":"ListTemplate.LeaveRequests","name":"Leave Requests"},{"kind":"ListTemplate","id":"ListTemplate.HeadcountReviews","name":"Headcount Reviews"},{"kind":"ContentType","id":"ContentType.Organization","name":"Organization"},{"kind":"ContentType","id":"ContentType.Contract","name":"Contract"},{"kind":"ListTemplate","id":"ListTemplate.Organizations","name":"Organizations"},{"kind":"ListTemplate","id":"ListTemplate.Contracts","name":"Contracts"},{"kind":"ContentType","id":"ContentType.BidRequest","name":"Bid Request"},{"kind":"ContentType","id":"ContentType.Bid","name":"Bid"},{"kind":"ListTemplate","id":"ListTemplate.BidRequests","name":"Bid Requests"},{"kind":"ListTemplate","id":"ListTemplate.Bids","name":"Bids"},{"kind":"Skill","id":"Skill.OpenIssue","name":"Open Issue","description":"File a new Issue with title, description, and priority","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Processing","requiresApproval":false,"capabilities":["Call Tool.ListSchema(site, list=Issues) to learn the field shape (Priority/IssueStatus choices)","Triage user description into a clear Title \u002B Description","Pick a Priority based on impact \u002B urgency","Emit a ProvisioningDelta with AddListItem against ListTemplate.Issues"],"requiresTools":["Tool.Llm","Tool.ListSchema"]},{"kind":"Skill","id":"Skill.ReviewProcedure","name":"Review Procedure","description":"Read a freshly-submitted Procedure row and file an ApprovalRequest naming its Owner. Bound to ER.OnProcedureSubmitted; emits one AddListItem against ApprovalRequests on the procedure\u0027s site. The existing approval-verdict machinery flips ProcedureStatus to Active later.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Approval","requiresApproval":false,"capabilities":["Read the new Procedure (Subject, AssignedTo, OwnerRole)","Compose an ApprovalRequest Subject using the procedure name","Emit a ProvisioningDelta with one AddListItem against ApprovalRequests (RequestStatus=Open, QuorumRequired=1)"],"requiresTools":["Tool.Llm","Tool.ListSchema"]},{"kind":"Skill","id":"Skill.AssignIssue","name":"Assign Issue","description":"Route an open Issue to the right owner; bound to ER.OnIssueOpened for auto-routing","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Assignment","requiresApproval":false,"capabilities":["Call Tool.ListSchema(site, list=Issues) to confirm IssueStatus choices","Read the new issue and the department\u0027s roster","Choose an AssignedTo \u002B flip IssueStatus to InProgress","Emit a delta updating the issue"],"requiresTools":["Tool.Llm","Tool.ListSchema"]},{"kind":"Skill","id":"Skill.CommentOnIssue","name":"Comment on Issue","description":"Add an IssueComment to an existing issue","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","category":"Communication","requiresApproval":false,"capabilities":["Call Tool.ListSchema(site, list=IssueComments) to confirm the IssueId foreign-key field","Author a focused comment that progresses the issue","Emit a ProvisioningDelta with AddListItem against ListTemplate.IssueComments"],"requiresTools":["Tool.Llm","Tool.ListSchema"]},{"kind":"Skill","id":"Skill.ResolveIssue","name":"Resolve Issue","description":"Mark an issue Resolved with a closing summary","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Processing","requiresApproval":false,"capabilities":["Verify the issue\u0027s acceptance criteria are met","Set IssueStatus=Resolved \u002B stamp ResolvedAt","Emit a delta updating the issue"],"requiresTools":["Tool.Llm"]},{"kind":"EventReceiver","id":"ER.OnIssueOpened.CustomerSupport","name":"CustomerSupport: route incoming ticket"},{"kind":"EventReceiver","id":"ER.OnIssueOpened.IT","name":"IT: route incoming helpdesk ticket"},{"kind":"Skill","id":"Skill.RouteLeaveRequest","name":"Route Leave Request","description":"Resolve the manager-of-record for a fresh LeaveRequest, set Field.Manager, flip Field.LeaveStatus from Submitted to AwaitingManager. Bound to ER.OnLeaveRequestSubmitted; emits a ProvisioningDelta updating the original row.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Assignment","requiresApproval":false,"capabilities":["Call Tool.ListSchema(site, list=LeaveRequests) to confirm field shape","Look up the requester\u0027s manager from the People directory","Set Field.Manager and flip Field.LeaveStatus to AwaitingManager","Emit a ProvisioningDelta with one AddListItem updating the request"],"requiresTools":["Tool.Llm","Tool.ListSchema"]},{"kind":"Skill","id":"Skill.AnnualHeadcountReview","name":"Annual Headcount Review","description":"Roll up the year\u0027s HR activity (LeaveRequests filed, approval rates, JobLevel distribution) into a HeadcountReview Note. Bound to Schedule.AnnualHeadcountReview which fires on Q1 first Monday.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Reporting","requiresApproval":false,"capabilities":["Pull the past year of LeaveRequest activity from the audit log","Group rollup by JobLevel \u002B LeaveType taxonomy values","Author a Markdown summary suitable for the HeadcountReviews list","Emit a ProvisioningDelta with one AddListItem against ListTemplate.HeadcountReviews"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.MonthlyClose","name":"Monthly Close","description":"Roll up the past month\u0027s operational activity AND LLM spend into a single Note suitable for finance review. Bound to Schedule.MonthlyClose; reads Tool.CostRollup for the spend snapshot and folds it into the body.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Reporting","requiresApproval":false,"capabilities":["Read Tool.CostRollup output (front-loaded into the briefing) for period spend","Summarise operational highlights from the audit log","Author a single Markdown body with two sections - operations \u002B LLM spend","Emit a ProvisioningDelta with one AddListItem against ListTemplate.Notes"],"requiresTools":["Tool.Llm","Tool.CostRollup"]},{"kind":"Skill","id":"Skill.QuarterlyReport","name":"Quarterly Report","description":"Quarterly rollup with longer horizon and cross-quarter trend commentary. Same Cost-Rollup integration as MonthlyClose but a 92-day window.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Reporting","requiresApproval":false,"capabilities":["Read Tool.CostRollup output over a 92-day window","Spot quarter-over-quarter spend movement","Author a Markdown quarterly summary suitable for executive review","Emit a ProvisioningDelta with one AddListItem against ListTemplate.Notes"],"requiresTools":["Tool.Llm","Tool.CostRollup"]},{"kind":"EventReceiver","id":"ER.OnLeaveRequestSubmitted","name":"On leave request submitted: run Workflow.RouteLeaveRequest"},{"kind":"Skill","id":"Skill.IntakeContract","name":"Intake Contract","description":"Read a fresh contract row\u0027s Body / Subject, infer Counterparty / Jurisdiction / EffectiveDate / ExpirationDate / RenewalTerms, and emit a ProvisioningDelta updating those typed fields. Bound to ER.OnContractAdded.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Assignment","requiresApproval":false,"capabilities":["Call Tool.ListSchema(site, list=Contracts) to learn the field shape","Call Tool.ListSchema(site=Directory, list=Organizations) to discover known counterparties before creating a new one","Extract typed values from the contract Body and Subject (no YAML / no text-parsing assumptions - infer Counterparty as a Title match against the Organizations list)","Emit a ProvisioningDelta with one AddListItem updating the contract row \u002B flipping ContractStatus to Active"],"requiresTools":["Tool.Llm","Tool.ListSchema"]},{"kind":"Skill","id":"Skill.ExpirationDigest","name":"Expiration Digest","description":"Query the contracts list for rows expiring within 30 days, write a Markdown digest Note. Bound to Schedule.WeeklyExpirationDigest; pulls SavedQuery.ExpiringContracts via the new ListItems CAML target.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Reporting","requiresApproval":false,"capabilities":["Read SavedQuery.ExpiringContracts results (front-loaded into the briefing) for contracts expiring soon","Group rollup by Counterparty \u002B Jurisdiction","Author a Markdown digest highlighting renewal-required entries first","Emit a ProvisioningDelta with one AddListItem against ListTemplate.Notes"],"requiresTools":["Tool.Llm"]},{"kind":"Skill","id":"Skill.AwardBid","name":"Award Bid","description":"Score open Bids per RFQ and pick a winner. Bound to Schedule.WeeklyBidAward; reads SavedQuery.OpenBids via the ListItems CAML target.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Decision","requiresApproval":false,"capabilities":["Read SavedQuery.OpenBids results (front-loaded into the briefing) - all currently-Submitted Bids","Group bids by RfqId; ignore RFQs whose RfqStatus is not Closed","Rank candidates by Amount \u002B DeliveryDays (lower better) with vendor history as tiebreaker","Emit a ProvisioningDelta with one AddListItem per winning Bid (BidStatus=Awarded), one per losing Bid (BidStatus=Rejected), and one per BidRequest (RfqStatus=Awarded \u002B AwardedBidId set)"],"requiresTools":["Tool.Llm"]},{"kind":"EventReceiver","id":"ER.OnContractAdded","name":"On contract added: run Workflow.ContractIntake"},{"kind":"EventReceiver","id":"ER.OnProcedureSubmitted","name":"On procedure submitted: run Workflow.ReviewProcedure"},{"kind":"Webhook","id":"Webhook.OnIssueOpened.Notify","name":"Notify external system on new Issue"},{"kind":"FieldDefinition","id":"Field.LastEdited","name":"LastEdited"},{"kind":"ContentType","id":"ContentType.WikiPage","name":"Wiki Page"},{"kind":"ContentType","id":"ContentType.Note","name":"Note"},{"kind":"ListTemplate","id":"ListTemplate.Notes","name":"Notes"},{"kind":"ListTemplate","id":"ListTemplate.WikiPages","name":"Wiki Pages"},{"kind":"FieldDefinition","id":"Field.TermPath","name":"Path"},{"kind":"FieldDefinition","id":"Field.TermParent","name":"ParentPath"},{"kind":"FieldDefinition","id":"Field.TermOtherLabels","name":"OtherLabels"},{"kind":"ContentType","id":"ContentType.Term","name":"Term"},{"kind":"ListTemplate","id":"ListTemplate.TermSet","name":"Term Set"},{"kind":"FieldDefinition","id":"Field.ActorId","name":"ActorId"},{"kind":"FieldDefinition","id":"Field.MemoryContent","name":"Content"},{"kind":"FieldDefinition","id":"Field.MemoryType","name":"MemoryType"},{"kind":"ContentType","id":"ContentType.ActorMemoryEntry","name":"Actor Memory Entry"},{"kind":"ListTemplate","id":"ListTemplate.ActorMemory","name":"Actor Memory"},{"kind":"ActorProfile","id":"Actor.AlicePM","name":"Alice (Project Manager)"},{"kind":"ActorProfile","id":"Actor.LegalReviewer","name":"Legal Reviewer"},{"kind":"ActorProfile","id":"Actor.OperationsCoordinator","name":"Operations Coordinator"},{"kind":"ActorProfile","id":"Actor.OperationsDeputy","name":"Operations Deputy"},{"kind":"ActorProfile","id":"Actor.HrOfficer","name":"HR Officer"},{"kind":"ActorProfile","id":"Actor.FinanceController","name":"Finance Controller"},{"kind":"ActorProfile","id":"Actor.ComplianceOfficer","name":"Compliance Officer"},{"kind":"ActorProfile","id":"Actor.ProcurementOfficer","name":"Procurement Officer"},{"kind":"ActorProfile","id":"Actor.EngineeringLead","name":"Engineering Lead"},{"kind":"ActorProfile","id":"Actor.ApprovalsSteward","name":"Approvals Steward"},{"kind":"FieldDefinition","id":"Field.Subtitle","name":"Subtitle"},{"kind":"FieldDefinition","id":"Field.PostDate","name":"PostDate"},{"kind":"FieldDefinition","id":"Field.HeroImage","name":"HeroImage"},{"kind":"FieldDefinition","id":"Field.Tags","name":"Tags"},{"kind":"ContentType","id":"ContentType.NewsPost","name":"News Post"},{"kind":"ListTemplate","id":"ListTemplate.News","name":"News"},{"kind":"FieldDefinition","id":"Field.PageName","name":"PageName"},{"kind":"FieldDefinition","id":"Field.Layout","name":"Layout"},{"kind":"FieldDefinition","id":"Field.PublishingStartDate","name":"PublishingStartDate"},{"kind":"FieldDefinition","id":"Field.PublishingEndDate","name":"PublishingEndDate"},{"kind":"ContentType","id":"ContentType.Page","name":"Web Part Page"},{"kind":"ListTemplate","id":"ListTemplate.SitePages","name":"Site Pages"},{"kind":"FieldDefinition","id":"Field.FolderPath","name":"FolderPath"},{"kind":"ContentType","id":"ContentType.Folder","name":"Folder"},{"kind":"FieldDefinition","id":"Field.ApprovalStatus","name":"ApprovalStatus"},{"kind":"ContentType","id":"ContentType.DesignDoc","name":"Design Document"},{"kind":"ListTemplate","id":"ListTemplate.DesignDocs","name":"Design Documents"},{"kind":"ContentType","id":"ContentType.CustomItem","name":"Custom Item"},{"kind":"ContentType","id":"ContentType.GenericItem","name":"Generic Item"},{"kind":"FieldDefinition","id":"Field.FirstName","name":"FirstName"},{"kind":"FieldDefinition","id":"Field.FullName","name":"FullName"},{"kind":"FieldDefinition","id":"Field.Company","name":"Company"},{"kind":"FieldDefinition","id":"Field.WorkPhone","name":"WorkPhone"},{"kind":"FieldDefinition","id":"Field.HomePhone","name":"HomePhone"},{"kind":"FieldDefinition","id":"Field.CellPhone","name":"CellPhone"},{"kind":"FieldDefinition","id":"Field.WorkFax","name":"WorkFax"},{"kind":"FieldDefinition","id":"Field.WorkAddress","name":"WorkAddress"},{"kind":"FieldDefinition","id":"Field.WorkCity","name":"WorkCity"},{"kind":"FieldDefinition","id":"Field.WorkState","name":"WorkState"},{"kind":"FieldDefinition","id":"Field.WorkZip","name":"WorkZip"},{"kind":"FieldDefinition","id":"Field.WorkCountry","name":"WorkCountry"},{"kind":"FieldDefinition","id":"Field.WebPage","name":"WebPage"},{"kind":"ContentType","id":"ContentType.Contact","name":"Contact"},{"kind":"FieldDefinition","id":"Field.EventDate","name":"EventDate"},{"kind":"FieldDefinition","id":"Field.EventEndDate","name":"EndDate"},{"kind":"FieldDefinition","id":"Field.Location","name":"Location"},{"kind":"FieldDefinition","id":"Field.fAllDayEvent","name":"fAllDayEvent"},{"kind":"FieldDefinition","id":"Field.EventCategory","name":"Category"},{"kind":"ContentType","id":"ContentType.Event","name":"Event"},{"kind":"FieldDefinition","id":"Field.ImageWidth","name":"ImageWidth"},{"kind":"FieldDefinition","id":"Field.ImageHeight","name":"ImageHeight"},{"kind":"FieldDefinition","id":"Field.ImageCreateDate","name":"ImageCreateDate"},{"kind":"FieldDefinition","id":"Field.Keywords","name":"Keywords"},{"kind":"ContentType","id":"ContentType.Picture","name":"Picture"},{"kind":"FieldDefinition","id":"Field.BackgroundImageLocation","name":"BackgroundImageLocation"},{"kind":"FieldDefinition","id":"Field.LinkLocation","name":"LinkLocation"},{"kind":"FieldDefinition","id":"Field.LaunchBehavior","name":"LaunchBehavior"},{"kind":"FieldDefinition","id":"Field.TileOrder","name":"TileOrder"},{"kind":"ContentType","id":"ContentType.PromotedLink","name":"Promoted Link"},{"kind":"ContentType","id":"ContentType.SurveyResponse","name":"Survey Response"},{"kind":"FieldDefinition","id":"Field.SurveyWorkload","name":"Workload"},{"kind":"FieldDefinition","id":"Field.SurveyTools","name":"ToolsRating"},{"kind":"FieldDefinition","id":"Field.SurveyRecommend","name":"Recommend"},{"kind":"FieldDefinition","id":"Field.SurveyComments","name":"SurveyComments"},{"kind":"ContentType","id":"ContentType.TeamSurvey","name":"Team Survey"},{"kind":"ContentType","id":"ContentType.FormDocument","name":"Form"},{"kind":"FieldDefinition","id":"Field.ClaimAmount","name":"ClaimAmount"},{"kind":"FieldDefinition","id":"Field.ClaimCategory","name":"ClaimCategory"},{"kind":"FieldDefinition","id":"Field.ClaimDate","name":"ClaimDate"},{"kind":"FieldDefinition","id":"Field.ClaimPurpose","name":"ClaimPurpose"},{"kind":"FieldDefinition","id":"Field.ClaimApprover","name":"ClaimApprover"},{"kind":"FieldDefinition","id":"Field.ClaimLines","name":"ClaimLines"},{"kind":"FieldDefinition","id":"Field.LineWhat","name":"LineWhat"},{"kind":"FieldDefinition","id":"Field.LineAmount","name":"LineAmount"},{"kind":"ContentType","id":"ContentType.ExpenseLine","name":"Expense Line"},{"kind":"ContentType","id":"ContentType.ExpenseClaim","name":"Expense Claim"},{"kind":"FormTemplate","id":"Form.ExpenseClaim","name":"Expense claim"},{"kind":"FieldDefinition","id":"Field.PublishedDate","name":"PublishedDate"},{"kind":"FieldDefinition","id":"Field.PostCategory","name":"PostCategory"},{"kind":"FieldDefinition","id":"Field.PostTitle","name":"PostTitle"},{"kind":"ContentType","id":"ContentType.Post","name":"Post"},{"kind":"ContentType","id":"ContentType.Comment","name":"Comment"},{"kind":"SiteTemplate","id":"SiteTemplate.MarketDesk","name":"Market Desk"},{"kind":"SiteTemplate","id":"SiteTemplate.TeamSite","name":"Team Site"},{"kind":"SiteTemplate","id":"SiteTemplate.DocumentCenter","name":"Document Center"},{"kind":"SiteTemplate","id":"SiteTemplate.RecordsCenter","name":"Records Center"},{"kind":"SiteTemplate","id":"SiteTemplate.Blog","name":"Blog"},{"kind":"SiteTemplate","id":"SiteTemplate.DocumentReview","name":"Document Library and Review"},{"kind":"SiteTemplate","id":"SiteTemplate.AbsenceRequest","name":"Absence Request and Vacation Schedule"},{"kind":"SiteTemplate","id":"SiteTemplate.SearchCenter","name":"Enterprise Search Center"},{"kind":"FieldDefinition","id":"Field.RiskProbability","name":"Probability"},{"kind":"FieldDefinition","id":"Field.RiskImpact","name":"Impact"},{"kind":"FieldDefinition","id":"Field.RiskMitigation","name":"MitigationPlan"},{"kind":"FieldDefinition","id":"Field.RiskContingency","name":"ContingencyPlan"},{"kind":"FieldDefinition","id":"Field.RiskTrigger","name":"TriggerDescription"},{"kind":"ContentType","id":"ContentType.Risk","name":"Risk"},{"kind":"SiteTemplate","id":"SiteTemplate.ProjectSite","name":"Project Site"},{"kind":"Feature","id":"Feature.ProjectSiteDefaults","name":"Project site default content"},{"kind":"KnowledgeArticle","id":"KA.HarmlessProbe","name":"KA.HarmlessProbe","description":null,"version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"","tags":[],"source":null},{"kind":"FieldDefinition","id":"F.ActorRole","name":"ActorRole"},{"kind":"FieldDefinition","id":"F.Goal","name":"Goal"},{"kind":"FieldDefinition","id":"F.Backstory","name":"Backstory"},{"kind":"FieldDefinition","id":"F.Provider","name":"Provider"},{"kind":"FieldDefinition","id":"F.ModelId","name":"ModelId"},{"kind":"FieldDefinition","id":"F.MaxIterations","name":"MaxIterations"},{"kind":"FieldDefinition","id":"F.MaxCostUsdPerCall","name":"MaxCostUsdPerCall"},{"kind":"FieldDefinition","id":"F.SkillCatalog","name":"SkillCatalog"},{"kind":"ContentType","id":"ContentType.ActorProfile","name":"ActorProfile"},{"kind":"FieldDefinition","id":"Field.CopilotStatus","name":"CopilotStatus"},{"kind":"FieldDefinition","id":"Field.Owner","name":"Owner"},{"kind":"FieldDefinition","id":"Field.KnowledgeSources","name":"KnowledgeSources"},{"kind":"FieldDefinition","id":"Field.TargetAudiences","name":"TargetAudiences"},{"kind":"FieldDefinition","id":"Field.LastPublished","name":"LastPublished"},{"kind":"FieldDefinition","id":"Field.LastTested","name":"LastTested"},{"kind":"FieldDefinition","id":"Field.ConversationStarters","name":"ConversationStarters"},{"kind":"FieldDefinition","id":"Field.RiskLevel","name":"RiskLevel"},{"kind":"ContentType","id":"ContentType.Copilot","name":"Copilot"},{"kind":"CustomAction","id":"CustomAction.Copilot.Test.DisplayFormToolbar","name":"Test"},{"kind":"CustomAction","id":"CustomAction.Copilot.Test.EditControlBlock","name":"Test"},{"kind":"ActorProfile","id":"Actor.DemoLibrarian","name":"Demo Knowledge Librarian"},{"kind":"ActorProfile","id":"Actor.CompetencyReviewer","name":"Competency Reviewer"},{"kind":"ActorProfile","id":"Actor.TalentMediaSpecialist","name":"Talent Media Specialist"},{"kind":"ActorProfile","id":"Actor.TalentSlideSpecialist","name":"Talent Slide Specialist"},{"kind":"Skill","id":"Skill.CreateAgency","name":"Create Agency","description":"Design a new agency: choose its entry CEO, member operators, comm graph, and pipelines; emit the declarative Agency part.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Management","requiresApproval":false,"capabilities":["Decompose a goal into an org: CEO \u002B roles \u002B comm flows","Reuse existing operators/pipelines before creating new ones"],"requiresTools":["Tool.BuildDivision","Tool.SendMail"]},{"kind":"Skill","id":"Skill.CreateOperator","name":"Create Operator","description":"Define a new operator (ActorProfile): role, goal, backstory, model\u002Bcost, skill catalogue, placement.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Management","requiresApproval":false,"capabilities":["Author an onboarding-ready ActorProfile for a needed seat"],"requiresTools":[]},{"kind":"Skill","id":"Skill.CreatePipeline","name":"Create Pipeline","description":"Define a new production pipeline (Routing): ordered stations bound to catalog machines, with cost \u002B QC.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Management","requiresApproval":false,"capabilities":["Compose a Routing from reusable catalog machines (see /machines)"],"requiresTools":[]},{"kind":"ActorProfile","id":"Actor.GenesisCeo","name":"Genesis CEO"},{"kind":"ActorProfile","id":"Actor.AgencyArchitect","name":"Agency Architect"},{"kind":"ActorProfile","id":"Actor.OperatorSmith","name":"Operator Smith"},{"kind":"ActorProfile","id":"Actor.PipelineWright","name":"Pipeline Wright"},{"kind":"ActorProfile","id":"Actor.PartArchitect","name":"Part Architect"},{"kind":"ActorProfile","id":"Actor.PageSmith","name":"Page Smith"},{"kind":"DecisionTable","id":"DT.AgencyTriage","name":"Agency request triage"},{"kind":"DecisionTable","id":"DT.AutoGenesisPark","name":"AutoGenesis park guard"},{"kind":"SettingScope","id":"Scope.AutoGenesis","name":"AutoGenesis tunables"},{"kind":"Agency","id":"Agency.Genesis","name":"Genesis Agency"},{"kind":"Agency","id":"Agency.Content","name":"Content Agency"},{"kind":"Skill","id":"Skill.ResearchGap","name":"Research a Gap","description":"Take a capability gap and compose a candidate pipeline from existing catalog machines; flag the aspects that need a new machine (code). Reuse-first.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Management","requiresApproval":false,"capabilities":["Compose from existing machines before proposing new code","Name the minimal novel primitive when composition can\u0027t cover the need"],"requiresTools":[]},{"kind":"ActorProfile","id":"Actor.ResearchLead","name":"Research Lead"},{"kind":"Agency","id":"Agency.Research","name":"Research Plant"},{"kind":"ActorProfile","id":"Actor.ResearchEnrichmentLead","name":"Research Enrichment Lead"},{"kind":"Agency","id":"Agency.ResearchEnrichment","name":"Research and Enrichment"},{"kind":"ActorProfile","id":"Actor.WisdomKeeper","name":"Wisdom Keeper"},{"kind":"ActorProfile","id":"Actor.WisdomCurator","name":"Wisdom Curator"},{"kind":"Agency","id":"Agency.Wisdom","name":"Wisdom Library"},{"kind":"ActorProfile","id":"Actor.TrainingMaster","name":"Training Master"},{"kind":"Agency","id":"Agency.Academy","name":"Training Academy"},{"kind":"ActorProfile","id":"Actor.ChiefStrategyOfficer","name":"Chief Strategy Officer"},{"kind":"Agency","id":"Agency.Strategy","name":"Office of Strategy"},{"kind":"SettingScope","id":"Scope.TrainingDrills","name":"Agent training drills"},{"kind":"Agency","id":"Agency.PartsFactory","name":"Parts Factory"},{"kind":"LlmProvider","id":"Provider.Echo","name":"Echo (offline stub)"},{"kind":"LlmProvider","id":"Provider.DeepSeek","name":"Baseten / DeepSeek"},{"kind":"LlmProvider","id":"Provider.DeepSeekDirect","name":"DeepSeek / deepseek-chat"},{"kind":"LlmProvider","id":"Provider.Anthropic","name":"Anthropic / Claude"},{"kind":"LlmProvider","id":"Provider.Jev","name":"TypeSafe / Jev 1.13 (decision model)"},{"kind":"SearchProvider","id":"Search.Exa","name":"Exa"},{"kind":"SearchProvider","id":"Search.Tavily","name":"Tavily"},{"kind":"SearchProvider","id":"Search.Serper","name":"Serper"},{"kind":"Skill","id":"Skill.Viz","name":"Viz (sealed skill)","description":"Sealed from a successful RT-VIZ run (2026-06-10). Reproducible capability over 1 tool(s); produced: ### Page already present: \u0060ship-city\u0060\n\n- Site: IssuesPortal\n- Title: Ship and city (live)\n- Template: \u0060ShipCityViz\u0060\n- List: SitePages (ContentType.Page)\n\nRender\u2026","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Processing","requiresApproval":false,"capabilities":["Run the Viz route: MakePage."],"requiresTools":["Tool.MakePage"]},{"kind":"Feature","id":"Feature.IssueTracker","name":"Issue tracker"},{"kind":"FieldDefinition","id":"Field.IssueId","name":"IssueId"},{"kind":"ContentType","id":"ContentType.IssueComment","name":"Issue Comment"},{"kind":"EventReceiver","id":"ER.OnIssueOpened.ProjectTracker","name":"ProjectTracker: triage new Issue"},{"kind":"SiteTemplate","id":"SiteTemplate.MissionDivision","name":"MissionDivision"},{"kind":"SiteTemplate","id":"SiteTemplate.OnetDemo","name":"OnetDemo"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.ACCSRV-0","name":"Access Services Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.ACCSVC-0","name":"Access Services Site Internal"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.ACCSVC-1","name":"Access Services Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.APP-0","name":"App Template"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.APPCATALOG-0","name":"App Catalog Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.BICenterSite-0","name":"Business Intelligence Center"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.BLANKINTERNET-0","name":"Publishing Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.BLANKINTERNET-1","name":"Press Releases Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.BLANKINTERNET-2","name":"Publishing Site with Workflow"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.BLANKINTERNETCONTAINER-0","name":"Publishing Portal"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.CENTRALADMIN-0","name":"Central Admin Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.CMSPUBLISHING-0","name":"Publishing Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.COMMUNITY-0","name":"Community Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.COMMUNITYPORTAL-0","name":"Community Portal"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.DEV-0","name":"Developer Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.EDISC-0","name":"eDiscovery Center"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.EDISC-1","name":"eDiscovery Case"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.GLOBAL-0","name":"Global template"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.GROUP-0","name":"Group"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.MPS-0","name":"Basic Meeting Workspace"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.MPS-1","name":"Blank Meeting Workspace"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.MPS-2","name":"Decision Meeting Workspace"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.MPS-3","name":"Social Meeting Workspace"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.MPS-4","name":"Multipage Meeting Workspace"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.OFFILE-0","name":"(obsolete) Records Center"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.OSRV-0","name":"Shared Services Administration Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.POINTPUBLISHINGHUB-0","name":"PointPublishing Hub"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.POINTPUBLISHINGPERSONAL-0","name":"PointPublishing Personal"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.POINTPUBLISHINGTOPIC-0","name":"PointPublishing Topic"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.POLICYCTR-0","name":"Compliance Policy Center"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.PPSMASite-0","name":"PerformancePoint"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.PROFILES-0","name":"Profiles"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.PWA-0","name":"Project Web App Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.PWS-0","name":"Microsoft Project Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SGS-0","name":"Group Work Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SITEPAGEPUBLISHING-0","name":"Communication site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPS-0","name":"SharePoint Portal Server Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSCOMMU-0","name":"Community area template"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSMSITE-0","name":"Personalization Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSMSITEHOST-0","name":"My Site Host"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSNEWS-0","name":"News Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSNHOME-0","name":"News Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSPERS-2","name":"Storage And Social SharePoint Portal Server Personal Space"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSPERS-3","name":"Storage Only SharePoint Portal Server Personal Space"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSPERS-4","name":"Social Only SharePoint Portal Server Personal Space"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSPERS-5","name":"Empty SharePoint Portal Server Personal Space"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSPERS-6","name":"Storage And Social SharePoint Portal Server Personal Space"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSPERS-7","name":"Storage And Social SharePoint Portal Server Personal Space"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSPERS-8","name":"Storage And Social SharePoint Portal Server Personal Space"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSPERS-9","name":"Storage And Social SharePoint Portal Server Personal Space"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSPERS-10","name":"Storage And Social SharePoint Portal Server Personal Space"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSPORTAL-0","name":"Collaboration Portal"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSREPORTCENTER-0","name":"Report Center"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSSITES-0","name":"Site Directory"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSTOC-0","name":"Contents area Template"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SPSTOPIC-0","name":"Topic area template"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SRCHCENTERLITE-0","name":"Basic Search Center"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.SRCHCENTERLITE-1","name":"Basic Search Center"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.STS-1","name":"Blank Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.STS-2","name":"Document Workspace"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.STS-3","name":"Team site (no Office 365 group)"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.TBH-0","name":"In-Place Hold Policy Center"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.TENANTADMIN-0","name":"Tenant Admin Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.visprus-0","name":"Visio Process Repository"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.WIKI-0","name":"Wiki Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-1","name":"Budgeting and Tracking Multiple Projects"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-2","name":"Bug Database"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-3","name":"Call Center"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-4","name":"Change Request Management"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-5","name":"Compliance Process Support Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-6","name":"Contacts Management"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-8","name":"Event Planning"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-9","name":"Expense Reimbursement and Approval"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-12","name":"IT Team Workspace"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-13","name":"Job Requisition and Interview Management"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-14","name":"Knowledge Base"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-15","name":"Lending Library"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-16","name":"Physical Asset Tracking and Management"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-17","name":"Project Tracking Workspace"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-18","name":"Room and Equipment Reservations"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-19","name":"Sales Lead Pipeline"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-20","name":"Board of Directors"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-21","name":"Business Performance Reporting"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-22","name":"Case Management for Government Agencies"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-23","name":"Classroom Management"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-24","name":"Clinical Trial Initiation and Management"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-25","name":"Competitive Analysis Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-26","name":"Discussion Database"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-27","name":"Disputed Invoice Management"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-28","name":"Employee Activities Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-29","name":"Employee Self-Service Benefits"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-30","name":"Employee Training Scheduling and Materials"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-31","name":"Equity Research"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-32","name":"Integrated Marketing Campaign Tracking"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-33","name":"Manufacturing Process Management"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-34","name":"New Store Opening"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-35","name":"Product and Marketing Requirements Planning"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-36","name":"Request for Proposal"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-37","name":"Sports League"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-38","name":"Team Work Site"},{"kind":"SiteTemplate","id":"SiteTemplate.WebTemp.FAB40-39","name":"Timecard Management"},{"kind":"FieldDefinition","id":"Field.CurrencyCode","name":"Code"},{"kind":"FieldDefinition","id":"Field.CurrencySymbol","name":"Symbol"},{"kind":"FieldDefinition","id":"Field.CurrencyMinorUnit","name":"MinorUnit"},{"kind":"FieldDefinition","id":"Field.CurrencyIsoNumeric","name":"IsoNumeric"},{"kind":"FieldDefinition","id":"Field.CountryAlpha2","name":"Alpha2"},{"kind":"FieldDefinition","id":"Field.CountryAlpha3","name":"Alpha3"},{"kind":"FieldDefinition","id":"Field.CountryIsoNumeric","name":"IsoNumeric"},{"kind":"FieldDefinition","id":"Field.CountryEuMember","name":"EuMember"},{"kind":"FieldDefinition","id":"Field.CountryDefaultCurrencyCode","name":"DefaultCurrencyCode"},{"kind":"FieldDefinition","id":"Field.LanguageAlpha2","name":"Alpha2"},{"kind":"FieldDefinition","id":"Field.LanguageAlpha3","name":"Alpha3"},{"kind":"FieldDefinition","id":"Field.LanguageNativeName","name":"NativeName"},{"kind":"FieldDefinition","id":"Field.UomCode","name":"Code"},{"kind":"FieldDefinition","id":"Field.UomCategory","name":"Category"},{"kind":"FieldDefinition","id":"Field.UomBaseCode","name":"BaseCode"},{"kind":"FieldDefinition","id":"Field.UomFactor","name":"Factor"},{"kind":"FieldDefinition","id":"Field.AccountTypeCode","name":"Code"},{"kind":"FieldDefinition","id":"Field.AccountTypeCategory","name":"Category"},{"kind":"FieldDefinition","id":"Field.AccountTypeNormalBalance","name":"NormalBalance"},{"kind":"FieldDefinition","id":"Field.PaymentTermCode","name":"Code"},{"kind":"FieldDefinition","id":"Field.PaymentTermNetDays","name":"NetDays"},{"kind":"FieldDefinition","id":"Field.PaymentTermDiscountPct","name":"DiscountPercent"},{"kind":"FieldDefinition","id":"Field.PaymentTermDiscountDays","name":"DiscountDays"},{"kind":"FieldDefinition","id":"Field.BusinessPartnerRoleCode","name":"Code"},{"kind":"ContentType","id":"ContentType.Currency","name":"Currency"},{"kind":"ContentType","id":"ContentType.Country","name":"Country"},{"kind":"ContentType","id":"ContentType.Language","name":"Language"},{"kind":"ContentType","id":"ContentType.UnitOfMeasure","name":"Unit Of Measure"},{"kind":"ContentType","id":"ContentType.AccountType","name":"Account Type"},{"kind":"ContentType","id":"ContentType.PaymentTerm","name":"Payment Term"},{"kind":"ContentType","id":"ContentType.BusinessPartnerRole","name":"Business Partner Role"},{"kind":"ListTemplate","id":"ListTemplate.Currencies","name":"Currencies"},{"kind":"ListTemplate","id":"ListTemplate.Countries","name":"Countries"},{"kind":"ListTemplate","id":"ListTemplate.Languages","name":"Languages"},{"kind":"ListTemplate","id":"ListTemplate.UnitsOfMeasure","name":"Units Of Measure"},{"kind":"ListTemplate","id":"ListTemplate.AccountTypes","name":"Account Types"},{"kind":"ListTemplate","id":"ListTemplate.PaymentTerms","name":"Payment Terms"},{"kind":"ListTemplate","id":"ListTemplate.BusinessPartnerRoles","name":"Business Partner Roles"},{"kind":"KnowledgeArticle","id":"KB.Tc.Standards","name":"Tc package: standards adopted at V12.0a","description":"Which world-standard taxonomies the Common master-data package adopts and where each lookup field binds.","version":"1.0.0","classification":"Public","minimumRole":"Assistant","body":"STANDARDS ADOPTED:\n\n  ISO 4217        - Currency codes (USD, EUR, JPY, ...) - ContentType.Currency, list \u0022Common/Currencies\u0022.\n  ISO 3166-1      - Country codes (US, BE, NL, ...)     - ContentType.Country, list \u0022Common/Countries\u0022.\n  ISO 639-1       - Language codes (en, nl, fr, ...)    - ContentType.Language, list \u0022Common/Languages\u0022.\n  UN/CEFACT Rec 20 - Unit-of-measure codes (KGM, MTR, PCE, ...) - ContentType.UnitOfMeasure, list \u0022Common/UnitsOfMeasure\u0022.\n  GAAP / IFRS     - Account-type root categories         - ContentType.AccountType, list \u0022Common/AccountTypes\u0022.\n\n  PLATFORM-DEFINED:\n\n  PaymentTerm     - NET30 / 2-10-NET30 / COD / PREPAID  - list \u0022Common/PaymentTerms\u0022.\n  BusinessPartnerRole - CUSTOMER / SUPPLIER / CARRIER / BANK / TAX / EMPLOYEE - list \u0022Common/BusinessPartnerRoles\u0022.\n\n  WHY EACH CHOICE:\n  ISO 4217 currency codes are the de-facto standard everywhere SWIFT/banking touches; downstream UBL invoices need the alpha-3 code.\n  ISO 3166-1 country alpha-2 is what most APIs accept; EuMember flag drives VAT and PEPPOL routing.\n  ISO 639-1 covers the 184 living languages most platforms need; the alpha-2 is what content-language headers use.\n  UN/CEFACT Rec 20 is the standard CEFACT/UNECE codes for trade documents; aligns with UBL InvoiceLine quantity unit codes.\n  GAAP/IFRS five-category root is the common ground between national accounting standards; jurisdiction-specific refinements layer as child rows on ContentType.ChartOfAccount.\n\n  EXTENSION PATH: when a downstream module needs richer rows (e.g., UNSPSC item classification at lower levels), add another typed ContentType.Term subclass in the appropriate Tc-or-module package; do not invent parallel lookup tables.","tags":["foundation","taxonomy","standards","iso","v12.0a"],"source":"SPICE.Apps.Erp.Tc/Parts.Tc.xml"},{"kind":"FieldDefinition","id":"Field.BpLei","name":"Lei"},{"kind":"FieldDefinition","id":"Field.BpGln","name":"Gln"},{"kind":"FieldDefinition","id":"Field.BpVatNumber","name":"VatNumber"},{"kind":"FieldDefinition","id":"Field.BpRoleCode","name":"RoleCode"},{"kind":"FieldDefinition","id":"Field.BpCountryCode","name":"CountryCode"},{"kind":"FieldDefinition","id":"Field.BpDefaultCurrencyCode","name":"DefaultCurrencyCode"},{"kind":"FieldDefinition","id":"Field.BpDefaultPaymentTermCode","name":"DefaultPaymentTermCode"},{"kind":"FieldDefinition","id":"Field.BpSku","name":"Sku"},{"kind":"FieldDefinition","id":"Field.ItemSku","name":"Sku"},{"kind":"FieldDefinition","id":"Field.ItemUnspscCode","name":"UnspscCode"},{"kind":"FieldDefinition","id":"Field.ItemUomCode","name":"UomCode"},{"kind":"FieldDefinition","id":"Field.ItemDefaultUnitCost","name":"DefaultUnitCost"},{"kind":"FieldDefinition","id":"Field.ItemDefaultCurrencyCode","name":"DefaultCurrencyCode"},{"kind":"FieldDefinition","id":"Field.AddressStreet","name":"Street"},{"kind":"FieldDefinition","id":"Field.AddressCity","name":"City"},{"kind":"FieldDefinition","id":"Field.AddressPostalCode","name":"PostalCode"},{"kind":"FieldDefinition","id":"Field.AddressRegion","name":"Region"},{"kind":"FieldDefinition","id":"Field.AddressCountryCode","name":"CountryCode"},{"kind":"FieldDefinition","id":"Field.AddressType","name":"AddressType"},{"kind":"FieldDefinition","id":"Field.AddressBusinessPartnerSku","name":"BusinessPartnerSku"},{"kind":"FieldDefinition","id":"Field.BankAccountIban","name":"Iban"},{"kind":"FieldDefinition","id":"Field.BankAccountBic","name":"Bic"},{"kind":"FieldDefinition","id":"Field.BankAccountBpSku","name":"BusinessPartnerSku"},{"kind":"FieldDefinition","id":"Field.BankAccountCurrencyCode","name":"CurrencyCode"},{"kind":"FieldDefinition","id":"Field.RateFromCurrencyCode","name":"FromCurrencyCode"},{"kind":"FieldDefinition","id":"Field.RateToCurrencyCode","name":"ToCurrencyCode"},{"kind":"FieldDefinition","id":"Field.RateEffectiveDate","name":"EffectiveDate"},{"kind":"FieldDefinition","id":"Field.RateValue","name":"Rate"},{"kind":"FieldDefinition","id":"Field.AccountCode","name":"AccountCode"},{"kind":"FieldDefinition","id":"Field.AccountTypeCodeRef","name":"AccountTypeCode"},{"kind":"FieldDefinition","id":"Field.AccountParentCode","name":"ParentAccountCode"},{"kind":"ContentType","id":"ContentType.BusinessPartner","name":"Business Partner"},{"kind":"ContentType","id":"ContentType.MasterItem","name":"Master Item"},{"kind":"ContentType","id":"ContentType.Address","name":"Address"},{"kind":"ContentType","id":"ContentType.BankAccount","name":"Bank Account"},{"kind":"ContentType","id":"ContentType.ExchangeRate","name":"Exchange Rate"},{"kind":"ContentType","id":"ContentType.ChartOfAccount","name":"Chart of Account"},{"kind":"ListTemplate","id":"ListTemplate.BusinessPartners","name":"Business Partners"},{"kind":"ListTemplate","id":"ListTemplate.Items","name":"Items"},{"kind":"ListTemplate","id":"ListTemplate.Addresses","name":"Addresses"},{"kind":"ListTemplate","id":"ListTemplate.BankAccounts","name":"Bank Accounts"},{"kind":"ListTemplate","id":"ListTemplate.ExchangeRates","name":"Exchange Rates"},{"kind":"ListTemplate","id":"ListTemplate.ChartOfAccounts","name":"Chart of Accounts"},{"kind":"KnowledgeArticle","id":"KB.Tc.MasterData","name":"Tc package: V12.1 master-data shapes","description":"Which V12.1 ContentTypes exist for foundational master data, what well-known identifiers each carries, and how operational modules layer on top.","version":"1.0.0","classification":"Public","minimumRole":"Assistant","body":"V12.1 SHIPS 6 MASTER-DATA CONTENT TYPES.  Each is a typed-XML record validated through IContentTypeResolver and stored as one row per Sku/Code/Key on a list under Common.\n\n  ContentType.BusinessPartner      list \u0022Common/BusinessPartners\u0022\n    Globally-unique business partner (Customer/Supplier/Carrier/Bank/Tax/Employee).\n    Well-known identifiers: LEI (ISO 17442), GLN (GS1), VAT number.\n    Lookups: RoleCode -\u003E BusinessPartnerRoles; CountryCode -\u003E Countries;\n             DefaultCurrencyCode -\u003E Currencies; DefaultPaymentTermCode -\u003E PaymentTerms.\n\n  ContentType.Item                 list \u0022Common/Items\u0022\n    Master-data Item (SKU \u002B classification \u002B UoM).\n    Well-known identifiers: UNSPSC (United Nations Standard Products and Services Code).\n    Lookups: UomCode -\u003E UnitsOfMeasure; DefaultCurrencyCode -\u003E Currencies.\n\n  ContentType.Address              list \u0022Common/Addresses\u0022\n    Postal address linked to a BusinessPartner via Sku.\n    Well-known shape: ISO 19160 postal-address fields (Street/City/PostalCode/Region/Country).\n    Lookups: CountryCode -\u003E Countries.\n\n  ContentType.BankAccount          list \u0022Common/BankAccounts\u0022\n    Bank account on a BusinessPartner (Iban \u002B Bic \u002B Currency).\n    Well-known identifiers: ISO 13616 IBAN, ISO 9362 BIC.\n    Lookups: CurrencyCode -\u003E Currencies.\n\n  ContentType.ExchangeRate         list \u0022Common/ExchangeRates\u0022\n    Effective-dated currency conversion rate.\n    Lookups: FromCurrencyCode \u002B ToCurrencyCode -\u003E Currencies.\n\n  ContentType.ChartOfAccount       list \u0022Common/ChartOfAccounts\u0022\n    Hierarchical accounting code mapped to a GAAP root category.\n    Lookups: AccountTypeCode -\u003E AccountTypes.  Self-ref via ParentAccountCode for hierarchy.\n\nWHAT V12.1 DELIBERATELY EXCLUDES (queued for downstream-module cycles):\n\n  - FiscalCalendar.  Year / Period / StartDate / EndDate / Status.  Layered in V12.5 (Tf Finance) because period-close is a Tf concern.\n  - TaxCategory \u002B TaxRate.  Country-specific; layered in V12.5 alongside FiscalCalendar.\n  - UNSPSC tree beyond top 2 levels.  V12.0a seeded only the segment\u002Bfamily levels (~3000 rows at full coverage); deeper levels load via operator action or a future Connector to a UNSPSC source.\n\nWHY EACH WELL-KNOWN ID IS REQUIRED VS OPTIONAL:\n\n  LEI required on a BusinessPartner that transacts in regulated financial flows; optional for internal-only roles (Employee, internal cost centre).  Platform doesn\u0027t enforce - field is optional in the XSD and the resolver flags as Warning, not Error, when absent.\n\n  GLN optional - mostly relevant for logistics (Carrier role) and large retail Supplier chains; not every BusinessPartner has one.\n\n  IBAN required on BankAccount but only Member-role-readable per the field\u0027s Confidential classification - cross-module accounting joins via BusinessPartnerSku join key, not by exposing the IBAN.\n\n  VAT number context-required: EU B2B invoices need it on Customer \u002B Supplier rows; the country prefix MUST match the BusinessPartner\u0027s CountryRef.  Not platform-enforced today; queued for V12.5 when invoicing ships.\n\nDOWNSTREAM MODULE EXTENSION RECIPE:\n\n  Operational ContentTypes (V12.3\u002B SalesOrder, ProductionOrder, PurchaseOrder, Invoice, etc.) reference these masters via two patterns:\n\n    (1) Parent inheritance: ContentType.SalesOrderHeader can derive from ContentType.Item then add SalesOrder-specific fields \u002B a Transitions block for status workflow.\n    (2) Direct Lookup: a SalesOrderHeader.CustomerSku Lookup field binds to Common/BusinessPartners; the resolver renders the partner\u0027s Title in dropdowns \u002B form views.\n\n  Pattern (2) is the more common - inheritance is reserved for ContentTypes that genuinely extend the master\u0027s shape (e.g. a \u0022ContentType.PreferredSupplier\u0022 that inherits BusinessPartner and adds a PriorityScore field).","tags":["foundation","master-data","tc","v12.1"],"source":"SPICE.Apps.Erp.Tc/Parts.Tc.xml"},{"kind":"FieldDefinition","id":"Field.FpYear","name":"Year"},{"kind":"FieldDefinition","id":"Field.FpPeriodNumber","name":"PeriodNumber"},{"kind":"FieldDefinition","id":"Field.FpStartDate","name":"StartDate"},{"kind":"FieldDefinition","id":"Field.FpEndDate","name":"EndDate"},{"kind":"FieldDefinition","id":"Field.FpStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.TaxCode","name":"Code"},{"kind":"FieldDefinition","id":"Field.TaxRate","name":"Rate"},{"kind":"FieldDefinition","id":"Field.TaxJurisdictionCountryCode","name":"JurisdictionCountryCode"},{"kind":"FieldDefinition","id":"Field.TaxDescription","name":"Description"},{"kind":"ContentType","id":"ContentType.FiscalPeriod","name":"Fiscal Period"},{"kind":"ContentType","id":"ContentType.TaxCategory","name":"Tax Category"},{"kind":"ListTemplate","id":"ListTemplate.FiscalPeriods","name":"Fiscal Periods"},{"kind":"ListTemplate","id":"ListTemplate.TaxCategories","name":"Tax Categories"},{"kind":"FieldDefinition","id":"Field.LeadSku","name":"LeadSku"},{"kind":"FieldDefinition","id":"Field.LeadName","name":"LeadName"},{"kind":"FieldDefinition","id":"Field.LeadEmail","name":"Email"},{"kind":"FieldDefinition","id":"Field.LeadPhone","name":"Phone"},{"kind":"FieldDefinition","id":"Field.LeadIndustry","name":"Industry"},{"kind":"FieldDefinition","id":"Field.LeadSource","name":"Source"},{"kind":"FieldDefinition","id":"Field.LeadScore","name":"Score"},{"kind":"FieldDefinition","id":"Field.LeadStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.LeadAssigneeSku","name":"AssigneeSku"},{"kind":"FieldDefinition","id":"Field.LeadPartySku","name":"PartySku"},{"kind":"FieldDefinition","id":"Field.LeadCampaignSku","name":"CampaignSku"},{"kind":"FieldDefinition","id":"Field.LeadSubmittedByExternal","name":"SubmittedByExternal"},{"kind":"FieldDefinition","id":"Field.LeadSubmittedQuoteAmount","name":"SubmittedQuoteAmount"},{"kind":"FieldDefinition","id":"Field.LeadInternalNotes","name":"InternalNotes"},{"kind":"FieldDefinition","id":"Field.OppOpportunityCode","name":"OpportunityCode"},{"kind":"FieldDefinition","id":"Field.OppPartySku","name":"PartySku"},{"kind":"FieldDefinition","id":"Field.OppOwnerSku","name":"OwnerSku"},{"kind":"FieldDefinition","id":"Field.OppAmount","name":"Amount"},{"kind":"FieldDefinition","id":"Field.OppCurrencyCode","name":"CurrencyCode"},{"kind":"FieldDefinition","id":"Field.OppExpectedCloseDate","name":"ExpectedCloseDate"},{"kind":"FieldDefinition","id":"Field.OppProbabilityPct","name":"ProbabilityPct"},{"kind":"FieldDefinition","id":"Field.OppLeadSku","name":"LeadSku"},{"kind":"FieldDefinition","id":"Field.OppCampaignSku","name":"CampaignSku"},{"kind":"FieldDefinition","id":"Field.OppStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.OppLostReason","name":"LostReason"},{"kind":"FieldDefinition","id":"Field.OppCurrentQuoteNumber","name":"CurrentQuoteNumber"},{"kind":"FieldDefinition","id":"Field.ActActivityCode","name":"ActivityCode"},{"kind":"FieldDefinition","id":"Field.ActSubject","name":"Subject"},{"kind":"FieldDefinition","id":"Field.ActKind","name":"Kind"},{"kind":"FieldDefinition","id":"Field.ActPartySku","name":"PartySku"},{"kind":"FieldDefinition","id":"Field.ActLeadSku","name":"LeadSku"},{"kind":"FieldDefinition","id":"Field.ActOpportunityCode","name":"OpportunityCode"},{"kind":"FieldDefinition","id":"Field.ActAssigneeSku","name":"AssigneeSku"},{"kind":"FieldDefinition","id":"Field.ActDueDate","name":"DueDate"},{"kind":"FieldDefinition","id":"Field.ActStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.ActNotes","name":"Notes"},{"kind":"FieldDefinition","id":"Field.CamCampaignSku","name":"CampaignSku"},{"kind":"FieldDefinition","id":"Field.CamName","name":"Name"},{"kind":"FieldDefinition","id":"Field.CamChannel","name":"Channel"},{"kind":"FieldDefinition","id":"Field.CamStartDate","name":"StartDate"},{"kind":"FieldDefinition","id":"Field.CamEndDate","name":"EndDate"},{"kind":"FieldDefinition","id":"Field.CamBudgetAmount","name":"BudgetAmount"},{"kind":"FieldDefinition","id":"Field.CamCurrencyCode","name":"CurrencyCode"},{"kind":"FieldDefinition","id":"Field.CamNotes","name":"Notes"},{"kind":"FieldDefinition","id":"Field.QteQuoteNumber","name":"QuoteNumber"},{"kind":"FieldDefinition","id":"Field.QteOpportunityCode","name":"OpportunityCode"},{"kind":"FieldDefinition","id":"Field.QtePartySku","name":"PartySku"},{"kind":"FieldDefinition","id":"Field.QteAmount","name":"Amount"},{"kind":"FieldDefinition","id":"Field.QteCurrencyCode","name":"CurrencyCode"},{"kind":"FieldDefinition","id":"Field.QteValidUntil","name":"ValidUntil"},{"kind":"FieldDefinition","id":"Field.QteStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.QteNotes","name":"Notes"},{"kind":"FieldDefinition","id":"Field.QtlQuoteNumber","name":"QuoteNumber"},{"kind":"FieldDefinition","id":"Field.QtlLineNumber","name":"LineNumber"},{"kind":"FieldDefinition","id":"Field.QtlItemSku","name":"ItemSku"},{"kind":"FieldDefinition","id":"Field.QtlDescription","name":"Description"},{"kind":"FieldDefinition","id":"Field.QtlQuantity","name":"Quantity"},{"kind":"FieldDefinition","id":"Field.QtlUnitPrice","name":"UnitPrice"},{"kind":"FieldDefinition","id":"Field.QtlLineExtensionAmount","name":"LineExtensionAmount"},{"kind":"FieldDefinition","id":"Field.ClgLogId","name":"LogId"},{"kind":"FieldDefinition","id":"Field.ClgPartySku","name":"PartySku"},{"kind":"FieldDefinition","id":"Field.ClgDirection","name":"Direction"},{"kind":"FieldDefinition","id":"Field.ClgChannel","name":"Channel"},{"kind":"FieldDefinition","id":"Field.ClgTimestampUtc","name":"TimestampUtc"},{"kind":"FieldDefinition","id":"Field.ClgBody","name":"Body"},{"kind":"FieldDefinition","id":"Field.PrelFromPartySku","name":"FromPartySku"},{"kind":"FieldDefinition","id":"Field.PrelToPartySku","name":"ToPartySku"},{"kind":"FieldDefinition","id":"Field.PrelKind","name":"Kind"},{"kind":"FieldDefinition","id":"Field.PrelNotes","name":"Notes"},{"kind":"ContentType","id":"ContentType.Lead","name":"Lead"},{"kind":"ContentType","id":"ContentType.Opportunity","name":"Opportunity"},{"kind":"ContentType","id":"ContentType.Activity","name":"Activity"},{"kind":"ContentType","id":"ContentType.Campaign","name":"Campaign"},{"kind":"ContentType","id":"ContentType.Quote","name":"Quote"},{"kind":"ContentType","id":"ContentType.QuoteLine","name":"Quote Line"},{"kind":"ContentType","id":"ContentType.CommunicationLog","name":"Communication Log"},{"kind":"ContentType","id":"ContentType.PartyRelationship","name":"Party Relationship"},{"kind":"ListTemplate","id":"ListTemplate.Leads","name":"Leads"},{"kind":"ListTemplate","id":"ListTemplate.Opportunities","name":"Opportunities"},{"kind":"ListTemplate","id":"ListTemplate.Activities","name":"Activities"},{"kind":"ListTemplate","id":"ListTemplate.Campaigns","name":"Campaigns"},{"kind":"ListTemplate","id":"ListTemplate.Quotes","name":"Quotes"},{"kind":"ListTemplate","id":"ListTemplate.QuoteLines","name":"Quote Lines"},{"kind":"ListTemplate","id":"ListTemplate.CommunicationLogs","name":"Communication Logs"},{"kind":"ListTemplate","id":"ListTemplate.PartyRelationships","name":"Party Relationships"},{"kind":"FieldDefinition","id":"Field.LscLeadSku","name":"LeadSku"},{"kind":"FieldDefinition","id":"Field.LscSource","name":"Source"},{"kind":"FieldDefinition","id":"Field.LscIndustry","name":"Industry"},{"kind":"FieldDefinition","id":"Field.LscScoreBucket","name":"ScoreBucket"},{"kind":"FieldDefinition","id":"Field.LscScoreValue","name":"ScoreValue"},{"kind":"FieldDefinition","id":"Field.LscScoredAt","name":"ScoredAt"},{"kind":"FieldDefinition","id":"Field.LscDecisionTableId","name":"DecisionTableId"},{"kind":"ContentType","id":"ContentType.LeadScore","name":"Lead Score"},{"kind":"ListTemplate","id":"ListTemplate.LeadScores","name":"Lead Scores"},{"kind":"DecisionTable","id":"DT.Tcm.LeadScore","name":"Lead score classification"},{"kind":"CrossModuleRule","id":"Rule.Crm.LeadQualifiedScored","name":"Lead Qualified -\u003E LeadScore projection via DT.Tcm.LeadScore"},{"kind":"Phase","id":"Phase.IssueOpportunity","name":"Issue OASIS CIQ Party (Opportunity intake)"},{"kind":"KnowledgeArticle","id":"KB.Tcm.Overview","name":"Tcm package: Customer Management overview - the N=6 receipt","description":"What V14.5 ships, why CRM as a dedicated package on top of V12.0a Tc masters, and how the portal-ready hooks unblock V15\u002B external client portal \u002B subscription work.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"V14.5 SHIPS the N=6 receipt: Td (V12.4) \u002B Tf (V12.6) \u002B Ti (V12.7) \u002B Tp (V12.8) \u002B Tm (V14.1) \u002B Tcm (this cycle) all live on the same V12.0 foundation \u002B V12.0a Tc masters with zero per-module C# beyond the empty AppModuleBase subclass.\n\nWHY TCM (vs extending Tc):\n\n  Tc (Common) is the master-data substrate: BusinessPartner, Address, Currency, ItemMaster, etc.  Reference data that every other module looks up.  Putting workflow CTs (Lead, Opportunity, Activity, Quote) into Tc would invert that dependency direction - Tc would contain operational rows instead of being looked up by operational rows.  Tcm sits on top of Tc as a separate operational module, mirroring Td/Tf/Ti/Tp/Tm.  The Sales/CRM team gets their own SiteBlueprint (CrmPortal) without polluting the common-master site.\n\nSEVEN CONTENT TYPES:\n\n  ContentType.Lead              list \u0027Crm/Leads\u0027\n    Status: New -\u003E Contacted -\u003E Qualified -\u003E Converted/Disqualified.\n    V15 hooks: SubmittedByExternal (Bool), PartySku Lookup, Classification split.\n\n  ContentType.Opportunity       list \u0027Crm/Opportunities\u0027\n    Status: Identified -\u003E Qualified -\u003E Proposal -\u003E Negotiation -\u003E Won/Lost.\n    PartySku Lookup to Common/BusinessPartners (Customer).\n    V14.6 candidate: Opportunity.Won -\u003E Td.SalesOrder via CrossModuleRule.\n\n  ContentType.Activity          list \u0027Crm/Activities\u0027\n    Status: Planned -\u003E InProgress -\u003E Done/Cancelled.\n    Kind: Call/Email/Meeting/Task/Note.\n    Cross-refs: Activity-on-Lead, Activity-on-Opportunity, Activity-on-Party.\n\n  ContentType.Campaign          list \u0027Crm/Campaigns\u0027\n    No Transitions - campaigns are date-bound (StartDate/EndDate).\n    Lead.CampaignSku \u002B Opportunity.CampaignSku attribute attribution.\n\n  ContentType.Quote             list \u0027Crm/Quotes\u0027\n    Status: Draft -\u003E Sent -\u003E Accepted/Rejected/Expired.\n    Cross-ref to parent Opportunity.\n\n  ContentType.CommunicationLog  list \u0027Crm/CommunicationLogs\u0027\n    No Transitions - immutable append-only log.\n    Direction: Inbound/Outbound; Channel: Email/Phone/SMS/InPerson/Other.\n\n  ContentType.PartyRelationship list \u0027Crm/PartyRelationships\u0027\n    No Transitions - relationships are state.\n    Kind: ParentOf/SubsidiaryOf/Influencer/Partner/Competitor (xPRL-aligned).\n\nPORTAL-READY HOOKS (V15\u002B external client portal):\n\n  Every workflow CT carries PartySku (Lookup to Common/BusinessPartners) so V15\n  portal can scope \u0027show me only rows where PartySku = current customer\u0027 without\n  retrofitting the data model.\n\n  Lead.SubmittedByExternal (Boolean) flags web-form intake.  Future PublicForm\n  part type \u002B magic-link auth plugin sets this true on anonymous submissions;\n  ACL surfaces only operator-approved leads on the public portal.\n\n  Per-field Classification deliberately set:\n    Public:        LeadName, LeadEmail, LeadPhone, LeadSubmittedQuoteAmount,\n                   OppAmount, OppPartySku, QuoteAmount, etc.\n    Internal:      LeadScore, ActivityNotes, CampaignBudgetAmount, etc.\n    Confidential:  Lead.InternalNotes, Opportunity.LostReason, etc.\n\n  V15 client portal honors classification automatically: only Public fields\n  appear on the customer\u0027s portal view; Internal/Confidential stay\n  operator-only.  No code change required at portal cycle time.\n\nCROSS-MODULE QUEUED (V14.6 candidates):\n\n  - Rule.Tcm.OpportunityWon -\u003E Td.SalesOrder draft (the canonical CRM-to-ERP\n    handoff).  Either duplicate per portal or generalize CrossModuleRule.Match\n    to accept multiple Dept/List tuples.\n  - Rule.Tcm.QuoteSent -\u003E Activity follow-up reminder (Schedule cron 3 days\n    after Sent).\n  - Rule.Tcm.LeadConverted -\u003E Opportunity draft creation.\n\nFUTURE PACKAGES (V15\u002B):\n\n  - SPICE.Apps.Erp.Tsub (Subscriptions): Plan, Subscription, BillingCycle,\n    UsageRecord.  Recurring-invoice generation via CrossModuleRule Schedule.\n    Stripe Subscriptions / Chargebee / Zuora shape.\n  - SPICE.Plugins.Auth.MagicLink \u002B \u003CPublicForm/\u003E part type: external client\n    portal infrastructure.  Per-customer ACL based on PartySku.","tags":["v14.5","tcm","crm","n6-receipt","portal-ready"],"source":"SPICE.Apps.Erp.Tcm/Parts.Tcm.xml"},{"kind":"KnowledgeArticle","id":"KB.Tcm.OasisCiqMapping","name":"Tcm: OASIS CIQ standards mapping (xPIL / xPRL / xNAL anchor)","description":"How V14.5 Tcm CTs map to the OASIS Customer Information Quality v3.0 family.  Standards anchor for future XSD vendoring \u002B PEPPOL-equivalent partner-master interop.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"OASIS Customer Information Quality (CIQ) v3.0 is the canonical XML/XSD family for CRM-shaped data.  SPICE Tcm anchors its design on CIQ so future cycles can vendor the XSDs (V14.5b candidate) and claim standards-conformance by construction - the same shape V12.6b earned for UBL-aligned invoices.\n\nOASIS CIQ MEMBERS (renamed in v3.0):\n\n  xNL  (eXtensible Name Language)            - person/organization names\n  xAL  (eXtensible Address Language)         - postal addresses (ISO 19160-aligned)\n  xNAL (eXtensible Name and Address Language) - xNL \u002B xAL composed\n  xPIL (eXtensible Party Information Language, formerly xCIL)\n       - party as customer: contacts, communications, account refs\n  xPRL (eXtensible Party Relationships Language, formerly xCRL)\n       - account-contact-lead-opportunity cross-links\n\nSPICE MAPPING:\n\n  CIQ standard          SPICE ContentType            Where it lives\n  ----------------------------------------------------------------------------\n  xPIL (Party Info)     ContentType.BusinessPartner  V12.0a Tc/BusinessPartners\n                        ContentType.Lead             V14.5 Tcm/Leads\n                        ContentType.Opportunity      V14.5 Tcm/Opportunities\n\n  xAL  (Address)        ContentType.Address          V12.0a Tc/Addresses\n\n  xNL  (Name)           Field.LeadName (V14.5 single Text; future decompose\n                        into FirstName/LastName/OrganizationName when receipts\n                        justify - probably V14.5b or V15)\n\n  xPRL (Relationships)  ContentType.PartyRelationship V14.5 Tcm/PartyRelationships\n                        (Kind enum: ParentOf/SubsidiaryOf/Influencer/Partner/\n                        Competitor matches xPRL relationship-type-code vocab)\n\nVENDORING POSTURE (V14.5 -\u003E V15.3 SHIPPED):\n\n  V14.5 shipped the MAPPING (this KB) without vendoring the XSDs.  V15.3\n  closes the loop by vendoring OASIS CIQ v3.0 cs02 XSDs into\n  SPICE.Apps.Erp.Tcm/Schemas/OASIS-CIQ-v3/ and wiring Phase.IssueOpportunity\n  with OutputSchema=\u0022Schemas/OASIS-CIQ-v3/xPIL.xsd\u0022.\n\n  Vendored XSD set (10 files, ~200 KB total):\n    CommonTypes.xsd           - shared CIQ-wide types\n    xlink-2003-12-31.xsd      - W3C XLink (CIQ uses for relationship hrefs)\n    xNL.xsd  \u002B xNL-types.xsd  - Names\n    xAL.xsd  \u002B xAL-types.xsd  - Addresses\n    xNAL.xsd \u002B xNAL-types.xsd - composed Name\u002BAddress\n    xPIL.xsd \u002B xPIL-types.xsd - Party Information (top of the stack)\n\n  **Note on xPRL:** OASIS CIQ v3.0 cs02 did NOT ship a standalone xPRL XSD.\n  The historical xPRL \u0022Party Relationships Language\u0022 (v2 and earlier)\n  was folded INTO xPIL: relationships now live as PartyRelationships /\n  PartyRelationship sub-elements inside xPIL.xsd.  ContentType.PartyRelationship\n  still maps cleanly to the xPIL party-relationship sub-shape (Kind enum\n  matches xPIL\u0027s RelationshipType vocabulary), and the validation rail\n  catches structural deviations identically.  The V14.5 KB\u0027s reference to\n  xPRL as a separate XSD is retained as historical anchoring; tagging\n  preserves searchability for anyone landing here from CIQ v2 docs.\n\n  Phase.OutputSchema=\u0022Schemas/OASIS-CIQ-v3/xPIL.xsd\u0022 is wired on\n  Phase.IssueOpportunity (this manifest).  Resolved by\n  PhaseOrchestrator.ResolveSchemaPath via the V12.6b app-package probe\n  (AppContext.BaseDirectory/Schemas/OASIS-CIQ-v3/...).  Agent-emitted Party\n  XML is XSD-validated before persist runs.  Operator wanting to import a\n  third-party CRM\u0027s CIQ-export pipes through the same XSD without writing\n  a per-source adapter.\n\nWHY THIS COMPOUNDS:\n\n  Standards-conformance is a recurring SPICE bet.  V12.0a anchored ISO 4217\n  (currencies), ISO 3166 (countries), ISO 17442 (LEI), GS1 GLN.  V12.6b\n  vendored UBL Invoice 2.1.  V14.5 adds OASIS CIQ as the CRM-side anchor.\n  When SPICE talks to other ERP/CRM systems, the conversation happens in\n  standard XML; the platform\u0027s typed-CT layer is the operator-facing\n  presentation, not a proprietary data model.","tags":["v14.5","oasis-ciq","standards","xpil","xprl","xnal","crm"],"source":"SPICE.Apps.Erp.Tcm/Parts.Tcm.xml"},{"kind":"FieldDefinition","id":"Field.SoOrderNumber","name":"OrderNumber"},{"kind":"FieldDefinition","id":"Field.SoCustomerSku","name":"CustomerSku"},{"kind":"FieldDefinition","id":"Field.SoOrderDate","name":"OrderDate"},{"kind":"FieldDefinition","id":"Field.SoCurrencyCode","name":"CurrencyCode"},{"kind":"FieldDefinition","id":"Field.SoPaymentTerm","name":"PaymentTermCode"},{"kind":"FieldDefinition","id":"Field.SoTotalAmount","name":"TotalAmount"},{"kind":"FieldDefinition","id":"Field.SoStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.SoNotes","name":"Notes"},{"kind":"FieldDefinition","id":"Field.PoOrderNumber","name":"OrderNumber"},{"kind":"FieldDefinition","id":"Field.PoSupplierSku","name":"SupplierSku"},{"kind":"FieldDefinition","id":"Field.PoOrderDate","name":"OrderDate"},{"kind":"FieldDefinition","id":"Field.PoCurrencyCode","name":"CurrencyCode"},{"kind":"FieldDefinition","id":"Field.PoPaymentTerm","name":"PaymentTermCode"},{"kind":"FieldDefinition","id":"Field.PoTotalAmount","name":"TotalAmount"},{"kind":"FieldDefinition","id":"Field.PoExpectedReceipt","name":"ExpectedReceiptDate"},{"kind":"FieldDefinition","id":"Field.PoStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.PoNotes","name":"Notes"},{"kind":"FieldDefinition","id":"Field.SnShipmentNumber","name":"ShipmentNumber"},{"kind":"FieldDefinition","id":"Field.SnCarrierSku","name":"CarrierSku"},{"kind":"FieldDefinition","id":"Field.SnSalesOrderNumber","name":"SalesOrderNumber"},{"kind":"FieldDefinition","id":"Field.SnShipDate","name":"ShipDate"},{"kind":"FieldDefinition","id":"Field.SnTrackingNumber","name":"TrackingNumber"},{"kind":"FieldDefinition","id":"Field.SnStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.SnNotes","name":"Notes"},{"kind":"FieldDefinition","id":"Field.SnSupplierSku","name":"SupplierSku"},{"kind":"FieldDefinition","id":"Field.SolSalesOrderNumber","name":"SalesOrderNumber"},{"kind":"FieldDefinition","id":"Field.SolLineNumber","name":"LineNumber"},{"kind":"FieldDefinition","id":"Field.SolItemSku","name":"ItemSku"},{"kind":"FieldDefinition","id":"Field.SolDescription","name":"Description"},{"kind":"FieldDefinition","id":"Field.SolQuantity","name":"Quantity"},{"kind":"FieldDefinition","id":"Field.SolUnitPrice","name":"UnitPrice"},{"kind":"FieldDefinition","id":"Field.SolLineExtensionAmount","name":"LineExtensionAmount"},{"kind":"FieldDefinition","id":"Field.SolTaxCategoryCode","name":"TaxCategoryCode"},{"kind":"FieldDefinition","id":"Field.PolPurchaseOrderNumber","name":"PurchaseOrderNumber"},{"kind":"FieldDefinition","id":"Field.PolLineNumber","name":"LineNumber"},{"kind":"FieldDefinition","id":"Field.PolItemSku","name":"ItemSku"},{"kind":"FieldDefinition","id":"Field.PolDescription","name":"Description"},{"kind":"FieldDefinition","id":"Field.PolQuantity","name":"Quantity"},{"kind":"FieldDefinition","id":"Field.PolUnitPrice","name":"UnitPrice"},{"kind":"FieldDefinition","id":"Field.PolLineExtensionAmount","name":"LineExtensionAmount"},{"kind":"ContentType","id":"ContentType.SalesOrder","name":"Sales Order"},{"kind":"ContentType","id":"ContentType.PurchaseOrder","name":"Purchase Order"},{"kind":"ContentType","id":"ContentType.ShipmentNotice","name":"Shipment Notice"},{"kind":"ContentType","id":"ContentType.SalesOrderLine","name":"Sales Order Line"},{"kind":"ContentType","id":"ContentType.PurchaseOrderLine","name":"Purchase Order Line"},{"kind":"ListTemplate","id":"ListTemplate.SalesOrders","name":"Sales Orders"},{"kind":"ListTemplate","id":"ListTemplate.PurchaseOrders","name":"Purchase Orders"},{"kind":"ListTemplate","id":"ListTemplate.ShipmentNotices","name":"Shipment Notices"},{"kind":"ListTemplate","id":"ListTemplate.SalesOrderLines","name":"Sales Order Lines"},{"kind":"ListTemplate","id":"ListTemplate.PurchaseOrderLines","name":"Purchase Order Lines"},{"kind":"KnowledgeArticle","id":"KB.Td.Overview","name":"Td package: Distribution module overview","description":"What V12.4 ships, which Tc masters each ContentType binds to, and the status flow on each of the 3 ContentTypes.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"V12.4 SHIPS 3 OPERATIONAL HEADER CONTENTTYPES, each with a BaaN-style status flow declared via the V12.0b Transitions seam.  Manifest-only - zero C# beyond an empty AppModuleBase.\n\n  ContentType.SalesOrder       list \u0022Distribution/SalesOrders\u0022\n    Status: Draft -\u003E Approved -\u003E Picked -\u003E Shipped -\u003E Invoiced -\u003E Closed\n    Cancel: from Draft, Approved, or Picked (post-Picked needs reverse moves first).\n    Lookups: CustomerSku -\u003E Common/BusinessPartners; CurrencyCode -\u003E Common/Currencies; PaymentTermCode -\u003E Common/PaymentTerms.\n\n  ContentType.PurchaseOrder    list \u0022Distribution/PurchaseOrders\u0022\n    Status: Draft -\u003E Approved -\u003E Sent -\u003E Received -\u003E Closed\n    Cancel: from Draft, Approved, or Sent.\n    Lookups: SupplierSku -\u003E Common/BusinessPartners; CurrencyCode -\u003E Common/Currencies; PaymentTermCode -\u003E Common/PaymentTerms.\n\n  ContentType.ShipmentNotice   list \u0022Distribution/ShipmentNotices\u0022\n    Status: Created -\u003E Loaded -\u003E InTransit -\u003E Delivered (terminal)\n    Lost: terminal escape from Created / Loaded / InTransit.\n    Lookups: CarrierSku -\u003E Common/BusinessPartners.\n    SalesOrderNumber stays Text for now (V12.4b will promote to Lookup against SalesOrders once a self-list parent-ref convention is decided).\n\nWHAT YOU GET FOR FREE (no extra cycle):\n  - Typed forms at /sites/Distribution/Lists/{Sales,Purchase,Shipment}{Orders,Notices}/New\n    with Lookup dropdowns populated from V12.1 Tc termsets/masters\n    (V12.1 already proved BusinessPartners JSON Schema renders with live option counts).\n  - \u0022Next step\u0022 buttons on the Display form (V12.2 FormView projection of Transitions).\n  - POST /sites/Distribution/Lists/{X}/items/{Id}/advance?to=Y (V12.2 controller).\n  - MCP tool_advance_list_item works against all 3 ContentTypes\n    (V12.3 IToolInvoker reads any Transitions block via IContentTypeResolver).\n  - REST CRUD at /api/sites/Distribution/lists/{X}/items with XSD validation\n    (V8.x ListsApiController \u002B V12.3.5 ContentType-on-create persistence).\n  - JSON Schema at /api/sites/Distribution/lists/{X}/_schema with resolved Lookup options.\n\nV13.6 SHIPPED (closing the V12.4 line-item deferral):\n  ContentType.SalesOrderLine    list \u0022Distribution/SalesOrderLines\u0022    parent-ref: SalesOrderNumber \u002B LineNumber\n    Fields: SalesOrderNumber \u002B LineNumber \u002B ItemSku \u002B Description \u002B Quantity \u002B UnitPrice \u002B LineExtensionAmount \u002B TaxCategoryCode (Lookup -\u003E Common/TaxCategories).\n  ContentType.PurchaseOrderLine list \u0022Distribution/PurchaseOrderLines\u0022 parent-ref: PurchaseOrderNumber \u002B LineNumber\n    Fields: PurchaseOrderNumber \u002B LineNumber \u002B ItemSku \u002B Description \u002B Quantity \u002B UnitPrice \u002B LineExtensionAmount.\n  No Transitions on either - lines ride their parent header\u0027s lifecycle.\n\nWHAT V12.4 \u002B V13.6 STILL DEFER:\n  - Cross-module engagement (Td -\u003E Ti on Receive to register a StockMove).  V12.7 ships Ti.\n  - UBL XSD validation on the Order shape.  V12.6 ships Tf with UBL Invoice; orders can follow the same pattern in V13.7\u002B.\n  - Tax calculation on TotalAmount.  V12.5 ships TaxCategory.\n  - Parent-ref promotion to Lookup (instead of Text \u002B LineNumber).  Needs an engine-side self-list seam; deferred to a future cycle that covers it across SalesOrderLine \u002B PurchaseOrderLine \u002B InvoiceLine \u002B JournalEntryLine \u002B Payment.InvoiceNumber together.\n  - Auto-rollup of LineExtensionAmount -\u003E header TotalAmount via an IItemAddedListener.\n\nEXTENSION RECIPE (adding a new operational ContentType to this module):\n  1. Declare FieldDefinitions for the new shape, prefixing field Ids with the document code (Po* / So* / Sn* / etc.) to keep cross-CT field-name collisions impossible.\n  2. Declare the ContentType inheriting ContentType.Item, FieldRefs, and a Transitions block.\n  3. Add a ListTemplate.\n  4. Add a List to DistributionPortal in SAF-Site-Manifest.xml.\n  Done.  The form, the API, the MCP advance, the schema endpoint, the dropdowns all light up.","tags":["distribution","sales","purchase","shipment","v12.4"],"source":"SPICE.Apps.Erp.Td/Parts.Td.xml"},{"kind":"CrossModuleRule","id":"Rule.Td.OpportunityWon","name":"Opportunity Won -\u003E Distribution draft SalesOrder"},{"kind":"CrossModuleRule","id":"Rule.Td.OpportunityWonLines","name":"Opportunity Won -\u003E Distribution SalesOrderLines (one per QuoteLine)"},{"kind":"FieldDefinition","id":"Field.InvInvoiceNumber","name":"InvoiceNumber"},{"kind":"FieldDefinition","id":"Field.InvIssueDate","name":"IssueDate"},{"kind":"FieldDefinition","id":"Field.InvDueDate","name":"DueDate"},{"kind":"FieldDefinition","id":"Field.InvTypeCode","name":"InvoiceTypeCode"},{"kind":"FieldDefinition","id":"Field.InvCurrencyCode","name":"CurrencyCode"},{"kind":"FieldDefinition","id":"Field.InvSupplierSku","name":"SupplierSku"},{"kind":"FieldDefinition","id":"Field.InvCustomerSku","name":"CustomerSku"},{"kind":"FieldDefinition","id":"Field.InvPaymentTerm","name":"PaymentTermCode"},{"kind":"FieldDefinition","id":"Field.InvFiscalPeriod","name":"FiscalPeriodTitle"},{"kind":"FieldDefinition","id":"Field.InvTotalAmount","name":"TotalAmount"},{"kind":"FieldDefinition","id":"Field.InvTaxAmount","name":"TaxAmount"},{"kind":"FieldDefinition","id":"Field.InvTaxCategoryCode","name":"TaxCategoryCode"},{"kind":"FieldDefinition","id":"Field.InvStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.InvNotes","name":"Notes"},{"kind":"FieldDefinition","id":"Field.PayPaymentNumber","name":"PaymentNumber"},{"kind":"FieldDefinition","id":"Field.PayInvoiceNumber","name":"InvoiceNumber"},{"kind":"FieldDefinition","id":"Field.PayPaidDate","name":"PaidDate"},{"kind":"FieldDefinition","id":"Field.PayCurrencyCode","name":"CurrencyCode"},{"kind":"FieldDefinition","id":"Field.PayAmount","name":"Amount"},{"kind":"FieldDefinition","id":"Field.PayBankAccountIban","name":"BankAccountIban"},{"kind":"FieldDefinition","id":"Field.PayStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.PayNotes","name":"Notes"},{"kind":"FieldDefinition","id":"Field.JeJournalNumber","name":"JournalNumber"},{"kind":"FieldDefinition","id":"Field.JeEntryDate","name":"EntryDate"},{"kind":"FieldDefinition","id":"Field.JeFiscalPeriod","name":"FiscalPeriodTitle"},{"kind":"FieldDefinition","id":"Field.JeDebitAccountCode","name":"DebitAccountCode"},{"kind":"FieldDefinition","id":"Field.JeCreditAccountCode","name":"CreditAccountCode"},{"kind":"FieldDefinition","id":"Field.JeAmount","name":"Amount"},{"kind":"FieldDefinition","id":"Field.JeCurrencyCode","name":"CurrencyCode"},{"kind":"FieldDefinition","id":"Field.JeDescription","name":"Description"},{"kind":"FieldDefinition","id":"Field.JeStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.IlInvoiceNumber","name":"InvoiceNumber"},{"kind":"FieldDefinition","id":"Field.IlLineNumber","name":"InvoiceLineNumber"},{"kind":"FieldDefinition","id":"Field.IlInvoicedQuantity","name":"InvoicedQuantity"},{"kind":"FieldDefinition","id":"Field.IlLineExtensionAmount","name":"LineExtensionAmount"},{"kind":"FieldDefinition","id":"Field.IlItemSku","name":"ItemSku"},{"kind":"FieldDefinition","id":"Field.IlItemDescription","name":"ItemDescription"},{"kind":"FieldDefinition","id":"Field.IlUnitPrice","name":"UnitPrice"},{"kind":"FieldDefinition","id":"Field.IlTaxCategoryCode","name":"TaxCategoryCode"},{"kind":"FieldDefinition","id":"Field.JelJournalNumber","name":"JournalNumber"},{"kind":"FieldDefinition","id":"Field.JelLineNumber","name":"LineNumber"},{"kind":"FieldDefinition","id":"Field.JelAccountCode","name":"AccountCode"},{"kind":"FieldDefinition","id":"Field.JelDebitAmount","name":"DebitAmount"},{"kind":"FieldDefinition","id":"Field.JelCreditAmount","name":"CreditAmount"},{"kind":"FieldDefinition","id":"Field.JelLineDescription","name":"LineDescription"},{"kind":"ContentType","id":"ContentType.Invoice","name":"Invoice"},{"kind":"ContentType","id":"ContentType.Payment","name":"Payment"},{"kind":"ContentType","id":"ContentType.JournalEntry","name":"Journal Entry"},{"kind":"ContentType","id":"ContentType.InvoiceLine","name":"Invoice Line"},{"kind":"ContentType","id":"ContentType.JournalEntryLine","name":"Journal Entry Line"},{"kind":"ListTemplate","id":"ListTemplate.Invoices","name":"Invoices"},{"kind":"ListTemplate","id":"ListTemplate.Payments","name":"Payments"},{"kind":"ListTemplate","id":"ListTemplate.JournalEntries","name":"Journal Entries"},{"kind":"ListTemplate","id":"ListTemplate.InvoiceLines","name":"Invoice Lines"},{"kind":"ListTemplate","id":"ListTemplate.JournalEntryLines","name":"Journal Entry Lines"},{"kind":"Phase","id":"Phase.IssueInvoice","name":"Issue UBL Invoice"},{"kind":"Webhook","id":"Webhook.Tf.InvoicePaidNotification","name":"Notify external system when an Invoice transitions to Paid"},{"kind":"KnowledgeArticle","id":"KB.Tf.UblMapping","name":"Tf package: UBL 2.4 InvoiceType -\u003E ContentType.Invoice field map","description":"The standards-conformance receipt of the V12 horizon. Documents how each ContentType.Invoice FieldDefinition corresponds to a UBL 2.4 InvoiceType element so V12.6b can wire actual UBL XSD validation without re-deriving the mapping.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"STRATEGIC FRAME (per KB.ErpFoundationPlan): the strongest leverage the platform has for ERP isn\u0027t the runtime; it\u0027s typed XML against world-standard schemas.  UBL 2.4 InvoiceType is exactly the shape we need, so mirror it field-for-field.  V12.6 ships the typed shape \u002B lookups \u002B status flow; V12.6b vendors the actual UBL XSD as an embedded resource and wires it as Phase.OutputSchema for agent emit \u002B ContentType.Invoice validation for human/API write.\n\nUBL 2.4 InvoiceType -\u003E ContentType.Invoice MAPPING (element-by-element):\n\n  UBL element                                | SPICE FieldDefinition                  | Notes\n  ------------------------------------------ | -------------------------------------- | -----\n  cbc:ID                                     | Field.InvInvoiceNumber                | required string\n  cbc:IssueDate                              | Field.InvIssueDate                    | required DateTime\n  cbc:DueDate                                | Field.InvDueDate                      | optional DateTime; auto-computable as IssueDate \u002B PaymentTerm.NetDays\n  cbc:InvoiceTypeCode                        | Field.InvTypeCode                     | Choice (380 / 381 / 384); default 380 commercial\n  cbc:DocumentCurrencyCode                   | Field.InvCurrencyCode                 | Lookup -\u003E Common/Currencies (ISO 4217)\n  cac:AccountingSupplierParty/cac:Party      | Field.InvSupplierSku                  | Lookup -\u003E Common/BusinessPartners (SUPPLIER role)\n  cac:AccountingCustomerParty/cac:Party      | Field.InvCustomerSku                  | Lookup -\u003E Common/BusinessPartners (CUSTOMER role)\n  cac:PaymentTerms                           | Field.InvPaymentTerm                  | Lookup -\u003E Common/PaymentTerms\n  (out-of-band: fiscal-period selection)     | Field.InvFiscalPeriod                 | Tf cross-ref to Common/FiscalPeriods.Title (V12.5)\n  cac:LegalMonetaryTotal/cbc:PayableAmount   | Field.InvTotalAmount                  | required Number, currency from InvCurrencyCode\n  cac:TaxTotal/cbc:TaxAmount                 | Field.InvTaxAmount                    | optional Number\n  cac:TaxCategory/cbc:ID                     | Field.InvTaxCategoryCode              | Lookup -\u003E Common/TaxCategories (V12.5)\n  cbc:Note                                   | Field.InvNotes                        | optional Note\n  (workflow state - not in UBL)              | Field.InvStatus                       | Choice (Draft/Sent/Posted/Paid/Closed/Cancelled); drives Transitions\n\nUBL ELEMENTS SHIPPED IN V13.6 (cac:InvoiceLine field map):\n\n  UBL element                                          | SPICE FieldDefinition          | Notes\n  ---------------------------------------------------- | ------------------------------ | -----\n  cbc:ID (within cac:InvoiceLine)                      | Field.IlLineNumber             | required ordinal, 1..N within invoice\n  cbc:InvoicedQuantity                                 | Field.IlInvoicedQuantity       | required Number in item UoM\n  cbc:LineExtensionAmount                              | Field.IlLineExtensionAmount    | required Number; sum across lines = header PayableAmount\n  cac:Item/cac:SellersItemIdentification/cbc:ID        | Field.IlItemSku                | cross-ref to Common/Items.Sku\n  cac:Item/cbc:Description                             | Field.IlItemDescription        | per-line description (may override master)\n  cac:Price/cbc:PriceAmount                            | Field.IlUnitPrice              | per-unit price in header currency\n  cac:Item/cac:ClassifiedTaxCategory/cbc:ID            | Field.IlTaxCategoryCode        | Lookup -\u003E Common/TaxCategories; overrides header default\n  (header parent-ref - not in UBL)                     | Field.IlInvoiceNumber          | Text reference to parent Invoice.InvoiceNumber\n\n  Closes V12.6b\u0027s \u0022minimal-valid UBL Invoice rejected without InvoiceLine\u0022 XSD-rejection pin: a real header\u002Blines invoice now round-trips through the vendored XSD without rejection.\n\nUBL ELEMENTS STILL DEFERRED:\n  cac:Delivery       (delivery dates \u002B ship-to)\n  cac:OrderReference (cross-ref back to a PurchaseOrder.OrderNumber)\n  cac:BillingReference (credit-note back-references)\n\n  These layer on top of the V13.6 InvoiceLine field map without disturbing it - additive cycle.\n\nWHY THIS MATTERS:\n  1. PEPPOL BIS Billing 3.0 is built on UBL.  An agent that emits a SPICE Invoice row with these fields IS emitting a PEPPOL-compliant invoice payload (modulo line-item completeness).  V12.6b\u0027s XSD wiring catches the gap programmatically.\n  2. ISO 20022 financial messages (V12.7\u002B) reuse much of UBL\u0027s CommonAggregateComponents (cac:Party / cac:Address etc.).  Adopting UBL field names here means future ISO 20022 modules layer on top without renaming.\n  3. Inter-system interop becomes trivial: a PEPPOL access point can POST a UBL XML invoice straight to V11.24 WorkflowsController (Content-Type=application/xml) -\u003E V11.1 validation against the UBL XSD -\u003E V11.2 auto-persist to Tf/Invoices.  Zero mapping layer.\n\nV12.6 SHIPS:\n  3 typed ContentTypes (Invoice, Payment, JournalEntry) each with Transitions.\n  FinancePortal SiteBlueprint hosting Invoices \u002B Payments \u002B JournalEntries lists.\n  ListsApiController already validates writes against the resolved ContentType (V8.x); the BaaN-style /advance \u002B MCP tool_advance_list_item paths work automatically.\n\nV12.6b SHIPPED (vendoring \u002B wiring):\n  UBL 2.1 Invoice XSD bundle vendored at SPICE.Apps.Erp.Tf/Schemas/UBL/ - maindoc/UBL-Invoice-2.1.xsd plus 14 common/*.xsd files (CAC \u002B CBC \u002B CommonExtensionComponents \u002B CCTS \u002B UnqualifiedDataTypes \u002B QualifiedDataTypes \u002B xmldsig \u002B XAdES).  Copyright (c) OASIS Open 2013, freely distributable.\n  Phase.IssueInvoice declared in this manifest with OutputSchema=\u0027Schemas/UBL/maindoc/UBL-Invoice-2.1.xsd\u0027.  Resolved by PhaseOrchestrator.ResolveConfigPath via the new app-package probe (AppContext.BaseDirectory/Schemas/UBL/...).  Agent-emitted UBL Invoice XML is XSD-validated before persist runs.\n\nV13.6 SHIPPED (header \u002B lines):\n  ContentType.InvoiceLine with the UBL field map above; list \u0022Finance/InvoiceLines\u0022; parent-ref Field.IlInvoiceNumber -\u003E Invoice.InvoiceNumber.\n  ContentType.JournalEntryLine for double-entry split (LineNumber \u002B AccountCode \u002B DebitAmount \u002B CreditAmount \u002B LineDescription); list \u0022Finance/JournalEntryLines\u0022; parent-ref Field.JelJournalNumber -\u003E JournalEntry.JournalNumber.\n\nEXTENSION RECIPE: when adding a new UBL-aligned ContentType (CreditNote / DespatchAdvice / etc.):\n  1. Find the UBL XSD\u0027s root element \u002B its CommonBasic/CommonAggregate children.\n  2. Declare FieldDefinitions in the same order, with UBL element names in the Description text.\n  3. Declare ContentType inheriting ContentType.Item, FieldRefs in UBL order.\n  4. Declare Transitions for the document\u0027s status flow.\n  5. Optional: drop the XSD into Schemas/UBL/ for V12.6b validation wiring.\n  Done.","tags":["finance","ubl","peppol","standards","v12.6"],"source":"SPICE.Apps.Erp.Tf/Parts.Tf.xml"},{"kind":"CrossModuleRule","id":"Rule.Tf.SalesOrderShipped","name":"SalesOrder Shipped -\u003E Finance draft Invoice"},{"kind":"CrossModuleRule","id":"Rule.Tf.InvoicePaid","name":"Invoice Paid -\u003E Finance draft JournalEntry"},{"kind":"FieldDefinition","id":"Field.StItemSku","name":"ItemSku"},{"kind":"FieldDefinition","id":"Field.StWarehouseCode","name":"WarehouseCode"},{"kind":"FieldDefinition","id":"Field.StBinCode","name":"BinCode"},{"kind":"FieldDefinition","id":"Field.StOnHandQuantity","name":"OnHandQuantity"},{"kind":"FieldDefinition","id":"Field.StReservedQuantity","name":"ReservedQuantity"},{"kind":"FieldDefinition","id":"Field.StUomCode","name":"UnitOfMeasureCode"},{"kind":"FieldDefinition","id":"Field.SmMoveNumber","name":"MoveNumber"},{"kind":"FieldDefinition","id":"Field.SmItemSku","name":"ItemSku"},{"kind":"FieldDefinition","id":"Field.SmQuantity","name":"Quantity"},{"kind":"FieldDefinition","id":"Field.SmUomCode","name":"UnitOfMeasureCode"},{"kind":"FieldDefinition","id":"Field.SmFromWarehouse","name":"FromWarehouseCode"},{"kind":"FieldDefinition","id":"Field.SmToWarehouse","name":"ToWarehouseCode"},{"kind":"FieldDefinition","id":"Field.SmFromBin","name":"FromBinCode"},{"kind":"FieldDefinition","id":"Field.SmToBin","name":"ToBinCode"},{"kind":"FieldDefinition","id":"Field.SmMoveDate","name":"MoveDate"},{"kind":"FieldDefinition","id":"Field.SmReason","name":"Reason"},{"kind":"FieldDefinition","id":"Field.SmReference","name":"Reference"},{"kind":"FieldDefinition","id":"Field.SmStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.SmNotes","name":"Notes"},{"kind":"FieldDefinition","id":"Field.BinCode","name":"Code"},{"kind":"FieldDefinition","id":"Field.BinWarehouseCode","name":"WarehouseCode"},{"kind":"FieldDefinition","id":"Field.BinAisle","name":"Aisle"},{"kind":"FieldDefinition","id":"Field.BinRack","name":"Rack"},{"kind":"FieldDefinition","id":"Field.BinShelf","name":"Shelf"},{"kind":"FieldDefinition","id":"Field.BinType","name":"BinType"},{"kind":"ContentType","id":"ContentType.StockItem","name":"Stock Item"},{"kind":"ContentType","id":"ContentType.StockMove","name":"Stock Move"},{"kind":"ContentType","id":"ContentType.BinLocation","name":"Bin Location"},{"kind":"ListTemplate","id":"ListTemplate.StockItems","name":"Stock Items"},{"kind":"ListTemplate","id":"ListTemplate.StockMoves","name":"Stock Moves"},{"kind":"ListTemplate","id":"ListTemplate.BinLocations","name":"Bin Locations"},{"kind":"KnowledgeArticle","id":"KB.Ti.Overview","name":"Ti package: Inventory module overview \u002B cross-module engagement plan","description":"What V12.7 ships, what V12.7b adds (cross-module engagement Td PO.Received -\u003E Ti StockMove), and how StockMove\u0027s Done transition triggers OnHandQuantity recompute.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"V12.7 SHIPS the N=3 operational module receipt - Td Distribution (V12.4), Tf Finance (V12.6), and now Ti Inventory all live on the same V12.0 foundation with zero per-module C#.  3 ContentTypes \u002B portal blueprint \u002B lookups \u002B status flow = a working warehouse module.\n\n  ContentType.StockItem      list \u0027Inventory/StockItems\u0027\n    Balance row per (ItemSku, WarehouseCode, BinCode).  Updated by\n    StockMove transitions on Done.  No Transitions - balances aren\u0027t\n    workflow documents.\n\n  ContentType.StockMove      list \u0027Inventory/StockMoves\u0027\n    Status: Open -\u003E Reserved -\u003E Picked -\u003E Done (\u002B Cancelled from pre-\n    Done).  The operational unit.  Reason enum picks Receipt /\n    Shipment / Transfer / Adjustment / Internal - drives cross-module\n    audit narrative.\n\n  ContentType.BinLocation    list \u0027Inventory/BinLocations\u0027\n    Master-data row per warehouse bin.  Code is the cross-ref key.\n    BinType Choice (Picking / Bulk / Quarantine / Receiving / Shipping)\n    enables future picking-strategy automation.\n\nCROSS-MODULE ENGAGEMENT (V12.7b candidate):\n  The pattern that makes Ti\u002BTd\u002BTf actually compose end-to-end:\n\n    Td PurchaseOrder.Status: Sent -\u003E Received\n       triggers IItemEventListener that creates a Ti StockMove with:\n         Reason = Receipt\n         Reference = PurchaseOrder.OrderNumber\n         ItemSku = (from PO line; V12.7b layered with InvoiceLine)\n         ToWarehouse = (operator\u0027s default receiving warehouse)\n         Status = Open\n\n    Td SalesOrder.Status: Approved -\u003E Picked\n       triggers IItemEventListener that creates a Ti StockMove with:\n         Reason = Shipment\n         Reference = SalesOrder.OrderNumber\n         ItemSku = (from SO line)\n         FromWarehouse = (operator\u0027s default outbound warehouse)\n         Status = Open\n\n  IMPLEMENTATION SHAPE (deferred to V12.7b):\n    - SPICE.Apps.Erp.Ti gains a TiAppModule.RegisterAppServices\n      registration for one IItemEventListener (CrossModuleStockMoveListener).\n    - The listener filters AddListItemOpHandler\u0027s V8.4 fan-out:\n        if site == \u0027Distribution\u0027 AND (\n          (list == \u0027PurchaseOrders\u0027 AND newStatus == \u0027Received\u0027) OR\n          (list == \u0027SalesOrders\u0027 AND newStatus == \u0027Picked\u0027)\n        )\n        then create Ti/StockMoves row with Reference=that.OrderNumber.\n    - Pattern banked: same shape as V11.5 OodaLoop\u0027s LearnedPattern-\n      WritebackListener (V8.4 fan-out \u002B V11.5 AppModule registration).\n      Cross-module is the new wrinkle; everything else is platform-native.\n\nWHAT V12.7 DEFERS:\n  - OnHandQuantity recompute on StockMove.Done.  Needs an EventReceiver\n    or IItemEventListener wiring to scan affected StockItem rows.\n    V12.7b.\n  - Negative stock guards.  V12.7b adds a policy rule that refuses\n    StockMove transitions where the resulting OnHandQuantity would go\n    negative.\n  - Picking-strategy automation (FIFO / FEFO / nearest-bin).  Needs a\n    Skill that takes a SalesOrder line and picks the right StockMove\n    sequence.  V12.8\u002B.\n\nV12.7 PROVES the N=3 thesis for operational modules and seeds the\ncross-module-engagement work without committing to its wiring yet.\nThe cross-module shape lives here in this KB so V12.7b doesn\u0027t need\nto re-derive it.","tags":["inventory","stockmove","warehouse","cross-module","v12.7"],"source":"SPICE.Apps.Erp.Ti/Parts.Ti.xml"},{"kind":"CrossModuleRule","id":"Rule.Ti.PurchaseOrderReceived","name":"PurchaseOrder Received -\u003E Inventory Receipt StockMove"},{"kind":"CrossModuleRule","id":"Rule.Ti.SalesOrderPicked","name":"SalesOrder Picked -\u003E Inventory Shipment StockMove"},{"kind":"FieldDefinition","id":"Field.BomId","name":"BomId"},{"kind":"FieldDefinition","id":"Field.BomProductSku","name":"ProductSku"},{"kind":"FieldDefinition","id":"Field.BomVersion","name":"Version"},{"kind":"FieldDefinition","id":"Field.BomEffectiveDate","name":"EffectiveDate"},{"kind":"FieldDefinition","id":"Field.BomStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.BomNotes","name":"Notes"},{"kind":"FieldDefinition","id":"Field.BomCompBomId","name":"BomId"},{"kind":"FieldDefinition","id":"Field.BomCompLineNumber","name":"LineNumber"},{"kind":"FieldDefinition","id":"Field.BomCompComponentSku","name":"ComponentSku"},{"kind":"FieldDefinition","id":"Field.BomCompQuantityPer","name":"QuantityPer"},{"kind":"FieldDefinition","id":"Field.BomCompUomCode","name":"UomCode"},{"kind":"FieldDefinition","id":"Field.RoutingId","name":"RoutingId"},{"kind":"FieldDefinition","id":"Field.RoutingProductSku","name":"ProductSku"},{"kind":"FieldDefinition","id":"Field.RoutingVersion","name":"Version"},{"kind":"FieldDefinition","id":"Field.RoutingEffectiveDate","name":"EffectiveDate"},{"kind":"FieldDefinition","id":"Field.RoutingStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.RoutingNotes","name":"Notes"},{"kind":"FieldDefinition","id":"Field.RoutingOpRoutingId","name":"RoutingId"},{"kind":"FieldDefinition","id":"Field.RoutingOpLineNumber","name":"LineNumber"},{"kind":"FieldDefinition","id":"Field.RoutingOpOperationCode","name":"OperationCode"},{"kind":"FieldDefinition","id":"Field.RoutingOpDescription","name":"Description"},{"kind":"FieldDefinition","id":"Field.RoutingOpWorkCenterCode","name":"WorkCenterCode"},{"kind":"FieldDefinition","id":"Field.RoutingOpSetupMinutes","name":"SetupMinutes"},{"kind":"FieldDefinition","id":"Field.RoutingOpRunMinutes","name":"RunMinutes"},{"kind":"FieldDefinition","id":"Field.RoutingOpArgs","name":"Args"},{"kind":"FieldDefinition","id":"Field.WorkCenterCode","name":"WorkCenterCode"},{"kind":"FieldDefinition","id":"Field.WorkCenterName","name":"Name"},{"kind":"FieldDefinition","id":"Field.WorkCenterDescription","name":"Description"},{"kind":"FieldDefinition","id":"Field.WorkCenterCapacityPerHour","name":"CapacityPerHour"},{"kind":"FieldDefinition","id":"Field.WorkCenterCostPerHour","name":"CostPerHour"},{"kind":"FieldDefinition","id":"Field.WorkCenterMachineToolId","name":"MachineToolId"},{"kind":"FieldDefinition","id":"Field.WorkCenterStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.ProductionOrderNumber","name":"OrderNumber"},{"kind":"FieldDefinition","id":"Field.ProductionOrderProductSku","name":"ProductSku"},{"kind":"FieldDefinition","id":"Field.ProductionOrderBomId","name":"BomId"},{"kind":"FieldDefinition","id":"Field.ProductionOrderRoutingId","name":"RoutingId"},{"kind":"FieldDefinition","id":"Field.ProductionOrderQuantity","name":"Quantity"},{"kind":"FieldDefinition","id":"Field.ProductionOrderPlannedStart","name":"PlannedStart"},{"kind":"FieldDefinition","id":"Field.ProductionOrderPlannedFinish","name":"PlannedFinish"},{"kind":"FieldDefinition","id":"Field.ProductionOrderStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.ProductionOpOrderNumber","name":"OrderNumber"},{"kind":"FieldDefinition","id":"Field.ProductionOpLineNumber","name":"LineNumber"},{"kind":"FieldDefinition","id":"Field.ProductionOpOperationCode","name":"OperationCode"},{"kind":"FieldDefinition","id":"Field.ProductionOpWorkCenterCode","name":"WorkCenterCode"},{"kind":"FieldDefinition","id":"Field.ProductionOpPlannedHours","name":"PlannedHours"},{"kind":"FieldDefinition","id":"Field.ProductionOpActualHours","name":"ActualHours"},{"kind":"ContentType","id":"ContentType.BillOfMaterials","name":"Bill of Materials"},{"kind":"ContentType","id":"ContentType.BomComponent","name":"BOM Component"},{"kind":"ContentType","id":"ContentType.Routing","name":"Routing"},{"kind":"ContentType","id":"ContentType.RoutingOperation","name":"Routing Operation"},{"kind":"ContentType","id":"ContentType.WorkCenter","name":"Work Center"},{"kind":"ContentType","id":"ContentType.ProductionOrder","name":"Production Order"},{"kind":"ContentType","id":"ContentType.ProductionOperation","name":"Production Operation"},{"kind":"ListTemplate","id":"ListTemplate.BillsOfMaterials","name":"Bills of Materials"},{"kind":"ListTemplate","id":"ListTemplate.BomComponents","name":"BOM Components"},{"kind":"ListTemplate","id":"ListTemplate.Routings","name":"Routings"},{"kind":"ListTemplate","id":"ListTemplate.RoutingOperations","name":"Routing Operations"},{"kind":"ListTemplate","id":"ListTemplate.WorkCenters","name":"Work Centers"},{"kind":"ListTemplate","id":"ListTemplate.ProductionOrders","name":"Production Orders"},{"kind":"ListTemplate","id":"ListTemplate.ProductionOperations","name":"Production Operations"},{"kind":"KnowledgeArticle","id":"KB.Tm.Overview","name":"Tm package: Manufacturing module overview - the N=5 receipt","description":"What V14.1 ships, why Manufacturing opens the V14 horizon\u0027s BaaN expansion, and how the four header \u002B three line ContentTypes cross-link to Ti (StockMoves consume / receipt) \u002B Td (sales-driven MRP at V14.3) at V14.2.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"V14.1 SHIPS the N=5 receipt: Td (V12.4) \u002B Tf (V12.6) \u002B Ti (V12.7) \u002B Tp (V12.8) \u002B Tm (this cycle) all live on the same V12.0 foundation with zero per-module C# (beyond the empty AppModuleBase subclass).  Seven ContentTypes (4 headers \u002B 3 lines) \u002B portal blueprint \u002B Transitions = the manufacturing module\u0027s structural surface.\n\n  ContentType.BillOfMaterials   list \u0027Manufacturing/BillsOfMaterials\u0027\n    Status: Draft -\u003E Active -\u003E Obsolete \u002B Cancelled escape from Draft.\n    Identified by (ProductSku, Version); BomComponent lines reference both.\n\n  ContentType.BomComponent      list \u0027Manufacturing/BomComponents\u0027\n    Lines under BOM.  Parent-ref (ProductSku, Version, LineNumber).\n    No Transitions - rides parent BOM lifecycle.\n\n  ContentType.Routing           list \u0027Manufacturing/Routings\u0027\n    Status: Draft -\u003E Active -\u003E Obsolete \u002B Cancelled escape from Draft.\n    Identified by (ProductSku, Version); RoutingOperation lines reference both.\n\n  ContentType.RoutingOperation  list \u0027Manufacturing/RoutingOperations\u0027\n    Lines under Routing.  Parent-ref (ProductSku, Version, LineNumber).\n    No Transitions - rides parent Routing lifecycle.\n\n  ContentType.WorkCenter        list \u0027Manufacturing/WorkCenters\u0027\n    Status: Available \u003C-\u003E Maintenance \u003C-\u003E Offline \u002B Decommissioned terminal.\n    Three recoverable states \u002B one terminal retirement state.\n    CapacityPerHour \u002B CostPerHour drive V14.6 capacity/load /admin card.\n\n  ContentType.ProductionOrder   list \u0027Manufacturing/ProductionOrders\u0027\n    Status: Planned -\u003E Released -\u003E InProgress -\u003E Completed \u002B Cancelled escape.\n    Released is the V14.2 fan-out trigger to Ti consumption StockMoves.\n    Completed is the V14.2 receipt-StockMove trigger for the parent item.\n\n  ContentType.ProductionOperation list \u0027Manufacturing/ProductionOperations\u0027\n    Lines under ProductionOrder.  Parent-ref (OrderNumber, LineNumber).\n    No Transitions - rides parent order lifecycle.\n    ActualHours populated at parent Completed time.\n\nWHY MANUFACTURING OPENS V14:\n  The V12.4/V12.6/V12.7/V12.8 ladder proved the V12.0 foundation generalises\n  across four BaaN package codes.  Tm is the fifth - the N=5 receipt that\n  shows the abstraction holds for a process-oriented (rather than document-\n  oriented) module.  BOM \u002B Routing \u002B WorkCenter are master-data shapes;\n  ProductionOrder is the workflow document that ties them together at\n  execution time.\n\nCROSS-MODULE WIRING (queued for V14.2):\n  - ProductionOrder.Released  -\u003E Ti consumption StockMove per BomComponent\n                                 (issue materials to the order).\n  - ProductionOrder.Completed -\u003E Ti receipt StockMove for parent product\n                                 (receive finished goods into inventory).\n  This brings cross-module listener fan-out to N=5 (V12.7b/c \u002B V13.1b \u002B V13.2\n  \u002B V14.2); CrossModuleListenerBase becomes a candidate lift if the shape\n  repeats meaningfully.\n\nPARENT-REF CONVENTION:\n  All three line CTs use Text \u002B Number (LineNumber) for parent-ref,\n  matching V13.6 SalesOrderLine / PurchaseOrderLine / InvoiceLine /\n  JournalEntryLine.  V14.7 sweeps these (8\u002B candidates total) to proper\n  Lookup once the engine-side self-list parent-ref seam lands.","tags":["manufacturing","v14.1","n5-receipt","tm"],"source":"SPICE.Apps.Erp.Tm/Parts.Tm.xml"},{"kind":"CrossModuleRule","id":"Rule.Tm.ProductionOrderReleased","name":"ProductionOrder Released -\u003E Ti ProductionIssue per BOM component"},{"kind":"FieldDefinition","id":"Field.MrpItemSku","name":"ItemSku"},{"kind":"FieldDefinition","id":"Field.MrpWarehouseCode","name":"WarehouseCode"},{"kind":"FieldDefinition","id":"Field.MrpCurrentQuantity","name":"CurrentQuantity"},{"kind":"FieldDefinition","id":"Field.MrpSuggestedReorder","name":"SuggestedReorderQuantity"},{"kind":"FieldDefinition","id":"Field.MrpStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.MrpNotes","name":"Notes"},{"kind":"ContentType","id":"ContentType.MrpSuggestion","name":"MRP Suggestion"},{"kind":"ListTemplate","id":"ListTemplate.MrpSuggestions","name":"MRP Suggestions"},{"kind":"ListTemplate","id":"ListTemplate.ContentRecipes","name":"Content Recipes"},{"kind":"ListTemplate","id":"ListTemplate.RecipeIngredients","name":"Recipe Ingredients"},{"kind":"ListTemplate","id":"ListTemplate.ProductionPipelines","name":"Production Pipelines"},{"kind":"ListTemplate","id":"ListTemplate.PipelineSteps","name":"Pipeline Steps"},{"kind":"ListTemplate","id":"ListTemplate.ProductionStations","name":"Production Stations"},{"kind":"ListTemplate","id":"ListTemplate.ContentRuns","name":"Content Runs"},{"kind":"ListTemplate","id":"ListTemplate.RunSteps","name":"Run Steps"},{"kind":"ListTemplate","id":"ListTemplate.SourcingSuggestions","name":"Sourcing Suggestions"},{"kind":"KnowledgeArticle","id":"KB.Tm.ContentProductionAlias","name":"V14.4 ContentProductionPortal: N=2 worked example of Tm primitives across domains","description":"Banks the receipt that the V14.1 Tm primitives (BOM/Routing/WorkCenter/ProductionOrder \u002B line CTs \u002B MrpSuggestion) genuinely generalize - the same typed-CT layer drives a Content Production agency without a single C# edit.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"V14.4 SHIPS the first non-Manufacturing receipt of the V14.1 Tm primitives.  Same ContentTypes, same FieldDefinitions, same Transitions.  Operator-facing list names alias the Manufacturing terminology to the Content Production domain via 8 ListTemplate entries; the underlying typed-XML shape is byte-identical.\n\nALIAS TABLE:\n\n  Manufacturing term      -\u003E ContentProduction alias       (same ContentType)\n  ----------------------------------------------------------------------------\n  BillOfMaterials         -\u003E Content Recipe                ContentType.BillOfMaterials\n  BomComponent            -\u003E Recipe Ingredient             ContentType.BomComponent\n  Routing                 -\u003E Production Pipeline           ContentType.Routing\n  RoutingOperation        -\u003E Pipeline Step                 ContentType.RoutingOperation\n  WorkCenter              -\u003E Production Station            ContentType.WorkCenter\n  ProductionOrder         -\u003E Content Run                   ContentType.ProductionOrder\n  ProductionOperation     -\u003E Run Step                      ContentType.ProductionOperation\n  MrpSuggestion           -\u003E Sourcing Suggestion           ContentType.MrpSuggestion\n\nWHAT CARRIES OVER (the receipt):\n\n  - Status workflows: Content Recipe Draft -\u003E Active -\u003E Obsolete is the BOM lifecycle.\n    Content Run Planned -\u003E Released -\u003E InProgress -\u003E Completed is the ProductionOrder lifecycle.\n  - V12.2 FormView \u0022Next step\u0022 buttons render identically (driven by Transitions on the CT).\n  - V12.3 MCP tool_advance_list_item works against ContentProduction lists without any registration.\n  - V8.x typed REST \u002B form rendering picks up the alias list automatically.\n  - V12.1 Lookup fields (ItemSku etc.) still resolve against the same Common masters.\n\nCROSS-MODULE RULE REACH (V15.4 RESOLVED):\n\n  V14.4 banked the honest limitation that cross-module rules matched on (Department,\n  List, To) and couldn\u0027t reach both Manufacturing/ProductionOrders AND\n  ContentProduction/ContentRuns from a single rule.  V15.4 closes the gap with\n  \u0027*\u0027 wildcard support on Department and List (the To attribute stays exact-match\n  by design - rules pin a specific transition, broadening that to \u0027*\u0027 would let\n  one Match fire on every advance event and pollute the audit log).\n\n  Operators with a real Content Production agency who want auto-fan-out now have:\n\n    (a) Duplicate the rules per portal: Rule.Cprod.ContentRunReleased with the same\n        Emit shape pointed at ContentProduction\u0027s storage tracker (if any).  Simple,\n        works today, low blast radius.\n    (b) **V15.4 SHIPPED**: generalize via wildcards.  Rule with Match\n        Department=\u0022*\u0022 List=\u0022ContentRuns\u0022 To=\u0022Released\u0022 fires regardless of\n        department.  Or Department=\u0022Manufacturing\u0022 List=\u0022*\u0022 To=\u0022Released\u0022 for\n        any-list-in-this-dept.  Or Department=\u0022*\u0022 List=\u0022*\u0022 To=\u0022Released\u0022 for\n        the broadest cross-portal sweep.  The engine special-cases \u0027*\u0027 in\n        CrossModuleRuleDispatcher.MatchesEvent (~6 LOC); existing single-Dept\n        single-List rules keep matching exactly as before (regression-pinned\n        in V154MatchWildcardTests).\n    (c) Treat the typed-CT layer as the platform\u0027s contract and accept that\n        cross-module reactions are dept-scoped.  Reasonable for ERP boundaries -\n        physical manufacturing inventory shouldn\u0027t auto-emit content-production\n        rows.  V14.4 shipped under this stance; V15.4 makes option (b) feasible\n        for the cases that genuinely want it.\n\nWHY THIS COMPOUNDS:\n\n  V14.4 receipts the V14.1 plan claim \u0022abstraction is real.\u0022  N=1 worked example\n  with the typed-CT layer \u002B Transitions intact.  V14.5 (a second non-manufacturing\n  worked example - sprint planning or release management) brings N=2, which is\n  the platform\u0027s standard threshold for promoting a pattern from \u0022specific\u0022 to\n  \u0022framework.\u0022  If V14.5 also lands clean, V14.7 (parent-ref Lookup sweep) and\n  V14.8 (horizon debrief) can confidently say the Tm primitives are the platform\u0027s\n  process-engine layer, not \u0022another ERP module.\u0022","tags":["v14.4","content-production","alias","worked-example","n-equals-1-receipt"],"source":"SPICE.Apps.Erp.Tm/Parts.Tm.xml"},{"kind":"CrossModuleRule","id":"Rule.Tm.MrpSweep","name":"MRP-lite nightly sweep -\u003E MrpSuggestion per low-stock StockItem"},{"kind":"KnowledgeArticle","id":"KB.Tm.MrpLite","name":"V14.3 MRP-lite: scheduled CrossModuleRule as materialized-view analogue","description":"The first cycle to consume V14.2c\u0027s IStorageProvider.Enumerate seam.  Banks the pattern: cron-triggered enumerate\u002Bfilter\u002Bemit as a single declarative XML rule.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"V14.3 SHIPS the deterministic MRP-lite sweep without writing a new hosted service.  Instead, the V14.2c CrossModuleRule grammar gains a Schedule trigger as a one-of with Match:\n\n  \u003CCrossModuleRule Id=\u0022Rule.Tm.MrpSweep\u0022 ...\u003E\n  \u003CSchedule Cron=\u00220 2 * * *\u0022 /\u003E\n  \u003CFanOut Site=\u0022Inventory\u0022 List=\u0022StockItems\u0022\u003E\n    \u003Ccaml:Where\u003E\n      \u003Ccaml:Leq\u003E\n        \u003Ccaml:FieldRef Name=\u0022StOnHandQuantity\u0022 /\u003E\n        \u003Ccaml:Value Type=\u0022Number\u0022\u003E0\u003C/caml:Value\u003E\n      \u003C/caml:Leq\u003E\n    \u003C/caml:Where\u003E\n  \u003C/FanOut\u003E\n  \u003CEmit TargetSite=\u0022Manufacturing\u0022 TargetList=\u0022MrpSuggestions\u0022 ContentType=\u0022ContentType.MrpSuggestion\u0022\n        KeyTemplate=\u0022AUTO-MRP-{FanOut.StItemSku}-{FanOut.StWarehouseCode}\u0022\u003E\n    \u003CField Name=\u0022ItemSku\u0022 FromFanOut=\u0022StItemSku\u0022 /\u003E\n    ...\n  \u003C/Emit\u003E\n\u003C/CrossModuleRule\u003E\n\nWHAT THE V14.3 RESEARCH FOUND:\n\nThe pattern \u0022enumerate one list, compute derived quantity, emit per-row, on a schedule\u0022 is the materialized-view shape (Databricks REFRESH EVERY, ClickHouse refreshable MVs, dbt incremental \u002B unique_key).  SP Designer workflows expressed it via a \u0022Pause \u002B loop-back\u0022 hack on top of timer jobs; SP didn\u0027t have a clean declarative shape for it.  XSLT 3.0 streaming with xsl:result-document is the XML-native cousin but needs Saxon and fights pure-functional model with side-effect writes.\n\nThe cleanest SPICE-native answer turned out to be: extend the V14.2c CrossModuleRule grammar with a Schedule trigger.  Same FanOut/Emit semantics; only the trigger type changes.  Foundation\u0027s SchedulerHostedService gains a second pass that fires scheduled rules per minute-tick.  Result: zero new hosted services per future scan-and-emit feature.  All declarative XML.\n\nPATTERN BANKED:\n\n  Event-driven cross-module reaction:  \u003CMatch Department=\u0022...\u0022 List=\u0022...\u0022 To=\u0022...\u0022 /\u003E\n  Time-driven scan-and-emit:           \u003CSchedule Cron=\u00220 2 * * *\u0022 /\u003E\n\nBoth use the same \u003CFanOut/\u003E, \u003Ccaml:Where/\u003E, \u003CEmit/\u003E, \u003CField/\u003E, KeyTemplate.  The dispatcher\u0027s only branching is at the trigger level; everything downstream is shared.\n\nWHAT V14.3 DELIBERATELY DEFERS:\n\n  - Synthetic event fields ({Event.FiredAt}, {Event.RuleId}) for scheduled rules.  Today FromEvent and {Event.X} are rejected at parse time on scheduled rules.  Add when a real receipt needs them.\n  - Arithmetic in field bindings (Quantity = -QuantityPer * OrderQty).  Today bindings are literal \u002B FromEvent \u002B FromFanOut \u002B token substitution.  Add when a receipt needs computed values across two sources.\n  - LLM-driven MRP (an agent reasoning over forecast \u002B supplier lead-times \u002B capacity).  V15 scope.\n  - Per-item reorder thresholds (Field.MrpThreshold on ItemMaster).  V14.3 uses a global cron-baked threshold (the \u003CLeq\u003E...0\u003C/Leq\u003E predicate); future cycles can lift this into the ItemMaster.","tags":["v14.3","mrp","scheduled-rule","materialized-view","declarative"],"source":"SPICE.Apps.Erp.Tm/Parts.Tm.xml"},{"kind":"CrossModuleRule","id":"Rule.Tm.ProductionOrderCompleted","name":"ProductionOrder Completed -\u003E Ti ProductionReceipt for parent product"},{"kind":"FieldDefinition","id":"Field.ProjProjectCode","name":"ProjectCode"},{"kind":"FieldDefinition","id":"Field.ProjClientSku","name":"ClientSku"},{"kind":"FieldDefinition","id":"Field.ProjStartDate","name":"StartDate"},{"kind":"FieldDefinition","id":"Field.ProjEndDate","name":"EndDate"},{"kind":"FieldDefinition","id":"Field.ProjCurrencyCode","name":"CurrencyCode"},{"kind":"FieldDefinition","id":"Field.ProjTotalBudget","name":"TotalBudget"},{"kind":"FieldDefinition","id":"Field.ProjStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.ProjProjectType","name":"ProjectType"},{"kind":"FieldDefinition","id":"Field.ProjNotes","name":"Notes"},{"kind":"FieldDefinition","id":"Field.TaskTaskNumber","name":"TaskNumber"},{"kind":"FieldDefinition","id":"Field.TaskProjectCode","name":"ProjectCode"},{"kind":"FieldDefinition","id":"Field.TaskTitle","name":"TaskTitle"},{"kind":"FieldDefinition","id":"Field.TaskAssigneeSku","name":"AssigneeSku"},{"kind":"FieldDefinition","id":"Field.TaskComments","name":"TaskComments"},{"kind":"FieldDefinition","id":"Field.TaskPredecessors","name":"Predecessors"},{"kind":"FieldDefinition","id":"Field.TaskRelatedItems","name":"RelatedItems"},{"kind":"FieldDefinition","id":"Field.TaskParentID","name":"ParentID"},{"kind":"FieldDefinition","id":"Field.TaskDueDate","name":"DueDate"},{"kind":"FieldDefinition","id":"Field.TaskEstimateHours","name":"EstimateHours"},{"kind":"FieldDefinition","id":"Field.TaskStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.BudgProjectCode","name":"ProjectCode"},{"kind":"FieldDefinition","id":"Field.BudgAccountCode","name":"AccountCode"},{"kind":"FieldDefinition","id":"Field.BudgCategory","name":"Category"},{"kind":"FieldDefinition","id":"Field.BudgAmount","name":"Amount"},{"kind":"FieldDefinition","id":"Field.BudgDescription","name":"Description"},{"kind":"ContentType","id":"ContentType.ProjectDefinition","name":"Project Definition"},{"kind":"ContentType","id":"ContentType.ProjectTask","name":"Project Task"},{"kind":"ContentType","id":"ContentType.ProjectBudget","name":"Project Budget"},{"kind":"ListTemplate","id":"ListTemplate.ProjectDefinitions","name":"Project Definitions"},{"kind":"ListTemplate","id":"ListTemplate.ProjectTasks","name":"Project Tasks"},{"kind":"ListTemplate","id":"ListTemplate.ProjectBudgets","name":"Project Budgets"},{"kind":"KnowledgeArticle","id":"KB.Tp.Overview","name":"Tp package: Project module overview - the N=4 receipt","description":"What V12.8 ships, why Project closes the 4-module ERP loop, and how it cross-links to Td (Tasks reference SalesOrder lines) \u002B Tf (Budget lines reference ChartOfAccounts).","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"V12.8 SHIPS the N=4 receipt: Td (V12.4) \u002B Tf (V12.6) \u002B Ti (V12.7) \u002B Tp (this cycle) all live on the same V12.0 foundation with zero per-module C# (beyond the empty AppModuleBase subclass \u002B V12.7b cross-module listener which lives in Ti, not the foundation).  4 ContentTypes \u002B portal blueprint \u002B lookups \u002B Transitions = a working project-management module.\n\n  ContentType.ProjectDefinition  list \u0027Projects/Projects\u0027\n    Status: Planning -\u003E Active -\u003E Closed \u002B Cancelled escapes.\n    Lookups: ClientSku -\u003E Common/BusinessPartners (CUSTOMER), CurrencyCode -\u003E Common/Currencies.\n\n  ContentType.ProjectTask        list \u0027Projects/ProjectTasks\u0027\n    Status: Todo -\u003E InProgress -\u003E Done \u002B Blocked (recoverable) \u002B Cancelled (terminal).\n    AssigneeSku -\u003E Common/BusinessPartners (EMPLOYEE role expected).\n    ProjectCode -\u003E ProjectDefinition.ProjectCode (text cross-ref; V12.8b promotes to Lookup once self-list parent-ref settles).\n\n  ContentType.ProjectBudget      list \u0027Projects/ProjectBudgets\u0027\n    Quantity rows per (Project, Category, AccountCode).\n    No Transitions - budgets revise by new rows; versioning preserves history.\n\nWHY PROJECT CLOSES THE LOOP:\n  Td (Sales/Purchase/Shipment) covers the deal cycle.\n  Tf (Invoice/Payment/JournalEntry) covers the financial cycle.\n  Ti (StockItem/StockMove/BinLocation) covers the physical cycle.\n  Tp (Project/Task/Budget) covers the work cycle.\n\n  Together they span the four canonical ERP nouns (deal, money, stock, work).\n  An operator running Td \u002B Tf \u002B Ti \u002B Tp has the minimum-viable typed ERP.\n\nCROSS-MODULE LINKS (queued for V12.8b/V12.9):\n  - Tp.Task.Reference -\u003E Td.SalesOrder.OrderNumber (project work fulfilling a deal)\n  - Tp.Budget.AccountCode -\u003E Tf.ChartOfAccount.AccountCode (project cost mapping)\n  - V12.7b-style cross-module listener: Tp.Task -\u003E Done could fire Tf\n    JournalEntry posting (revenue recognition).","tags":["project","v12.8","n4-receipt"],"source":"SPICE.Apps.Erp.Tp/Parts.Tp.xml"},{"kind":"FieldDefinition","id":"Field.EmpEmployeeId","name":"EmployeeId"},{"kind":"FieldDefinition","id":"Field.EmpDisplayName","name":"DisplayName"},{"kind":"FieldDefinition","id":"Field.EmpEmail","name":"Email"},{"kind":"FieldDefinition","id":"Field.EmpManagerSku","name":"ManagerSku"},{"kind":"FieldDefinition","id":"Field.EmpHireDate","name":"HireDate"},{"kind":"ContentType","id":"ContentType.EmployeeProfile","name":"Employee Profile"},{"kind":"ListTemplate","id":"ListTemplate.EmployeeProfiles","name":"Employee Profiles"},{"kind":"FieldDefinition","id":"Field.TsEmployeeSku","name":"EmployeeSku"},{"kind":"FieldDefinition","id":"Field.TsWeekStarting","name":"WeekStarting"},{"kind":"FieldDefinition","id":"Field.TsMonHours","name":"MonHours"},{"kind":"FieldDefinition","id":"Field.TsTueHours","name":"TueHours"},{"kind":"FieldDefinition","id":"Field.TsWedHours","name":"WedHours"},{"kind":"FieldDefinition","id":"Field.TsThuHours","name":"ThuHours"},{"kind":"FieldDefinition","id":"Field.TsFriHours","name":"FriHours"},{"kind":"FieldDefinition","id":"Field.TsSatHours","name":"SatHours"},{"kind":"FieldDefinition","id":"Field.TsSunHours","name":"SunHours"},{"kind":"FieldDefinition","id":"Field.TsTotalHours","name":"TotalHours"},{"kind":"FieldDefinition","id":"Field.TsManagerSku","name":"ManagerSku"},{"kind":"FieldDefinition","id":"Field.TsStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.TsNotes","name":"Notes"},{"kind":"ContentType","id":"ContentType.Timesheet","name":"Timesheet"},{"kind":"ListTemplate","id":"ListTemplate.Timesheets","name":"Timesheets"},{"kind":"FieldDefinition","id":"Field.LrEmployeeSku","name":"EmployeeSku"},{"kind":"FieldDefinition","id":"Field.LrLeaveType","name":"LeaveType"},{"kind":"FieldDefinition","id":"Field.LrStartDate","name":"StartDate"},{"kind":"FieldDefinition","id":"Field.LrEndDate","name":"EndDate"},{"kind":"FieldDefinition","id":"Field.LrDurationDays","name":"DurationDays"},{"kind":"FieldDefinition","id":"Field.LrEmployeeTenureYears","name":"EmployeeTenureYears"},{"kind":"FieldDefinition","id":"Field.LrReason","name":"Reason"},{"kind":"FieldDefinition","id":"Field.LrManagerSku","name":"ManagerSku"},{"kind":"FieldDefinition","id":"Field.LrApprovalQueue","name":"ApprovalQueue"},{"kind":"FieldDefinition","id":"Field.LrStatus","name":"Status"},{"kind":"FieldDefinition","id":"Field.LrDecisionNotes","name":"DecisionNotes"},{"kind":"ContentType","id":"ContentType.HrLeaveRequest","name":"Leave Request"},{"kind":"DecisionTable","id":"DT.Hr.LeaveRouting","name":"Leave request approval-queue routing"},{"kind":"CrossModuleRule","id":"Rule.Hr.LeaveRequestRouted","name":"LeaveRequest entered ManagerReview -\u003E stamp DT-routed ApprovalQueue in place"},{"kind":"CrossModuleRule","id":"Rule.Hr.LeaveRequestRoutedHrReview","name":"LeaveRequest entered HRReview -\u003E stamp DT-routed ApprovalQueue in place"},{"kind":"ListTemplate","id":"ListTemplate.HrLeaveRequests","name":"Leave Requests"},{"kind":"SiteTemplate","id":"SiteTemplate.Helpdesk","name":"Helpdesk"},{"kind":"SiteTemplate","id":"SiteTemplate.Crm","name":"CRM"},{"kind":"SiteTemplate","id":"SiteTemplate.Inventory","name":"Inventory"},{"kind":"SiteTemplate","id":"SiteTemplate.MarketWatch","name":"Market Watch"},{"kind":"SiteTemplate","id":"SiteTemplate.Workspace","name":"Unified Workspace"},{"kind":"SiteTemplate","id":"SiteTemplate.Intranet","name":"Intranet in a box"},{"kind":"SiteTemplate","id":"SiteTemplate.ProductCatalog","name":"Product Catalog"},{"kind":"KnowledgeArticle","id":"KB.ObservatoryLayer","name":"The Observatory is an exchangeable layer over the spine - the world is projected, not painted","description":"Why V25.41 stands up SPICE.Apps.Observatory as a swappable SoC presentation layer whose scene-graph is projected from the spine (retiring the hand-authored /ship topology) and whose edges show the agent message bus live via the AG-UI stream.","version":"1.0.0","classification":"Internal","minimumRole":"Member","body":"The legacy /ship board looked alive but was half-painting: live data came from XQuery over the spine, yet the topology was hand-authored (the NODES array in ship-scene.js \u002B the Consoles dict in ShipBoardRenderer.cs) and the page chrome was built as C# strings (the FW.CsharpHtmlToXslt debt). The Observatory layer corrects this on two axes. First, the world is PROJECTED: the scene-graph is a Query-backed Board part deriving its nodes from spine entities (Category, Agency, ActorProfile, Machine, Board), so adding an agency in XML grows the view with zero JS/C# - the self-building city as a data consequence. Second, the bus is VISIBLE: in-flight messages render as animated dots on the topology edges, driven by the AG-UI event stream (the V25.40 leg) upgraded to resumable, deep-JSON state deltas. It is built as an exchangeable App layer (Core/Foundation-only); the App owns the scene-graph data \u002B XSLT skins, while the renderer JS, the thin controller shim, and the vendored client assets stay in the host - the Marketplace/GalleryController SoC pattern. Bus visibility is a projection channel over the spine \u002B AG-UI, never a parallel coordination/rendering stack (KB.AgentProtocolChannels); the tap is read-only.","tags":["observability","ag-ui","projection","soc","app-layer","game-ui"],"source":"docs/plans/2026-06-01-001-feat-observatory-live-layer-plan.md"},{"kind":"Board","id":"Board.Station","name":"The Station (live)"},{"kind":"Board","id":"Board.NodeDetail","name":"Node detail (inspector)"},{"kind":"Board","id":"Board.Progress","name":"Progression (the captain\u0027s ladder \u002B log)"},{"kind":"Board","id":"Board.Knowledge","name":"Research library"},{"kind":"DecisionTable","id":"DT.CombatDamage","name":"Warfront combat damage multipliers"},{"kind":"DecisionTable","id":"DT.TechGate","name":"Warfront tech and age gates"},{"kind":"Board","id":"Board.Warfront","name":"Warfront (the city at war)"},{"kind":"FieldDefinition","id":"Field.SKU","name":"SKU"},{"kind":"FieldDefinition","id":"Field.PriceUSD","name":"PriceUSD"},{"kind":"FieldDefinition","id":"Field.ProductCategory","name":"ProductCategory"},{"kind":"FieldDefinition","id":"Field.RawTitle","name":"RawTitle"},{"kind":"FieldDefinition","id":"Field.RawVendor","name":"RawVendor"},{"kind":"FieldDefinition","id":"Field.RawBlob","name":"RawBlob"},{"kind":"FieldDefinition","id":"Field.SourceRawId","name":"SourceRawId"},{"kind":"FieldDefinition","id":"Field.EnrichedAt","name":"EnrichedAt"},{"kind":"FieldDefinition","id":"Field.EnrichmentStatus","name":"EnrichmentStatus"},{"kind":"FieldDefinition","id":"Field.EnrichmentSource","name":"EnrichmentSource"},{"kind":"ContentType","id":"ContentType.RawProduct","name":"Raw Product"},{"kind":"ContentType","id":"ContentType.Product","name":"Product"},{"kind":"ListTemplate","id":"ListTemplate.RawProducts","name":"Raw Products"},{"kind":"ListTemplate","id":"ListTemplate.Products","name":"Products"},{"kind":"Skill","id":"Skill.EnrichProduct","name":"Enrich Product","description":"Read a freshly-landed RawProduct row, infer typed fields (SKU, Vendor Lookup, ProductCategory, PriceUSD), and emit a ProvisioningDelta with one AddListItem against the sibling Products list. SourceRawId points back to the raw row; the raw row\u0027s EnrichmentStatus flips Pending -\u003E Enriched in the same delta.","version":"1.0.0","classification":"Internal","minimumRole":"Lead","category":"Processing","requiresApproval":false,"capabilities":["Call Tool.ListSchema(site, list=Products) to confirm the enriched-row field shape","Call Tool.ListSchema(site=Directory, list=Organizations) to discover known vendors before resolving Field.Vendor","Parse Field.RawTitle \u002B Field.RawBlob into typed values (SKU pattern, category hint, list price)","Pick a ProductCategory term value from the ProductCategories TermSet (slash-joined Path)","Emit a ProvisioningDelta with one AddListItem against Products (with SourceRawId set) and one updating the source RawProduct\u0027s EnrichmentStatus to Enriched"],"requiresTools":["Tool.Llm","Tool.ListSchema"]},{"kind":"Phase","id":"Phase.EnrichProduct","name":"Enrich Product"},{"kind":"Workflow","id":"Workflow.EnrichProduct","name":"Enrich Product"},{"kind":"EventReceiver","id":"ER.OnRawProductAdded","name":"On raw product added: run Workflow.EnrichProduct"},{"kind":"Schedule","id":"Schedule.WeeklyVendorPull","name":"Weekly vendor pull cadence"},{"kind":"Feature","id":"Feature.ProductCatalog","name":"Product Catalog"},{"kind":"FieldDefinition","id":"Field.PowerW","name":"PowerW"},{"kind":"FieldDefinition","id":"Field.PanelType","name":"PanelType"},{"kind":"FieldDefinition","id":"Field.CellTech","name":"CellTech"},{"kind":"FieldDefinition","id":"Field.EfficiencyPct","name":"EfficiencyPct"},{"kind":"FieldDefinition","id":"Field.VocV","name":"VocV"},{"kind":"FieldDefinition","id":"Field.VmpV","name":"VmpV"},{"kind":"FieldDefinition","id":"Field.ImpA","name":"ImpA"},{"kind":"FieldDefinition","id":"Field.IscA","name":"IscA"},{"kind":"FieldDefinition","id":"Field.WeightKg","name":"WeightKg"},{"kind":"FieldDefinition","id":"Field.DimensionsText","name":"DimensionsText"},{"kind":"FieldDefinition","id":"Field.WarrantyText","name":"WarrantyText"},{"kind":"FieldDefinition","id":"Field.GpcBrick","name":"GpcBrick"},{"kind":"FieldDefinition","id":"Field.LowestOfferEur","name":"LowestOfferEur"},{"kind":"FieldDefinition","id":"Field.LowestOfferProvider","name":"LowestOfferProvider"},{"kind":"FieldDefinition","id":"Field.LowestLandedCostEur","name":"LowestLandedCostEur"},{"kind":"FieldDefinition","id":"Field.LowestLandedCostProvider","name":"LowestLandedCostProvider"},{"kind":"FieldDefinition","id":"Field.EurPerWp","name":"EurPerWp"},{"kind":"FieldDefinition","id":"Field.WeightPerWp","name":"WeightPerWp"},{"kind":"FieldDefinition","id":"Field.AvgIndependentRatingPct","name":"AvgIndependentRatingPct"},{"kind":"FieldDefinition","id":"Field.IndependentReviewCount","name":"IndependentReviewCount"},{"kind":"FieldDefinition","id":"Field.CatalogProductRef","name":"CatalogProductRef"},{"kind":"FieldDefinition","id":"Field.ProviderRef","name":"ProviderRef"},{"kind":"FieldDefinition","id":"Field.Price","name":"Price"},{"kind":"FieldDefinition","id":"Field.PriceVat","name":"PriceVat"},{"kind":"FieldDefinition","id":"Field.ShippingCost","name":"ShippingCost"},{"kind":"FieldDefinition","id":"Field.Availability","name":"Availability"},{"kind":"FieldDefinition","id":"Field.CheckedOn","name":"CheckedOn"},{"kind":"FieldDefinition","id":"Field.Rating","name":"Rating"},{"kind":"FieldDefinition","id":"Field.RatingScale","name":"RatingScale"},{"kind":"FieldDefinition","id":"Field.Independence","name":"Independence"},{"kind":"FieldDefinition","id":"Field.MeasuredOutputPct","name":"MeasuredOutputPct"},{"kind":"FieldDefinition","id":"Field.FailureReports","name":"FailureReports"},{"kind":"FieldDefinition","id":"Field.PublishingRollupImage","name":"PublishingRollupImage"},{"kind":"ContentType","id":"ContentType.CatalogProduct","name":"Catalog Product"},{"kind":"FieldDefinition","id":"Field.RequisitionStatus","name":"RequisitionStatus"},{"kind":"ContentType","id":"ContentType.PurchaseRequisition","name":"Purchase Requisition"},{"kind":"ListTemplate","id":"ListTemplate.PurchaseRequisitions","name":"Purchase Requisitions"},{"kind":"FieldDefinition","id":"Field.OfferShipToCountry","name":"ShipToCountry"},{"kind":"FieldDefinition","id":"Field.RecommendedOfferRef","name":"RecommendedOfferRef"},{"kind":"FieldDefinition","id":"Field.PurchaseOrderRef","name":"PurchaseOrderRef"},{"kind":"FieldDefinition","id":"Field.LandedCostEur","name":"LandedCostEur"},{"kind":"FieldDefinition","id":"Field.ProviderShipsTo","name":"ShipsTo"},{"kind":"ContentType","id":"ContentType.Offer","name":"Offer"},{"kind":"ContentType","id":"ContentType.Review","name":"Review"},{"kind":"ContentType","id":"ContentType.Provider","name":"Provider"},{"kind":"Tool","id":"Tool.Catalog.FitsRequisition","name":"Fit check for a purchase requisition","description":"Judge every catalog candidate of a purchase requisition\u0027s category by its declared fit rules (DT.Catalog.Fits.Category: each rule Yes, No or Unchecked with the reason) and price them by the catalog rollups; recommend the cheapest fitting candidate delivered to the requisition\u0027s country within its budget. Args: site, list, itemId (the requisition); recommend=true also writes RecommendedOfferRef and a Fit check section to the requisition\u0027s Comments as the caller.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"FitsRequisitionToolInvoker","endpoint":null,"loadStrategy":"Lazy"},{"kind":"SavedQuery","id":"Query.Procurement.OpenRequisitions","name":"Open purchase requisitions"},{"kind":"SavedQuery","id":"Query.Procurement.OffersForProduct","name":"Offers for one catalog product"},{"kind":"SavedQuery","id":"Query.Procurement.SuppliersShippingTo","name":"Suppliers that deliver to a country"},{"kind":"SavedQuery","id":"Query.Terms.ProductCategoryByLabel","name":"Find a product category by any of its names"},{"kind":"FieldDefinition","id":"Field.PowerTolerancePct","name":"PowerTolerancePct"},{"kind":"FieldDefinition","id":"Field.MaxSystemVoltageV","name":"MaxSystemVoltageV"},{"kind":"FieldDefinition","id":"Field.ReverseCurrentA","name":"ReverseCurrentA"},{"kind":"FieldDefinition","id":"Field.TempCoeffPmppPctK","name":"TempCoeffPmppPctK"},{"kind":"FieldDefinition","id":"Field.TempCoeffVocPctK","name":"TempCoeffVocPctK"},{"kind":"FieldDefinition","id":"Field.TempCoeffIscPctK","name":"TempCoeffIscPctK"},{"kind":"FieldDefinition","id":"Field.OperatingTempRange","name":"OperatingTempRange"},{"kind":"FieldDefinition","id":"Field.CellMaterial","name":"CellMaterial"},{"kind":"FieldDefinition","id":"Field.CellCount","name":"CellCount"},{"kind":"FieldDefinition","id":"Field.ModuleStructure","name":"ModuleStructure"},{"kind":"FieldDefinition","id":"Field.ModuleDesign","name":"ModuleDesign"},{"kind":"FieldDefinition","id":"Field.WithFrame","name":"WithFrame"},{"kind":"FieldDefinition","id":"Field.FrameColour","name":"FrameColour"},{"kind":"FieldDefinition","id":"Field.CellColour","name":"CellColour"},{"kind":"FieldDefinition","id":"Field.BackColour","name":"BackColour"},{"kind":"FieldDefinition","id":"Field.AntiReflectionGlass","name":"AntiReflectionGlass"},{"kind":"FieldDefinition","id":"Field.OverheadGlazing","name":"OverheadGlazing"},{"kind":"FieldDefinition","id":"Field.LengthMm","name":"LengthMm"},{"kind":"FieldDefinition","id":"Field.WidthMm","name":"WidthMm"},{"kind":"FieldDefinition","id":"Field.ThicknessMm","name":"ThicknessMm"},{"kind":"FieldDefinition","id":"Field.WithCable","name":"WithCable"},{"kind":"FieldDefinition","id":"Field.CableLengthMm","name":"CableLengthMm"},{"kind":"FieldDefinition","id":"Field.BypassDiodes","name":"BypassDiodes"},{"kind":"FieldDefinition","id":"Field.BusbarCount","name":"BusbarCount"},{"kind":"FieldDefinition","id":"Field.NmotC","name":"NmotC"},{"kind":"FieldDefinition","id":"Field.Certifications","name":"Certifications"},{"kind":"FieldDefinition","id":"Field.DegradationText","name":"DegradationText"},{"kind":"FieldDefinition","id":"Field.BendLimit","name":"BendLimit"},{"kind":"FieldDefinition","id":"Field.Walkable","name":"Walkable"},{"kind":"FieldDefinition","id":"Field.MechanicalLoad","name":"MechanicalLoad"},{"kind":"FieldDefinition","id":"Field.JunctionBoxConnector","name":"JunctionBoxConnector"},{"kind":"ContentType","id":"ContentType.SolarPanel","name":"Solar panel"},{"kind":"Skill","id":"Skill.CatalogResearch.SolarPanel","name":"Solar panel catalog research","description":"Research Solar panel models for the ProductCatalog catalog from sources in a fixed order - datasheet, independent tests, customer reviews, community, offers - asking every ETIM EC001746 feature and the declared extensions, and leaving a value empty rather than guessing it.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Processing","requiresApproval":false,"capabilities":["Find and read the manufacturer datasheet (PDF) of each model and extract every listed feature with its unit and the page it is on","Find independent tests and compare measured output with the rating","Collect customer ratings with their count and independence, and community pros, cons and failure reports","Record current offers with price, currency, VAT basis, shipping and the date seen"],"requiresTools":["Tool.DeepResearch","Tool.WebSearch"]},{"kind":"ActorProfile","id":"Actor.CatalogResearcher.SolarPanel","name":"Solar panel catalog researcher"},{"kind":"Phase","id":"Phase.CatalogResearch.SolarPanel","name":"Solar panel catalog research"},{"kind":"Eval","id":"Eval.CatalogResearch.SolarPanel","name":"Solar panel catalog research is sourced and complete"},{"kind":"Workflow","id":"Workflow.CatalogResearch.SolarPanel","name":"Solar panel catalog research"},{"kind":"Phase","id":"Phase.CatalogExtract.SolarPanel","name":"Solar panel datasheet extraction"},{"kind":"Eval","id":"Eval.CatalogExtract.SolarPanel","name":"Solar panel datasheet extraction is real and correct"},{"kind":"Workflow","id":"Workflow.CatalogExtract.SolarPanel","name":"Solar panel datasheet extraction"},{"kind":"SavedQuery","id":"Query.Catalog.Compare.SolarPanel","name":"Compare the catalog: Solar panel"},{"kind":"FieldDefinition","id":"Field.TyreSize","name":"TyreSize"},{"kind":"FieldDefinition","id":"Field.TyreConstruction","name":"TyreConstruction"},{"kind":"FieldDefinition","id":"Field.SectionWidthMm","name":"SectionWidthMm"},{"kind":"FieldDefinition","id":"Field.AspectRatioPct","name":"AspectRatioPct"},{"kind":"FieldDefinition","id":"Field.RimDiameterIn","name":"RimDiameterIn"},{"kind":"FieldDefinition","id":"Field.OverallDiameterMm","name":"OverallDiameterMm"},{"kind":"FieldDefinition","id":"Field.LoadIndexSingle","name":"LoadIndexSingle"},{"kind":"FieldDefinition","id":"Field.LoadIndexDual","name":"LoadIndexDual"},{"kind":"FieldDefinition","id":"Field.MaxLoadKg","name":"MaxLoadKg"},{"kind":"FieldDefinition","id":"Field.SpeedSymbol","name":"SpeedSymbol"},{"kind":"FieldDefinition","id":"Field.PlyRating","name":"PlyRating"},{"kind":"FieldDefinition","id":"Field.CommercialMark","name":"CommercialMark"},{"kind":"FieldDefinition","id":"Field.TubeType","name":"TubeType"},{"kind":"FieldDefinition","id":"Field.ApprovedRimWidths","name":"ApprovedRimWidths"},{"kind":"FieldDefinition","id":"Field.EuRollingClass","name":"EuRollingClass"},{"kind":"FieldDefinition","id":"Field.EuWetGripClass","name":"EuWetGripClass"},{"kind":"FieldDefinition","id":"Field.EuNoiseDb","name":"EuNoiseDb"},{"kind":"FieldDefinition","id":"Field.RimSize","name":"RimSize"},{"kind":"FieldDefinition","id":"Field.BoltPattern","name":"BoltPattern"},{"kind":"FieldDefinition","id":"Field.CentreBoreMm","name":"CentreBoreMm"},{"kind":"FieldDefinition","id":"Field.OffsetEtMm","name":"OffsetEtMm"},{"kind":"FieldDefinition","id":"Field.DotDate","name":"DotDate"},{"kind":"ContentType","id":"ContentType.CaravanTyre","name":"Caravan tyre"},{"kind":"Skill","id":"Skill.CatalogResearch.CaravanTyre","name":"Caravan tyre catalog research","description":"Research Caravan tyre models for the ProductCatalog catalog from sources in a fixed order - datasheet, independent tests, customer reviews, community, offers - asking every ETRTO UN-ECE-R54 feature and the declared extensions, and leaving a value empty rather than guessing it.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Processing","requiresApproval":false,"capabilities":["Find and read the manufacturer datasheet (PDF) of each model and extract every listed feature with its unit and the page it is on","Find independent tests and compare measured output with the rating","Collect customer ratings with their count and independence, and community pros, cons and failure reports","Record current offers with price, currency, VAT basis, shipping and the date seen"],"requiresTools":["Tool.DeepResearch","Tool.WebSearch"]},{"kind":"ActorProfile","id":"Actor.CatalogResearcher.CaravanTyre","name":"Caravan tyre catalog researcher"},{"kind":"Phase","id":"Phase.CatalogResearch.CaravanTyre","name":"Caravan tyre catalog research"},{"kind":"Eval","id":"Eval.CatalogResearch.CaravanTyre","name":"Caravan tyre catalog research is sourced and complete"},{"kind":"Workflow","id":"Workflow.CatalogResearch.CaravanTyre","name":"Caravan tyre catalog research"},{"kind":"Phase","id":"Phase.CatalogExtract.CaravanTyre","name":"Caravan tyre datasheet extraction"},{"kind":"Eval","id":"Eval.CatalogExtract.CaravanTyre","name":"Caravan tyre datasheet extraction is real and correct"},{"kind":"Workflow","id":"Workflow.CatalogExtract.CaravanTyre","name":"Caravan tyre datasheet extraction"},{"kind":"SavedQuery","id":"Query.Catalog.Compare.CaravanTyre","name":"Compare the catalog: Caravan tyre"},{"kind":"DecisionTable","id":"DT.Catalog.Substitutes.CaravanTyre","name":"Caravan tyre size substitutes"},{"kind":"DecisionTable","id":"DT.Catalog.Fits.CaravanTyre","name":"Caravan tyre fit verdict"},{"kind":"FieldDefinition","id":"Field.CurrentTyreSize","name":"CurrentTyreSize"},{"kind":"FieldDefinition","id":"Field.RegisteredSizes","name":"RegisteredSizes"},{"kind":"FieldDefinition","id":"Field.MaxMassKg","name":"MaxMassKg"},{"kind":"FieldDefinition","id":"Field.WheelsOnAxle","name":"WheelsOnAxle"},{"kind":"FieldDefinition","id":"Field.TyreOrWheel","name":"TyreOrWheel"},{"kind":"FieldDefinition","id":"Field.CurrentBoltPattern","name":"CurrentBoltPattern"},{"kind":"FieldDefinition","id":"Field.RimIsTubeless","name":"RimIsTubeless"},{"kind":"FieldDefinition","id":"Field.SubstitutesAllowed","name":"SubstitutesAllowed"},{"kind":"ContentType","id":"ContentType.CaravanTyreRequisition","name":"Caravan tyre requisition"},{"kind":"FieldDefinition","id":"Field.DeckTopic","name":"DeckTopic"},{"kind":"FieldDefinition","id":"Field.DeckAudience","name":"DeckAudience"},{"kind":"FieldDefinition","id":"Field.DeckSlideCount","name":"DeckSlideCount"},{"kind":"FieldDefinition","id":"Field.DeckOutline","name":"DeckOutline"},{"kind":"FieldDefinition","id":"Field.DeckExportUrl","name":"DeckExportUrl"},{"kind":"FieldDefinition","id":"Field.StudioRequestSummary","name":"StudioRequestSummary"},{"kind":"FieldDefinition","id":"Field.StudioSpecialists","name":"StudioSpecialists"},{"kind":"FieldDefinition","id":"Field.ResearchFindings","name":"ResearchFindings"},{"kind":"FieldDefinition","id":"Field.ResearchKeyClaims","name":"ResearchKeyClaims"},{"kind":"FieldDefinition","id":"Field.ResearchCitations","name":"ResearchCitations"},{"kind":"FieldDefinition","id":"Field.ResearchConfidence","name":"ResearchConfidence"},{"kind":"ContentType","id":"ContentType.StudioRouteDecision","name":"Studio Route Decision"},{"kind":"ContentType","id":"ContentType.ResearchReport","name":"Research Report"},{"kind":"ContentType","id":"ContentType.SlideDeck","name":"Slide Deck"},{"kind":"ListTemplate","id":"ListTemplate.StudioRouteDecisions","name":"Studio Route Decisions"},{"kind":"ListTemplate","id":"ListTemplate.SlideDecks","name":"Slide Decks"},{"kind":"ListTemplate","id":"ListTemplate.ResearchReports","name":"Research Reports"},{"kind":"ActorProfile","id":"Actor.StudioOrchestrator","name":"Studio Orchestrator"},{"kind":"ActorProfile","id":"Actor.SlideAuthor","name":"Slide Author"},{"kind":"ActorProfile","id":"Actor.DeepResearch","name":"Deep Research"},{"kind":"ActorProfile","id":"Actor.ImageGen","name":"Image Generation"},{"kind":"ActorProfile","id":"Actor.VideoGen","name":"Video Generation"},{"kind":"ActorProfile","id":"Actor.DocAuthor","name":"Document Author"},{"kind":"ActorProfile","id":"Actor.MediaProducer","name":"Media Producer"},{"kind":"Skill","id":"Skill.RouteStudioRequest","name":"Route Studio Request","description":"Orchestrator skill: parse the userTask, distil to a typed StudioRouteDecision, decide which specialists need to fire. Never produces the actual deliverable.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Management","requiresApproval":false,"capabilities":["Pure routing, no content authorship","Disambiguate ambiguous requests by emitting OpenQuestions"],"requiresTools":[]},{"kind":"Skill","id":"Skill.GenerateImage","name":"Generate Image","description":"ImageGen skill: invoke Tool.GenerateImage with a prompt, model, and size. Returns one image URL per call.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Documentation","requiresApproval":false,"capabilities":["Single-image invocations only - no batch generation","Defers prompt-engineering judgment to the calling specialist"],"requiresTools":[]},{"kind":"Skill","id":"Skill.GenerateVideo","name":"Generate Video","description":"VideoGen skill: invoke Tool.GenerateVideo with a prompt and duration. Highest-cost specialist on the platform - Lead role gate \u002B 0.50 USD per-call cap.","version":"1.0.0","classification":"Confidential","minimumRole":"Lead","category":"Documentation","requiresApproval":false,"capabilities":["Short clips only - default 8s, hard-cap 60s","Asks for confirmation above 15s"],"requiresTools":[]},{"kind":"Skill","id":"Skill.DeepResearch","name":"Deep Research","description":"DeepResearch skill: evidence gathering across the platform\u0027s stored knowledge (vector \u002B graph) plus fresh web/arXiv lookups. Output is a structured ResearchReport that downstream specialists treat as the evidence base.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Documentation","requiresApproval":false,"capabilities":["Vector \u002B graph recall before web search (cheapest wins first)","Citable claims only - if it can\u0027t be sourced, mark Low confidence"],"requiresTools":[]},{"kind":"Skill","id":"Skill.GenerateSlides","name":"Generate Slides","description":"SlideAuthor skill: produce a Markdown slide outline from a StudioRouteDecision PriorOutput. Output is the structured ContentType.SlideDeck; the V11.22b tool invoker handles HTML\u002BPPTX export.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Documentation","requiresApproval":false,"capabilities":["Outline-first, never freehand prose","One heading per slide, 2-4 bullets per slide"],"requiresTools":[]},{"kind":"Skill","id":"Skill.GenerateDocument","name":"Generate Document","description":"DocAuthor skill: produce a long-form document from a StudioRouteDecision PriorOutput. V11.22d wires the PDF export tool; until then the document body lives as the typed Note field on the ContentType.Document row.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Documentation","requiresApproval":false,"capabilities":["Structured prose with clear sections","Inline citations, no buried lede"],"requiresTools":[]},{"kind":"Skill","id":"Skill.ProduceMediaPack","name":"Produce Media Pack","description":"V20.3 composite-skill worked example: a media-production qualification that subsumes Generate Image \u002B Generate Video \u002B Generate Slides. Competency is satisfied either by declaring this skill directly or by being (recursively) competent in all of its RequiresSkill children.","version":"1.0.0","classification":"Internal","minimumRole":"Member","category":"Documentation","requiresApproval":false,"capabilities":["Coordinate image, video, and slide outputs into one deliverable"],"requiresTools":[]},{"kind":"Tool","id":"Tool.RenderSlideDeck","name":"Render Slide Deck","description":"V11.22b inline Markdown -\u003E HTML5 deck renderer. One section per \u0027#\u0027-prefixed slide heading; \u0027-\u0027/\u0027*\u0027 bullets become li entries. V11.22j: a Markdown image line ![alt](gen:prompt) adds a hero image to the slide - gen: resolves to a free Pollinations image URL (browser fetches it; renderer stays pure), http(s) URLs pass through. Args: outline (required Markdown), topic (optional cover title), audience (optional subtitle). Output: complete HTML5 document with a self-contained inline stylesheet. No file I/O - the caller chooses where to persist. View live at /studio/deck.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"SlideDeckRenderToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.RenderDocument","name":"Render Document","description":"V11.22d inline Markdown -\u003E HTML5 document renderer with a print-friendly stylesheet. Subset supported: headings (# ## ###), paragraphs, bullet lists (- or *), numbered lists (1.), bold (**text**), italic (*text*), inline code (\u0060code\u0060), links ([text](url)), images ![alt](src). V11.22j: an image src of gen:prompt resolves to a free Pollinations image URL. Args: markdown (required body), title (optional cover heading), author (optional byline). Output: complete HTML5 document - any headless-Chromium wrapper can ingest it for PDF export. View live at /studio/doc.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"DocumentRenderToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.ExportDeckPptx","name":"Export Deck (PPTX)","description":"V11.22g Markdown outline -\u003E real .pptx (PresentationML) export via dependency-free OpenXML - the download sibling of Tool.RenderSlideDeck (same outline grammar, same parse). Args: outline (required Markdown, one \u0027#\u0027-heading per slide, \u0027-\u0027/\u0027*\u0027 bullets), topic (optional cover title), audience (optional cover subtitle). Output: a Markdown summary followed by the .pptx package as Base64 (data:pptx;base64,...). Emits the ISO/IEC 29500 minimal part set (presentation \u002B presProps \u002B master \u002B layout \u002B theme \u002B one part per slide) so PowerPoint opens it without repair.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"PptxExportToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.ExportDocumentDocx","name":"Export Document (DOCX)","description":"V11.22f Markdown -\u003E real .docx (WordprocessingML) export via dependency-free OpenXML - the download sibling of Tool.RenderDocument (same Markdown subset, same input). Args: markdown (required body), title (optional), author (optional). Output: a Markdown summary followed by the .docx package as Base64 (data:docx;base64,...). Closes the OpenSwarm \u0027Docs Agent -\u003E Word\u0027 gap the system way: an OPC package is a zip of XML parts, so no library is needed.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"DocxExportToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.GenerateImage","name":"Generate Image","description":"V11.22k image generation as one machine with interchangeable vendors (IImageProvider strategy). Args: prompt (required), provider (optional: pollinations [free/keyless, default] | cloudflare [FLUX, free tier, 1024x1024] | gemini [Nano Banana, needs billing] | fal [paid]), model/width/height/steps (optional). Returns the image inline as a data:image base64 URI (vendors return bytes; a URL-only vendor surfaces its link). Keyed vendors degrade to an actionable \u0027not configured\u0027 notice.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"GenerateImageToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Tool","id":"Tool.GenerateVideo","name":"Generate Video","description":"V11.22e provider-agnostic video generator (Sora / Veo / Seedance / RunwayML). Gated on Plugins:videogen:ApiKey \u002B Plugins:videogen:Endpoint - degrades silently when either is absent. Args: prompt (required), durationSec (optional, default 8, capped at 60). Returns Markdown summary of the request \u002B raw response. Cost-aware by design: durationSec clamping \u002B V8.5a per-actor cost ceiling on Actor.VideoGen.","version":"1.0.0","classification":"Internal","minimumRole":"Member","provider":"VideoGenToolInvoker","endpoint":null,"loadStrategy":"Eager"},{"kind":"Phase","id":"Phase.RouteStudioRequest","name":"Route Studio Request"},{"kind":"Phase","id":"Phase.DeepResearch","name":"Deep Research"},{"kind":"Phase","id":"Phase.GenerateSlides","name":"Generate Slides"},{"kind":"Phase","id":"Phase.GenerateDocument","name":"Generate Document"},{"kind":"Workflow","id":"Workflow.StudioRequest","name":"Studio Request"},{"kind":"FieldDefinition","id":"Field.SprintCode","name":"SprintCode"},{"kind":"FieldDefinition","id":"Field.SprintGoal","name":"SprintGoal"},{"kind":"FieldDefinition","id":"Field.SprintStartDate","name":"SprintStartDate"},{"kind":"FieldDefinition","id":"Field.SprintEndDate","name":"SprintEndDate"},{"kind":"FieldDefinition","id":"Field.SprintStatus","name":"SprintStatus"},{"kind":"FieldDefinition","id":"Field.EpicCode","name":"EpicCode"},{"kind":"FieldDefinition","id":"Field.EpicGoal","name":"EpicGoal"},{"kind":"FieldDefinition","id":"Field.EpicStatus","name":"EpicStatus"},{"kind":"ContentType","id":"ContentType.Sprint","name":"Sprint"},{"kind":"ContentType","id":"ContentType.Epic","name":"Epic"},{"kind":"ListTemplate","id":"ListTemplate.Sprints","name":"Sprints"},{"kind":"ListTemplate","id":"ListTemplate.Epics","name":"Epics"},{"kind":"KnowledgeArticle","id":"KB.Tracker.Overview","name":"Tracker package: native Jira-equivalent App","description":"What V13.1a ships, why we built rather than imported, and how Sprint\u002BEpic compose with the platform\u0027s existing ContentType.Issue.","version":"1.0.0","classification":"Internal","minimumRole":"Assistant","body":"V13.1 was originally backlog-shaped as \u0022first external connector: Jira/Linear ticket import\u0022.  The redirect during the V13.1a kick-off was \u0022make our own Jira on our platform way\u0022 - i.e. the platform IS the issue tracker.  The receipt: zero external system to authenticate against, zero webhook to keep alive, and the typed-XML spine carries through.\n\nV13.1a SHIPS:\n  ContentType.Sprint   list \u0027IssueTracker/Sprints\u0027\n    Planning -\u003E Active -\u003E Closed with Cancelled escape from Planning.\n    Fields: SprintCode \u002B SprintGoal \u002B SprintStartDate \u002B SprintEndDate \u002B SprintStatus.\n\n  ContentType.Epic     list \u0027IssueTracker/Epics\u0027\n    Open -\u003E InProgress -\u003E Done with Cancelled escape.\n    Fields: EpicCode \u002B EpicGoal \u002B EpicStatus.\n\n  ContentType.Issue extension (in SPICE.Web/Config/Parts.xml):\n    \u002B Field.IssueType        (Choice: Bug/Story/Task/Epic)\n    \u002B Field.StoryPoints      (Number)\n    \u002B Field.IssueSprintRef   (Lookup -\u003E IssueTracker/Sprints)\n    \u002B Field.IssueEpicRef     (Lookup -\u003E IssueTracker/Epics)\n    \u002B Field.IssueReporter    (Lookup -\u003E Directory/People)\n    \u002B Field.IssueStatus      (existing) gains Selected / InReview / Done choices\n    \u002B Transitions block: Open -\u003E Selected -\u003E InProgress -\u003E InReview -\u003E Done\n      (Jira-flavour) coexisting with Open -\u003E InProgress -\u003E Resolved -\u003E Closed\n      (classic SP flavour) so existing Feature.IssueTracker depts stay valid.\n\n  IssueTrackerPortal blueprint (in SAF-Site-Manifest.xml):\n    Tracker department.  Lists: Issues, Epics, Sprints, IssueComments.\n    Feature.IssueTracker activated so the existing open/assign/comment/resolve\n    skills bind.\n\nWHY BUILD RATHER THAN IMPORT:\n  An external connector would have shipped one binding per third-party tracker\n  (Jira, Linear, Azure DevOps, ...) plus the inbound-webhook plumbing per binding.\n  The native shape compounds against everything else in the platform:\n    - V12.0b Transitions: BaaN-style Next-step buttons render automatically.\n    - V12.3 Tool.AdvanceListItem: MCP clients advance Issues via tool call.\n    - V11.1\u002BV11.2: agent phases can emit typed Issues via OutputSchema/OutputList.\n    - F4 refined ListView: Kanban projection is one ?refine=IssueStatus query away.\n    - F8 admin portal: cross-site rollup just works.\n    - V12.7b cross-module listeners: Sprint.Closed -\u003E auto-create retro Issue is one wire away.\n\nThe Lookup fields (Sprint, Epic) are still resolvable when the IssueTrackerPortal\nblueprint is absent - the FormView simply renders empty pickers.  Other depts\ngain the Jira-flavour fields on Issue without being forced to populate them.\n\nV13.1b SHIPS (deterministic sprint cadence):\n  SprintCadenceHostedService timer (registered by TrackerAppModule;\n  ticks every 10 minutes) calls SprintCadenceService.Tick which:\n    (a) Opens the current ISO-week sprint if absent and we\u0027re past\n        Monday 09:00 UTC.  Sprint key is canonical Sprint-YYYY-Wnn\n        (e.g. Sprint-2026-W21) so the next-week key is computable\n        without enumerating the list.\n    (b) Auto-closes the previous-week sprint by flipping its\n        SprintStatus from Active to Closed once the new week has\n        started.  Deterministic because the previous-week key is\n        computable from \u0027now - 7 days\u0027.\n\n  Why a hosted service rather than Schedule \u002B Workflow \u002B agent:\n  sprint open/close is date arithmetic, not a reasoning task.\n  Routing it through the agent path would spend LLM tokens on\n  plumbing and would fail in Echo-only dev environments.  The OodaLoop\n  App is the showcase of Schedule \u002B agent (Workflow.OodaCycle);\n  Tracker is the symmetric showcase of Schedule \u002B deterministic\n  listener.  Both patterns are now load-bearing in the platform.\n\nQUEUED FOR V13.1c:\n  V13.1c: Rollover of unfinished Issues (IssueStatus != Done/Closed/\n          Resolved) from the closing sprint into the new sprint;\n          requires list enumeration (today only the SqlServer storage\n          provider exposes that).  Kanban projection (refined ListView\n          grouped by IssueStatus).  HubPortal Jira card cross-site\n          rollup of all Active Sprints \u002B WIP.","tags":["tracker","jira","v13.1a"],"source":"SPICE.Apps.Tracker/Parts.Tracker.xml"}]