Skip to content

Establish stable Knowledge Asset versioning - #23

Merged
kl3inIT merged 2 commits into
mainfrom
kl3inIT/knowledge-asset-foundation
Jul 23, 2026
Merged

Establish stable Knowledge Asset versioning#23
kl3inIT merged 2 commits into
mainfrom
kl3inIT/knowledge-asset-foundation

Conversation

@kl3inIT

@kl3inIT kl3inIT commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • split stable KnowledgeAsset authorization identity from immutable KnowledgeAssetVersion content/provenance
  • make source revisions monotonic and publication transactional across PostgreSQL/OpenFGA with worker convergence
  • share chunking across upload and connector ingestion, then remove the retired Capability Asset MVP and stale contracts/docs

Safety invariants

  • retrieval pins current stable asset, immutable active version, current source revision, ACL/model/profile, and projection generation
  • OpenFGA is called only after PostgreSQL prepare commits; failures remain retryable and fail closed
  • convergence scans all tuple pages before deleting managed orphan tuples

Verification

  • ./gradlew --no-daemon clean build
  • corepack pnpm -C web check:api
  • corepack pnpm -C web typecheck
  • corepack pnpm -C web build
  • fga model test --tests store.fga.yaml (5/5 tests, 19/19 checks, 5/5 ListObjects)
  • generated API and route-tree drift checks
  • Markdown relative-link check

JetBrains MCP inspection was unavailable in this session; the repository fallback compile/full-test/mechanical gates were used.

Summary by CodeRabbit

  • New Features

    • Introduced immutable, versioned knowledge assets with evidence links and source revision tracking.
    • Added permission-aware retrieval against the currently published asset version.
    • Added scheduled authorization reconciliation to repair model drift and remove orphaned access entries.
    • Improved ingestion chunking with configurable limits, versioning, and page metadata.
  • Bug Fixes

    • Improved publication ordering and retry consistency for source revisions and knowledge asset versions.
    • Removed deferred-content outcomes from ingestion reporting.
  • Documentation

    • Updated architecture, README, and testing guidance to reflect the knowledge lifecycle model.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kl3inIT, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 10 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 71d501ab-b7b8-4ccf-ae62-62f139c3d90e

📥 Commits

Reviewing files that changed from the base of the PR and between 2deb78d and 745b3c6.

⛔ Files ignored due to path filters (2)
  • docs/decisions/0012-stable-knowledge-assets-and-immutable-versions.md is excluded by !docs/**
  • docs/increments/completed/2026-07-23-knowledge-asset-foundation/design.md is excluded by !docs/**
📒 Files selected for processing (11)
  • .codex/skills/orgmemory-create-test/SKILL.md
  • apps/worker/src/main/java/com/orgmemory/worker/authorization/KnowledgeAuthorizationConvergenceScheduler.java
  • apps/worker/src/main/java/com/orgmemory/worker/ingestion/SourceIngestionProcessor.java
  • apps/worker/src/main/java/com/orgmemory/worker/ingestion/SourceProcessingProperties.java
  • apps/worker/src/main/java/com/orgmemory/worker/ingestion/SpringAiKnowledgeTextChunker.java
  • apps/worker/src/test/java/com/orgmemory/worker/ingestion/SpringAiKnowledgeTextChunkerTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorReconciler.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeChunkDraftAssembler.java
  • core/src/main/resources/db/migration/V22__knowledge_asset_identity_and_legacy_cleanup.sql
  • core/src/test/java/com/orgmemory/core/knowledge/KnowledgeAssetLegacyResetMigrationIntegrationTests.java
  • core/src/test/java/com/orgmemory/core/knowledge/KnowledgeChunkDraftAssemblerTests.java
📝 Walkthrough

Walkthrough

This PR replaces capability-asset persistence and authorization flows with versioned knowledge assets, source revision staging, version-aware publication and retrieval, OpenFGA tuple convergence, delegated chunking, updated migrations, and corresponding integration-test fixtures and documentation.

Changes

Knowledge lifecycle modernization

Layer / File(s) Summary
Versioned knowledge persistence
core/src/main/java/com/orgmemory/core/knowledge/*, core/src/main/resources/db/migration/V22__...sql
Stable knowledge assets, immutable versions, evidence links, source revision pointers, and version-chain database constraints are introduced.
Connector revision and chunking flow
core/src/main/java/com/orgmemory/core/knowledge/Connector*, apps/worker/src/main/java/com/orgmemory/worker/ingestion/*
Connector ingestion stages or reuses revisions, delegates chunking through KnowledgeTextChunker, embeds chunks, and reports materialized or rotated outcomes.
Version-aware publication and retrieval
core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublication*, KnowledgeChunkProjectionStore.java, SecureKnowledgeRetrievalStore.java
Publication outbox records, chunk projections, source publication, and retrieval eligibility now include current asset-version identifiers.
Authorization tuple convergence
core/src/main/java/com/orgmemory/core/authorization/*, core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAuthorization*, integrations/authorization-openfga/*, apps/worker/src/main/java/com/orgmemory/worker/authorization/*
OpenFGA tuple reads, drift repair, orphan deletion, scheduled reconciliation, and indeterminate-result reporting are added.
Integration fixtures and validation
apps/api/src/test/*, apps/worker/src/test/*, core/src/test/*, integrations/*/src/test/*
Integration seeds and assertions are updated for stable assets, version rows, latest revisions, version-scoped chunks, and publication records.
Capability removal and documentation
apps/api/src/main/java/com/orgmemory/api/capability/*, core/src/main/java/com/orgmemory/core/capability/*, README.md, ARCHITECTURE.md, .codex/skills/*
Legacy capability-asset APIs, entities, authorization definitions, and fixtures are removed; documentation describes the knowledge lifecycle model.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.74% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: introducing stable Knowledge Asset versioning.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch kl3inIT/knowledge-asset-foundation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/worker/src/main/java/com/orgmemory/worker/ingestion/SourceIngestionProcessor.java (1)

156-172: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate chunk-embedding-to-draft assembly logic between upload and connector paths. Both files independently validate vectors.size() == texts.size() and build an identical KnowledgeChunkDraft(index, content, sha256, null, startPage, endPage, null, vector) list from chunks + embedding vectors — the same duplication pattern that chunking itself (KnowledgeTextChunker) was already extracted to solve.

  • apps/worker/src/main/java/com/orgmemory/worker/ingestion/SourceIngestionProcessor.java#L156-L172: extract this draft-building loop (and the preceding vector-count check) into a shared helper (e.g. alongside KnowledgeTextChunker) that both this class and ConnectorReconciler can call.
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorReconciler.java#L302-L314: replace this equivalent loop with the same shared helper once extracted.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/worker/src/main/java/com/orgmemory/worker/ingestion/SourceIngestionProcessor.java`
around lines 156 - 172, Extract the shared vector-count validation and
KnowledgeChunkDraft assembly from SourceIngestionProcessor and
ConnectorReconciler into a reusable helper alongside KnowledgeTextChunker,
preserving index, content, hash, page bounds, and vector fields. Update both
SourceIngestionProcessor.java:156-172 and ConnectorReconciler.java:302-314 to
call the helper and remove their duplicate loops.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.codex/skills/orgmemory-create-test/SKILL.md:
- Around line 15-23: Update the required test gates in the skill’s explicit
command guidance to follow docs/guidelines/testing-harness.md, covering the
worker, integration, frontend, and clean-test gates relevant to its ingestion,
publication, persistence, Modulith, and frontend scope. Use a terminating clean
test as the context gate and remove any implication that bootRun is
verification, while preserving the existing lifecycle rules.

In
`@apps/worker/src/main/java/com/orgmemory/worker/authorization/KnowledgeAuthorizationConvergenceScheduler.java`:
- Around line 33-54: Confirm that concurrent reconcile() executions across
worker replicas are supported by the deployment topology and underlying
idempotent operations. If they are not safe, update the scheduler to use a
distributed lock or equivalent single-runner coordination; otherwise document or
preserve the current fixedDelay scheduling while ensuring concurrent model
recording and orphan deletion remain safe.

In
`@apps/worker/src/main/java/com/orgmemory/worker/ingestion/SpringAiKnowledgeTextChunker.java`:
- Around line 18-48: Update the TokenTextSplitter configuration in
SpringAiKnowledgeTextChunker so withMaxNumChunks does not use
properties.maximumChunks() as the application cap; configure it with the
supported high or unbounded value instead. Preserve the manual chunks.size()
check and RejectedSourceException flow so oversized documents are rejected
rather than truncated.

In
`@core/src/main/resources/db/migration/V22__knowledge_asset_identity_and_legacy_cleanup.sql`:
- Around line 96-283: The migration applies blocking schema changes and
non-concurrent indexes, so choose and document an explicit deployment strategy.
For online application, replace applicable foreign-key and check additions with
NOT VALID followed by separate VALIDATE CONSTRAINT steps, use nullable-column
checks instead of immediate SET NOT NULL, and create indexes with CONCURRENTLY
in separate transactions; otherwise document that V22 requires a maintenance
window.
- Around line 36-37: Update the migration backfill before adding
uq_knowledge_asset_source so knowledge_assets is collapsed to at most one row
per (organization_id, source_object_id). Reuse a single stable
knowledge_asset_id for revisions sharing a source_object_id, resolve duplicate
rows deterministically, and remove or merge conflicting rows before creating the
unique constraint.

---

Outside diff comments:
In
`@apps/worker/src/main/java/com/orgmemory/worker/ingestion/SourceIngestionProcessor.java`:
- Around line 156-172: Extract the shared vector-count validation and
KnowledgeChunkDraft assembly from SourceIngestionProcessor and
ConnectorReconciler into a reusable helper alongside KnowledgeTextChunker,
preserving index, content, hash, page bounds, and vector fields. Update both
SourceIngestionProcessor.java:156-172 and ConnectorReconciler.java:302-314 to
call the helper and remove their duplicate loops.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 99b10115-41a4-4616-bb83-3ccf2a38a3da

📥 Commits

Reviewing files that changed from the base of the PR and between 34906ab and 2deb78d.

⛔ Files ignored due to path filters (17)
  • contracts/openapi.json is excluded by !contracts/openapi.json
  • docs/decisions/0012-stable-knowledge-assets-and-immutable-versions.md is excluded by !docs/**
  • docs/increments/active/2026-07-22-secure-hybrid-retrieval/plan.md is excluded by !docs/**
  • docs/increments/completed/2026-07-23-knowledge-asset-foundation/design.md is excluded by !docs/**
  • docs/increments/completed/2026-07-23-knowledge-asset-foundation/plan.md is excluded by !docs/**
  • docs/increments/completed/2026-07-23-permissions-admin/design.md is excluded by !docs/**
  • docs/roadmap.md is excluded by !docs/**
  • docs/specs/domains/capability-assets.md is excluded by !docs/**
  • docs/specs/domains/knowledge-ingestion.md is excluded by !docs/**
  • docs/specs/domains/relational-capability-graph.md is excluded by !docs/**
  • docs/specs/domains/secure-knowledge-graph.md is excluded by !docs/**
  • docs/specs/domains/secure-retrieval.md is excluded by !docs/**
  • docs/tests/domains/assistant-and-mcp.md is excluded by !docs/**
  • docs/tests/domains/capability-assets.md is excluded by !docs/**
  • docs/tests/domains/identity-and-organization.md is excluded by !docs/**
  • docs/vision.md is excluded by !docs/**
  • integrations/authorization-openfga/src/main/openfga/local-demo-tuples.csv is excluded by !**/*.csv
📒 Files selected for processing (92)
  • .codex/skills/orgmemory-create-test/SKILL.md
  • ARCHITECTURE.md
  • README.md
  • apps/api/src/main/java/com/orgmemory/api/ApiExceptionHandler.java
  • apps/api/src/main/java/com/orgmemory/api/capability/AssetVersionResponse.java
  • apps/api/src/main/java/com/orgmemory/api/capability/BackupOwnerRequest.java
  • apps/api/src/main/java/com/orgmemory/api/capability/CapabilityAssetController.java
  • apps/api/src/main/java/com/orgmemory/api/capability/CapabilityAssetResponse.java
  • apps/api/src/main/java/com/orgmemory/api/capability/CreateAssetRequest.java
  • apps/api/src/main/java/com/orgmemory/api/capability/ReviewRequest.java
  • apps/api/src/main/java/com/orgmemory/api/capability/UsageRequest.java
  • apps/api/src/main/java/com/orgmemory/api/capability/UsageResponse.java
  • apps/api/src/test/java/com/orgmemory/api/admin/PermissionsAdminIntegrationTests.java
  • apps/api/src/test/java/com/orgmemory/api/capability/CapabilityAssetServiceIntegrationTests.java
  • apps/api/src/test/java/com/orgmemory/api/knowledge/KnowledgeIngestionIntegrationTests.java
  • apps/worker/src/main/java/com/orgmemory/worker/OrgMemoryWorkerApplication.java
  • apps/worker/src/main/java/com/orgmemory/worker/authorization/KnowledgeAuthorizationConvergenceProperties.java
  • apps/worker/src/main/java/com/orgmemory/worker/authorization/KnowledgeAuthorizationConvergenceScheduler.java
  • apps/worker/src/main/java/com/orgmemory/worker/connector/ConnectorCrawlRunner.java
  • apps/worker/src/main/java/com/orgmemory/worker/ingestion/SourceIngestionProcessor.java
  • apps/worker/src/main/java/com/orgmemory/worker/ingestion/SpringAiKnowledgeTextChunker.java
  • apps/worker/src/main/resources/application.yml
  • apps/worker/src/test/java/com/orgmemory/worker/connector/ConnectorStagingIngestionIntegrationTests.java
  • apps/worker/src/test/java/com/orgmemory/worker/ingestion/SourceIngestionPipelineIntegrationTests.java
  • core/src/main/java/com/orgmemory/core/authorization/RelationshipTuplePage.java
  • core/src/main/java/com/orgmemory/core/authorization/RelationshipTupleReconciliationPort.java
  • core/src/main/java/com/orgmemory/core/capability/ApprovalAction.java
  • core/src/main/java/com/orgmemory/core/capability/AssetApprovalEvent.java
  • core/src/main/java/com/orgmemory/core/capability/AssetApprovalEventRepository.java
  • core/src/main/java/com/orgmemory/core/capability/AssetStatus.java
  • core/src/main/java/com/orgmemory/core/capability/AssetType.java
  • core/src/main/java/com/orgmemory/core/capability/AssetUsageEvent.java
  • core/src/main/java/com/orgmemory/core/capability/AssetUsageEventRepository.java
  • core/src/main/java/com/orgmemory/core/capability/AssetUsageTotal.java
  • core/src/main/java/com/orgmemory/core/capability/AssetVersion.java
  • core/src/main/java/com/orgmemory/core/capability/AssetVersionRepository.java
  • core/src/main/java/com/orgmemory/core/capability/AssetVisibility.java
  • core/src/main/java/com/orgmemory/core/capability/CapabilityAsset.java
  • core/src/main/java/com/orgmemory/core/capability/CapabilityAssetListing.java
  • core/src/main/java/com/orgmemory/core/capability/CapabilityAssetNotFoundException.java
  • core/src/main/java/com/orgmemory/core/capability/CapabilityAssetRepository.java
  • core/src/main/java/com/orgmemory/core/capability/CapabilityAssetService.java
  • core/src/main/java/com/orgmemory/core/capability/CreateCapabilityAssetCommand.java
  • core/src/main/java/com/orgmemory/core/capability/RiskLevel.java
  • core/src/main/java/com/orgmemory/core/capability/UsageEventType.java
  • core/src/main/java/com/orgmemory/core/capability/package-info.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorIngestionResult.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorIngestionService.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorReconciler.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorRevisionDraft.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorSourceRevisionCoordinator.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAsset.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceLink.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceLinkRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceRole.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationCoordinator.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationOutbox.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationOutboxRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationState.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetRef.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersion.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersionRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersionStatus.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceReport.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceService.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeChunkProjectionStore.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeIngestionService.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextChunk.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextChunker.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextDocument.java
  • core/src/main/java/com/orgmemory/core/knowledge/PromoteNormalizedRecordCommand.java
  • core/src/main/java/com/orgmemory/core/knowledge/PublishKnowledgeAssetCommand.java
  • core/src/main/java/com/orgmemory/core/knowledge/SecureKnowledgeRetrievalStore.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceIngestionCoordinator.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceObject.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceQueryService.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceRevision.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceRevisionRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceUploadRegistrationService.java
  • core/src/main/resources/db/migration/V22__knowledge_asset_identity_and_legacy_cleanup.sql
  • core/src/test/java/com/orgmemory/core/authorization/BatchAuthorizationQueryTests.java
  • core/src/test/java/com/orgmemory/core/knowledge/ExternalPrincipalRetrievalIntegrationTests.java
  • core/src/test/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceServiceTests.java
  • core/src/test/java/com/orgmemory/core/knowledge/SourceQueryServiceTests.java
  • integrations/authorization-openfga/src/main/java/com/orgmemory/integrations/authorization/openfga/OpenFgaAuthorizationConfiguration.java
  • integrations/authorization-openfga/src/main/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipTupleReconciliationAdapter.java
  • integrations/authorization-openfga/src/main/openfga/model.fga
  • integrations/authorization-openfga/src/test/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipAuthorizationSetAdapterTests.java
  • integrations/authorization-openfga/src/test/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipTupleReconciliationAdapterTests.java
  • integrations/authorization-openfga/src/test/openfga/store.fga.yaml
  • integrations/graph-rag-postgres/src/test/java/com/orgmemory/graphrag/postgres/PostgresGraphProjectionStoreIntegrationTests.java
💤 Files with no reviewable changes (33)
  • apps/api/src/main/java/com/orgmemory/api/capability/BackupOwnerRequest.java
  • core/src/main/java/com/orgmemory/core/capability/AssetStatus.java
  • apps/api/src/main/java/com/orgmemory/api/capability/CreateAssetRequest.java
  • core/src/main/java/com/orgmemory/core/capability/CreateCapabilityAssetCommand.java
  • core/src/main/java/com/orgmemory/core/capability/AssetUsageEventRepository.java
  • core/src/main/java/com/orgmemory/core/capability/AssetApprovalEventRepository.java
  • apps/api/src/main/java/com/orgmemory/api/capability/AssetVersionResponse.java
  • core/src/main/java/com/orgmemory/core/capability/RiskLevel.java
  • apps/api/src/main/java/com/orgmemory/api/capability/UsageRequest.java
  • core/src/main/java/com/orgmemory/core/capability/AssetType.java
  • core/src/main/java/com/orgmemory/core/capability/AssetVisibility.java
  • core/src/main/java/com/orgmemory/core/capability/CapabilityAssetListing.java
  • core/src/main/java/com/orgmemory/core/capability/AssetApprovalEvent.java
  • core/src/main/java/com/orgmemory/core/capability/ApprovalAction.java
  • core/src/main/java/com/orgmemory/core/capability/AssetUsageEvent.java
  • core/src/main/java/com/orgmemory/core/capability/AssetVersion.java
  • apps/api/src/main/java/com/orgmemory/api/capability/CapabilityAssetResponse.java
  • core/src/main/java/com/orgmemory/core/capability/package-info.java
  • core/src/main/java/com/orgmemory/core/capability/CapabilityAssetRepository.java
  • core/src/main/java/com/orgmemory/core/capability/UsageEventType.java
  • apps/api/src/main/java/com/orgmemory/api/capability/CapabilityAssetController.java
  • core/src/main/java/com/orgmemory/core/capability/AssetUsageTotal.java
  • core/src/main/java/com/orgmemory/core/capability/CapabilityAssetNotFoundException.java
  • core/src/main/java/com/orgmemory/core/capability/AssetVersionRepository.java
  • apps/api/src/main/java/com/orgmemory/api/capability/UsageResponse.java
  • apps/api/src/main/java/com/orgmemory/api/capability/ReviewRequest.java
  • core/src/main/java/com/orgmemory/core/capability/CapabilityAsset.java
  • apps/api/src/main/java/com/orgmemory/api/ApiExceptionHandler.java
  • apps/api/src/test/java/com/orgmemory/api/capability/CapabilityAssetServiceIntegrationTests.java
  • integrations/authorization-openfga/src/main/openfga/model.fga
  • core/src/main/java/com/orgmemory/core/capability/CapabilityAssetService.java
  • core/src/main/java/com/orgmemory/core/knowledge/PublishKnowledgeAssetCommand.java
  • integrations/authorization-openfga/src/test/openfga/store.fga.yaml
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Backend · Java 25
🧰 Additional context used
📓 Path-based instructions (7)
**/*

📄 CodeRabbit inference engine (CLAUDE.md)

**/*: Before changing unfamiliar Spring Boot 4, Spring Modulith 2, Spring AI 2, Gradle, React, Vite, Tailwind, or TypeScript APIs, consult Context7/current official documentation and the project orgmemory-* verification skills.
Read docs/guidelines/agent-safety.md before retrieval, AI, MCP, permission, upload, graph, or export work.
Never commit .env files, provider keys, tokens, or customer data.
Run the relevant gates from docs/guidelines/testing-harness.md; use a terminating clean test as the context gate, and do not treat bootRun as verification.
Current behavior belongs in architecture/specs only after it exists in code; intent belongs in vision, roadmap, or an active increment, and repository state must not be duplicated across documents.

Files:

  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorRevisionDraft.java
  • core/src/main/java/com/orgmemory/core/authorization/RelationshipTupleReconciliationPort.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationState.java
  • apps/worker/src/main/java/com/orgmemory/worker/authorization/KnowledgeAuthorizationConvergenceScheduler.java
  • apps/worker/src/main/java/com/orgmemory/worker/connector/ConnectorCrawlRunner.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorSourceRevisionCoordinator.java
  • core/src/test/java/com/orgmemory/core/knowledge/SourceQueryServiceTests.java
  • core/src/main/java/com/orgmemory/core/authorization/RelationshipTuplePage.java
  • core/src/main/java/com/orgmemory/core/knowledge/PromoteNormalizedRecordCommand.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextDocument.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceRole.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceLinkRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceReport.java
  • integrations/authorization-openfga/src/test/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipAuthorizationSetAdapterTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextChunker.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersionRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetRef.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextChunk.java
  • README.md
  • core/src/main/java/com/orgmemory/core/knowledge/SourceQueryService.java
  • apps/worker/src/main/resources/application.yml
  • integrations/authorization-openfga/src/main/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipTupleReconciliationAdapter.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersionStatus.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceRevisionRepository.java
  • integrations/authorization-openfga/src/test/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipTupleReconciliationAdapterTests.java
  • apps/worker/src/main/java/com/orgmemory/worker/authorization/KnowledgeAuthorizationConvergenceProperties.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorIngestionResult.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceLink.java
  • core/src/test/java/com/orgmemory/core/authorization/BatchAuthorizationQueryTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceUploadRegistrationService.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceIngestionCoordinator.java
  • core/src/test/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceServiceTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersion.java
  • apps/worker/src/main/java/com/orgmemory/worker/OrgMemoryWorkerApplication.java
  • apps/api/src/test/java/com/orgmemory/api/knowledge/KnowledgeIngestionIntegrationTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationOutboxRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetRepository.java
  • apps/worker/src/main/java/com/orgmemory/worker/ingestion/SpringAiKnowledgeTextChunker.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationOutbox.java
  • integrations/authorization-openfga/src/main/java/com/orgmemory/integrations/authorization/openfga/OpenFgaAuthorizationConfiguration.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceObject.java
  • apps/worker/src/test/java/com/orgmemory/worker/ingestion/SourceIngestionPipelineIntegrationTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeChunkProjectionStore.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationCoordinator.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceService.java
  • apps/worker/src/test/java/com/orgmemory/worker/connector/ConnectorStagingIngestionIntegrationTests.java
  • ARCHITECTURE.md
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorIngestionService.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAsset.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceRevision.java
  • apps/api/src/test/java/com/orgmemory/api/admin/PermissionsAdminIntegrationTests.java
  • core/src/main/resources/db/migration/V22__knowledge_asset_identity_and_legacy_cleanup.sql
  • integrations/graph-rag-postgres/src/test/java/com/orgmemory/graphrag/postgres/PostgresGraphProjectionStoreIntegrationTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeIngestionService.java
  • core/src/main/java/com/orgmemory/core/knowledge/SecureKnowledgeRetrievalStore.java
  • apps/worker/src/main/java/com/orgmemory/worker/ingestion/SourceIngestionProcessor.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorReconciler.java
  • core/src/test/java/com/orgmemory/core/knowledge/ExternalPrincipalRetrievalIntegrationTests.java
**/*.{java,sql}

📄 CodeRabbit inference engine (CLAUDE.md)

Pair JPA schema changes with a Flyway migration.

Files:

  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorRevisionDraft.java
  • core/src/main/java/com/orgmemory/core/authorization/RelationshipTupleReconciliationPort.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationState.java
  • apps/worker/src/main/java/com/orgmemory/worker/authorization/KnowledgeAuthorizationConvergenceScheduler.java
  • apps/worker/src/main/java/com/orgmemory/worker/connector/ConnectorCrawlRunner.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorSourceRevisionCoordinator.java
  • core/src/test/java/com/orgmemory/core/knowledge/SourceQueryServiceTests.java
  • core/src/main/java/com/orgmemory/core/authorization/RelationshipTuplePage.java
  • core/src/main/java/com/orgmemory/core/knowledge/PromoteNormalizedRecordCommand.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextDocument.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceRole.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceLinkRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceReport.java
  • integrations/authorization-openfga/src/test/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipAuthorizationSetAdapterTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextChunker.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersionRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetRef.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextChunk.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceQueryService.java
  • integrations/authorization-openfga/src/main/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipTupleReconciliationAdapter.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersionStatus.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceRevisionRepository.java
  • integrations/authorization-openfga/src/test/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipTupleReconciliationAdapterTests.java
  • apps/worker/src/main/java/com/orgmemory/worker/authorization/KnowledgeAuthorizationConvergenceProperties.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorIngestionResult.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceLink.java
  • core/src/test/java/com/orgmemory/core/authorization/BatchAuthorizationQueryTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceUploadRegistrationService.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceIngestionCoordinator.java
  • core/src/test/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceServiceTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersion.java
  • apps/worker/src/main/java/com/orgmemory/worker/OrgMemoryWorkerApplication.java
  • apps/api/src/test/java/com/orgmemory/api/knowledge/KnowledgeIngestionIntegrationTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationOutboxRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetRepository.java
  • apps/worker/src/main/java/com/orgmemory/worker/ingestion/SpringAiKnowledgeTextChunker.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationOutbox.java
  • integrations/authorization-openfga/src/main/java/com/orgmemory/integrations/authorization/openfga/OpenFgaAuthorizationConfiguration.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceObject.java
  • apps/worker/src/test/java/com/orgmemory/worker/ingestion/SourceIngestionPipelineIntegrationTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeChunkProjectionStore.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationCoordinator.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceService.java
  • apps/worker/src/test/java/com/orgmemory/worker/connector/ConnectorStagingIngestionIntegrationTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorIngestionService.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAsset.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceRevision.java
  • apps/api/src/test/java/com/orgmemory/api/admin/PermissionsAdminIntegrationTests.java
  • core/src/main/resources/db/migration/V22__knowledge_asset_identity_and_legacy_cleanup.sql
  • integrations/graph-rag-postgres/src/test/java/com/orgmemory/graphrag/postgres/PostgresGraphProjectionStoreIntegrationTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeIngestionService.java
  • core/src/main/java/com/orgmemory/core/knowledge/SecureKnowledgeRetrievalStore.java
  • apps/worker/src/main/java/com/orgmemory/worker/ingestion/SourceIngestionProcessor.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorReconciler.java
  • core/src/test/java/com/orgmemory/core/knowledge/ExternalPrincipalRetrievalIntegrationTests.java
**/*.java

📄 CodeRabbit inference engine (CLAUDE.md)

JetBrains IDE inspection is a Java-backend gate only.

Files:

  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorRevisionDraft.java
  • core/src/main/java/com/orgmemory/core/authorization/RelationshipTupleReconciliationPort.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationState.java
  • apps/worker/src/main/java/com/orgmemory/worker/authorization/KnowledgeAuthorizationConvergenceScheduler.java
  • apps/worker/src/main/java/com/orgmemory/worker/connector/ConnectorCrawlRunner.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorSourceRevisionCoordinator.java
  • core/src/test/java/com/orgmemory/core/knowledge/SourceQueryServiceTests.java
  • core/src/main/java/com/orgmemory/core/authorization/RelationshipTuplePage.java
  • core/src/main/java/com/orgmemory/core/knowledge/PromoteNormalizedRecordCommand.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextDocument.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceRole.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceLinkRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceReport.java
  • integrations/authorization-openfga/src/test/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipAuthorizationSetAdapterTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextChunker.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersionRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetRef.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextChunk.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceQueryService.java
  • integrations/authorization-openfga/src/main/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipTupleReconciliationAdapter.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersionStatus.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceRevisionRepository.java
  • integrations/authorization-openfga/src/test/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipTupleReconciliationAdapterTests.java
  • apps/worker/src/main/java/com/orgmemory/worker/authorization/KnowledgeAuthorizationConvergenceProperties.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorIngestionResult.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceLink.java
  • core/src/test/java/com/orgmemory/core/authorization/BatchAuthorizationQueryTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceUploadRegistrationService.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceIngestionCoordinator.java
  • core/src/test/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceServiceTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersion.java
  • apps/worker/src/main/java/com/orgmemory/worker/OrgMemoryWorkerApplication.java
  • apps/api/src/test/java/com/orgmemory/api/knowledge/KnowledgeIngestionIntegrationTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationOutboxRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetRepository.java
  • apps/worker/src/main/java/com/orgmemory/worker/ingestion/SpringAiKnowledgeTextChunker.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationOutbox.java
  • integrations/authorization-openfga/src/main/java/com/orgmemory/integrations/authorization/openfga/OpenFgaAuthorizationConfiguration.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceObject.java
  • apps/worker/src/test/java/com/orgmemory/worker/ingestion/SourceIngestionPipelineIntegrationTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeChunkProjectionStore.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationCoordinator.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceService.java
  • apps/worker/src/test/java/com/orgmemory/worker/connector/ConnectorStagingIngestionIntegrationTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorIngestionService.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAsset.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceRevision.java
  • apps/api/src/test/java/com/orgmemory/api/admin/PermissionsAdminIntegrationTests.java
  • integrations/graph-rag-postgres/src/test/java/com/orgmemory/graphrag/postgres/PostgresGraphProjectionStoreIntegrationTests.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeIngestionService.java
  • core/src/main/java/com/orgmemory/core/knowledge/SecureKnowledgeRetrievalStore.java
  • apps/worker/src/main/java/com/orgmemory/worker/ingestion/SourceIngestionProcessor.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorReconciler.java
  • core/src/test/java/com/orgmemory/core/knowledge/ExternalPrincipalRetrievalIntegrationTests.java
core/src/main/java/com/orgmemory/core/{authorization,knowledge,permission}/**/*.java

⚙️ CodeRabbit configuration file

core/src/main/java/com/orgmemory/core/{authorization,knowledge,permission}/**/*.java: Treat PostgreSQL ACL evidence as canonical and OpenFGA as the relationship
authorization decision point. Authorization must fail closed. Filtering
must happen before ranking, LIMIT, graph traversal, answer generation,
export, and citation rendering. Flag metadata or timing leak paths.

Files:

  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorRevisionDraft.java
  • core/src/main/java/com/orgmemory/core/authorization/RelationshipTupleReconciliationPort.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationState.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorSourceRevisionCoordinator.java
  • core/src/main/java/com/orgmemory/core/authorization/RelationshipTuplePage.java
  • core/src/main/java/com/orgmemory/core/knowledge/PromoteNormalizedRecordCommand.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextDocument.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceRole.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceLinkRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceReport.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextChunker.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersionRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetRef.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeTextChunk.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceQueryService.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersionStatus.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceRevisionRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorIngestionResult.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetEvidenceLink.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceUploadRegistrationService.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceIngestionCoordinator.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetVersion.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationOutboxRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetRepository.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationOutbox.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceObject.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeChunkProjectionStore.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAssetPublicationCoordinator.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAuthorizationConvergenceService.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorIngestionService.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeAsset.java
  • core/src/main/java/com/orgmemory/core/knowledge/SourceRevision.java
  • core/src/main/java/com/orgmemory/core/knowledge/KnowledgeIngestionService.java
  • core/src/main/java/com/orgmemory/core/knowledge/SecureKnowledgeRetrievalStore.java
  • core/src/main/java/com/orgmemory/core/knowledge/ConnectorReconciler.java
integrations/authorization-openfga/**/*

⚙️ CodeRabbit configuration file

integrations/authorization-openfga/**/*: Source-native ACL is a hard ceiling. Flag any parent, organization, role,
or wildcard relation that can broaden source access. Require negative
Check and ListObjects coverage for every new permission path.

Files:

  • integrations/authorization-openfga/src/test/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipAuthorizationSetAdapterTests.java
  • integrations/authorization-openfga/src/main/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipTupleReconciliationAdapter.java
  • integrations/authorization-openfga/src/test/java/com/orgmemory/integrations/authorization/openfga/OpenFgaRelationshipTupleReconciliationAdapterTests.java
  • integrations/authorization-openfga/src/main/java/com/orgmemory/integrations/authorization/openfga/OpenFgaAuthorizationConfiguration.java
**/*.{yml,yaml,properties}

📄 CodeRabbit inference engine (CLAUDE.md)

Keep ddl-auto=validate in application configuration.

Files:

  • apps/worker/src/main/resources/application.yml
core/src/main/resources/db/migration/*.sql

⚙️ CodeRabbit configuration file

core/src/main/resources/db/migration/*.sql: Flyway migrations are immutable after release. Check tenant isolation,
foreign keys, uniqueness, indexes, append-only evidence semantics, safe
defaults, and compatibility with PostgreSQL 18 plus pgvector.

Files:

  • core/src/main/resources/db/migration/V22__knowledge_asset_identity_and_legacy_cleanup.sql
🪛 SQLFluff (4.2.2)
core/src/main/resources/db/migration/V22__knowledge_asset_identity_and_legacy_cleanup.sql

[error] 118-121: ADD CONSTRAINT ... FOREIGN KEY should use NOT VALID to avoid locking the table while validating existing rows.

(PG01)


[error] 130-138: ADD CONSTRAINT ... FOREIGN KEY should use NOT VALID to avoid locking the table while validating existing rows.

(PG01)


[error] 146-149: ADD CONSTRAINT ... FOREIGN KEY should use NOT VALID to avoid locking the table while validating existing rows.

(PG01)


[error] 266-267: CREATE INDEX should use CONCURRENTLY to avoid locking the table during the build.

(PG01)


[error] 268-270: CREATE INDEX should use CONCURRENTLY to avoid locking the table during the build.

(PG01)


[error] 271-272: CREATE INDEX should use CONCURRENTLY to avoid locking the table during the build.

(PG01)


[error] 273-274: CREATE INDEX should use CONCURRENTLY to avoid locking the table during the build.

(PG01)

🪛 Squawk (2.59.0)
core/src/main/resources/db/migration/V22__knowledge_asset_identity_and_legacy_cleanup.sql

[warning] 18-18: Renaming a table may break existing clients.

(renaming-table)


[warning] 97-97: Setting a column NOT NULL blocks reads while the table is scanned. Make the field nullable and use a CHECK constraint instead.

(adding-not-nullable-field)


[warning] 98-98: Setting a column NOT NULL blocks reads while the table is scanned. Make the field nullable and use a CHECK constraint instead.

(adding-not-nullable-field)


[warning] 99-100: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 99-100: Adding a UNIQUE constraint requires an ACCESS EXCLUSIVE lock which blocks reads and writes to the table while the index is built. Create an index CONCURRENTLY and create the constraint using the index.

(disallowed-unique-constraint)


[warning] 101-102: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 101-102: Adding a UNIQUE constraint requires an ACCESS EXCLUSIVE lock which blocks reads and writes to the table while the index is built. Create an index CONCURRENTLY and create the constraint using the index.

(disallowed-unique-constraint)


[warning] 103-104: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 103-104: Adding a UNIQUE constraint requires an ACCESS EXCLUSIVE lock which blocks reads and writes to the table while the index is built. Create an index CONCURRENTLY and create the constraint using the index.

(disallowed-unique-constraint)


[warning] 105-107: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 105-107: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 108-110: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 108-110: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 111-112: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 114-116: During normal index creation, table updates are blocked, but reads are still allowed. Use concurrently to avoid blocking writes.

(require-concurrent-index-creation)


[warning] 131-133: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 131-133: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 134-136: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 134-136: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 137-138: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 137-138: Adding a UNIQUE constraint requires an ACCESS EXCLUSIVE lock which blocks reads and writes to the table while the index is built. Create an index CONCURRENTLY and create the constraint using the index.

(disallowed-unique-constraint)


[warning] 147-149: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 147-149: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 158-158: Setting a column NOT NULL blocks reads while the table is scanned. Make the field nullable and use a CHECK constraint instead.

(adding-not-nullable-field)


[warning] 159-161: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 159-161: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 162-168: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 162-168: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 169-177: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 169-177: Adding a UNIQUE constraint requires an ACCESS EXCLUSIVE lock which blocks reads and writes to the table while the index is built. Create an index CONCURRENTLY and create the constraint using the index.

(disallowed-unique-constraint)


[warning] 187-187: Setting a column NOT NULL blocks reads while the table is scanned. Make the field nullable and use a CHECK constraint instead.

(adding-not-nullable-field)


[warning] 188-189: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 188-189: Adding a UNIQUE constraint requires an ACCESS EXCLUSIVE lock which blocks reads and writes to the table while the index is built. Create an index CONCURRENTLY and create the constraint using the index.

(disallowed-unique-constraint)


[warning] 190-192: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 190-192: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 193-199: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 193-199: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 207-207: Changing the size of a varchar field requires an ACCESS EXCLUSIVE lock, that will prevent all reads and writes to the table. Use a TEXT field with a CHECK constraint.

(prefer-text-field)


[warning] 208-208: Using 32-bit integer fields can result in hitting the max int limit. Use 64-bit integer values instead to prevent hitting this limit.

(prefer-bigint-over-int)


[warning] 209-209: Using 32-bit integer fields can result in hitting the max int limit. Use 64-bit integer values instead to prevent hitting this limit.

(prefer-bigint-over-int)


[warning] 271-272: During normal index creation, table updates are blocked, but reads are still allowed. Use concurrently to avoid blocking writes.

(require-concurrent-index-creation)


[warning] 280-283: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 280-283: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 287-287: Dropping a table may break existing clients.

(ban-drop-table)


[warning] 288-288: Dropping a table may break existing clients.

(ban-drop-table)


[warning] 289-289: Dropping a table may break existing clients.

(ban-drop-table)


[warning] 290-290: Dropping a table may break existing clients.

(ban-drop-table)


[warning] 291-291: Dropping a table may break existing clients.

(ban-drop-table)


[warning] 292-292: Dropping a table may break existing clients.

(ban-drop-table)


[warning] 293-293: Dropping a table may break existing clients.

(ban-drop-table)

Comment thread .codex/skills/orgmemory-create-test/SKILL.md
Comment on lines +36 to +37
CONSTRAINT uq_knowledge_asset_source
UNIQUE (organization_id, source_object_id),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect prior migrations for the old knowledge_assets/source_revisions shape and
# confirm the unique keys the new FKs depend on already exist.
fd -e sql . core/src/main/resources/db/migration | sort
echo "----- old knowledge_assets definition + source_revisions unique keys -----"
rg -n -C3 'knowledge_assets|source_revisions' core/src/main/resources/db/migration \
  | rg -n -C3 'CREATE TABLE|UNIQUE|source_object_id|knowledge_asset_id'

Repository: kl3inIT/OrgMemory

Length of output: 33683


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in \
  core/src/main/resources/db/migration/V11__knowledge_ingestion_spine.sql \
  core/src/main/resources/db/migration/V15__source_upload_and_embedding_pipeline.sql \
  core/src/main/resources/db/migration/V18__knowledge_space_upload_authorization.sql \
  core/src/main/resources/db/migration/V21__secure_graph_projection.sql \
  core/src/main/resources/db/migration/V22__knowledge_asset_identity_and_legacy_cleanup.sql
do
  echo "===== $f ====="
  sed -n '1,220p' "$f" | nl -ba -nln
done

echo "===== source_object_id usage in source_revisions and knowledge_assets insert/updates ====="
rg -n -C4 'source_object_id|knowledge_asset_id|source_revision_id|raw_source_object_id' core/src/main/resources/db/migration \
  | sed -n '1,260p'

Repository: kl3inIT/OrgMemory

Length of output: 280


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in \
  core/src/main/resources/db/migration/V11__knowledge_ingestion_spine.sql \
  core/src/main/resources/db/migration V15__source_upload_and_embedding_pipeline.sql \
  core/src/main/resources/db/migration/V18__knowledge_space_upload_authorization.sql \
  core/src/main/resources/db/migration/V21__secure_graph_projection.sql \
  core/src/main/resources/db/migration/V22__knowledge_asset_identity_and_legacy_cleanup.sql
do
  if [[ -f "$f" ]]; then
    echo "===== $f ====="
    awk '{printf "%6d\t%s\n", NR, $0}' "$f" | sed -n '1,240p'
  else
    echo "MISSING $f"
  fi
done

echo "===== source_object_id knowledge_asset_id source_revision_id raw_source_object_id usage ====="
rg -n -C4 'source_object_id|knowledge_asset_id|source_revision_id|raw_source_object_id' core/src/main/resources/db/migration \
  | sed -n '1,320p'

Repository: kl3inIT/OrgMemory

Length of output: 50373


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "===== files containing source_revisions table definition ====="
rg -n -C3 'CREATE TABLE source_revisions|source_revisions_knowledge_asset_id_fkey|current_revision_id|current_revision_id_fkey|uq_source_revision|source_revisions ADD CONSTRAINT|ALTER TABLE source_revisions .*source_revision' core/src/main/resources/db/migration

echo "===== V15 source upload full source_revisions definition ====="
awk '{printf "%6d\t%s\n", NR, $0}' core/src/main/resources/db/migration/V15__source_upload_and_embedding_pipeline.sql | sed -n '93,135p'

echo "===== source_revisions constraint/index names across migrations ====="
rg -n 'source_revisions[_(\s]|source_revisions\.)|source_revision.*fkey|source_revisions.*fkey|source_revision.*index|uq_source_revision|current_revision_id_fkey|uq_source_revision_current_revision' core/src/main/resources/db/migration \
  | sed -n '1,260p'

Repository: kl3inIT/OrgMemory

Length of output: 12607


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "===== source_object_id constraint/index names across migrations ====="
rg -n 'source_object_id|source_object.*fkey|source_object.*index|uq_source_object|current_revision_id|fk_source_object_current_revision|latest_revision_id|fk_source_object_latest_revision' core/src/main/resources/db/migration \
  | sed -n '1,220p'

echo "===== source_revisions CREATE TABLE full definition ====="
awk '{printf "%6d\t%s\n", NR, $0}' core/src/main/resources/db/migration/V15__source_upload_and_embedding_pipeline.sql \
  | sed -n '93,140p'

echo "===== source_objects relevant constraints and additions ====="
awk '{printf "%6d\t%s\n", NR, $0}' core/src/main/resources/db/migration/V15__source_upload_and_embedding_pipeline.sql \
  | sed -n '70,92p'
awk '{printf "%6d\t%s\n", NR, $0}' core/src/main/resources/db/migration/V16__secure_knowledge_asset_publication.sql \
  | sed -n '35,45p'
awk '{printf "%6d\t%s\n", NR, $0}' core/src/main/resources/db/migration/V18__knowledge_space_upload_authorization.sql \
  | sed -n '75,85p'
awk '{printf "%6d\t%s\n", NR, $0}' core/src/main/resources/db/migration/V22__knowledge_asset_identity_and_legacy_cleanup.sql \
  | sed -n '140,150p'

echo "===== knowledge_assets knowledge_asset_id constraints across migrations ====="
rg -n 'knowledge_assets|knowledge_asset_id|knowledge_assets\.)|knowledge_assets_fkey|source_revisions_knowledge_asset_id_fkey' core/src/main/resources/db/migration \
  | sed -n '1,200p'

Repository: kl3inIT/OrgMemory

Length of output: 12997


Deduplicate the backfill before adding uq_knowledge_asset_source.

source_revisions models multiple revisions per source_object_id (uq_source_revision_number and uq_source_revision_content), so an existing knowledge_assets row can reuse an existing stable knowledge_asset_id across multiple revisions, or multiple rows can end up choosing the same source_object_id. Add the UNIQUE after a collapsed backfill or otherwise enforce at most one stable asset per (organization_id, source_object_id).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@core/src/main/resources/db/migration/V22__knowledge_asset_identity_and_legacy_cleanup.sql`
around lines 36 - 37, Update the migration backfill before adding
uq_knowledge_asset_source so knowledge_assets is collapsed to at most one row
per (organization_id, source_object_id). Reuse a single stable
knowledge_asset_id for revisions sharing a source_object_id, resolve duplicate
rows deterministically, and remove or merge conflicting rows before creating the
unique constraint.

Source: Linters/SAST tools

Comment on lines +96 to +283
ALTER TABLE knowledge_asset_versions
ALTER COLUMN knowledge_asset_id SET NOT NULL,
ALTER COLUMN version_number SET NOT NULL,
ADD CONSTRAINT uq_knowledge_asset_version_number
UNIQUE (knowledge_asset_id, version_number),
ADD CONSTRAINT uq_knowledge_asset_version_id_organization
UNIQUE (id, organization_id),
ADD CONSTRAINT uq_knowledge_asset_version_chain
UNIQUE (id, organization_id, knowledge_asset_id),
ADD CONSTRAINT fk_knowledge_asset_version_asset
FOREIGN KEY (knowledge_asset_id, organization_id)
REFERENCES knowledge_assets(id, organization_id),
ADD CONSTRAINT fk_knowledge_asset_version_revision
FOREIGN KEY (source_revision_id, organization_id)
REFERENCES source_revisions(id, organization_id),
ADD CONSTRAINT chk_knowledge_asset_version_number
CHECK (version_number > 0);

CREATE UNIQUE INDEX uq_knowledge_asset_one_active_version
ON knowledge_asset_versions (knowledge_asset_id)
WHERE status = 'ACTIVE';

ALTER TABLE knowledge_assets
ADD CONSTRAINT fk_knowledge_asset_current_version
FOREIGN KEY (current_version_id, organization_id, id)
REFERENCES knowledge_asset_versions(id, organization_id, knowledge_asset_id);

ALTER TABLE source_revisions
ADD COLUMN knowledge_asset_version_id uuid;

UPDATE source_revisions
SET knowledge_asset_version_id = knowledge_asset_id
WHERE knowledge_asset_id IS NOT NULL;

ALTER TABLE source_revisions
ADD CONSTRAINT fk_source_revision_knowledge_asset
FOREIGN KEY (knowledge_asset_id, organization_id)
REFERENCES knowledge_assets(id, organization_id),
ADD CONSTRAINT fk_source_revision_knowledge_asset_version
FOREIGN KEY (knowledge_asset_version_id, organization_id, knowledge_asset_id)
REFERENCES knowledge_asset_versions(id, organization_id, knowledge_asset_id),
ADD CONSTRAINT uq_source_revision_asset_version
UNIQUE (id, organization_id, knowledge_asset_id, knowledge_asset_version_id);

ALTER TABLE source_objects
ADD COLUMN latest_revision_id uuid;

UPDATE source_objects
SET latest_revision_id = current_revision_id;

ALTER TABLE source_objects
ADD CONSTRAINT fk_source_object_latest_revision
FOREIGN KEY (latest_revision_id, organization_id, id)
REFERENCES source_revisions(id, organization_id, source_object_id);

ALTER TABLE knowledge_chunks
ADD COLUMN knowledge_asset_version_id uuid;

UPDATE knowledge_chunks
SET knowledge_asset_version_id = knowledge_asset_id;

ALTER TABLE knowledge_chunks
ALTER COLUMN knowledge_asset_version_id SET NOT NULL,
ADD CONSTRAINT fk_knowledge_chunk_asset_organization
FOREIGN KEY (knowledge_asset_id, organization_id)
REFERENCES knowledge_assets(id, organization_id),
ADD CONSTRAINT fk_knowledge_chunk_asset_version
FOREIGN KEY (
knowledge_asset_version_id,
organization_id,
knowledge_asset_id
)
REFERENCES knowledge_asset_versions(id, organization_id, knowledge_asset_id),
ADD CONSTRAINT uq_knowledge_chunk_version_provenance
UNIQUE (
id,
organization_id,
source_revision_id,
knowledge_asset_id,
knowledge_asset_version_id,
projection_generation
);

ALTER TABLE knowledge_asset_publication_outbox
DROP CONSTRAINT IF EXISTS uq_knowledge_asset_publication_asset,
ADD COLUMN knowledge_asset_version_id uuid;

UPDATE knowledge_asset_publication_outbox
SET knowledge_asset_version_id = knowledge_asset_id;

ALTER TABLE knowledge_asset_publication_outbox
ALTER COLUMN knowledge_asset_version_id SET NOT NULL,
ADD CONSTRAINT uq_knowledge_asset_publication_version
UNIQUE (knowledge_asset_version_id),
ADD CONSTRAINT fk_knowledge_asset_publication_asset
FOREIGN KEY (knowledge_asset_id, organization_id)
REFERENCES knowledge_assets(id, organization_id),
ADD CONSTRAINT fk_knowledge_asset_publication_version
FOREIGN KEY (
knowledge_asset_version_id,
organization_id,
knowledge_asset_id
)
REFERENCES knowledge_asset_versions(id, organization_id, knowledge_asset_id);

CREATE TABLE knowledge_asset_evidence_links (
id uuid PRIMARY KEY,
organization_id uuid NOT NULL REFERENCES organizations(id),
knowledge_asset_version_id uuid NOT NULL,
source_revision_id uuid NOT NULL,
source_acl_snapshot_id uuid NOT NULL,
evidence_role varchar(32) NOT NULL,
span_start integer,
span_end integer,
created_at timestamptz NOT NULL,
updated_at timestamptz NOT NULL,
version bigint NOT NULL,
CONSTRAINT uq_knowledge_asset_evidence
UNIQUE (knowledge_asset_version_id, source_revision_id, source_acl_snapshot_id),
CONSTRAINT fk_knowledge_asset_evidence_version
FOREIGN KEY (knowledge_asset_version_id, organization_id)
REFERENCES knowledge_asset_versions(id, organization_id)
ON DELETE CASCADE,
CONSTRAINT fk_knowledge_asset_evidence_revision
FOREIGN KEY (source_revision_id, organization_id)
REFERENCES source_revisions(id, organization_id),
CONSTRAINT fk_knowledge_asset_evidence_acl
FOREIGN KEY (source_acl_snapshot_id, organization_id)
REFERENCES source_acl_snapshots(id, organization_id),
CONSTRAINT chk_knowledge_asset_evidence_role
CHECK (evidence_role IN ('PRIMARY', 'SUPPORTING')),
CONSTRAINT chk_knowledge_asset_evidence_span CHECK (
(span_start IS NULL AND span_end IS NULL)
OR (
span_start IS NOT NULL
AND span_end IS NOT NULL
AND span_start >= 0
AND span_end > span_start
)
)
);

INSERT INTO knowledge_asset_evidence_links (
id,
organization_id,
knowledge_asset_version_id,
source_revision_id,
source_acl_snapshot_id,
evidence_role,
span_start,
span_end,
created_at,
updated_at,
version
)
SELECT
gen_random_uuid(),
version_row.organization_id,
version_row.id,
version_row.source_revision_id,
version_row.source_acl_snapshot_id,
'PRIMARY',
NULL,
NULL,
now(),
now(),
0
FROM knowledge_asset_versions version_row
WHERE version_row.source_revision_id IS NOT NULL;

CREATE INDEX idx_knowledge_asset_space
ON knowledge_assets (organization_id, knowledge_space_id, updated_at DESC);
CREATE INDEX idx_knowledge_asset_current_version
ON knowledge_assets (organization_id, current_version_id)
WHERE current_version_id IS NOT NULL;
CREATE INDEX idx_knowledge_asset_version_asset
ON knowledge_asset_versions (organization_id, knowledge_asset_id, version_number DESC);
CREATE INDEX idx_knowledge_asset_evidence_revision
ON knowledge_asset_evidence_links (organization_id, source_revision_id);

-- Graph contribution rows remain rebuildable. Their source revision now pins an
-- immutable asset version; the stable asset ID remains the authorization key.
ALTER TABLE graph_projection_heads
DROP CONSTRAINT IF EXISTS fk_graph_projection_revision_asset,
ADD CONSTRAINT fk_graph_projection_revision_asset
FOREIGN KEY (source_revision_id, organization_id, knowledge_asset_id)
REFERENCES source_revisions(id, organization_id, knowledge_asset_id)
ON DELETE CASCADE;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Online-locking strategy for a forward-only migration.

Static analysis flags numerous statements (SET NOT NULL on 97/98/158/187, ADD CONSTRAINT ... FOREIGN KEY/UNIQUE throughout, and CREATE INDEX at 114–116/266–274) that take table-scanning/ACCESS EXCLUSIVE locks and block reads/writes during the build. Combined with the RENAME/DROP TABLE operations, this migration is effectively a maintenance-window change rather than an online one.

If online application is a goal, split into transactions using ADD CONSTRAINT ... NOT VALID + later VALIDATE CONSTRAINT, CREATE INDEX CONCURRENTLY, and nullable-column + CHECK instead of immediate SET NOT NULL. Otherwise, document that this migration requires downtime so operators plan accordingly.

🧰 Tools
🪛 SQLFluff (4.2.2)

[error] 118-121: ADD CONSTRAINT ... FOREIGN KEY should use NOT VALID to avoid locking the table while validating existing rows.

(PG01)


[error] 130-138: ADD CONSTRAINT ... FOREIGN KEY should use NOT VALID to avoid locking the table while validating existing rows.

(PG01)


[error] 146-149: ADD CONSTRAINT ... FOREIGN KEY should use NOT VALID to avoid locking the table while validating existing rows.

(PG01)


[error] 266-267: CREATE INDEX should use CONCURRENTLY to avoid locking the table during the build.

(PG01)


[error] 268-270: CREATE INDEX should use CONCURRENTLY to avoid locking the table during the build.

(PG01)


[error] 271-272: CREATE INDEX should use CONCURRENTLY to avoid locking the table during the build.

(PG01)


[error] 273-274: CREATE INDEX should use CONCURRENTLY to avoid locking the table during the build.

(PG01)

🪛 Squawk (2.59.0)

[warning] 97-97: Setting a column NOT NULL blocks reads while the table is scanned. Make the field nullable and use a CHECK constraint instead.

(adding-not-nullable-field)


[warning] 98-98: Setting a column NOT NULL blocks reads while the table is scanned. Make the field nullable and use a CHECK constraint instead.

(adding-not-nullable-field)


[warning] 99-100: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 99-100: Adding a UNIQUE constraint requires an ACCESS EXCLUSIVE lock which blocks reads and writes to the table while the index is built. Create an index CONCURRENTLY and create the constraint using the index.

(disallowed-unique-constraint)


[warning] 101-102: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 101-102: Adding a UNIQUE constraint requires an ACCESS EXCLUSIVE lock which blocks reads and writes to the table while the index is built. Create an index CONCURRENTLY and create the constraint using the index.

(disallowed-unique-constraint)


[warning] 103-104: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 103-104: Adding a UNIQUE constraint requires an ACCESS EXCLUSIVE lock which blocks reads and writes to the table while the index is built. Create an index CONCURRENTLY and create the constraint using the index.

(disallowed-unique-constraint)


[warning] 105-107: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 105-107: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 108-110: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 108-110: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 111-112: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 114-116: During normal index creation, table updates are blocked, but reads are still allowed. Use concurrently to avoid blocking writes.

(require-concurrent-index-creation)


[warning] 131-133: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 131-133: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 134-136: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 134-136: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 137-138: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 137-138: Adding a UNIQUE constraint requires an ACCESS EXCLUSIVE lock which blocks reads and writes to the table while the index is built. Create an index CONCURRENTLY and create the constraint using the index.

(disallowed-unique-constraint)


[warning] 147-149: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 147-149: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 158-158: Setting a column NOT NULL blocks reads while the table is scanned. Make the field nullable and use a CHECK constraint instead.

(adding-not-nullable-field)


[warning] 159-161: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 159-161: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 162-168: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 162-168: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 169-177: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 169-177: Adding a UNIQUE constraint requires an ACCESS EXCLUSIVE lock which blocks reads and writes to the table while the index is built. Create an index CONCURRENTLY and create the constraint using the index.

(disallowed-unique-constraint)


[warning] 187-187: Setting a column NOT NULL blocks reads while the table is scanned. Make the field nullable and use a CHECK constraint instead.

(adding-not-nullable-field)


[warning] 188-189: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 188-189: Adding a UNIQUE constraint requires an ACCESS EXCLUSIVE lock which blocks reads and writes to the table while the index is built. Create an index CONCURRENTLY and create the constraint using the index.

(disallowed-unique-constraint)


[warning] 190-192: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 190-192: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 193-199: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 193-199: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)


[warning] 207-207: Changing the size of a varchar field requires an ACCESS EXCLUSIVE lock, that will prevent all reads and writes to the table. Use a TEXT field with a CHECK constraint.

(prefer-text-field)


[warning] 208-208: Using 32-bit integer fields can result in hitting the max int limit. Use 64-bit integer values instead to prevent hitting this limit.

(prefer-bigint-over-int)


[warning] 209-209: Using 32-bit integer fields can result in hitting the max int limit. Use 64-bit integer values instead to prevent hitting this limit.

(prefer-bigint-over-int)


[warning] 271-272: During normal index creation, table updates are blocked, but reads are still allowed. Use concurrently to avoid blocking writes.

(require-concurrent-index-creation)


[warning] 280-283: By default new constraints require a table scan and block writes to the table while that scan occurs. Use NOT VALID with a later VALIDATE CONSTRAINT call.

(constraint-missing-not-valid)


[warning] 280-283: Adding a foreign key constraint requires a table scan and a SHARE ROW EXCLUSIVE lock on both tables, which blocks writes to each table. Add NOT VALID to the constraint in one transaction and then VALIDATE the constraint in a separate transaction.

(adding-foreign-key-constraint)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@core/src/main/resources/db/migration/V22__knowledge_asset_identity_and_legacy_cleanup.sql`
around lines 96 - 283, The migration applies blocking schema changes and
non-concurrent indexes, so choose and document an explicit deployment strategy.
For online application, replace applicable foreign-key and check additions with
NOT VALID followed by separate VALIDATE CONSTRAINT steps, use nullable-column
checks instead of immediate SET NOT NULL, and create indexes with CONCURRENTLY
in separate transactions; otherwise document that V22 requires a maintenance
window.

Source: Linters/SAST tools

@kl3inIT
kl3inIT merged commit e7e33c7 into main Jul 23, 2026
5 checks passed
@kl3inIT
kl3inIT deleted the kl3inIT/knowledge-asset-foundation branch July 23, 2026 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant