11/** Real PostgreSQL content admission, pagination, captured metadata, and streamed ZIP readback. */
2+ import { mkdtempSync } from 'node:fs'
3+ import { rm } from 'node:fs/promises'
4+ import { tmpdir } from 'node:os'
5+ import path from 'node:path'
26import * as audit from '@sim/audit'
37import { db } from '@sim/db'
48import {
@@ -18,6 +22,14 @@ import { eq, inArray } from 'drizzle-orm'
1822import { PostgresJsPreparedQuery } from 'drizzle-orm/postgres-js/session'
1923import JSZip from 'jszip'
2024import { afterAll , afterEach , beforeAll , describe , expect , it , vi } from 'vitest'
25+
26+ const fixtureStorage = vi . hoisted ( ( ) => ( { root : '' } ) )
27+ vi . mock ( '@/lib/uploads/core/setup.server' , ( ) => ( {
28+ get UPLOAD_DIR_SERVER ( ) {
29+ return fixtureStorage . root
30+ } ,
31+ } ) )
32+
2133import { observeContentDelivery } from '@/lib/core/application'
2234import { encryptSecret } from '@/lib/core/security/encryption'
2335import type { DurableSecretProvenance } from '@/lib/execution/durable-secret-provenance'
@@ -28,11 +40,13 @@ import {
2840import { admitKnowledgeChunks } from '@/lib/knowledge/application/admit-knowledge-content'
2941import { KNOWLEDGE_DELEGATION_AUDIENCE } from '@/lib/knowledge/application/authorization'
3042import { listKnowledgeChunks } from '@/lib/knowledge/application/chunks'
43+ import * as knowledgeContexts from '@/lib/knowledge/application/contexts'
3144import { listKnowledgeDocuments } from '@/lib/knowledge/application/documents'
3245import {
3346 exportKnowledgeBase ,
3447 type KnowledgeBaseExportBundle ,
3548} from '@/lib/knowledge/application/exports'
49+ import { readOriginalKnowledgeDocument } from '@/lib/knowledge/application/read-original-document'
3650import {
3751 readDetailedKnowledgeTagUsage ,
3852 readKnowledgeTagUsage ,
@@ -48,6 +62,7 @@ import { buildKnowledgeBundleArchive } from '@/lib/knowledge/transfer/export-arc
4862import { embeddingVectorValues } from '@/lib/knowledge/vector-columns'
4963import { createCopilotChatPrincipal } from '@/lib/mothership/auth/application-delegation'
5064import { createRegistryContentGate } from '@/lib/mothership/content-delivery/registry-gate'
65+ import { uploadFile } from '@/lib/uploads/core/storage-service'
5166import { ResolvedSecretTraceRegistry } from '@/executor/utils/resolved-secret-trace-registry'
5267
5368const SECRET = 'fixture-knowledge-token-41875'
@@ -173,6 +188,7 @@ async function drainAudits() {
173188}
174189
175190beforeAll ( async ( ) => {
191+ fixtureStorage . root = mkdtempSync ( path . join ( tmpdir ( ) , 'sim-knowledge-delivery-' ) )
176192 await seedKnowledgeAclFixture ( ids )
177193 const record = audit . recordAudit
178194 vi . spyOn ( audit , 'recordAudit' ) . mockImplementation ( ( entry ) => {
@@ -208,6 +224,7 @@ afterAll(async () => {
208224 await deleteWorkspaceFixture ( db , eq ( workspace . id , ids . workspaceId ) )
209225 await db . delete ( organization ) . where ( eq ( organization . id , ids . organizationId ) )
210226 await db . delete ( user ) . where ( inArray ( user . id , [ ids . aliceId , ids . bobId ] ) )
227+ await rm ( fixtureStorage . root , { recursive : true , force : true } )
211228 await db . $client . end ( )
212229} )
213230
@@ -444,6 +461,68 @@ describe('knowledge content delivery', () => {
444461 }
445462 )
446463
464+ it ( 'binds an original read to the captured storage key across a concurrent replacement' , async ( ) => {
465+ const doc = await seedDocument ( { original : false , content : SECRET , provenance : exact } )
466+ const oldKey = `kb/${ generateId ( ) } .txt`
467+ const newKey = `kb/${ generateId ( ) } .txt`
468+ for ( const [ key , content ] of [
469+ [ oldKey , SECRET ] ,
470+ [ newKey , 'replacement public content' ] ,
471+ ] ) {
472+ await uploadFile ( {
473+ file : Buffer . from ( content ) ,
474+ fileName : 'fixture.txt' ,
475+ contentType : 'text/plain' ,
476+ context : 'knowledge-base' ,
477+ customKey : key ,
478+ preserveKey : true ,
479+ persistMetadata : false ,
480+ } )
481+ }
482+ await db . update ( document ) . set ( { storageKey : oldKey } ) . where ( eq ( document . id , doc . id ) )
483+ const input = {
484+ knowledgeBaseId : ids . knowledgeBaseId ,
485+ documentId : doc . id ,
486+ assertedWorkspaceId : ids . workspaceId ,
487+ }
488+ const matched = await inChat ( ( ) => readOriginalKnowledgeDocument . execute ( { principal, input } ) )
489+ expect ( matched . buffer ?. toString ( ) ) . toBe ( SECRET )
490+ expect ( matched . hasRecordedSecrets ) . toBe ( true )
491+ const resolve = knowledgeContexts . resolveCanonicalActiveKnowledgeDocumentContext
492+ let replaced = false
493+ const interleave = vi
494+ . spyOn ( knowledgeContexts , 'resolveCanonicalActiveKnowledgeDocumentContext' )
495+ . mockImplementation ( async ( ...args ) => {
496+ const context = await resolve ( ...args )
497+ await db . transaction ( async ( tx ) => {
498+ const [ row ] = await tx
499+ . update ( document )
500+ . set ( { storageKey : newKey } )
501+ . where ( eq ( document . id , doc . id ) )
502+ . returning ( )
503+ await replaceKnowledgeDocumentSecretProvenanceInTx (
504+ tx ,
505+ doc . id ,
506+ createKnowledgeDocumentSourceValue ( row ) ,
507+ { status : 'exact' , entries : [ ] }
508+ )
509+ } )
510+ replaced = true
511+ return context
512+ } )
513+ try {
514+ await expect (
515+ inChat ( ( ) => readOriginalKnowledgeDocument . execute ( { principal, input } ) )
516+ ) . rejects . toThrow ( / p r o v e n a n c e | m o d e l / i)
517+ expect ( replaced ) . toBe ( true )
518+ } finally {
519+ interleave . mockRestore ( )
520+ }
521+ const current = await inChat ( ( ) => readOriginalKnowledgeDocument . execute ( { principal, input } ) )
522+ expect ( current . buffer ?. toString ( ) ) . toBe ( 'replacement public content' )
523+ expect ( current . hasRecordedSecrets ) . toBe ( false )
524+ } )
525+
447526 it ( 'exports clean and legacy originals with chunks through the existing ZIP stream' , async ( ) => {
448527 const docs = [
449528 await seedDocument ( ) ,
0 commit comments