From eb797fd69ef2b371e3a1812198fe6f159eeafc1c Mon Sep 17 00:00:00 2001 From: "Prashant Rane (ALLYIS INC)" Date: Thu, 29 Oct 2026 11:31:03 -0600 Subject: [PATCH 1/3] fix(api): prepare compatible advisory pins for CI lock generation Stack on exact unmerged PR 260. Reserve 0.55.64, assess actual consumers, retain Hono lifecycle blocker. CI bootstrap only; immutable RED fixture awaits authenticated locks, final clean restore and protected Validate publication. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CHANGELOG.md | 14 ++ DEPLOYMENT.md | 2 +- README.md | 8 +- Session_starter.md | 14 ++ api/package.json | 6 +- docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md | 138 ++++++++++++++++++ docs/AUTHENTICATION_GUIDE.md | 2 +- docs/AZURE_DEPLOYMENT_AND_USAGE_GUIDE.md | 4 +- docs/COMPLETE_API_REFERENCE.md | 4 +- docs/CONTEXT_INSTRUCTIONS.md | 9 +- docs/CUSTOM_EXTENSIONS_RFC_GUIDE.md | 2 +- docs/DOCKER_GUIDE_AND_TEST_REPORT.md | 4 +- docs/ENDPOINT_CONFIG_FLAGS_REFERENCE.md | 4 +- docs/ENDPOINT_CREATION_WIKI.md | 4 +- docs/ENDPOINT_LIFECYCLE_AND_USAGE.md | 4 +- docs/ENDPOINT_PROFILE_ARCHITECTURE.md | 2 +- .../GLOBAL_NAVIGATION_AND_WORKFLOW_CONTEXT.md | 2 +- docs/INDEX.md | 8 +- docs/LOGGING_AND_OBSERVABILITY.md | 2 +- docs/MULTI_ENDPOINT_GUIDE.md | 4 +- ...ERVABILITY_TRACEABILITY_AND_DIAGNOSTICS.md | 2 +- docs/PATCH_OPERATIONS_COMPLETE_GUIDE.md | 2 +- docs/PROD_TO_DEV_MIRRORING_AND_FIXTURES.md | 4 +- docs/RELEASE_NOTES.md | 11 +- docs/REMOTE_DEBUGGING_AND_DIAGNOSIS.md | 2 +- docs/SCHEMA_ATTRIBUTE_CUSTOMIZATION_GUIDE.md | 2 +- docs/SCHEMA_CUSTOMIZATION_GUIDE.md | 2 +- docs/SOVEREIGN_AND_GOV_CLOUD_DEPLOYMENT.md | 4 +- docs/UI_GUIDE.md | 4 +- .../ENGINEERING_LESSONS_AND_PATTERNS.md | 13 ++ web/package.json | 2 +- 31 files changed, 244 insertions(+), 41 deletions(-) create mode 100644 docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 94ef60ee..34c8fb03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### 0.55.64 preparation - compatible API advisory pins, stacked on draft #260 + +- Reserve 0.55.64 after checking existing branches, pull requests and releases. + Keep the exact #260 ancestry; do not merge or retarget either draft. +- Select qs 6.16.1 and fast-uri 4.2.3 to address five of the six assessed + advisory records. Leave `@hono/node-server` 1.19.15 unchanged because + compatibility with the actual Prisma development lifecycle is unproved. +- Add 14 actual-consumer regressions: corrected pre-manifest RED is 11 + failures / three passes. Existing Ajv compiler, Express parser, Superagent + serializer and body-parser stream behavior already pass at baseline. +- [Public changes, actual ownership, advisory boundaries and execution RCA](docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md). + Full test counts and final protected publication are recorded only after + the authenticated CI locks and clean restore. No deployed release claim. + ### 0.55.63 preparation - API complete-tree override context validity - Independent rollback unit from master 0.55.61; 0.55.62 is reserved by the diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 4ee6e8a6..9105c409 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -1,6 +1,6 @@ # SCIMServer Deployment Options -> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.64` > Updated: 2026-10-16 - Scope: production + local deployment paths diff --git a/README.md b/README.md index 1c998d3a..71b9d0ed 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # SCIMServer -> **Status:** User-facing reference - **Last verified:** 2026-10-21 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-21 - **Product version:** `0.55.64` > Production-ready, multi-tenant SCIM 2.0 server for Microsoft Entra ID provisioning and any RFC 7643/7644-compliant identity client. @@ -9,6 +9,10 @@ cover 0.55.58 correction preparation, merged 0.55.57 source, the deployed 0.55.5 cumulative changes since 0.55.20, migration/rollback steps and known limits. See [CHANGELOG.md](CHANGELOG.md) for detailed engineering history. +**Pending stacked API advisory patch:** [Consumer compatibility and remaining Hono blocker](docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md) +describes proposed 0.55.64 on unmerged draft #260. Five assessed advisory +records are targeted; no merge, deployment or full advisory-clearance claim. + **Pending source-only inventory correction:** [API override-context validity](docs/API_OVERRIDE_CONTEXT_VALIDITY.md) describes proposed 0.55.63 and the complete-tree npm regression. It changes no application behavior and does not qualify a deployment or clear the @@ -20,7 +24,7 @@ For actual supported shapes and integration limits, see Keep strict validation enabled for Entra; diagnose the request and effective schema before applying a targeted compatibility setting. -[![Version](https://img.shields.io/badge/version-0.55.63-blue)]() +[![Version](https://img.shields.io/badge/version-0.55.64-blue)]() [![Node.js](https://img.shields.io/badge/Node.js-24-green)]() [![NestJS](https://img.shields.io/badge/NestJS-11.1-red)]() [![PostgreSQL](https://img.shields.io/badge/PostgreSQL-17-blue)]() diff --git a/Session_starter.md b/Session_starter.md index 6903aac2..8b7dcd5d 100644 --- a/Session_starter.md +++ b/Session_starter.md @@ -2,6 +2,20 @@ **Last verified:** 2026-10-29 +### Stacked API advisory remediation (2026-10-29) + +Proposed 0.55.64 starts from exact draft #260 head +`6eb1b59cb1a8ea324bb1a32b17355fabc605279d` on +`fix/api-advisory-pins-20261029`. Only qs 6.16.1 and fast-uri 4.2.3 +are selected. Actual consumers are three qs owners and nested Ajv 8.20.0; +its pre-existing forced major remains explicitly outside `^3.0.1`. +Corrected RED before manifest edits: 11 failed, three passed, 14 tests. +[Compatibility, advisory boundaries and RCA](docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md) +records why Hono 2.1.3 remains blocked by unproved actual Prisma lifecycle +compatibility. No service is started and no other worktree is owned. +CI-only lock import and final protected validation remain required. +PR #259/#260 are unmerged, #251 and every existing hold remain unchanged. + ### Independent API override-context correction (2026-10-29) Proposed 0.55.63 starts from fresh master `727860866c53c7ec8d01d1ff5bae858f80a1715d`, diff --git a/api/package.json b/api/package.json index 5398e614..2ec131ea 100644 --- a/api/package.json +++ b/api/package.json @@ -1,6 +1,6 @@ { "name": "scimserver-api", - "version": "0.55.63", + "version": "0.55.64", "description": "SCIMServer backend service providing SCIM 2.0 endpoints and logging for troubleshooting.", "license": "MIT", "main": "dist/main.js", @@ -84,7 +84,7 @@ "@hono/node-server": "1.19.15", "defu": "6.1.5", "effect": "3.20.0", - "fast-uri": "4.1.5", + "fast-uri": "4.2.3", "hono": "4.13.11", "multer": "2.5.0", "deepmerge-ts": "8.0.0", @@ -110,7 +110,7 @@ "js-yaml": "3.15.2", "node-releases": "2.0.57", "proxy-addr": "2.0.8", - "qs": "6.16.0", + "qs": "6.16.1", "valibot": "1.4.2" } } diff --git a/docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md b/docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md new file mode 100644 index 00000000..62d8e791 --- /dev/null +++ b/docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md @@ -0,0 +1,138 @@ +# API advisory pins: consumer compatibility and execution RCA + +**Last verified:** 2026-10-29 + +## Executive summary + +Proposed product 0.55.64 is stacked on draft PR #260 at +`6eb1b59cb1a8ea324bb1a32b17355fabc605279d`. It changes only qs 6.16.0 to +6.16.1 and fast-uri 4.1.5 to 4.2.3. Neither this patch nor its parent is +merged. PR #259 and #251 remain separate. No deployed version changes. + +The six-record assessment consists of one qs advisory, four fast-uri +advisories and one Hono adapter advisory. Five records can be corrected +with bounded consumer evidence. The Hono adapter remains blocked, not +suppressed. No finding is dismissed because a package is development-only. + +## Actual owners and compatibility boundaries + +| Dependency | Locked and installed owners | Assessment | +|---|---|---| +| qs 6.16.1 | body-parser 2.4.0 requires `^6.16.1`; Express 5.2.1 requires `^6.14.0`; Superagent 10.3.0 requires `^6.14.1` | All three ranges accept the patch. The previous override suppressed body-parser's published minimum. | +| fast-uri 4.2.3 | The only owner is Ajv 8.20.0 nested under `@prisma/streams-local`, requiring `^3.0.1` | This range does NOT accept either the old forced 4.1.5 or new 4.2.3. Compatibility is bounded behavioral evidence through the actual Ajv compiler and its own URI resolver, not semver acceptance. | +| `@hono/node-server` 1.19.15, unchanged | `@prisma/dev` 0.24.3 requires exact 1.19.11 | Patched 2.1.3 is outside the exact requirement. No compatible parent patch has been proved in this rollback unit. | + +```text +Express / body-parser / Superagent -> shared qs 6.16.1 +Prisma streams-local -> actual nested Ajv 8.20.0 -> fast-uri 4.2.3 +Prisma dev 0.24.3 -> node-server 1.19.15 (blocked advisory remains) +``` + +The graph shows actual locked consumers, not a representative replacement +application. The regression enumerates every occurrence and checks installed +owner declarations and the exact module each owner resolves. + +### Public upstream assessment + +- [qs comparison](https://github.com/ljharb/qs/compare/v6.16.0...v6.16.1): + comma-format serialization handles non-callable `toString`; additional + parser, nesting-bound, encoding and strict-merge fixes require testing + parsing as well as serialization. No major API change is claimed. +- [fast-uri comparison](https://github.com/fastify/fast-uri/compare/v4.1.5...v4.2.3): + encoded schemes and invalid hosts are rejected; relative-reference meaning + and suffix colons are preserved. Other changes cover IPv6 zones, mailto, + URN dot segments and invalid references. The public type diff adds optional + `ipv6Zone`, without removing existing resolver methods. This is not a + promise of all-input compatibility: deliberately malformed inputs change. +- [Hono adapter v2 release](https://github.com/honojs/node-server/releases/tag/v2.0.0) + says the public API stays the same, but replaces request/response internals + for performance. Node >=20 is only an engine prerequisite, not proof of + compatibility with a parent pinned to 1.x. +- [Hono patch release](https://github.com/honojs/node-server/releases/tag/v2.1.3) + rejects remaining percent signs after static-path decoding, with an explicit + opt-in for literal percent signs. + +### Why the Hono adapter is blocked + +Installed `@prisma/dev/dist/index.cjs`, `daemon.cjs` and the ESM chunk +`chunk-2O6J3K3T.js` dynamically import `serve`. The actual parent supplies +Node's HTTP `createServer`, its own constructed Hono application's `fetch`, +`overrideGlobalObjects: false` and a port, and awaits the listening callback. +It registers an `EADDRINUSE` error path. Its close operation promisifies +`server.close` and also stops the parent-managed database components. + +This couples compatibility to real parent initialization, request/response +handling, errors and shutdown, not merely the existence of `serve`. A tiny +Hono fixture or a Node engine check cannot prove those claims. The actual +parent lifecycle starts its development database/server; this task forbids +starting applications or databases. No parent/runtime redesign or broad +Prisma upgrade is authorized. Therefore leave the adapter override unchanged, +retain [GHSA-rmxm-3fg6-px4f](https://github.com/advisories/GHSA-rmxm-3fg6-px4f), +and require an isolated, explicitly authorized parent lifecycle qualification +or a minimally compatible upstream Prisma patch before changing it. + +## Advisory boundaries and permanent evidence + +| Advisory | Boundary on selected line | New outcome | +|---|---|---| +| [GHSA-6pq8-jhm2-2vcw](https://github.com/advisories/GHSA-6pq8-jhm2-2vcw) | qs >=6.7.0, <=6.16.0 | 6.16.1 is outside | +| [GHSA-w74x-v6f9-j3xg](https://github.com/advisories/GHSA-w74x-v6f9-j3xg) | fast-uri >=4.0.0, <4.2.3 | 4.2.3 is outside | +| [GHSA-xhq7-xmqj-769h](https://github.com/advisories/GHSA-xhq7-xmqj-769h) | fast-uri >=4.0.0, <4.2.3 | 4.2.3 is outside | +| [GHSA-wjr9-j795-jxcr](https://github.com/advisories/GHSA-wjr9-j795-jxcr) | fast-uri >=4.0.1, <4.2.3 | 4.2.3 is outside | +| [GHSA-333x-w4r6-6crp](https://github.com/advisories/GHSA-333x-w4r6-6crp) | fast-uri >=4.0.0, <4.2.3 | 4.2.3 is outside | +| GHSA-rmxm-3fg6-px4f | adapter >=1.19.10, <2.1.3 | Still present, compatibility blocked | + +New tests in `api/src/scripts/check-api-advisory-consumers.spec.ts` exercise +all three qs resolutions, the real Express configured parser, Superagent's +form serializer and body-parser's request-stream middleware without opening +a server. Comma-format hardening is tested through each owner's resolved qs, +not misrepresented as those parents' default options. + +The actual nested Ajv compiles external, relative, fragment and recursive +schema references. Tests assert valid and invalid data plus exact validation +error locations and keywords and unresolved-reference rejection. They obtain +the URI resolver from the actual Ajv instance and check each advisory +mechanism independently. Existing complete `npm ls --all --json` acceptance +remains mandatory and unfiltered. + +## RED/GREEN and validation + +Before any manifest edit, the corrected actual-consumer run produced +11 real assertion failures and three passes across 14 tests. The three +compatibility paths already passed on old dependencies; exact pins, installed +versions, comma serialization and all four URI mechanisms failed as expected. +Logs are retained under `test-results/api-advisory-pins-20261029/`. + +CI-only lock generation, authenticated digest verification, approved-feed byte +verification, clean restore, final GREEN and normal protected Validate +publication are required before this draft can claim patch qualification. +Bootstrap publication, if needed to dispatch the unchanged lock workflow, +is not final dependency qualification. No hosted PR-to-master matrix is +inferred when the draft uses a stacked base. + +## Execution issues and root-cause analysis + +| ID / type / severity | Symptom and mechanism | Correction and prevention | Detection / earliest possible | +|---|---|---|---| +| AC-1 / test correctness / Low | Initial Superagent fixture called its private query finalizer before the real request builder serializes queued objects. URL stayed unchanged. | Use the actual public form serializer, assert complete values, and retain corrected RED before manifests change. No network request is needed. | First focused RED / same | +| AC-2 / tooling / Low | Comparing Hono v1.19.15 to v2.1.3 returned HTTP 404 because that comparison ref is unavailable. | Read authenticated public v2 release notes and patch release plus actual installed parent bundle. Do not equate failed lookup with compatibility. | Assessment / same | + +Provenance: this bounded execution retains raw command logs and public metadata +in the ignored evidence directory. Final handoff reconciles tool failures, +assertions and publication receipts; no full-transcript reconciliation is +claimed unless the complete transcript is available. + +## Self-improvement and design disposition + +**Applied:** actual-parent owner enumeration, behavioral RED/GREEN, explicit +forced-major rejection and one assertion per advisory mechanism prevent an +engine check or a toy adapter fixture from becoming false compatibility proof. + +**Accepted:** two flat version pins and a focused regression file introduce no +new runtime responsibility, dependency seam or response field. A generalized +resolver abstraction would duplicate existing package tooling without a +second justified implementation. + +Performance, customer-data, cleanup-403, live/browser, visual/native/renderer, +latest-admission and user-stopped authentication holds remain unchanged. +No release-complete, review-approval, deployment or merge claim is made. diff --git a/docs/AUTHENTICATION_GUIDE.md b/docs/AUTHENTICATION_GUIDE.md index 8ad56292..aab5bc39 100644 --- a/docs/AUTHENTICATION_GUIDE.md +++ b/docs/AUTHENTICATION_GUIDE.md @@ -1,6 +1,6 @@ # Authentication Guide -> **Status:** Living reference - **Last verified:** 2026-10-21 - **Product version:** `0.55.63` +> **Status:** Living reference - **Last verified:** 2026-10-21 - **Product version:** `0.55.64` > > **The captured protocol examples below were measured against a running server.** Request and response bodies are verbatim wire captures. Status codes and `reason_code` values are what the server actually returned. The reason-code table in [Section 8](#8-troubleshooting) is generated from [auth-reason-catalog.ts](../api/src/oauth/auth-reason-catalog.ts), so it cannot drift from the implementation. > diff --git a/docs/AZURE_DEPLOYMENT_AND_USAGE_GUIDE.md b/docs/AZURE_DEPLOYMENT_AND_USAGE_GUIDE.md index bbf7575f..c854c113 100644 --- a/docs/AZURE_DEPLOYMENT_AND_USAGE_GUIDE.md +++ b/docs/AZURE_DEPLOYMENT_AND_USAGE_GUIDE.md @@ -1,8 +1,8 @@ # Azure Deployment & Usage Guide -> **Status:** User-facing reference - **Last verified:** 2026-08-12 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-08-12 - **Product version:** `0.55.64` -> **Version:** 0.55.63 - **Updated:** June 3, 2026 +> **Version:** 0.55.64 - **Updated:** June 3, 2026 > **Source of truth:** [deploy.ps1](../deploy.ps1), [scripts/deploy-azure.ps1](../scripts/deploy-azure.ps1), [infra/](../infra/) --- diff --git a/docs/COMPLETE_API_REFERENCE.md b/docs/COMPLETE_API_REFERENCE.md index 91f771a0..1b3e5f13 100644 --- a/docs/COMPLETE_API_REFERENCE.md +++ b/docs/COMPLETE_API_REFERENCE.md @@ -1,8 +1,8 @@ # Complete API Reference -> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.64` -> **Version:** 0.55.63 - **Updated:** 2026-10-16 +> **Version:** 0.55.64 - **Updated:** 2026-10-16 > **Current release:** [Release notes, upgrade steps and validation limits](RELEASE_NOTES.md). Earlier isolated P1-P9 receipts remain historical; the correctness consolidation is included in the deployed release. > **Base URL:** `http://localhost:{PORT}/scim` (configurable via `API_PREFIX` env var) > **121 route handlers** across 33 controllers (includes 2 dashboard analytics routes and the web SPA catch-all). Counted from the `@Get`/`@Post`/`@Put`/`@Patch`/`@Delete`/`@Sse` decorators in `api/src/**/*.controller.ts` with comments stripped; the count is enforced by `node scripts/audit-doc-content.mjs`. diff --git a/docs/CONTEXT_INSTRUCTIONS.md b/docs/CONTEXT_INSTRUCTIONS.md index d4fdff2c..ebe18d5d 100644 --- a/docs/CONTEXT_INSTRUCTIONS.md +++ b/docs/CONTEXT_INSTRUCTIONS.md @@ -1,7 +1,7 @@ # SCIMServer - Context Instructions for AI Assistants > **Purpose**: This file provides complete project context for AI coding assistants (GitHub Copilot, etc.) to enable productive sessions without re-discovery of architecture, patterns, and decisions. -> **Version**: 0.55.63 +> **Version**: 0.55.64 > **Last Updated**: October 29, 2026 > **Last verified:** 2026-10-29 @@ -9,6 +9,13 @@ ## Active Delivery Process +**2026-10-29 stacked API advisory remediation:** proposed 0.55.64 is based +on draft #260 exact head `6eb1b59cb1a8ea324bb1a32b17355fabc605279d`, +not master or web #259. [Consumer compatibility and RCA](API_ADVISORY_CONSUMER_COMPATIBILITY.md) +records qs 6.16.1, fast-uri 4.2.3, actual-parent RED and the unchanged +Hono adapter compatibility blocker. Ajv's forced 4.x remains a documented +range exception, not semver acceptance. No merge or deploy is authorized. + **2026-10-29 independent API correction:** proposed 0.55.63 branches from master `727860866c53c7ec8d01d1ff5bae858f80a1715d`, excluding draft #259. [API override-context correction and RCA](API_OVERRIDE_CONTEXT_VALIDITY.md) diff --git a/docs/CUSTOM_EXTENSIONS_RFC_GUIDE.md b/docs/CUSTOM_EXTENSIONS_RFC_GUIDE.md index 51778634..3faa4cb1 100644 --- a/docs/CUSTOM_EXTENSIONS_RFC_GUIDE.md +++ b/docs/CUSTOM_EXTENSIONS_RFC_GUIDE.md @@ -9,7 +9,7 @@ or fetching them. See [minimal-schema validation](GOOGLE_MINIMAL_GROUP_MEMBERSHI [reference persistence and compatibility](GROUP_MEMBER_REFERENCE_PRESERVATION.md) and [release notes](RELEASE_NOTES.md). -> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.64` > **P7a behavior, included since 0.55.36:** [Profile validation](SCIM_P7A_PROFILE_VALIDATION.md) > adds declaration/type/cardinality checks, required extension enforcement, diff --git a/docs/DOCKER_GUIDE_AND_TEST_REPORT.md b/docs/DOCKER_GUIDE_AND_TEST_REPORT.md index cecc0edc..e20cb236 100644 --- a/docs/DOCKER_GUIDE_AND_TEST_REPORT.md +++ b/docs/DOCKER_GUIDE_AND_TEST_REPORT.md @@ -1,8 +1,8 @@ # Docker Guide -> **Status:** User-facing reference - **Last verified:** 2026-10-09 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-09 - **Product version:** `0.55.64` -> **Version:** 0.55.63 - **Updated:** June 3, 2026 +> **Version:** 0.55.64 - **Updated:** June 3, 2026 > **Source of truth:** [Dockerfile](../Dockerfile), [docker-compose.yml](../docker-compose.yml) --- diff --git a/docs/ENDPOINT_CONFIG_FLAGS_REFERENCE.md b/docs/ENDPOINT_CONFIG_FLAGS_REFERENCE.md index c7e62722..ae62c558 100644 --- a/docs/ENDPOINT_CONFIG_FLAGS_REFERENCE.md +++ b/docs/ENDPOINT_CONFIG_FLAGS_REFERENCE.md @@ -1,8 +1,8 @@ # Endpoint Configuration Flags Reference -> **Status:** User-facing reference - **Last verified:** 2026-09-29 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-09-29 - **Product version:** `0.55.64` -> **Version:** 0.55.63 - **Updated:** September 29, 2026 +> **Version:** 0.55.64 - **Updated:** September 29, 2026 > **Source of truth:** [endpoint-profile.types.ts](../api/src/modules/scim/endpoint-profile/endpoint-profile.types.ts) (`ProfileSettings`) > 39 registered settings in the unreleased lifetime port: 20 boolean + 16 numeric (11 runtime-egress overrides + 3 active-credential caps + 2 token lifetimes) + 3 other typed values. `PersistRequestSecrets` is inert and `CredentialSecretVisibility` supports only `always`. See the [behavioral evidence and explicit coverage gaps](SCIM_SETTINGS_BEHAVIOR_EVIDENCE.md) and [Entra compatibility guide](SCIM_ENTRA_COMPATIBILITY.md). Registry membership is not evidence of enforcement. > 6 value types: `boolean`, `logLevel`, `primaryEnforcement`, `credentialVisibility`, `structured`, and `number` (the last added for the runtime JWKS-fetch egress knobs). diff --git a/docs/ENDPOINT_CREATION_WIKI.md b/docs/ENDPOINT_CREATION_WIKI.md index 52ceac36..29d7aaff 100644 --- a/docs/ENDPOINT_CREATION_WIKI.md +++ b/docs/ENDPOINT_CREATION_WIKI.md @@ -1,8 +1,8 @@ # Create Your Own SCIM Endpoint - Self-Service Wiki -> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.64` -> **Version:** 0.55.63 - **Updated:** 2026-10-16 +> **Version:** 0.55.64 - **Updated:** 2026-10-16 > Beginner-friendly, copy-paste guide for standing up a SCIM endpoint in minutes. > **Source of truth:** [endpoint.controller.ts](../api/src/modules/endpoint/controllers/endpoint.controller.ts) - [built-in-presets.ts](../api/src/modules/scim/endpoint-profile/built-in-presets.ts) diff --git a/docs/ENDPOINT_LIFECYCLE_AND_USAGE.md b/docs/ENDPOINT_LIFECYCLE_AND_USAGE.md index a889c067..2de9b3cd 100644 --- a/docs/ENDPOINT_LIFECYCLE_AND_USAGE.md +++ b/docs/ENDPOINT_LIFECYCLE_AND_USAGE.md @@ -1,8 +1,8 @@ # Endpoint Lifecycle & Usage Guide -> **Status:** User-facing reference - **Last verified:** 2026-10-12 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-12 - **Product version:** `0.55.64` -> **Version:** 0.55.63 - **Updated:** June 3, 2026 +> **Version:** 0.55.64 - **Updated:** June 3, 2026 > Quick-start recipes for common SCIMServer operations --- diff --git a/docs/ENDPOINT_PROFILE_ARCHITECTURE.md b/docs/ENDPOINT_PROFILE_ARCHITECTURE.md index 943773c2..ae92d6fd 100644 --- a/docs/ENDPOINT_PROFILE_ARCHITECTURE.md +++ b/docs/ENDPOINT_PROFILE_ARCHITECTURE.md @@ -1,6 +1,6 @@ # Endpoint Profile Architecture -> **Status:** User-facing reference - **Last verified:** 2026-10-21 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-21 - **Product version:** `0.55.64` > **Updated:** 2026-10-17 > **Source of truth:** [endpoint-profile/](../api/src/modules/scim/endpoint-profile/) and [endpoint.service.ts](../api/src/modules/endpoint/services/endpoint.service.ts) diff --git a/docs/GLOBAL_NAVIGATION_AND_WORKFLOW_CONTEXT.md b/docs/GLOBAL_NAVIGATION_AND_WORKFLOW_CONTEXT.md index 55556be2..3642fb18 100644 --- a/docs/GLOBAL_NAVIGATION_AND_WORKFLOW_CONTEXT.md +++ b/docs/GLOBAL_NAVIGATION_AND_WORKFLOW_CONTEXT.md @@ -1,6 +1,6 @@ # Global navigation and workflow context -> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.64` See [current release notes](RELEASE_NOTES.md) for deployment and acceptance boundaries. Endpoints now uses available window height, Dashboard uses compact diff --git a/docs/INDEX.md b/docs/INDEX.md index ca068df3..7920ec3e 100644 --- a/docs/INDEX.md +++ b/docs/INDEX.md @@ -1,8 +1,8 @@ # SCIMServer Documentation Index -> **Status:** User-facing reference - **Last verified:** 2026-10-21 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-21 - **Product version:** `0.55.64` -> **Version:** 0.55.63 - **Updated:** 2026-10-21 +> **Version:** 0.55.64 - **Updated:** 2026-10-21 > 6 presets - **39 endpoint settings controls** in the unreleased lifetime port (20 boolean flags + 3 other typed settings + 16 numerics) - profile-driven User, Group, and custom ResourceType forms **Unreleased preparation:** [endpoint token lifetime integration and original @@ -11,6 +11,10 @@ current-master port from earlier isolated validation and deployed behavior. ### Start here +**Pending stacked API advisory remediation:** [Actual consumer compatibility and RCA](API_ADVISORY_CONSUMER_COMPATIBILITY.md) +records proposed 0.55.64, five targeted advisory records and the unchanged +Hono adapter blocker. Its draft base is unmerged #260, not master. + **Pending independent inventory correction:** [API shared override context validity](API_OVERRIDE_CONTEXT_VALIDITY.md) records proposed 0.55.63, all real owners, full-tree RED/GREEN and the same-version root override correction. Draft web #259 remains independent. diff --git a/docs/LOGGING_AND_OBSERVABILITY.md b/docs/LOGGING_AND_OBSERVABILITY.md index e85271f9..9b0b4ba9 100644 --- a/docs/LOGGING_AND_OBSERVABILITY.md +++ b/docs/LOGGING_AND_OBSERVABILITY.md @@ -1,6 +1,6 @@ # Logging & Observability Guide -> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.64` **Current UI presentation:** absolute timestamps in Logs, Activity, Operations and live/detail drawers include full UTC date/time and milliseconds. Copy diff --git a/docs/MULTI_ENDPOINT_GUIDE.md b/docs/MULTI_ENDPOINT_GUIDE.md index ad14700f..8f68e453 100644 --- a/docs/MULTI_ENDPOINT_GUIDE.md +++ b/docs/MULTI_ENDPOINT_GUIDE.md @@ -1,8 +1,8 @@ # Multi-Endpoint Architecture Guide -> **Status:** User-facing reference - **Last verified:** 2026-09-28 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-09-28 - **Product version:** `0.55.64` -> **Version:** 0.55.63 - **Updated:** June 3, 2026 +> **Version:** 0.55.64 - **Updated:** June 3, 2026 > **Source of truth:** [endpoint.service.ts](../api/src/modules/endpoint/services/endpoint.service.ts) --- diff --git a/docs/OBSERVABILITY_TRACEABILITY_AND_DIAGNOSTICS.md b/docs/OBSERVABILITY_TRACEABILITY_AND_DIAGNOSTICS.md index c5f64a0d..d4b36895 100644 --- a/docs/OBSERVABILITY_TRACEABILITY_AND_DIAGNOSTICS.md +++ b/docs/OBSERVABILITY_TRACEABILITY_AND_DIAGNOSTICS.md @@ -1,6 +1,6 @@ # Observability, Traceability, Correlation IDs, Logging, Error Handling and Diagnostics -> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.64` **Current operator presentation:** all absolute UI timestamps carry complete UTC date/time, milliseconds and timezone; invalid expiry values are explicit, diff --git a/docs/PATCH_OPERATIONS_COMPLETE_GUIDE.md b/docs/PATCH_OPERATIONS_COMPLETE_GUIDE.md index 7f705a17..d23dcfd9 100644 --- a/docs/PATCH_OPERATIONS_COMPLETE_GUIDE.md +++ b/docs/PATCH_OPERATIONS_COMPLETE_GUIDE.md @@ -11,7 +11,7 @@ rejected later operation saves no earlier mutation. See [reference persistence and rollback compatibility](GROUP_MEMBER_REFERENCE_PRESERVATION.md) and [current release notes](RELEASE_NOTES.md). -> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.64` > Comprehensive, source-verified reference for every PATCH option, mode, setting, path form, verb, and persistence outcome across Users, Groups, custom extensions, and custom resource types - grounded in RFC 7644 / RFC 7643 and the SCIMServer implementation. diff --git a/docs/PROD_TO_DEV_MIRRORING_AND_FIXTURES.md b/docs/PROD_TO_DEV_MIRRORING_AND_FIXTURES.md index f0e7cf80..5e62c937 100644 --- a/docs/PROD_TO_DEV_MIRRORING_AND_FIXTURES.md +++ b/docs/PROD_TO_DEV_MIRRORING_AND_FIXTURES.md @@ -1,8 +1,8 @@ # Prod -> Dev mirroring + synthetic shape-coverage fixtures -> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.64` -> **Version:** 0.55.63 - **Date:** May 6, 2026 +> **Version:** 0.55.64 - **Date:** May 6, 2026 > **Scope:** dev-tooling, no API surface change > **Affects:** [api/src/scripts/mirror-prod-to-dev.ts](../api/src/scripts/mirror-prod-to-dev.ts), [api/src/scripts/seed-shape-coverage.ts](../api/src/scripts/seed-shape-coverage.ts), [scripts/mirror-prod-to-dev.ps1](../scripts/mirror-prod-to-dev.ps1) diff --git a/docs/RELEASE_NOTES.md b/docs/RELEASE_NOTES.md index 65fad473..b8e7620a 100644 --- a/docs/RELEASE_NOTES.md +++ b/docs/RELEASE_NOTES.md @@ -1,6 +1,6 @@ # SCIMServer release notes -> **Status:** User-facing reference - **Last verified:** 2026-10-23 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-23 - **Product version:** `0.55.64` These curated notes explain what changes for operators and integrators, how to upgrade, and what remains limited. The [engineering changelog](../CHANGELOG.md) @@ -15,6 +15,15 @@ notes rather than assuming that a patch label makes every rollback lossless. ## Unreleased +### Stacked API advisory preparation: 0.55.64 + +The [actual-consumer compatibility report](API_ADVISORY_CONSUMER_COMPATIBILITY.md) +records proposed qs 6.16.1 and fast-uri 4.2.3 pins, stacked on unmerged +draft #260. Five assessed API advisory records are targeted. The Prisma +development adapter advisory remains blocked pending actual-parent lifecycle +qualification; this is not full advisory clearance or a deployed release. +No API response contract, migration or operator configuration changes. + ### 0.55.61 request-body security dependency patch This draft patch pins body-parser to 2.4.0 and multer to 2.5.0 for the two diff --git a/docs/REMOTE_DEBUGGING_AND_DIAGNOSIS.md b/docs/REMOTE_DEBUGGING_AND_DIAGNOSIS.md index 86e5e45e..b347938e 100644 --- a/docs/REMOTE_DEBUGGING_AND_DIAGNOSIS.md +++ b/docs/REMOTE_DEBUGGING_AND_DIAGNOSIS.md @@ -1,6 +1,6 @@ # Remote Debugging & Diagnosis Guide -> **Status:** User-facing reference - **Last verified:** 2026-10-09 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-09 - **Product version:** `0.55.64` > **Version:** 3.2 - **Source-verified against:** v0.55.36 - **Updated:** 2026-10-01 > Request-history identity and authenticated stream transport re-verified against v0.55.36 on 2026-10-01; the full line-by-line pass dates from v0.53.0. diff --git a/docs/SCHEMA_ATTRIBUTE_CUSTOMIZATION_GUIDE.md b/docs/SCHEMA_ATTRIBUTE_CUSTOMIZATION_GUIDE.md index 70c5ce53..eb755499 100644 --- a/docs/SCHEMA_ATTRIBUTE_CUSTOMIZATION_GUIDE.md +++ b/docs/SCHEMA_ATTRIBUTE_CUSTOMIZATION_GUIDE.md @@ -1,6 +1,6 @@ # Schema Attribute Customization Guide -> **Status:** User-facing reference - **Last verified:** 2026-09-28 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-09-28 - **Product version:** `0.55.64` > **Version**: 1.1 - **Date**: 2026-08-04 - **Status**: Complete (PATCH merge semantics re-verified against `mergeProfilePartial()` on 2026-08-04; the full line-by-line source pass dates from v0.40.0) > **Audience**: Operators, ISV admins, Entra ID integration engineers diff --git a/docs/SCHEMA_CUSTOMIZATION_GUIDE.md b/docs/SCHEMA_CUSTOMIZATION_GUIDE.md index 0b7b652d..d88c8845 100644 --- a/docs/SCHEMA_CUSTOMIZATION_GUIDE.md +++ b/docs/SCHEMA_CUSTOMIZATION_GUIDE.md @@ -10,7 +10,7 @@ effective mutability and response projection. See [reference persistence and migration compatibility](GROUP_MEMBER_REFERENCE_PRESERVATION.md) and [release notes](RELEASE_NOTES.md). -> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.64` > **P7a correctness, included since 0.55.36:** [Declaration and POST/PUT validation](SCIM_P7A_PROFILE_VALIDATION.md) > documents the source changes below, with owned PostgreSQL/InMemory evidence. diff --git a/docs/SOVEREIGN_AND_GOV_CLOUD_DEPLOYMENT.md b/docs/SOVEREIGN_AND_GOV_CLOUD_DEPLOYMENT.md index f6ff3787..10b9a654 100644 --- a/docs/SOVEREIGN_AND_GOV_CLOUD_DEPLOYMENT.md +++ b/docs/SOVEREIGN_AND_GOV_CLOUD_DEPLOYMENT.md @@ -1,8 +1,8 @@ # SCIMServer - Sovereign & Government Cloud Deployment Guide -> **Status:** User-facing reference - **Last verified:** 2026-08-12 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-08-12 - **Product version:** `0.55.64` -> **Version:** 0.55.63 - **Updated:** April 28, 2026 +> **Version:** 0.55.64 - **Updated:** April 28, 2026 > Covers: Azure Government (US), Azure China (21Vianet), Azure BLEU (France), Azure Germany, and custom sovereign environments --- diff --git a/docs/UI_GUIDE.md b/docs/UI_GUIDE.md index b3f9636c..fc90e824 100644 --- a/docs/UI_GUIDE.md +++ b/docs/UI_GUIDE.md @@ -1,8 +1,8 @@ # SCIMServer Web Admin UI Guide -> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.63` +> **Status:** User-facing reference - **Last verified:** 2026-10-16 - **Product version:** `0.55.64` -> **Status:** Active | **Last Updated:** 2026-10-16 | **Version:** 0.55.63 +> **Status:** Active | **Last Updated:** 2026-10-16 | **Version:** 0.55.64 > Single-page React + Fluent UI v9 admin console. Nine pages, one shared app shell, live SSE log stream. > **Endpoint/profile/authentication flows:** [PORTABLE_ENDPOINT_PROFILE_AUTHENTICATION_AND_DISCOVERY_DESIGN.md](PORTABLE_ENDPOINT_PROFILE_AUTHENTICATION_AND_DISCOVERY_DESIGN.md) distinguishes the current Create, Discovery, Connect, endpoint Settings, and global Settings surfaces from the target profile-import workflow. > **Screenshot provenance:** every image below was re-captured on **2026-07-31** from the live **dev** estate (then `scimserver-dev.proudbush-ae90986e.eastus.azurecontainerapps.io`) running **v0.55.6 / Node v24.18.1**, at a pinned 1440x900 viewport, using: diff --git a/docs/strategy/ENGINEERING_LESSONS_AND_PATTERNS.md b/docs/strategy/ENGINEERING_LESSONS_AND_PATTERNS.md index d7cefbcd..0d0fe63f 100644 --- a/docs/strategy/ENGINEERING_LESSONS_AND_PATTERNS.md +++ b/docs/strategy/ENGINEERING_LESSONS_AND_PATTERNS.md @@ -16,6 +16,19 @@ ## 1. The self-improvement loop (how this doc is fed and used) +### A parent-compatible dependency patch needs actual consumer evidence + +An engine range only answers whether Node can load a package, not whether an +exact-pinned parent remains correct. Likewise, a pre-existing forced major +does not make the next forced version semver-compatible. Enumerate locked +and installed owners, assess public API changes, and exercise the real +parent's parser/compiler/lifecycle. Preserve successful baseline behavior +alongside discriminating security RED/GREEN. A toy replacement fixture is +not proof for an actual parent's initialization and shutdown. +The [stacked API advisory patch](../API_ADVISORY_CONSUMER_COMPATIBILITY.md) +keeps the Prisma/Hono adapter blocked because those lifecycle claims cannot +be verified under the no-service-start constraint. + ### Shared override repairs must reach complete-tree acceptance An installed version can satisfy every owner range while Arborist rejects diff --git a/web/package.json b/web/package.json index ccd9896f..3973518d 100644 --- a/web/package.json +++ b/web/package.json @@ -1,7 +1,7 @@ { "name": "scimserver-web", "private": true, - "version": "0.55.63", + "version": "0.55.64", "type": "module", "scripts": { "dev": "vite", From b368331bc356a5e80e682396a5e39df3cead44e3 Mon Sep 17 00:00:00 2001 From: "Prashant Rane (ALLYIS INC)" Date: Thu, 29 Oct 2026 11:50:04 -0600 Subject: [PATCH 2/3] fix(api): import authenticated advisory locks and prove actual consumers CI-only artifact 12918583682 changes only qs 6.16.1 and fast-uri 4.2.3. Approved-feed bytes match locked SHA512 and clean restore preserves both lock hashes. Final actual-consumer focus 57/57, complete API inventory exit 0. Keep Hono compatibility blocked, stacked parent unmerged and all release holds intact. Design accepted: cohesive flat pins; self-improvement applied: actual-consumer boundaries and four independent URI regressions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CHANGELOG.md | 12 +- Session_starter.md | 6 +- api/package-lock.json | 16 +- .../check-api-advisory-consumers.spec.ts | 220 ++++++++++++++++++ docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md | 68 +++++- docs/CONTEXT_INSTRUCTIONS.md | 5 +- web/package-lock.json | 4 +- 7 files changed, 307 insertions(+), 24 deletions(-) create mode 100644 api/src/scripts/check-api-advisory-consumers.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 34c8fb03..3b6b17f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,12 +14,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Select qs 6.16.1 and fast-uri 4.2.3 to address five of the six assessed advisory records. Leave `@hono/node-server` 1.19.15 unchanged because compatibility with the actual Prisma development lifecycle is unproved. -- Add 14 actual-consumer regressions: corrected pre-manifest RED is 11 +- Add 19 actual-consumer and advisory-boundary regressions: pre-manifest RED is 11 failures / three passes. Existing Ajv compiler, Express parser, Superagent serializer and body-parser stream behavior already pass at baseline. - [Public changes, actual ownership, advisory boundaries and execution RCA](docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md). - Full test counts and final protected publication are recorded only after - the authenticated CI locks and clean restore. No deployed release claim. + Authenticated CI run 40923567650 changes exactly two API entries and no + non-root web entry; approved-feed bytes match locked SHA-512. Clean restore + keeps both lock hashes identical and full API npm inventory exits 0. + Final restored focus: 57/57 in three suites, up from 38 parent checks. + Bootstrap units 6,229/214 suites and HTTP 2,514/118 passing suites retain + 42 existing skipped tests and two skipped suites. Final broad protected + Validate counts are recorded in the handoff after execution; + no deployed release claim. ### 0.55.63 preparation - API complete-tree override context validity diff --git a/Session_starter.md b/Session_starter.md index 8b7dcd5d..beb5abee 100644 --- a/Session_starter.md +++ b/Session_starter.md @@ -13,7 +13,11 @@ Corrected RED before manifest edits: 11 failed, three passed, 14 tests. [Compatibility, advisory boundaries and RCA](docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md) records why Hono 2.1.3 remains blocked by unproved actual Prisma lifecycle compatibility. No service is started and no other worktree is owned. -CI-only lock import and final protected validation remain required. +CI-only run 40923567650, artifact 12918583682, changes exactly two API entries +and no non-root web entry. Approved-feed bytes match authenticated SHA-512; +clean API/web restores keep both lock hashes identical. Initial restored +focus is 57/57 in three suites including 19 new checks; complete npm +inventory exits 0 without problems. Final protected Validate remains required. PR #259/#260 are unmerged, #251 and every existing hold remain unchanged. ### Independent API override-context correction (2026-10-29) diff --git a/api/package-lock.json b/api/package-lock.json index 9bca935b..8efa1d0f 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -1,12 +1,12 @@ { "name": "scimserver-api", - "version": "0.55.63", + "version": "0.55.64", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "scimserver-api", - "version": "0.55.63", + "version": "0.55.64", "license": "MIT", "dependencies": { "@nestjs/common": "^11.1.27", @@ -4640,9 +4640,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.1.5.tgz", - "integrity": "sha512-vZeoMRB4epNr7QfdHxel7te/RcX16CxyXI07JCCTFWZA2s4v1azGNESRj+2EoaHSaWFL/Z3GmKT2jF6A202jLg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.2.3.tgz", + "integrity": "sha512-I1PXwP5eAhlNlcdpjt9CgB59op2ZvZfxw+BkqGFVIUOgNpCVTcTqp3HhTX7brxj5vsip+nSY4nTvff+eIA76hg==", "devOptional": true, "funding": [ { @@ -7436,9 +7436,9 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.16.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz", - "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", + "version": "6.16.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.1.tgz", + "integrity": "sha512-5Px6J7rfHBAGUhNQ3es4YzcOdBBw0SDcVtThJml4RdnKw4tKs2epA0kPZ+K8X+WiHktT93RHVcQ/3ym5aTCgtg==", "license": "BSD-3-Clause", "dependencies": { "es-define-property": "^1.0.1", diff --git a/api/src/scripts/check-api-advisory-consumers.spec.ts b/api/src/scripts/check-api-advisory-consumers.spec.ts new file mode 100644 index 00000000..c0cc214e --- /dev/null +++ b/api/src/scripts/check-api-advisory-consumers.spec.ts @@ -0,0 +1,220 @@ +import { readFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { Readable } from 'node:stream'; +import { satisfiesGhsaRange } from './check-dependency-pins'; + +type Package = { + version: string; + dependencies?: Record; + resolved?: string; + integrity?: string; +}; +type Uri = { + parse(value: string): { scheme?: string; host?: string; error?: string }; + normalize(value: string, options?: { reference: string }): string; + serialize(value: { path: string; scheme?: string }, options?: { reference: string }): string; + resolve(base: string, relative: string): string; +}; +type Query = { + parse(value: string, options?: Record): unknown; + stringify(value: unknown, options?: Record): string; +}; + +const apiRoot = resolve(__dirname, '../..'); +const lock = JSON.parse(readFileSync(resolve(apiRoot, 'package-lock.json'), 'utf8')) as { + packages: Record; +}; +const manifest = JSON.parse(readFileSync(resolve(apiRoot, 'package.json'), 'utf8')) as { + overrides: Record; +}; +const semver = require('semver') as { satisfies(version: string, range: string): boolean }; +const ajvOwner = 'node_modules/@prisma/streams-local/node_modules/ajv'; +const consumerModule = (owner: string, name: string): string => + require.resolve(name, { paths: [resolve(apiRoot, owner)] }); +const uri = require(consumerModule(ajvOwner, 'fast-uri')) as Uri; + +describe('API advisory pins and actual installed consumers', () => { + it.each([ + ['GHSA-6pq8-jhm2-2vcw', '6.16.0', '6.16.1', '>= 6.7.0, <= 6.16.0'], + ['GHSA-w74x-v6f9-j3xg', '4.1.5', '4.2.3', '>= 4.0.0, < 4.2.3'], + ['GHSA-xhq7-xmqj-769h', '4.1.5', '4.2.3', '>= 4.0.0, < 4.2.3'], + ['GHSA-wjr9-j795-jxcr', '4.1.5', '4.2.3', '>= 4.0.1, < 4.2.3'], + ['GHSA-333x-w4r6-6crp', '4.1.5', '4.2.3', '>= 4.0.0, < 4.2.3'], + ])('checks both sides of the published %s boundary', (_id, before, patched, range) => { + expect(satisfiesGhsaRange(before, range)).toBe(true); + expect(satisfiesGhsaRange(patched, range)).toBe(false); + }); + + it.each([ + ['qs', '6.16.1', '>= 6.7.0, <= 6.16.0'], + ['fast-uri', '4.2.3', '>= 4.0.0, < 4.2.3'], + ])('pins every %s occurrence outside its advisory boundary', (name, version, range) => { + expect(manifest.overrides[name]).toBe(version); + const occurrences = Object.entries(lock.packages).filter(([path]) => + path === `node_modules/${name}` || path.endsWith(`/node_modules/${name}`), + ); + expect(occurrences.map(([path]) => path)).toEqual([`node_modules/${name}`]); + for (const [, entry] of occurrences) { + expect(entry.version).toBe(version); + expect(satisfiesGhsaRange(entry.version, range)).toBe(false); + expect(entry.resolved).toBe(`https://registry.npmjs.org/${name}/-/${name}-${version}.tgz`); + expect(entry.integrity).toMatch(/^sha512-[A-Za-z0-9+/]+=*$/); + } + }); + + it('resolves every declared qs owner to the compatible installed patch', () => { + const owners = Object.entries(lock.packages).flatMap(([path, entry]) => + entry.dependencies?.qs ? [[path, entry.dependencies.qs]] : [], + ); + expect(owners).toEqual([ + ['node_modules/body-parser', '^6.16.1'], + ['node_modules/express', '^6.14.0'], + ['node_modules/superagent', '^6.14.1'], + ]); + for (const [path, range] of owners) { + const owner = JSON.parse(readFileSync(resolve(apiRoot, path, 'package.json'), 'utf8')) as Package; + expect(owner.dependencies?.qs).toBe(range); + expect(semver.satisfies('6.16.1', range)).toBe(true); + const installedPath = consumerModule(path, 'qs/package.json'); + expect(installedPath).toBe(resolve(apiRoot, 'node_modules/qs/package.json')); + expect((JSON.parse(readFileSync(installedPath, 'utf8')) as Package).version).toBe('6.16.1'); + } + }); + + it('records the real Ajv owner and does not mistake an existing forced major for semver acceptance', () => { + const owners = Object.entries(lock.packages).flatMap(([path, entry]) => + entry.dependencies?.['fast-uri'] ? [[path, entry.dependencies['fast-uri']]] : [], + ); + expect(owners).toEqual([[ajvOwner, '^3.0.1']]); + const owner = JSON.parse(readFileSync(resolve(apiRoot, ajvOwner, 'package.json'), 'utf8')) as Package; + expect(owner.version).toBe('8.20.0'); + expect(owner.dependencies?.['fast-uri']).toBe('^3.0.1'); + expect(semver.satisfies('4.2.3', '^3.0.1')).toBe(false); + const installedPath = consumerModule(ajvOwner, 'fast-uri/package.json'); + expect(installedPath).toBe(resolve(apiRoot, 'node_modules/fast-uri/package.json')); + expect((JSON.parse(readFileSync(installedPath, 'utf8')) as Package).version).toBe('4.2.3'); + }); + + it.each(['body-parser', 'express', 'superagent'])( + 'keeps %s query parsing and serialization correct and handles non-callable comma elements', + owner => { + const qs = require(consumerModule(`node_modules/${owner}`, 'qs')) as Query; + expect(qs.parse('filter=userName%20eq%20%22Ada%22&attributes=userName%2Cname&startIndex=1')) + .toEqual({ filter: 'userName eq "Ada"', attributes: 'userName,name', startIndex: '1' }); + expect(qs.parse('profile[name]=Ada&tags[]=one&tags[]=two&__proto__[polluted]=yes', { + allowPrototypes: true, + depth: 32, + arrayLimit: 100, + })).toEqual({ profile: { name: 'Ada' }, tags: ['one', 'two'] }); + expect(qs.stringify({ filter: 'userName eq "Ada"', attributes: ['userName', 'name'] })) + .toBe('filter=userName%20eq%20%22Ada%22&attributes%5B0%5D=userName&attributes%5B1%5D=name'); + expect(qs.stringify({ values: [{ toString: 'not callable' }] }, { + arrayFormat: 'comma', + })).toBe('values=%5Bobject%20Object%5D'); + }, + ); + + it('uses the real Express query parser and Superagent form serializer', () => { + const express = require('express') as { + (): { + set(name: string, value: string): void; + get(name: string): (input: string) => unknown; + }; + }; + const app = express(); + app.set('query parser', 'extended'); + expect(app.get('query parser fn')('filter=active%20eq%20true&name[givenName]=Ada')) + .toEqual({ filter: 'active eq true', name: { givenName: 'Ada' } }); + const superagent = require('superagent') as { + serialize: Record string>; + }; + expect(superagent.serialize['application/x-www-form-urlencoded']({ + filter: 'active eq true', attributes: ['userName', 'name'], + })).toBe('filter=active%20eq%20true&attributes=userName&attributes=name'); + }); + + it('parses a real body-parser URL-encoded request stream without opening a server', async () => { + const body = 'profile[name]=Ada&tags[]=one&tags[]=two&__proto__[polluted]=yes'; + const request = Object.assign(Readable.from([Buffer.from(body)]), { + headers: { + 'content-type': 'application/x-www-form-urlencoded', + 'content-length': String(Buffer.byteLength(body)), + }, + method: 'POST', + body: undefined as unknown, + }); + const bodyParser = require('body-parser') as { + urlencoded(options: { extended: boolean }): ( + req: typeof request, response: object, next: (error?: Error) => void + ) => void; + }; + await new Promise((complete, reject) => { + bodyParser.urlencoded({ extended: true })(request, {}, error => error ? reject(error) : complete()); + }); + expect(request.body).toEqual({ profile: { name: 'Ada' }, tags: ['one', 'two'] }); + }); + + it('compiles external, relative, fragment and recursive references with the actual nested Ajv', () => { + const Ajv = require(resolve(apiRoot, ajvOwner)) as new (options: Record) => { + opts: { uriResolver: Uri }; + addSchema(schema: unknown): void; + compile(schema: unknown): ((data: unknown) => boolean) & { + errors: { instancePath: string; keyword: string }[] | null; + }; + }; + const ajv = new Ajv({ allErrors: true }); + expect(ajv.opts.uriResolver).toBe(uri); + ajv.addSchema({ + $id: 'https://schemas.example/common.json', + definitions: { + name: { type: 'string', minLength: 2 }, + node: { + type: 'object', + properties: { name: { $ref: '#/definitions/name' }, child: { $ref: '#/definitions/node' } }, + required: ['name'], + additionalProperties: false, + }, + }, + }); + const validate = ajv.compile({ + $id: 'https://schemas.example/team/user.json', + type: 'object', + properties: { profile: { $ref: '../common.json#/definitions/node' } }, + required: ['profile'], + additionalProperties: false, + }); + expect(validate({ profile: { name: 'Ada', child: { name: 'Grace' } } })).toBe(true); + expect(validate({ profile: { name: 'A', child: { name: 7 }, extra: true } })).toBe(false); + expect(validate.errors).toEqual(expect.arrayContaining([ + expect.objectContaining({ instancePath: '/profile/name', keyword: 'minLength' }), + expect.objectContaining({ instancePath: '/profile/child/name', keyword: 'type' }), + expect.objectContaining({ instancePath: '/profile', keyword: 'additionalProperties' }), + ])); + expect(() => ajv.compile({ $ref: 'missing.json#/absent' })).toThrow(/resolve reference/); + }); + + it('rejects encoded schemes through the actual Ajv URI resolver', () => { + expect(uri.parse('%6Aavascript:alert(1)').error).toBe('URI scheme is malformed.'); + expect(uri.normalize('%6Aavascript:alert(1)')).toBe('%6Aavascript:alert(1)'); + expect(() => uri.resolve('https://schemas.example/', '%u006Aavascript:alert(1)')).toThrow(); + }); + + it('preserves relative-reference meaning before actual Ajv URI resolution', () => { + const base = 'https://schemas.example/team/schema.json'; + for (const relative of ['../common.json', 'a/../common.json', './child:part']) { + expect(uri.resolve(base, uri.normalize(relative))).toBe(uri.resolve(base, relative)); + } + expect(uri.normalize('../common.json')).toBe('../common.json'); + }); + + it('rejects host confusion through the actual Ajv URI resolver', () => { + expect(uri.parse('http://a@b@evil.example/').error).toBeDefined(); + expect(uri.parse('http://good\tevil.example/').error).toBeDefined(); + }); + + it('escapes suffix colons through the actual Ajv URI resolver', () => { + const suffix = uri.serialize({ scheme: 'x', path: 'javascript:alert(1)' }, { reference: 'suffix' }); + expect(suffix).toBe('javascript%3Aalert(1)'); + expect(uri.parse(suffix).scheme).toBeUndefined(); + }); +}); diff --git a/docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md b/docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md index 62d8e791..2ce76f60 100644 --- a/docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md +++ b/docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md @@ -103,12 +103,53 @@ compatibility paths already passed on old dependencies; exact pins, installed versions, comma serialization and all four URI mechanisms failed as expected. Logs are retained under `test-results/api-advisory-pins-20261029/`. -CI-only lock generation, authenticated digest verification, approved-feed byte -verification, clean restore, final GREEN and normal protected Validate -publication are required before this draft can claim patch qualification. -Bootstrap publication, if needed to dispatch the unchanged lock workflow, -is not final dependency qualification. No hosted PR-to-master matrix is -inferred when the draft uses a stacked base. +Follow-up fixture correction distinguishes `parse` returning an error from +`normalize` preserving malformed input, and tests suffix serialization with +an explicit input scheme that is omitted from output. The public advisory's +string-normalization example does not reproduce on the patch. Replaying the +real old 4.1.5 approved-feed bytes produces four URI assertion failures and +one Ajv compiler pass; restoring 4.2.3 passes all five. This is separate from +the original pre-manifest RED, not a rewritten account of it. Comma-format +serialization also asserts the full hardened output, not merely no exception. + +The final regression includes five explicit published advisory boundaries, +for 19 new tests. The first complete authenticated-restore focus passed 52/52 +before adding those boundary assertions, including the existing 38 regressions. +The final focus passes 57/57 in three suites. Lock provenance, documentation +freshness, documentation content and diff whitespace checks also pass. +Protected Validate totals are retained in the handoff after execution. + +### Clean CI lock and restore receipts + +- Unchanged regeneration workflow run + [40923567650](https://github.com/pranems/SCIMServer/actions/runs/40923567650) + uses exact bootstrap source `eb797fd69ef2b371e3a1812198fe6f159eeafc1c`. +- Artifact `12918583682` ZIP SHA-256: + `bb3b81a1a4dd2eeb14f04e4838d50f6f883fae666057d0ece60e05d42ff29edf`. + Authenticated GitHub metadata and downloaded bytes agree. +- API lock SHA-256: + `01c0c63e29db93f5520195d3bfccf3b22fedbe20bcb1ca77effb0bccf136209e`. + Web lock SHA-256: + `b0c972aa28b428439e46913847b5e25ac85ae5395e5ed3ab6078c1ad33e629c9`. +- Exactly two non-root API entries change: qs and fast-uri. Zero non-root + web entries change. Only product/root versions change otherwise. +- Approved-feed tarball bytes match both authenticated locked SHA-512 values. + Missing SHA-512 metadata from the proxy was not treated as success. +- CI measured ages at 2026-10-29T17:40:35.970Z: qs 14.815 days, + fast-uri 9.784 days, both above the unchanged seven-day floor. +- Physical ownership checks precede restore. Clean `npm ci` in API and web + succeeds through the existing corporate registry, with both tracked locks + byte-identical afterwards. The actual complete API inventory exits 0 + with no problems and empty stderr. + +The normal Fast bootstrap push passes 25 gates, 6,229 API units in 214 suites +and 2,514 HTTP tests in 118 passing suites (42 existing skipped tests and two +skipped suites). This bootstrap uses provisional dependencies, not final +qualification. Hosted bootstrap Build Test Image `40923545248` correctly +fails `npm ci` on the two intentionally stale lock entries; its failure +receipt is retained. The final normal Validate push owns broad applicable +gates after the clean CI-lock restore. No PR-to-master matrix is inferred +when the draft uses a stacked base. ## Execution issues and root-cause analysis @@ -116,11 +157,20 @@ inferred when the draft uses a stacked base. |---|---|---|---| | AC-1 / test correctness / Low | Initial Superagent fixture called its private query finalizer before the real request builder serializes queued objects. URL stayed unchanged. | Use the actual public form serializer, assert complete values, and retain corrected RED before manifests change. No network request is needed. | First focused RED / same | | AC-2 / tooling / Low | Comparing Hono v1.19.15 to v2.1.3 returned HTTP 404 because that comparison ref is unavailable. | Read authenticated public v2 release notes and patch release plus actual installed parent bundle. Do not equate failed lookup with compatibility. | Assessment / same | +| AC-3 / test correctness / Medium | Initial URI fixtures assumed normalize throws and that a scheme-free suffix object discriminates the colon defect. The patch preserves malformed input; that object was already safe on old bytes. | Assert parse's actual error, normalization preservation and resolve's throw separately. Supply an explicit omitted output scheme for suffix serialization. Real old-byte replay fails all four mechanisms, while the actual Ajv compiler remains green. | First provisional GREEN / same | +| AC-4 / dependency tooling / Low | Bootstrap install without a lockfile write changed the provisional local tree and left one platform-related extraneous package. | Remove that owned extraneous directory, retain full inventory output, and replace the entire provisional installation with clean npm ci from authenticated CI locks. Bootstrap is never final consumer evidence. No lockfile was generated locally. | Focused inventory / same | +| AC-5 / CI bootstrap / Low | Hosted bootstrap npm ci rejects the deliberately stale qs/fast-uri entries. | Dispatch the existing regeneration workflow from the protected source, authenticate run and archive, allow only the two intended entries, then restore and publish normally. | Hosted install / expected before authenticated artifact | +| AC-6 / documentation / Low | Header freshness repair left the README badge and source-coupled release notes requiring explicit updates. A first index edit assumed the wrong heading. | Use actual headings, update badge and release narrative, then pass existing freshness and content gates. | Bootstrap static audit / same | +| AC-7 / tooling / Low | A source-snippet command had shell quoting error; one guessed documentation command/file did not exist, and gh run view rejected a path JSON field. | Use exact discovered filenames and GitHub REST run metadata for workflow path. Retain failed receipts without interpreting them as package failures. | Assessment / same | Provenance: this bounded execution retains raw command logs and public metadata -in the ignored evidence directory. Final handoff reconciles tool failures, -assertions and publication receipts; no full-transcript reconciliation is -claimed unless the complete transcript is available. +in the ignored evidence directory. Tool failures, assertion failures and +publication receipts were reconciled against this execution's available +commands and retained logs. `VSCODE_TARGET_SESSION_LOG` is not present, so a +full debug-transcript reconciliation could not be performed and is not claimed. +The original assertion assumptions were corrected as AC-3, not dismissed. +Existing Jest worker/forced-exit warnings and competing-renderer diagnostics +remain inherited holds, not new runtime regressions or resolved problems. ## Self-improvement and design disposition diff --git a/docs/CONTEXT_INSTRUCTIONS.md b/docs/CONTEXT_INSTRUCTIONS.md index ebe18d5d..8df5bec6 100644 --- a/docs/CONTEXT_INSTRUCTIONS.md +++ b/docs/CONTEXT_INSTRUCTIONS.md @@ -14,7 +14,10 @@ on draft #260 exact head `6eb1b59cb1a8ea324bb1a32b17355fabc605279d`, not master or web #259. [Consumer compatibility and RCA](API_ADVISORY_CONSUMER_COMPATIBILITY.md) records qs 6.16.1, fast-uri 4.2.3, actual-parent RED and the unchanged Hono adapter compatibility blocker. Ajv's forced 4.x remains a documented -range exception, not semver acceptance. No merge or deploy is authorized. +range exception, not semver acceptance. CI lock run 40923567650 changes only +the two API packages; authenticated archive and approved-feed SHA-512 agree. +Clean restored final focus 57/57, complete inventory exit 0. Protected +Validate is recorded separately after execution. No merge or deploy. **2026-10-29 independent API correction:** proposed 0.55.63 branches from master `727860866c53c7ec8d01d1ff5bae858f80a1715d`, excluding draft #259. diff --git a/web/package-lock.json b/web/package-lock.json index 7afeb992..20bf8a4b 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "scimserver-web", - "version": "0.55.63", + "version": "0.55.64", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "scimserver-web", - "version": "0.55.63", + "version": "0.55.64", "dependencies": { "@fluentui/react-components": "^9.74.2", "@fluentui/react-icons": "^2.0.331", From f4fcfe3ccac83de6548ed9991ed44048ee8d660a Mon Sep 17 00:00:00 2001 From: "Prashant Rane (ALLYIS INC)" Date: Thu, 29 Oct 2026 12:02:47 -0600 Subject: [PATCH 3/3] test(api): keep advisory consumer fixture lint-clean Remove the redundant request-body assertion discovered during consolidation and retain the interrupted pre-publication receipt. Focused ESLint exits 0 without warnings and all 57 dependency checks pass. No runtime or dependency change; design accepted as cohesive, static-quality improvement applied. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- api/src/scripts/check-api-advisory-consumers.spec.ts | 2 +- docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/api/src/scripts/check-api-advisory-consumers.spec.ts b/api/src/scripts/check-api-advisory-consumers.spec.ts index c0cc214e..8eec2b0c 100644 --- a/api/src/scripts/check-api-advisory-consumers.spec.ts +++ b/api/src/scripts/check-api-advisory-consumers.spec.ts @@ -141,7 +141,7 @@ describe('API advisory pins and actual installed consumers', () => { 'content-length': String(Buffer.byteLength(body)), }, method: 'POST', - body: undefined as unknown, + body: undefined, }); const bodyParser = require('body-parser') as { urlencoded(options: { extended: boolean }): ( diff --git a/docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md b/docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md index 2ce76f60..c1b1f795 100644 --- a/docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md +++ b/docs/API_ADVISORY_CONSUMER_COMPATIBILITY.md @@ -162,6 +162,7 @@ when the draft uses a stacked base. | AC-5 / CI bootstrap / Low | Hosted bootstrap npm ci rejects the deliberately stale qs/fast-uri entries. | Dispatch the existing regeneration workflow from the protected source, authenticate run and archive, allow only the two intended entries, then restore and publish normally. | Hosted install / expected before authenticated artifact | | AC-6 / documentation / Low | Header freshness repair left the README badge and source-coupled release notes requiring explicit updates. A first index edit assumed the wrong heading. | Use actual headings, update badge and release narrative, then pass existing freshness and content gates. | Bootstrap static audit / same | | AC-7 / tooling / Low | A source-snippet command had shell quoting error; one guessed documentation command/file did not exist, and gh run view rejected a path JSON field. | Use exact discovered filenames and GitHub REST run metadata for workflow path. Retain failed receipts without interpreting them as package failures. | Assessment / same | +| AC-8 / static quality / Low | The first final-push lint run exposed one new unnecessary type assertion in the request-stream fixture, raising warnings from 507 to 508 despite zero errors. | Stop the owned publication before push, remove the redundant assertion, run focused ESLint, then publish normally with the unchanged protected Validate hook. Preserve the interrupted receipt. No warning ceiling is raised. | Consolidation lint / focused new-file lint could have caught it earlier | Provenance: this bounded execution retains raw command logs and public metadata in the ignored evidence directory. Tool failures, assertion failures and