mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-10-05 22:56:55 +01:00
Type B gap (Francis): bc-mcp-bridge.js is a Node.js script and the businesscentral MCP registration launches it via 'node ...', but nothing in the setup checklist ever verified Node was actually installed. Found missing on a fresh machine during a full developer onboarding today -- the bridge deployed fine, the MCP server registered fine, and then every connection attempt would have failed with a generic timeout instead of a clear "Node missing" message. Checked first: this is genuinely uncovered, not a documentation-clarity issue -- ~/.bc-mcp.config.json's path is already stated unambiguously everywhere it's referenced, so no rule needed there. This is a different, real gap: no prerequisite check existed at all.
1051 lines
No EOL
51 KiB
Markdown
1051 lines
No EOL
51 KiB
Markdown
---
|
||
kind: action-skill
|
||
id: curabis-standard-setup
|
||
version: 25
|
||
title: CURABIS Standard — Project Setup
|
||
description: >
|
||
Configures a new or existing repository to the CURABIS Standard development
|
||
environment. Writes a slim project CLAUDE.md, cspell.json, and the two
|
||
repo-local exceptions (bcquality.agent.md, feynman.agent.md) from
|
||
authoritative templates in BCQuality. Deploys bc-mcp-bridge.js, the
|
||
three-layer BCQuality knowledge mirror, the shared agent roster
|
||
(~/.claude/curabis-agents/), find-altool.ps1, and the al/businesscentral
|
||
MCP server registrations to the developer's machine (~/.claude/) — all
|
||
machine-local, never committed to a project repository (v24: this now
|
||
includes the roster and MCP config that used to be copied into every repo,
|
||
see BCQuality rule roster-agents-live-on-machine-not-in-repo). Also handles
|
||
updates to an already-configured project, including cleanup of v6-era
|
||
repo-local mirrors and one-time migration of pre-v24 repos off the
|
||
per-repo roster/.mcp.json/find-altool.ps1 copies. Mode C onboards a support
|
||
user (non-developer) to the Feynman support profile: browser-only,
|
||
read-only, no machine setup — unaffected by the v24 machine/repo split.
|
||
inputs: [repo-root]
|
||
outputs: [CLAUDE.md, .github/.agents/bcquality.agent.md, .github/.agents/feynman.agent.md, ~/.claude/bcquality-knowledge/, ~/.claude/curabis-agents/, ~/.claude/find-altool.ps1, cspell.json, projectmemory/, docs/]
|
||
domain: setup
|
||
keywords: [setup, bootstrap, update, mcp, bcquality, standard, new-project]
|
||
---
|
||
|
||
# CURABIS Standard — Project Setup
|
||
|
||
## Purpose
|
||
|
||
One command turns an empty or existing AL-Go repository into a fully configured
|
||
CURABIS development environment: BCQuality rules loaded, BC MCP wired, Immanuel
|
||
on guard, and project memory ready.
|
||
|
||
## Triggers
|
||
|
||
This agent runs when the developer says any of:
|
||
|
||
- **"Konfigurer dette projekt til CURABIS Standard"** → full setup (new project)
|
||
- **"Opdater CURABIS Standard fra BCQuality"** → update mode (existing project)
|
||
- **"Onboard en supportbruger til CURABIS Standard"** → support profile (Mode C)
|
||
|
||
Detect which mode based on the trigger phrase and proceed accordingly.
|
||
|
||
## Company policy — glide through when there's no real decision (2026-08-04)
|
||
|
||
Observed live: a consultant onboarding a machine hit "no" on a setup
|
||
confirmation reflexively while moving fast, and only noticed afterward. Most
|
||
of this document's `ja/nej` gates aren't actual choices — the standard is
|
||
company policy, not a per-developer preference, and a blocking question
|
||
where there's only one sane answer just invites exactly that kind of
|
||
misclick.
|
||
|
||
The rule going forward, applied throughout this document:
|
||
|
||
- **No real decision + no real risk → don't ask.** If the file is
|
||
git-tracked (repo history is the safety net) and the replacement content
|
||
is already verified correct/present, act directly and report what
|
||
changed. This covers: the v6-era repo-mirror cleanup, CLAUDE.md's
|
||
obsolete-forms replacement, and the v24 migration's repo-local agent-file
|
||
removal — all git-committed, all fully recoverable via `git revert` if
|
||
anyone ever wants the old version back.
|
||
- **Genuine irreducible ambiguity → don't ask either; default to the safe
|
||
side and make it visible.** `.mcp.json`'s and `.claude/settings.json`'s
|
||
multi-developer migration steps are the one real exception: whether every
|
||
developer on a repo has migrated their own machine is a fact only a human
|
||
knows, and Claude cannot verify it. But per this policy, that still isn't
|
||
a reason to interrupt setup with a blocking question — leave the legacy
|
||
entries in place by default (already documented as harmless, not a fault
|
||
state), report the finding, and offer removal as a separate, explicitly-
|
||
requested action later, once a developer confirms the migration is
|
||
actually complete.
|
||
- **Real risk of losing uncommitted work → still stop and ask.** This is
|
||
the one case that's a genuine decision: if a file has actual uncommitted
|
||
local changes, a human has to decide what happens to them; that isn't
|
||
something to glide past.
|
||
- **The developer's personal machine file (`~/.claude/CLAUDE.md`) still
|
||
gets asked.** It's not git-tracked and carries the developer's own
|
||
Identity section — there's no VCS safety net the way there is for
|
||
repo-committed files.
|
||
- **Committing on the developer's behalf stays a real question** (Step 5,
|
||
and the post-update commit prompt) — timing of a commit is a legitimate
|
||
choice, not company policy with one right answer.
|
||
|
||
## Source: the channel clone (BCQuality is PRIVATE — no raw URLs)
|
||
|
||
All artifacts come from the machine's **channel clone** — a git clone of
|
||
`Curabis/QualityHub` pinned to the `stable` branch. Authentication is Git
|
||
Credential Manager (the developer's existing GitHub login); there are NO
|
||
tokenless raw.githubusercontent fetches anywhere — the repo is private.
|
||
|
||
```
|
||
SRC = %USERPROFILE%\.claude\QualityHub (kanal-klonen, stable)
|
||
BASE = {SRC}\custom\setup
|
||
AGENTS_BASE = {SRC}\custom\agents
|
||
```
|
||
|
||
**Before ANY Mode A/B work, ensure the channel clone is fresh:**
|
||
|
||
git -C "$env:USERPROFILE\.claude\QualityHub" fetch origin stable --quiet
|
||
git -C "$env:USERPROFILE\.claude\QualityHub" checkout -B stable origin/stable --quiet
|
||
|
||
If the clone is missing entirely:
|
||
|
||
git clone --branch stable --single-branch https://github.com/Curabis/QualityHub.git "$env:USERPROFILE\.claude\QualityHub"
|
||
|
||
**Vocabulary:** wherever this document says "fetch", it means **copy the file
|
||
from SRC** — a filesystem copy, which preserves raw bytes by definition (the
|
||
old HTTP-encoding pitfalls do not exist here).
|
||
|
||
| Artefakt | Placering |
|
||
|---|---|
|
||
| bc-mcp-bridge.js | `{BASE}/bc-mcp-bridge.js` |
|
||
| bc-mcp.config.template.json | `{BASE}/machine/bc-mcp.config.template.json` |
|
||
| settings.json (permissions template) | `{BASE}/machine/settings.json` (merged into `~/.claude/settings.json`, never overwritten wholesale — see Step 3c) |
|
||
| bcquality.agent.md | `{BASE}/templates/bcquality.agent.md` |
|
||
| immanuel.agent.md | `{AGENTS_BASE}/immanuel.agent.md` |
|
||
| carlin.agent.md | `{AGENTS_BASE}/carlin.agent.md` |
|
||
| francis.agent.md | `{AGENTS_BASE}/francis.agent.md` |
|
||
| al-triage.agent.md | `{BASE}/templates/al-triage.agent.md` |
|
||
| al-complexity.agent.md | `{BASE}/templates/al-complexity.agent.md` |
|
||
| al-review.agent.md | `{BASE}/templates/al-review.agent.md` |
|
||
| bc-mcp.agent.md | `{BASE}/templates/bc-mcp.agent.md` |
|
||
| algo-settings.agent.md | `{BASE}/templates/algo-settings.agent.md` |
|
||
| columbo.agent.md | `{AGENTS_BASE}/columbo.agent.md` |
|
||
| florence.agent.md | `{AGENTS_BASE}/florence.agent.md` |
|
||
| m365.agent.md | `{AGENTS_BASE}/m365.agent.md` |
|
||
| weber.agent.md | `{AGENTS_BASE}/weber.agent.md` |
|
||
| feynman.agent.md | `{AGENTS_BASE}/feynman.agent.md` |
|
||
| smiley.agent.md | `{AGENTS_BASE}/smiley.agent.md` |
|
||
| court.agent.md | `{AGENTS_BASE}/court.agent.md` |
|
||
| lincoln.agent.md | `{AGENTS_BASE}/lincoln.agent.md` |
|
||
| aurelius.agent.md | `{AGENTS_BASE}/aurelius.agent.md` |
|
||
| munger.agent.md | `{AGENTS_BASE}/munger.agent.md` |
|
||
| ergasterion.agent.md | `{AGENTS_BASE}/ergasterion.agent.md` |
|
||
| hickey.agent.md | `{AGENTS_BASE}/hickey.agent.md` |
|
||
| fowler.agent.md | `{AGENTS_BASE}/fowler.agent.md` |
|
||
| parnas.agent.md | `{AGENTS_BASE}/parnas.agent.md` |
|
||
| edison.agent.md | `{AGENTS_BASE}/edison.agent.md` |
|
||
| ferencz.agent.md | `{AGENTS_BASE}/ferencz.agent.md` |
|
||
| roemer.agent.md | `{AGENTS_BASE}/roemer.agent.md` |
|
||
| curabis-task-state-check.yml | `{BASE}/templates/curabis-task-state-check.yml` |
|
||
| cspell.json | `{BASE}/templates/cspell.json` |
|
||
| find-altool.ps1 | `{BASE}/machine/find-altool.ps1` (v24: machine artifact, not a repo template) |
|
||
| feynman-onboarding.md | `{BASE}/templates/feynman-onboarding.md` |
|
||
| sync-bcquality-knowledge.ps1 | `{BASE}/sync-bcquality-knowledge.ps1` |
|
||
|
||
CLAUDE.md is generated dynamically — not fetched as a static template because
|
||
it contains project-specific paths.
|
||
|
||
**v24 — machine vs. repo split:** of the 26 agent files above, only
|
||
`bcquality.agent.md` (the marker this whole mechanism gates on) and
|
||
`feynman.agent.md` (support sessions have no `~/.claude/` to read from) are
|
||
still written into a repo's `.github/.agents/`. The remaining 24 — including
|
||
`florence.agent.md`, which goes to `~/.claude/agents/florence.md` as a real
|
||
Claude Code subagent rather than `~/.claude/curabis-agents/` — are deployed
|
||
ONCE PER MACHINE by `sync-bcquality-knowledge.ps1` to `~/.claude/curabis-agents/`
|
||
(or `~/.claude/agents/` for Florence) and referenced from the machine's own
|
||
`~/.claude/CLAUDE.md`, not from any repo's CLAUDE.md. Same script also
|
||
deploys `find-altool.ps1` to `~/.claude/find-altool.ps1` and registers the
|
||
`al` + `businesscentral` MCP servers at user scope (`claude mcp add --scope
|
||
user`) — no `.mcp.json` is written into the repo for these two standard
|
||
servers any more. See BCQuality rule `roster-agents-live-on-machine-not-in-repo`.
|
||
|
||
---
|
||
|
||
## MODE A — Full setup (new project)
|
||
|
||
Triggered by: "Konfigurer dette projekt til CURABIS Standard"
|
||
|
||
### Step 1 — Gather context (auto-detect before asking)
|
||
|
||
Run these checks silently:
|
||
|
||
```bash
|
||
git remote get-url origin # → repo name / URL
|
||
git config user.email # → developer identity
|
||
git config user.name
|
||
```
|
||
|
||
Check whether these paths exist:
|
||
- `~/.claude/find-altool.ps1` → AL MCP tool-finder deployed (v24: machine-global, not repo-local)
|
||
- `CLAUDE.md` → already configured?
|
||
- `~/.claude/bc-mcp-bridge.js` → bridge already installed?
|
||
- `~/.bc-mcp.config.json` → BC credentials present?
|
||
|
||
**Runtime prerequisite — check before Step 3, not after:** run `node --version`.
|
||
`bc-mcp-bridge.js` (Step 3a) is a Node.js script, and the `businesscentral` MCP
|
||
registration (Step 3c) launches it via `node ...` — without Node installed and on
|
||
PATH, the bridge can never run, and `claude mcp add` will register a server that
|
||
fails on every connection attempt with a generic timeout, not a clear "Node
|
||
missing" message. If `node --version` fails, stop and tell the developer to
|
||
install Node.js (LTS) before continuing — do not deploy the bridge or register
|
||
the MCP server on a machine that can't run either. 2026-08-03: found missing on a
|
||
fresh machine during a full developer onboarding; nothing in this checklist
|
||
would have caught it before Step 3 silently deployed a script that couldn't run.
|
||
|
||
Also run `claude mcp list` (or `claude mcp get al` / `claude mcp get businesscentral`)
|
||
to check whether the two standard MCP servers are already registered at user scope.
|
||
If any of the above machine-level artifacts are missing, Step 3 will deploy them via
|
||
`sync-bcquality-knowledge.ps1` — no separate action needed here beyond noting it in
|
||
the setup report.
|
||
|
||
If `CLAUDE.md` already exists: check `git status` for it specifically. If it
|
||
has uncommitted local changes, stop and tell the developer to commit or
|
||
stash first — that is real, potentially-lost work, a genuine decision, not
|
||
a policy gate. Otherwise (clean, or already tracked with nothing pending),
|
||
overwrite it directly and report what changed — no `ja/nej` needed, per the
|
||
company policy above; git history already protects the old version.
|
||
|
||
### Step 1b — Structural readiness: raise the flags (Rømer)
|
||
|
||
Before configuring anything, run Rømer's structural stations (10-11 in
|
||
`roemer.agent.md` — rule `al-go-template-layout-with-test-app-required`):
|
||
|
||
1. AL-Go template layout: apps folder with per-app project subfolders + `.AL-Go/`
|
||
2. Test app companion for every main app
|
||
|
||
Report every finding immediately and prominently:
|
||
|
||
```
|
||
⚠️ Strukturflag ved BCQuality-implementering:
|
||
|
||
- <fladt layout: tests kan ikke oprettes før migrering til AL-Go template>
|
||
- <manglende test-app for <App>: kør CreateTestApp-workflowet>
|
||
```
|
||
|
||
Setup MAY continue on a non-compliant repo — the flags go in the setup
|
||
report, prominently, and setup continues directly to Step 2 without waiting
|
||
for an acknowledgment (company policy above: reporting the flag IS the
|
||
record, and a blocking `ja/nej` here has no real decision behind it since
|
||
setup proceeds regardless of the answer). Never restructure silently,
|
||
though — actually migrating the repo's structure stays a separate,
|
||
deliberate, explicitly-requested action.
|
||
|
||
### Step 2 — Ask exactly three questions
|
||
|
||
Do not proceed until all three are answered.
|
||
|
||
```
|
||
1. Hvad er projektets navn?
|
||
(bruges som overskrift i CLAUDE.md og i projectmemory)
|
||
|
||
2. Hvilke AL-app mapper er i repoen?
|
||
Eksempler:
|
||
a) Flad struktur — kildefiler direkte i roden (AppSource/)
|
||
b) .apps/<AppName> (main app)
|
||
c) .apps/<AppName> + .apps/<AppName>.Test (main + test)
|
||
Angiv de faktiske mapper.
|
||
|
||
3. Hvad er dit brugernavn til projectmemory-filen?
|
||
(f.eks. "mid" → memoryupdates_mid.md)
|
||
```
|
||
|
||
### Step 3 — Deploy machine files
|
||
|
||
#### 3a. bc-mcp-bridge.js
|
||
|
||
Node.js must already be confirmed present (Step 1's runtime prerequisite check)
|
||
before this step — a bridge script deployed onto a machine without Node to run
|
||
it is a silent dead end until Step 3c's registration fails.
|
||
|
||
1. Fetch `{BASE}/bc-mcp-bridge.js`
|
||
2. Write to `~/.claude/bc-mcp-bridge.js` (overwrite silently — BCQuality is authoritative)
|
||
3. Confirm: "bc-mcp-bridge.js er opdateret på din maskine."
|
||
|
||
#### 3b. bc-mcp.config.json
|
||
|
||
If `~/.bc-mcp.config.json` already exists: skip silently.
|
||
|
||
If it does NOT exist:
|
||
1. Fetch `{BASE}/machine/bc-mcp.config.template.json`
|
||
2. Write it to `~/.bc-mcp.config.json` as-is
|
||
3. Tell the developer:
|
||
> "⚠️ `~/.bc-mcp.config.json` er oprettet fra CURABIS-template.
|
||
> Udfyld ALLE placeholder-felter (tenant, clientId, client secret, company)
|
||
> — ikke kun secret'en. For `company`: brug PRÆCIS firmanavnet fra BC's
|
||
> 'Navn'-kolonne på virksomhedslisten, IKKE 'Vist navn' — de to kan være
|
||
> forskellige strenge for samme firma (2026-07-31: 'CURABIS ApS' vs.
|
||
> 'Curabis ApS' forårsagede et 30-sekunders timeout uden brugbar fejl —
|
||
> se `bc-mcp-company-header-must-match-exact-company-name`).
|
||
> Gem filen — BC MCP er klar når du genstarter Claude Code."
|
||
|
||
#### 3c. bcquality-knowledge, roster agents, find-altool.ps1, MCP registration (v24)
|
||
|
||
Everything machine-global beyond the bridge and BC secret — the knowledge
|
||
mirror, the 20 roster agent files (19 to `~/.claude/curabis-agents/` +
|
||
Florence to `~/.claude/agents/florence.md`), `~/.claude/find-altool.ps1`, and
|
||
the `al`/`businesscentral`/`microsoft-learn` MCP registrations — is deployed
|
||
by ONE script, `sync-bcquality-knowledge.ps1`. None of it is ever committed
|
||
to a project repository (BCQuality rule
|
||
`bcquality-knowledge-must-mirror-to-machine-not-repo`, extended in v24 to
|
||
`roster-agents-live-on-machine-not-in-repo`). Rationale: developers switch
|
||
between many repos daily — N per-repo copies are permanently out of sync
|
||
with each other, while one machine copy needs exactly one sync per upstream
|
||
change.
|
||
|
||
1. Fetch `{BASE}/sync-bcquality-knowledge.ps1` → write AS RAW BYTES
|
||
(`Invoke-WebRequest -OutFile`, never via string content — re-encoding
|
||
corrupts UTF-8) to `~/.claude/sync-bcquality-knowledge.ps1`
|
||
2. Run it once:
|
||
`powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\.claude\sync-bcquality-knowledge.ps1"`
|
||
This populates:
|
||
- `~/.claude/bcquality-knowledge/{custom,community,microsoft}/` + `INDEX.md`
|
||
(domain + keywords per file, for relevance-based lookup — `custom/` is
|
||
always read in full, `community/` and `microsoft/` are scanned via the
|
||
index rather than preloaded, since together they run into the hundreds
|
||
of files)
|
||
- `~/.claude/curabis-agents/*.agent.md` (19 files)
|
||
- `~/.claude/agents/florence.md` (Florence, as a real subagent)
|
||
- `~/.claude/find-altool.ps1`
|
||
- `al` + `businesscentral` + `microsoft-learn` registered at user MCP scope
|
||
(idempotent — a server that already exists is reported, not re-added or
|
||
overwritten). `microsoft-learn` is `https://learn.microsoft.com/api/mcp`,
|
||
HTTP transport, no auth — the same official documentation search Mode C
|
||
already gives support users; v24 closes the gap where developers had
|
||
only the static `microsoft/` knowledge-file snapshot and no live search
|
||
of Microsoft's own docs.
|
||
3. If a v6-era `.github/.agents/bcquality-knowledge/` exists in THIS repo,
|
||
add it to `.gitignore` so no future session can accidentally commit it
|
||
(see the v6-cleanup step in Mode B for full removal — this step just
|
||
prevents new commits).
|
||
4. Confirm: "Maskine-opsætning synkroniseret — bcquality-knowledge [antal]
|
||
filer, curabis-agents 19 filer, Florence, find-altool.ps1, MCP (al,
|
||
businesscentral, microsoft-learn)."
|
||
|
||
This machine setup is what the global `~/.claude/CLAUDE.md` roster section
|
||
and the project CLAUDE.md's session-start line both depend on. Without this
|
||
step, those references point at artifacts that don't exist yet on a fresh
|
||
machine.
|
||
|
||
### Step 4 — Write project files
|
||
|
||
#### 4a. CLAUDE.md
|
||
|
||
**v24 change:** most of what used to be duplicated into every repo's CLAUDE.md
|
||
(Smiley, Carlin, on-demand roster, Francis, projectmemory/docs read
|
||
instructions) now lives ONCE in the developer's own `~/.claude/CLAUDE.md`
|
||
(see `machine/CLAUDE.md`'s "CURABIS Standard — Shared Roster" section),
|
||
gated on this repo having `.github/.agents/bcquality.agent.md` — the same
|
||
marker file/gate the existing "Auto-update BCQuality" section already used.
|
||
The project CLAUDE.md shrinks to what is genuinely repo state OR must work
|
||
before any global file exists: project name, AL app layout, the machine
|
||
self-heal bootstrap (kept — see why below), the Feynman support-session
|
||
trigger (kept — support sessions have no `~/.claude/` to read the global
|
||
file from either), and the project footer.
|
||
|
||
**Why self-heal stays repo-local (do NOT move it to global):** self-heal's
|
||
entire job is bootstrapping `~/.claude/CLAUDE.md` on a machine that doesn't
|
||
have it yet — a developer cloning an already-configured repo for the first
|
||
time on a fresh machine has nothing BUT this repo's CLAUDE.md to read. If
|
||
self-heal itself lived only in the global file, there would be no way to
|
||
reach it on that fresh machine. This is the mirror image of why Feynman
|
||
stays repo-local (his audience never gets a global file; self-heal's job IS
|
||
installing one) — both are genuine exceptions to the v24 move, for opposite
|
||
reasons.
|
||
|
||
Generate from this template, substituting answers from Step 2:
|
||
|
||
```markdown
|
||
# {PROJECT_NAME} — Claude Code Instructions
|
||
|
||
This file is read automatically by Claude Code at the start of every
|
||
session, together with the developer's `~/.claude/CLAUDE.md` (once it
|
||
exists — see self-heal below for a fresh machine). This repo has
|
||
`.github/.agents/bcquality.agent.md`, so once the global file exists, its
|
||
"CURABIS Standard — Shared Roster" section applies for the whole session:
|
||
BCQuality knowledge, Smiley, Carlin, the on-demand agent roster, Francis,
|
||
and the projectmemory/docs read instructions. That content is not
|
||
duplicated here — see `~/.claude/CLAUDE.md` on the developer's machine for
|
||
the full text.
|
||
|
||
## BCQuality — machine self-heal
|
||
|
||
**Trigger** if EITHER (a) this machine is not CURABIS-onboarded —
|
||
`~/.claude/CLAUDE.md` or `~/.claude/bc-mcp-bridge.js` is missing — OR (b) the
|
||
machine is STALE: `~/.claude/CLAUDE.md` still references
|
||
`raw.githubusercontent.com` or the legacy `Curabis/BCQuality` repo (a
|
||
machine that slept through a consumption migration — vacation, leave, spare
|
||
laptop). Run the onboarding NOW (idempotent; identity from git config; the
|
||
first git contact may open a browser login — that IS the authentication):
|
||
|
||
git clone --branch stable --single-branch https://github.com/Curabis/QualityHub.git "$env:USERPROFILE\.claude\QualityHub"
|
||
powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\.claude\QualityHub\custom\setup\machine\Install-CurabisMachine.ps1"
|
||
|
||
(Skip the clone line if `%USERPROFILE%\.claude\QualityHub` already exists.)
|
||
This installs `~/.claude/CLAUDE.md` (never overwriting an existing one),
|
||
`~/.claude/bc-mcp-bridge.js`, `~/.bc-mcp.config.json` (template), and runs
|
||
`sync-bcquality-knowledge.ps1` — which also deploys the roster agents,
|
||
Florence, `find-altool.ps1`, and the `al`/`businesscentral` MCP
|
||
registrations (see Step 3c in Mode A). In the STALE case, additionally
|
||
refresh the machine's `~/.claude/CLAUDE.md` CURABIS sections from
|
||
`%USERPROFILE%\.claude\QualityHub\custom\setup\machine\CLAUDE.md` — show the
|
||
diff, preserve the Identity section and any personal sections verbatim, and
|
||
ask for confirmation (it is the developer's personal file). Report the
|
||
manual leftovers (personal client secret; the AL Language extension if VS
|
||
Code lacks it) and ask the developer to restart Claude Code.
|
||
|
||
If only `~/.claude/bcquality-knowledge/` (or the roster/find-altool.ps1/MCP
|
||
registrations) is missing or stale, the lighter self-heal suffices:
|
||
|
||
powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\.claude\sync-bcquality-knowledge.ps1"
|
||
|
||
This section stays repo-local — see the note above.
|
||
|
||
## Feynman — Support-sessioner
|
||
|
||
Hvis sessionens første besked starter med **"Feynman:"** — eller brugeren
|
||
identificerer sig som support/forretningskonsulent (ikke-udvikler):
|
||
|
||
1. Læs `.github/.agents/feynman.agent.md` og arbejd efter hans protokol
|
||
resten af sessionen.
|
||
2. Spring over: BCQuality machine self-heal, AL MCP, BC MCP og test-afvikling.
|
||
Support-miljøet er browserbaseret (claude.ai / Claude Code på web) — der er
|
||
ingen lokal maskine at onboarde, og det er meningen.
|
||
3. Strengt læsende: ingen redigering, ingen commits, ingen builds.
|
||
|
||
Denne sektion har forrang over BCQuality-sektionens self-heal — og den bliver
|
||
bevidst stående HER, repo-lokalt, uanset v24-flytningen ovenfor: en
|
||
supportbruger har intet `~/.claude/CLAUDE.md` at læse den globale roster-
|
||
sektion fra, så Feynman-trigger'en skal være synlig i selve repoet.
|
||
|
||
## AL projects
|
||
|
||
{AL_PROJECTS_SECTION}
|
||
|
||
## About this project
|
||
|
||
{PROJECT_NAME} Business Central extension
|
||
```
|
||
|
||
**AL_PROJECTS_SECTION substitution rules:**
|
||
|
||
- Flat (AppSource/):
|
||
```
|
||
Main app is in `AppSource/` at repo root.
|
||
```
|
||
- .apps/\<Name\> only:
|
||
```
|
||
The app is loaded via MCP hooks:
|
||
- .apps\<Name> — main app
|
||
```
|
||
- .apps/\<Name\> + .apps/\<Name\>.Test:
|
||
```
|
||
Both apps are always loaded via MCP hooks:
|
||
- .apps\<Name> — main app
|
||
- .apps\<Name>.Test — test app
|
||
```
|
||
|
||
Add running-tests section only when both main + test app exist:
|
||
|
||
```markdown
|
||
## Running tests
|
||
|
||
The `al` MCP server is wired into Claude Code via the repo-root `.mcp.json`.
|
||
To run the test suite end to end:
|
||
|
||
1. `al_auth_login` - authenticate to the BC sandbox (once per session).
|
||
2. `al_downloadsymbols` - fetch dependency symbols.
|
||
3. `al_compile` (or `al_build`) - confirm both apps build clean.
|
||
4. `al_publish` - publish main + test app to the sandbox.
|
||
5. `al_run_tests` - execute the tests; optionally filter to one codeunit.
|
||
|
||
After creating any new `.al` file, reload the AL extension in VS Code
|
||
(`Ctrl+Shift+P -> AL: Reload Extension`) before trusting diagnostics.
|
||
```
|
||
|
||
#### 4b. AL MCP + businesscentral MCP (v24: machine-registered, no repo .mcp.json)
|
||
|
||
**v24 change:** both standard MCP servers now live entirely on the
|
||
developer's machine — registered once via `claude mcp add --scope user`,
|
||
never committed as `.mcp.json` in the repo. This eliminates the entire class
|
||
of "hardcoded developer path in a git-committed file" bugs, since there is
|
||
now exactly one place per machine to get it right, not one per repo.
|
||
|
||
Nothing to write here in Step 4 — Step 3c (above) already handled
|
||
registration as part of the machine deploy, and it is idempotent (safe to
|
||
run again on an already-onboarded machine).
|
||
|
||
If a repo ever needs an ADDITIONAL MCP server beyond these two standard
|
||
ones (repo- or customer-specific), create `.mcp.json` for just that entry —
|
||
never re-add `al` or `businesscentral` to it; they would shadow the
|
||
user-scope registration with a project-scope duplicate approval prompt for
|
||
no benefit.
|
||
|
||
The only machine prerequisite for the `al` server is the AL Language
|
||
extension itself (`ms-dynamics-smb.al` from the Marketplace, recent version)
|
||
— `find-altool.ps1` locates its `altool.exe` dynamically and reports clearly
|
||
if it is missing.
|
||
|
||
#### 4c. .github/.agents/ (fetch from BCQuality — v24: two files, not twenty-one)
|
||
|
||
Fetch and write verbatim:
|
||
- `{BASE}/templates/bcquality.agent.md` → `.github/.agents/bcquality.agent.md`
|
||
- `{AGENTS_BASE}/feynman.agent.md` → `.github/.agents/feynman.agent.md`
|
||
|
||
Create `.github/.agents/` if it does not exist.
|
||
|
||
These are the only two agent files that belong in a repo. `bcquality.agent.md`
|
||
is the marker file the machine's `~/.claude/CLAUDE.md` gates the whole
|
||
"CURABIS Standard — Shared Roster" section on; `feynman.agent.md` must stay
|
||
repo-local because Mode C support sessions have no `~/.claude/` to read a
|
||
global roster from. Every other roster agent (Smiley, Carlin, Immanuel,
|
||
Francis, Columbo, Florence, the Court, Rømer, Weber, Ferencz, Edison,
|
||
al-triage, al-complexity, al-review, bc-mcp, algo-settings) is deployed machine-globally
|
||
by Step 3c and referenced from `~/.claude/CLAUDE.md` — see BCQuality rule
|
||
`roster-agents-live-on-machine-not-in-repo`.
|
||
|
||
#### 4c-2. bcquality-knowledge, roster agents, MCP — see Step 3c
|
||
|
||
Already handled by Step 3c above (it runs before project files are written,
|
||
since 4a's CLAUDE.md and 4c's bcquality.agent.md both assume the machine
|
||
side is in place). Nothing further to do here.
|
||
|
||
#### 4d. cspell.json
|
||
|
||
Fetch `{BASE}/templates/cspell.json` and write to repo root.
|
||
If a `cspell.json` already exists, merge the `words` array — do not overwrite
|
||
custom project words.
|
||
|
||
#### 4e. projectmemory/
|
||
|
||
Create `projectmemory/` if it does not exist.
|
||
Create `projectmemory/memoryupdates_<username>.md` if it does not exist:
|
||
|
||
```markdown
|
||
# Project Memory — <username> (<full name>)
|
||
|
||
Observationer og beslutninger der er relevante for alle på projektet.
|
||
Læses automatisk af Claude Code ved session-start (via CLAUDE.md).
|
||
|
||
---
|
||
|
||
(Tilføj observationer her)
|
||
```
|
||
|
||
#### 4f. HEARTBEAT.md
|
||
|
||
If `HEARTBEAT.md` does NOT exist at repo root:
|
||
1. Fetch `{BASE}/templates/HEARTBEAT.md`
|
||
2. Replace `{PROJECT_NAME}` with the project name from Step 2
|
||
3. Replace `{SETUP_DATE}` with today's ISO date
|
||
4. Write to repo root
|
||
5. Confirm: "HEARTBEAT.md oprettet — Florence er klar til at gå sine runder."
|
||
|
||
If `HEARTBEAT.md` already exists: skip silently.
|
||
|
||
#### 4g. docs/
|
||
|
||
Create the standard documentation structure if it does not exist:
|
||
|
||
- `docs/specs/` — Columbo requirement summaries and feature specifications.
|
||
Read by Claude at session start. One file per feature in kebab-case.
|
||
- `docs/decisions/` — Architectural decision records. Formal, dated, immutable.
|
||
- `docs/cleanup/` — Cleanup task lists with checkbox status.
|
||
|
||
Create a `.gitkeep` file in each empty subfolder so git tracks them.
|
||
|
||
#### 4h. .github/workflows/curabis-task-state-check.yml (2026-08-03)
|
||
|
||
Fetch `{BASE}/templates/curabis-task-state-check.yml` and write to
|
||
`.github/workflows/curabis-task-state-check.yml`.
|
||
|
||
Deterministic (not LLM-instruction-based) enforcement of
|
||
`[[task-state-lives-in-the-mandatory-artifact]]`'s AppSource checklist
|
||
order — see that rule and `al-review.agent.md`'s "state trail complete"
|
||
checklist item for the full picture. This is a real CI check, not an agent
|
||
protocol: it parses the PR body for a `## CURABIS Task State` section and
|
||
fails if a later stage is checked while an earlier one isn't. It silently
|
||
does nothing on PRs with no such section — never make it block an unrelated
|
||
PR (a docs fix, an infra change).
|
||
|
||
**Manual one-time step, cannot be automated by this file deployment:**
|
||
tell the developer/admin to add this check as a **required status check**
|
||
in the repo's branch protection settings (GitHub → Settings → Branches →
|
||
the target branch's protection rule) if they want it to actually block a
|
||
merge rather than just show as a failed check someone could ignore. Report
|
||
this explicitly — do not silently assume it's required just because the
|
||
workflow file exists.
|
||
|
||
### Step 5 — Confirm and offer initial commit
|
||
|
||
List all files written, then ask:
|
||
> "Setup er færdigt. Vil du have mig til at lave det første commit? (ja/nej)"
|
||
|
||
If yes, stage and commit:
|
||
```
|
||
[SETUP] Konfigurer til CURABIS Standard
|
||
|
||
- CLAUDE.md (slank, peger på ~/.claude/CLAUDE.md for delte regler)
|
||
- .github/.agents/bcquality.agent.md + feynman.agent.md (repo-lokale undtagelser)
|
||
- cspell.json
|
||
- HEARTBEAT.md — Florence's vagtliste
|
||
- projectmemory/ — delt projekthukommelse
|
||
- docs/specs/, docs/decisions/, docs/cleanup/ — projektdokumentation
|
||
|
||
(Resten af rosteret, find-altool.ps1 og MCP-registrering er maskin-globalt —
|
||
intet at committe for dem, se Step 3c.)
|
||
|
||
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
```
|
||
|
||
---
|
||
|
||
## MODE B — Update (existing project)
|
||
|
||
Triggered by: "Opdater CURABIS Standard fra BCQuality"
|
||
|
||
**Step 0 — freshen the channel clone** (see Source section): fetch + checkout
|
||
`origin/stable` in `%USERPROFILE%\.claude\QualityHub`; create the clone if
|
||
missing. Every copy below reads from that clone.
|
||
|
||
Updates only the files that come directly from BCQuality.
|
||
Never touches `CLAUDE.md`'s project-specific content, `projectmemory/`, `docs/`, or `~/.bc-mcp.config.json`.
|
||
|
||
**v24 note:** as of v24 this table is much shorter than it used to be — 19 of
|
||
the 21 agent files, `.mcp.json`'s standard entries, and `find-altool.ps1` are
|
||
no longer repo artifacts at all; they are machine-global (see the
|
||
machine-level table below, and Step 3c in Mode A for what deploys them).
|
||
Repos still on v23 or earlier need the one-time migration below before this
|
||
shorter table applies to them.
|
||
|
||
### What gets updated — repo-level
|
||
|
||
| Fil | Handling |
|
||
|---|---|
|
||
| `.github/.agents/bcquality.agent.md` | Fetch fresh from BCQuality, overwrite |
|
||
| `.github/.agents/feynman.agent.md` | Fetch fresh from BCQuality, overwrite (add if missing) |
|
||
| `cspell.json` — words from template | Merge new words, keep project words |
|
||
| `.github/workflows/curabis-task-state-check.yml` | Fetch fresh from BCQuality, overwrite (add if missing) — remind about the branch-protection required-check step if just added |
|
||
| `.apps/*.code-workspace` — reference layout | Create/complete: app projects + `.AL-Go` + relative `../docs` (rule `al-development-must-use-apps-workspace`) |
|
||
| Alle øvrige `*.code-workspace` (inkl. rodens `al.code-workspace`) | Delete — kun ét workspace pr. repo; rapportér de slettede |
|
||
| `HEARTBEAT.md` | Create from template if missing (substitute tokens), never overwrite — but run the staleness check below on every Mode B pass |
|
||
| `docs/specs/`, `docs/decisions/`, `docs/cleanup/` | Create if missing, never overwrite content |
|
||
|
||
### What gets updated — machine-level (once per machine, not per repo)
|
||
|
||
Run every time Mode B runs, regardless of which repo it was triggered from —
|
||
these are shared across every CURABIS repo on the machine:
|
||
|
||
| Artefakt | Handling |
|
||
|---|---|
|
||
| `~/.claude/bc-mcp-bridge.js` | Fetch fresh from BCQuality, overwrite |
|
||
| `~/.claude/sync-bcquality-knowledge.ps1` | Fetch fresh from BCQuality (raw bytes), overwrite (add if missing) |
|
||
| `~/.claude/bcquality-knowledge/` | Re-run the sync script (see below) |
|
||
| `~/.claude/curabis-agents/*.agent.md` (19 files) | Re-run the sync script |
|
||
| `~/.claude/agents/florence.md` | Re-run the sync script |
|
||
| `~/.claude/find-altool.ps1` | Re-run the sync script |
|
||
| `al` + `businesscentral` + `microsoft-learn` MCP servers (user scope) | Re-run the sync script — idempotent: registers if missing, does NOT touch an existing registration (a developer's personal-scope config is not policed the way repo-shared `.mcp.json` used to be) |
|
||
| `.github/.agents/bcquality-knowledge/` + `.github/.agents/sync-bcquality-knowledge.ps1` | v6-era repo-local mirror: propose removal (see below) |
|
||
|
||
### bcquality-knowledge — machine re-sync (Mode B)
|
||
|
||
After overwriting `~/.claude/sync-bcquality-knowledge.ps1`, always re-run it:
|
||
|
||
```
|
||
powershell -ExecutionPolicy Bypass -File "$env:USERPROFILE\.claude\sync-bcquality-knowledge.ps1"
|
||
```
|
||
|
||
This refreshes `~/.claude/bcquality-knowledge/{custom,community,microsoft}/`
|
||
and regenerates `INDEX.md` from the live BCQuality tree. Run this every time Mode B
|
||
runs, not just when the script itself changed — the mirror goes stale independently
|
||
of the script (new upstream knowledge files land on their own schedule). The mirror
|
||
is machine-local: there is no repo diff to stage.
|
||
|
||
### v6-era repo-local mirror — cleanup (Mode B)
|
||
|
||
Projects configured under setup v6 have the mirror committed INSIDE the repo.
|
||
Detect and clean up:
|
||
|
||
1. If `.github/.agents/bcquality-knowledge/` exists in the repo (tracked or not),
|
||
remove it directly and report it — no `ja/nej` (company policy above:
|
||
git-tracked, fully recoverable via `git revert`, and the machine-local
|
||
mirror it's replaced by is already confirmed present earlier in this
|
||
same run):
|
||
|
||
```
|
||
ℹ️ Dette repo indeholdt en v6-æra repo-lokal BCQuality-mirror
|
||
(.github/.agents/bcquality-knowledge/, ~[antal] filer) — fjernet.
|
||
Standarden er nu maskin-lokal mirror (~/.claude/bcquality-knowledge/).
|
||
```
|
||
|
||
`git rm -r --cached .github/.agents/bcquality-knowledge/` (if tracked),
|
||
delete the folder, delete `.github/.agents/sync-bcquality-knowledge.ps1` (its
|
||
`$PSScriptRoot`-relative destination is what created the repo mirror), and add
|
||
`.github/.agents/bcquality-knowledge/` to `.gitignore`.
|
||
|
||
2. Check the project's CLAUDE.md `## BCQuality` section for obsolete forms:
|
||
- a flat list of `raw.githubusercontent.com/...` knowledge URLs (pre-mirror era)
|
||
- a reference to `.github/.agents/bcquality-knowledge/` (v6 repo-mirror era)
|
||
- a literal per-developer path such as `C:\Users\<name>\.claude\...` — must be
|
||
`~/.claude/...` / `%USERPROFILE%`, never one developer's username
|
||
- ANY remaining `raw.githubusercontent.com`-based self-heal or onboarding
|
||
command (v15-v18 era) — the repo is private; raw URLs are dead. The
|
||
current form is git-based via the channel clone.
|
||
If any match, replace the section with the current template from Step 4a
|
||
directly and report it — no confirmation needed (company policy above:
|
||
these forms are objectively obsolete, CLAUDE.md is git-tracked, and this
|
||
only touches the flagged section, never project-specific content).
|
||
|
||
### Machine CLAUDE.md refresh (Mode B)
|
||
|
||
The developer's global `~/.claude/CLAUDE.md` carries the CURABIS auto-update
|
||
instructions. After a consumption-model change (like v19's git migration, or
|
||
v24's move of the roster/on-demand-agents/Smiley/Carlin/Francis sections
|
||
from every repo's CLAUDE.md into this file), those instructions go stale on
|
||
every already-onboarded machine. Compare the machine file's CURABIS sections
|
||
against `{BASE}/machine/CLAUDE.md` in the channel clone. If they diverge
|
||
structurally (e.g. still reference raw URLs or GitHub-API SHA checks, or are
|
||
missing the v24 "CURABIS Standard — Shared Roster" section entirely),
|
||
propose the update — show the diff, preserve the Identity section verbatim,
|
||
and ask for confirmation before editing: it is the developer's personal file.
|
||
Unlike the repo-committed files above, this one stays a real question under
|
||
the company policy above — it isn't git-tracked, so there's no revert
|
||
safety net, and it carries the developer's own personal customizations
|
||
mixed in alongside the CURABIS sections.
|
||
|
||
### v23 → v24 migration (existing repos, one-time per repo)
|
||
|
||
v24 moved 19 agent files, `.mcp.json`'s two standard entries, and
|
||
`find-altool.ps1` from repo-local to machine-global (see the Source section's
|
||
"machine vs. repo split" note). A repo configured under v23 or earlier still
|
||
has the old repo-local copies. Detect and migrate. Steps 1, 2, and 4 below
|
||
act directly and report, per the company policy above (git-tracked,
|
||
verified-safe); step 3 is the one genuine multi-developer ambiguity and
|
||
defaults to leaving things in place, not asking:
|
||
|
||
**1. Extra `.github/.agents/*.agent.md` files**
|
||
|
||
List `.github/.agents/*.agent.md`. Anything other than `bcquality.agent.md`
|
||
and `feynman.agent.md` is a pre-v24 repo-local copy of a now-machine-global
|
||
agent. Before removing, confirm Step 3c has run on THIS machine in THIS
|
||
Mode B pass (it always does, earlier in this flow) — that guarantees the
|
||
roster is available globally before the repo-local copies disappear. Then
|
||
remove and report directly, no `ja/nej`:
|
||
|
||
```
|
||
ℹ️ v24-migrering: [N] agent-filer i .github/.agents/ er nu maskin-globale
|
||
(~/.claude/curabis-agents/ + ~/.claude/agents/florence.md) — fjernet, siden
|
||
maskinen her allerede har den globale roster (bekræftet i dette Mode B-kald).
|
||
|
||
- immanuel.agent.md, francis.agent.md, columbo.agent.md, ... [list them]
|
||
```
|
||
|
||
`git rm` each file not in `{bcquality.agent.md, feynman.agent.md}`.
|
||
|
||
**2. Old-style CLAUDE.md (inline generic sections)**
|
||
|
||
Check for any of these headings still present verbatim in the project
|
||
CLAUDE.md: `## Smiley — Session Watchdog`, `## Carlin — Bullshit Detector`,
|
||
`## On-demand agents`, `## Francis — proaktiv regelobservation`,
|
||
`## Shared project memory`, `## Project documentation`. Their presence means
|
||
this repo predates v24. Remove only those headings/sections directly and
|
||
replace them with the short pointer paragraph from Step 4a — no `ja/nej`.
|
||
Do NOT touch `## BCQuality` (the self-heal section) or `## Feynman —
|
||
Support-sessioner` — both stay, unchanged, in every version. Preserve
|
||
everything project-specific (project name, AL_PROJECTS_SECTION,
|
||
running-tests, about-this-project) verbatim. Report the diff after editing,
|
||
same as the v6-era obsolete-forms replacement above.
|
||
|
||
**3. `.mcp.json` — standard entries (the one genuine ambiguity — default to leaving it)**
|
||
|
||
This is the one migration step that is NOT safe to do unilaterally from a
|
||
single Mode B run, because `.mcp.json` is git-committed and shared: removing
|
||
it assumes EVERY developer working on this repo has already run Step 3c on
|
||
their OWN machine. Doing this before that is true silently breaks AL/BC MCP
|
||
for anyone who pulls the change and hasn't migrated yet — and whether every
|
||
developer has migrated is a fact only a human knows, not something Claude
|
||
can verify. Per the company policy above, that's still not a reason to
|
||
interrupt setup with a blocking question:
|
||
|
||
If `.mcp.json` contains the standard `al` and/or `businesscentral` entries,
|
||
leave them in place by default and report it — no `ja/nej`:
|
||
|
||
```
|
||
ℹ️ .mcp.json indeholder stadig de to standard MCP-servere (al, businesscentral)
|
||
fra før v24 — det er maskin-globalt nu, men filen skader ikke noget stående
|
||
som den er (duplikeret konfiguration, ikke en fejltilstand). Fjernes kun når
|
||
du eksplicit bekræfter at ALLE udviklere på repoet er migreret — sig til når
|
||
det er tilfældet.
|
||
```
|
||
|
||
Only remove the two entries (never the whole file — a repo may have
|
||
legitimate additional MCP servers) when a developer separately and
|
||
explicitly confirms every developer on the repo has migrated — never as
|
||
part of this automatic setup/update flow itself. If the file becomes empty
|
||
afterward (`{"mcpServers": {}}`), offer deleting `.mcp.json` entirely at
|
||
that same later point.
|
||
|
||
**4. `.vscode/find-altool.ps1`**
|
||
|
||
If present, remove it directly and report it — no `ja/nej`. It is
|
||
superseded by `~/.claude/find-altool.ps1` (machine-global, cwd-walkup
|
||
discovery, no repo dependency), git-tracked, and safe to remove
|
||
independently of the `.mcp.json` migration above, since removing the *file*
|
||
doesn't affect any `.mcp.json` entry that still references the old
|
||
repo-relative walk-up form until that entry itself is migrated per step 3.
|
||
|
||
**5. `.claude/settings.json` — legacy repo-committed permissions block
|
||
(2026-08-03, same genuine ambiguity as step 3 — default to leaving it)**
|
||
|
||
A repo from before the BC MCP static-tool-mode migration (2026-08-03) may
|
||
have a git-committed `.claude/settings.json` with a `permissions.allow`
|
||
block naming the OLD Dynamic Tool Mode tool names
|
||
(`mcp__businesscentral__bc_actions_search` / `bc_actions_describe` /
|
||
`bc_actions_invoke`) and/or an `enabledMcpjsonServers` entry for `al` /
|
||
`businesscentral`. Found live in the `Wareco` repo during a full developer
|
||
onboarding: the stale `enabledMcpjsonServers` entry causes the MCP servers
|
||
panel to show `al`/`businesscentral` duplicated under "Project" scope
|
||
alongside the correct "User" scope registration — confusing, and every
|
||
other CURABIS repo from before the migration likely has the same file.
|
||
|
||
If `.claude/settings.json` contains `bc_actions_search`, `bc_actions_describe`,
|
||
`bc_actions_invoke`, or an `enabledMcpjsonServers` entry for `al`/`businesscentral`,
|
||
leave it in place by default and report it — no `ja/nej`, same reasoning as
|
||
step 3 (a developer who hasn't migrated their own machine's
|
||
`~/.claude/settings.json` yet would lose their auto-approvals if this were
|
||
pulled before they have, and Claude can't verify that from here):
|
||
|
||
```
|
||
ℹ️ .claude/settings.json indeholder en forældet tilladelsesliste fra før
|
||
static-tool-mode-migreringen (bc_actions_search/describe/invoke er de gamle
|
||
værktøjsnavne) og/eller enabledMcpjsonServers for al/businesscentral, som
|
||
duplikerer den korrekte user-scope-registrering under "Project" i MCP-panelet.
|
||
De aktuelle, korrekte værktøjsnavne dækkes allerede af ~/.claude/settings.json
|
||
(maskin-globalt, Step 3c). Fjernes kun når du eksplicit bekræfter at ALLE
|
||
udviklere på repoet er migreret — sig til når det er tilfældet.
|
||
```
|
||
|
||
Only remove the stale entries once a developer separately and explicitly
|
||
confirms every developer on the repo has migrated — never as part of this
|
||
automatic setup/update flow itself. If the file becomes empty afterward,
|
||
offer deleting it entirely at that same later point.
|
||
|
||
### HEARTBEAT.md token substitution (Mode B)
|
||
|
||
When creating HEARTBEAT.md from template in Mode B:
|
||
|
||
1. Derive `{PROJECT_NAME}` — read the first `# ` heading from `CLAUDE.md`
|
||
(e.g. `# ProjectManagement — Claude Code Instructions` → `ProjectManagement`).
|
||
If CLAUDE.md has no heading, use the git remote repo name.
|
||
2. Set `{SETUP_DATE}` to today's ISO date (YYYY-MM-DD)
|
||
3. Substitute both tokens before writing the file
|
||
|
||
### HEARTBEAT.md staleness check (Mode B)
|
||
|
||
`HEARTBEAT.md` is "never overwrite" (Step 4f / the reconciliation table above) — that
|
||
protects legitimate developer customization and the "Sidst opdateret" line, but it must
|
||
not mean drift goes undetected forever (BCQuality rule
|
||
`mode-b-never-overwrite-files-still-need-staleness-checks`). If `HEARTBEAT.md` already
|
||
exists, check it for known-bad patterns:
|
||
|
||
- **`Curabis/BCQuality` referenced anywhere** (PR checks, API URLs — e.g.
|
||
`https://api.github.com/repos/Curabis/BCQuality/pulls?state=open`). That repository is
|
||
the abandoned public fork of `microsoft/BCQuality` — Florence will silently report
|
||
"Routine: no open PRs" against it forever, since no one opens PRs there. The correct
|
||
target is `Curabis/QualityHub`.
|
||
|
||
If a match is found, show the specific line(s) and the proposed corrected line(s), and
|
||
ask for confirmation before editing — same confirmation gate as the CLAUDE.md
|
||
obsolete-forms check above. Never silently rewrite the whole file; this is a targeted
|
||
line fix that leaves everything else (custom checklist items, the "Sidst opdateret" date,
|
||
any team-added stations) untouched.
|
||
|
||
### What does NOT get updated
|
||
|
||
- `CLAUDE.md`'s project-specific content (project name, AL_PROJECTS_SECTION,
|
||
running-tests, Feynman section, about-this-project) — managed per project,
|
||
never auto-overwritten. Its now-removed generic sections (Smiley, Carlin,
|
||
on-demand roster, Francis, projectmemory/docs instructions) are only
|
||
touched once, during the v23→v24 migration above, and only with confirmation.
|
||
- `projectmemory/` — team knowledge, never overwritten by tooling
|
||
- `docs/` content — project documentation, never overwritten by tooling
|
||
- `~/.bc-mcp.config.json` — contains developer secrets
|
||
- An existing `al`/`businesscentral` user-scope MCP registration — Step 3c
|
||
registers if missing but never corrects an existing one (see the
|
||
machine-level table above)
|
||
|
||
### After update — lokal-agent-check (RegelSanity)
|
||
|
||
The reconciliation and validation steps in this Mode B flow constitute
|
||
**Rømer's inspection round** (`roemer.agent.md` owns the complete station
|
||
list). Reconciliation runs in BOTH directions. Missing template files are
|
||
handled above — this check finds the opposite: **extra** files in
|
||
`.github/.agents/` that are not in this document's template table (see
|
||
BCQuality rule `repo-local-agents-must-be-universalized-or-removed`).
|
||
|
||
**v24 note:** the template table now has exactly two rows (`bcquality.agent.md`,
|
||
`feynman.agent.md`), so on a v24 repo this check simply means "nothing else
|
||
should ever appear in `.github/.agents/`." A repo still full of pre-v24
|
||
copies isn't a RegelSanity violation — it is v23-era state, handled by the
|
||
one-time migration above (step 1), which runs first. This check is what
|
||
catches NEW extra files going forward (e.g. someone manually drops a custom
|
||
agent into `.github/.agents/` after migration) — same universalize-or-remove
|
||
choice as before.
|
||
|
||
1. List `.github/.agents/*.agent.md` and compare against the template table
|
||
2. For each file NOT in the table, output:
|
||
|
||
```
|
||
⚠️ RegelSanity: dette repo har en lokal agent, som ingen andre CURABIS-repos har:
|
||
|
||
- <navn>.agent.md
|
||
|
||
Repoer må ikke opføre sig forskelligt. Agenten skal enten:
|
||
a) universaliseres — jeg ruter den til Francis/Immanuel som BCQuality-forslag
|
||
(Retten hører sagen, hvis den rejser et portefølje-spørgsmål)
|
||
b) fjernes fra repoet
|
||
|
||
Hvad vælger du? (a/b)
|
||
```
|
||
|
||
3. Never delete without the developer's answer; never silently keep.
|
||
If (a): draft the Francis observation immediately — the local file is the
|
||
evidence. If (b): remove the file and note it in the update report.
|
||
|
||
### After update — agent-synligheds-check (v24: machine-level, not repo-level)
|
||
|
||
**v24 change:** the on-demand roster and the always-active Smiley/Carlin
|
||
sections moved to `~/.claude/CLAUDE.md` (see "CURABIS Standard — Shared
|
||
Roster" in `machine/CLAUDE.md`), so this check no longer compares against
|
||
the PROJECT CLAUDE.md — there is nothing left there to reconcile (the
|
||
project CLAUDE.md has no on-demand list any more; Feynman has his own
|
||
dedicated section and needs no separate visibility check). The check itself
|
||
still matters, just one level up: compare `~/.claude/curabis-agents/*.agent.md`
|
||
+ `~/.claude/agents/florence.md` against the roster list inside
|
||
`~/.claude/CLAUDE.md`.
|
||
|
||
**Special case — Smiley:** `smiley.agent.md` is always-active, not on-demand.
|
||
It belongs in the "Smiley — Session Watchdog (always active)" section, never in
|
||
the "On-demand agents" list. If Smiley is missing, propose his own section —
|
||
not an on-demand entry.
|
||
|
||
In practice this check is subsumed by "Machine CLAUDE.md refresh (Mode B)"
|
||
above: that step already diffs the developer's `~/.claude/CLAUDE.md`
|
||
structurally against `{BASE}/machine/CLAUDE.md` and proposes the update
|
||
(with confirmation) whenever they diverge — a newly-shipped roster agent not
|
||
yet listed is exactly the kind of structural divergence that step catches.
|
||
No separate action needed here beyond running that step.
|
||
|
||
### After update — report and commit
|
||
|
||
Report what changed, then ask:
|
||
> "Opdatering færdig. Vil du have mig til at committe ændringerne? (ja/nej)"
|
||
|
||
If yes, commit:
|
||
```
|
||
[SETUP] Opdater CURABIS Standard fra BCQuality
|
||
|
||
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
```
|
||
|
||
---
|
||
|
||
## MODE C — Support-profil (onboard en supportbruger)
|
||
|
||
Triggered by: **"Onboard en supportbruger til CURABIS Standard"**
|
||
(også accepteret: "Konfigurer support-profil")
|
||
|
||
Formål: give en ikke-udvikler (forretningskonsulent, supportmedarbejder)
|
||
mulighed for at stille spørgsmål til CURABIS-repos og Microsofts kilder —
|
||
via Feynman-agenten (`feynman.agent.md`), uden VS Code, uden lokal
|
||
maskinopsætning og uden skriveadgang.
|
||
|
||
### Hvad profilen IKKE indeholder — med vilje
|
||
|
||
- Ingen VS Code, ingen AL Language extension
|
||
- Ingen bc-mcp-bridge, ingen `~/.bc-mcp.config.json` — supportbrugeren får
|
||
aldrig secrets
|
||
- Ingen QualityHub-klon og ingen machine self-heal — supportbrugeren har ikke
|
||
(og skal ikke have) adgang til QualityHub; `feynman.agent.md` ligger i hvert
|
||
konfigureret repo, og CLAUDE.md-templatens "Feynman — Support-sessioner"-
|
||
sektion slår self-heal fra i support-mode
|
||
- Ingen skriveadgang til noget repo — rollen er læsende, og GitHub-rollen
|
||
håndhæver det
|
||
|
||
### Step 1 — Spørg om to ting
|
||
|
||
```
|
||
1. Supportbrugerens navn og GitHub-brugernavn?
|
||
2. Hvilke repos skal brugeren have læseadgang til?
|
||
```
|
||
|
||
### Step 2 — GitHub-adgang (udføres af administratoren)
|
||
|
||
Guide administratoren gennem:
|
||
|
||
1. Invitér brugeren til organisationen som **member**
|
||
2. Giv **Read**-rolle på de valgte repos — aldrig Write/Maintain/Admin
|
||
3. Verificér at brugeren IKKE har adgang til `Curabis/QualityHub` — og tjek
|
||
BÅDE vejene dertil, ikke kun den ene: (a) ingen direkte collaborator-
|
||
invitation til QualityHub, OG (b) brugeren er ikke medlem af et team der
|
||
selv har adgang til QualityHub (team-nedarvet adgang omgår en ren
|
||
per-repo-check), OG (c) organisationens "Base permissions" (Org Settings →
|
||
Member privileges) ikke er sat bredere end "No permission"/"Read" på en
|
||
måde der stiltiende dækker private repos. 2026-08-03: et tidligere audit
|
||
fandt at trin 3 kun tjekkede (a) — en bruger kunne i praksis få adgang via
|
||
(b) eller (c) uden at noget fangede det.
|
||
4. **Registrér onboardingen** i `custom/setup/support-users-onboarded.md`
|
||
(denne fil, append-only) — navn, GitHub-brugernavn, dato, tildelte repos.
|
||
Uden dette har intet senere trin (station 15 i Rømers runde) noget at
|
||
tjekke imod, og en glemt/forkert adgang forbliver usynlig for altid, ikke
|
||
kun til næste inspektion.
|
||
|
||
### Step 3 — Claude-miljø (browser, ikke VS Code)
|
||
|
||
1. Claude-sæde til brugeren (Team-plan)
|
||
2. **Claude Code på web** (claude.ai/code): forbind brugerens GitHub-konto og
|
||
vælg de tildelte repos
|
||
3. MCP-connectors i brugerens miljø — begge læsende, ingen tokens med
|
||
skrive-scopes:
|
||
- **GitHub MCP** — adgang til Microsofts offentlige repos:
|
||
`microsoft/BCApps`, `microsoft/ALAppExtensions`,
|
||
`MicrosoftDocs/dynamics365smb-docs`
|
||
- **Microsoft Learn MCP** — officiel dokumentationssøgning
|
||
|
||
### Step 4 — Onboarding-dokument
|
||
|
||
1. Fetch `{BASE}/templates/feynman-onboarding.md`
|
||
2. Erstat `{SUPPORT_NAME}`, `{REPO_LIST}` (punktliste over de tildelte repos)
|
||
og `{SETUP_DATE}` (dags dato, ISO)
|
||
3. Aflevér dokumentet til supportbrugeren (mail/Teams) — det forklarer
|
||
trigger-frasen "Feynman:", gode spørgsmål, og hvordan et Feynman-notat
|
||
videresendes til en udvikler
|
||
|
||
### Step 5 — Verifikation
|
||
|
||
Bed supportbrugeren starte en session i et af de tildelte repos med:
|
||
|
||
> "Feynman: hvad kan du hjælpe mig med i dette projekt?"
|
||
|
||
Forventet: svar på dansk i forretningssprog, bekræftelse af support-mode
|
||
(strengt læsende), og INGEN self-heal-/onboarding-støj ved session-start.
|
||
|
||
### Forudsætning
|
||
|
||
Mode C forudsætter at de tildelte repos er konfigureret med CURABIS Standard
|
||
v23+ (Feynman i rosteret + support-sektionen i CLAUDE.md). Kør Mode B på
|
||
repos, der endnu ikke har `feynman.agent.md`.
|
||
|
||
---
|
||
|
||
## Invocation note
|
||
|
||
This agent is read on demand from the machine's channel clone
|
||
(`%USERPROFILE%\.claude\QualityHub\custom\setup\curabis-standard.agent.md`,
|
||
after freshening — see Source section). All three commands work in any project —
|
||
including one not yet configured — because the machine's `~/.claude/CLAUDE.md`
|
||
(installed by onboarding) knows the clone location. On a machine without the
|
||
clone, the two-line onboarding in Step 4a's self-heal is the entry point. |