@aifabrix/builder 2.59.0 → 2.61.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/README.md +14 -11
  2. package/docs/README.md +80 -0
  3. package/docs/builder-help/evidence-patterns.json +155 -0
  4. package/docs/builder-help/golden-examples/crm-company.json +30 -0
  5. package/docs/builder-help/golden-examples/crm-deal.json +29 -0
  6. package/docs/builder-help/golden-examples/document-storage-keyed-get.json +85 -0
  7. package/docs/builder-help/golden-examples/document-storage.json +30 -0
  8. package/docs/builder-help/golden-examples/meeting-transcript.json +29 -0
  9. package/docs/builder-help/golden-examples/repository-template.json +29 -0
  10. package/docs/builder-help/golden-examples/service-ticket.json +29 -0
  11. package/docs/builder-help/platform-roles.json +98 -0
  12. package/docs/builder-help/resource-type-catalog.json +402 -0
  13. package/lib/agent-kit/git-identity.js +180 -0
  14. package/lib/agent-kit/setup.js +3 -0
  15. package/lib/agent-kit/start.js +45 -1
  16. package/lib/api/configuration.api.js +131 -0
  17. package/lib/api/role-assistant-test-job.api.js +60 -0
  18. package/lib/api/system-secrets.api.js +72 -0
  19. package/lib/api/work-search.api.js +13 -6
  20. package/lib/app/deploy.js +8 -1
  21. package/lib/app/run-docker-fallback.js +6 -1
  22. package/lib/app/run-helpers.js +2 -1
  23. package/lib/app/run-parameter-sync.js +142 -0
  24. package/lib/app/show-display.js +1 -0
  25. package/lib/app/show-online.js +15 -0
  26. package/lib/build/docker-build-args.js +5 -2
  27. package/lib/build/index.js +3 -2
  28. package/lib/build/standard-docker-build.js +6 -3
  29. package/lib/cli/setup-app.js +19 -1
  30. package/lib/cli/setup-environment.js +156 -0
  31. package/lib/cli/setup-utility.js +24 -1
  32. package/lib/commands/datasource-capability-upsert-cli.js +112 -0
  33. package/lib/commands/datasource-capability.js +4 -2
  34. package/lib/commands/env-secret-context.js +113 -0
  35. package/lib/commands/env-secret-list.js +200 -0
  36. package/lib/commands/env-secret-push-confirm.js +54 -0
  37. package/lib/commands/env-secret-push-run.js +227 -0
  38. package/lib/commands/env-secret-push.js +168 -0
  39. package/lib/commands/repair-datasource-apply.js +2 -0
  40. package/lib/commands/repair-datasource-keyed-document.js +122 -0
  41. package/lib/commands/repair-datasource-run.js +1 -0
  42. package/lib/commands/role-assistant.js +7 -0
  43. package/lib/commands/setup-modes.js +1 -8
  44. package/lib/commands/setup-prompts.js +2 -180
  45. package/lib/commands/verify-operations-skip-e2e.js +25 -1
  46. package/lib/commands/verify-operations-steps.js +13 -1
  47. package/lib/commands/wizard-config-normalizer.js +7 -4
  48. package/lib/commands/wizard-core.js +5 -157
  49. package/lib/commands/wizard-file-saving.js +163 -0
  50. package/lib/core/env-platform-expand.js +97 -0
  51. package/lib/core/secrets-env-content.js +42 -4
  52. package/lib/core/secrets-env-write.js +10 -3
  53. package/lib/core/secrets-load.js +4 -2
  54. package/lib/datasource/binary-documents-validator.js +190 -0
  55. package/lib/datasource/capability/run-capability-upsert.js +202 -0
  56. package/lib/datasource/capability/upsert-ingredients.js +291 -0
  57. package/lib/datasource/capability/upsert-operations.js +138 -0
  58. package/lib/datasource/capability/upsert-test-scaffold.js +189 -0
  59. package/lib/datasource/validate.js +12 -5
  60. package/lib/deployment/installation/azure-infra-stage.js +3 -1
  61. package/lib/deployment/installation/infra-catalog.js +2 -5
  62. package/lib/generator/builders.js +17 -0
  63. package/lib/generator/helpers.js +23 -2
  64. package/lib/generator/index.js +13 -6
  65. package/lib/lifecycle/product-model.js +4 -3
  66. package/lib/lifecycle/report-display.js +3 -2
  67. package/lib/parameters/infra-parameter-catalog.js +1 -1
  68. package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +1 -1
  69. package/lib/programmatic/builder-help-governance.js +1 -1
  70. package/lib/programmatic/builder-help.js +1 -1
  71. package/lib/role-assistant/test-cases-search.js +3 -0
  72. package/lib/role-assistant/test-job-runner.js +125 -0
  73. package/lib/role-assistant/test-runner-search.js +44 -2
  74. package/lib/role-assistant/test-runner-workhub-answers.js +4 -1
  75. package/lib/role-assistant/test-runner-workhub-missing-fields.js +42 -0
  76. package/lib/role-assistant/test-runner-workhub-wait-stop.js +94 -0
  77. package/lib/role-assistant/test-runner-workhub.js +28 -19
  78. package/lib/schema/application-schema.json +205 -2
  79. package/lib/schema/external-datasource.schema.json +23 -3
  80. package/lib/schema/infra-parameter.schema.json +139 -33
  81. package/lib/schema/infra.parameter.yaml +416 -66
  82. package/lib/schema/infrastructure-schema.json +10 -35
  83. package/lib/utils/compose-generate-docker-compose.js +16 -9
  84. package/lib/utils/datasource-binary-evidence.js +92 -0
  85. package/lib/utils/datasource-test-run-capability-scope.js +44 -1
  86. package/lib/utils/datasource-test-run-debug-display.js +2 -0
  87. package/lib/utils/datasource-test-run-display.js +8 -2
  88. package/lib/utils/datasource-test-run-issue-guidance.js +176 -0
  89. package/lib/utils/datasource-test-run-tty-log.js +2 -0
  90. package/lib/utils/docker-build.js +29 -8
  91. package/lib/utils/docker-manifest-public-port.js +36 -0
  92. package/lib/utils/env-copy.js +11 -10
  93. package/lib/utils/external-system-system-test-tty.js +3 -2
  94. package/lib/utils/image-tags.js +2 -2
  95. package/lib/utils/platform-kv-ref.js +1 -1
  96. package/lib/utils/platform-resolution.js +226 -0
  97. package/lib/utils/prepare-local-data-mount.js +58 -0
  98. package/lib/utils/resolve-docker-image-ref.js +8 -3
  99. package/lib/utils/secrets-helpers.js +0 -1
  100. package/lib/utils/system-secret-mapping.js +125 -0
  101. package/lib/utils/test-log-writer.js +2 -1
  102. package/lib/validation/external-manifest-validator.js +5 -0
  103. package/lib/validation/openapi-contract-surface-validator.js +3 -1
  104. package/lib/validation/validate-external-file.js +5 -1
  105. package/package.json +5 -4
  106. package/templates/README.md +2 -1
  107. package/templates/agent-kit/agent-kit.yaml +4 -1
  108. package/templates/agent-kit/instructions/AGENTKIT.md +1 -1
  109. package/templates/agent-kit/instructions/root.AGENTS.md +2 -0
  110. package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +35 -2
  111. package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +15 -0
  112. package/templates/agent-kit/skills/aifabrix-connected-system/scripts/delivery-verdict.js +176 -0
  113. package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +6 -2
  114. package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +28 -2
  115. package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +22 -0
  116. package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +28 -1
  117. package/templates/agent-kit/skills/aifabrix-role-assistant/references/testing-playbook.md +117 -0
  118. package/templates/agent-kit/skills/shared/feedback.md +31 -0
  119. package/templates/agent-kit/skills/shared/hosts.md +13 -3
  120. package/templates/agent-kit/skills/shared/interaction.md +83 -0
  121. package/templates/agent-kit/skills/shared/status.md +76 -0
  122. package/templates/agent-kit/workspace/BUILDER_IMPROVEMENT_FINDINGS.md +27 -0
  123. package/templates/applications/builder-api/application.yaml +1 -1
  124. package/templates/applications/builder-api/env.template +5 -1
  125. package/templates/applications/dataplane/application.yaml +30 -2
  126. package/templates/applications/dataplane/env.template +36 -5
  127. package/templates/applications/keycloak/application.yaml +6 -1
  128. package/templates/applications/miso-controller/application.yaml +96 -1
  129. package/templates/applications/miso-controller/env.template +63 -37
  130. package/templates/applications/miso-controller/rbac.yaml +17 -0
  131. package/templates/external-system/external-datasource.yaml.hbs +7 -1
  132. package/templates/marketplace/main.json +73 -225
  133. package/templates/python/Dockerfile.hbs +2 -0
  134. package/templates/python/docker-compose.hbs +1 -1
  135. package/templates/typescript/Dockerfile.hbs +2 -0
  136. package/templates/typescript/docker-compose.hbs +12 -0
  137. package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +0 -34
  138. /package/{lib/programmatic/help-content → docs/builder-help/content}/channel-onboarding.md +0 -0
  139. /package/{lib/programmatic/help-content → docs/builder-help/content}/cip-overview.md +0 -0
  140. /package/{lib/programmatic/help-content → docs/builder-help/content}/connected-system-ui.md +0 -0
  141. /package/{lib/programmatic/help-content → docs/builder-help/content}/dimensions-guide.md +0 -0
  142. /package/{lib/programmatic/help-content → docs/builder-help/content}/enterprise-sync-fabrix.md +0 -0
  143. /package/{lib/programmatic/help-content → docs/builder-help/content}/overview.md +0 -0
  144. /package/{lib/programmatic/help-content → docs/builder-help/content}/subscription-guide.md +0 -0
  145. /package/{lib/programmatic/help-content → docs/builder-help/content}/workflow.md +0 -0
@@ -0,0 +1,31 @@
1
+ # Feedback — where an observation goes
2
+
3
+ `aifabrix agent-kit update` rewrites `.agents/skills/**`, `AGENTKIT.md`, and the
4
+ managed sections of `AGENTS.md` and `CLAUDE.md` from the installed kit. Editing
5
+ them blocks the next update as a conflict, and `--force` discards the edit with
6
+ no diff to review. Improve the kit by filing a finding, not by editing a skill.
7
+
8
+ | Observation | Where it goes |
9
+ | --- | --- |
10
+ | Generic CLI, skill, or platform gap | `BUILDER_IMPROVEMENT_FINDINGS.md` |
11
+ | Manual EDS edit | `integration/<systemKey>/INTEGRATION_CHANGELOG.md` |
12
+ | Vendor limits, tenant ids, PII stance | `integration/<systemKey>/README.md` |
13
+ | Delivery learning for a role | `role-assistant/ra-<roleKey>/learning/learning.md` |
14
+
15
+ ## Writing a finding
16
+
17
+ Newest first, under a `## YYYY-MM-DD — one line naming the gap` heading:
18
+
19
+ - **Command** — the exact command, customer values replaced by placeholders.
20
+ - **Observed** — what happened, with the error text and the verdict.
21
+ - **Expected** — what should have happened, and why that is reasonable.
22
+ - **Scope** — whether it reproduces outside this workspace, and what is still
23
+ unproven. Say so plainly when the root cause is not established.
24
+
25
+ A finding is read outside this workspace, so leave out correlation ids, audit
26
+ refs, internal URLs, tenant or record identifiers, hostnames, and customer
27
+ names. Customer specifics belong in the package README or the role's
28
+ `learning.md` instead.
29
+
30
+ Never weaken a gate, assertion, or test to make a finding go away. A failing
31
+ gate with a filed finding is a better outcome than a green run that hides one.
@@ -18,7 +18,17 @@ permission settings; the standalone start defaults below remain separate.
18
18
  - Claude Code: `.claude/settings.local.json` (`permissions.defaultMode` = `bypassPermissions`, `allow` = `Bash(aifabrix *)` and `Read(~/**)`)
19
19
  - Codex: `.codex/config.toml` (`approval_policy = "never"`, `sandbox_mode = "workspace-write"`)
20
20
 
21
- Those files stay in **this workspace**. Claude may **read** files under the developer home (`Read(~/**)`) and run the delivery CLI (`Bash(aifabrix *)`). They do not add sibling folders as extra workspaces, do not grant Write outside this repo, and do not allow every shell command. `agent-kit start claude|codex` writes only the selected host's file by default; `--skip-approve-all` opts out. Install/update retain their explicit approval prompts and flags. `--force` overwrites existing local files. Builder never writes `~/.claude` or `~/.codex`.
21
+ Those files stay in **this workspace**; Builder never writes `~/.claude` or `~/.codex`, and neither file adds a sibling folder as an extra workspace.
22
+
23
+ Understand what you are accepting for Claude Code. `bypassPermissions` stops the
24
+ prompt for **every** tool call in this workspace, not only the two `allow`
25
+ entries, which grant nothing extra while that mode is set. That includes
26
+ `aifabrix` subcommands which change remote state, such as `deploy`, `upload`,
27
+ `identity sync` and `protection upload`. Codex is narrower: `approval_policy`
28
+ removes the prompt, while `sandbox_mode = "workspace-write"` still confines
29
+ writes to this workspace.
30
+
31
+ Use `--skip-approve-all` when you want the prompts, on a shared or production-connected installation. `agent-kit start claude|codex` writes only the selected host's file by default. Install/update retain their explicit approval prompts and flags. `--force` overwrites existing local files.
22
32
 
23
33
  ## Cursor
24
34
 
@@ -38,7 +48,7 @@ available from the same Claude account when supported.
38
48
  aifabrix agent-kit start claude
39
49
  ```
40
50
 
41
- tmux session name is this folder (for example `aifabrix-docs`). Remote Control name is `hostname-user-folder` (for example `builder01-dev03-aifabrix-docs`). `--name` overrides the folder; `--no-remote-control` and `--skip-approve-all` opt out. Several workspaces can run at once. Detach without killing Claude: `Ctrl-b` then `d`. Reattach: `tmux attach -t aifabrix-docs`. A duplicate `start` fails instead of attaching. Then `/aifabrix-plan` (or another `/aifabrix-*` skill). First run in a project asks you to trust the folder; accept only this workspace.
51
+ tmux session name is this folder (for example `acme-workspace`). Remote Control name is `hostname-user-folder` (for example `devhost-alice-acme-workspace`). `--name` overrides the folder; `--no-remote-control` and `--skip-approve-all` opt out. Several workspaces can run at once. Detach without killing Claude: `Ctrl-b` then `d`. Reattach: `tmux attach -t acme-workspace`. A duplicate `start` fails instead of attaching. Then `/aifabrix-plan` (or another `/aifabrix-*` skill). First run in a project asks you to trust the folder; accept only this workspace.
42
52
 
43
53
  **Phone and PC.** Sign in with the same Claude Pro/Max/Team account (`claude auth login` — not an API key). After Remote Control starts, open **Code** in the Claude mobile app and/or [claude.ai/code](https://claude.ai/code) on the PC. In an already-running session, `/remote-control` or `/mobile`.
44
54
 
@@ -60,7 +70,7 @@ installer.
60
70
  aifabrix agent-kit start codex
61
71
  ```
62
72
 
63
- Default `--name` is the last folder. `--no-remote-control` skips that daemon; `--skip-approve-all` leaves Codex permissions unchanged. If that session already exists, `start` fails with list/kill guidance. Detach: `Ctrl-b` then `d`. Reattach with `tmux attach -t aifabrix-docs`. Then `$aifabrix-plan` (and the other `$aifabrix-*` skills). Codex reads `AGENTS.md`. A separate Codex app server used by a desktop SSH chat appears in `agent-kit list` and the interactive `agent-kit kill` menu; stopping it requires confirmation and may disconnect the chat. `codex remote-control stop` only controls a standalone-managed daemon.
73
+ Default `--name` is the last folder. `--no-remote-control` skips that daemon; `--skip-approve-all` leaves Codex permissions unchanged. If that session already exists, `start` fails with list/kill guidance. Detach: `Ctrl-b` then `d`. Reattach with `tmux attach -t acme-workspace`. Then `$aifabrix-plan` (and the other `$aifabrix-*` skills). Codex reads `AGENTS.md`. A separate Codex app server used by a desktop SSH chat appears in `agent-kit list` and the interactive `agent-kit kill` menu; stopping it requires confirmation and may disconnect the chat. `codex remote-control stop` only controls a standalone-managed daemon.
64
74
 
65
75
  **Foreground only (no tmux).**
66
76
 
@@ -0,0 +1,83 @@
1
+ # Structured choices and phase gates
2
+
3
+ This file owns interactive choices for every Agent Kit skill. Use the same behavior in
4
+ Cursor, Claude, and Codex; host-specific tool names do not change the workflow.
5
+
6
+ ## Show choices in the host control
7
+
8
+ When the user must choose between discrete actions, invoke the host's native structured
9
+ question control instead of printing a `Choose:` block in chat:
10
+
11
+ | Host | Native control |
12
+ | --- | --- |
13
+ | Cursor | `AskQuestion` |
14
+ | Claude | `AskUserQuestion` |
15
+ | Codex | `request_user_input` |
16
+
17
+ Give the control a short header, one direct question, and mutually exclusive options.
18
+ Put the recommended option first, label it `(Recommended)`, and add one short description
19
+ of its effect. Keep the stable option ids below as the workflow result even when a host
20
+ returns a label rather than an id.
21
+
22
+ If the host supplies its own free-form **Other** choice, map that response to the matching
23
+ `*-other` id. Otherwise include an explicit **Something else** option. If no structured
24
+ question control is available, show the same choices as a numbered list and wait for one
25
+ answer. Never continue merely because an option was recommended.
26
+
27
+ Do not open a control when the user already made an unambiguous choice in the current
28
+ turn. Treat that choice exactly like the corresponding control result.
29
+
30
+ ## Bare-invocation routes
31
+
32
+ Ask once and proceed only on an explicit choice.
33
+
34
+ | Option id | Control label | Means |
35
+ | --- | --- | --- |
36
+ | `route-normal` | Run normal path (Recommended) | Run the normal path for this skill through to its gate, stopping at each phase gate |
37
+ | `route-check` | Inspect and test only | Run validation, checks, and status with no publish or promotion |
38
+ | `route-other` | Something else | Collect the action in the control's free-form response |
39
+ | `next-stop` | Stop here | End without further action |
40
+
41
+ `route-normal` still stops at every phase gate and still needs `next-yes` to continue. It
42
+ is a route, not permission to run the whole lifecycle unattended.
43
+
44
+ ## After success
45
+
46
+ Offer the next eligible phase with the structured question control. Proceed only on
47
+ `next-yes`.
48
+
49
+ Shared option ids: `next-yes` · `next-no` · `next-stop`.
50
+
51
+ | Completed | Next offer |
52
+ | --- | --- |
53
+ | aifabrix-plan PLAN_READY | connected-system validate |
54
+ | connected-system READY | connected-system build |
55
+ | connected-system BUILT | connected-system publish |
56
+ | connected-system PASS or PASS_WITH_SKIPS | archive (separate) and/or prove validate |
57
+ | prove READY / BUILT / UPDATED | prove next phase |
58
+ | prove PASS or PASS_WITH_SKIPS | iterate validate/build |
59
+
60
+ Archive is a distinct user decision (`archive-yes` / `archive-no`). Never archive as a
61
+ side effect of PASS.
62
+
63
+ ## On gaps
64
+
65
+ - NEEDS_DECISIONS: ask about every challenge row with the structured control. No
66
+ `cust-next`.
67
+ - BLOCKED / FAIL / NEEDS_FIXES / ABORTED: do not offer the next phase as if success.
68
+
69
+ A phase gate is per-gate, not overall. Offer the next phase only when the **Delivery** row
70
+ supports it; a passing package gate beside `Delivery: NEEDS_FIXES` is not success and the
71
+ offer must name what is still open.
72
+
73
+ ## Phase detection (connected-system and prove)
74
+
75
+ 1. Explicit phase from the user
76
+ 2. Ask with the structured control, offering the bare-invocation routes above
77
+
78
+ There is no third step. Package and plan state decide what you *recommend*, never what you
79
+ run: a bare invocation reports status and stops ([status.md](status.md)). Inferring "the
80
+ safe next eligible phase" is what makes a skill start working before the user has said
81
+ what they want.
82
+
83
+ Never silently run the following phase after success.
@@ -0,0 +1,76 @@
1
+ # Status first — what a bare invocation does
2
+
3
+ A skill named with no phase is a **question, not an instruction**. Report status, say what
4
+ you would do next, and wait. This is the default for every lifecycle skill.
5
+
6
+ ## Read-only means read-only
7
+
8
+ With no phase argument, you may read local packages, run `aifabrix auth status`, and run
9
+ read-only inspection such as `show --online` and `list`. You may **not**:
10
+
11
+ - upload, deploy, publish, or promote anything
12
+ - advance a plan task or mark one done
13
+ - create proof assets, Evidence, Knowledge, or tests
14
+ - run assistant cases or any command that mutates external state
15
+
16
+ Never infer a phase from "the safe next eligible one". Ambiguity is a reason to ask, not a
17
+ licence to start. Read-only inspection is still allowed when the user names a phase that
18
+ cannot run yet — report why instead of doing adjacent work.
19
+
20
+ ## Open by saying what you are about to do
21
+
22
+ Before the first command of any phase, state in one line what the phase will change and
23
+ what it will leave alone. A user who has not used this kit before cannot consent to work
24
+ they cannot see coming.
25
+
26
+ ## Offer the route, do not choose it
27
+
28
+ Use the host's native selection control and the canonical route options in
29
+ [interaction.md](interaction.md). Proceed only on an explicit choice. Do not print a
30
+ `Choose:` block when a structured question control is available.
31
+
32
+ ## Always report the combined matrix
33
+
34
+ Report every row, in this order, for any status, phase result, or completion claim. Use
35
+ `UNKNOWN` for anything not measured — never omit a row and never fill one by inference.
36
+ [delivery-verdict.js](../aifabrix-connected-system/scripts/delivery-verdict.js) computes
37
+ the verdict rows from what you observed.
38
+
39
+ | Row | Where the value comes from |
40
+ | --- | --- |
41
+ | Package | `aifabrix validate <key>` — `Validation passed!` / `Validation failed!` (`--format json` gives `valid`) |
42
+ | Online | `aifabrix show <key> --online` — `Draft` / `Published` / `Archived`; `--json` returns the raw lowercase status |
43
+ | AI Readiness | **no CLI surface** — record what the portal shows, or report `UNKNOWN` |
44
+ | Operations | `aifabrix verify-operations <key> --json` — `verdict`, `operationalReadinessPercent` |
45
+ | Trust | `aifabrix verify-trust <key> --json` — `verdict`, `aiTrustPercent` |
46
+ | Governance | `aifabrix verify-governance <key> --json` — `verdict`, `policyCoveragePercent` |
47
+ | Role Assistant | `aifabrix role-assistant test <roleKey> --json` — `verdict`, `certification`. **Availability is an operator action with no CLI surface**: confirm it explicitly or report `UNKNOWN` |
48
+ | Prove readiness | computed — READY or BLOCKED |
49
+ | Delivery | computed — overall verdict |
50
+
51
+ Pillar verdicts are `VERIFIED`, `FAILED`, `NOT_VERIFIED`, `NOT_APPLICABLE` — never `PASSED`.
52
+ `NOT_VERIFIED` is **not** a pass: it is where a pillar sits until it has been proved.
53
+ Certification is a separate axis (`BRONZE`…`PLATINUM`, `TECHNICALLY_READY`…), never a
54
+ substitute for a verdict.
55
+
56
+ `READY`, `BUILT`, `PASS`, `PASS_WITH_SKIPS`, `NEEDS_FIXES` and `BLOCKED` are this kit's
57
+ delivery vocabulary, not CLI output. Never quote them as if a command printed them.
58
+
59
+ ## Never headline a success the verdict does not support
60
+
61
+ When Delivery is `NEEDS_FIXES` or `BLOCKED`, do not open with a bare `READY`, `BUILT`,
62
+ `PASS`, or "all checks passed". Qualify every claim with its scope:
63
+
64
+ ```text
65
+ Package: BUILT · Online: Draft · Operations: FAILED 60% · Delivery: NEEDS_FIXES · Prove: BLOCKED
66
+ ```
67
+
68
+ A green package gate is a statement about files on disk. It says nothing about whether the
69
+ system is published, whether it behaves correctly, or whether the business case is proven.
70
+
71
+ ## A known failure stays open
72
+
73
+ A runtime, governance, persistence, or E2E failure remains active until **that same
74
+ concern** is rerun and passes. Later structural or integration success does not clear it,
75
+ and neither does a rerun of a different layer. Carry open failures into every subsequent
76
+ status report until they are genuinely resolved.
@@ -0,0 +1,27 @@
1
+ # Builder improvement findings
2
+
3
+ Generic gaps in the Builder CLI, the Agent Kit skills, or the platform. Created
4
+ once by `aifabrix agent-kit install` and owned by this workspace from then on;
5
+ update never rewrites it.
6
+
7
+ File a finding here instead of editing `.agents/skills/**`, which
8
+ `aifabrix agent-kit update` rewrites. Never weaken a gate, assertion, or test to
9
+ make a finding go away.
10
+
11
+ Keep customer specifics out: no correlation ids, audit refs, internal URLs,
12
+ tenant or record identifiers, hostnames, or customer names. A reader outside
13
+ this workspace should still be able to act on it. Anything customer-specific
14
+ belongs in `integration/<systemKey>/README.md` or the role's `learning.md`.
15
+
16
+ Newest first.
17
+
18
+ ## YYYY-MM-DD — One line naming the gap
19
+
20
+ Command: the exact command, with customer values replaced by placeholders.
21
+
22
+ Observed: what happened, including the error text and the verdict.
23
+
24
+ Expected: what should have happened, and why that is the reasonable behavior.
25
+
26
+ Scope: whether this reproduces outside this workspace, and what is still
27
+ unproven. Say so plainly when the root cause is not established.
@@ -5,7 +5,7 @@ app:
5
5
  description: 'Business Transformation services — HTTP orchestration for connected-system workspace lifecycle via Dataplane Enterprise MCP and governance APIs.'
6
6
  type: webapp
7
7
  language: typescript
8
- version: 2.59.0
8
+ version: 2.61.2
9
9
 
10
10
  # Image Configuration
11
11
  image:
@@ -23,11 +23,15 @@ MAX_UPLOAD_TIMEOUT_MS=300000
23
23
  # =============================================================================
24
24
  # url:// resolves after kv:// at resolve time (see docs/configuration/resolve-running-urls.md)
25
25
 
26
+ # Governed configuration uses per-application client credentials by default. The SDK loads
27
+ # its bootstrap snapshot and refreshes it automatically within two minutes; consumers decide
28
+ # whether a changed key also requires an internal client or resource to be recreated.
29
+ MISO_AUTH_MODE=client-credentials
26
30
  # Registered OAuth client (populated by aifabrix app register / bootstrap — same as dataplane)
27
31
  MISO_CLIENTID=kv://builder-api-client-idKeyVault
28
32
  MISO_CLIENTSECRET=kv://builder-api-client-secretKeyVault
29
33
 
30
- # Internal: controller API for token validation (supports all miso-controller auth modes)
34
+ # Private service-to-service controller origin. Public or remote controller origins require HTTPS.
31
35
  MISO_CONTROLLER_URL=url://miso-controller-internal
32
36
  # Public: OAuth profile and remaining-step links shown to vendors (not Docker DNS)
33
37
  MISO_CONTROLLER_PUBLIC_URL=url://miso-controller-public
@@ -5,7 +5,7 @@ app:
5
5
  description: "AI Fabrix Dataplane is a secure, in-tenant integration and automation layer that supplies governed, normalized, and explainable enterprise data to AI agents. Using CIP as a declarative standard, it enforces RBAC and ABAC, executes integrations, and exposes trusted data via MCP and OpenAPI."
6
6
  type: webapp
7
7
  language: python # Explicitly specify Python language
8
- version: 2.0.71
8
+ version: 2.0.79
9
9
  # Image Configuration
10
10
  # Set tag to match your build (example: aifabrix build dataplane -t 1.0.0).
11
11
  # Registry is required so the controller can pull the image (avoids docker-not-found on the controller host).
@@ -98,7 +98,35 @@ build:
98
98
  # (never product OPENAI_* / AZURE_OPENAI_*). ≥2 providers →
99
99
  # ENTERPRISE_LLM_DEFAULT_SELECTOR (portal/env deploy default); Environment
100
100
  # Settings ai.llmProvider overrides without redeploy.
101
- # - ENVIRONMENT → set by deployment target
101
+ # - ENVIRONMENT → resolved per environment below
102
+
103
+ # =============================================================================
104
+ # Environment Resolution
105
+ # =============================================================================
106
+ # One installation runs dev, tst and pro Dataplanes side by side
107
+ # (environmentScopedResources: true), so these values vary by environment, not by
108
+ # resource group. There is no `platforms:` section: nothing here depends on which
109
+ # stack the installation is. env.template consumes the names as {NAME}.
110
+ environments:
111
+ - environment: dev
112
+ configuration:
113
+ - name: ENVIRONMENT
114
+ value: 'dev'
115
+ - name: PIPELINE_ENV_KEY
116
+ value: 'dev'
117
+ - environment: tst
118
+ configuration:
119
+ - name: ENVIRONMENT
120
+ value: 'tst'
121
+ - name: PIPELINE_ENV_KEY
122
+ value: 'tst'
123
+ - environment: pro
124
+ configuration:
125
+ - name: ENVIRONMENT
126
+ value: 'pro'
127
+ # Empty keeps the existing behaviour: derive the key from MISO_CLIENTID.
128
+ - name: PIPELINE_ENV_KEY
129
+ value: ''
102
130
 
103
131
  configuration:
104
132
  # -------------------------------------------------------------------------
@@ -8,8 +8,8 @@
8
8
 
9
9
  # HTTP port for the app
10
10
  PORT=${PORT}
11
- # dev | tst | pro
12
- ENVIRONMENT=dev
11
+ # dev | tst | pro. Resolved from the deployment environment; local Docker is dev.
12
+ ENVIRONMENT={ENVIRONMENT}
13
13
  # Enable debug mode
14
14
  DEBUG=false
15
15
  # Logging level: DEBUG, INFO, WARNING, ERROR, CRITICAL
@@ -44,7 +44,7 @@ API_KEY_BYPASS_ROLES=full-access
44
44
 
45
45
  # API Configuration
46
46
  API_V1_STR=/api/v1
47
- VERSION=2.0.71
47
+ VERSION=2.0.79
48
48
  # Minimum supported aifabrix-builder CLI semver (advertised on /health and /api/v1/health; empty = no gate)
49
49
  # MIN_BUILDER_CLI_VERSION=2.45.0
50
50
  MIN_BUILDER_CLI_VERSION=2.45.5
@@ -98,6 +98,15 @@ DB_3_PASSWORD=kv://databases-dataplane-3-passwordKeyVault
98
98
  # so Docker dataplane + miso-controller do not exhaust max_connections alongside make dev.
99
99
  # SAME_SERVER_POOL_BUDGET=24
100
100
 
101
+ # Transaction lifetime guardrails (587.0). Loaders run remote/AI/file work outside
102
+ # transactions; these are leak guards and telemetry, not the normal control path.
103
+ # idle_in_transaction_session_timeout applied to every Dataplane engine (seconds, 0 = off).
104
+ DB_IDLE_IN_TRANSACTION_TIMEOUT_SECONDS=60
105
+ # Warn (sanitized: loader/phase/duration/counts/correlation only) when one transaction exceeds this.
106
+ DB_SLOW_TRANSACTION_WARN_SECONDS=5
107
+ # Upper bound of rows per Evidence bulk load request (atomic below the bound; larger fails before mutation).
108
+ EVIDENCE_LOAD_MAX_ITEMS=500
109
+
101
110
  # =============================================================================
102
111
  # REDIS CONFIGURATION
103
112
  # =============================================================================
@@ -128,6 +137,18 @@ ABAC_POLICY_PARSE_CACHE_MAX_ENTRIES=2048
128
137
  # AUTHENTICATION CONFIGURATION
129
138
  # =============================================================================
130
139
 
140
+ # MISO governed configuration runtime (583.0): client credentials are active by default.
141
+ # The SDK uses the per-application credentials below to load its bootstrap snapshot and
142
+ # refreshes it automatically within two minutes. Changed names invoke application refresh
143
+ # handlers; a handler may still recreate an internal resource such as a DB or Redis client.
144
+ # Override with MISO_AUTH_MODE=local only for an explicit .env/dotenv development flow.
145
+ # Invalidation (denial/expiry) stops new secret-dependent work and makes health unhealthy.
146
+ # Health: /health, /api/v1/health and /api/v1/health/platform return HTTP 503 with
147
+ # reasonCode misoTokenUnavailable | misoTokenRejected | misoControllerUnreachable |
148
+ # misoValidationTimeout whenever the Controller does not accept the live client
149
+ # token — in LOCAL_MODE too. These endpoints measure usable application health,
150
+ # not process liveness.
151
+ MISO_AUTH_MODE=client-credentials
131
152
  # MISO Application Client Credentials (per application)
132
153
  # Backend-only: never expose MISO_CLIENTSECRET to the Vite frontend (use VITE_* in app-ui).
133
154
  MISO_CLIENTID=kv://dataplane-client-idKeyVault
@@ -143,7 +164,8 @@ KEYCLOAK_REALM=aifabrix
143
164
  # =============================================================================
144
165
  # Public: browser redirects and CORS (includes /controller front-door path from miso-controller application.yaml).
145
166
  MISO_WEB_SERVER_URL=url://miso-controller-public
146
- # Internal: server-to-controller API calls (Docker: service:port; local: host:port — no front-door path).
167
+ # Private service-to-service controller origin. The SDK permits HTTP only for a local/private
168
+ # target; public or remote controller origins still require HTTPS.
147
169
  MISO_CONTROLLER_URL=url://miso-controller-internal
148
170
  # Browser logout page on miso-controller (path relative to MISO_WEB_SERVER_URL; not dataplane /login).
149
171
  MISO_LOGOUT_URL=/logout
@@ -151,7 +173,7 @@ MISO_LOGOUT_URL=/logout
151
173
  # Environment key sent to miso-controller (e.g. environmentKey on RBAC/register) when not supplied in the payload.
152
174
  # Set MISO_PIPELINE_ENV_KEY=dev when the controller installation uses dev (e.g. MISO_CLIENTID=miso-controller-dev-dataplane).
153
175
  # If unset, derived from MISO_CLIENTID (e.g. dev from miso-controller-dev-dataplane).
154
- MISO_PIPELINE_ENV_KEY=
176
+ MISO_PIPELINE_ENV_KEY={PIPELINE_ENV_KEY}
155
177
 
156
178
  # LLM: chat/embed route through governed enterprise-llm only. Provider credentials
157
179
  # live on LLM provider external systems + dataplane secret store (not product .env).
@@ -334,3 +356,12 @@ TRUST_AI_EXPOSURE_GATE_ENABLED=false
334
356
  # when 346.rules / §17 revisions must invalidate existing certificates without matching rulesVersion.
335
357
  CERTIFICATION_DATASOURCE_SCHEMA_VERSION=
336
358
  CERTIFICATION_RULES_VERSION=
359
+
360
+ # =============================================================================
361
+ # DIMENSION ABAC ENFORCEMENT (589.0)
362
+ # =============================================================================
363
+ # false (default): Stage 1 dimension ABAC scope services do not enforce
364
+ # external-system/source assignment scope, client-principal system binding or
365
+ # subscription owner scope (RBAC permissions still apply).
366
+ # true: enforce the Dimension ABAC certification rules (2026-09-21).
367
+ DIMENSION_ABAC_ENFORCEMENT_ENABLED=false
@@ -9,7 +9,12 @@ app:
9
9
  # Image Configuration
10
10
  image:
11
11
  name: aifabrix/keycloak
12
- tag: '26.7.3-aifabrix.1'
12
+ # `latest`, like every other app here. The Keycloak version lives in app.version above,
13
+ # which is what `aifabrix push --tag 'latest,{version}'` expands, so nothing is lost by
14
+ # not repeating it here. Pinning it made `aifabrix run` look for keycloak-dev1:<version>
15
+ # while `aifabrix build` only ever produces :latest, so dev-build-kc failed with
16
+ # "Docker image not found" on an image it had just built.
17
+ tag: latest
13
18
  registry: aifabrixacr.azurecr.io
14
19
  registryMode: external
15
20
 
@@ -4,7 +4,7 @@ app:
4
4
  displayName: 'Miso Controller'
5
5
  description: 'Miso is the AI Fabrix in-tenant controller and portal layer for securely operating enterprise AI apps inside a customer’s Azure tenant. It provides Entra ID SSO, RBAC, audit logs, environment/app configuration via schemas, and safe secret handling via Key Vault references—ensuring governance, traceability, and predictable UX across portal, SDK, and CLI.'
6
6
  type: webapp
7
- version: '2.0.82'
7
+ version: '2.0.89'
8
8
  # Image Configuration
9
9
  # Set tag to match your build (e.g. aifabrix build miso-controller -t 1.0.0 then tag: 1.0.0)
10
10
  # Registry is required so the controller can pull the image (avoids "docker: not found" on the controller host).
@@ -75,6 +75,101 @@ repository:
75
75
  # - DATABASE_URL, REDIS_URL, KEYCLOAK_* → auto-generated during Azure install
76
76
  # - Other MISO_*, AZURE_*, kv:// → credentials and system parameters
77
77
  # - PORT, NODE_ENV, MISO_ENVIRONMENT → set by deployment target
78
+ # - LOCATION → resolved from the platform match below
79
+
80
+ # =============================================================================
81
+ # Platform Resolution (target Azure resource group decides)
82
+ # =============================================================================
83
+ # One controller per installation (MISO_ENVIRONMENT=miso), so the values that vary
84
+ # are stack-level, not per environment: there is no `environments:` section.
85
+ # env.template consumes these names as {NAME}.
86
+ platforms:
87
+ # Production is matched first and by its literal name, because its host is not the suffixed
88
+ # pattern the other platforms follow: `platform.aifabrix.dev`, not `platform-pro.aifabrix.dev`.
89
+ - resource: aifabrix-int-pro
90
+ name: aifabrix
91
+ platform: pro
92
+ configuration:
93
+ - name: LOCATION
94
+ value: 'swedencentral'
95
+ - name: MORI_BASE_URL
96
+ value: 'https://platform.aifabrix.dev/mori'
97
+
98
+ # Local Docker runs. No resource group is supplied, so `matchLocalPlatform` takes the FIRST entry
99
+ # declaring the local platform (`dev`) -- this one -- and the literal `aifabrix-local` can never
100
+ # match a real group, so Azure deployments fall through to the entries below.
101
+ #
102
+ # It MUST sit above `aifabrix-int-{platform}`: that entry also resolves to `dev`, so without this
103
+ # one a local stack took `https://platform-dev.aifabrix.dev/mori` -- a host that does not exist on
104
+ # a developer machine. Measured on dev01 2026-09-28: every Mori call failed with `socket hang up`,
105
+ # and `LicenseValidationService.pickupLicenseFromMori` maps that transport failure to
106
+ # `LicenseInvalidError`, which surfaces as **HTTP 403** on
107
+ # `POST /api/ide/onboarding/license/pickup`. A connection failure reported as Forbidden sent the
108
+ # investigation after api-key permissions for days (mori 48.0 `reproduce-license-pickup-403`).
109
+ #
110
+ # Service-to-service traffic has no reason to leave the cluster through the public edge, and the
111
+ # public host is not even resolvable from inside the container. Verified from the miso-controller
112
+ # container: `http://mori-controller:3004/api/v1/health` answers 200 while both
113
+ # `platform-dev.aifabrix.dev` and `dev01.aifabrix.dev` fail to connect.
114
+ #
115
+ # The value is the declarative `url://` form rather than a literal host, so the Builder resolves
116
+ # it from the platform topology the same way Mori's own env.template resolves
117
+ # `url://miso-controller-internal`. A literal would be a second place to edit whenever the local
118
+ # service address changes, and the whole point of `url://` is that there is one.
119
+ #
120
+ # Verified on dev01 that this is the reachable address and that the `/mori` prefix it carries is
121
+ # served: from the miso-controller container both `http://mori-controller:3004/api/v1/health` and
122
+ # `http://mori-controller:3004/mori/api/v1/health` answer 200. `moriApiBase()` appends `/api/v1`.
123
+ #
124
+ # NOT `kv://mori-controller-web-server-url`, which is what the entries below deliberately moved
125
+ # away from: that reads the application RECORD, and on aifabrix-ce-16 the record still held
126
+ # `http://localhost:3004`. `url://` is resolved from the topology at resolve time, not from a
127
+ # record an Azure deployment never overwrites.
128
+ - resource: aifabrix-local
129
+ name: aifabrix
130
+ platform: dev
131
+ configuration:
132
+ - name: LOCATION
133
+ value: 'swedencentral'
134
+ - name: MORI_BASE_URL
135
+ value: 'url://mori-controller-internal'
136
+
137
+ - resource: aifabrix-int-{platform}
138
+ name: aifabrix
139
+ options: [dev, tst]
140
+ configuration:
141
+ - name: LOCATION
142
+ value: 'swedencentral'
143
+ # Mori the installation talks to. Previously `kv://mori-controller-web-server-url`, which
144
+ # resolved to whatever the *application record* held — on aifabrix-ce-16 that was
145
+ # `http://localhost:3004`, because an Azure deployment never overwrites a stale URL, so every
146
+ # consumer of it was pointed at a loopback address that does not exist in the cluster.
147
+ - name: MORI_BASE_URL
148
+ value: 'https://platform-{platform}.aifabrix.dev/mori'
149
+
150
+ - resource: aifabrix-ce-*
151
+ name: '*'
152
+ # The group carries no dev|tst|pro token, so the platform is declared.
153
+ platform: dev
154
+ configuration:
155
+ - name: LOCATION
156
+ value: 'swedencentral'
157
+ # The App Service hostname, not the Front Door one, because only this is derivable.
158
+ #
159
+ # The Front Door endpoint carries an Azure-generated suffix (`fzahchbachcfbgaj`) that no
160
+ # template can spell: `{platform}`, `{platform.name}` and `{resourceGroup}` are the only
161
+ # tokens, and none of them yields it. The previous literal was aifabrix-ce-16's endpoint and
162
+ # was therefore wrong for every other `aifabrix-ce-*` installation -- the next one built would
163
+ # have pointed its Miso at ce-16's Mori.
164
+ #
165
+ # The web app is named `{resourceGroup}-miso-mori-controller` by the installer, so its default
166
+ # hostname IS derivable and is correct for every installation in the group. Verified on
167
+ # aifabrix-ce-16 2026-09-27: that host answers /mori/health with 200. This is also the better
168
+ # address for Miso->Mori traffic, which is service-to-service and has no reason to leave the
169
+ # cluster through the public edge. When the named platform hosts exist
170
+ # (`platform-dev.aifabrix.dev/mori`) this entry can follow the pattern used above.
171
+ - name: MORI_BASE_URL
172
+ value: 'https://{resourceGroup}-miso-mori-controller.azurewebsites.net/mori'
78
173
 
79
174
  configuration:
80
175
  # -------------------------------------------------------------------------