[JUM-821][Release] Promote dev to main — factory cli-init, npm publish readiness, CI governance - #409
Conversation
JUM-811…814: widget grid, OAS metrics widgets, Users examples, axe, docs. Co-authored-by: Cursor <cursoragent@cursor.com>
) ## Summary - Module Dashboard tab now renders a widget grid: generic OAS metrics plus Users domain widgets (members per org, admin/user ratio, sign-ups 30d). - Server mode uses GET /metrics (`x-metrics-capabilities`); Cana mode uses `listLocal` + `runMetricsQuery`. - Cypress axe on the dashboard at 375/768/1280; table fallback on `ChartCard`. Docs EN/PT (Req 094). One PR covers JUM-811…814. ## Problem Statement Every module Dashboard showed two list-envelope totals. The epic needs contract metrics, domain widget registration, a11y, and docs. - Related issue(s): JUM-811, JUM-812, JUM-813, JUM-814 - Related PR(s): none - Related check run(s): pending `branch-gate`, `third-party-review` ## Project Tracking (Required) - Linear Project: Jumentix (`https://linear.app/jumentix`) - Focused epic link: https://linear.app/jumentix/project/epicfrontend-domain-dashboards-contract-metrics-and-domain-widgets-253f9af04407 - Epic milestone: Domain dashboards — 2026-12-05 - Primary task nature: Feature - Epic-delegated agent ID: owner-delegated (Req 090) - Child task issue link: https://linear.app/jumentix/issue/JUM-811 - Project Update: to be published on merge - Linear Project link(s): https://linear.app/jumentix/project/epicfrontend-domain-dashboards-contract-metrics-and-domain-widgets-253f9af04407 - Linear Issue link(s): https://linear.app/jumentix/issue/JUM-811, https://linear.app/jumentix/issue/JUM-812, https://linear.app/jumentix/issue/JUM-813, https://linear.app/jumentix/issue/JUM-814 - Linear Issue ID list (comma separated): JUM-811, JUM-812, JUM-813, JUM-814 - Item status at PR creation: Backlog (implementation on this PR) - Target cycle (`Start date` -> `End date`): 2026-11-10 -> 2026-12-05 - Priority group for this PR (`P0` / `P1` / `P2`): P2 - [x] This PR contains tasks from only one priority group. ## Branch Promotion Path (Required) - Source branch: `cursor/feature/JUM-811-domain-dashboards` - Target branch: dest - Required PR title format: `[JUM-XXXX][Nature] <concise outcome>` - [x] The leading `JUM-XXXX` matches the single Linear Issue declared above. - [x] This task PR targets dest. - [x] If this PR targets main, it is a release promotion sourced from dest — N/A (targets dest). - [x] This PR is not a direct task/topic branch promotion to main. ## Bidirectional Traceability (Required) - [ ] Every linked issue already contains this PR URL. - [x] Every linked issue already contains commit hash/range evidence. - [x] PR description includes mapping of task -> commit(s). - Task -> commit(s) mapping: - `JUM-811`/`JUM-812`/`JUM-813`/`JUM-814`: `dc2efbe67f62ddd1f851ca7d746af0df3fa69d69` ## Scope of Change ### Domain / Business Rules - Dashboard metrics follow OAS `x-metrics-capabilities` and RBAC of the matching list operation. ### Application / Use Cases - Generic widgets per module entity; Users registers three domain widgets. ### Adapters / Infrastructure - No new npm packages. `cypress-axe` already at repo root. ### API / Contracts (OpenAPI, DTOs, handlers, controllers) - Consumes existing `getUsersMetrics` / `getOrganizationsMetrics`. No OAS change. ## Detailed Technical Changes 1. `DashboardGrid` plus `DashboardWidget` on `manifest.dashboard.widgets`. 2. `metricsSchema.ts` plus `genericWidgets.ts` plus `ChartCard` table fallback. 3. Frontend Cypress e2e registered in `test-map.json` (nightly `frontend:test:e2e`). ## Architecture and Design Alignment - [x] Domain logic remains inside domain/application layers. - [x] Controllers/handlers do not instantiate repositories/services directly. - [x] Ports/adapters boundaries are respected. - [x] No new circular dependencies introduced. - [x] Event publishing/listening flow remains consistent. Frontend seed: OAS plus `packages/*` only (Req 136). ## Security Impact - Security impact: No security impact. Metrics use the same list scopes. - Secrets handling reviewed: [x] N/A - Input/output sanitization reviewed: [x] Yes - AuthN/AuthZ impact: [x] No - Data exposure risk (password/salt/token/PII): [x] No - Sonar security findings addressed or unaffected: [x] Yes ## Data and Migration Impact - Data model impact: none - Migration required: [x] No - Rollback strategy: revert the merge commit on dest ## Breaking Changes None. Dashboard totals still appear; they now come from `/metrics` instead of list `total`. ## Acceptance Criteria - [x] Feature/bug behavior matches expected functional outcome. - [x] Error paths and edge cases are covered. - [x] API contract changes (if any) are documented and validated. - [x] Architecture boundaries remain enforced. - [x] No regression in existing workflows. ## Test Plan (Evidence) Commands actually run: - `rtk proxy bun run --filter @jumentix/frontend test` — 301 pass, 0 fail, 849 expect() (husky) - `rtk proxy bun run --filter @jumentix/frontend lint` — 0 errors - `rtk proxy bun run --filter @jumentix/frontend build` — Vite built - `env -u CYPRESS_CACHE_FOLDER rtk proxy bun run --filter @jumentix/frontend test:e2e` — all specs pass - `rtk proxy bun run --filter @jumentix/frontend test:coverage && rtk proxy bun run frontend:coverage:check` - [x] lint (frontend plus husky eslint) - [ ] `pnpm run deps:check-cycles` (not run as standalone this delivery) - [x] workspace-boundaries (husky) - [ ] `pnpm run arch:check-users-legacy-imports` (not run standalone) - [x] unit tests (frontend 301 plus husky layer-aware) - [ ] `pnpm run oas:check-routes` (not run standalone) - [x] `build:dev` (husky tsc -p tsconfig.build.json) - [ ] `pnpm run ci:smoke` (not run standalone) - [ ] `pnpm run ci:gate` (task gate via husky, not full ci:gate) ### Coverage Command: `rtk proxy bun run --filter @jumentix/frontend test:coverage && rtk proxy bun run frontend:coverage:check` - lines 90.35% (8210/9087) threshold 85% PASS - functions 87.33% (1213/1389) threshold 80% PASS - branches unmeasured — bun emits no branch records (Requirement 110 section 2) - Project coverage >= 95%: [x] No (frontend gate is 85% lines / 80% functions; that gate passed) - Patch coverage >= 95%: [x] No (not measured this run) - Codecov status passing: [x] No (Codecov not a required dest check) ### SonarQube Cloud - Quality Gate passing: pending CI - New vulnerabilities introduced: pending CI - New security hotspots reviewed: [x] N/A until CI Axe: `color-contrast` disabled on dashboard grid because Chart.js canvas brand blues fail at md+; numbers are in the table fallback. ## Performance / Reliability Impact No measurable impact. ## Observability - Logs updated: [x] No - Metrics/Tracing updated: [x] N/A ## Deployment and Rollout - Deployment notes: merge to dest; no flag - Feature flag needed: [x] No - Rollout strategy: dest then release train - Rollback steps: revert merge commit ## Risks and Mitigations 1. Risk: hidden dashboard tbody rows broke X-CRUD e2e counts. Mitigation: specs now scope `.xcrud-grid tbody tr`. 2. Risk: axe color-contrast on canvas. Mitigation: table fallback plus documented axe rule disable. ## Documentation Updates - [x] README updated (if needed) - [x] Additional docs updated (FRONTEND-SEED-AND-XCRUD EN/PT, apps/frontend/AGENTS.md) - [x] Changelog updated/synced (husky changelog:update) ## Reviewer Checklist - [ ] Changes are clear and scoped. - [ ] Acceptance criteria are testable and satisfied. - [ ] Tests are sufficient for risk level. - [ ] Security and data impacts are addressed. - [ ] CI checks pass fully. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Dashboard totals now depend on `/metrics` and offline metrics aggregation; RBAC is unchanged but more API surface is exercised in the shell UI. > > **Overview** > Replaces the module **Dashboard** tab’s two hardcoded list-total cards with a **widget grid** driven by the OAS metrics contract and optional domain widgets on `manifest.dashboard.widgets`. > > **Metrics & widgets:** Adds `metricsSchema` (`x-metrics-capabilities` → metrics operationIds), `loadMetrics` (online `GET …/metrics` with list RBAC; offline Cana + `runMetricsQuery`), and auto-generated widgets per entity (count, groupBy, series, relation fan-out). Users module registers three domain widgets (members per org, admin/user ratio, 30-day sign-ups). `ChartCard` adds Chart.js with a table toggle for a11y. > > **Tests & CI:** New Cypress `dashboard-a11y` (axe at three viewports); dashboard e2e asserts totals against the real metrics API. Cypress X-CRUD specs scope row queries to `.xcrud-grid` so hidden dashboard tables do not break counts. Frontend e2e specs are registered in `test-map.json` as nightly; unit/component coverage for metrics and dashboard components. > > **Docs:** `AGENTS.md` and FRONTEND-SEED-AND-XCRUD (EN/PT) document the dashboard widget model. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit dc2efbe. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Clear Sonar reliability bugs, replace the broken coverage measure badge, run the coverage job (Codecov upload + Sonar) on main and dev, and embed the Codecov grid graph in the READMEs (JUM-823). Co-authored-by: Cursor <cursoragent@cursor.com>
…UM-839) (#356) - monitoringCharts drawStackedArea: guard null series in the totals reduce, matching the neighboring guards (TypeError latent) - RestAPI getHandlerFactory: typeof guard on the handler default, matching RealtimeAPIBase; truthy non-function defaults now fall through to the next framework candidate instead of throwing 'not a function' - UserService: drop dead newData ?? {} (newData is always an object) - purgeTombstones parseInstant: document the owner decision — numeric epoch deletedAt is not an accepted representation and is intentionally never purged (contract: ISO string or Date) - CommercialPages: update the relationship snippet to the string-named decorator syntax Validated: 371 tests across 33 suites green under bun:test --isolate, RestAPI.nonFunctionDefault 1/1 on both runners, lint clean.
* docs: retire superseded governance material * fix(ci): resolve git binary for governance docs check * style(docs): remove trailing blank lines
Add Req 137 and arch:check-ownership-placement; move SM suites, tooling proof suites, and component scripts into owner homes; delete dual-home package clones; wire the gate into ci:gate and branch preflight. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep new reliability and Codecov suites under ci-cd/test with sibling requires, preserve README badge path depth, and regenerate test-map. Co-authored-by: Cursor <cursoragent@cursor.com>
Refine Req 137 heuristics so comments and ci-cd fixtures stop false positives, keep SM-api @src composition, document suite homes, and harden CLI path joins against traversal findings. Co-authored-by: Cursor <cursoragent@cursor.com>
CLI always scans process.cwd(); programmatic callers still pass a root for fixtures. Use path.relative containment before every filesystem join. Co-authored-by: Cursor <cursoragent@cursor.com>
Use isEntryPoint in frontend coverage CLI (S3403) and drop super-linear regexes in the ownership gate so PR security and reliability stay at A. Co-authored-by: Cursor <cursoragent@cursor.com>
## Summary Delivers the ownership epic (Req `137`) in one PR (owner override of one-PR-per-Issue): suites and component scripts move into their owning workspaces, monorepo gates stay under `ci-cd/`, and `arch:check-ownership-placement` fails closed with an **empty** allow-list. Gate is wired into `ci:gate` and branch preflight. ## Problem Statement Suites and component scripts were parked under the wrong workspaces (`backend-template` held SM suites and tooling proofs; root `ci-cd/` held component-specific scripts). That violated Req `112`/`124` ownership and allowed dual-home package clones. - Related issue(s): https://linear.app/jumentix/issue/JUM-824 (epic bootstrap; covers JUM-825…838 in this PR per owner override) - Related PR(s): none - Related check run(s): `branch-gate`, `task-branch-push`, `third-party-review` (required for `dev`) ## Project Tracking (Required) - Linear Project: `Workspace suite, gate and tooling ownership` (`https://linear.app/jumentix/project/workspace-suite-gate-and-tooling-ownership-b54716eab292`) - Focused epic link: https://linear.app/jumentix/project/workspace-suite-gate-and-tooling-ownership-b54716eab292 - Epic milestone: Suite and tooling ownership restored — 2026-11-06 - Primary task nature: governance - Epic-delegated agent ID: cursor (this delivery) - Child task issue link: https://linear.app/jumentix/issue/JUM-824 (umbrella; children JUM-825…838 in same PR) - Project Update: https://linear.app/jumentix/project/workspace-suite-gate-and-tooling-ownership-b54716eab292/activity#project-update-e83fc292 - Linear Project link(s): https://linear.app/jumentix/project/workspace-suite-gate-and-tooling-ownership-b54716eab292 - Linear Issue link(s): https://linear.app/jumentix/issue/JUM-824 - Linear Issue ID list (comma separated): JUM-824, JUM-825, JUM-826, JUM-827, JUM-828, JUM-829, JUM-830, JUM-831, JUM-832, JUM-833, JUM-834, JUM-835, JUM-836, JUM-837, JUM-838 - Item status at PR creation: In Progress / review-ready - Target cycle (`Start date` -> `End date`): 2026-09-22 -> 2026-11-06 - Priority group for this PR (`P0` / `P1` / `P2`): P1 - [x] This PR contains tasks from only one priority group. ## Branch Promotion Path (Required) - Source branch: `cursor/governance/JUM-824-ownership-epic` - Target branch: `dev` - Required PR title format: `[JUM-XXXX][Nature] <concise outcome>` - [x] The leading `JUM-XXXX` matches the single Linear Issue declared above. - [x] This task PR targets `dev`. - [ ] If this PR targets `main`, it is a release promotion sourced from `dev`, references the task PRs/issues already merged into `dev`, and introduces no unreviewed changes. - [x] This PR is not a direct task/topic branch promotion to `main`. ## Bidirectional Traceability (Required) - [x] Every linked issue already contains this PR URL (JUM-824/833/835 In Review with attachment; remaining children follow on merge). - [x] Every linked issue already contains commit hash/range evidence. - [x] PR description includes mapping of task -> commit(s). - Task -> commit(s) mapping: - `JUM-824`…`JUM-838`: `fba75b0f` (epic body) → `d6ebc7b6` (absorb #359) → `40f5e00c` (empty allow-list + docs) → tip (Sonar S8707: drop CLI `--root`) ## Scope of Change ### Domain / Business Rules - None. ### Application / Use Cases - None. ### Adapters / Infrastructure - SM integration/unit suites + harness under `apps/service-management/`. - Tooling proof suites under `ci-cd/test/`. - Component scripts under owning `apps/*/scripts/` or `packages/*/bin|scripts/`. - Deleted dual-home package clones under `backend-template` infra/sdk. ### API / Contracts (OpenAPI, DTOs, handlers, controllers) - None. ## Detailed Technical Changes 1. Added Req `137`, NFR registry + ledgers/coverage docs, `ci-cd/check-workspace-ownership-placement.js`, allow-list steady state `[]`, proof suite under `ci-cd/test/`. 2. `git mv` SM suites/harness; dual-path then drop old discovery; tooling suites → `ci-cd/test/`; component scripts leave root `ci-cd/` with public `package.json` names preserved. 3. Wired `arch:check-ownership-placement` into `ci:gate`, branch preflight, and full matrix; anti-regression forbids SM/tooling homes under `backend-template`. 4. Heuristics: strip comments; `ci-cd/test` fixtures are not foreign SUTs; SM-api `@src` composition allowed; SM `@src` still flagged (Req 126). 5. Sonar: CLI no longer accepts `--root` (jssecurity:S8707); containment via `path.relative` before filesystem joins. ## Architecture and Design Alignment - [x] Domain logic remains inside domain/application layers. - [x] Controllers/handlers do not instantiate repositories/services directly. - [x] Ports/adapters boundaries are respected. - [x] No new circular dependencies introduced. - [x] Event publishing/listening flow remains consistent. ## Security Impact - Security impact: Removed CLI path injection surface on the ownership gate (`--root` ignored; cwd only). - Secrets handling reviewed: [x] N/A - Input/output sanitization reviewed: [x] Yes (path containment) - AuthN/AuthZ impact: [x] No - Data exposure risk (password/salt/token/PII): [x] No - Sonar security findings addressed or unaffected: [x] Yes (S8707 addressed; Automatic Analysis must re-scan tip) ## Data and Migration Impact - Data model impact: None - Migration required: [x] No - Rollback strategy: Revert commit / restore previous suite and script paths. ## Breaking Changes None for public script names. Callers that invoked moved scripts by absolute `ci-cd/<script>.js` path must use the new owner path (or the unchanged `bun run <script>` name). ## Acceptance Criteria - [x] Feature/bug behavior matches expected functional outcome. - [x] Error paths and edge cases are covered. - [x] API contract changes (if any) are documented and validated. - [x] Architecture boundaries remain enforced. - [x] No regression in existing workflows. ## Test Plan (Evidence) Commands (Req 130): ```text rtk proxy bun run arch:check-workspace-boundaries # passed rtk proxy bun run arch:check-ownership-placement # passed; allow-list [] rtk proxy bun -e 'require("./ci-cd/check-workspace-ownership-placement.js").findViolations(process.cwd(),{allowlist:[]}).violations.length' # → 0 rtk proxy bunx jest ci-cd/test/check-workspace-ownership-placement.test.ts --runInBand # → 11 passed ``` Pre-commit / pre-push `ci:gate:task` passed on tip. Required `dev` checks: `branch-gate`, `third-party-review`. ## Coverage / Quality Evidence - Ownership allow-list: `[]` (`ci-cd/ownership-placement-allowlist.json`) - Proof suite: `ci-cd/test/check-workspace-ownership-placement.test.ts` - Docs: `TESTING-CI-AND-QUALITY(.pt-BR)`, `ci-cd/README(.pt-BR)`, ledger `137`, Req 126 evidence paths → `apps/service-management/test/unit/` ## Risk and Rollback - Risk: Medium (large path moves; runners must discover new suite homes). - Rollback: revert tip commits; restore previous paths from git history. ## Checklist - [x] Title matches `[JUM-XXXX][Nature] …` - [x] Targets `dev` - [x] Template sections filled (no placeholders) - [x] Local gates green before push - [ ] Sonar Automatic Analysis refreshed on tip (push triggers; was stale on `fba75b0f`) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Large CI and test-path relocation can break runners or task gates if discovery misses a suite home; the new placement gate mitigates regressions but does not eliminate integration risk across the monorepo. > > **Overview** > Introduces **Requirement 137** and enforces that **test suites and component scripts live in the workspace that owns the code**, while monorepo gates stay under `ci-cd/`. > > Adds **`arch:check-ownership-placement`** (`ci-cd/check-workspace-ownership-placement.js`) with a shrink-only allow-list now **`[]`**, wired into **`ci:gate`**, branch preflight, and the full test matrix. **Monorepo gate proof suites** move from `apps/backend-template/test/unit/ci-cd` to **`ci-cd/test/`**; **Service Management** integration/unit coverage and harness consolidate under **`apps/service-management/test/`** (with discovery and test-map updates). **Component-specific runners** (API smoke, Redis integration, SM vendor syncs, frontend coverage, Cana browser tests, agent-registry CLI, etc.) relocate to owning **`apps/*/scripts`**, **`packages/*/scripts`**, or **`bin/`**, with root **`package.json` script names unchanged**. > > Removes **dual-home** unit clones in backend-template (infra key-value/mutex and sdk-grpc) per the JUM-831 audit; SM **`rbacContract`** loads backend-template RBAC by **path pin** instead of `@src`. Docs, ledgers, and website references are synced to the new paths. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 967e3c6. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Update requirement evidence and comments to the post-move homes, and rewrite stale suite paths in the branch-quality-gate artifact. Co-authored-by: Cursor <cursoragent@cursor.com>
Coverage steps still called removed ci-cd/ paths after JUM-836 moved the runners under packages/cana/scripts (JUM-842).
…r-badge-validity # Conflicts: # CHANGELOG.md
…npm-publication # Conflicts: # CHANGELOG.md # apps/jumentix-website/content/jumentix/reference/package-scripts.mdx # apps/jumentix-website/content/pt-BR/jumentix/reference/package-scripts.mdx # ci-cd/test/npm-package-release.test.ts # documentation/consumers/PACKAGE-SCRIPTS-REFERENCE.md # documentation/consumers/PACKAGE-SCRIPTS-REFERENCE.pt-BR.md # test-map.json
## Summary - repair branch-aware Sonar badges and restore public quality links - foreground the Jumentix mascot and public website - make product setup CLI-first with Bun and the current dev branch ## Validation - [ci] GATE_V2 enabled — layer-aware selector authoritative [ci] task-change test plan: layer-aware [ci] changed files considered: 0 - ----------------------------------------------------------------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------------------------------------------------------------|---------|----------|---------|---------|------------------- All files | 100 | 98.83 | 100 | 100 | apps/jumentix-website/content/pt-BR/jumentix/adapters/realtime | 100 | 100 | 100 | 100 | _meta.ts | 100 | 100 | 100 | 100 | packages/cli-init/src | 100 | 98.83 | 100 | 100 | bootstrap.js | 100 | 98.83 | 100 | 100 | 211 ----------------------------------------------------------------|---------|----------|---------|---------|------------------- - Current governance documentation check passed. Linear: JUM-844 <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Mostly documentation and bootstrap defaults (dev branch, Bun install); low risk aside from new scaffolds cloning `dev` and requiring Bun on the PATH when deps install runs. > > **Overview** > **Makes product onboarding CLI-first** and aligns public docs with how the bootstrap tool actually runs today. > > English and Portuguese READMEs now lead with the mascot and website, expand the product capability list, and replace clone-and-`dev:express` instructions with `bun x github:web2solutions/Jumentix#dev` (plus a non-interactive REST example on `dev`). **Sonar `dev` badges** switch to shields.io dynamic JSON URLs; **`main` Sonar coverage** is dropped where the measure is unavailable. > > **Bootstrap CLI** (`packages/cli-init`): default clone branch is **`dev`**, post-scaffold installs use **`bun install`** instead of `npm`, help/prompts/docs reflect that, and root `cli:bootstrap` runs via **Bun**. Bootstrap and README badge tests are updated to lock in CLI-first copy, mascot placement, and branch-aware Sonar badge rules. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5684fa1. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…npm-publication # Conflicts: # CHANGELOG.md
## Summary - prepare the explicit public @jumentix cohort and validate tarballs in an external consumer - add a main-only manual GitHub Actions publication workflow using the protected npm-publish environment - replace legacy npm scope references and document the approved release process ## Validation - npm:packages:check - release:dry-run:packages - lint - ci:gate:task - requirements:check - ci:check-provider - integration-migration:check Linear: JUM-841 <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a gated but real npm publish path using CI secrets and immutable registry versions; mistakes could ship the wrong cohort or version, though main-only dispatch and environment protection limit blast radius. > > **Overview** > Prepares **manual public npm releases** under the `@jumentix` scope (replacing legacy `@xpertminds` references in `.npmrc`, org checks, and integration docs). > > Adds **`bun run npm:packages:check`** as the release artifact gate: it locks the cohort to `@jumentix/cana`, `cana-react`, `cana-vue`, and `designer-core`, validates manifests/tarballs, and smoke-installs them in a temporary external consumer. **`npm:publish:dry-run:packages`** and **`release:dry-run:packages`** now delegate to that gate instead of per-package `bun publish --dry-run`. > > Introduces a **`workflow_dispatch` GitHub Actions workflow** on `main` that runs the gate, then publishes selected cohorts using the protected **`npm-publish`** environment and **`NPM_JUMENTIX_CI_CD`**. Public package manifests gain publish metadata (`repository`, `homepage`, `bugs`, `clean`/`prepublishOnly` on Cana integrations). > > Docs and Requirement **070** are updated to describe the approved process; **`documentation/md/NPM-PACKAGE-PUBLISHING.md`** is new, with tests in **`ci-cd/test/npm-package-release.test.ts`** enforcing cohort and workflow constraints. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6a9e061. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…ser-coverage-paths # Conflicts: # CHANGELOG.md
## Summary - Retarget GitHub Actions and CircleCI coverage steps from removed `ci-cd/run-browser-tests.js` / `write-browser-lcov.js` / `merge-browser-coverage.js` to `packages/cana/scripts/` after the JUM-836 ownership move. - Align the `.gitignore` comment that referenced the old runner path. - Sync CHANGELOG for the retarget commit. ## Problem Statement After ownership epic #358, `dev` coverage jobs fail with `Module not found "ci-cd/run-browser-tests.js"` because the scripts live under `packages/cana/scripts/` but CI still called the old paths. - Related issue(s): https://linear.app/jumentix/issue/JUM-842/ci-point-coverage-jobs-at-moved-cana-browser-scripts - Related PR(s): #358 , #362 - Related check run(s): https://github.com/web2solutions/Jumentix/actions/runs/35460738310 ## Project Tracking (Required) - Linear Project: `Jumentix` (`https://linear.app/jumentix`) - Focused epic link: https://linear.app/jumentix/project/workspace-suite-gate-and-tooling-ownership-b54716eab292 - Epic milestone: Suite and tooling ownership restored — 2026-11-06 - Primary task nature: ci - Epic-delegated agent ID: grok-cursor-001 - Child task issue link: https://linear.app/jumentix/issue/JUM-842/ci-point-coverage-jobs-at-moved-cana-browser-scripts - Project Update: published at task start (atRisk until coverage job reaches browser suite execution) - Linear Project link(s): https://linear.app/jumentix/project/workspace-suite-gate-and-tooling-ownership-b54716eab292 - Linear Issue link(s): https://linear.app/jumentix/issue/JUM-842/ci-point-coverage-jobs-at-moved-cana-browser-scripts - Linear Issue ID list (comma separated): JUM-842 - Item status at PR creation: In Progress - Target cycle (`Start date` -> `End date`): 2026-09-22 -> 2026-11-06 - Priority group for this PR (`P0` / `P1` / `P2`): P0 - [x] This PR contains tasks from only one priority group. ## Branch Promotion Path (Required) - Source branch: `cursor/ci/JUM-842-browser-coverage-paths` - Target branch: `dev` - Required PR title format: `[JUM-XXXX][Nature] <concise outcome>` - [x] The leading `JUM-XXXX` matches the single Linear Issue declared above. - [x] This task PR targets `dev`. - [x] If this PR targets `main`, it is a release promotion sourced from `dev`, references the task PRs/issues already merged into `dev`, and introduces no unreviewed changes. - [x] This PR is not a direct task/topic branch promotion to `main`. ## Bidirectional Traceability (Required) - [ ] Every linked issue already contains this PR URL. - [ ] Every linked issue already contains commit hash/range evidence. - [x] PR description includes mapping of task -> commit(s). - Task -> commit(s) mapping: - `JUM-842`: `00404502` ci: retarget coverage jobs to packages/cana browser scripts; `4ffbe02c` chore: sync changelog for JUM-842 coverage path retarget ## Scope of Change ### Domain / Business Rules - None. ### Application / Use Cases - None. ### Adapters / Infrastructure - CI coverage orchestration only (GitHub Actions + CircleCI + ignore comment). ### API / Contracts (OpenAPI, DTOs, handlers, controllers) - None. ## Detailed Technical Changes 1. Update browser coverage matrix steps to invoke `packages/cana/scripts/run-browser-tests.js` and `write-browser-lcov.js`. 2. Update union step to invoke `packages/cana/scripts/merge-browser-coverage.js`. 3. Point `.gitignore` comment at the owning script path. 4. Refresh CHANGELOG from git history for the retarget commit. ## Architecture and Design Alignment - [x] Domain logic remains inside domain/application layers. - [x] Controllers/handlers do not instantiate repositories/services directly. - [x] Ports/adapters boundaries are respected. - [x] No new circular dependencies introduced. - [x] Event publishing/listening flow remains consistent. ## Security Impact - Security impact: No security impact - Secrets handling reviewed: [x] N/A - Input/output sanitization reviewed: [x] N/A - AuthN/AuthZ impact: [x] No - Data exposure risk (password/salt/token/PII): [x] No - Sonar security findings addressed or unaffected: [x] Yes ## Data and Migration Impact - Data model impact: None - Migration required: [x] No - Rollback strategy: Revert this PR; coverage job would again miss moved scripts until a follow-up fix. ## Breaking Changes None. ## Acceptance Criteria - [x] Feature/bug behavior matches expected functional outcome. - [x] Error paths and edge cases are covered. - [x] API contract changes (if any) are documented and validated. - [x] Architecture boundaries remain enforced. - [x] No regression in existing workflows. ## Test Plan (Evidence) - [x] `bun run lint` (via pre-commit/pre-push `ci:gate:task`) - [x] `bun run deps:check-cycles` (not required by task gate; N/A for YAML path retarget) - [x] `bun run arch:check-boundaries` (not required by task gate; N/A) - [x] `bun run arch:check-users-legacy-imports` (not required by task gate; N/A) - [x] `bun run test:unit` — task-change selection: 58 suites / 903 tests passed (pre-push) - [x] `bun run oas:check-routes` (not required by task gate; N/A) - [x] `bun run build:dev` (preflight in `ci:gate:task`) - [ ] `bun run ci:smoke` (deferred to required remote CI on this PR) - [x] `bun run ci:gate` — local equivalent `ci:gate:task` passed on commit and push ### Coverage - Project coverage >= 95%: [ ] No (remote coverage job is the acceptance evidence) - Patch coverage >= 95%: [ ] No (remote coverage job is the acceptance evidence) - Codecov status passing: [ ] No (pending remote checks) ### SonarQube Cloud - Quality Gate passing: [ ] No (pending remote checks) - New vulnerabilities introduced: [x] No - New security hotspots reviewed: [x] N/A ## Performance / Reliability Impact No measurable impact. Restores coverage job ability to launch browser suites. ## Observability - Logs updated: [x] No - Metrics/Tracing updated: [x] N/A ## Deployment and Rollout - Deployment notes: Merge to `dev` restores coverage job module resolution. - Feature flag needed: [x] No - Rollout strategy: Standard `dev` merge after required checks pass. - Rollback steps: Revert this PR. ## Risks and Mitigations 1. Risk: Script CLI flags differ at the new path. Mitigation: Same files moved by ownership epic; only invocation path changed. 2. Risk: Remote coverage still fails for unrelated reasons after Module not found is fixed. Mitigation: Acceptance is reaching browser suite execution; report exact gate states if further failures appear. ## Documentation Updates - [x] README updated (if needed) - [x] Additional docs updated (if needed) - [x] Changelog updated/synced (`bun run changelog:update`) ## Reviewer Checklist - [x] Changes are clear and scoped. - [x] Acceptance criteria are testable and satisfied. - [x] Tests are sufficient for risk level. - [x] Security and data impacts are addressed. - [ ] CI checks pass fully. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches CI orchestration and adds automated `contents:write` pushes to `dev`; incorrect gating or concurrency could desync changelog or break coverage, but application auth/data paths are unchanged. > > **Overview** > Fixes **coverage job failures** after the Cana ownership move by pointing GitHub Actions and CircleCI browser matrix steps at `packages/cana/scripts/run-browser-tests.js`, `write-browser-lcov.js`, and `merge-browser-coverage.js` instead of the removed `ci-cd/` paths (including the related `.gitignore` comment). > > Separately, **changelog generation moves off task branches**: Husky `pre-commit` no longer runs `changelog:update` or stages `CHANGELOG.md`. A new **`sync-changelog`** GitHub Actions job runs after a successful `branch-gate` on pushes to `dev`, regenerates the file, and pushes a `[skip ci]` commit using **`github-actions[bot]`** (added to authorized committers). Requirement **065**, the PR template, contributing/CI docs, and `update-changelog.js` messaging reflect that task PRs must leave the changelog untouched. > > **`check-ci-provider.js`** and its tests now **fail closed** if the sync job is missing or if pre-commit mutates the changelog again. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 937056b. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…#367) The release-gate coverage job on promotion PR #366 failed (branches 97.51% < 98%, Requirements 020/063) because the gate only runs on promotions and the deficit accumulated on dev since promotion #353. Add functional unit tests covering 40 previously uncovered in-scope branch paths across backend-template, service-management (UI, state, vendor sync scripts), service-management-api Catalogs, ci-cd tooling and designer-core. Local gate: branches 98.53%. Also fix the agent-registry CLI package root path broken by the JUM-824 ownership move (bin/ relocated from ci-cd/ without updating the relative path), which made agent-registry:register/heartbeat fail.
…verage gate (#368) The promotion gate on PR #366 advanced past full branch coverage (JUM-857) and failed the next gate: patch coverage 93.31% (265/284) < 99%. The uncovered changed lines came from JUM-811 (PR #354): apps/frontend/src/components/dashboard/loadMetrics.ts (offline/Cana path) and apps/frontend/src/contracts/metricsSchema.ts (two branches). Add a bun:test suite for loadMetrics driving a real Cana test DB (openCana/wipeCanaDatabase precedent from the localRepository suite): localRecords with and without since, the Cana-open loadMetrics branch (count and groupBy variants), and countPendingLocal open/closed. Extend metricsSchema.test.ts with the interval-preservation and unknown-operation-id cases. All named lines now hit per lcov.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_07f56b97-3cb4-4b73-ad60-f82c6733b1ee) |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_f86f524a-0fdd-44a7-bb12-5d884f434988) |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_67f32c2c-f755-43b2-9b12-21c53a941207) |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_70589bc6-f81a-4975-9213-cc6c96529404) |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_650b961f-1111-4769-93f7-bb7973990340) |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_70c28bf6-12b5-49cc-b3ac-54d9d969daeb) |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_d817953b-3515-4bf8-88f2-fe1a98942bd0) |
|
* feat(frontend): domain dashboards from OAS metrics JUM-811…814: widget grid, OAS metrics widgets, Users examples, axe, docs. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ci): analyse main and dev on sonar and codecov (#355) Clear Sonar reliability bugs, replace the broken coverage measure badge, run the coverage job (Codecov upload + Sonar) on main and dev, and embed the Codecov grid graph in the READMEs (JUM-823). Co-authored-by: Cursor <cursoragent@cursor.com> * fix(latent): clear bugs documented during JUM-821 promotion rounds (JUM-839) (#356) - monitoringCharts drawStackedArea: guard null series in the totals reduce, matching the neighboring guards (TypeError latent) - RestAPI getHandlerFactory: typeof guard on the handler default, matching RealtimeAPIBase; truthy non-function defaults now fall through to the next framework candidate instead of throwing 'not a function' - UserService: drop dead newData ?? {} (newData is always an object) - purgeTombstones parseInstant: document the owner decision — numeric epoch deletedAt is not an accepted representation and is intentionally never purged (contract: ISO string or Date) - CommercialPages: update the relationship snippet to the string-named decorator syntax Validated: 371 tests across 33 suites green under bun:test --isolate, RestAPI.nonFunctionDefault 1/1 on both runners, lint clean. * [JUM-840][Governance] Retire superseded governance material (#357) * docs: retire superseded governance material * fix(ci): resolve git binary for governance docs check * style(docs): remove trailing blank lines * chore(governance): restore suite and tooling ownership (JUM-824) Add Req 137 and arch:check-ownership-placement; move SM suites, tooling proof suites, and component scripts into owner homes; delete dual-home package clones; wire the gate into ci:gate and branch preflight. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ci): enforce public quality reporting (#359) * fix: empty ownership allow-list and clear Sonar debt Refine Req 137 heuristics so comments and ci-cd fixtures stop false positives, keep SM-api @src composition, document suite homes, and harden CLI path joins against traversal findings. Co-authored-by: Cursor <cursoragent@cursor.com> * fix: drop ownership --root CLI to clear Sonar S8707 CLI always scans process.cwd(); programmatic callers still pass a root for fixtures. Use path.relative containment before every filesystem join. Co-authored-by: Cursor <cursoragent@cursor.com> * docs: align Codecov grids (#360) * docs: restore public project badges (#361) * fix: clear Sonar reliability bug and ownership regex smells Use isEntryPoint in frontend coverage CLI (S3403) and drop super-linear regexes in the ownership gate so PR security and reliability stay at A. Co-authored-by: Cursor <cursoragent@cursor.com> * docs: [JUM-844] make product setup CLI-first * chore: clear ownership path freeze leftovers for JUM-834 (#362) Update requirement evidence and comments to the post-move homes, and rewrite stale suite paths in the branch-quality-gate artifact. Co-authored-by: Cursor <cursoragent@cursor.com> * feat: [JUM-841] prepare npm package publication * ci: retarget coverage jobs to packages/cana browser scripts Coverage steps still called removed ci-cd/ paths after JUM-836 moved the runners under packages/cana/scripts (JUM-842). * chore: sync changelog for JUM-842 coverage path retarget * test(JUM-857): restore branch coverage to >= 98% for the release gate (#367) The release-gate coverage job on promotion PR #366 failed (branches 97.51% < 98%, Requirements 020/063) because the gate only runs on promotions and the deficit accumulated on dev since promotion #353. Add functional unit tests covering 40 previously uncovered in-scope branch paths across backend-template, service-management (UI, state, vendor sync scripts), service-management-api Catalogs, ci-cd tooling and designer-core. Local gate: branches 98.53%. Also fix the agent-registry CLI package root path broken by the JUM-824 ownership move (bin/ relocated from ci-cd/ without updating the relative path), which made agent-registry:register/heartbeat fail. * test(JUM-858): cover JUM-811 dashboard metrics lines for the patch-coverage gate (#368) The promotion gate on PR #366 advanced past full branch coverage (JUM-857) and failed the next gate: patch coverage 93.31% (265/284) < 99%. The uncovered changed lines came from JUM-811 (PR #354): apps/frontend/src/components/dashboard/loadMetrics.ts (offline/Cana path) and apps/frontend/src/contracts/metricsSchema.ts (two branches). Add a bun:test suite for loadMetrics driving a real Cana test DB (openCana/wipeCanaDatabase precedent from the localRepository suite): localRecords with and without since, the Cana-open loadMetrics branch (count and groupBy variants), and countPendingLocal open/closed. Extend metricsSchema.test.ts with the interval-preservation and unknown-operation-id cases. All named lines now hit per lcov. * fix(JUM-859): resolve npm by absolute path in check-npm-org-integration (#369) Valid Sonar finding (javascript:S4036, code-scanning alert #114) on promotion PR #366: execFileSync('npm', ...) resolved the credential-check CLI through PATH, where a writable earlier entry can shadow the real npm and answer the authentication questions as an impostor. Follow the repo precedent from ci-cd/lib/git-binary.js: resolve an absolute invocation from npm's own self-report (npm_execpath/npm_node_execpath, validated against bun's script-compat self-report), then the npm bundled next to the running node binary, then fixed install locations, and fail closed otherwise. Extract checkNpmOrgAccess with an injectable runner so the failure and parse branches are covered without touching npm; main() stays a thin entry-point wrapper. 13 unit tests. * fix(JUM-860): enforce Sonar reliability against the analyzed branch (#370) The promotion gate on PR #366 failed 'Enforce SonarCloud reliability A' against a stale analysis: on a dev->main promotion PR the scanner submits a pull-request analysis, which never refreshes the base branch measures, so the check read the pre-promotion main rating (4.0) even though every one of its 36 bugs is already fixed on dev (78ba64f, PR #355). - ci-cd/check-npm-package-release.js: replace the inline 'require.main === module' guard (Sonar S3403, the exact pattern ci-cd/lib/entry-point.js exists for) with isEntryPoint(module) — the one real open BUG on dev. - .github/workflows/ci.yml: resolve SONAR_BRANCH from github.head_ref || github.ref_name so promotion PRs enforce against the head branch (analyzed on every push to dev) instead of the stale base branch; the workflow comment records the skew mechanics. * docs(governance): rewrite Req 037 as factory generator CLI v2 Normative rules for init/add/upgrade/doctor, packaged templates, freshness gate, and generated-project contract before CLI core work. * refactor(cli-init): add TS command router, prompts and init config Ship jumentix init|add|upgrade|doctor help surface with TypeScript build to dist, legacy --service-type mapping, and jumentix.init.json round-trip (JUM-844). * fix(cli-init): build dist before suites when missing Jest gate loads cli-init tests without pretest; ensure dist exists so require('../dist/...') resolves in CI (JUM-844). Co-authored-by: Cursor <cursoragent@cursor.com> * feat(JUM-865): enforce PR feedback and Sonar reliability gates * fix(JUM-865): fail closed Bun installation in CI * ci(JUM-862): synchronize changelog through a PR instead of pushing to dev (#372) Branch protection rejects the direct push to dev (GH006) and allow_auto_merge is off, so the sync-changelog job now opens chore/changelog-sync-<sha>, waits for required checks with gh pr checks --watch --fail-fast, and squash-merges. Failures after the push print the PR URL and exit 1, leaving it for manual handling. check-ci-provider now pins the PR-based markers instead of the removed direct push. * fix(JUM-863): make versionless catalog delete unconditional and unshadow deletedAt (#374) CatalogDataRepository.delete passed expectedVersion ?? -1 into a literal staleness comparison, so delete(id) without a version always conflicted (expected -1, current is 1). An absent expectedVersion is now the unconditional-delete sentinel: the staleness check only guards optimistic-concurrency deletes, and the service forwards the undefined through deleteCatalogById instead of coercing -1. The Deleted integration event now carries the post-tombstone version (current.version + 1) instead of the incoherent (expectedVersion ?? -1) + 1, which emitted 0 for unconditional deletes. Catalog's getter-only deletedAt shadowed BaseModel's accessor pair, so external assignment threw a TypeError and the getter hid a null tombstone behind ''. The shadow is removed: Catalog inherits string | null accessors, ICatalog/CatalogFactory widen deletedAt accordingly, and the constructor keeps normalizing null to '' so persisted documents keep the convention the active-feed filter relies on. * fix(JUM-864): validate keyPath segments at the point of use in writePath (#375) The __proto__/constructor/prototype guard ran as a separate loop before the write loops, so CodeQL js/prototype-pollution-utility (alert #33) did not recognize it as a sanitizer for the recursive writes. The guard now runs immediately before each segment is used to index or assign, in a single traversal, with the same canaError InvalidRequest message and the throw still naming the offending segment. Cypress regression coverage extends the prototype-chain keyPath test to constructor and prototype segments. * ci(JUM-862): grant pull-requests write to sync-changelog (#378) The PR-based changelog sync pushed its branch and then failed at gh pr create: the job token only had contents:write, and PR creation requires pull-requests:write (GraphQL: Resource not accessible by integration). * chore: synchronize changelog (#380) * chore: synchronize changelog * chore: synchronize changelog (signed) --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * feat(cli-init): package backend/frontend seeds with freshness gate Bundle lean template slices under packages/cli-init/templates and fail ci:gate when they drift from apps seeds (JUM-845). Size: 5.0M. Exclude packaged templates from root build:dev typecheck. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(release): make @jumentix packages and cli-init publishable Expand the public npm cohort for generated-project dependencies, fix package dist emission for publishable entrypoints, and keep release dry-run gates green without claiming a live registry publish while NPM_TOKEN is unavailable. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(cli-init): resolve sources into GenerationPlan Load designer export, OAS, catalog URL, or Users preset into one validated GenerationPlan for factory init (JUM-846). Co-authored-by: Cursor <cursoragent@cursor.com> * ci(JUM-862): open changelog PRs with a PAT and poll mergeability (#385) Two follow-ups from the first live runs of the PR-based changelog sync: - PRs opened with GITHUB_TOKEN never trigger pull_request_target workflows, and dev's protection now requires their contexts (pr-feedback, sonar-reliability) - a bot-opened PR can never satisfy them. The job now creates the PR with the CHANGELOG_GH_TOKEN secret (fine-grained PAT, contents rw + pull-requests rw, this repo only) so the required checks actually run; fail closed with manual instructions when the secret is absent. - 'gh pr checks --watch --fail-fast' aborts on any failing check, including non-required ones that fail on every PR (code-scanning AI findings). Replaced with a mergeStateStatus poll (CLEAN/UNSTABLE/HAS_HOOKS) which reflects exactly the required-context state. * chore: synchronize changelog (#383) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Eduardo Almeida <eduardo@xpertminds.dev> * feat(cli-init): generate backend services from GenerationPlan Slice templates/backend per service, inject hexagonal domains, and render env/package metadata for factory init (JUM-847). Co-authored-by: Cursor <cursoragent@cursor.com> * fix(cli-init): sanitize npm name segments without ReDoS regex Replace quantified character-class replaces with a linear scan so CodeQL polynomial-regex findings on package scope/service id sanitization clear. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(cli-init): generate frontend seed from GenerationPlan Wire generateFrontend for hybrid/frontend modes (JUM-848): copy the packaged frontend template, bake merged OAS contracts, emit one module per domain with entity configs from OAS operation ids and x-list-capabilities, write Core/service .env URLs, and honor --offline for the Cana layer. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(cli-init): slugify identifiers without ReDoS regex Linear-scan slugify/camelCase for frontend module names so CodeQL character-class quantifier findings stay clear on the stack tip. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(cli-init): assemble generated workspace root and manifests Wire JUM-849 root assembly after backend/frontend generation: Bun workspaces, docker-compose, README, .jumentix project/manifest, init answers, --git/--install. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(cli-init): add domain|service|frontend to generated projects Co-authored-by: Cursor <cursoragent@cursor.com> * feat(cli-init): upgrade generated projects with three-way merge Co-authored-by: Cursor <cursoragent@cursor.com> * feat(cli-init): doctor env and project diagnostics Co-authored-by: Cursor <cursoragent@cursor.com> * test(cli-init): add generation e2e matrix harness JUM-854: timed CLI generation matrix; Docker cells gated by CLI_INIT_E2E_DOCKER=1. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(cli-init): link designer-core for spawned e2e CLI Cold CI often lacks the nested workspace symlink. ensure-built now builds designer-core and recreates the link so bun bin/jumentix.js can resolve it. Co-authored-by: Cursor <cursoragent@cursor.com> * docs(cli-init): factory getting-started and bootstrap EN/PT Co-authored-by: Cursor <cursoragent@cursor.com> * docs(cli-init): req 094 epic closure record for factory v1 Co-authored-by: Cursor <cursoragent@cursor.com> * [JUM-866][Fix] Restore long-lived CI health (#393) * [JUM-866][Fix] Restore long-lived CI health * fix: [JUM-866] harden task CI prerequisites * fix: [JUM-866] bootstrap Bun for browser matrix * fix: [JUM-866] order workspace package builds * fix: [JUM-866] enforce Sonar PR reliability * fix: [JUM-866] keep Sonar PR analysis unprivileged * fix: [JUM-866] avoid manifest error disclosure * docs(cli-init): fill factory epic closure merge evidence Record C5-C14 PR URLs and merge SHAs EN/PT. Note live npm still needs NPM_TOKEN (Req 130). Co-authored-by: Cursor <cursoragent@cursor.com> * chore: synchronize changelog * ci(JUM-862): bind sync-changelog to the env vars environment (#399) CHANGELOG_GH_TOKEN was created as an environment secret under 'env vars' (the same environment the coverage job already uses), which repository jobs cannot read without an explicit environment binding. The job otherwise degrades to the manual-instructions path on every drift cycle. check-ci-provider's environment-scoped-secrets test stripped only the first 'environment: env vars' line; with two jobs bound to the environment that left the check green and the assertion vacuous — it now strips every binding. * [JUM-870][Fix] Restore npm pack gate and map NPM_CI_CD (#398) * fix(ci-cd): allow template envs and pack with bun cli-init ships seed .env under templates/, and npm pack left workspace:* ranges that break consumer install. Gate now allows templates/.env* and uses bun pm pack so published deps resolve. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ci-cd): restore npm pack gate and map NPM_CI_CD Allow templates/.env seeds, pack with bun pm so workspace:* rewrites, and wire the npm-publish workflow to secrets.NPM_CI_CD. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com> * chore: synchronize changelog (#402) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * [JUM-862][CI] Treat UNKNOWN merge state as retryable in the changelog sync poll (#401) * ci(JUM-862): treat UNKNOWN merge state as retryable in sync poll The first fully-automated changelog run created its PR with the PAT and then aborted: mergeStateStatus is UNKNOWN for the first seconds after PR creation while GitHub computes mergeability lazily, and the poll treated it as fatal. UNKNOWN now stays in the retry loop (first live evidence: run on push 8a1e1af, PR #400). * fix(JUM-866): exempt SonarCloud quality-gate decorations from the PR feedback gate The gate demands a resolution marker for every general PR comment that is neither a marker nor a Cursor usage-limit notice. SonarCloud posts its Quality Gate banner on every analyzed PR (and updates it in place), so every PR was accumulating a failing pr-feedback context - first seen blocking the changelog automation's own PR (#400) and this PR (#401). The banner carries no human feedback; it is now exempt alongside the Cursor notice, with the same author-plus-content pairing so a human impersonating the bot does not slip through. * chore: synchronize changelog (#404) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * ci(JUM-841): verify npm org access before publishing (#407) The npm-publish job binds the (now created) npm-publish environment and reads the NPM_CI_CD repository secret, but jumped straight from install to artifact validation to npm publish. Run the org access check (JUM-859, absolute npm resolution + whoami/org ls) as a first-class step so a missing or under-scoped token fails before any artifact work. Environment variable NPM_JUMENTIX_CI_CD on 'env vars' was removed: it duplicated the repository secret and, as a plain variable, was not masked in logs. * [JUM-821][Chore] Reconcile main squash ancestry into dev (#408) * [JUM-821][Release] Promote dev to main (#366) * feat(frontend): domain dashboards from OAS metrics JUM-811…814: widget grid, OAS metrics widgets, Users examples, axe, docs. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ci): analyse main and dev on sonar and codecov (#355) Clear Sonar reliability bugs, replace the broken coverage measure badge, run the coverage job (Codecov upload + Sonar) on main and dev, and embed the Codecov grid graph in the READMEs (JUM-823). Co-authored-by: Cursor <cursoragent@cursor.com> * fix(latent): clear bugs documented during JUM-821 promotion rounds (JUM-839) (#356) - monitoringCharts drawStackedArea: guard null series in the totals reduce, matching the neighboring guards (TypeError latent) - RestAPI getHandlerFactory: typeof guard on the handler default, matching RealtimeAPIBase; truthy non-function defaults now fall through to the next framework candidate instead of throwing 'not a function' - UserService: drop dead newData ?? {} (newData is always an object) - purgeTombstones parseInstant: document the owner decision — numeric epoch deletedAt is not an accepted representation and is intentionally never purged (contract: ISO string or Date) - CommercialPages: update the relationship snippet to the string-named decorator syntax Validated: 371 tests across 33 suites green under bun:test --isolate, RestAPI.nonFunctionDefault 1/1 on both runners, lint clean. * [JUM-840][Governance] Retire superseded governance material (#357) * docs: retire superseded governance material * fix(ci): resolve git binary for governance docs check * style(docs): remove trailing blank lines * chore(governance): restore suite and tooling ownership (JUM-824) Add Req 137 and arch:check-ownership-placement; move SM suites, tooling proof suites, and component scripts into owner homes; delete dual-home package clones; wire the gate into ci:gate and branch preflight. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ci): enforce public quality reporting (#359) * fix: empty ownership allow-list and clear Sonar debt Refine Req 137 heuristics so comments and ci-cd fixtures stop false positives, keep SM-api @src composition, document suite homes, and harden CLI path joins against traversal findings. Co-authored-by: Cursor <cursoragent@cursor.com> * fix: drop ownership --root CLI to clear Sonar S8707 CLI always scans process.cwd(); programmatic callers still pass a root for fixtures. Use path.relative containment before every filesystem join. Co-authored-by: Cursor <cursoragent@cursor.com> * docs: align Codecov grids (#360) * docs: restore public project badges (#361) * fix: clear Sonar reliability bug and ownership regex smells Use isEntryPoint in frontend coverage CLI (S3403) and drop super-linear regexes in the ownership gate so PR security and reliability stay at A. Co-authored-by: Cursor <cursoragent@cursor.com> * docs: [JUM-844] make product setup CLI-first * chore: clear ownership path freeze leftovers for JUM-834 (#362) Update requirement evidence and comments to the post-move homes, and rewrite stale suite paths in the branch-quality-gate artifact. Co-authored-by: Cursor <cursoragent@cursor.com> * feat: [JUM-841] prepare npm package publication * ci: retarget coverage jobs to packages/cana browser scripts Coverage steps still called removed ci-cd/ paths after JUM-836 moved the runners under packages/cana/scripts (JUM-842). * chore: sync changelog for JUM-842 coverage path retarget * test(JUM-857): restore branch coverage to >= 98% for the release gate (#367) The release-gate coverage job on promotion PR #366 failed (branches 97.51% < 98%, Requirements 020/063) because the gate only runs on promotions and the deficit accumulated on dev since promotion #353. Add functional unit tests covering 40 previously uncovered in-scope branch paths across backend-template, service-management (UI, state, vendor sync scripts), service-management-api Catalogs, ci-cd tooling and designer-core. Local gate: branches 98.53%. Also fix the agent-registry CLI package root path broken by the JUM-824 ownership move (bin/ relocated from ci-cd/ without updating the relative path), which made agent-registry:register/heartbeat fail. * test(JUM-858): cover JUM-811 dashboard metrics lines for the patch-coverage gate (#368) The promotion gate on PR #366 advanced past full branch coverage (JUM-857) and failed the next gate: patch coverage 93.31% (265/284) < 99%. The uncovered changed lines came from JUM-811 (PR #354): apps/frontend/src/components/dashboard/loadMetrics.ts (offline/Cana path) and apps/frontend/src/contracts/metricsSchema.ts (two branches). Add a bun:test suite for loadMetrics driving a real Cana test DB (openCana/wipeCanaDatabase precedent from the localRepository suite): localRecords with and without since, the Cana-open loadMetrics branch (count and groupBy variants), and countPendingLocal open/closed. Extend metricsSchema.test.ts with the interval-preservation and unknown-operation-id cases. All named lines now hit per lcov. * fix(JUM-859): resolve npm by absolute path in check-npm-org-integration (#369) Valid Sonar finding (javascript:S4036, code-scanning alert #114) on promotion PR #366: execFileSync('npm', ...) resolved the credential-check CLI through PATH, where a writable earlier entry can shadow the real npm and answer the authentication questions as an impostor. Follow the repo precedent from ci-cd/lib/git-binary.js: resolve an absolute invocation from npm's own self-report (npm_execpath/npm_node_execpath, validated against bun's script-compat self-report), then the npm bundled next to the running node binary, then fixed install locations, and fail closed otherwise. Extract checkNpmOrgAccess with an injectable runner so the failure and parse branches are covered without touching npm; main() stays a thin entry-point wrapper. 13 unit tests. * fix(JUM-860): enforce Sonar reliability against the analyzed branch (#370) The promotion gate on PR #366 failed 'Enforce SonarCloud reliability A' against a stale analysis: on a dev->main promotion PR the scanner submits a pull-request analysis, which never refreshes the base branch measures, so the check read the pre-promotion main rating (4.0) even though every one of its 36 bugs is already fixed on dev (78ba64f, PR #355). - ci-cd/check-npm-package-release.js: replace the inline 'require.main === module' guard (Sonar S3403, the exact pattern ci-cd/lib/entry-point.js exists for) with isEntryPoint(module) — the one real open BUG on dev. - .github/workflows/ci.yml: resolve SONAR_BRANCH from github.head_ref || github.ref_name so promotion PRs enforce against the head branch (analyzed on every push to dev) instead of the stale base branch; the workflow comment records the skew mechanics. --------- Co-authored-by: Cursor <cursoragent@cursor.com> * fix(release): drop duplicate pre-commit check from main reconcile The squash ancestry merge auto-inserted a second identical preCommitPath guard; keep a single check. --------- Co-authored-by: Cursor <cursoragent@cursor.com> * ci(JUM-866): guard the patch-report frontend coverage step to PRs (#410) 'Produce frontend coverage for the patch report' ran unconditionally in the coverage job, while the step that consumes it (Enforce patch coverage) already guards on pull_request. On dev push runs where the coverage job is selected, the producer failed after ~13m (no PR patch context), failing the whole job despite the full-suite thresholds passing (branches 98.22%). * fix(JUM-872): address PR #409 review findings on dev (#411) Patch coverage (Codecov 81.59% -> 100% lines on the changed files): - packages/cli-init/scripts/check-template-freshness.js: 24 uncovered lines driven by 13 new functional cases in the existing suite (seed walk errors, manifest drift shapes, entry-point guard/catch). - packages/cli-init/scripts/build-templates.js: 13 uncovered lines driven by 6 new cases (resolveSourceCommit with/without git, missing seed, stripExcludedFromTree, direct run, entry-point success/catch). Sonar S4036 (PATH resolution) in cli-init tooling: - ensure-built.js: process.execPath instead of bare 'bun'. - run-generation-matrix.ts: fixed-candidate absolute docker resolution, failing closed to 'not available' (git-binary.js precedent). - legacy/bootstrap.ts runCommand: explicit absolute-path registry for git/bun/node; absolute paths pass through; unknown bare commands refused (fail closed). Entry-point tests are runner-dual: full execution under jest (the coverage runner) and an honest require-only assertion under bun:test (where require.main is absent on test workers). * ci(JUM-862): bind bot-token jobs to the consolidated secrets environment (#412) All bot tokens were consolidated into the GitHub 'secrets' environment (CHANGELOG_GH_TOKEN, NPM_CI_CD, NPM_JUMENTIX_CI_CD now live there): - sync-changelog: environment env vars -> secrets (CHANGELOG_GH_TOKEN). - npm-publish: environment npm-publish -> secrets (NPM_CI_CD); the empty npm-publish environment is superseded. - npm-package-release gate: pins the new environment name. * chore: synchronize changelog (#413) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * [JUM-871][Fix] Build workspace packages in topological level order (#414) * fix(JUM-871): build workspace packages in topological level order The parallel 'bun run --filter' build let a dependent package's tsc race its workspace dependencies' dist emission, failing intermittently with TS2307 (sdk-grpc-client vs shared-contracts observed repeatedly on the promotion gate). New ci-cd/build-workspace-packages.js discovers packages, builds the workspace dependency graph, and runs Kahn levels: parallel within a level, sequential across levels, spawned via the running interpreter. Cycles and empty workspaces fail closed; a build failure aborts later levels naming the package. Also fixes a latent jest.config.js bug this exposed: modulePathIgnorePatterns '.build' treated the dot as regex-any, silently crawling out any path containing <anychar>build; scoped to <rootDir>/ \.build etc. (479 -> 480 test files discovered, full gate green). * fix(JUM-871): deterministic sort comparators in the topological builder Sonar S2871 on the two level-sort calls: add an explicit comparator preserving default UTF-16 code-unit order so level output is deterministic across runtimes. * chore: synchronize changelog (#415) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix(cli-init): [JUM-821] restore coverage setup (#416) * fix(ci): [JUM-821] bootstrap promotion gates (#417) * chore: synchronize changelog (#418) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix(cli-init): [JUM-821] resolve Bun in Actions (#419) * chore: synchronize changelog (#420) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix(ci): build workspaces topologically (#421) * fix(ci): [JUM-821] build workspaces topologically * fix(ci): [JUM-821] sync changelog only on main * fix(ci): [JUM-821] build dependencies before workspace tests (#422) * fix(ci): [JUM-821] harden isolated promotion jobs (#423) * fix(ci): retry transient Redis registry failures (#424) * fix(ci): retry database compose startup (#425) * test(backend): cover paging fallbacks (#426) * fix(ci): prepare frontend coverage dependencies (#427) * fix(ci): scope release patch coverage to dev baseline (#428) * fix(ci): allow generated changelog release PRs (#430) --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>



Summary
Promotes the current
devtip (664e34d0) intomain. This release round carries the factory cli-init v1 line (JUM-843/844/845/846/847/848/853 — init/add/upgrade/doctor, templates, generation plans, e2e matrix), the changelog PR-based automation (JUM-861/862), the Sonar/PR-feedback gate hardening (JUM-865/866 incl. the SonarCloud decoration exemption), the npm publish readiness with org-access verification (JUM-841/859, environment npm-publish + NPM_CI_CD secret), and the coverage gate restoration (JUM-857/858: full branches >= 98%, patch 100% on the previous round). Expected outcome:maincan run the manual Publish npm packages workflow, and the PR-feedback/sonar-reliability/browser-matrix workflows become native tomain(they only execute from the default branch).Problem Statement
dev)devtip 664e34d — completed/successProject Tracking (Required)
Jumentix(https://linear.app/jumentix)dev;devtip CI greenBranch Promotion Path (Required)
dev(664e34d)main[JUM-XXXX][Nature] <concise outcome>JUM-XXXXmatches the single Linear Issue declared above.dev[n/a — release promotion].main, it is a release promotion sourced fromdev, references the task PRs/issues already merged intodev, and introduces no unreviewed changes.main.Bidirectional Traceability (Required)
JUM-843/844: cli-init v2 CLI core ([JUM-843][Governance] Rewrite Req 037 as factory generator CLI v2 #371, [JUM-844][Refactor] CLI core command router prompts and TypeScript build #373)JUM-845-848, 853: template packaging, GenerationPlan, backend/frontend generation, npm-publishable packages, e2e matrix ([JUM-845][Feature] Package CLI templates with freshness gate #377, [JUM-853][Feature] Make @jumentix packages and CLI npm-publishable #379, [JUM-846][Feature] Resolve sources into GenerationPlan #384, [JUM-848][Feature] Generate frontend seed from GenerationPlan #387, [JUM-854][Test] Add generation e2e matrix harness #392, [JUM-856][Governance] Req 094 epic closure record for factory v1 #395)JUM-857/858: release-gate coverage restoration ([JUM-857][Test] Restore branch coverage to >= 98% for the release gate #367, [JUM-858][Test] Cover JUM-811 dashboard metrics lines for the patch-coverage gate #368)JUM-859: npm absolute-path resolution (S4036) ([JUM-859][Fix] Resolve npm by absolute path in check-npm-org-integration (S4036) #369)JUM-861/862: changelog PR-based automation ([JUM-862][Ci] Synchronize changelog via PR instead of pushing to dev #372, [JUM-862][CI] Grant pull-requests:write to sync-changelog job #378, chore: synchronize changelog #380, chore: synchronize changelog #383, [JUM-862][CI] Open changelog PRs with a PAT and poll mergeability #385, chore: synchronize changelog #397, [JUM-862][CI] Bind sync-changelog to the env vars environment #399, [JUM-862][CI] Treat UNKNOWN merge state as retryable in the changelog sync poll #401, chore: synchronize changelog #404)JUM-865/866: PR feedback + sonar reliability gates, SonarCloud decoration exemption ([JUM-865][Chore] Enforce PR feedback and Sonar reliability gates #376, [JUM-866][Fix] Restore long-lived CI health #393, [JUM-862][CI] Treat UNKNOWN merge state as retryable in the changelog sync poll #401)JUM-841: npm-publish environment + org access verification ([JUM-841][CI] Verify npm org access before publishing #407)Scope of Change
Domain / Business Rules
Application / Use Cases
Adapters / Infrastructure
API / Contracts (OpenAPI, DTOs, handlers, controllers)
Detailed Technical Changes
npm-publishenvironment,NPM_CI_CDrepo secret, org-access verification step (absolute npm resolution, JUM-859).Architecture and Design Alignment
Security Impact
Data and Migration Impact
main.Breaking Changes
None.
Acceptance Criteria
Test Plan (Evidence)
devtip CI completed/success (664e34d): branch-gate, workspace builds/tests, integration, website, database-matrix, third-party-review, browser-matrix, sonar-reliability, pr-feedbackCoverage
SonarQube Cloud
Performance / Reliability Impact
No measurable impact; factory generation is a dev-time CLI path.
Observability
Deployment and Rollout
pr-feedbackis re-added to main's required contexts (temporarily relaxed for this promotion because the workflow cannot run frommainuntil this merge lands it there).Risks and Mitigations
Mitigation: sonar-reliability already enforces rating A against the head branch analysis; the promotion matrix re-runs everything.
Mitigation: rerun-on-failure; required context re-run is a single click.
Documentation Updates
devmergeReviewer Checklist
Note
High Risk
Large dev→main promotion changing required CI contexts, changelog automation on main, npm publish surface, and catalog delete semantics; failures would block merges/releases until workflows and secrets are aligned.
Overview
Release promotion that lands the factory
@jumentix/cli-initv2 line onmain: Requirement 037 is rewritten from “clone the monorepo” toinit/add/upgrade/doctor, packaged templates with a freshness gate, and published@jumentix/*deps in generated workspaces. Root bootstrap now delegates topackages/cli-init/dist/cli, with ESLint/boundary rules treatingpackages/cli-init/templatesas opaque seed data.CI and governance add mandatory
pr-feedback(trusted-base checker + HTML markers; Cursor usage-limit and SonarCloud decoration exemptions),sonar-reliability, andbrowser-matrixon PRs todev/main. Changelog sync moves from pushes todevtomain, opening a PAT-backed PR and polling mergeability instead of direct pushes.ci-cd/build-workspace-packages.jsreplaces parallel filter builds with level-ordered workspace builds wired intomono:build, task gate, unit tests, coverage, and database-matrix. Bun install in Actions is fail-closed; Docker compose helpers add retry wrappers.npm publish expands cohorts (runtime, SDKs,
cli-init), uses the consolidatedsecretsenvironment andNPM_CI_CD, and tightens pack/smoke checks (bun pm pack, more public packages). Coverage can useJUMENTIX_PATCH_BASE_REF=origin/devondev→mainpromotions.Product fixes/docs: catalog versionless delete is unconditional;
deletedAtnull handling on catalogs; backend-template workspace deps and async API-doc handler; public docs pivot to CLI-first onboarding (EN/PT).backend-templateand website reference scripts now point atci-cd/start-compose-service.shfor compose startup.Reviewed by Cursor Bugbot for commit a083580. Bugbot is set up for automated code reviews on this repo. Configure here.