Commit graph

184 commits

Author SHA1 Message Date
Michael Dieringer
7e703b93d5 Forslag: upgrade-tag-logic-must-not-nest-deeply 2026-08-13 08:11:54 +02:00
Michael Dieringer
16f3cd0aee Sharpen: Setup-page OnOpenPage must instantiate the singleton record 2026-08-13 07:38:53 +02:00
Michael Dieringer
14ac4485c8
Merge pull request #64 from Curabis/rule/al-comments-must-not-restate-what-code-already-shows
Forslag: AL-kommentarer maa ikke bare genfortaelle koden
2026-08-13 07:19:09 +02:00
Michael Dieringer
3df1d630d4 Forslag: AL-kommentarer maa ikke bare genfortaelle koden 2026-08-13 07:18:15 +02:00
Michael Dieringer
a74b8e35f3 Forslag: GIVEN-blokke skal daekke hele precondition-kaeden for posting/rapporter 2026-08-13 07:14:01 +02:00
Michael Dieringer
13c7d4e198
Merge pull request #61 from Curabis/rule/file-datatype-direct-io-is-onprem-only
[BCQuality] File data type's direct I/O methods are OnPrem-only
2026-08-13 07:02:24 +02:00
Michael Dieringer
860f2db01b Forslag: prefer-email-module-over-codeunit-mail-397 2026-08-13 06:56:40 +02:00
Michael Dieringer
10af99bb22 Forslag: file-datatype-direct-io-is-onprem-only 2026-08-13 06:56:39 +02:00
Michael Dieringer
0d578e9f3d Forslag: dimension-support skal foelge DimensionManagement-wiring-moensteret 2026-08-13 06:31:46 +02:00
Michael Dieringer
7e70c4aa5d Forslag: posting-rutiner skal foelge Check Line/Post Line/Post Batch-moensteret 2026-08-13 06:25:20 +02:00
Michael Dieringer
4bb14fb821
Merge pull request #48 from Curabis/rule/table-design-must-match-bc-table-type-conventions
[BCQuality] BC table-type conventions (naming, primary key, pages)
2026-08-13 06:09:42 +02:00
Michael Dieringer
10ff2449f6
Merge pull request #49 from Curabis/rule/page-design-must-match-bc-page-type-conventions
[BCQuality] BC page-type conventions (naming, structure, links)
2026-08-13 06:09:26 +02:00
Michael Dieringer
fba0ff2a26
Merge pull request #50 from Curabis/rule/intrinsic-al-functions-must-use-modern-casing
[BCQuality] Intrinsic AL function calls use modern casing, not ALL-CAPS
2026-08-13 06:09:02 +02:00
Michael Dieringer
d7001e0e23
Merge pull request #51 from Curabis/rule/binary-choice-must-be-boolean
[BCQuality] Binary yes/no choices must be Boolean, not Option/Integer
2026-08-13 06:08:37 +02:00
Michael Dieringer
9d4126ac34
Merge pull request #52 from Curabis/rule/fixed-choice-set-must-use-enum-not-integer
[BCQuality] Fixed choice sets must use Enum, not raw Integer
2026-08-13 06:08:10 +02:00
Michael Dieringer
87c7b6aaa2
Merge pull request #53 from Curabis/rule/variable-names-must-be-semantically-descriptive
[BCQuality] Variable names must be semantically descriptive, not type+number
2026-08-13 06:07:44 +02:00
Michael Dieringer
be75cf8e70
Merge pull request #54 from Curabis/rule/var-parameters-require-an-addressable-variable
[BCQuality] var parameters require an addressable variable, not a literal
2026-08-13 06:07:16 +02:00
Michael Dieringer
336fca3d10
Merge pull request #55 from Curabis/rule/code-must-not-change-workdate
[BCQuality] Application code must not change the WorkDate
2026-08-13 06:06:57 +02:00
Michael Dieringer
c79908a695
Merge pull request #56 from Curabis/rule/ambiguous-record-failure-handling-must-be-clarified
[BCQuality] Ambiguous record-failure handling must be clarified, not guessed
2026-08-13 06:06:28 +02:00
Michael Dieringer
5e55e5b197
Merge pull request #57 from Curabis/rule/document-reports-should-default-to-word-layout
[BCQuality] Document reports should default to Word layout, not RDLC
2026-08-13 06:05:56 +02:00
Michael Dieringer
c14a7189c8 Forslag: billeder skal gemmes i Media/MediaSet, ikke BLOB 2026-08-12 23:02:31 +02:00
Michael Dieringer
f4a1108209 Forslag: dokumentrapporter skal defaulte til Word layout, ikke RDLC 2026-08-12 22:57:57 +02:00
Michael Dieringer
e61c3db041 Forslag: ambiguous-record-failure-handling-must-be-clarified 2026-08-12 22:51:15 +02:00
Michael Dieringer
f2d6674391 Forslag: code-must-not-change-workdate 2026-08-12 22:51:14 +02:00
Michael Dieringer
bed13b9b60 Forslag: var-parametre kraever en adresserbar variabel, ikke literal/udtryk 2026-08-12 22:44:57 +02:00
Michael Dieringer
35c29f6af3 Udvid undtagelse: s/c i Dialog/Window progress-idiom er ogsaa accepteret 2026-08-12 22:37:28 +02:00
Michael Dieringer
c06effd01e Forslag: variable-names-must-be-semantically-descriptive 2026-08-12 22:30:50 +02:00
Michael Dieringer
e7f9d9f87a Forslag: fixed-choice-set-must-use-enum-not-integer 2026-08-12 22:30:48 +02:00
Michael Dieringer
a06b684e87 Forslag: binary-choice-must-be-boolean 2026-08-12 22:30:47 +02:00
Michael Dieringer
943d1ac6ee Forslag: intrinsic AL-funktionskald skal bruge moderne casing, ikke ALL-CAPS 2026-08-12 22:17:42 +02:00
Michael Dieringer
19e3bb7c72 Ret: tilfoej Design Pages Best Practices (s.112) + fjern duplikeret afsnit 2026-08-12 22:09:24 +02:00
Michael Dieringer
8ef8209cce Forslag: BC page-type conventions (naming, structure, links) 2026-08-12 22:04:51 +02:00
Michael Dieringer
052288bc9b Forslag: BC table-type conventions (naming, PK, pages) 2026-08-12 21:58:50 +02:00
Michael Dieringer
d1fec64533 Foreslå regel: al MCP build/publish kræver absolut projectPath 2026-08-10 11:41:26 +02:00
Michael Dieringer
4c225c4ac3 EXPERIMENTAL, UNTESTED: explicit session close (DELETE) before reinitializing
Neither of the bridge's two "clear sessionId and reinitialize" paths ever
told BC the old session was actually done - they just drop the local
sessionId variable and let a fresh session get issued on the next call.
The MCP Streamable HTTP transport spec defines an explicit way to end a
session: an HTTP DELETE to the endpoint carrying the session's
Mcp-Session-Id. The bridge has never called it.

Trying this as a candidate fix for the recurring Internal_CompanyNotFound
pattern documented in bc-mcp-company-header-must-match-exact-company-name.md:
a client-side session reset (clear sessionId + reinitialize) does NOT clear
the error, but a manual save on the BC-side MCP Server Configuration record
does. If BC's server-side session state is what's actually stuck, an
explicit close might do the same job the manual config-save has been doing
by accident.

Committed before live-testing (not after) specifically so it survives the
next sync-bcquality-knowledge.ps1 run instead of being silently overwritten
from the old source - this is a durability commit, not a confirmed-fix
commit. Best-effort and silent on failure: if BC responds 404/405 (DELETE
not implemented), that's evidence for the MS support escalation, not a bug
here. Update this commit's status (confirmed working / confirmed no effect
/ reverted) once tested against a live recurrence.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-07 21:42:08 +02:00
Michael Dieringer
2ce2697010 Record candidate workaround: MCP Server Configuration save correlates with recovery
New follow-up section, distinct from the 2026-08-03 "ruled out" static
verification (Aktiv/Standard confirmed on, unchanged). This is about the
save/toggle *action* on CURABIS_DEV's MCP Server Configuration page, not
its resting state - not previously tested.

Observed 2026-08-07 (MID): Internal_CompanyNotFound recurred. VS Code
restart + retry failed (consistent with the already-falsified restart
theory). Toggling the Standard field on CURABIS_DEV and saving, then
retrying, worked immediately. MID reports having seen this same pattern -
restart-retry fails, config-touch-retry succeeds - on prior occasions.

Framed explicitly as a candidate, not a confirmed fix: n>=2 informal
observations, toggle direction untested (MID's own read is that direction
is probably irrelevant, pointing at the save/republish action busting a
server-side cache rather than at the field's value), and no baseline
established against the error's already-documented intermittency. Does
not override the Microsoft-support-escalation guidance - if anything it's
supporting evidence for that escalation, since a CURABIS-side config touch
masking a BC-side symptom points at BC's MCP session/cache layer.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-07 14:06:31 +02:00
Michael Dieringer
461d3279e8
Merge pull request #35 from Curabis/fix/bc-mcp-restart-theory-falsified
[BCQuality] Retract restart theory, confirm MS-support escalation for BC MCP company error
2026-08-07 12:34:08 +02:00
Michael Dieringer
73e5a01a36
Merge pull request #46 from Curabis/fix/bc-mcp-bridge-proactive-session-refresh
[bc-mcp-bridge] Reactive + proactive session self-heal
2026-08-07 08:36:34 +02:00
Michael Dieringer
386729f2ef bc-mcp-bridge: reactive + proactive session self-heal
Two fixes bundled together, both diagnosed from a live BC MCP failure in
a Jernpladsen (Project Management 365) session:

- 2026-08-05 (previously drafted, never committed): BC rejects a
  non-initialize request with a stale/absent Mcp-Session-Id with "A new
  session can only be created by an initialize request." The prior retry
  just cleared sessionId and resent the same message with no header,
  reproducing the identical error. Now replays the client's cached
  initialize message first to obtain a fresh session, then retries.
  This also fixes dispatchCreateComment's per-chunk fresh-session reset,
  which was hitting exactly this failure on every chunk of a >250-char
  Task Comment.

- 2026-08-07: the reactive fix above only self-heals after BC has
  already rejected a request. A client that opens a fresh session per
  call (e.g. a Power Automate flow) never hits staleness at all, which
  is why that pattern reads as more reliable than our long-lived
  interactive bridge process. Added a proactive refresh: if the cached
  session has been idle past a heuristic threshold, re-initialize
  before attempting the call instead of waiting for the rejection.
2026-08-07 08:34:20 +02:00
Michael Dieringer
44c7c1ad6b
Merge pull request #45 from Curabis/rule/adopt-community-batch-2026-08-07
[BCQuality] Adopt 11 community rules into custom always-on layer
2026-08-07 08:07:06 +02:00
Michael Dieringer
d4e351f333 Adopt 11 community rules into custom always-on layer
Promotes rules that are already published in community/ to custom/knowledge/,
so they load at every session start instead of only on keyword relevance.
Each file carries extends: pointing back to its community source.

Passed Immanuel's four-test Categorical Imperative validation on 2026-08-07.
2026-08-07 08:04:12 +02:00
Michael Dieringer
9fa160ec1f Foreslaa regel: TestField a setup-table value before using it in a correctness-critical branch 2026-08-06 21:12:33 +02:00
Michael Dieringer
0563887aea bc-mcp-bridge: timeout + one-retry-with-fresh-session self-heal
Neither fetch() call had a timeout, and the BC session (Mcp-Session-Id)
plus the underlying HTTP connection were reused for the bridge process's
entire lifetime with no proactive refresh. A long-running Claude Code
session with gaps between calls can leave either stale.

Observed today: a 30-minute hang on one call (no timeout meant it never
failed on its own), and separately an "Internal_CompanyNotFound" on two
machines that likely wasn't a real company problem but a dead session --
Michael noticed the pattern independently: Summatim's frequent quick calls
never have this issue, longer sessions with gaps do.

Added REQUEST_TIMEOUT_MS (30s) via AbortSignal.timeout on both fetch
calls, and wrapped forward() to retry once with sessionId cleared on any
failure -- self-heals a stale session/connection without the developer
noticing. Tested end to end: full initialize + tools/call succeeds
normally (no retry needed), and a forced-failure path correctly retries
once then surfaces the real error if it persists.
2026-08-05 14:05:42 +02:00
Michael Dieringer
1fe40a2001 Add Node.js runtime prerequisite check before machine setup Step 3
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.
2026-08-04 12:41:09 +02:00
Michael Dieringer
6c3e5ace35 Company policy: glide through setup gates with no real decision
Observed live: a consultant hit "no" reflexively on a setup confirmation
while moving fast through onboarding, and only noticed afterward. Most
of this document's ja/nej gates aren't real choices -- the standard is
company policy, not a per-developer preference -- and a blocking
question with only one sane answer just invites that kind of misclick.

v24 -> v25. Converted to act-and-report (no question) wherever the file
is git-tracked and the replacement is already verified correct: the
v6-era repo-mirror cleanup, CLAUDE.md's obsolete-forms replacement, and
the v24 migration's repo-local agent-file / find-altool.ps1 removal --
all fully recoverable via git revert if anyone ever wants the old
version back. Converted the two genuine multi-developer-coordination
steps (.mcp.json, .claude/settings.json -- whether every developer has
migrated their own machine is a fact only a human knows) from a
blocking question to a safe default (leave in place, report, offer
removal later once a developer explicitly confirms).

Left three gates as real questions, on purpose: uncommitted local
changes on CLAUDE.md (actual risk of lost work), the developer's
personal ~/.claude/CLAUDE.md (not git-tracked, carries personal
customization), and the two "should I commit this?" prompts (commit
timing is a legitimate choice, not a policy with one right answer).
2026-08-04 11:40:02 +02:00
Michael Dieringer
a3b79eedc2 Deploy a shared MCP-tool permissions allowlist; detect legacy .claude/settings.json
Two related fixes, discovered together while debugging Wareco's duplicated
"Project" scope MCP entries:

1. New custom/setup/machine/settings.json template + a merge-safe deploy
   step in sync-bcquality-knowledge.ps1 (section 10): auto-approves the
   read-only/already-protocol-gated tool calls across the three
   CURABIS-managed MCP servers (businesscentral's 15 static tools, al's
   11 dev-loop tools, microsoft-learn's 3 docs tools) via
   ~/.claude/settings.json's permissions.allow -- merged into whatever
   already exists, never overwritten, since that file also carries a
   developer's personal settings. Tested against a real 298-entry
   settings.json: preserved every existing key/array untouched, added
   only the 14 genuinely-missing entries.

   Found and fixed two real bugs while building this: -AsHashtable
   doesn't exist in Windows PowerShell 5.1 (this script also runs via
   `powershell`, not just `pwsh`) -- switched to PSCustomObject +
   Add-Member. And Set-Content -Encoding utf8 writes a BOM in PS5.1 with
   no utf8NoBOM option -- switched to [System.IO.File]::WriteAllText
   with an explicit no-BOM UTF8Encoding, since the original file had no
   BOM and a JSON parser choking on one would have silently broken every
   developer's settings.json.

2. Wareco's committed .claude/settings.json still has the pre-migration
   Dynamic Tool Mode tool names (bc_actions_search/describe) and an
   enabledMcpjsonServers entry for al/businesscentral -- the latter is
   why the MCP servers panel shows them duplicated under "Project" scope
   next to the correct "User" scope registration. Added detection +
   confirmed-removal migration step (mirroring the existing .mcp.json
   migration's multi-developer coordination caveat) and Roemer station
   16 to catch this on other pre-migration repos (gtt-marine likely has
   the same file).
2026-08-04 07:31:46 +02:00
Michael Dieringer
4227997ceb Sharpen: retract restart theory, confirm MS-support escalation for BC MCP company error
The 2026-08-03 follow-up's "restart Claude Code" step was falsified same
day by a full machine reboot that left Internal_CompanyNotFound unchanged.
Records the two theories ruled out with evidence (stale bridge process;
MCP config/company misconfiguration, both screenshot-verified) and states
plainly that this is a client-unfixable, likely BC/SaaS-side condition
requiring Microsoft support escalation.
2026-08-03 16:00:15 +02:00
Michael Dieringer
3d4d858497 Sharpen: BC MCP company-header rule — correct header isn't proof against recurrence
Internal_CompanyNotFound recurred 2026-08-03 on two machines with the
company header already matching Navn correctly, ruling out the original
header-mismatch cause. Failure was intermittent and appeared to clear after
restarting Claude Code, suggesting a separate, still-unconfirmed session/
bridge staleness issue. Adds a follow-up section with next steps so future
sessions don't re-verify an already-correct header a third time.
2026-08-03 15:10:18 +02:00
Michael Dieringer
0792bec11a Smiley/Carlin disclosure: intent-triggered, not name-triggered
"If asked directly about Smiley... by name" required a user to guess the
right codename to get an honest answer about whether something shapes
the session's behavior -- a concealment regardless of good intent, and
the same "keyed to phrasing instead of the actual thing being asked" bug
already fixed elsewhere in this standard (Columbo/al-complexity split,
Smiley's TDD gate), just applied to disclosure instead of activation.

Raised independently by a Claude session during Linh's onboarding, which
declined to treat "never explain the mechanism" as covering a good-faith
general question. Fixed the wording to match: stay quiet unprompted, but
answer honestly if asked in general terms, name or no name.
2026-08-03 14:29:04 +02:00
Michael Dieringer
9e5273443f Fix all 6 confirmed findings from today's gap audit
Implements every confirmed finding from the workflow-based audit of
CURABIS Standard's agent model (7 finders + adversarial verification,
8 confirmed / 5 refuted):

1. Roemer/Florence phantom wiring - roemer.agent.md claimed Florence's
   heartbeat "may summon me when a ward smells of drift" with nothing in
   florence.agent.md or HEARTBEAT.md implementing it. Fixed by adding an
   explicit "Kald Roemer" instruction to HEARTBEAT.md ward 6 (agent
   visibility, his actual domain), mirroring ward 8's existing "Kald
   Weber" pattern, and correcting roemer.agent.md's own claim to match.

2. m365.agent.md's "Florence's morning brief pattern" was a one-way
   orphaned reference - a full 4-step pattern with nothing in
   florence.agent.md implementing it. Added it to florence.agent.md as
   an explicit on-demand capability, separate from the timestamp-gated
   Round protocol.

3. An Ergasterion "PROCEED WITH CHANGES" ruling had no way to be checked
   against the eventual diff - al-review's checklists never referenced
   it. Added ERGASTERION_RULING to the [CURABIS-STATE] vocabulary,
   wired Ergasterion to write it, and added a BLOCKing checklist item to
   al-review's Titus checklist that verifies required changes were
   actually implemented.

4. curabis-task-state-check.yml was headered "Deterministic enforcement
   (not LLM diligence)" but only checks checkbox order, only blocks
   anything if a human separately enabled branch protection (never
   verified anywhere), and doesn't exist at all for the PTE track.
   Corrected the header's claims and added Roemer station 14 to verify
   branch protection is actually configured.

5. Mode C's only safeguard against a support user reaching
   Curabis/QualityHub was a single manual eyeball check with no re-check
   ever. Strengthened Step 2 to cover team-inherited and org-default
   access paths, added an append-only support-user registry, and added
   Roemer station 15 to periodically re-verify every registered user
   against it.

6. Columbo's persona was presented as genuine autobiography with no
   disclosure of its fictional TV origin (Levinson & Link, Peter Falk),
   unlike Smiley which discloses explicitly. Added a reader-facing
   editorial note - never something Columbo says aloud, since unlike
   Smiley he actually performs the persona to customers.
2026-08-03 14:12:05 +02:00