Repository navigation
Fix center safety bootstrap, scoped actions and profile load races; restore strict security gate - #409
Merged
Conversation
…ary review workflows
…ning integrity tests
…d through the authorized connector
…ry repair workflow
…lication bootstrap
sultanasiri001-sys
marked this pull request as draft
October 2, 2026 08:31
sultanasiri001-sys
marked this pull request as ready for review
October 3, 2026 16:05
This was referenced Oct 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Production release completed — 2026-10-03
PR #409 merged through the normal API with expected head
ee6b846e34e15388e167f104adb63edbf29e2319; merge commita294c9dfd2f6bc76410906703cac75bfd6bd169c.Both native Render services are LIVE on that merge commit:
dep-db0igd60tbcc7380ejs0, live at 16:08:25 UTC. Build command:node ../../scripts/build-api-release.mjs(rootDir apps/api).dep-db0ihdp42hec73e83a70, live at 16:10:00 UTC. Build command:node scripts/build-web-release.mjs.20261003080000_center_license_attachmentswas applied successfully, followed by successful application startup.This section supersedes historical no-merge/no-deploy statements below. The next work starts from the live release above; mobile remediation, authenticated center acceptance, and previously documented external integration/restore boundaries remain open.
Mobile follow-up — 2026-10-03, after production release
A fresh mobile audit still fails with 19 high / 10 moderate / 0 critical dependency entries. Registry verification: node-forge latest 1.4.0, braces latest 3.0.3; both GitHub advisories still list no patched version. Forge PR #1152 is still open. Latest Expo 57.0.26 still depends on @expo/cli ^57.0.27, whose dependencies include node-forge ^1.3.3 and @expo/code-signing-certificates ^0.0.6. Current React Native 0.86.3 independently reaches braces through community-cli-plugin → metro → metro-file-map → micromatch; latest micromatch 4.0.8 still requires braces ^3.0.3. Thus upgrading Expo to the newest patch or removing Expo alone does not remove both roots. React Native latest 0.87.1 was observed but was not installed or represented as Expo-compatible. No dependency or audit-policy changes, unsafe forced upgrade, fork substitution, or mobile release were made. Next mobile release requires a verified compatible fix/removal for both roots and passing functional + security gates.
Latest head — native Render build parity (
ee6b846)Actual Render service inspection found native Node deployments, not the Docker Blueprint: API rootDir apps/api runs a broad npm install command; web builds from root. Prepared exact replacements: API
node ../../scripts/build-api-release.mjs; webnode scripts/build-web-release.mjs. They use scoped committed installs and fail-closed release audits; API pruning retains generated Prisma engines and validates actual runtime packages. Phase 11 now executes both native build scripts and tests native API/PostgreSQL readiness in addition to both Docker images.5322463passed all 11 applicable web/API/functional workflows; the independent mobile security workflow remained failed as designed. Exact-head CI verified foree6b846e34e15388e167f104adb63edbf29e2319: all 11 applicable web/API and functional workflows pass. API run 37114284237: 340/340 center HTTP/PostgreSQL assertions; Web run 37114284208: 175/175 browser plus 4/4 focused notifications. Phase 11 run 37114284256 passed both Docker images, both exact native Render build scripts, runtime inventory/Prisma retention, and native API/PostgreSQL readiness. Security audit and Dependency lock audit both pass with zero web/API findings. Independent mobile security remains failed with full report retention. Further permitted GitHub reads show main protected:false, empty required checks and no rulesets; no protection settings changed. Render has commit-triggered auto-deploy; its connector cannot edit build commands. No merge/deployment until the actual native build configuration is aligned through an approved supported fallback.Latest continuation — approved independent release channels (
5322463)User approved proceeding after the explicit proposal to separate web/API releases from blocked mobile releases. Web/API/root are now installed, tested, typechecked, built and audited as their own release; development/build dependencies remain in the audit. Mobile keeps independent functional validation and a failing security workflow that also retains the full unfiltered repository audit. No advisories are waived or hidden.
The shared fail-closed audit validator has focused error/severity regression tests. Lock validation uses npm ci and rejects lock mutation. Pages publishing runs the web/API audit before artifact upload. Prior API image physical isolation remains unchanged.
Local checks: web/API audit zero findings; mobile and repository audits both reject 19 high/10 moderate/0 critical entries; validator and repository security controls pass. Exact-head CI pending. No merge, deploy or branch-protection changes. Branch-protection inspection returned GitHub 403; release rules must not be bypassed. Current policy:
docs/RELEASE_CHANNELS_2026-10-03.md; earlier all-project hold statements below are historical and superseded only for web/API.Latest continuation — API dependency boundary (
ff9f10d)Root cause: both Dockerfiles installed all workspaces and shipped mobile tooling in the API runtime. Both images now install only API dependencies, use a separate production dependency stage, and preserve locally generated Prisma engines/client. Prisma is correctly runtime-classified because Render startup runs migrations. No resolved package versions changed.
Local isolated runtime inventory: 247 packages; no Expo/React Native/Metro/node-forge/braces/Playwright/Nest CLI; scoped API audit zero vulnerabilities. AppModule/generated Prisma/CLI checks passed. Docker is unavailable locally; exact-head CI now builds both images, inventories actual files, checks offline CLI and non-root/read-only PostgreSQL readiness. Exact-head CI verified for
ff9f10d80270df1f7269b6f5a972710c5a755759: Phase 11 image run 37112966140 passed both Docker builds, actual-file boundary inventories, offline Prisma engine/CLI checks, zero-vulnerability API image audit, and non-root/read-only startup with disposable PostgreSQL readiness. API run 37112966097 passed (340/340 center assertions); Web run 37112966143 passed 175/175 plus 4/4 notifications; Mobile validation passed. Nine of eleven workflows pass. Full Security audit 37112966139 and Dependency lock audit 37112966114 still fail on the mobile graph, as intended; neither was weakened.The full repository security audit is unchanged and remains blocking for the unresolved mobile dependency chain. This removes actual accidental API shipping; it is not an audit exemption or mobile remediation. No merge/deployment. Root-cause report:
docs/API_DEPENDENCY_BOUNDARY_2026-10-03.md.Latest continuation — license registration race (
ea81833)Center registration now atomically matches the validated attachment ID, validity dates and updatedAt when changing DRAFT to REGISTERED. A concurrent edit returns 409 without a registration success audit; a fresh request can retry. Existing non-center callers retain the canonical registration contract.
Added two deterministic real-PostgreSQL/HTTP interleavings, including equal timestamp precision, to the center suite. Local API typecheck/build, script syntax and diff checks passed. The server change at
41b0cd3passed API CI with 340/340 center assertions. Its browser run passed 174/175; the prior role-revocation test clicked a dashboard switch after role freshness removed it.ea81833changes only that test to trigger the real visibility-refresh path and assert revocation before using the remaining switcher. No product UI code or denial assertion was removed. Local browser launch was unavailable because Chromium is not installed. Exact-head CI verified forea818330959f5557d548632a51e7ff9d2c9bd0ed: API run 37112040671 passed, including 340/340 center HTTP/PostgreSQL assertions and the TEXT/UUID migration checks; Web run 37112040640 passed 175/175 browser tests plus 4/4 focused notifications. Eight of nine workflows passed. Security audit 37112040698 remains failed; dependency manifests/lock and strict gate were not changed. Earlier evidence below is historical. Security hold remains; no merge or deployment.Release hold — dependency security remediation required
Draft. Do not merge or deploy while the independent dependency Security audit fails.
Latest continuation — 2026-10-03
Head:
b17f023a4b112e0af0ae4f85cf74ed679d3548ab.Base/main:
830d1be035f1d4c48e9a92f8cccbf86db910b8bc.Center license internal review workflow
The portal now supports explicit registration/attachment locking, routing to a separate active unit, independent reviewer assignment and APPROVE/REJECT decisions. Four new center-scoped endpoints require the current ACTIVE DIVE_CENTER role and managed-center record/routing ownership before delegating to the canonical AdministrativeAffairsPersistenceService. Registration requires attached evidence/dates and a matching file digest. Registration and routing are separate user actions, not an atomic combined operation.
Portal reviewer candidates are active OWNER/ADMIN members with active accounts and ACTIVE DIVE_CENTER access whose selected center matches this center; requester self-assignment is rejected. Other scoped admin reviewers retain their existing administrative workflow. No permissions are granted. The assigned non-requester alone can decide, final decisions cannot be overwritten/reassigned, and canonical actor audit events remain intact.
All review rows remain visible, latest first. The UI consumes server-computed decision permission and filtered reviewer options, reauthorizes every mutation and hides finalized controls. Reviewer display names remain in historical rows after later role revocation; eligibility changes affect future options, not recorded identity. Internal review does not verify the issuer or activate regulatory approval.
Center license creation and renewal
Managers can create DRAFT regulatory records in an active unit belonging to their managed center. Reference, subject and record type are validated; ownership, organization and status are server-controlled. Creation and actor audit commit atomically, and concurrent duplicate references yield one record plus a 409.
A separate renewal endpoint accepts an owned non-DRAFT record and a new reference/subject. It inherits the source type/unit but no attachment, validity dates, review or approval. The old record remains unchanged. Audit metadata records source ID/reference; no further migration is required. The web panel supports creation, renewal, immediate attachment editing and duplicate-error correction with fresh authorization before writes.
Registration/routing/assignment/decision UI is now implemented as described above. Creation/renewal alone is not approval.
Center license attachment and validity
Managers can now upload PDF/PNG/JPEG attachments (up to 2 MB) and ordered issue/expiry dates to existing owned DRAFT regulatory records. The API validates encoding/signature, parses PDFs, calculates SHA-256, deduplicates within the center, and atomically links the file/dates with an actor audit event. Registered/archived records are immutable through this endpoint. Downloads enforce fresh center authorization, scoped record/asset ownership and digest integrity, with attachment disposition and private/no-store caching.
The web panel uploads/downloads after fresh authorization, shows date validity separately from the latest internal administrative review outcome, and removes the upload form after registration. Existing administrative registration, routing, assignment and independent decision endpoints remain the review workflow. Internal approval is not issuer/regulatory verification.
A new forward migration adds nullable attachment/date fields and follows the actual TEXT/UUID asset-key type. The exact migration passed isolated tests for both types, FK integrity, date ordering, deletion restrictions and legacy null records. No production migration was executed; release code and schema together only after security clearance.
Scope: new and existing DRAFT records, with separate renewal drafts. Registration, routing, assignment and decision screens now complete the internal portal path; production/manual acceptance and external verification remain open. This is not a malware scanner or external license verification integration.
Document lifecycle version race
A concurrent DRAFT revision could commit after transition's initial read but before its transaction; status-only checking then submitted the changed version. A local execution of the actual service reproduced version 2 being submitted after reading version 1. Transition now checks status and version in the transaction and conditional update. The same reproduction rejects without writes.
The new deterministic PostgreSQL regression commits the competing revision through the HTTP API, then executes the original transition transaction. Stale submit is rejected with no transition event; DRAFT v2, revisions and reference are preserved; a fresh HTTP submit succeeds with exactly one v2 event. This guards the server-side interleaving, not an as-yet-unimplemented client expected-version contract.
License attachment scope is described above; external regulatory approval remains open. Existing document signing is not claimed as qualified electronic-signature acceptance.
Server-side center authorization
The center API previously authenticated the account and checked active OWNER/ADMIN membership, but did not require an ACTIVE DIVE_CENTER role. Direct API access could therefore continue after the portal role was suspended. A local reproduction executing the actual service reached both protected safety queries with zero role checks.
The shared managedCenter boundary now checks the exact current DIVE_CENTER assignment before membership or data access. Every center route retains the existing organization and manager-membership isolation. An unrelated active role does not substitute for the required role.
The isolated HTTP/PostgreSQL suite covers all 20 center routes across five inactive role states and a missing assignment, same-token restoration of the non-equipment reads, and metadata/license isolation between two real test centers. It retains all earlier safety assertions. Equipment coverage now also executes 70 additional assertions through real HTTP/PostgreSQL: two-center isolation, guest/staff/foreign write denials, closed/foreign trips, missing/failed/expired inspections, all seven movement types, permanent retirement and audit linkage for each successful movement. Document tests establish list privacy, not upload/download/signature/approval acceptance.
Equipment inspection and audit repair
Center CHECK_OUT previously bypassed the canonical inspection/service policy evaluation and did not record the inventory audit event. It now reuses EquipmentInspectionService and writes EQUIPMENT_INVENTORY_MOVED atomically with the movement and stock update. REVIEW/DISABLED policy behavior stays aligned with the existing inventory service.
Center SQL binds organization identifiers to the actual EquipmentBarcode column type, supporting TEXT and UUID without casting the indexed column. The CI fixture verifies a TEXT foreign key, then UUID query compatibility; it is not a production schema/FK migration rehearsal.
Dependency blocker
The current lockfile audit reports 19 high-rated affected dependency entries, 10 moderate, 0 critical. These are dependency-entry counts. The high roots are
node-forge <=1.4.0(GHSA-86w9-cpqp-85rv / CVE-2026-85393) andbraces <=3.0.3(GHSA-vfj7-8cjw-p6xm / CVE-2026-93687).Registry verification on 2026-10-03: latest node-forge is 1.4.0; latest braces is 3.0.3. Expo 57.0.26's CLI 57.0.27 still depends on node-forge, as does current @expo/code-signing-certificates. micromatch 4.0.8 still depends on braces. A compatible published upgrade removing the blockers was not established; upstream forge PR #1152 remains open. No manifests, lockfile, audit policy, package exceptions, forced downgrade or unreviewed replacement were introduced in this continuation.
Existing PR repairs retained
Verification
LOCAL: Prisma generation, API typecheck/build, web static checks/build, regression script syntax and whitespace checks passed.
Eight of nine workflows passed on this exact head. Center API: 328/328; browser: 175/175 plus separate notifications 4/4. Security audit remains the release blocker.
API job
111167507695; Web job111167508065. Visual artifacts: public11270061540, portal11269901902, account11270116367. Artifact retention does not claim manual review. Main was rechecked at830d1be; no production migration/deployment was performed.Test stabilization: native review-form submission isolates authorization assertions from focus/scroll preemption; positive click-flow tests remain. The existing professional-profile test now explicitly refreshes/enforces revoked access, asserts dashboard removal, then uses the remaining switcher and asserts the instructor option is disabled. No production behavior or denial/privacy assertions were removed.
Production and remaining acceptance
Both services were last verified LIVE on
830d1beand follow main. No merge, deployment trigger, production-data mutation, environment change, role activation or external-provider activation was performed. Deployment metadata and green uptime are not full production functional acceptance.Resolve both security roots without weakening the gate. Review visual artifacts and complete document/license lifecycles, finance/reporting and production acceptance before claiming whole-center closure. Previously accepted storage setup and internal professional-portal scope must not be automatically reopened.
Production restore/PITR remains unverified despite issue #369 being marked closed: its evidence is a synthetic isolated restore only. External certification, emergency dispatch, Nafath, regulatory integrations and provider acceptance remain separate closure boundaries.
Detailed continuation:
docs/CENTER_PORTAL_REVIEW_2026-10-03.md.Historical checkpoint: head
9d7108apassed 154 browser tests with 4 high / 11 moderate dependency entries. Head9e2dbf2later passed 160/160 plus 4/4 and retained all three screenshot artifacts. Those historical counts do not replace the current-head CI results above.Concrete Render application sequence (not executed)
Because both services currently auto-deploy main and the new build scripts are only on this PR, do not set a command referencing an absent main file or merge into automatic deployment with the old broad build command. Through an approved supported UI/configuration path: temporarily disable auto-deploy for both services; merge only the verified expected head without bypass; once main contains the scripts, set the API/Web build commands listed above while preserving start commands/environment; deliberately release and verify each service before restoring the intended deployment behavior. The connector exposes no build-command or auto-deploy update operation. No production configuration was changed in this turn.