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

7.7 KiB

Scratchpad — Extension Version Immutability and Version Viewer

  • Plan slug: extension-version-immutability-and-viewer
  • Created: 2026-02-10

What This Is

Working notes for implementing extension publish duplicate handling, strict version immutability, and a read-only versions viewer.

Decisions

  • (2026-02-10) Scope locked to three outcomes only: friendly duplicate-version errors, read-only versions viewer, strict immutability.
  • (2026-02-10) Strict immutability means version reuse is rejected even when content hash is identical.
  • (2026-02-10) Viewer is read-only in Extension Details; no invalidation/delete controls in this phase.

Discoveries / Constraints

  • (2026-02-10) CLI and UI publish flows converge on extFinalizeUpload and upsertVersionFromManifest.
  • (2026-02-10) Current registry v2 behavior allows version reuse and can attach multiple bundle hashes to one version.
  • (2026-02-10) Existing UI only surfaces current installed version; there is no full versions list UI.
  • (2026-02-10) Runner static ext-ui path is hash-addressed and heavily cached; strict immutability reduces future reuse ambiguity but does not clean up historical rows.

Commands / Runbooks

  • (2026-02-10) Scaffolded plan: python3 /Users/roberisaacs/.codex/skills/alga-plan/scripts/scaffold_plan.py "Extension Version Immutability and Version Viewer" --slug extension-version-immutability-and-viewer
  • (2026-02-10) Validate plan artifacts: python3 /Users/roberisaacs/.codex/skills/alga-plan/scripts/validate_plan.py ee/docs/plans/2026-02-10-extension-version-immutability-and-viewer
  • Publish flow entry: sdk/alga-client-sdk/src/lib/publish.ts
  • UI installer flow: ee/server/src/components/settings/extensions/InstallerPanel.tsx
  • Finalize action: ee/server/src/lib/actions/extBundleActions.ts
  • Registry v2 upsert semantics: ee/server/src/lib/extensions/registry-v2.ts
  • Versions list helper (existing internal): ee/server/src/lib/extensions/registry-v2-repo-knex.ts
  • Extension settings list/details UI: ee/server/src/components/settings/extensions/Extensions.tsx, ee/server/src/components/settings/extensions/ExtensionDetails.tsx
  • Runner ext-ui caching/validation: ee/runner/src/http/ext_ui.rs, ee/runner/src/registry/client.rs, ee/runner/src/engine/loader.rs

Open Questions

  • Should viewer expose only latest hash per version, or also a legacy “multiple bundles” indicator for versions that already have >1 hash?
  • Exact duplicate-version error code string to align with existing API error naming conventions.

Implementation Progress

  • (2026-02-10) Completed F001: Define duplicate-version API contract for finalize: HTTP 409 + stable error code + friendly message
  • (2026-02-10) Completed F002: Update registry-v2 finalize version upsert path to enforce strict immutability (reject existing version regardless of hash)
  • (2026-02-10) Completed F003: Remove/disable duplicate-version branch that currently appends a new bundle hash to an existing version
  • (2026-02-10) Completed F004: Map DB unique-constraint races for (registry_id, version) to the same friendly duplicate-version 409 response
  • (2026-02-10) Completed F005: Ensure ext-bundles/finalize route and server action return consistent duplicate-version error payloads for UI and CLI callers
  • (2026-02-10) Completed F006: Update installer/publish UI flow to surface duplicate-version message directly to users
  • (2026-02-10) Completed F007: Add registry query/action to list all versions for a registry extension in tenant context
  • (2026-02-10) Completed F008: Include in version list payload: version string, created/published timestamp, latest content hash metadata
  • (2026-02-10) Completed F009: Include installed marker in version list payload by joining tenant_extension_install.version_id
  • (2026-02-10) Completed F010: Handle legacy version rows with multiple bundles by deterministically selecting latest bundle metadata in viewer payload
  • (2026-02-10) Completed F011: Render read-only Versions section in Extension Details page
  • (2026-02-10) Completed F012: Versions table shows columns Version, Published, Content hash, Installed
  • (2026-02-10) Completed F013: Versions section includes explicit empty state when no versions exist
  • (2026-02-10) Completed F014: Enforce existing permission checks for version listing (extension read scope)
  • (2026-02-10) Completed F015: Add tests for duplicate-version friendly response in both direct duplicate and race-condition paths
  • (2026-02-10) Completed F016: Add tests for strict immutability guaranteeing no new bundle rows are created when version already exists
  • (2026-02-10) Completed F017: Add tests for versions viewer backend query covering installed marker and legacy multi-bundle versions
  • (2026-02-10) Completed F018: Add UI tests for Extension Details versions section rendering, sorting, and empty state
  • (2026-02-10) Completed T001: Finalize returns HTTP 409 with stable duplicate-version error code when manifest version already exists for extension
  • (2026-02-10) Completed T002: Duplicate-version 409 payload includes user-friendly message with conflicting version value
  • (2026-02-10) Completed T003: Finalize rejects duplicate version when incoming content hash is identical to existing bundle hash
  • (2026-02-10) Completed T004: Finalize rejects duplicate version when incoming content hash differs from existing bundle hash
  • (2026-02-10) Completed T005: Version-upsert path does not create a new extension_bundle row for duplicate version attempts
  • (2026-02-10) Completed T006: Concurrent finalize requests for same publisher/name/version map losing request to friendly duplicate-version 409
  • (2026-02-10) Completed T007: DB unique violation for (registry_id, version) is normalized to duplicate-version code and message
  • (2026-02-10) Completed T008: Finalize HTTP route returns same duplicate-version payload shape as server action result
  • (2026-02-10) Completed T009: Installer UI shows duplicate-version friendly message from finalize response without generic fallback text
  • (2026-02-10) Completed T010: CLI publish surfaces duplicate-version response message from finalize path
  • (2026-02-10) Completed T011: Version list backend returns all versions for given registry extension sorted newest first
  • (2026-02-10) Completed T012: Version list backend includes version string and publish timestamp fields for each row
  • (2026-02-10) Completed T013: Version list backend includes deterministic latest content hash metadata per version
  • (2026-02-10) Completed T014: Version list marks installed=true only for row matching tenant_extension_install.version_id
  • (2026-02-10) Completed T015: Version list handles extension with no install row by returning all rows installed=false
  • (2026-02-10) Completed T016: Legacy data case: one version with multiple bundle rows still returns one deterministic viewer row
  • (2026-02-10) Completed T017: Extension Details page renders Versions section heading and table when version data exists
  • (2026-02-10) Completed T018: Versions table renders expected columns Version, Published, Content hash, Installed
  • (2026-02-10) Completed T019: Versions table rows are sorted newest-first by publish timestamp
  • (2026-02-10) Completed T020: Versions section renders empty-state copy when backend returns no rows
  • (2026-02-10) Completed T021: Unauthorized caller cannot access version-list backend action/route without extension read permission
  • (2026-02-10) Completed T022: Authorized extension-read caller can access version-list backend action/route
  • (2026-02-10) Completed T023: Strict immutability leaves existing historical duplicate-bundle data untouched (no destructive migration)
  • (2026-02-10) Completed T024: Finalize happy path still succeeds for brand-new version values