feat(platform): add managed data product history plane
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
import { createHash } from 'node:crypto'
|
||||
import { spawnSync } from 'node:child_process'
|
||||
import { cp, lstat, mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
|
||||
import { lstat, mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { dirname, join, resolve } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
@@ -15,6 +15,7 @@ const [patchId = '', ...extra] = process.argv.slice(2)
|
||||
const storeRelativePath = 'nodedc-source/server/engineAgents/store.js'
|
||||
const predecessorSha256 = '52daa43499d6d9a97fe7ffa891edb9212b7791e733f91dd3ca686d42739b7e9a'
|
||||
const targetSha256 = '2e62654c2dc12905efcc83a9dff45a818dd7b47924a10600160835c4416540e9'
|
||||
const readerExtendedSourceSha256 = 'debd351fe0b8c72b33b8c79909b8f339cbaf061b970576f3ae72df52ebaa211f'
|
||||
const previouslyIssuedPatchIds = new Set([
|
||||
'engine-agent-full-grant-migration-20260717-001',
|
||||
])
|
||||
@@ -29,7 +30,7 @@ if (previouslyIssuedPatchIds.has(patchId)) {
|
||||
const source = join(engineRoot, storeRelativePath)
|
||||
const sourceInfo = await lstat(source)
|
||||
if (sourceInfo.isSymbolicLink() || !sourceInfo.isFile()) throw new Error('engine_agent_store_source_unsafe')
|
||||
const sourceBytes = await readFile(source)
|
||||
const sourceBytes = materializeFrozenTarget(await readFile(source))
|
||||
if (digest(sourceBytes) !== targetSha256) throw new Error('engine_agent_store_target_sha256_mismatch')
|
||||
const sourceText = sourceBytes.toString('utf8')
|
||||
for (const required of [
|
||||
@@ -56,7 +57,7 @@ const stage = await mkdtemp(join(tmpdir(), 'nodedc-engine-agent-grant-migration-
|
||||
try {
|
||||
const destination = join(stage, 'payload', storeRelativePath)
|
||||
await mkdir(dirname(destination), { recursive: true })
|
||||
await cp(source, destination, { force: false, verbatimSymlinks: true })
|
||||
await writeFile(destination, sourceBytes)
|
||||
await writeFile(
|
||||
join(stage, 'manifest.env'),
|
||||
`id=${patchId}\ncomponent=engine\ntype=app-overlay\n`,
|
||||
@@ -119,3 +120,22 @@ function run(command, args) {
|
||||
function digest(bytes) {
|
||||
return createHash('sha256').update(bytes).digest('hex')
|
||||
}
|
||||
|
||||
function materializeFrozenTarget(bytes) {
|
||||
const sourceSha256 = digest(bytes)
|
||||
if (sourceSha256 === targetSha256) return bytes
|
||||
if (sourceSha256 !== readerExtendedSourceSha256) {
|
||||
throw new Error('engine_agent_store_target_sha256_mismatch')
|
||||
}
|
||||
const text = bytes.toString('utf8')
|
||||
const readerScopes = [
|
||||
" 'engine:l2:data-product-read-grant:plan',\n",
|
||||
" 'engine:l2:data-product-read-grant:write',\n",
|
||||
]
|
||||
let frozen = text
|
||||
for (const scope of readerScopes) {
|
||||
if (!frozen.includes(scope)) throw new Error('engine_agent_store_reader_scope_boundary_missing')
|
||||
frozen = frozen.replace(scope, '')
|
||||
}
|
||||
return Buffer.from(frozen, 'utf8')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user