Merge pull request #6 from Curabis/rule/bc-mcp-discovery-and-governance-autonomy

[BCQuality] BC MCP discovery guidance + autonomous Francis->Immanuel hand-off
This commit is contained in:
Michael Dieringer 2026-07-04 08:32:46 +02:00 • committed by GitHub
commit 7f925855b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 117 additions and 7 deletions

View file

@ -147,11 +147,25 @@ A weak proposal wastes Immanuel's time. Francis would rather say
## Hand-off ## Hand-off
Every proposal ends with: The hand-off to Immanuel is **automatic** — do not ask the user for permission
to proceed. "Skal jeg kalde Immanuel?" is not a question to ask; the pipeline
diagram above already answers it. Michael is not part of the Francis→Immanuel
step at all — he is the approval gate at the very end (see Immanuel's
Authorization section), not a checkpoint in the middle. Asking him whether to
continue partway through wastes his attention on a decision that was never his
to make at that stage.
> "Forslaget er klar til Immanuel. Kald Immanuel-agenten med dette oplæg Every proposal ends with continuing directly into Immanuel's validation —
> for Kategorisk Imperativ-validering og universalisering inden det same response, no pause:
> løftes til Michael (mid)."
> "Forslaget er klar til Immanuel." — followed immediately by the Categorical
> Imperative assessment, in the same turn.
Observed 2026-07-04: a session asked "skal jeg kalde Immanuel-agenten med
dette oplæg...?" after producing valid Type A/B proposals. Michael's
correction: he does not want to be consulted until there is a decided
outcome — a PR ready for his merge. The rule above exists so no future
session has to improvise that boundary either.
## Field routing — proposals from developer machines ## Field routing — proposals from developer machines

View file

@ -63,6 +63,13 @@ Michael's verified GitHub account (`MichaelDieringer`).
Immanuel's job ends when the PR is open. Michael's merge IS the approval. Immanuel's job ends when the PR is open. Michael's merge IS the approval.
No extra confirmation text is needed or accepted. No extra confirmation text is needed or accepted.
**Michael is not a mid-pipeline checkpoint.** Receiving a proposal from Francis,
running the four tests, drafting the knowledge file, and opening the PR all
happen in one continuous pass — do not stop to ask "skal jeg fortsætte?" or
"skal jeg oprette PR'en?" at any point before the PR exists. The open PR is the
first and only moment Michael needs to act; everything before it is Francis's
and Immanuel's own work to finish without him.
## Input from Francis ## Input from Francis
Immanuel receives proposals from Francis in two forms: Immanuel receives proposals from Francis in two forms:

View file

@ -0,0 +1,61 @@
---
bc-version: [all]
domain: mcp
keywords: [mcp, tools, naming, bc-actions-search, verification, bc]
technologies: [al]
countries: [w1]
application-area: [all]
---
---
rule: bc-mcp-naming-convention-must-be-reverified
title: BC MCP action-naming conventions must be reverified, not assumed
category: mcp
severity: required
---
# BC MCP action-naming conventions must be reverified, not assumed
## Description
Documentation describing the `businesscentral` MCP server's action-naming pattern
(`List_<Entity>_PAG<id>`, `Modify_<Entity>_PAG<id>`, `Create_<Entity>_PAG<id>`) must
state it as an **expectation to reverify per call with `bc_actions_search`**, never
as a guaranteed fact. The verb prefix is not uniform across every entity.
## Why
The `bc-mcp.agent.md` template asserted the modify-action name as `ListUpdate<entity>
_PAG<id>` as fact. The real action returned by `bc_actions_search` for updating
`projectRepositories` was `Modify_ProjectRepository_PAG6102904` - singular entity
name, `Modify_` prefix, not `ListUpdate`. An agent that trusts the documented pattern
without verifying hunts for a tool that does not exist, wasting a round trip exactly
like the one this rule replaces.
Meanwhile `Create_NewTask_PAG6102905` (used elsewhere in the same template) DOES
match the documented `Create_<entity>_PAG<id>` shape - so the pattern is a reasonable
starting guess, just not one to assert as fact without confirming it that call.
## What counts as a violation
- A BC MCP agent template states an action name or naming pattern as guaranteed,
without an instruction to confirm it via `bc_actions_search` before relying on it.
- An agent session assumes an action name from documentation and calls
`bc_actions_invoke` with it directly, without first getting the exact name from
`bc_actions_search` or `bc_actions_describe`.
## Correct pattern
1. bc_actions_search(SearchText: "<entity keywords>", SearchMode: keyword,
ActionType: [List|Modify|Create])
2. Use the exact name returned - do not construct it from a remembered pattern.
3. bc_actions_describe on that exact name before invoking it.
Documentation may state the *expected* shape as a memory aid, but must mark it
explicitly as unverified per-entity, e.g.: "expect `Modify_<Entity>_PAG<id>` -
reverify, do not assume."
## Scope
Applies to every BC MCP agent template and every session that calls
`bc_actions_search` / `bc_actions_describe` / `bc_actions_invoke` in any CURABIS
project.

View file

@ -60,10 +60,37 @@ branch / status / a note back to BC.
so attribute work to a developer yourself (see "Developer identity" below). so attribute work to a developer yourself (see "Developer identity" below).
- If the server is not connected, say so and stop. Do not invent task data. - If the server is not connected, say so and stop. Do not invent task data.
## Session start: pre-load the three MCP tools
Before producing any user-visible output, load the three tool schemas by exact name:
ToolSearch query: select:mcp__businesscentral__bc_actions_search,mcp__businesscentral__bc_actions_invoke,mcp__businesscentral__bc_actions_describe
Do this first, silently. It must complete before you respond to the user - loading it
mid-task means the user hits unexpected latency at the moment they expect an action,
not setup.
## Tools (BC MCP, Dynamic Tool Mode OFF) ## Tools (BC MCP, Dynamic Tool Mode OFF)
Tool names follow `List<entity>_PAG<id>` (read), `ListUpdate<entity>_PAG<id>` (modify), The `businesscentral` MCP server exposes exactly **three** callable tools:
`Create<entity>_PAG<id>` (create). Confirm exact names from the server's tool list. `bc_actions_search`, `bc_actions_describe`, `bc_actions_invoke`. There is no static
tool list to browse - BC entity/action names (`List_Projects_PAG6102901` and so on)
are not separate MCP tools; they only exist as results of `bc_actions_search`.
**Do not use the general-purpose `ToolSearch` to look for BC entity/action names.**
`ToolSearch` only resolves this session's own deferred client-side tools (the three
above) - it does not search Business Central's action catalog and will return
irrelevant matches from unrelated servers. To find an action:
1. `bc_actions_search` with `SearchMode: keyword` and a few field/entity keywords
(e.g. `"project, repository, gitHubRepository"`), filtered by `ActionType` if known.
2. `bc_actions_describe` on the exact name it returns, to get the callable schema.
3. `bc_actions_invoke` with matching `RequestParameters`.
Expected naming convention - **reverify per call with `bc_actions_search`, do not
assume it holds**: `List_<Entity>_PAG<id>` (read), `Modify_<Entity>_PAG<id>` (update,
**singular** entity name - e.g. `Modify_ProjectRepository_PAG6102904`, not
`ModifyProjectRepositories` or `ListUpdate...`), `Create_<Entity>_PAG<id>` (create).
| Entity (page) | Read | Write you MAY do | Never | | Entity (page) | Read | Write you MAY do | Never |
| --- | --- | --- | --- | | --- | --- | --- | --- |
@ -85,7 +112,8 @@ Moving to `Accepted` requires `Starting date`, `Estimated time` and `Expected De
1. **Find the work.** Read `activeTasks` (filter by `projectNo` or `gitHubRepository`). Use 1. **Find the work.** Read `activeTasks` (filter by `projectNo` or `gitHubRepository`). Use
`gitHubRepository` on the project to confirm you are in the right repo. `gitHubRepository` on the project to confirm you are in the right repo.
2. **Claim it.** When you start, set `gitHubBranch` to the working branch and 2. **Claim it.** When you start, set `gitHubBranch` to the working branch and
`gitHubDevStatus = In Progress` on the task (`ListUpdate activeTasks`). `gitHubDevStatus = In Progress` on the task (search `bc_actions_search` for the
modify action on `activeTasks` - expect `Modify_ActiveTask_PAG6102900`, reverify).
3. **Record progress.** Post a status note with `Create taskComments` 3. **Record progress.** Post a status note with `Create taskComments`
(`projectNo` + `subTaskNo` scope it to one task). Keep notes short and factual. (`projectNo` + `subTaskNo` scope it to one task). Keep notes short and factual.
4. **Finish.** Set `gitHubDevStatus = Done` automatically when branch is merged to main. 4. **Finish.** Set `gitHubDevStatus = Done` automatically when branch is merged to main.