seed-media-write-staging.mjs
sha256:b5f647cb9c409f563d4671fe3fc05ddea01fabfed9b41fc11cb923588e1c1baf
mirror: GitHub Phase A durable MCP OAuth (#270)
Human
minor
⚠ breaking
10 days ago
| 1 | #!/usr/bin/env node |
| 2 | /** |
| 3 | * Phase 2F-b-d-kn-d — seed dev/staging media write policy (external link + attach gates). |
| 4 | * |
| 5 | * Writes to the configured data_dir (never production defaults): |
| 6 | * - hub_media_write_policy.json — both gates on (link unchanged from 2F-b-d-kn-c) |
| 7 | * - hub_media_connector_policy.json — gdrive allowlisted for the target vault (admin seed) |
| 8 | * |
| 9 | * Usage: |
| 10 | * node scripts/seed-media-write-staging.mjs |
| 11 | * KNOWTATION_HUB_VAULT_ID=default node scripts/seed-media-write-staging.mjs |
| 12 | * |
| 13 | * @see docs/MEDIA-WRITE-SURFACES-CONTRACT-2F-b-d-kn.md §16.2 |
| 14 | */ |
| 15 | |
| 16 | import fs from 'node:fs'; |
| 17 | import path from 'node:path'; |
| 18 | import { fileURLToPath } from 'node:url'; |
| 19 | |
| 20 | import { loadConfig } from '../lib/config.mjs'; |
| 21 | import { |
| 22 | MEDIA_WRITE_POLICY_FILE, |
| 23 | readMediaWritePolicyFile, |
| 24 | getMediaExternalLinkEnabled, |
| 25 | getMediaAttachEnabled, |
| 26 | } from '../lib/attachments/attachment-write.mjs'; |
| 27 | import { |
| 28 | saveMediaConnectorPolicy, |
| 29 | loadMediaConnectorPolicy, |
| 30 | getEnabledConnector, |
| 31 | } from '../lib/attachments/media-connector-policy.mjs'; |
| 32 | |
| 33 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); |
| 34 | const repoRoot = path.resolve(__dirname, '..'); |
| 35 | |
| 36 | const vaultId = process.env.KNOWTATION_HUB_VAULT_ID || 'default'; |
| 37 | const connectorId = process.env.MEDIA_STAGING_CONNECTOR_ID || 'gdrive'; |
| 38 | |
| 39 | function resolveDataDir() { |
| 40 | const fromEnv = (process.env.KNOWTATION_DATA_DIR || '').trim(); |
| 41 | if (fromEnv) return path.resolve(fromEnv); |
| 42 | const config = loadConfig(repoRoot); |
| 43 | const dir = config?.data_dir || 'data/'; |
| 44 | return path.isAbsolute(dir) ? dir : path.join(repoRoot, dir); |
| 45 | } |
| 46 | |
| 47 | function seedWritePolicy(dataDir) { |
| 48 | const fp = path.join(dataDir, MEDIA_WRITE_POLICY_FILE); |
| 49 | const payload = { |
| 50 | media_external_link_enabled: true, |
| 51 | media_attach_enabled: true, |
| 52 | }; |
| 53 | fs.mkdirSync(dataDir, { recursive: true }); |
| 54 | fs.writeFileSync(fp, JSON.stringify(payload, null, 2) + '\n', 'utf8'); |
| 55 | return fp; |
| 56 | } |
| 57 | |
| 58 | function seedConnectorAllowlist(dataDir, vault, connector) { |
| 59 | const store = loadMediaConnectorPolicy(dataDir); |
| 60 | if (!store.vaults[vault]) store.vaults[vault] = { connectors: {} }; |
| 61 | const now = new Date().toISOString(); |
| 62 | store.vaults[vault].connectors[connector] = { |
| 63 | enabled: true, |
| 64 | display_name: 'Google Drive (staging)', |
| 65 | updated: now, |
| 66 | }; |
| 67 | saveMediaConnectorPolicy(dataDir, store); |
| 68 | return getMediaConnectorPolicyPath(dataDir); |
| 69 | } |
| 70 | |
| 71 | function getMediaConnectorPolicyPath(dataDir) { |
| 72 | return path.join(dataDir, 'hub_media_connector_policy.json'); |
| 73 | } |
| 74 | |
| 75 | function main() { |
| 76 | const dataDir = resolveDataDir(); |
| 77 | console.log(`2F-b-d-kn-d media write staging seed — data_dir=${dataDir} vault=${vaultId}`); |
| 78 | |
| 79 | const writeFp = seedWritePolicy(dataDir); |
| 80 | const connectorFp = seedConnectorAllowlist(dataDir, vaultId, connectorId); |
| 81 | |
| 82 | delete process.env.MEDIA_EXTERNAL_LINK_ENABLED; |
| 83 | delete process.env.MEDIA_ATTACH_ENABLED; |
| 84 | |
| 85 | const linkOn = getMediaExternalLinkEnabled(dataDir); |
| 86 | const attachOn = getMediaAttachEnabled(dataDir); |
| 87 | const connectorOk = getEnabledConnector(dataDir, vaultId, connectorId) !== null; |
| 88 | const policy = readMediaWritePolicyFile(dataDir); |
| 89 | |
| 90 | console.log(` wrote ${writeFp}`); |
| 91 | console.log(` wrote ${connectorFp}`); |
| 92 | console.log(` link gate (policy file): ${linkOn ? 'ON' : 'OFF'}`); |
| 93 | console.log(` attach gate (policy file): ${attachOn ? 'ON' : 'OFF'}`); |
| 94 | console.log(` connector ${connectorId}: ${connectorOk ? 'allowlisted' : 'MISSING'}`); |
| 95 | |
| 96 | if (!linkOn || !attachOn || !connectorOk) { |
| 97 | console.error('Seed verification failed — aborting.'); |
| 98 | process.exit(1); |
| 99 | } |
| 100 | if (policy.media_external_link_enabled !== true) { |
| 101 | console.error('KN-MD-4 violation: external-link gate must remain on.'); |
| 102 | process.exit(1); |
| 103 | } |
| 104 | |
| 105 | console.log('2F-b-d-kn-d staging seed PASS (link + attach gates on; external-link unchanged)'); |
| 106 | } |
| 107 | |
| 108 | main(); |
File History
1 commit
sha256:b5f647cb9c409f563d4671fe3fc05ddea01fabfed9b41fc11cb923588e1c1baf
mirror: GitHub Phase A durable MCP OAuth (#270)
Human
minor
⚠
10 days ago