mindspace: close authority boundaries
This commit is contained in:
@@ -0,0 +1,757 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const root = path.join(
|
||||
path.dirname(fileURLToPath(import.meta.url)),
|
||||
'..',
|
||||
);
|
||||
|
||||
function read(relativePath) {
|
||||
const targetPath = path.join(root, relativePath);
|
||||
if (!fs.existsSync(targetPath)) {
|
||||
throw new Error(
|
||||
`Missing MindSpace authority guard input: ${relativePath}`,
|
||||
);
|
||||
}
|
||||
return fs.readFileSync(targetPath, 'utf8');
|
||||
}
|
||||
|
||||
function requireSource(source, pattern, label) {
|
||||
if (!pattern.test(source)) {
|
||||
throw new Error(`Missing MindSpace authority guard: ${label}`);
|
||||
}
|
||||
}
|
||||
|
||||
function forbidSource(source, pattern, label) {
|
||||
if (pattern.test(source)) {
|
||||
throw new Error(`MindSpace authority leaked back into Portal: ${label}`);
|
||||
}
|
||||
}
|
||||
|
||||
const portalSource = read('server.mjs');
|
||||
const contractSource = read(
|
||||
'mindspace-server-adapter-contract.mjs',
|
||||
);
|
||||
const localRuntimeSource = read(
|
||||
'mindspace-local-runtime-services.mjs',
|
||||
);
|
||||
const publicFinishServiceSource = read(
|
||||
'mindspace-public-finish-service.mjs',
|
||||
);
|
||||
const wechatHtmlDeliverySource = read(
|
||||
'mindspace-wechat-html-delivery.mjs',
|
||||
);
|
||||
const portalSessionRoutesSource = read(
|
||||
'server/portal-session-routes.mjs',
|
||||
);
|
||||
const workspaceDeliveryServiceSource = read(
|
||||
'mindspace-workspace-publication-delivery-service.mjs',
|
||||
);
|
||||
const portalWorkspaceDeliverySource = read(
|
||||
'server/portal-workspace-publication-delivery.mjs',
|
||||
);
|
||||
const portalPublicationRoutesSource = read(
|
||||
'server/portal-publication-routes.mjs',
|
||||
);
|
||||
const portalDomainBootstrapSource = read(
|
||||
'server/portal-domain-services-bootstrap.mjs',
|
||||
);
|
||||
const portalGatewayBootstrapSource = read(
|
||||
'server/portal-gateway-services-bootstrap.mjs',
|
||||
);
|
||||
const portalAgentJobRoutesSource = read(
|
||||
'server/portal-agent-job-routes.mjs',
|
||||
);
|
||||
const portalIntegrationBootstrapSource = read(
|
||||
'server/portal-integration-services-bootstrap.mjs',
|
||||
);
|
||||
const wechatMpSource = read('wechat-mp.mjs');
|
||||
const workspaceToolServiceSource = read(
|
||||
'mindspace-workspace-tool-service.mjs',
|
||||
);
|
||||
const scopedMcpTokenSource = read(
|
||||
'mindspace-mcp-scoped-token.mjs',
|
||||
);
|
||||
const sandboxMcpSource = read(
|
||||
'mindspace-sandbox-mcp.mjs',
|
||||
);
|
||||
const capabilitiesSource = read(
|
||||
'capabilities.mjs',
|
||||
);
|
||||
const userAuthSource = read('user-auth.mjs');
|
||||
const mindSpaceRpcServerSource = read(
|
||||
'mindspace-service/mindspace-rpc-server.mjs',
|
||||
);
|
||||
const publicationServiceSource = read(
|
||||
'mindspace-publications.mjs',
|
||||
);
|
||||
const withRuntime =
|
||||
process.argv.includes('--with-runtime') ||
|
||||
process.env.MINDSPACE_VERIFY_RUNTIME === '1';
|
||||
|
||||
requireSource(
|
||||
portalSource,
|
||||
/mindSpaceChatSave\.materializeWorkspaceHtml\(/,
|
||||
'Portal delegates chat-save HTML materialization',
|
||||
);
|
||||
forbidSource(
|
||||
portalSource,
|
||||
/\bfsPromises\b/,
|
||||
'server.mjs must not retain the chat-save filesystem writer',
|
||||
);
|
||||
forbidSource(
|
||||
portalSource,
|
||||
/\bmaterializePrivateAssetsInWorkspaceHtml\b/,
|
||||
'server.mjs must not materialize private assets directly',
|
||||
);
|
||||
forbidSource(
|
||||
portalSource,
|
||||
/\brepairMissingHtmlAssetReferences\b/,
|
||||
'server.mjs must not repair stored HTML directly',
|
||||
);
|
||||
forbidSource(
|
||||
portalSource,
|
||||
/\bresolveMindSpaceUserPublishDir\b/,
|
||||
'server.mjs must not resolve MindSpace workspace directories',
|
||||
);
|
||||
forbidSource(
|
||||
portalSource,
|
||||
/\blistRecentlyModifiedPublicHtmlRelativePaths\b/,
|
||||
'server.mjs must not scan workspace HTML directly',
|
||||
);
|
||||
requireSource(
|
||||
portalSource,
|
||||
/\.listRecentlyModifiedPublicHtml\(\{/,
|
||||
'Portal delegates recent workspace discovery to MindSpace',
|
||||
);
|
||||
|
||||
const chatSaveRoutesSource = read(
|
||||
'server/portal-mindspace-chat-save-routes.mjs',
|
||||
);
|
||||
const chatShareRoutesSource = read(
|
||||
'server/portal-mindspace-chat-share-routes.mjs',
|
||||
);
|
||||
const portalAssetRoutesSource = read(
|
||||
'server/portal-mindspace-asset-routes.mjs',
|
||||
);
|
||||
forbidSource(
|
||||
chatSaveRoutesSource,
|
||||
/\bresolveMindSpaceUserPublishDir\b/,
|
||||
'chat-save routes must not resolve workspace publish directories',
|
||||
);
|
||||
forbidSource(
|
||||
chatSaveRoutesSource,
|
||||
/\bensureWorkspaceHtmlThumbnail\b/,
|
||||
'chat-save routes must not write workspace thumbnails directly',
|
||||
);
|
||||
requireSource(
|
||||
chatSaveRoutesSource,
|
||||
/getMindSpaceChatSave/,
|
||||
'chat-save routes delegate preview thumbnails to MindSpace',
|
||||
);
|
||||
requireSource(
|
||||
chatSaveRoutesSource,
|
||||
/chatSave\.ensurePreviewThumbnail\(/,
|
||||
'chat-save routes use MindSpace preview thumbnail authority',
|
||||
);
|
||||
requireSource(
|
||||
chatSaveRoutesSource,
|
||||
/chatSave\.renderPreviewThumbnailSvg\(/,
|
||||
'chat-save routes render preview thumbnails through MindSpace',
|
||||
);
|
||||
requireSource(
|
||||
chatShareRoutesSource,
|
||||
/chatSave\.createSharedHtml\(\{/,
|
||||
'quick share delegates shared HTML creation to MindSpace',
|
||||
);
|
||||
forbidSource(
|
||||
chatShareRoutesSource,
|
||||
/\bwriteFile\b/,
|
||||
'chat share routes must not write shared HTML directly',
|
||||
);
|
||||
forbidSource(
|
||||
chatShareRoutesSource,
|
||||
/\bbuildMindSpacePublicUrlForUser\b/,
|
||||
'chat share routes must not build public URLs',
|
||||
);
|
||||
forbidSource(
|
||||
chatShareRoutesSource,
|
||||
/\bresolveMindSpaceRuntimeConfig\b/,
|
||||
'chat share routes must not resolve storage roots',
|
||||
);
|
||||
forbidSource(
|
||||
chatShareRoutesSource,
|
||||
/\bresolveMindSpaceUserPublishDir\b/,
|
||||
'chat share routes must not resolve workspace publish directories',
|
||||
);
|
||||
forbidSource(
|
||||
chatShareRoutesSource,
|
||||
/\binlinePrivateAssetsInHtml\b/,
|
||||
'chat share routes must not localize private assets directly',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/chatSaveService:\s*Object\.freeze\(\[/,
|
||||
'local and remote adapters expose chatSaveService',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/'materializeWorkspaceHtml'/,
|
||||
'chat save contract includes workspace HTML authority',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/'ensurePreviewThumbnail'/,
|
||||
'chat save contract includes preview thumbnail authority',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/'renderPreviewThumbnailSvg'/,
|
||||
'chat save contract includes preview thumbnail rendering',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/'createSharedHtml'/,
|
||||
'chat save contract includes shared HTML authority',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/'readWorkspaceHtml'/,
|
||||
'chat save contract includes workspace HTML read authority',
|
||||
);
|
||||
requireSource(
|
||||
localRuntimeSource,
|
||||
/createMindSpaceChatSaveService\(\{/,
|
||||
'MindSpace local runtime owns chatSaveService',
|
||||
);
|
||||
requireSource(
|
||||
portalAssetRoutesSource,
|
||||
/assets\.readAssetContent\(/,
|
||||
'Portal asset download consumes logical MindSpace content',
|
||||
);
|
||||
requireSource(
|
||||
portalAssetRoutesSource,
|
||||
/\.readPublicAssetContent\(/,
|
||||
'Portal public asset download consumes logical MindSpace content',
|
||||
);
|
||||
forbidSource(
|
||||
portalAssetRoutesSource,
|
||||
/(?:node:fs|sendFile\(|\breadFile\()/,
|
||||
'Portal asset routes must not read physical asset paths',
|
||||
);
|
||||
forbidSource(
|
||||
contractSource,
|
||||
/'read(?:Public)?Asset'/,
|
||||
'remote asset contract must not expose physical readAsset paths',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/'readAssetContent'/,
|
||||
'remote asset contract exposes logical asset content',
|
||||
);
|
||||
requireSource(
|
||||
portalSource,
|
||||
/registerPublishedLongImageArtifact\(\{/,
|
||||
'Portal delegates published long image registration',
|
||||
);
|
||||
forbidSource(
|
||||
portalSource,
|
||||
/mindSpaceConversationPackageRegistry\.(?:putObjectForSession|recordArtifact|writeManifestForSession)\(/,
|
||||
'server.mjs must not mutate conversation packages directly',
|
||||
);
|
||||
forbidSource(
|
||||
portalSessionRoutesSource,
|
||||
/\bmaterializePublicHtmlWritesFromSessionEvent\b/,
|
||||
'Portal session routes must not materialize public HTML directly',
|
||||
);
|
||||
forbidSource(
|
||||
portalSessionRoutesSource,
|
||||
/\bsyncPublicHtmlAfterFinish\b/,
|
||||
'Portal session routes must not perform final public HTML sync directly',
|
||||
);
|
||||
forbidSource(
|
||||
portalSessionRoutesSource,
|
||||
/\bPUBLISH_ROOT_DIR\b/,
|
||||
'Portal session routes must not build public page URLs',
|
||||
);
|
||||
forbidSource(
|
||||
portalSessionRoutesSource,
|
||||
/(?:resolveMindSpaceUserPublishDir|resolveMindSpaceRuntimeConfig|\bpublishDir\b|\bstorageRoot\b)/,
|
||||
'Portal session routes must not resolve MindSpace storage paths',
|
||||
);
|
||||
requireSource(
|
||||
portalSessionRoutesSource,
|
||||
/publicFinish\.materializeSessionEvent\(\{/,
|
||||
'streamed public HTML writes delegate to MindSpace',
|
||||
);
|
||||
requireSource(
|
||||
portalSessionRoutesSource,
|
||||
/publicFinish\.syncAfterFinish\(\{/,
|
||||
'Finish public HTML sync delegates to MindSpace',
|
||||
);
|
||||
requireSource(
|
||||
portalSessionRoutesSource,
|
||||
/evaluation:\s*[\s\S]{0,80}syncResult[\s\S]{0,80}deliveryEvaluation/,
|
||||
'Portal consumes MindSpace HTML delivery evaluation',
|
||||
);
|
||||
requireSource(
|
||||
portalSessionRoutesSource,
|
||||
/publicFinish\.preparePageDataAfterFinish\(\{/,
|
||||
'Portal requests Page Data preparation from MindSpace after page sync',
|
||||
);
|
||||
requireSource(
|
||||
chatSaveRoutesSource,
|
||||
/conversationArtifacts\.registerChatDocxArtifact\(\{/,
|
||||
'chat DOCX artifact registration delegates to MindSpace',
|
||||
);
|
||||
forbidSource(
|
||||
chatSaveRoutesSource,
|
||||
/getConversationPackageRegistry/,
|
||||
'chat save routes must not access the package registry directly',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/conversationArtifactService:\s*Object\.freeze\(\[/,
|
||||
'local and remote adapters expose conversationArtifactService',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/'registerPublicHtmlArtifacts'/,
|
||||
'conversation artifact contract includes public HTML registration',
|
||||
);
|
||||
forbidSource(
|
||||
contractSource,
|
||||
/conversationPackageRegistry:\s*Object\.freeze\(\[[\s\S]{0,240}'(?:ensurePackage|putObjectForSession|recordArtifact|writeManifestForSession)'/,
|
||||
'remote package registry contract must stay read-only',
|
||||
);
|
||||
requireSource(
|
||||
localRuntimeSource,
|
||||
/createMindSpaceConversationArtifactService\(\{/,
|
||||
'MindSpace local runtime owns conversationArtifactService',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/publicFinishService:\s*Object\.freeze\(\[/,
|
||||
'local and remote adapters expose publicFinishService',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/'preparePageDataAfterFinish'/,
|
||||
'public Finish contract includes Page Data preparation',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/'prepareWechatPageDataDelivery'/,
|
||||
'public Finish contract includes WeChat Page Data delivery preparation',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/'prepareWechatHtmlDelivery'/,
|
||||
'public Finish contract includes WeChat HTML delivery preparation',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/'ensureWechatFreshPageThumbnails'/,
|
||||
'public Finish contract includes WeChat thumbnail authority',
|
||||
);
|
||||
requireSource(
|
||||
localRuntimeSource,
|
||||
/createMindSpacePublicFinishService\(\{/,
|
||||
'MindSpace local runtime owns publicFinishService',
|
||||
);
|
||||
requireSource(
|
||||
publicFinishServiceSource,
|
||||
/conversationArtifactService[\s\S]{0,160}\.registerPublicHtmlArtifacts\(\{/,
|
||||
'MindSpace Finish service owns public HTML artifact registration',
|
||||
);
|
||||
requireSource(
|
||||
publicFinishServiceSource,
|
||||
/evaluateH5HtmlFinishGuardFn\(\{/,
|
||||
'MindSpace Finish service owns HTML delivery evaluation',
|
||||
);
|
||||
requireSource(
|
||||
publicFinishServiceSource,
|
||||
/preparePageDataAfterFinishFn\(\{/,
|
||||
'MindSpace Finish service owns Page Data delivery preparation',
|
||||
);
|
||||
requireSource(
|
||||
publicFinishServiceSource,
|
||||
/resolvePageDataCollectOutcomeAsyncFn\(\{/,
|
||||
'MindSpace Finish service owns WeChat Page Data delivery evaluation',
|
||||
);
|
||||
requireSource(
|
||||
publicFinishServiceSource,
|
||||
/ensurePageDataDeliveryReadyFn\(\{/,
|
||||
'MindSpace Finish service owns WeChat Page Data backing delivery checks',
|
||||
);
|
||||
forbidSource(
|
||||
portalIntegrationBootstrapSource,
|
||||
/resolveMindSpaceRuntimeConfig|\bstorageRoot\b|\bauthPool\b/,
|
||||
'Portal integration bootstrap must not configure WeChat with MindSpace storage paths',
|
||||
);
|
||||
requireSource(
|
||||
portalIntegrationBootstrapSource,
|
||||
/pageDataFinishGuard:[\s\S]{0,180}mindSpacePublicFinish/,
|
||||
'Portal gives WeChat the logical MindSpace Finish authority',
|
||||
);
|
||||
requireSource(
|
||||
portalIntegrationBootstrapSource,
|
||||
/htmlDeliveryAuthority:[\s\S]{0,260}mindSpacePublicFinish/,
|
||||
'Portal gives WeChat the logical MindSpace HTML delivery authority',
|
||||
);
|
||||
forbidSource(
|
||||
wechatMpSource,
|
||||
/pageDataFinishGuard\?\.(?:pool|h5Root|storageRoot)/,
|
||||
'WeChat delivery must not receive MindSpace storage internals',
|
||||
);
|
||||
requireSource(
|
||||
wechatMpSource,
|
||||
/prepareWechatPageDataDelivery/,
|
||||
'WeChat delegates Page Data delivery preparation to MindSpace',
|
||||
);
|
||||
requireSource(
|
||||
wechatMpSource,
|
||||
/prepareWechatHtmlDelivery/,
|
||||
'WeChat delegates HTML delivery preparation to MindSpace',
|
||||
);
|
||||
requireSource(
|
||||
wechatMpSource,
|
||||
/ensureWechatFreshPageThumbnails/,
|
||||
'WeChat delegates fresh thumbnail delivery to MindSpace',
|
||||
);
|
||||
forbidSource(
|
||||
wechatMpSource,
|
||||
/materializeMissingPublicHtmlWrites|ensureWorkspaceHtmlThumbnail|collectRecentPublishedHtmlArtifacts|resolveLinkExistsForWorkingDir/,
|
||||
'WeChat must not perform physical HTML delivery work',
|
||||
);
|
||||
requireSource(
|
||||
publicFinishServiceSource,
|
||||
/prepareWechatHtmlDeliveryAtWorkspaceFn\(\{/,
|
||||
'MindSpace Finish service owns WeChat HTML backing-file preparation',
|
||||
);
|
||||
requireSource(
|
||||
publicFinishServiceSource,
|
||||
/ensureWechatFreshPageThumbnailsAtWorkspaceFn/,
|
||||
'MindSpace Finish service owns WeChat fresh thumbnail work',
|
||||
);
|
||||
requireSource(
|
||||
wechatHtmlDeliverySource,
|
||||
/materializeMissingPublicHtmlWrites\(\{/,
|
||||
'MindSpace WeChat delivery materializes HTML inside the service boundary',
|
||||
);
|
||||
requireSource(
|
||||
wechatHtmlDeliverySource,
|
||||
/ensureWorkspaceHtmlThumbnail\(/,
|
||||
'MindSpace WeChat delivery renders thumbnails inside the service boundary',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/workspacePublicationDeliveryService:\s*[\s\S]{0,80}Object\.freeze\(\[/,
|
||||
'local and remote adapters expose workspacePublicationDeliveryService',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/'resolveWorkspaceRequest'/,
|
||||
'workspace delivery contract includes logical request resolution',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/'listRecentlyModifiedPublicHtml'/,
|
||||
'workspace delivery contract includes recent HTML discovery',
|
||||
);
|
||||
requireSource(
|
||||
localRuntimeSource,
|
||||
/createMindSpaceWorkspacePublicationDeliveryService\(\{/,
|
||||
'MindSpace local runtime owns workspace publication delivery',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/workspacePageDeliveryService:\s*[\s\S]{0,80}Object\.freeze\(\['syncAndDeliver'\]\)/,
|
||||
'local and remote adapters expose workspace page delivery',
|
||||
);
|
||||
requireSource(
|
||||
localRuntimeSource,
|
||||
/createWorkspacePageDeliverService\(\{/,
|
||||
'MindSpace local runtime owns workspace page sync and delivery',
|
||||
);
|
||||
requireSource(
|
||||
portalDomainBootstrapSource,
|
||||
/\.workspacePageDeliveryService/,
|
||||
'Portal domain bootstrap consumes the MindSpace workspace page delivery binding',
|
||||
);
|
||||
forbidSource(
|
||||
portalDomainBootstrapSource,
|
||||
/(?:createWorkspacePageDeliverService|resolveMindSpaceRuntimeConfig|ensurePageDataHtmlPagesBound)/,
|
||||
'Portal domain bootstrap must not construct storage-aware workspace delivery',
|
||||
);
|
||||
requireSource(
|
||||
portalGatewayBootstrapSource,
|
||||
/service\.validateRunDeliverables\(/,
|
||||
'Portal run validation delegates to MindSpace',
|
||||
);
|
||||
forbidSource(
|
||||
portalGatewayBootstrapSource,
|
||||
/(?:resolveMindSpaceUserPublishDir|evaluatePageDataHtmlContent|readPageAccessPolicy|scanWorkspaceFilesForProhibitedBrowserStorage)/,
|
||||
'Portal gateway must not read workspace files for delivery validation',
|
||||
);
|
||||
forbidSource(
|
||||
portalGatewayBootstrapSource,
|
||||
/(?:mindSpaceAssets\.readAsset\(|readAssetFileFn)/,
|
||||
'Portal gateway must not read physical MindSpace asset paths',
|
||||
);
|
||||
forbidSource(
|
||||
portalAgentJobRoutesSource,
|
||||
/(?:node:fs|\breadFile\(|asset\.path)/,
|
||||
'Portal agent job routes must not read physical asset paths',
|
||||
);
|
||||
requireSource(
|
||||
portalAgentJobRoutesSource,
|
||||
/asset\.bodyBase64/,
|
||||
'Portal agent job delivery consumes MindSpace binary content',
|
||||
);
|
||||
requireSource(
|
||||
workspaceDeliveryServiceSource,
|
||||
/resolvePublicRequestFn\(\{/,
|
||||
'MindSpace workspace delivery resolves public backing files',
|
||||
);
|
||||
requireSource(
|
||||
workspaceDeliveryServiceSource,
|
||||
/getDeliveryContractFn\(\{/,
|
||||
'MindSpace workspace delivery validates delivery readiness',
|
||||
);
|
||||
requireSource(
|
||||
workspaceDeliveryServiceSource,
|
||||
/materializePrivateAssetsFn\(\{/,
|
||||
'MindSpace workspace delivery owns private asset materialization',
|
||||
);
|
||||
requireSource(
|
||||
workspaceDeliveryServiceSource,
|
||||
/async validateRunDeliverables\(\{/,
|
||||
'MindSpace workspace delivery owns run deliverable validation',
|
||||
);
|
||||
requireSource(
|
||||
portalWorkspaceDeliverySource,
|
||||
/\.resolveWorkspaceRequest\(\{/,
|
||||
'Portal workspace route delegates logical delivery to MindSpace',
|
||||
);
|
||||
requireSource(
|
||||
portalWorkspaceDeliverySource,
|
||||
/\.renderLongImage\(\{/,
|
||||
'Portal delegates workspace long-image rendering to MindSpace',
|
||||
);
|
||||
forbidSource(
|
||||
portalWorkspaceDeliverySource,
|
||||
/(?:node:fs|node:path|resolveMindSpaceUserPublishDir|resolveMindSpaceRuntimeConfig|resolveMindSpacePublicRequest|readFileSync|sendFile\()/,
|
||||
'Portal workspace delivery must not resolve or read physical backing files',
|
||||
);
|
||||
forbidSource(
|
||||
portalWorkspaceDeliverySource,
|
||||
/materializePrivateAssetsInWorkspaceHtml/,
|
||||
'Portal workspace delivery must not materialize private assets',
|
||||
);
|
||||
requireSource(
|
||||
portalPublicationRoutesSource,
|
||||
/\.readOwnerPublicAsset\(\{/,
|
||||
'owner public asset route delegates to MindSpace',
|
||||
);
|
||||
forbidSource(
|
||||
portalPublicationRoutesSource,
|
||||
/(?:node:fs|node:path|resolveMindSpaceUserPublishDir|sendFile\()/,
|
||||
'Portal publication routes must not resolve or serve physical files',
|
||||
);
|
||||
forbidSource(
|
||||
portalPublicationRoutesSource,
|
||||
/\bbuildMindSpacePublicRoutePath\b/,
|
||||
'Portal publication routes must not construct workspace canonical URLs',
|
||||
);
|
||||
requireSource(
|
||||
portalPublicationRoutesSource,
|
||||
/result\.workspacePublicUrl/,
|
||||
'Portal publication redirects use the MindSpace canonical URL',
|
||||
);
|
||||
requireSource(
|
||||
publicationServiceSource,
|
||||
/workspacePublicUrl:\s*[\s\S]{0,80}resolveWorkspaceMindSpacePublicUrl\(\{/,
|
||||
'MindSpace publication resolve result owns the workspace canonical URL',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/workspaceToolService:\s*Object\.freeze\(\[/,
|
||||
'local and remote adapters expose logical workspace tools',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/workspaceToolService:[\s\S]{0,240}'generateLongImage'[\s\S]{0,240}'writeBinaryFile'/,
|
||||
'workspace tool contract includes long-image generation and binary writes',
|
||||
);
|
||||
requireSource(
|
||||
contractSource,
|
||||
/conversationArtifactService:[\s\S]{0,240}'registerWorkspaceFileArtifact'/,
|
||||
'conversation artifact contract includes generic workspace write registration',
|
||||
);
|
||||
requireSource(
|
||||
localRuntimeSource,
|
||||
/createMindSpaceWorkspaceToolService\(\{/,
|
||||
'MindSpace local runtime owns logical workspace tools',
|
||||
);
|
||||
requireSource(
|
||||
workspaceToolServiceSource,
|
||||
/parseMindSpaceWorkspaceRef\(workspaceRef\)/,
|
||||
'workspace tools resolve a logical workspaceRef',
|
||||
);
|
||||
requireSource(
|
||||
workspaceToolServiceSource,
|
||||
/syncWorkspaceAssets\(/,
|
||||
'workspace writes synchronize logical assets',
|
||||
);
|
||||
requireSource(
|
||||
workspaceToolServiceSource,
|
||||
/\.registerWorkspaceFileArtifact\(\{/,
|
||||
'non-public workspace writes register package artifacts directly',
|
||||
);
|
||||
requireSource(
|
||||
workspaceToolServiceSource,
|
||||
/\.registerPublicHtmlArtifacts\(\{/,
|
||||
'public HTML workspace writes register package artifacts immediately',
|
||||
);
|
||||
requireSource(
|
||||
workspaceToolServiceSource,
|
||||
/async writeBinaryFile\([\s\S]{0,900}registerWrite\(\{/,
|
||||
'binary workspace writes persist and register through MindSpace',
|
||||
);
|
||||
requireSource(
|
||||
workspaceToolServiceSource,
|
||||
/async generateLongImage\([\s\S]{0,1800}renderLongImageFn\(\{[\s\S]{0,900}registerWrite\(\{/,
|
||||
'long-image generation and artifact registration run inside MindSpace',
|
||||
);
|
||||
forbidSource(
|
||||
workspaceToolServiceSource,
|
||||
/\babsolutePath\s*:/,
|
||||
'logical workspace tool results must not expose absolute paths',
|
||||
);
|
||||
requireSource(
|
||||
scopedMcpTokenSource,
|
||||
/sessionId:[\s\S]{0,180}packageId:[\s\S]{0,180}workspaceRef:[\s\S]{0,180}tools:/,
|
||||
'MCP token binds session, package, workspace, and tool allowlist',
|
||||
);
|
||||
requireSource(
|
||||
mindSpaceRpcServerSource,
|
||||
/verifyMindSpaceMcpScopedToken\(\{/,
|
||||
'MindSpace MCP RPC verifies scoped tokens',
|
||||
);
|
||||
requireSource(
|
||||
mindSpaceRpcServerSource,
|
||||
/workspaceToolService[\s\S]{0,240}claims\.workspaceRef/,
|
||||
'MindSpace MCP RPC injects token workspace claims into tool calls',
|
||||
);
|
||||
requireSource(
|
||||
mindSpaceRpcServerSource,
|
||||
/generate_long_image:\s*'generateLongImage'[\s\S]{0,160}write_binary_file:\s*'writeBinaryFile'/,
|
||||
'MindSpace MCP RPC exposes scoped long-image and binary operations',
|
||||
);
|
||||
requireSource(
|
||||
sandboxMcpSource,
|
||||
/callLogicalWorkspaceTool\(/,
|
||||
'sandbox MCP delegates logical workspace operations over RPC',
|
||||
);
|
||||
requireSource(
|
||||
sandboxMcpSource,
|
||||
/MINDSPACE_MCP_SCOPED_TOKEN/,
|
||||
'sandbox MCP accepts only a scoped service token',
|
||||
);
|
||||
requireSource(
|
||||
sandboxMcpSource,
|
||||
/case 'generate_docx':[\s\S]{0,1200}callLogicalWorkspaceTool\([\s\S]{0,120}'write_binary_file'/,
|
||||
'scoped DOCX generation uploads through MindSpace instead of the workspace path',
|
||||
);
|
||||
requireSource(
|
||||
sandboxMcpSource,
|
||||
/LOGICAL_WORKSPACE_TOOLS[\s\S]{0,240}'generate_long_image'/,
|
||||
'scoped long-image generation delegates to MindSpace',
|
||||
);
|
||||
requireSource(
|
||||
capabilitiesSource,
|
||||
/mintMindSpaceMcpScopedToken\(\{/,
|
||||
'Portal policy assembly mints a scoped MCP token',
|
||||
);
|
||||
requireSource(
|
||||
capabilitiesSource,
|
||||
/mcpTools\.includes\('generate_docx'\)[\s\S]{0,100}'write_binary_file'/,
|
||||
'DOCX capability grants only the internal scoped binary write operation',
|
||||
);
|
||||
forbidSource(
|
||||
capabilitiesSource,
|
||||
/envs\.MINDSPACE_MCP_TOKEN_SECRET/,
|
||||
'the MCP signing secret must never enter the Goose extension environment',
|
||||
);
|
||||
requireSource(
|
||||
userAuthSource,
|
||||
/workspaceRef:[\s\S]{0,180}sessionId:[\s\S]{0,180}packageId:/,
|
||||
'agent session policy supplies logical workspace/session/package scope',
|
||||
);
|
||||
requireSource(
|
||||
userAuthSource,
|
||||
/mcpBaseUrl:[\s\S]{0,160}mcpTokenSecret:/,
|
||||
'agent session policy supplies the MCP endpoint and server-side signing secret',
|
||||
);
|
||||
|
||||
if (withRuntime) {
|
||||
const portalRuntimeSource = read('.runtime/portal/server.mjs');
|
||||
const mindSpaceRuntimeContract = read(
|
||||
'.runtime/mindspace-service/memind-source/mindspace-server-adapter-contract.mjs',
|
||||
);
|
||||
const mindSpaceRuntimeService = read(
|
||||
'.runtime/mindspace-service/memind-source/mindspace-chat-save-service.mjs',
|
||||
);
|
||||
const mindSpaceRuntimeArtifactService = read(
|
||||
'.runtime/mindspace-service/memind-source/mindspace-conversation-package-artifact-service.mjs',
|
||||
);
|
||||
const mindSpaceRuntimePublicFinishService = read(
|
||||
'.runtime/mindspace-service/memind-source/mindspace-public-finish-service.mjs',
|
||||
);
|
||||
const mindSpaceRuntimeWorkspaceDeliveryService = read(
|
||||
'.runtime/mindspace-service/memind-source/mindspace-workspace-publication-delivery-service.mjs',
|
||||
);
|
||||
requireSource(
|
||||
portalRuntimeSource,
|
||||
/materializeWorkspaceHtml/,
|
||||
'Portal runtime delegates chat-save materialization',
|
||||
);
|
||||
requireSource(
|
||||
mindSpaceRuntimeContract,
|
||||
/chatSaveService/,
|
||||
'MindSpace runtime exposes the chat-save RPC contract',
|
||||
);
|
||||
requireSource(
|
||||
mindSpaceRuntimeService,
|
||||
/writeFileFn\(absolutePath,\s*materializedHtml,\s*'utf8'\)/,
|
||||
'MindSpace runtime owns the chat-save workspace write',
|
||||
);
|
||||
requireSource(
|
||||
mindSpaceRuntimeService,
|
||||
/async createSharedHtml\(\{/,
|
||||
'MindSpace runtime owns shared HTML creation',
|
||||
);
|
||||
requireSource(
|
||||
mindSpaceRuntimeArtifactService,
|
||||
/registerPublicHtmlArtifacts/,
|
||||
'MindSpace runtime owns conversation artifact registration',
|
||||
);
|
||||
requireSource(
|
||||
mindSpaceRuntimePublicFinishService,
|
||||
/syncAfterFinish/,
|
||||
'MindSpace runtime owns public Finish synchronization',
|
||||
);
|
||||
requireSource(
|
||||
mindSpaceRuntimeWorkspaceDeliveryService,
|
||||
/resolveWorkspaceRequest/,
|
||||
'MindSpace runtime owns workspace publication delivery',
|
||||
);
|
||||
}
|
||||
|
||||
console.log(
|
||||
withRuntime
|
||||
? 'mindspace read/write authority boundary ok (with runtimes)'
|
||||
: 'mindspace read/write authority boundary ok',
|
||||
);
|
||||
Reference in New Issue
Block a user