Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

30 KiB

Scratchpad — Premium ABAC Exhaustive Remediation Sweep

  • Plan slug: premium-abac-exhaustive-remediation-sweep
  • Created: 2026-04-22

What This Is

This is the working memory for the exhaustive post-remediation premium-ABAC sweep.

It intentionally preserves the earlier 2026-04-22 remediation plan as a historical checkpoint and expands the remaining work into one comprehensive backlog covering lifecycle integrity, server-action parity, count/pagination honesty, linked-subresource semantics, and final close-out validation.

Decisions

  • (2026-04-22) Create a new remediation plan instead of mutating 2026-04-22-premium-abac-remediation/, so the earlier plan remains the historical record of the surgical pass.
  • (2026-04-22) This plan is the “leave no stone unturned” sweep for the premium-ABAC rollout.
  • (2026-04-22) API controller hardening is no longer enough; server actions, helper layers, counts, summaries, and linked-resource surfaces are now first-class remediation targets.
  • (2026-04-22) Aggregates, totals, tree counts, summary metrics, and file/URL helpers are security surfaces and must be treated as such.
  • (2026-04-22) Default principle for this sweep: reuse the shared kernel or a parent-authorized structural helper; do not create new shadow auth models.
  • (2026-04-22) Archive semantics decision: archiving a bundle will immediately disable active assignments to avoid misleading active-but-inert state.
  • (2026-04-22) Clone semantics decision: cloning a bundle without a published revision is rejected; cloning only uses published revisions.
  • (2026-04-22) Asset linked-child semantics decision: structural asset-owned data (maintenance/history) inherits parent asset authorization, while linked ticket/document payloads must satisfy intersection semantics (authorized parent asset + child resource-family authorization).

Discoveries / Constraints

Historical context

  • (2026-04-22) Existing premium-ABAC plan: ee/docs/plans/2026-04-21-premium-abac-authorization-kernel/
  • (2026-04-22) Existing surgical remediation plan: ee/docs/plans/2026-04-22-premium-abac-remediation/
  • (2026-04-22) Latest remediation checkpoint commit before this new plan: cfa8cd208fix(remediation): harden api parity and bundle lifecycle

Bundle lifecycle / EE control plane

  • (2026-04-22) ensureDraftBundleRevision(...) still has a revision-number race window: concurrent callers can compute the same nextRevisionNumber.
  • (2026-04-22) ensureDraftBundleRevision(...) copies published rules outside a single transaction boundary, so draft creation can succeed while rule copy fails partway.
  • (2026-04-22) EE actions call ensureDraftBundleRevision(...) before later write operations, leaving a stale-draft race window between draft acquisition and rule mutation/publish.
  • (2026-04-22) publishBundleRevision(...) currently needs a stronger policy around empty/invalid draft publish behavior.
  • (2026-04-22) 20260422143000_enforce_authorization_revision_lifecycle_uniqueness.cjs needs a duplicate-row preflight, otherwise uniqueness-index creation can fail too quietly when historical duplicates already exist.
  • (2026-04-22) Assignment/archive semantics are still under-defined: archived bundles can leave confusing assignment state behind unless governance is tightened further.
  • (2026-04-22) Implemented: ensureDraftBundleRevision(...) is now wrapped in one transaction that locks the bundle row, serializes draft creation, and copies published rules atomically.
  • (2026-04-22) Implemented: draft mutation/publish EE actions now run ensureDraft + write in one transaction boundary for stale-state safety.
  • (2026-04-22) Implemented: publishBundleRevision(...) now rejects empty drafts with an actionable error.
  • (2026-04-22) Implemented: assignment creation now rejects archived bundles; assignment status updates now fail loudly for missing assignments and archived-bundle reactivation attempts.
  • (2026-04-22) Implemented: archiveBundle(...) now disables active assignments as part of archive transition.
  • (2026-04-22) Implemented: lifecycle-uniqueness migration now preflights duplicate draft/published rows and emits a concrete repair query/path.

Billing / quote server actions

  • (2026-04-22) packages/billing/src/actions/quoteActions.ts is still inconsistent: getQuote, listQuotes, and approveQuote use kernel logic, but many other reads/mutations remain RBAC-only.
  • (2026-04-22) listQuotes still reports total: filteredData.length, which is page-local post-filter count, not true authorized total.
  • (2026-04-22) Quote item helpers (add/update/remove/reorder) still need parent-quote authorization and item-to-quote integrity validation.
  • (2026-04-22) Converted-contract / converted-invoice lookup helpers can return quotes without reapplying quote narrowing.
  • (2026-04-22) PDF/preview/reminder/send/conversion/version flows need the same read-before-mutate parity now present in ApiQuoteController.ts.
  • (2026-04-22) Implemented shared quote-read authorization helper set in packages/billing/src/actions/quoteActions.ts:
    • createQuoteAuthorizationKernel(...)
    • authorizeQuoteReadDecision(...)
    • getAuthorizedQuoteForRead(...)
    • assertQuoteReadAllowedForMutation(...)
  • (2026-04-22) Implemented record-level quote auth for read helpers:
    • versions, conversion preview, converted-contract/invoice lookups, pdf file-id lookup, PDF download, preview render.
  • (2026-04-22) Implemented record-level quote auth for mutations:
    • update/delete, submit-for-approval, request-changes, send/resend/remind, create-revision, conversion flows, regenerate-pdf.
  • (2026-04-22) Implemented quote-item integrity guards:
    • item update cannot move across quotes.
    • add/update/remove/reorder now require parent quote authorization.
  • (2026-04-22) Implemented authorization-aware quote pagination totals by using buildAuthorizationAwarePage(...) and authorized total/totalPages semantics.

Documents

  • (2026-04-22) packages/documents/src/actions/documentActions.ts now has partial auth-aware pagination, but many other surfaces remain RBAC-only or unauthenticated.
  • (2026-04-22) URL helper surfaces such as download/preview/thumbnail/image helper paths still need a complete kernel-backed story.
  • (2026-04-22) Bulk mutations (move, visibility, association, folder ops) still need record-level authorization.
  • (2026-04-22) getDocumentCountsForEntities and getFolderStats were flagged as especially risky because they can leak counts/sizes without real narrowing.
  • (2026-04-22) documentPermissionUtils.ts still acts as a weaker parallel permission model and should likely be bypassed or retired in favor of kernel-backed helpers.
  • (2026-04-22) documentContentActions.ts and documentBlockContentActions.ts were flagged for very weak or missing auth.
  • (2026-04-22) Implemented kernel-backed document URL helper hardening (F016) by adding/using authorized document resolvers:
    • new helper: getAuthorizedDocumentById(...) in packages/documents/src/actions/documentActions.ts
    • existing helper reused: getAuthorizedDocumentByFileId(...)
  • (2026-04-22) Hardened server URL routes to use authorized resolvers instead of raw RBAC-only document lookups:
    • server/src/app/api/documents/[documentId]/download/route.ts
    • server/src/app/api/documents/[documentId]/preview/route.ts
    • server/src/app/api/documents/[documentId]/thumbnail/route.ts
    • server/src/app/api/documents/view/[fileId]/route.ts
  • (2026-04-22) Hardened URL-returning document actions to require authorized-document lookup before returning URL values:
    • getDocumentDownloadUrl
    • getDocumentThumbnailUrl
    • getDocumentPreviewUrl
    • getImageUrl
  • (2026-04-22) Implemented document mutation hardening (F017) with shared mutation guards:
    • new helper: assertAuthorizedDocumentSetForMutation(...) in packages/documents/src/actions/documentActions.ts
    • update/delete/association/folder-mutation flows now fail closed when any targeted document is missing or unauthorized.
  • (2026-04-22) Hardened content/block-content document helpers (F018) so read/write/delete operations require:
    • resource-level RBAC permission (document.read/update/delete)
    • authorized parent-document resolution via getAuthorizedDocumentById(...)
  • (2026-04-22) Implemented aggregate hardening (F019) for document count surfaces:
    • getDocumentCountsForEntities now resolves associated documents and counts only kernel-authorized records.
    • getFolderStats now computes count/size from authorized document sets.
    • folder-tree count enrichment now removes hardcoded entity-type shortcuts and counts only authorized records.
  • (2026-04-22) Implemented F020 by removing the remaining documentPermissionUtils-based entity-type prefilter from getDocumentsByFolder(...); folder document visibility now depends on kernel-backed document authorization, not helper-layer shadow auth rules.
  • (2026-04-22) Closed F021 via the same aggregate sweep: folder trees (enrichFolderTreeWithCounts), folder stats (getFolderStats), and entity count helpers now derive values from authorized-document sets only.
  • (2026-04-22) Typecheck status after F018:
    • packages/documents still has pre-existing TS errors in UI components (block_data typing in CollaborativeEditor.tsx and Documents.tsx family).
    • no new type errors remain in changed action files after remediation patching.

Assets

  • (2026-04-22) packages/assets/src/actions/assetActions.ts only applies asset-level narrowing in a few places (getAsset, getAssetDetailBundle, listAssets).
  • (2026-04-22) listAssets still returns pre-narrowing totals.
  • (2026-04-22) getAssetSummaryMetrics was flagged as a zero-auth surface.
  • (2026-04-22) Relationship, maintenance, history, linked-ticket, and client-summary paths still mostly rely on RBAC only.
  • (2026-04-22) Asset detail bundles need an explicit policy decision about linked tickets/documents: parent asset read only, or parent + child intersection.
  • (2026-04-22) Implemented shared asset-read authorizer helpers (F022) in packages/assets/src/actions/assetActions.ts:
    • createAssetReadAuthorizationKernel(...)
    • createAssetReadAuthorizationContext(...)
    • authorizeAssetReadDecision(...)
    • assertAssetReadAllowed(...)
  • (2026-04-22) Implemented authorization-aware asset pagination totals (F023) by moving listAssets to buildAuthorizationAwarePage(...) and returning authorizedPage.total.
  • (2026-04-22) Implemented exhaustive asset read hardening (F024) in packages/assets/src/actions/assetActions.ts:
    • Added reusable helpers for ID-based asset auth enforcement across non-list surfaces:
      • resolveAssetAuthorizationInputById(...)
      • assertAssetReadAllowedById(...)
      • createAuthorizedAssetReadContextForUser(...)
      • getAuthorizedAssetIdsForClient(...)
    • Applied asset-level authorization checks to remaining read surfaces:
      • getAssetRelationships
      • getAssetMaintenanceSchedules
      • getAssetMaintenanceReport
      • getAssetHistory
      • getAssetLinkedTickets
      • listEntityAssets
      • getClientMaintenanceSummary
      • getClientMaintenanceSummaries
      • getAssetSummaryMetrics (previously zero-auth).
    • Client maintenance summaries now compute metrics over authorized asset sets only.
  • (2026-04-22) Implemented asset mutation hardening (F025) in packages/assets/src/actions/assetActions.ts:
    • Added asset-level authorization gating to:
      • updateAsset
      • deleteAsset
      • createAssetRelationship
      • deleteAssetRelationship
      • createAssetAssociation
      • removeAssetAssociation
      • createMaintenanceSchedule
      • updateMaintenanceSchedule
      • deleteMaintenanceSchedule
      • recordMaintenanceHistory
    • Added maintenance-history integrity check: schedule must belong to the provided asset.
  • (2026-04-22) Implemented linked-child intersection semantics (F026) in asset detail and linked-ticket/document reads:
    • getAssetDetailBundle now performs:
      • parent asset authorization for structural children
      • child ticket/document authorization filtering for linked payloads.
    • fetchAssetLinkedTickets(...) now supports child ticket kernel filtering.
    • fetchAssetDocuments(...) now supports child document kernel filtering.

Projects / tasks / statuses

  • (2026-04-22) packages/projects/src/actions/projectActions.ts is partially hardened but still has remaining parity work.
  • (2026-04-22) Local exploratory edits are currently in progress in projectActions.ts and projectAuthorization.contract.test.ts; they are not yet committed and are not by themselves the exhaustive solution.
  • (2026-04-22) packages/projects/src/actions/projectTaskActions.ts remains broadly RBAC-only and does not consistently resolve/authorize the parent project.
  • (2026-04-22) packages/projects/src/actions/projectTaskStatusActions.ts was flagged for both RBAC-only paths and zero-check surfaces.
  • (2026-04-22) Cross-project move/duplicate/link flows are especially risky because they need authorization on both source and target projects.
  • (2026-04-22) Phase task counts and status-mapping task counts are auth-sensitive aggregate leaks, not just UX helpers.
  • (2026-04-22) Implemented F027 project-actions parity sweep in packages/projects/src/actions/projectActions.ts:
    • phase mutations (updatePhase, deletePhase, addProjectPhase, reorderPhase) now resolve parent project and enforce assertProjectReadAllowed(...).
    • project status mutations now authorize all project mappings tied to a status ID before update/delete (resolveProjectIdsForStatus(...) + per-project assert).
    • internal status resolution helper getProjectTaskStatusesInternal(...) now enforces parent-project authorization before returning phase/status data.
  • (2026-04-22) Implemented F028-F029 parent-project gating across projectTaskActions.ts:
    • Added shared reusable parent-project gating helpers in task actions:
      • createProjectReadAuthorizer(...)
      • assertProjectReadAllowedById(...)
      • resolver helpers for task/phase/checklist/resource/ticket-link IDs.
    • Applied parent-project gating to task/checklist/dependency/resource/ticket-link reads and mutations.
    • getLinkedTasksForTicketAction now filters linked tasks to authorized project contexts only.
  • (2026-04-22) Implemented F030 status-action gating in projectTaskStatusActions.ts:
    • Added project kernel authorization helper assertProjectReadAllowed(...).
    • Applied parent-project gating to status mapping create/read/update/delete/reorder/copy/remove-phase flows.
    • Closed previously zero-check count surface by hardening getStatusMappingTaskCount.
  • (2026-04-22) Implemented F031-F032 via task/status helper hardening:
    • aggregate helpers now require project authorization (getPhaseTaskCounts, getProjectTaskData, getStatusMappingTaskCount).
    • cross-project move/duplicate/link flows now enforce source + target project authorization (moveTaskToPhase, duplicateTaskToPhase, addTicketLinkAction).

Time / remaining resource-family re-audit

  • (2026-04-22) The prior remediation fixed the time_entry resource key mismatch, but a broader re-audit is still needed to confirm there are no leftover helper/count leaks or RBAC-only delegation paths.
  • (2026-04-22) Re-audit (F034) found delegation gaps in time-sheet actions:
    • requestChangesForTimeSheet did not enforce delegation on the target subject.
    • non-owner path in addCommentToTimeSheet did not enforce delegation.
  • (2026-04-22) Implemented time/delegation remediation (F034) in:
    • packages/scheduling/src/actions/timeSheetActions.ts
    • packages/scheduling/src/actions/timeEntryDelegationAuth.ts
    • packages/scheduling/tests/timeDelegationSweep.contract.test.ts
    • packages/scheduling/tests/timeEntryDelegationAuth.authorization.test.ts
  • (2026-04-22) requestChangesForTimeSheet and non-owner comments now require assertCanActOnBehalf(...).
  • (2026-04-22) Delegation helper now avoids unnecessary managed-user expansion for tenant-wide (timesheet:read_all) checks while preserving fail-closed behavior.

Commands / Runbooks

  • (2026-04-22) Review current auth-remediation history:
    • git log --oneline --decorate --reverse --ancestry-path $(git merge-base HEAD origin/main)..HEAD
  • (2026-04-22) Review the latest remediation checkpoint commit:
    • git show --stat cfa8cd208
  • (2026-04-22) Inspect bundle lifecycle service:
    • read server/src/lib/authorization/bundles/service.ts
  • (2026-04-22) Inspect EE bundle actions:
    • read ee/server/src/lib/actions/auth/authorizationBundleActions.ts
  • (2026-04-22) Inspect hardened API controller patterns for reuse:
    • read server/src/lib/api/controllers/ApiTicketController.ts
    • read server/src/lib/api/controllers/ApiProjectController.ts
    • read server/src/lib/api/controllers/ApiQuoteController.ts
    • read server/src/lib/api/controllers/authorizationAwarePagination.ts
  • (2026-04-22) Inspect server-action domains:
    • read packages/billing/src/actions/quoteActions.ts
    • read packages/documents/src/actions/documentActions.ts
    • read packages/assets/src/actions/assetActions.ts
    • read packages/projects/src/actions/projectActions.ts
    • read packages/projects/src/actions/projectTaskActions.ts
    • read packages/projects/src/actions/projectTaskStatusActions.ts
  • (2026-04-22) Quick grep for auth-sensitive list/count/helper surfaces:
    • rg -n "count\(|totalCount|pagination|hasPermission\(|authorizeResource\(|authorizeMutation\(" packages server ee
  • (2026-04-22) Run targeted bundle hardening unit/contract tests:
    • cd server && pnpm vitest src/test/unit/authorization/bundleLifecycleHardening.contract.test.ts src/test/unit/authorization/bundleManagement.contract.test.ts src/test/unit/migrations/authorizationBundleRevisionLifecycleUniquenessMigration.test.ts
  • (2026-04-22) Run lifecycle integration tests (requires local Postgres):
    • cd server && pnpm vitest src/test/integration/authorization/bundleLifecycleIntegrity.integration.test.ts
  • (2026-04-22) Run quote parity contract test:
    • cd server && pnpm vitest ../packages/billing/src/actions/quoteAuthorizationParity.contract.test.ts
  • (2026-04-22) Run document URL authorization contract test:
    • cd server && pnpm vitest src/test/unit/documents/documentUrlAuthorization.contract.test.ts
  • (2026-04-22) Run focused document mutation/content regression tests:
    • cd server && pnpm vitest src/test/unit/documentFolderOperations.test.ts ../packages/documents/tests/documentActions.authorization.contract.test.ts ../packages/documents/tests/documentContent.authorization.contract.test.ts --coverage.enabled false
  • (2026-04-22) Run quote parity contract test for T007-T010 status validation:
    • cd server && pnpm vitest ../packages/billing/src/actions/quoteAuthorizationParity.contract.test.ts --coverage.enabled false
  • (2026-04-22) Run package-level document typecheck:
    • pnpm -C packages/documents typecheck
  • (2026-04-22) Re-run count/folder hardening tests:
    • cd server && pnpm vitest src/test/unit/documentFolderOperations.test.ts ../packages/documents/tests/documentActions.authorization.contract.test.ts --coverage.enabled false
  • (2026-04-22) Run asset auth/pagination contract test:
    • cd server && pnpm vitest ../packages/assets/src/actions/assetAuthorization.contract.test.ts --coverage.enabled false
  • (2026-04-22) Run assets package typecheck after exhaustive hardening:
    • pnpm -C packages/assets typecheck
  • (2026-04-22) Run project-action parity contract test:
    • cd server && pnpm vitest ../packages/projects/src/actions/projectAuthorization.contract.test.ts --coverage.enabled false
  • (2026-04-22) Run projects package typecheck:
    • pnpm -C packages/projects typecheck
  • (2026-04-22) Run time/delegation re-audit validation tests:
    • cd server && pnpm vitest ../packages/scheduling/tests/timeDelegationSweep.contract.test.ts ../packages/scheduling/tests/timeEntryDelegationAuth.authorization.test.ts --coverage.enabled false
  • (2026-04-22) Run close-out artifact contract test:
    • cd server && pnpm vitest src/test/unit/authorization/premiumAbacExhaustiveInventory.contract.test.ts --coverage.enabled false
  • Original premium-ABAC plan:
    • ee/docs/plans/2026-04-21-premium-abac-authorization-kernel/PRD.md
    • ee/docs/plans/2026-04-21-premium-abac-authorization-kernel/features.json
    • ee/docs/plans/2026-04-21-premium-abac-authorization-kernel/tests.json
    • ee/docs/plans/2026-04-21-premium-abac-authorization-kernel/CURRENT_AUTHORIZATION_BASELINE.md
  • Surgical remediation plan:
    • ee/docs/plans/2026-04-22-premium-abac-remediation/PRD.md
    • ee/docs/plans/2026-04-22-premium-abac-remediation/features.json
    • ee/docs/plans/2026-04-22-premium-abac-remediation/tests.json
    • ee/docs/plans/2026-04-22-premium-abac-remediation/SCRATCHPAD.md
  • Key implementation files:
    • server/src/lib/authorization/bundles/service.ts
    • server/src/lib/authorization/kernel/providers/bundleProvider.ts
    • server/src/lib/api/controllers/authorizationKernel.ts
    • server/src/lib/api/controllers/authorizationAwarePagination.ts
    • packages/billing/src/actions/quoteActions.ts
    • packages/documents/src/actions/documentActions.ts
    • packages/assets/src/actions/assetActions.ts
    • packages/projects/src/actions/projectActions.ts
    • packages/projects/src/actions/projectTaskActions.ts
    • packages/projects/src/actions/projectTaskStatusActions.ts

Open Questions

  • Should linked tickets/documents inside asset detail bundles require parent asset auth only, or intersection with child-resource auth?
  • For project-linked ticket/task surfaces, where exactly should inheritance stop so ticket auth is not weakened?
  • Should archiving a bundle automatically disable assignments for hygiene, or should assignments remain inert but active in the table?
  • If a bundle has never been published, should cloning copy its latest draft or reject the clone as ambiguous in-progress state?
  • Is SCRATCHPAD.md enough for the exhaustive surface matrix, or should we add a dedicated close-out artifact later?

Progress Log

  • (2026-04-22) Chose plan shape B with the user: preserve the earlier remediation plan and create a new exhaustive sweep plan.
  • (2026-04-22) Ran parallel reviewer audits across five domains:
    • documents
    • billing quote server actions
    • assets
    • projects/tasks/statuses
    • bundle lifecycle / EE control plane
  • (2026-04-22) Reviewer findings confirmed that the remaining scope is materially larger than the earlier surgical remediation plan and warrants a dedicated exhaustive backlog.
  • (2026-04-22) Created this new plan folder and drafted a PRD/features/tests set centered on the reviewer findings plus the already-known parity backlog.
  • (2026-04-22) Completed F001 by preserving explicit lineage/cross-links in the new PRD and scratchpad to both prior plans and prior checkpoint commit.
  • (2026-04-22) Completed lifecycle feature wave F002-F010 in:
    • server/src/lib/authorization/bundles/service.ts
    • ee/server/src/lib/actions/auth/authorizationBundleActions.ts
    • server/migrations/20260422143000_enforce_authorization_revision_lifecycle_uniqueness.cjs
  • (2026-04-22) Added lifecycle regression coverage for T001-T006 via:
    • server/src/test/integration/authorization/bundleLifecycleIntegrity.integration.test.ts
    • server/src/test/unit/migrations/authorizationBundleRevisionLifecycleUniquenessMigration.test.ts
    • server/src/test/unit/authorization/bundleLifecycleHardening.contract.test.ts
  • (2026-04-22) Validation status:
    • unit/contract tests pass for touched lifecycle contracts/migration.
    • integration suite is authored but currently cannot execute in this shell because Postgres is unavailable (ECONNREFUSED 127.0.0.1:5432).
  • (2026-04-22) Completed quote hardening feature wave F011-F015 in:
    • packages/billing/src/actions/quoteActions.ts
    • packages/billing/src/actions/quoteAuthorizationParity.contract.test.ts
  • (2026-04-22) Completed document URL helper hardening F016 in:
    • packages/documents/src/actions/documentActions.ts
    • server/src/app/api/documents/[documentId]/download/route.ts
    • server/src/app/api/documents/[documentId]/preview/route.ts
    • server/src/app/api/documents/[documentId]/thumbnail/route.ts
    • server/src/app/api/documents/view/[fileId]/route.ts
    • server/src/test/unit/documents/documentUrlAuthorization.contract.test.ts
  • (2026-04-22) Completed document mutation hardening F017 in:
    • packages/documents/src/actions/documentActions.ts
    • server/src/test/unit/documentFolderOperations.test.ts (updated to validate new mutation-guard behavior)
    • packages/documents/tests/documentActions.authorization.contract.test.ts (expanded with T012 mutation-surface contract coverage)
  • (2026-04-22) Completed document content/block-content hardening F018 in:
    • packages/documents/src/actions/documentContentActions.ts
    • packages/documents/src/actions/documentBlockContentActions.ts
    • packages/documents/tests/documentContent.authorization.contract.test.ts (T013)
  • (2026-04-22) Completed document aggregate hardening F019 in:
    • packages/documents/src/actions/documentActions.ts
    • packages/documents/tests/documentActions.authorization.contract.test.ts (T014)
    • server/src/test/unit/documentFolderOperations.test.ts (updated folder-stats expectations for auth-aware counting)
  • (2026-04-22) Completed F020 (bypass divergent documentPermissionUtils shadow auth path) in:
    • packages/documents/src/actions/documentActions.ts
    • packages/documents/tests/documentActions.authorization.contract.test.ts
    • server/src/test/unit/documentFolderOperations.test.ts (removed entity-type helper mock assumptions)
  • (2026-04-22) Completed F021 (authorized semantics for folder trees/counts/summary metrics) in:
    • packages/documents/src/actions/documentActions.ts
    • packages/documents/tests/documentActions.authorization.contract.test.ts (T014)
    • server/src/test/unit/documentFolderOperations.test.ts
  • (2026-04-22) Completed asset shared read-authorizer + pagination totals wave (F022-F023) in:
    • packages/assets/src/actions/assetActions.ts
    • packages/assets/src/actions/assetAuthorization.contract.test.ts (T015)
  • (2026-04-22) Completed asset exhaustive hardening wave (F024-F026) in:
    • packages/assets/src/actions/assetActions.ts
    • packages/assets/src/actions/assetAuthorization.contract.test.ts (T016-T018)
  • (2026-04-22) Completed asset regression-coverage feature (F042) by expanding asset contract coverage for:
    • remaining reads (relationships/maintenance/history/linked tickets/client summaries/entity-linked assets/summary metrics)
    • remaining mutations (asset update/delete, relationships/associations, maintenance mutations)
    • linked child-resource intersection semantics in detail bundles.
  • (2026-04-22) Validation status for asset exhaustive wave:
    • cd server && pnpm vitest ../packages/assets/src/actions/assetAuthorization.contract.test.ts --coverage.enabled false passed.
    • pnpm -C packages/assets typecheck passed.
  • (2026-04-22) Completed F027 (projectActions phase/detail/status/tree parity hardening) in:
    • packages/projects/src/actions/projectActions.ts
    • packages/projects/src/actions/projectAuthorization.contract.test.ts (T019)
  • (2026-04-22) Validation status for F027:
    • cd server && pnpm vitest ../packages/projects/src/actions/projectAuthorization.contract.test.ts --coverage.enabled false passed.
    • pnpm -C packages/projects typecheck passed.
  • (2026-04-22) Completed project task/status hardening wave (F028-F032) in:
    • packages/projects/src/actions/projectTaskActions.ts
    • packages/projects/src/actions/projectTaskStatusActions.ts
    • packages/projects/src/actions/projectAuthorization.contract.test.ts (T020-T023)
  • (2026-04-22) Completed F033 project structural-child semantics in:
    • packages/projects/src/actions/projectTaskActions.ts (linked ticket data now intersects with ticket-resource auth).
    • packages/projects/src/actions/projectAuthorization.contract.test.ts (F033 assertion block).
  • (2026-04-22) Completed exhaustive re-audit and close-out artifact wave (F034-F038) in:
    • packages/scheduling/src/actions/timeEntryDelegationAuth.ts
    • packages/scheduling/src/actions/timeSheetActions.ts
    • packages/scheduling/tests/timeDelegationSweep.contract.test.ts (T024)
    • packages/scheduling/tests/timeEntryDelegationAuth.authorization.test.ts (T024)
    • ee/docs/plans/2026-04-22-premium-abac-exhaustive-remediation-sweep/EXHAUSTIVE_SURFACE_INVENTORY.md (F037)
    • ee/docs/plans/2026-04-21-premium-abac-authorization-kernel/CURRENT_AUTHORIZATION_BASELINE.md (F038)
    • server/src/test/unit/authorization/premiumAbacExhaustiveInventory.contract.test.ts (T025)
  • (2026-04-22) Completed F043 project regression coverage by expanding contract assertions for:
    • T019 projectActions parity
    • T020 task/checklist/dependency/resource/ticket-link gating
    • T021 status-action parent gating + zero-check remediation
    • T022 aggregate/count helper protection
    • T023 cross-project source/target authorization.
  • (2026-04-22) Validation status for project task/status wave:
    • cd server && pnpm vitest ../packages/projects/src/actions/projectAuthorization.contract.test.ts --coverage.enabled false passed (7 tests).
    • pnpm -C packages/projects typecheck passed.
  • (2026-04-22) Validation status for re-audit + close-out wave:
    • cd server && pnpm vitest ../packages/scheduling/tests/timeDelegationSweep.contract.test.ts ../packages/scheduling/tests/timeEntryDelegationAuth.authorization.test.ts --coverage.enabled false passed.
    • close-out artifact contract premiumAbacExhaustiveInventory.contract.test.ts authored (executed in this wave).
  • (2026-04-22) Marked quote parity regression tests T007-T010 complete after re-validating:
    • packages/billing/src/actions/quoteAuthorizationParity.contract.test.ts
  • (2026-04-22) Marked document URL regression test T011 complete:
    • server/src/test/unit/documents/documentUrlAuthorization.contract.test.ts