Development Module
Fixes on the code the customer runs. Bug fixes and small features that extend existing functionality — never new modules (goals). The customer's lineage is not the main branch: it forked on 18.03.2025 and has diverged since — the counts live in memory with their measuring query, never as a quoted figure (§ 0.1) — so a fix developed on the main branch may not apply to the code the customer runs, and every case starts by naming which code it is fixing.
The flow, as the product page draws it. Planning — reproduction, the branch set, placement. Approval — the brief: why this seam, the blast radius, the test plan, before any code; a person decides, always. Implementation — isolated worktrees, one agent per source. Test — build, unit, interface, eval sets; a signed result. Corrections — an isolated reviewer with no author context, and the human, until both are satisfied. Merge request — reviewed under the estate's own development process before any script is approved. Scripts — gate H4: the script set per named target, the port prepared, the revert path. Deploy approval — on the named environment, by its approver. Deploy and verify — the deployment agent resolves the estate’s pipeline job by the per-environment rule and triggers it after the gate (D130); which commit actually serves is checked, then the port to master is opened; a signed result. Reversal — only on a problem: the standing revert path, on a human decision. Deploy, test and revert are the definition of done, so nothing here runs after the workflow.
P The module is source-agnostic (decision Vladimir, 02.09.2026 — D58): it is built against the idea of a source — a system it can read, change, build, test and deploy — never against a concrete estate. A source is configuration (a sources row set per customer plug-in, Whitelabel Catalogue § 4): its repositories, its database side, its branch model and start flows, its seam catalogue, its build/test gates, its deploy mechanism. The Bulstrad estate's sources — serdica-backend, serdica-ui, intentgpt and the environment databases' PL/SQL — are the first plug-in's content (the Camunda process files are not a source of their own: they live in serdica-backend, written by the camunda developer into source/serdica-backend/core), named in this page because they are the working example; the module that works them works any declared source. What a case runs on is not master by default: the customer lineage forked from master on 18.03.2025 F: measured; [memory]. Repository knowledge (microservice indexes, build truths, branch maps) lives in the source/* memory domains (§ 0.1 above; Agents Memory Part I), not in this document. The seam catalogue and the criteria that choose between them are in Stage Planning.
0. The agents
P The tree. One implementer per declared source, each booted from that repository's own memory domain; a planner that owns placement; a reviewer with no author context; a deployer; the Camunda developer and the database extractor as isolated sub-agents. The dashed edges are consults to the other modules' domains, the one handover, and the one exit.
flowchart TB R["source.root"]:::owner P["S1–S2 Planner"]:::work I["S3 Repository implementers"]:::work C["Camunda / DB specialists"]:::work T["S4 Test runner"]:::proof V["S5 Independent reviewer"]:::proof D["S6–S9 Deployer"]:::work K["Repository knowledge"]:::learn R --> P P -->|"approved work"| I I -.->|"specialise"| C I -->|"change and tests"| T T -->|"actual results"| V V -->|"reviewed revision"| D K -.->|"current applicability"| P D -.->|"propose experience"| K classDef work fill:#eef4ff,stroke:#6889ba,color:#17365b,stroke-width:1.3px classDef decision fill:#fff4df,stroke:#b78c36,color:#65470d,stroke-width:1.5px classDef proof fill:#e9f5ef,stroke:#689b81,color:#224e39,stroke-width:1.3px classDef learn fill:#f1edf9,stroke:#9580b9,color:#534172,stroke-width:1.3px classDef store fill:#f5f7fa,stroke:#98a6b7,color:#34445a,stroke-width:1.2px classDef owner fill:#24486b,stroke:#24486b,color:#ffffff,stroke-width:1.4px click R href "../modules.html" "Owns the bounded change and receives an accepted Hd handover." click P href "stage-planning.html" "Reproduces the issue and pins actual source lineage, scope and placement." click I href "stage-implementation.html" "Backend, UI, DB/PLSQL and declared external source; riskmodel stays with backend." click C href "stage-implementation.html" "Bounded process work and read-only stored-code extraction." click T href "stage-test-and-corrections.html" "Deterministic command execution in a confined worktree; no model prompt." click V href "stage-test-and-corrections.html" "Review the complete change series and relevant generated artefacts." click D href "stage-deploy-and-reversal.html" "Release graph, current permits, target proof, directional port and reversal." click K href "../50-agents/agents-memory.html" "Versioned placement, build and recovery knowledge; publish tested improvements."
Agent responsibility follows the work. Repository implementers prepare changes; only the shared granted execution path can publish, deploy or change a target.
Root: source.root owns the case and receives Hd handovers from Support and Configuration. Lateral: implementers consult configuration/abacus on engine questions and the experience index on precedent; the two-failed-attempts rule sends unknown contracts to the owning repo agent [F: the PC 9951 run]. P Implementer agents are per source, and the set is configuration (D58): another customer declares its own sources and gets its own implementer profiles; the module does not change. P A missing repository node is never a prerequisite — a summarizer creates it before the work continues (Agents § 0.6).
Profiles in full — what each boots from, writes, may use, is denied, and the eval set that proves it: Components — Development § 3.
0.1 Its branch of the memory tree
source/
├─ AGENTS.md repo index + placement rules
├─ serdica-backend/
│ ├─ AGENTS.md index of service areas and microservices
│ └─ <microservice>/AGENTS.md created on the first case that works it (Agents § 0.6)
├─ serdica-ui/AGENTS.md
├─ intentgpt/AGENTS.md
└─ db-plsql/AGENTS.md
Migration is wave 4 — per repository, as cases arrive (Agents Memory § 7); every seed a fact, linked.
| Domain | Owning profile | Contents | Seeds |
|---|---|---|---|
source/ |
root and planner | the seam catalogue per source, the placement criteria, the port procedure, the branch and environment map | Stage Planning; branch/env map + divergence |
source/serdica-backend |
backend implementer | microservice index: platform services (Core, ApiGateway, IdentityServer, Authority, FileServer, NotificationService, PdfGeneration, RestApi/GraphQL/ServiceApi, ScheduleJobs, McpProxy), PAS services (Claims, PasPolicy, PasPolicyCrud, PasPremium, PasHealth, PasOperations, PasAnnexProcessing, PasBatch, PasClient, PasCustomerCrud, PasClaimsCrud, PasSrdIprodCrud, PasValidation, OutreachService), customer services under BusinessInsurance/ (BstPasPaymentPlan, BstPasPolicyService, PasClaim family, Integrations), Analytics/riskmodel, __Libraries [F: git ls-tree origin/master src/…, 31.08.2026]; per-microservice child nodes created on first case; the index is built for both source layouts* — master/bulstrad-qa and bulstrad-staging/bulstrad-prod — with a path map and the packaging (project reference vs NuGet) per lineage (§ 5 G15, G16) |
root AGENTS.md build/test/Vault toolchain F; LSP rule; compiled EF model; branch/env map + divergence |
source/serdica-ui |
ui implementer | Nx/formly mechanics, factor payload gates, admin-page work, the per-branch path map | field validation; PC frontend-gate facts |
source/intentgpt |
intentgpt implementer | C built on first case — repo absent here; known: Beth+AI components, health path being replaced | Beth anatomy; AI-program retirement manifest [F: branch tools, inspected 31.08.2026] |
source/db-plsql |
plsql implementer | extract-apply, release audit, UEXIT seams, per-env DB model | 95 packages; workflow; 4-layer audit |
P Divergence numbers live in memory with their measuring query, never as a quoted figure, because they change (Development Details DG-3).
0.2 Skills and tools
P All five are stage skills — their evidence is the module design, not the ticket stream (Agents Memory and Skills § 9). Each is code plus assertions, governed like a prompt.
| Skill | Stage | What it does | What it asserts |
|---|---|---|---|
| worktree + build + test runner | S3, S4 | an isolated worktree per repository per case; the build, the unit tests, the front-end build and its tests — dotnet build authoritative, nx for the UI |
the build is the authority; a language-server diagnostic is not |
| PL/SQL snapshot + signature | S1, S3 | one row per environment × object × digest, append-only, mirrored to a repository the platform owns alone — the Stage Planning § 3b capture | the signature decides whether the source changed; a timestamp cannot carry that decision, because a recompile bumps it whether or not a change is in it |
| PL/SQL apply with precondition | S3, S8 | the capture → preflight → apply → verify → compensate loop | the signature recorded at extraction is a precondition of the write grant; if the other author saved in between, the apply is refused after authorised read preflight, before DDL; external-writer exclusion is also required and a three-way merge re-enters the gate |
| release audit | S8 | which commit actually serves on the target after a deploy — the 4-layer TEST vs PROD audit (release audit) | a valid database object can still be a stub; stack lines and versions are the evidence |
| port between layouts | S6 | a fix carried between two source layouts: feasibility check, path rewrite, layout files excluded, the pipeline file regenerated | the port is a commit of its own naming the source commit; "no counterpart" is an allowed recorded outcome |
Tools. gitlab — read, worktree, commit inside the worktree, push the case branch (never a protected branch) to open the merge request, merge under H4, read the infrastructure repository to enumerate a deploy set; oracle — stored-code snapshot and signature, the DDL packet with a signature precondition, the dependency and caller sweeps, applied by the write executor under HW-ddl (D104); ssh / host — read-only commands on an allow-list, a privileged command as a gated write; kibana — the runtime verification reads. The six standing prohibitions each skill guards: Components — Development § 4; the connector operations and their effect classes: Components — Development § 5.
1. The stages
flowchart TB P["Plan the actual lineage"]:::work G["Confirm scope and plan
H1 / H2"]:::decision I["Implement and test
S3 / S4"]:::work V["Review the full series
S5 / H3"]:::proof R["Prepare joined release
S6 / H4"]:::work D["Authorise and deploy
S7 / S8"]:::decision T["Verify target and port"]:::proof X["H7 Reversal
then prove recovery"]:::decision K["Retain regression
and lineage knowledge"]:::learn P --> G G --> I I --> V V -.->|"correction"| I V --> R R --> D D --> T T -.->|"failed proof"| X T -.->|"after result"| K classDef work fill:#eef4ff,stroke:#6889ba,color:#17365b,stroke-width:1.3px classDef decision fill:#fff4df,stroke:#b78c36,color:#65470d,stroke-width:1.5px classDef proof fill:#e9f5ef,stroke:#689b81,color:#224e39,stroke-width:1.3px classDef learn fill:#f1edf9,stroke:#9580b9,color:#534172,stroke-width:1.3px classDef store fill:#f5f7fa,stroke:#98a6b7,color:#34445a,stroke-width:1.2px classDef owner fill:#24486b,stroke:#24486b,color:#ffffff,stroke-width:1.4px click P href "stage-planning.html" "Reproduce, define the outcome, choose the approved seam and target set." click G href "../gating.html" "Parent confirmation orders work; the required role confirms its scope." click I href "stage-implementation.html" "One case may contain many commits and several repositories." click V href "stage-test-and-corrections.html" "Include schema, lockfile, configuration and generated-contract changes." click R href "stage-deployment-scripts.html" "Pin code, rows, packages, consumer images, BPMN and external templates." click D href "stage-deploy-and-reversal.html" "Execute the compatibility order under current target permissions." click T href "stage-deploy-and-reversal.html" "Serving revision and customer outcome, not image publication alone." click X href "stage-deploy-and-reversal.html" "Reconcile unknown effects; compensate only what this case changed." click K href "../50-agents/agents-memory.html" "Evaluate changes before the next independent case uses them."
Delivery is a joined, verified outcome. Dashed edges are correction, reversal or learning; a failed target check cannot be replaced by a successful build.
Stage ids name the stage documents, not a running order (D83).
P Which environment a case works on and which it targets is knowledge per product line (D123): the existing policy-administration products develop locally, then bulstrad-staging (TEST), then PROD, porting to master → bulstrad-qa afterwards; the health line (product 8000) works on QA, ports to master and targets the planned bulstrad-prod-2. The paths and the branch set they resolve to are Stage Planning § PL-3.
P Two signed results, and no step after the workflow. S4's green gates per repository and the pipeline result are the evidence S5 and H4 read (Stage Test and Corrections, DG-7); S8's runtime verification — which commit actually serves — is the signed result that opens the port (Stage Deploy and Reversal, D114, D141). Deploy, test and revert are the definition of done (DG-5), so nothing in this module runs after the workflow. The states are those of Gating § 1b (D148).
| Stage | Page |
|---|---|
| S1–S2 planning, placement, the brief | Planning |
| S3 implementation | Implementation |
| S4–S5 test, corrections, the merge request | Test and Corrections |
| S6 deployment scripts, the port, the revert path | Deployment Scripts |
| S7–S9 deploy, verify, revert | Deploy and Reversal |
Each page carries what happens there, what runs it, and the rules real changes forced onto it. This page keeps only what is common to all nine stages, documented on five pages (S1–S2, S3, S4–S5, S6, S7–S9).
Deployment, testing, and revert are the definition of done — a change missing any of the three keeps the case open (goals DG-5).
P The rules the eight real changes forced are on the stage pages they belong to — each stage's Rules this stage carries section — rather than in one list here.
2. The agents
The module's agent tree, its branch of the memory tree and its skills are at the head of this page (§ 0); every profile in full is Components — Development § 3.
2b. What this module asks of the others, and what they ask of it
P Two mechanisms, defined once in Agents § 5: a consult returns knowledge and uses a read; a handover (Hd) returns a changed system and uses a gate. Both handover directions here carry the one handover packet (D142 — request, response, completion; draft contract in Contracts § 2).
What Development asks:
| It asks | Of | When | What it does with the answer |
|---|---|---|---|
| "What has gone wrong in this seam, this service, this product before?" | Support — support/experience + the symptom domain |
S1 planning, before the brief | it sizes the blast radius, which is the half of the brief a person actually argues about |
| "Is this behaviour a catalogue row rather than a code path?" | Configuration — the owning stage domain | S1, at placement | yes ends the case here: Hd to Configuration, and no code is written for something a configuration cell owns |
| "What state is this product in, on this environment?" | Configuration — configuration/ipal |
S1 and S8 verification | tells a defect apart from a half-deployed product |
| "Configure this instead" | Configuration — Hd | after placement | the sub-case does the work; its verified outcome returns to the owning case before closure |
What is asked of Development:
| Asked | By | What answers it |
|---|---|---|
| "Does a deployed process fit this product's shape?" | Configuration, at S3 | source/serdica-backend — and no turns the consult into an Hd for the process itself (D86) |
| "Will this render, and to which roles?" | Configuration, at S5 | source/serdica-ui |
| "What has gone wrong in this service before?" | Data and information, at S2 investigation (D144) | the repository's own domain |
| "Build or fix this" | Support and Configuration — Hd | source.root accepts and opens a sub-case, or rejects with a reason |
P Placement is where configuration, the customer seam and the core proposition meet. The placement decision asks, in order: is this configuration (Hd to Configuration), is it a customer-specific seam, or is it core (a proposition that leaves the platform). Two of the three answers are not development work at all — which is why the consult to Configuration happens before the brief and not after the code.
3. Sample case
The claims-search feature of 29.06.2026 replayed (Development Module § 5 C1; backend ce4279c73f + UI c1a9cbe9b, ~1,700 lines in a day — F: evidence). S1: the change lives on the bulstrad-qa branch set (new layout: src/PolicyAdministrationSystem/Claims/… + serdica-ui apps/ipal/…), not on staging; placement is mixed — the search endpoint is core Claims (seam 4, a proposition), the Bulstrad-specific IBAN/card columns are the Bulstrad claims plug-in (seam 1); the brief names both and the interim duplication. S2: brief approved with the two-repository contract paper (DTO + route) and the deploy order UI-after-backend. S3: fix with failing test first in two worktrees. S4: dotnet build + tests, nx build, pipeline green as evidence. S5: reviewer checklist (test placement, i18n set, csproj bumps, appsettings hunks) → MR → human accepts. S6: QA deploy set; no master counterpart yet for the core part is recorded and becomes the proposition; revert commits prepared. S7–S8: H4 + the write auditor on QA, the deployment agent resolves and triggers the estate’s pipeline job (D130; Ablera DevOps keeps the rights and the compose units), runtime verification (D114). Close: experience entry + a source/serdica-backend/claims node created by the summarizer for both layouts.
4. Evaluation
Golden corpus: merged changes (requirement in → merged commit + test evidence as reference), seeded from the UAT Health file's dual-estimated rows F: [CEO evidence]; graded on placement, diff shape, and test coverage; re-runs when source/* domains or model routes change.
5. Real material — eight live changes
P Reading status. These are architecture test cases and historical gap records. Current execution and closure follow Runtime and Deploy and Reversal; an old quoted “closes against the issue” statement does not discharge a requested customer delivery.
F Re-read against the customer line on 07.09.2026 (Development module — typical cases): C2, C4, C5 and C6 are typical shapes of the 300 backend and 134 UI commits on bulstrad-staging since 06.2025; C8 is typical in delivery and rare in content; C1 and C7 are architecture tests (C1 is not on the customer line at all); C3 is configuration. The eight miss the seven most frequent real shapes — product processes, print rules, the reinsurance stream, product premium rules, partner registration, party data, agents and commissions — which the typical-cases page carries as DV-01 … DV-07, with the census and the challenges the real changes raise against this page.
Method: each case is a change that actually happened (or is actually open) in the Bulstrad estate, replayed through the v2 Development stages S1–S9 as written in the Development Module page (file 10 Architecture/30 Source/Source Module.md), Stage Planning, and the platform pages they lean on. Repository facts were read with git over origin/<branch> refs in serdica-backend and serdica-ui on 02.09.2026, never by checkout. DB facts come from the linked memories, not fresh queries. Every "breaks" item quotes the page and section it contradicts; every gap ends in a proposal with a target page.
Two estate facts recur in nearly every case and are stated once here:
- Two source layouts (Software Architecture § 9.0).
bulstrad-staging/bulstrad-prodare flatsrc/<Area>/<Svc>/with shared libraries consumed as NuGet packages built fromsrc/Common/CommonCustomLibraries/;master/bulstrad-qaaresrc/Serdica/…,src/PolicyAdministrationSystem/…,src/__Libraries/with project references and CI generated byCiJobsBuilder. Whole services exist on one line only (Claims: QA line only; PasNotes: customer line only). - The estate's own fix rule.
.claude/rules/code-changes.mdis on all four origin refs of both repositories (master,bulstrad-qa,bulstrad-staging,bulstrad-prod— re-checked withgit ls-treeon 07.09.2026; the 04.09 check that reported it absent usedgit cat-file -e ref:path, which mis-reports under MSYS path conversion; the staging blob differs from master's and was last touched 14.04.2026), andserdica_backend_branch_per_env.md§ Fix-branching matrix records the same rule:fix/SD-XXXbranched frombulstrad-staging→ MR tobulstrad-staging→ deploy + verify → cherry-pick tobulstrad-prod→ deploy + verify → cherry-pick tomasterlast, mandatory, adapted if diverged, with one exception ("the issue literally doesn't exist on master"). The estate keeps the word cherry-pick for that between-branch step; the module's term for the layout-crossing procedure is port, defined in Stage Deployment Scripts (D105). The rule is written, not practised: none of the 15 merges intobulstrad-stagingsince 06.2025 is a merge-request merge, and the estate holds two SD-named branches (typical cases § 0) — the S5 merge request of Stage Test and Corrections is a practice the module introduces. bulstrad-testis the staging branch's former name — renamed 22.10.2025 in both repositories; the backendbulstrad-testis an ancestor ofbulstrad-staging(tip 28.10.2025), the UI one diverges on 29.10.2025 with two orphan commits. Merge lines that name it are the same branch.
C1 — The claims-search feature (backend ce4279c73f + UI c1a9cbe9b, 29.06.2026)
The case. UAT Health row #30: search claims by IBAN / member card / email. One author, one day, both commits landed directly on bulstrad-qa. Backend: 20 files, +1,408/−8, all under src/PolicyAdministrationSystem/Claims/ — a generic pluggable framework in the service core (Claims.Abstractions/Contracts/IClaimSearchFilter.cs, App/Services/Search/ClaimSearchService.cs, App/Endpoints/Search/SearchClaimsEndpoint.cs, Contracts/Processing/ClaimSearchDtos.cs) plus one customer/health-specific filter in a plugin (__Plugins/Claims.Plugin.Health/Services/Search/MemberCardSearchFilter.cs), seven plugin .csproj bumps, and 777 lines of tests — all of them placed in test/Claims.Plugin.Health.Tests, including the tests of the core service. UI: 15 files, +276/−83 — claims.component.ts, a new claim-search.adapter.ts, three service files, and i18n keys in four languages (ar/bg/en/es) in two file sets each. The Claims microservice has zero files on bulstrad-staging and bulstrad-prod (only 2023 Routes_For_INSIS-Claims migrations); the UI on those branches has a claims-list component reading claims from elsewhere. No DB change.
v2 walk-through.
- S1 planning — planner + placement analyst. Reproduction: none possible; this is an extension, so "the evidence that stands in for it" (Stage Planning § PL-4) is the UAT row. Branch set: the default start
bulstrad-staging(Development Module § 1, decision 31.08.2026) is wrong for this case — the Claims service does not exist there; the planner must detect this bygit ls-tree(branch memory rule) and re-target tobulstrad-qafor both repos, DB: none. Placement by the four criteria: who else has it — IBAN/email search is standard for every claims customer → the framework is seam 4; the member-card filter is health-customer only → seam 1. Under Stage Planning § PL-1 P choosing seam 4 "produces a core-change proposition … addressed to the estate development lead (D108)"; the Development case records the handover and closes against the GitLab issue id. The plugin half depends on the framework half. The rule splits a one-day feature into a proposition that leaves the module and a plugin that waits on it. Experience-index lookup ("seen before?") againstsupport/experience: nothing — new capability. - S2 approval (H2) — the brief: seam(s), blast radius (Claims service = every QA-line deployment: Bulstrad QA and Ablera DEV), branch set, test plan (
dotnet build src/PolicyAdministrationSystem/Claims/App/Claims.csproj,dotnet teston the Health tests,nx build/nx test serdica-ui, UI run on QA), deploy + revert path. Answered by an Operator. - S3 implementation —
source.rootspawnssource.implementer.<source>for each source in the branch set — heresource.implementer.serdica-backend(worktreeserdica-backend@bulstrad-qa) andsource.implementer.serdica-ui(worktreeserdica-ui@bulstrad-qa).source/serdica-backend/claimsdoes not exist → summarizer (Agents § 0.6) reads the Claims tree, its plugins,AGENTS.md, recent history, and creates the node; audited memory write. Cross-repo contract:ClaimSearchDtos↔claim-search.adapter.ts— the contract paper travels from S1 (Stage Planning § Rules) and binds both implementers (Stage Implementation § Rules), so the DTO is agreed before either side builds and the deploy order is read off it. - S4 test — test runner (mechanical):
dotnet buildauthoritative (LSP rule), ~6 min cold for the claims plugin;nxbuild/test; no eval set (no agent behaviour changes). Ledger: build state per repo. - S5 corrections (H3) — reviewer (isolated), working the checklist Stage Test and Corrections § Rules carries: test placement, the i18n set across the maintained languages, plugin
.csprojbumps, appsettings hunks. Without it a reviewer passes tests-in-the-wrong-project, which is exactly what this case produced. - S6 deployment scripts (H4) — the stage prepares the target set named in the brief. There is no prod target: the change ships to QA. Port to
master: master is a strict subset ofbulstrad-qa(measured 18.08.2026), sogit merge --no-ff+ the appsettings restore + proof gates from the branch memory. Revert path: revert commits + redeploy. - S7–S8 deploy — QA is a shared non-customer environment: H4 plus the write auditor govern the deploy; STAGING/TEST and PROD are customer-facing and use H4 + H5 (D114). Deploy mechanics: CI build/push on push to
bulstrad-qa(image tagbulstrad-qa), then the Ansible job inserdica-infrastructure— resolved by the per-environment rule and triggered by the deployment agent after the gate; Ablera DevOps keeps the rights and the compose units (D130, Software Architecture § 10). Runtime verification: the image tag serving, a stack line, the endpoint answering. P The job is found by rule, not by a person (D130): a deployment agent with per-environment rules locates the last build job ofserdica-infrastructure, then in its deployment phase the job that includes the service (named in the.ymlfiles);bulstrad-stagingandbulstrad-prodderive from thev3.0.0branch with their own compose files,masterand every other environment frommaster. The environment path itself is per product line (D123). - S9 — revert commits, H7.
Where the architecture breaks or is silent.
- The sample case is this branch set. § 3 records the QA branch set, the core Claims endpoint and the Bulstrad plug-in split, which is what this case actually was.
- Stage Planning § PL-1 carries the mixed-seam rule. A feature that is a core framework plus a customer plugin is the normal shape of a plugin architecture; the proposition rule routes the core part out of the module and the case "closes against it" while the plugin part cannot ship.
- S6 deploys the target set named in the brief, not a fixed "bulstrad-prod set" (Stage Deployment Scripts § Rules; DG-2 makes the start environment configurable).
- A non-production deploy is gated too (Gating § 1; Stage Deploy and Reversal § Rules): QA deploys are H4 + the write auditor; STAGING/TEST deploys are H4 + H5 (D114).
- No cross-repo contract step. DG-3 defines the branch set across repos; nothing defines how two implementers agree a DTO or in which order the two repos deploy (backend before UI).
- No review criteria for the isolated reviewer (test placement, i18n completeness across the four maintained languages, plugin
.csprojbumps). - The MR is in the flow. S5 ends in a merge request reviewed under the estate's own development process (Stage Test and Corrections § Rules, DG-7), its pipeline result is S4 evidence, and § 0.2 / Components — Development § 5 carry the gitlab operations that open and merge it.
Gaps → proposals. G1 rewrite Development Module § 3 with the real branch set and the real mixed placement (Development Module). G2 add a mixed-seam rule to Stage Planning § PL-1: the customer part ships in the customer lineage now; the core part becomes a proposition and an interim copy in the customer seam where the plugin needs it, with the duplication recorded as debt (Stage Planning). G3 replace "the bulstrad-prod set" with "the target set named in the brief" (Stage Deployment Scripts). G4 is closed by QA = H4 + write auditor and STAGING/TEST/PROD = H4 + H5 (D114). G5 add an inter-repo contract paper (DTO/route) to the case papers and a deploy order to S6 (Stage Planning; Stage Implementation). G6 write the reviewer's checklist (Stage Test and Corrections § Rules). G7 put the MR in the flow: S5 ends with an MR to the environment branch; its CI pipeline result is S4 evidence; the merger is the deployer under H4 (Stage Test and Corrections § Rules).
C2 — SD-1863: PROD SRD_INTEGR.POLQRY stub raising ORA-06503
The case. The print gate OBJECT_CREDITED( (backend commits 0561840d4f, 52de8b3721 on staging; f7c6fba83a on prod 24.08.2026) calls POLQRY.gINSIS_CREDITED_OBJ_IDS. On PROD the package spec had been promoted and the body recompiled from it, leaving the function as BEGIN NULL; END; — STATUS='VALID', raising ORA-06503 on every call, surfacing through the caller's fail-safe as "no data" (memory). TEST returned 3213616087,3213616088 for the same argument. Signature comparison — spec 19756319, body lines 1..87 255288638, equal on both — proved a whole-body CREATE OR REPLACE PACKAGE BODY from staging would be surgical. POLQRY is not in git (workflow memory); the PL/SQL developer edits packages directly on QA and commits nothing (Stage Planning § 3b). The related incident: a spec change to ABC_PREM_OBJ on 15.05.2026 broke every ABACUS-priced product for 23 minutes because INSIS.ABC_ACCESS.* callers over @abacus do not revalidate (memory).
v2 walk-through.
- S1 — planner: reproduction is the live call on the PROD connection (grant
PROD / IPAL / read), not an inference from TEST. Branch set: DB side = PRODSRD_INTEGR.POLQRYbody; code side =bulstrad-prod(the evaluator, already deployed). Placement: seam 3 by criterion 3 ("logic that needs the row it operates on"). Stage Planning § PL-1 defines seam 3 as "everySRD_INTEGRpackage",UEXIT_*among them — wide enough forPOLQRY. Caller sweep (all_source LIKE '%POLQRY%', the SD-1732 rule) is a plan step. Cross-DB check: body-only change → no remote invalidation; the check is still run and recorded. - S2 (H2) — brief: seam 3, blast radius = one environment × every
POLQRYcaller, ordering constraint stated with both wrong orders named (KI-050 memory), test plan, revert = the pre-apply snapshot. - S3 —
source.implementer.plsql; oracle connector extracts the whole body from staging on its own connection (ALL_SOURCE), never a routine; spec + body in one script set (prohibition table, Stage Planning § 3b). Snapshot capture at case open for PROD and staging into the target schemaSRD_SUPPORT(not yet created — verified 03.09.2026; D30/D47) and the agent-owned git mirror. - S4 — "PL/SQL: source-signature proof and one real call; the apply is S8" (Stage Test and Corrections § 1). The environment under test is staging, which already has the body; the source call proves the candidate and S8 repeats it on the target.
- S5 (H3) — reviewer compares proposed vs baseline (
sql/refvssql/proposeddiscipline). - S6 (H4) — script =
CREATE OR REPLACE PACKAGE BODY+ verification tail (status,ALL_ERRORS, signature vs source env, a real call returning a value); revert = re-apply the pre-apply PROD snapshot. Simulation default (Failure and Recovery § 5): the five-condition exemption fails (not a single row) → simulate. On which venue? Staging is the source. QA has the developer's in-flight body — applying the staging body there is exactly the overwrite the signature precondition exists to refuse. - S7 (H5, Approver PROD) — grant bound to the statement hash and the PROD body signature as precondition (Trust and Data § 2). Write shape A (F&R § 1): apply + verify + real call in one connector call. But
CREATE OR REPLACEis DDL: it commits implicitly and cannot be rolled back — the effect class is compensable (re-apply the snapshot), never transactional; F&R § 1's two shapes are written for DML. - S8 — runtime verification: the real call on PROD; then the print action on the external surface (a real policy document) — post-commit, compensation planned.
- S9 (H7) — re-apply the snapshot.
Where the architecture breaks or is silent.
- Seam 3 is the environment's DB-resident PL/SQL, not only
UEXIT_*(Stage Planning § PL-1): the 95 packages includePOLQRY,TR_*,INS_*,ABC_PREM*— the fix set of every PL/SQL ticket in the memory. - The write identity for seam 3 is the executor's (D104). The write executor applies DDL under
HW-ddlwith the identity of the current D65 stage; one-time creation of the target schemaSRD_SUPPORT(not yet created — verified 03.09.2026; D30/D47) remains the narrowed D47 exception. - DDL is its own effect class (Stage Planning § 3b; Failure and Recovery § 2, D60): auto-committed, not rolled back, its undo the re-apply of the pre-apply snapshot — which is why no DDL runs without that snapshot in the case.
- S4 has no meaning for promotion cases. Where the fix is "copy the staging body to PROD", there is nothing to build or unit-test; the test is the post-apply call, which S4 places before S6.
- The cross-DB dependency check names no tool. The
@insis/@abacusremote dependents cannot be enumerated from IPAL; they needALL_DEPENDENCIESon the INSIS side (PROD / INSIS / read, andSELECTon the view through the connector’s role) — not in the brief's grant set for an IPAL case. - Snapshot store and the promotion direction. Stage Planning § 3b snapshots "the staging and production packages … over connections to those databases"; the developer's in-flight work is on QA. Promotion is staging → PROD, so the QA snapshot (the developer's) is never the base for a PROD apply — the design should say so, and say that a QA→staging promotion of the developer's body is a different case type with the developer as author.
Gaps → proposals. G8 redefine seam 3 as "the environment's DB-resident PL/SQL — the SRD_INTEGR/SRD_IPROD/SRD_CUST packages, UEXIT_* among them" (Stage Planning § PL-1). G9 add effect class DDL / auto-committed with "undo = compensating re-apply of the pre-apply snapshot" (F&R § 2; Agent Runtime § 5). G10 decide the seam-3 apply identity per environment and add a unified-audit policy on CREATE/ALTER PACKAGE for it (Software Architecture § 10; Stage Planning § 3b already raises the policy). G11 make S4 for seam-3 promotions = "signature proof + real call on the source env", and S8 = the same call on the target (Stage Test and Corrections). G12 add the INSIS-side dependency query and the PROD / INSIS / read grant to every seam-3 plan that touches a spec (Stage Planning § 3b table).
C3 — A serdica-ui fix: the formly dependency machinery (field-generator.ts)
The case. Stage IPAL § PF-8: a DEPENDENT_ON_FACTOR value without | makes the onInit dependency machinery return early, the list is never filtered and falls through to the full store list — and 137 live rows on the Ablera DEV database (PROD 102 · TEST 103 · QA 126 on 03.09.2026) are in that state, so it is the estate's normal configuration, not a defect backlog. The code: on master libs/serdica-utils/src/lib/serdica-utils/formly/field-generator.ts:471 (const [mainFactor, dependOnKey] = factor.dependentOnFactor.split('|'), 610 lines); on bulstrad-staging/bulstrad-prod the same logic lives at a different path — libs/serdica-shared/src/lib/formly/field-generator.ts:475 (640 lines). KI-054 recorded the file as "absent on bulstrad-prod"; it is present under the older path — the memory is wrong about absence and right about drift. A comparable real staging UI fix for scale: 6a76d8df1 fix(SD-2005): extend cargo framework visibility — one file, +4/−3, 06.08.2026.
v2 walk-through.
- S1 — reproduction on the staging UI against the staging backend (the operator's dropdown shows the full list). Placement first question: is it code at all? 137 rows say the fix could be configuration (add the pipe) → Hd to Configuration, or code (tolerate a pipe-less value, or fail loud), or both. The wiki's Solution Take covers this choice for Support; the Development module has no "is this really Development?" step. Branch set:
serdica-ui@bulstrad-staging, no backend, no DB. Seam: the formly generator is core UI (every customer) → seam 4 → proposition → leaves the module. A two-line fix. - S2 (H2) — brief. Blast radius: every product's wizard on the environment.
- S3 —
source.implementer.ui; worktree;source/serdica-uinode exists (seeded from field-validation memory). The node's knowledge is master-shaped (serdica-utilspath); the staging tree usesserdica-shared. The implementer must discover the path per branch. - S4 —
nx build,nx test: the estate's UI CI has no test stage (stagesbuild,e2e,deploy; e2e iswhen: manual,allow_failure: true, Protractor). 158 spec files on staging, 199 on master (03.09.2026) — run only by whoever runs them. "UI runs" (Development Module § 1) means serving the staging-branch build against the staging backend from the QA host: reach10.239.82.112(Software Architecture § 10, unverified), authenticate as an operator, drive a browser. Browser evidence from a customer-facing environment is handle-substituted at the browser connector before it reaches a model or a paper (D116). - S5–S6 — reviewer; the UI image is built per branch by CI on push (
build-jobs.ymlfires only forbulstrad-qa|staging|prod|dev|bulstrad2); runtime environment comes from/rest-api/environment-settings.json, so the UI build is environment-neutral — the UI has no appsettings trap, which the wiki never says. Port to master: different path, 30-line size difference →git applywith path rewrite or manual port;merge-treefeasibility test first. - S7–S9 — as C1; staging is a customer-facing environment, so the deploy is H4 + H5 (D114).
Where the architecture breaks or is silent.
- S1 asks "configuration, code, or both?" before anything else (Stage Planning § Rules): a symptom the catalogue can fix is Hd to Configuration, a mixed one is decomposed one sub-case per placement row — so a Development case opened in place cannot quietly fix a configuration problem in code.
- The UI evidence surface is personal data. Development "inherits the Support boundary wherever a reproduction touches real data" (Agents § 0.3); browser evidence from customer-facing environments is handle-substituted at the connector before it reaches a model or paper (D116).
source/serdica-uiis seeded from master-shaped knowledge (§ 0.1) while the default start environment isbulstrad-staging, whose library layout differs.- The estate's UI pipeline runs no unit tests; the wiki's "nx build/test" gate is the platform's own and must be run by the test runner, not read from CI.
Gaps → proposals. G13 add a placement pre-question to S1: configuration, code, or both — with Hd to Configuration when the data is the fix (Stage Planning § PL-2). G14 declare the browser connector's evidence class: screenshots are customer-identifying, stored as artefacts under the Support boundary, never inlined into a prompt; prefer DOM text through the handle substitution (Trust and Data § 4; Architecture § 1 tools row). G15 seed source/serdica-ui with a per-branch path map (shared vs utils) and the CI facts (no test stage; env-neutral build) (§ 0.1).
C4 — One fix on bulstrad-staging, ported to master: the two-layout problem
The case. 39c4f21b32 (27.08.2026, staging): "Add policy flat rate endpoint and consolidate the PasPolicy Bulstrad plugin" — 38 files. Paths on staging: src/BusinessInsurance/PasPolicy/…; the same service on master: src/PolicyAdministrationSystem/PasPolicy/…. The commit also touches .gitlab-ci/configs/services/pas-policy.yml (hand-written on staging; on master the equivalent is generated, .gitlab-ci/autogenerated/microservices/pas-policy.yml), PasPolicy.Dockerfile, PasPolicy.sln (75 lines), appsettings.json (3 lines), a new __Plugins/PasPolicy.Plugin.Bulstrad.Dockerfile, and deletes PasPolicy.Plugin.Registration.Bulstrad/Standard — a staging-only consolidation (AGENTS.md@bulstrad-staging:5 says PasPolicy on this branch defaults to Registration.Bulstrad). Second instance: SD-1863's 0561840d4f — staging path src/BusinessInsurance/Integrations/BstPrintDocuments/App/Services/PrintDocuments/PrintPolicyDocuments.cs, master path src/PolicyAdministrationSystem/__Integrations/BstIntegration/App/Services/BstPrintDocuments/PrintDocuments/PrintPolicyDocuments.cs, plus an appsettings.json bundled in the feature commit (the cherry-pick variant in the branch memory).
v2 walk-through.
- S1–S5 — as a normal staging case; placement seam 2 (
BusinessInsurance/PasPolicyis a customer service on staging — on master it sits underPolicyAdministrationSystem, i.e. the same service is customer-seam on one lineage and PAS-core on the other; the seam table in Stage Planning § PL-1 is a master-layout table, and its amendments say so). - S6 port — Development Module § 1: "the port to master (fix commits only, base commit named; appsettings never carried across)".
git cherry-pick 39c4f21b32onto master fails on every path. The real procedure: build the patch restricted to functional files, rewrite paths (git apply --directoryor a per-service path map), drop.sln/Dockerfile/CI hunks (layout-specific), regenerate the CI file withCiJobsBuilder(whose invocation has no README — CH-57), never carryappsettings.json, and decide what the plugin consolidation means on a lineage that may not have the Registration plugins.git merge-tree --write-tree --merge-base=…answers "conflicts?" without a checkout — it is the feasibility gate; Stage Deployment Scripts names it now. Order of operations: the port MR opens after the runtime check unless the brief records why it goes first (D105). - S7–S8 — the staging deploy of a plugin change: on this branch "plugin-enabled services are shipped as one image with plugin binaries baked in at build time" (
AGENTS.md@bulstrad-staging:4) — a seam-1/2 change redeploys the whole service image; the seam's blast-radius column ("one customer") is right, its deploy unit is not smaller than core's.
Where the architecture breaks or is silent.
- Stage Planning § PL-1's seam table is master-layout, and says so.
BusinessInsurance/Bst*and__Pluginsare the master/QA paths; on the default start environment the paths, the plugin packaging, and even which area a service belongs to differ. - § 0.1 builds the microservice index from
git ls-tree origin/master— the wrong lineage for a module whose default start isbulstrad-staging. Thesource/serdica-backend/<service>node needs two trees per service and a path map between them. - The layout-crossing procedure is a port, not a cherry-pick — both terms are defined once in Stage Deployment Scripts § Rules (D105), and this page defers to that definition.
- The port MR opens after runtime verification unless the brief says otherwise (Stage Deployment Scripts § Rules; Stage Deploy and Reversal § Rules, D141).
- Layout-specific files (
.sln, Dockerfile, hand-written vs generated CI, plugin Dockerfiles) have no rule at all.
Gaps → proposals. G16 the summarizer creates source/serdica-backend/<service> with both trees, a path map, the plugin packaging per lineage and the CI file kind (Agents § 0 for the summarizer; § 0.1 for the node). G17 replace "cherry-pick" with a port procedure: functional-paths patch → merge-tree feasibility → path rewrite → layout files excluded → CI regenerated → appsettings proof gates → "adapted" recorded in the commit when it was (Development Module § 1; Development Details DG-2). G18 move the master port after prod verification, or make the order a brief decision (Stage Deployment Scripts). G19 add a per-lineage seam table, or state that Stage Planning § PL-1 names master paths and the source/serdica-backend node holds the path map (Stage Planning § PL-1).
C5 — A per-branch appsettings.json change
The case. 64 appsettings.json files on bulstrad-staging; the appsettings-only staging→prod diff touches 44 of them (+541/−688), while the whole diff is 379 files (+2,847/−15,761). Two facts the wiki does not carry: (1) the committed src/Core/Core/appsettings.json on bulstrad-prod points ApiGateway, Redis, RabbitMQ and Camunda at serdicatest.bulstrad.bg — the decommissioned old TEST hostname; (2) the committed PasNotes appsettings.json on bulstrad-prod carries a connection string to 10.239.82.106 — the QA database — with a schema user. Neither is what PROD runs, so the branch's appsettings is not a description of the environment: the running values are injected at deploy time. On the old layout there are zero AddEnvironmentVariables("SERDICA_…") hits in source, yet AGENTS.md@bulstrad-staging:7 says Bulstrad deployments inject SERDICA_Serilog__… "through shared infra vars" — the binding lives in a NuGet package the agent cannot read on that branch. The same file also holds functional config: Core's RabbitMQRoutingConfig.RouteConfigs (command → exchange/queue), where pas_policy.register_policy exists on staging and not on prod (CH-25), and PasNotes' MaxPageSize: 100 (staging only — the KI-044 cap). Real commits: d7f8c72210 (staging, 19.08) edits PasNotes appsettings.json alongside library code; 0561840d4f bundles staging RabbitMQ/Redis/Oracle/BI Publisher addresses into a print fix.
v2 walk-through.
- S1 — a config-only or config-plus-code case. Branch set: the file per branch — staging and prod each get their own commit; master gets a third, or none. Placement: not a seam question; the seam table has no row for configuration-in-repo.
- S3 — implementer edits the staging worktree's file. The file contains the environment's real password (branch memory:
bulstrad-*carry the real DB password). Trust and Data § 4: secrets "never to any model" — but an implementer that opensappsettings.jsonin a worktree sends it. Agent Runtime pattern 20 scrubs environment variables, not files. - S6 — "appsettings never carried across" (Stage Deployment Scripts § Rules) is right and insufficient: the change must be re-authored per branch and it must survive the deploy-time override — if Ansible templates the whole file, a committed change is dead on arrival; if it overlays variables, a committed change wins unless a variable names the same key. Which is true is in
serdica-infrastructure, which the agent cannot see (Software Architecture § 10, CH-58/CH-63). - S8 — runtime verification of a config change means reading the effective configuration in the container (
docker exec … env, or the service's startup log line). Thessh/ host connector carries it — read-only commands on an allow-list, a privileged command as a gated write (Components — Development § 5, seeded fromssh-mcp); Kibana startup logs are the fallback.
Where the architecture breaks or is silent.
- Committed appsettings ≠ running config on the customer branches. Stage Planning § Rules makes configuration items part of the branch set and requires the override status per key; what is still missing is the old-layout half — Software Architecture § 10 describes the new-layout
SERDICA_*mechanism as if it were universal. - Functional config and environment addresses share one file; the "never carried across" rule blocks legitimate functional config from travelling and nothing says how it travels instead.
- Secrets in worktrees. The trust boundary is enforced at connectors and env vars; a repo file with a live password is neither.
- The host connector carries runtime verification and the "immediate relief" actions of C7 (Components — Development § 5); what is still open is the SSH identity it uses per host.
- The override mechanism is invisible on the old layout (NuGet) and lives in a repository the platform does not have (
serdica-infrastructure).
Gaps → proposals. G20 add a config item class to S1's branch set: per-branch file, deploy-time override checked, functional vs environmental keys separated; record for each key whether Ansible/compose overrides it (Stage Planning § Rules; Software Architecture § 10). G21 worktree secret scrubbing — a pre-read filter on *appsettings*.json, *.env, connection strings; the implementer sees redacted values and edits by key (Trust and Data § 4; Agent Runtime § 2 rule 3). G22 add a host connector (SSH to the compose hosts, read-only exec + restart as a gated write) to the connector list; seed from ssh-mcp (Architecture § 1; Software Architecture § 10). G23 add read access to serdica-infrastructure (a GitLab project token) as a Development-module prerequisite (Software Architecture § 10).
C6 — A Camunda process for a new product (Hd: Configuration → Development)
The case. Product 3606 on staging, 06.07.2026: c37e140c76 "Product 3606 Creation Staging" is exactly two files — …/Policy/…/Products/GuestsAtTouristSites…PolicyIssue3606Single.bpmn (51 lines) and its …3606SingleUserTasks.cs (64 lines) under src/Core/Plugins/Core.Plugin.Bulstrad/; the UI commit 147767697 adds one i18n key in three languages. The shape is the generator's: per line-of-business Generate<Line>Products.sh scripts stamp <Key><Code>.bpmn + <Key><Code>UserTasks.cs from a template (17 liability products in one script). Deployment mechanics (WorkflowClient.LoadProcesses, staging src/Core/Core/WorkflowEngine/WorkflowClient.cs): at Core start-up every *.bpmn under WorkflowEngine/Processes, the plugin Processes/, and EnvSpecific/{SERDICA_PROJECT_ENV} is uploaded to Camunda via REST Deployments.Create(duplicateFiltering: true); a higher folder overrides a lower one by file name. 168 BPMN files on staging, 185 on master. On master, Camunda obsoletion decision.md (11.02.2026, "Proposed") plans the move to Elsa Workflows; Camunda 7 CE is end-of-life. The Configuration module's S5 Serdica says: "the process itself is Development-module work (Hd), its registration is configuration" (Stage Serdica).
v2 walk-through.
- Hd — the Configuration root recruits the Development root as a sub-case after human confirmation; the handover carries the product code, the process it should resemble, the operations. The receiving case's S1: branch set =
serdica-backend@bulstrad-staging(Core.Plugin.Bulstrad), UI i18n, no DB. Placement: seam 1 (customer plugin) — correct by the table. Blast radius by deploy unit: the plugin is baked into the Core image; a BPMN change redeploys Core, the workflow client of every product on the environment. - S3 — the Camunda developer profile is
source.camunda_developer(Components § 3); it writes process files and a migration statement forsource/serdica-backend/core. Running the generator script is the implementation; hand-editing 51 lines of BPMN XML is the alternative. - S4 — how is a BPMN tested? By starting a process instance on the environment's Camunda: that creates process instances, user tasks, and a policy, none of them transactional (F&R § 2). Teardown = terminate the instance + remove the policy rows; the write log must include Camunda REST calls. Simulation venue: staging is the customer's TEST environment; QA has its own Core and Camunda — the natural venue, but the plugin must first be deployed there, which is a Core redeploy on QA.
- S6 — deploy = Core redeploy through the
serdica-infrastructureAnsible job, triggered by the deployment agent after the gate (D130; Ablera DevOps keeps the rights and the compose units). Revert is not "remove the process": Camunda versions definitions; redeploying the previous file creates a new version, in-flight instances stay on the version they started on, andduplicateFilteringskips an unchanged file — so a revert must state what happens to running instances (migrate, let finish, cancel). Port to master: master is heading to Elsa; the brief chooses port, port-as-Elsa, or no counterpart (D105). - S7–S9 — staging is customer-facing, so deploy is H4 + H5; reversal per above (D114).
Where the architecture breaks or is silent.
- Camunda deployment and versioning are a case type now (Stage Deploy and Reversal § Rules): a process change carries effect classes, a migration statement per version and its teardown, and the camunda developer holds the gated start/terminate/migrate (Components — Development § 3). What no page yet states is the mechanics this case measured — that BPMN rides the Core image, that deployment happens at start-up, that
EnvSpecific/overrides by name — which belongs in thesource/serdica-backend/corenode (G24). - The camunda developer is a profile with its Camunda REST read, its gated start/terminate/migrate and its denied deploy action (Components — Development § 3).
- Non-Goals N-4 keeps Camunda as "a configuration target (process registration for products)" — but the process file is code in a plugin and its deployment is a service redeploy; the Configuration/Development boundary is drawn through one artefact.
- A process change is a case type with an effect inventory — effect classes and in-flight-instance handling (Stage Deploy and Reversal § Rules).
- The Elsa decision on master is a lineage fact the port rule must know.
Gaps → proposals. G24 a source/serdica-backend/core node section on the Camunda mechanics (start-up upload, name override, versioning, revert semantics, instance migration), created by the summarizer on the first case (§ 0.1). G25 define the camunda developer profile: writes to source/serdica-backend/core, tools = worktree + the generator scripts + a Camunda REST connector (read: definitions, instances; gated write: start, terminate, migrate) (Components — Development § 3; Architecture § 1). G26 a process-change case type with effect classes for start/terminate and a revert statement about in-flight instances (Development Module § 1; F&R § 2). G27 record the Elsa decision as a lineage fact and let the brief choose "port to master" / "port as Elsa" / "no master counterpart" (Stage Planning § PL-3; Stage Deployment Scripts).
C7 — A Known Issue that is code: KI-044 (pas_notes_getlist unbounded reply → RabbitMQ 406)
The case. KNOWN_ISSUES KI-044: one scopeless pas_notes_getlist with filters:[] and pageSize:-1 selected all 1,152,205 SR_USER_NOTES rows, a ≈292 MiB reply exceeded the broker's 128 MiB max_message_size, RabbitMQ closed the channel, and /pas-notes — whose RabbitClient holds one channel created in its constructor and publishes without an IsOpen check — replayed the close-reason for hours; the gateway answered HTTP 200 with an empty list, operators saw "Бележки 0". Immediate relief: restart /pas-notes. The fix set spans six owners: (a) SrUserNotesGetListOperation.AllSelector base scope + pageSize cap + reject scopeless — PasNotes; (b) channel recovery on 406 + reply-size check — the RabbitMQSerdica library (src/Common/CommonCustomLibraries/RabbitMQSerdica/ on staging); (c) serdica-ui never sends filters:[]; (d) ApiGateway returns a real error on TaskStore timeout; (e) broker max_message_size; (f) Bulstrad archiving of SR_USER_NOTES. Lineage fact: SrUserNotesGetListOperation.cs exists on bulstrad-prod and bulstrad-staging only; on master/bulstrad-qa PasNotes is ten generated doc/*.md files and no code. The generic half of (a) already shipped: d7f8c72210 "Clamp the no limit requests" (staging, 19.08) in CrudBaseServices (see C8).
v2 walk-through.
- Intake — a KI is not a ticket; the case opens from the admin UI or as a Support Hd sub-case. S1 must decompose into sub-cases by placement: (a) seam 2 (customer service); (b) and (d) seam 4 (shared library, platform gateway) → propositions → leave the module; (c) UI core → proposition; (e) infrastructure — no seam, no module; (f) customer — Support communication. The restart is an operations action with no home: not a DB write, not code; no host connector (C5).
- S2 (H2) — the brief for (a) alone; blast radius = every notes reader on the environment; ordering: (a) is safe to ship alone; (b) needs the library release (NuGet on the old layout → every consumer rebuilt).
- S3–S4 — implementer on
PasNotes@bulstrad-staging; unit test for the scope rule; an integration test for channel recovery needs a broker — the QA broker on10.239.82.105is the platform's own message bus (Software Architecture § 10); a test that closes channels with 300 MB messages on it has a blast radius on the platform itself. Reproducing the failure on staging would kill the notes function for Bulstrad's testers — staging is the customer's TEST environment, not a sandbox. F&R § 5 lists "dev, staging or QA" as interchangeable venues. - S6 — prod set for (a): PasNotes image; config
MaxPageSizeper branch (C5). Port to master: no counterpart — the service does not exist there.code-changes.mdhas the exception; Development Module § 1 S6 records the "no master counterpart" outcome, so DG-5 is satisfied without a master target. - S7–S8 — H5; runtime verification = a scopeless request now refused (log line), and the Kibana signature (
is larger than configured max size) absent for 24 h. - Data boundary:
SR_USER_NOTEScarries operator names and approval details (KI-045) → personal data → EU-resident route; the 1.15M-row reproduction result is an artefact, never a prompt (Agent Runtime § 6).
Where the architecture breaks or is silent.
- A multi-placement case is decomposed: S1 emits a placement matrix and opens one sub-case per row, with an ordering statement (Stage Planning § Rules).
- "No master counterpart" is an allowed S6 outcome, recorded with its reason (Stage Deployment Scripts § Rules).
- Simulation venues are not equal: staging is customer-facing; the QA broker is the platform's own. Failure and Recovery § 5 carries the venue ranking (G30), so the brief names the venue and its co-tenants.
- Operations actions (restart a container, change a broker limit) have no module, no connector, no gate — yet they are the first line of KI-044 and KI-016.
- Library changes on the old layout are NuGet releases (
.gitlab-ci/configs/libraries/*.yml): a seam-4 fix there is a package version bump in every consumer's.csprojand a rebuild of every consuming service — a deploy set the wiki's "artifacts + DB scripts + config" does not describe.
Gaps → proposals. G28 S1 emits a placement matrix (component → seam → module/owner) and opens one sub-case per row, with an ordering statement (Stage Planning § Rules; Agent Runtime § 11). G29 add "no master counterpart — recorded, with the reason" as a legitimate S6 outcome (Development Module § 1; Development Details DG-2). G30 rank simulation venues: platform-shared resources and customer-facing environments need a blast-radius statement in the plan; prefer an isolated compose unit for broker/message tests (F&R § 5). G31 an operations action kind — restart, scale, broker setting — through the host and RabbitMQ connectors under H5-equivalent gating (Stage Deploy and Reversal § Rules; Architecture § 1). G32 describe the NuGet release path for old-layout libraries in S6 (Stage Deployment Scripts; source/serdica-backend node).
C8 — A genuinely standard change and how it leaves the module: "Clamp the no limit requests"
The case. d7f8c72210 (staging, 19.08.2026) adds PagingHelper.cs (+57), a MaxPageSize setting in MainServiceConfig, a clamp in GetListCrudOperation and BaseMainService, and bumps the Ablera.Serdica.CrudBaseServices package version — in src/Common/CommonCustomLibraries/ (NuGet on the old layout) — plus the PasNotes appsettings.json value. Eleven days later a44b7e21c8 (bulstrad-qa, 30.08) is the same five code files re-applied by hand under src/PolicyAdministrationSystem/__Libraries/Ablera.Serdica.CrudBaseServices/ (project reference on the new layout), no appsettings; master received it by merge on 31.08. The UI counterpart 8b7860a1c "Fix big unclamped loads of configurations data" (staging, 30.08) touches 17 components and adds a spec. This is the textbook seam-4 case: every customer benefits from clamping pageSize:-1; it was also urgent for Bulstrad (KI-044, S2, no workaround).
v2 walk-through.
- S1 — placement: criterion 1 → every customer → seam 4 → Stage Planning § PL-1 P: "a core-change proposition is addressed to the estate development lead … the Development case records the GitLab issue id and closes against it" (D108). Under the dual-path rule, customer urgency can ship the customer-lineage fix now while the master port is the proposition.
- S2 (H2) — what the human should see: "core change; ship in the customer lineage now under the customer's urgency; the master port is the proposition, with the two-layout adaptation recorded". The brief contract (Contracts § 2,
brief.schema.json) requiresconfiguration_or_code,split(ships_now/proposition/interim_duplication),port_planand the predicted minutes — so the dual path is a field, and urgency rides thesplitdecision (Stage Planning § PL-4). - S3–S5 — implementer on the library; on the old layout the library is a NuGet: the fix is not deployed until the package is published by its CI job (
crud-base-services.yml) and every consuming service bumps and rebuilds — the version bump in the commit is that mechanism; the PasNotes appsettings change is the first consumer's opt-in. Tests: the library's own; the reviewer must check the default whenMaxPageSizeis absent (a clamp that defaults to unlimited fixes nothing). - S6 — prod set = the package + each rebuilt consumer image + the per-branch config (C5). Master port = re-implementation at a different path (C4) — done by hand in reality.
- S7–S9 — H5 for PROD; runtime verification = a
pageSize:-1request logs the clamp.
Where the architecture breaks or is silent.
- The proposition rule is bounded by urgency. Stage Planning § PL-1 routes seam 4 out of the module, and the dual-path amendment lets the customer-lineage fix ship now while the master port is the proposition; a Sev-2 production defect whose fix is standard code cannot wait for "the estate's own development process". The estate did the opposite and it was right.
- "Development" is a destination with an address (Stage Planning § PL-1, D108): the estate development lead receives a GitLab issue on
master, and issue-state changes return as ledger events. - Library = release on the old layout. Seam 4's blast-radius column says "every customer, every upgrade"; on
bulstrad-stagingit also means "every consuming service image on this environment", a concrete deploy set the S6 text ("artifacts + DB scripts + config") does not enumerate. - The eval corpus for Development (Agent Framework § 6.5: "merged changes: requirement in, merged commit + test evidence as reference — graded on placement, diff shape, test coverage") would grade this pair as two placements for one requirement; the corpus needs a lineage dimension or it penalises the correct dual path.
Gaps → proposals. G33 a dual-path rule for seam 4 under customer urgency: fix in the customer lineage as seam 4 on that lineage, and the master port is the proposition, opened as an MR to master with the adaptation recorded; the case closes when both exist or the master side is formally declined (Stage Planning § PL-1). G34 define the proposition artefact and destination: a GitLab issue or MR on master with the brief attached, its id in the ledger, and a return signal (Stage Planning § PL-1; Architecture § 1 GitLab connector). G35 enumerate the old-layout library deploy set (package publish → consumer bumps → images) in S6 and in the source/serdica-backend node (Stage Deployment Scripts; § 0.1). G36 add a lineage dimension to the Development eval corpus so a staging fix and its master re-implementation grade as one requirement (Agent Framework § 6.5; § 4 above).
Gap table
| # | Gap | Evidence | Target page | Proposal | Status |
|---|---|---|---|---|---|
| G1 | Sample case names a branch set and placement that cannot exist | C1 | Development Module § 3 (this page) | rewrite with the real QA branch set and the real core+plugin split | closed — § 3 |
| G2 | No mixed-seam rule; the proposition rule splits one feature | C1 | Stage Planning § PL-1 | customer part ships now; core part = proposition + recorded interim duplication | closed — Stage Planning § PL-1 |
| G3 | S6 hard-codes "the bulstrad-prod set" | C1 | — | "the target set named in the brief" | closed — Stage Deployment Scripts § 4 |
| G4 | No gate for non-production deploys (QA/staging) | C1, C3, C6 | — | add H4b or scope H4 to a named environment | closed — Stage Deploy and Reversal § 4; QA = H4 + auditor, STAGING/TEST = H4 + H5 (D114) |
| G5 | No inter-repo contract check or deploy order | C1 | — | contract paper (DTO/route) + deploy order in S6 | closed — Stage Planning § Rules; Stage Implementation § Rules |
| G6 | Reviewer has no criteria | C1 | Stage Test and Corrections § Rules; Agent Framework § 6.5 for the scoring | reviewer checklist: test placement, i18n set, csproj bumps, appsettings hunks | residual: checklist exists in Stage Test and Corrections; eval scoring remains external |
| G7 | GitLab MR, CI result and merger absent from the flow | C1, all | — | S5 ends in an MR; pipeline result is S4 evidence; deployer merges under H4 | closed — Stage Test and Corrections § Rules |
| G8 | Seam 3 defined as UEXIT_* only |
C2 | Stage Planning § PL-1 | seam 3 = the environment's DB-resident PL/SQL | closed — Stage Planning § PL-1 |
| G9 | DDL has no effect class / write shape | C2 | — | class "DDL, auto-committed; undo = re-apply pre-apply snapshot" | closed — Stage Planning § 3b and Failure and Recovery § 2 (D60) |
| G10 | Seam-3 apply identity on PROD undecided and unaudited | C2 | Software Architecture § 10; Stage Planning § 3b | name the account per env; unified-audit policy on it | residual: D104 names executor/stage identity; audit policy remains owner work |
| G11 | S4 vacuous for promotion cases | C2 | — | S4 = signature proof + real call on source env; S8 = same call on target | closed — Stage Test and Corrections § Rules |
| G12 | Cross-DB dependency check names no tool or grant | C2 | Stage Planning § 3b | INSIS-side ALL_DEPENDENCIES + PROD / INSIS / read in the plan |
closed — Stage Planning § 3b |
| G13 | No "configuration, code, or both?" pre-question | C3 | — | placement pre-question with Hd to Configuration | closed — Stage Planning § Rules |
| G14 | Browser evidence (screenshots) bypasses the handle boundary | C3 | — | screenshots = customer-identifying artefacts; prefer DOM text through handles | closed — Trust and Data § 4 (D116) |
| G15 | source/serdica-ui seeded master-shaped; UI CI facts missing |
C3 | § 0.1 (this page); Agents Memory Part I | per-branch path map; "no test stage, env-neutral build" facts | residual: belongs to Agents Memory; not assigned |
| G16 | Microservice index built from master only | C4 | § 0.1 (this page); Agents § 0 for the summarizer | summarizer builds both trees + path map + packaging per lineage | residual: belongs to Agents Memory; not assigned |
| G17 | "Cherry-pick" is wrong across layouts | C4 | — | port procedure with merge-tree feasibility, path rewrite, layout files excluded, CI regenerated |
closed — Stage Deployment Scripts § Rules |
| G18 | Port order contradicts the estate fix rule | C4 | — | master port after prod verification, or a brief decision | closed — Stage Deployment Scripts § Rules; Stage Deploy and Reversal § Rules |
| G19 | Seam table is master-layout | C4 | Stage Planning § PL-1 | per-lineage seam paths, or an explicit statement + node reference | closed — Stage Planning § PL-1 |
| G20 | Committed appsettings ≠ running config; functional and env keys share a file | C5 | — | config-item class in the branch set; per-key override check | closed — Stage Planning § Rules |
| G21 | Secrets in worktree files reach the model | C5 | — | pre-read scrubbing of appsettings/.env/connection strings | closed — Stage Implementation § Rules (D116) |
| G22 | No host/SSH connector for runtime verification or restarts | C5, C7 | — | host connector seeded from ssh-mcp; restart as gated write |
closed — Components § 5 and Stage Deploy and Reversal § Rules |
| G23 | serdica-infrastructure invisible to the platform |
C5, C6 | Software Architecture § 10 | read token on the repo as a Development prerequisite | residual: the token is an estate grant, not a wiki decision |
| G24 | Camunda deployment/versioning/revert semantics absent | C6 | Agents Memory Part I (source/serdica-backend/core) |
node section on start-up upload, name override, versions, migration | residual: mechanics described in case; memory node outside this edit set |
| G25 | Camunda developer sub-agent has no profile/node/tools | C6 | — | profile + Camunda REST connector (read; gated start/terminate/migrate) | closed — Components § 3 |
| G26 | Process test/teardown has no effect inventory in Development | C6 | — | process-change case type with effect classes and in-flight-instance statement | closed — Stage Deploy and Reversal § Rules |
| G27 | Elsa decision on master unknown to the port rule | C6 | — | lineage fact; brief chooses port / port-as-Elsa / no counterpart | closed — Stage Deployment Scripts § Rules |
| G28 | No decomposition of a multi-placement case | C7 | — | placement matrix → one sub-case per row + ordering | closed — Stage Planning § Rules |
| G29 | "No master counterpart" not an allowed S6 outcome | C7 | — | record the outcome with reason; DG-5 satisfied | closed — Stage Deployment Scripts § Rules |
| G30 | Simulation venues treated as equal | C7 | Failure and Recovery § 5 | rank venues by co-tenants; staging is customer-facing; isolated compose for broker tests | closed — Failure and Recovery § 5 ranks venues; D114 for the customer-facing half |
| G31 | Operations actions have no module/connector/gate | C7 | — | "operations action" kind through host/RabbitMQ connectors under gate | closed — Stage Deploy and Reversal § Rules |
| G32 | Old-layout library fix = NuGet release + consumer rebuilds, undescribed | C7, C8 | source/serdica-backend node (§ 0.1) |
enumerate the deploy set | closed — Stage Deployment Scripts § Rules |
| G33 | Proposition rule vs customer urgency | C8 | Stage Planning § PL-1 | dual path: fix in customer lineage now; master port is the proposition | closed — Stage Planning § PL-1 |
| G34 | "Development" undefined as a destination | C8 | Stage Planning § PL-1 | proposition = GitLab issue/MR on master with brief; id in ledger; return signal | closed — Stage Planning § PL-1 (D108) |
| G35 | Blast radius of seam 4 on the old layout under-described | C8 | Stage Planning § PL-1 | add "every consuming service image on this environment" | closed — Stage Planning § PL-1; Stage Deployment Scripts § Rules |
| G36 | Development eval corpus has no lineage dimension | C8 | Agent Framework § 6.5; § 4 (this page) | grade a lineage pair as one requirement | residual: the corpus is built with the first cases |
Coverage: 8 cases · 4 repositories/surfaces (serdica-backend both layouts, serdica-ui both layouts, DB-resident PL/SQL, Camunda) · all four seams exercised (1: C1/C6, 2: C4/C7, 3: C2, 4: C1/C3/C8) · all nine stages and gates H2, H3, H4, H5, H7 and Hd walked · 36 gaps, of which 7 are contradictions with facts in the estate or the wiki itself (G1, G3, G8, G17, G18, G19, G20) and 29 are silences. Not covered: intentgpt (repository absent — CH-05/CH-30 stand), a DB-model (dbml/migration) change, and any case starting from the mailbox or HDesk channels.