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

40 KiB
Raw Blame History

Scratchpad — Advanced Authorization Kernel and Premium ABAC Bundles

  • Plan slug: premium-abac-authorization-kernel
  • Created: 2026-04-21

What This Is

Keep a lightweight, continuously-updated log of discoveries and decisions made while implementing this plan.

Prefer short bullets. Append new entries as you learn things, and also update earlier notes when a decision changes or an open question is resolved.

Decisions

  • (2026-04-21) The product direction is a comprehensive authorization-kernel overhaul rather than a small ABAC bolt-on.
  • (2026-04-21) The design should follow the ALGA plan approach with PRD.md, features.json, tests.json, and SCRATCHPAD.md under ee/docs/plans/.
  • (2026-04-21) The old policy DSL should be treated as abandoned scaffolding and not evolved into the main runtime direction.
  • (2026-04-21) Configurable ABAC should use admin-configurable templates, not arbitrary expressions.
  • (2026-04-21) The most important first-class relationship concepts are owns / manages / assigned / same client / client portfolio / selected boards.
  • (2026-04-21) Configured premium ABAC is narrowing-only; it must never widen access beyond RBAC + built-in kernel behavior.
  • (2026-04-21) The shared authorization runtime should exist in CE and EE so existing ABAC-like product rules can be normalized without forking security behavior by edition.
  • (2026-04-21) The EE-only seam is the configurable control plane: bundle CRUD, assignments, publishing, simulation, and governance UX.
  • (2026-04-21) Configurable premium ABAC management is officially gated at the existing Premium tenant tier by default.
  • (2026-04-21) The packaging model should mirror existing EE plugin/provider seams: one stable interface, CE builtin implementation, EE configurable implementation.
  • (2026-04-21) Bundle assignments should support roles, teams, users, and API keys.
  • (2026-04-21) Bundle assignments should use one generic assignment table keyed by target_type + target_id.
  • (2026-04-21) Bundle changes should use a draft → publish model rather than editing active policy in place.
  • (2026-04-21) The primary admin artifact should be a bundle, not a raw policy row.
  • (2026-04-21) The first configurable resource families are tickets, documents, time, billing, projects, and assets, with API-key scoping treated as cross-cutting.
  • (2026-04-21) The EE simulator should support both real principals/records and synthetic scenarios.
  • (2026-04-21) The migration must explicitly document and validate current behavior parity before and after cutover.

Discoveries / Constraints

  • (2026-04-21) Core RBAC is currently centered in server/src/lib/auth/rbac.ts and packages/db/src/models/user.ts via role/permission lookup plus MSP/client portal gating.
  • (2026-04-21) There are multiple copies of RBAC and policy-engine code (server, packages/auth, packages/tags, ee/server), which reinforces the need for a single shared runtime contract.
  • (2026-04-21) The codebase already contains important production ABAC-like behavior that should become built-in kernel rules rather than optional premium overlays.
  • (2026-04-21) packages/tickets/src/lib/clientPortalVisibility.ts is the clearest existing shared scope-filter example and is a strong model for list/query narrowing.
  • (2026-04-21) packages/scheduling/src/actions/timeEntryDelegationAuth.ts already expresses a high-value managed-hierarchy relationship model (self, manager, tenant-wide).
  • (2026-04-21) server/src/app/api/documents/view/[fileId]/route.ts contains a large amount of inline relationship/visibility logic that should be kernelized carefully and fail-closed.
  • (2026-04-21) packages/client-portal/src/actions/client-portal-actions/visibilityGroupActions.ts demonstrates same-client and client-admin relationship guards that belong in the shared kernel, not only in premium configuration.
  • (2026-04-21) API-key-backed controllers such as server/src/lib/api/controllers/ApiBaseController.ts and ApiTicketController.ts are mostly RBAC-only today and are a likely parity gap compared with UI/server-action flows.
  • (2026-04-21) There is a legacy policies table and policy UI scaffolding, but runtime evaluation does not appear to rely on it as the authoritative production path.
  • (2026-04-21) The dev seed server/seeds/dev/49_policies.cjs references stale concepts like department, confirming drift in the old DSL path.
  • (2026-04-21) Existing EE gating patterns already exist in the repo:
    • edition detection via server/src/lib/features.ts
    • tier gating via server/src/lib/tier-gating/assertTierAccess.ts and ServerTierGate.tsx
    • feature-tier mapping in packages/types/src/constants/tierFeatures.ts
    • Teams-style availability logic in packages/integrations/src/lib/teamsAvailability.ts
  • (2026-04-21) The product already uses stable CE/EE entrypoint aliasing (for example packages/product-auth-ee/{oss,ee}/entry*), which is the preferred packaging pattern for the configurable authorization seam.

Commands / Runbooks

  • (2026-04-21) Search for RBAC/ABAC-related code and existing inline rules: rg -n --hidden --glob '!node_modules' --glob '!dist' "\bABAC\b|attribute[- ]based|access policy|policy engine|scope filter|row[- ]level|hasPermission\(|role_permissions|permissions|is_client_admin|portal_visibility_group_id|isInReportsToChain|approval_status|is_client_visible" packages server ee
  • (2026-04-21) Find policy-engine and legacy DSL scaffolding: rg -n --hidden --glob '!node_modules' --glob '!dist' "class PolicyEngine|evaluateAccess\(|parsePolicy|policyActions|policies\b" packages server ee
  • (2026-04-21) Inspect current Teams-style edition/tier gating references: rg -n --hidden --glob '!node_modules' --glob '!dist' "tier-gating|TIER_FEATURES|Teams integration|teamsAvailability|isEnterprise" packages server ee
  • (2026-04-21) Scaffold an ALGA plan folder: python3 /Users/roberisaacs/.agents/skills/alga-plan/scripts/scaffold_plan.py "Advanced Authorization Kernel and Premium ABAC Bundles" --slug premium-abac-authorization-kernel
  • packages/auth/src/lib/getSession.ts
  • packages/auth/src/lib/getCurrentUser.ts
  • packages/auth/src/lib/withAuth.ts
  • server/src/lib/auth/rbac.ts
  • packages/db/src/models/user.ts
  • packages/tickets/src/lib/clientPortalVisibility.ts
  • packages/scheduling/src/actions/timeEntryDelegationAuth.ts
  • server/src/app/api/documents/view/[fileId]/route.ts
  • packages/client-portal/src/actions/client-portal-actions/visibilityGroupActions.ts
  • server/src/lib/api/controllers/ApiBaseController.ts
  • server/src/lib/api/controllers/ApiTicketController.ts
  • packages/auth/src/actions/policyActions.ts
  • packages/product-auth-ee/oss/entry.tsx
  • packages/product-auth-ee/ee/entry.ts
  • server/src/lib/features.ts
  • server/src/lib/tier-gating/assertTierAccess.ts
  • server/src/lib/tier-gating/ServerTierGate.tsx
  • packages/types/src/constants/tierFeatures.ts
  • packages/integrations/src/lib/teamsAvailability.ts
  • ee/docs/plans/2026-04-21-premium-abac-authorization-kernel/CURRENT_AUTHORIZATION_BASELINE.md
  • context.md
  • research.md

Open Questions

  • Which exact project and asset surfaces are in the first migration wave under the shared kernel versus the second wave?
  • Which billing fields participate in v1 redaction, and which wait for a later phase?
  • Which API surfaces are in the first parity wave once the shared kernel exists?

Progress Log

  • (2026-04-21) Completed F001: validated and retained CURRENT_AUTHORIZATION_BASELINE.md as the parity contract for tickets/documents/time/projects/assets/billing/client-portal/API-key behaviors.
  • (2026-04-21) Completed F002 by introducing a shared kernel contract at server/src/lib/authorization/kernel/contracts.ts with common entry points for single-resource authorization, scope resolution, mutation authorization, field redactions, and explainability.
  • (2026-04-21) Completed F003 with CE builtin provider BuiltinAuthorizationKernelProvider (server/src/lib/authorization/kernel/providers/builtinProvider.ts) that evaluates only builtin product rules.
  • (2026-04-21) Completed F004 by introducing bundle overlay provider plumbing (BundleAuthorizationKernelProvider) plus EE kernel factory (ee/server/src/lib/authorization/kernel.ts) and CE stub seam (packages/ee/src/lib/authorization/kernel.ts).
  • (2026-04-21) Completed F005 with edition-aware runtime loading (server/src/lib/authorization/kernel/enterpriseEntry.ts + index.ts) so callers use one kernel interface without isEnterprise() branching.
  • (2026-04-21) Completed F006: kernel engine now hard-gates on RBAC first (server/src/lib/authorization/kernel/engine.ts) before builtin/bundle narrowing logic.
  • (2026-04-21) Completed F007 via shared relationship template evaluators in server/src/lib/authorization/kernel/relationships.ts for own, assigned, managed, same_client, client_portfolio, same_team, and selected_boards.
  • (2026-04-21) Completed F008 with explicit intersection composition in server/src/lib/authorization/kernel/scope.ts (intersectAuthorizationScopes).
  • (2026-04-21) Completed F009 by adding shared mutation-guard evaluation through builtin provider hooks and authorizeMutation in the kernel engine.
  • (2026-04-21) Completed F010 by adding shared redaction hook support through resolveFieldRedactions and provider-level field redaction resolvers.
  • (2026-04-21) Completed F011 by emitting structured stage-aware reasons (rbac, builtin, bundle, mutation, redaction) in every decision path.
  • (2026-04-21) Completed F012 with request-local memoization support (RequestLocalAuthorizationCache) and RBAC memoization in the kernel engine.
  • (2026-04-21) Validation runbook for this checkpoint:
    • cd server && npx vitest run src/test/unit/authorization/kernel.engine.test.ts src/test/unit/authorization/kernel.relationships.test.ts
    • cd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
  • (2026-04-21) Completed F013: added regression boundary test server/src/test/unit/authorization/kernel.legacyDirection.test.ts to enforce that the new kernel path does not import legacy policy DSL runtime modules; this codifies the cutover direction before resource-family migrations.
  • (2026-04-21) Completed F014-F017 with migration server/migrations/20260421190000_create_authorization_bundle_control_plane.cjs introducing authorization_bundles, authorization_bundle_revisions, authorization_bundle_rules, and generic authorization_bundle_assignments.
  • (2026-04-21) Completed F018 with tenant-scoped assignment target validation in createBundleAssignment(...) (server/src/lib/authorization/bundles/service.ts) for role/team/user/api_key targets.
  • (2026-04-21) Completed F019-F021 by modeling lifecycle states (active/archived, draft/published/archived, active/disabled) plus transactional publish, bundle archive, and assignment enable/disable service operations.
  • (2026-04-21) Completed F022 and F023 with bundle-resolution logic that aggregates active role/team/user/api_key assignments, resolves published revision rules, and applies them through kernel intersection semantics.
  • (2026-04-21) Completed F024 and F025 via typed catalog enforcement in server/src/lib/authorization/bundles/catalog.ts and expanded relationship template support (own_or_assigned, own_or_managed, selected_clients).
  • (2026-04-21) Completed F026 by adding support hooks for not_self_approver, client_visible_only, and hide_sensitive_fields constraint behavior in bundle evaluation.
  • (2026-04-21) Completed F027 by shipping starter bundle definitions in server/src/lib/authorization/bundles/starterBundles.ts for assigned-client technician, project delivery team, time manager, restricted asset operator, and finance reviewer scenarios.
  • (2026-04-21) Completed T001 and T002:
    • T001: baseline artifact validated and maintained.
    • T002: migration contract test added at server/src/test/unit/migrations/authorizationBundleControlPlaneMigration.test.ts to assert control-plane schema shape and narrowing-only constraints.
  • (2026-04-21) Additional validation runbook for this checkpoint:
    • cd server && npx vitest run src/test/unit/authorization/kernel.engine.test.ts src/test/unit/authorization/kernel.relationships.test.ts src/test/unit/authorization/kernel.legacyDirection.test.ts src/test/unit/authorization/bundle.catalog.test.ts src/test/unit/authorization/bundle.provider.test.ts src/test/unit/authorization/starterBundles.test.ts src/test/unit/migrations/authorizationBundleControlPlaneMigration.test.ts
    • cd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
  • (2026-04-21) Completed F028 by replacing EE PolicyManagement with a tier-gated Authorization Bundle Library surface:
    • UI: ee/server/src/components/settings/policy/PolicyManagement.tsx
    • Actions: ee/server/src/lib/actions/auth/authorizationBundleActions.ts
    • Service additions for list/create/clone: server/src/lib/authorization/bundles/service.ts
    • Tier feature gate: TIER_FEATURES.ADVANCED_AUTHORIZATION_BUNDLES in packages/types/src/constants/tierFeatures.ts
  • (2026-04-21) F028 implementation details:
    • Browse/search active+archived bundles from authorization_bundles.
    • Clone bundle into new draft-backed custom bundle while copying source revision rules.
    • Archive active bundles.
    • Seed starter bundles into tenant scope via one action.
    • Tier enforcement is server-side (assertTierAccess) and client-side (useTierFeature) with Premium minimum tier.
  • (2026-04-21) Completed T003 with DB-backed integration coverage in server/src/test/integration/authorization/bundleRevisionPublishing.integration.test.ts validating:
    • publish moves previous published revision to archived
    • target draft revision becomes published
    • stable bundle identity and assignment rows are preserved
  • (2026-04-21) Validation runbook for F028 + T003 checkpoint:
    • cd packages/types && npx vitest run src/constants/tierFeatures.test.ts --coverage.enabled=false
    • mkdir -p server/coverage/.tmp && cd server && npx vitest run --coverage.enabled=false src/test/integration/authorization/bundleRevisionPublishing.integration.test.ts
    • cd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
  • (2026-04-21) Completed F029 by extending EE policy settings to include a draft-oriented Bundle Editor in resource sections (Tickets, Documents, Time, Projects, Assets, Billing), replacing raw policy text editing:
    • UI editor surface: ee/server/src/components/settings/policy/PolicyManagement.tsx
    • Draft editor actions: getAuthorizationBundleDraftEditorAction, upsertAuthorizationBundleDraftRuleAction, deleteAuthorizationBundleDraftRuleAction in ee/server/src/lib/actions/auth/authorizationBundleActions.ts
    • Draft helpers in service layer: ensureDraftBundleRevision, listBundleRulesForRevision, deleteBundleRule in server/src/lib/authorization/bundles/service.ts
  • (2026-04-21) F029 rationale: enforce draft-first authoring semantics by materializing/rehydrating a draft revision from the currently published revision when no draft exists, then editing only draft rules grouped by resource family.
  • (2026-04-21) Completed F030 by adding human-readable summaries for both bundle-level and rule-level understanding:
    • Rule summaries in editor rows (Narrow <resource> <action> to ...) generated in ee/server/src/components/settings/policy/PolicyManagement.tsx.
    • Effective bundle summaries in library rows (status + assignment impact text).
    • Draft-vs-published revision summary generated server-side in getAuthorizationBundleDraftEditorAction (ee/server/src/lib/actions/auth/authorizationBundleActions.ts) and rendered in the editor header.
  • (2026-04-21) Completed F031 by adding an Assignment Manager panel to the EE bundle surface:
    • New action listAuthorizationBundleAssignmentsAction resolves assignment targets across role/team/user/api_key with friendly labels.
    • UI now has per-bundle Assignments toggle showing grouped assignment cards and status.
    • Files: ee/server/src/lib/actions/auth/authorizationBundleActions.ts, ee/server/src/components/settings/policy/PolicyManagement.tsx.
  • (2026-04-21) Completed F032 by adding an EE Access Simulator for real principals + existing records:
    • Principal lookup action: listAuthorizationSimulationPrincipalsAction.
    • Record lookup action by resource family: listAuthorizationSimulationRecordsAction.
    • Simulation execution: runAuthorizationBundleSimulationAction compares draft vs published revision decisions with explainability codes.
    • UI: simulator panel in ee/server/src/components/settings/policy/PolicyManagement.tsx.
  • (2026-04-21) Completed F033 by extending the simulator with synthetic scenarios:
    • Added synthetic record input (ownerUserId, clientId, boardId, isClientVisible) when no real record is suitable.
    • Simulation action now supports syntheticRecord payloads and runs the same draft-vs-published decision flow.
  • (2026-04-21) Completed F034 by tightening unavailable/upgrade states for non-entitled contexts:
    • EE tier-gate surface already blocks with useTierFeature(TIER_FEATURES.ADVANCED_AUTHORIZATION_BUNDLES).
    • CE placeholder copy updated (packages/ee/src/components/settings/policy/PolicyManagement.tsx) to show Premium upgrade path while clarifying builtin authorization remains active.
  • (2026-04-21) Completed F035 by adding explicit server-side permission/tier gates to bundle management actions:
    • CRUD + editor + simulator + assignment + publish actions all enforce assertTierAccess(TIER_FEATURES.ADVANCED_AUTHORIZATION_BUNDLES) plus RBAC permission checks (system_settings:read|write).
    • Added write-gated actions for publish and assignment status changes in ee/server/src/lib/actions/auth/authorizationBundleActions.ts.
  • (2026-04-21) Completed F036 by exposing an audit-trail read model from persisted bundle metadata:
    • Added getAuthorizationBundleAuditTrailAction returning chronological lifecycle events for bundle creation/archive, draft creation, publish events, and assignment changes.
    • Uses existing metadata columns (created_by, updated_by, published_by, timestamps, assignment status) as authoritative audit source.
  • (2026-04-21) Completed F037 for selected server-action paths by moving ticket list/detail authorization to shared kernel checks after RBAC:
    • packages/tickets/src/actions/ticketActions.ts now resolves authorization subject context and calls kernel authorizeResource for getTicketsForList and getTicketById.
    • List path applies kernel decision filtering to ticket rows; single-ticket path denies when kernel disallows.
    • Current cut keeps builtin-kernel path for these endpoints; premium ticket bundle overlays are tracked separately in F039.
  • (2026-04-21) Validation for F037 path-level cutover:
    • cd packages/tickets && npx vitest run src/actions/ticketActions.ticketOrigin.test.ts src/actions/ticketActions.moveToBoard.test.ts --coverage.enabled=false
  • (2026-04-21) Completed F038 by kernelizing selected-board narrowing for client-portal style ticket access in selected ticket action paths:
    • Added client visibility-group board resolution via getClientContactVisibilityContext(...).
    • For client principals, ticket list/detail now pass selectedBoardIds into kernel evaluation with selected_boards relationship template and fail-closed behavior when visibility context is missing/invalid.
    • Added client-scope guard (clientId) alongside board narrowing for list/detail parity.
  • (2026-04-21) Completed F039 by enabling premium bundle overlays on selected ticket list/detail paths:
    • Ticket actions now instantiate kernel with a bundle provider that resolves active published bundle rules for the current principal (resolveBundleNarrowingRulesForEvaluation).
    • Bundle template semantics are now enforced in bundle provider (bundle_template_denied) by evaluating each matching rules relationship template against record context.
    • This enables ticket narrowing from bundle templates like assignment/client/team/selected-board in the migrated ticket paths.
  • (2026-04-21) Completed F040 by migrating selected document server-action list/detail/download paths to the shared kernel:
    • Added shared document auth helpers in packages/documents/src/actions/documentActions.ts for principal resolution, relationship-context normalization from document_associations, and per-record kernel evaluation.
    • Migrated getDocument, getAllDocuments, getDocumentsByEntity, getDocumentsByFolder, and downloadDocument to run authorizeResource through the kernel after RBAC.
    • Preserved client-user semantics by enforcing own OR same_client relationship checks plus fail-closed is_client_visible guard on non-owned records.
  • (2026-04-21) Completed F041 by enabling premium document bundle overlays on migrated document paths:
    • Document actions now instantiate a bundle provider backed by resolveBundleNarrowingRulesForEvaluation(...).
    • Document record context passed to kernel now includes clientId, teamIds, and is_client_visible, enabling client/portfolio-style narrowing and client_visible_only enforcement where configured.
  • (2026-04-21) Completed F042 by wiring document field-redaction hooks into migrated document surfaces:
    • Migrated list/detail document actions now apply kernel-provided redactedFields to returned document payloads without mutating allow/deny behavior.
    • Redaction plumbing is centralized via authorizeAndRedactDocuments(...).
  • (2026-04-21) Validation runbook for F040-F042 checkpoint:
    • cd packages/documents && npx tsc --pretty false --noEmit -p tsconfig.json
    • cd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
    • cd server && npx vitest run src/test/unit/authorization/kernel.engine.test.ts src/test/unit/authorization/bundle.provider.test.ts --coverage.enabled=false
  • (2026-04-21) Completed F043 by kernelizing selected time/timesheet delegation checks through shared relationship semantics:
    • packages/scheduling/src/actions/timeEntryDelegationAuth.ts now resolves managed scope (teams manager + optional reports-to chain) and evaluates non-self delegation with kernel managed relationship templates via authorizeResource.
    • Preserved delegation hierarchy: self short-circuit, timesheet:approve prerequisite, timesheet:read_all tenant-wide override, then manager/reports-to managed scope.
    • fetchTimeSheetsForApproval now uses the same managed-subject resolver to scope approval list visibility consistently with delegation rules.
  • (2026-04-21) Validation runbook for F043 checkpoint:
    • cd packages/scheduling && npx tsc --pretty false --noEmit -p tsconfig.json
    • cd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
    • cd packages/scheduling && npx vitest run tests/timeEntryCrud.changeRequests.test.ts tests/timeSheetClient.reopen.test.tsx --coverage.enabled=false (known pre-existing failure in T012 mock chain: db(...).leftJoin is not a function)
  • (2026-04-21) Completed F044 by enabling premium time narrowing overlays in delegation evaluation:
    • assertCanActOnBehalf now composes built-in delegation and premium bundle narrowing by adding BundleAuthorizationKernelProvider with resolveBundleNarrowingRulesForEvaluation(...).
    • For timesheet:read_all principals, builtin delegation now allows broad scope, while bundle templates can narrow that scope (for example to managed-only/self-only behavior) without widening baseline RBAC/delegation.
    • Result scope classification remains explicit (manager when subject is in managed set, otherwise tenant-wide only when read-all plus kernel allow).
  • (2026-04-21) Validation runbook for F044 checkpoint:
    • cd packages/scheduling && npx tsc --pretty false --noEmit -p tsconfig.json
    • cd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
  • (2026-04-21) Completed F045 by kernelizing not-self-approver checks in selected time approval flows:
    • Added assertCanApproveSubject(...) in packages/scheduling/src/actions/timeEntryDelegationAuth.ts, which composes delegation checks with kernel authorizeMutation for approve mutations.
    • Added a built-in mutation guard (timesheet_not_self_approver_denied) and bundle-aware mutation overlay evaluation (not_self_approver constraint) so approval gating is centralized in kernel semantics.
    • Wired approval paths to the new guard:
      • packages/scheduling/src/actions/timeSheetActions.ts (approveTimeSheet, bulkApproveTimeSheets)
      • packages/scheduling/src/actions/timeEntryCrudActions.ts (updateTimeEntryApprovalStatus when transitioning to APPROVED)
  • (2026-04-21) Validation runbook for F045 checkpoint:
    • cd packages/scheduling && npx tsc --pretty false --noEmit -p tsconfig.json
    • cd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
  • (2026-04-21) Completed F046 by migrating selected project comment authorization semantics to kernel evaluation:
    • packages/projects/src/actions/projectTaskCommentActions.ts now enforces non-internal comment edit/delete access via kernel own relationship evaluation on the comment owner record.
    • Preserved prior behavior exactly for internal users (retain full edit/delete capability), while non-internal users must satisfy own semantics through the shared kernel path.
    • This captures the targeted v1 own-comment/internal-user seam under shared authorization contracts.
  • (2026-04-21) Validation runbook for F046 checkpoint:
    • cd packages/projects && npx tsc --pretty false --noEmit -p tsconfig.json
    • cd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
    • cd packages/projects && npx vitest run src/actions/projectPhaseStatusActions.contract.test.ts src/actions/projectPhaseStatusCopyRemove.contract.test.ts --coverage.enabled=false (known pre-existing contract drift in projectTaskStatusActions.ts expectation: missing literal async function getScopedProjectStatusMappings()
  • (2026-04-21) Completed F047 by enabling premium bundle narrowing on selected project list/detail surfaces:
    • packages/projects/src/actions/projectActions.ts now evaluates getProjects and getProject through kernel authorizeResource with BundleAuthorizationKernelProvider.
    • Added project record normalization for bundle template matching (assigned_to, client_id, optional assigned_team_id) and per-request subject context resolution (roles/teams/managed users/client).
    • Result: published bundle templates for assignment/client/team scope now narrow project visibility on these migrated read paths.
  • (2026-04-21) Validation runbook for F047 checkpoint:
    • cd packages/projects && npx tsc --pretty false --noEmit -p tsconfig.json
    • cd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
  • (2026-04-21) Completed F048 on selected asset read paths by migrating authorization to kernel evaluation:
    • packages/assets/src/actions/assetActions.ts now evaluates asset access via kernel in getAsset, getAssetDetailBundle, and listAssets.
    • Added shared asset authorization subject resolution and asset record normalization from assets + asset_associations (client/team/assignment hooks).
  • (2026-04-21) Completed F049 by enabling premium bundle narrowing on migrated asset paths:
    • Asset kernel calls now include BundleAuthorizationKernelProvider with resolveBundleNarrowingRulesForEvaluation(...), allowing published client/team/assignment bundle templates to narrow asset visibility on selected surfaces.
  • (2026-04-21) Validation runbook for F048-F049 checkpoint:
    • cd packages/assets && npx tsc --pretty false --noEmit -p tsconfig.json
    • cd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
    • cd packages/assets && npx vitest run tests --coverage.enabled=false (no matching tests discovered in this package)
  • (2026-04-21) Completed F050 by migrating selected billing (quote) visibility/mutation paths onto kernel checks:
    • packages/billing/src/actions/quoteActions.ts now authorizes getQuote and listQuotes through kernel authorizeResource (resource billing:read) after RBAC.
    • approveQuote now uses kernel authorizeMutation for approval guards before state transition.
  • (2026-04-21) Completed F051 by enabling premium billing bundle narrowing on migrated quote paths:
    • Billing quote read/approve kernel calls now include BundleAuthorizationKernelProvider with resolveBundleNarrowingRulesForEvaluation(...), enabling client-portfolio style narrowing and bundle mutation constraints.
  • (2026-04-21) Completed F052 by adding billing field-redaction hook application on selected quote surfaces:
    • getQuote and listQuotes now apply kernel redactedFields to returned quote payloads without changing base allow/deny semantics.
  • (2026-04-21) Validation runbook for F050-F052 checkpoint:
    • cd packages/billing && npx tsc --pretty false --noEmit -p tsconfig.json
    • cd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
    • cd packages/billing && npx vitest run tests/contractReportActions.revenue.assignmentFact.test.ts tests/contractReportActions.expiration.wiring.test.ts --coverage.enabled=false
  • (2026-04-21) Completed F053 and F054 for selected API-key-backed v1 parity read surfaces by moving API authorization to shared kernel decisions:
    • Added API helper server/src/lib/api/controllers/authorizationKernel.ts for subject normalization and kernel delegation.
    • Added apiKeyId to API request context (ApiContext, ApiBaseController.authenticate) so API-key bundle assignments are intersected in authorization subject evaluation.
    • Kernelized selected read paths in:
      • server/src/lib/api/controllers/ApiTicketController.ts (list, getById)
      • server/src/lib/api/controllers/ApiProjectController.ts (list, getById)
      • server/src/lib/api/controllers/ApiQuoteController.ts (list, getById)
    • These controllers now apply shared-kernel allow/deny checks per record, instead of RBAC-only pass-through.
  • (2026-04-21) Completed F055 by ensuring migrated API/server-action authorization uses shared kernel loading (getAuthorizationKernel) so CE remains on builtin-kernel runtime while EE overlays remain edition-gated.
  • (2026-04-21) Completed F056 by adding DB-backed narrowing regression coverage for assignment guards and intersection composition to catch silent broadening on migrated paths.
  • (2026-04-21) Completed T004, T005, T006, and T012 with DB-backed integration coverage in server/src/test/integration/authorization/bundleAssignmentResolution.integration.test.ts:
    • assignment target validation rejects invalid role/team/user/api_key references
    • role+team+user bundle attachments compose as narrowing intersections
    • api-key bundle restrictions intersect with impersonated user bundles
    • role assignment to published bundle immediately narrows ticket read decisions
  • (2026-04-21) Completed T008 and T009 using existing kernel guard/intersection unit tests (server/src/test/unit/authorization/kernel.engine.test.ts) and reinforced by new integration assertions.
  • (2026-04-21) Completed T030 via existing legacy-direction guard (server/src/test/unit/authorization/kernel.legacyDirection.test.ts).
  • (2026-04-21) Added API helper unit coverage in server/src/test/unit/api/authorizationKernel.test.ts for subject shaping and shared-kernel delegation.
  • (2026-04-21) Validation runbook for F053-F056 + tests checkpoint:
    • npx tsc --pretty false --noEmit -p server/tsconfig.json
    • cd server && npx vitest run --coverage.enabled=false src/test/unit/api/authorizationKernel.test.ts src/test/integration/authorization/bundleAssignmentResolution.integration.test.ts
  • (2026-04-21) Completed T007 with shared-contract mode tests in server/src/test/unit/authorization/kernel.contract.modes.test.ts:
    • validates that CE mode (builtin only) and EE-overlay mode (builtin + bundle provider) both expose and execute shared kernel entry points (authorizeResource, resolveScope, authorizeMutation, explainDecision).
  • (2026-04-21) Additional validation runbook:
    • cd server && npx vitest run --coverage.enabled=false src/test/unit/authorization/kernel.contract.modes.test.ts src/test/unit/api/authorizationKernel.test.ts
  • (2026-04-21) Completed T029 by extending server/src/test/unit/authorization/kernel.engine.test.ts with explicit reason-chain assertions that include RBAC gate (rbac_allowed), builtin relationship path (relationship_rules_allowed), and bundle narrowing (bundle_narrowing_applied).
  • (2026-04-21) Note on current integration runner state: repeated full integration reruns encountered transient DB pool exhaustion (KnexTimeoutError during test DB recreation). Unit-level checkpoints continue to run reliably; heavy integration reruns should be resumed after DB pool reset.
  • (2026-04-21) Completed T010 with simulator action unit coverage in server/src/test/unit/authorization/bundleSimulatorAction.test.ts:
    • validates real principal + persisted-record simulation paths (listAuthorizationSimulationPrincipalsAction, listAuthorizationSimulationRecordsAction, runAuthorizationBundleSimulationAction)
    • validates synthetic scenario simulation path (no persisted record lookup) against the same draft-vs-published decision flow
    • asserts explainability reason chains are emitted for both revisions (for example rbac:rbac_allowed, bundle:bundle_narrowing_applied, bundle:bundle_template_denied)
  • (2026-04-21) Fixed simulator action wiring in ee/server/src/lib/actions/auth/authorizationBundleActions.ts by restoring in-action record resolution and removing an orphaned trailing record block that had drifted outside any action scope.
  • (2026-04-21) Validation runbook for T010 checkpoint:
    • cd server && npx vitest run --coverage.enabled=false src/test/unit/authorization/bundleSimulatorAction.test.ts
    • cd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
  • (2026-04-21) Completed T011 with tier/edition guard coverage across EE actions and CE fallback surfaces:
    • server/src/test/unit/authorization/bundleSimulatorAction.test.ts now asserts non-entitled tier gating blocks EE bundle-management actions before service calls.
    • server/src/test/unit/authorization/kernel.ceFallback.test.ts verifies CE fallback behavior: when enterprise kernel factory is unavailable, getAuthorizationKernel() still runs builtin authorization decisions.
    • server/src/test/unit/authorization/cePolicyManagement.placeholder.test.ts enforces CE placeholder UI copy includes Premium upgrade guidance while explicitly stating builtin authorization remains active.
  • (2026-04-21) Validation runbook for T011 checkpoint:
    • cd server && npx vitest run --coverage.enabled=false src/test/unit/authorization/bundleSimulatorAction.test.ts src/test/unit/authorization/kernel.ceFallback.test.ts src/test/unit/authorization/cePolicyManagement.placeholder.test.ts
    • cd .. && npx tsc --pretty false --noEmit -p server/tsconfig.json
  • (2026-04-21) Completed T013 with ticket authorization narrowing regression coverage in packages/tickets/src/actions/ticketActions.authorizationNarrowing.test.ts:
    • validates migrated getTicketsForList + getTicketById preserve baseline client board-narrowing behavior via selected board visibility.
    • validates selected-client + selected-board bundle restrictions are enforced on list/detail paths in the migrated ticket authorization flow.
  • (2026-04-21) Validation runbook for T013 checkpoint:
    • cd packages/tickets && npx vitest run src/actions/ticketActions.authorizationNarrowing.test.ts --coverage.enabled=false
  • (2026-04-21) Completed T014 by extending packages/tickets/src/actions/ticketActions.authorizationNarrowing.test.ts with API/UI parity coverage:
    • compares migrated UI list scope (getTicketsForList) with API helper scope (authorizeApiResourceRead) under the same tenant/user/bundle-rule context.
    • asserts the same effective allowed ticket IDs for both paths in the selected v1 ticket parity scenario.
  • (2026-04-21) Completed T015 and T016 with document authorization contract coverage in packages/documents/tests/documentActions.authorization.contract.test.ts:
    • T015: verifies migrated document paths preserve client baseline own/same-client/client-visible semantics while including selected-client bundle narrowing hooks.
    • T016: verifies document redaction wiring applies redactedFields on allowed records without changing allow/deny filtering.
  • (2026-04-21) Completed T017, T018, and T019 with runtime delegation/approval coverage in packages/scheduling/tests/timeEntryDelegationAuth.authorization.test.ts:
    • T017: validates self, manager, reports-to, and tenant-wide delegation semantics remain intact.
    • T018: validates premium bundle overlays narrow delegation (for example self-only on read-all users) and do not broaden non-managed access.
    • T019: validates not-self-approver guard remains enforced in kernelized approval flow.
  • (2026-04-21) Completed T020 with project authorization contract coverage in packages/projects/src/actions/projectAuthorization.contract.test.ts:
    • preserves own-comment/internal-user behavior in projectTaskCommentActions.ts and bundle-aware kernel narrowing on project list/detail in projectActions.ts.
  • (2026-04-21) Completed T021 with asset authorization contract coverage in packages/assets/src/actions/assetAuthorization.contract.test.ts:
    • verifies selected migrated asset surfaces (getAsset, getAssetDetailBundle, listAssets) remain on shared kernel evaluation with bundle narrowing overlays.
  • (2026-04-21) Completed T022 and T023 with billing quote authorization contract coverage in packages/billing/tests/quoteAuthorization.contract.test.ts:
    • T022: verifies selected quote read/approve paths stay on kernel read/mutation checks with bundle narrowing and self-approver guard.
    • T023: verifies quote field redaction wiring on allowed records for both detail and list flows.
  • (2026-04-21) Completed T024, T025, and T027 with EE bundle-management contract coverage in server/src/test/unit/authorization/bundleManagement.contract.test.ts:
    • T024: verifies draft-first editor/publish/assignment flow wiring and explicit revision publishing seam.
    • T025: verifies resource-section and human-readable summary wiring in both UI and server payloads.
    • T027: verifies audit trail event model includes bundle/revision/assignment lifecycle metadata and chronological sorting.
  • (2026-04-21) Completed T026 with runtime action guard coverage in server/src/test/unit/authorization/bundleManagementPermissions.test.ts:
    • verifies create/edit/publish/assignment/simulator actions fail closed when system_settings permission is missing and no mutating service call executes.
  • (2026-04-21) Completed T028 with CE migration contract coverage in server/src/test/unit/authorization/kernel.ceMigratedFlows.contract.test.ts:
    • verifies selected migrated ticket/document/time/project/asset/billing paths continue to wire through shared builtin kernel entry points.
  • (2026-04-21) Validation runbook for T015-T028 checkpoint:
    • cd packages/documents && npx vitest run tests/documentActions.authorization.contract.test.ts --coverage.enabled=false
    • cd packages/scheduling && npx vitest run tests/timeEntryDelegationAuth.authorization.test.ts --coverage.enabled=false
    • cd packages/projects && npx vitest run src/actions/projectAuthorization.contract.test.ts --coverage.enabled=false
    • cd packages/assets && npx vitest run src/actions/assetAuthorization.contract.test.ts --coverage.enabled=false
    • cd packages/billing && npx vitest run tests/quoteAuthorization.contract.test.ts --coverage.enabled=false
    • cd server && npx vitest run src/test/unit/authorization/bundleManagement.contract.test.ts src/test/unit/authorization/kernel.ceMigratedFlows.contract.test.ts src/test/unit/authorization/bundleManagementPermissions.test.ts --coverage.enabled=false