Skip to content

Commit 37cf36f

Browse files
mdhellerclaude
andauthored
Lane G: add prophet-mesh memory-scope mirror contract (#38)
Closes the last unmirrored authority claim in the private-preview spine: - registry mirrors choir authority - model-router mirrors routing policy - agentplane projects execution receipts - memory-mesh now mirrors memory-scope policy (this commit) The mirror contract: - Pins the memory_scope policy boundary from prophet-mesh specs - Cross-references the agentplane adapter content hash (38a3edb6...) - Enforces non-production boundary (dry_run_receipt_preview, receipt_only) - Prohibits live_execution scope coverage - Includes a validator (make validate-prophet-mesh-scope-mirror) Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent d449eec commit 37cf36f

3 files changed

Lines changed: 149 additions & 0 deletions

File tree

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,6 @@ local-debug:
4848

4949
local-down:
5050
bash deploy/local/scripts/down-local.sh
51+
52+
validate-prophet-mesh-scope-mirror:
53+
node scripts/validate-prophet-mesh-scope-mirror.mjs
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"schemaVersion": "memory-mesh.cross-repo-scope-mirror.v0.1",
3+
"kind": "CrossRepoScopeMirror",
4+
"contractVersion": "v0.1",
5+
"mirrorId": "memory-mesh:prophet-mesh-memory-scope:v0.1",
6+
"createdAt": "2026-06-10T00:00:00Z",
7+
"sourceAuthority": {
8+
"repo": "SocioProphet/prophet-mesh",
9+
"path": "specs/runtime-release-bundle.yaml",
10+
"contractVersion": "v0.1",
11+
"claim": "memory_scope field in execution_trace must be explicit and non-empty"
12+
},
13+
"mirrorAuthority": {
14+
"repo": "SocioProphet/memory-mesh",
15+
"path": "contracts/prophet-mesh/prophet-mesh-memory-scope.v0.1.json",
16+
"attestation": "memory-mesh independently mirrors the memory-scope policy boundary established by prophet-mesh"
17+
},
18+
"scopePolicy": {
19+
"requiredField": "execution_trace.memory_scope",
20+
"allowedScopePatterns": [
21+
"relationship_context:approved",
22+
"noetica-session-local",
23+
"noetica-session-local:*",
24+
"unscoped"
25+
],
26+
"prohibitedValues": [null, ""],
27+
"enforcement": "reject_if_absent_or_empty",
28+
"effectBoundary": {
29+
"workspaceWriteEnabled": false,
30+
"externalSendEnabled": false,
31+
"effectEnabled": false
32+
}
33+
},
34+
"privatePreviewInvariants": [
35+
"execution_trace_must_include_memory_scope",
36+
"memory_scope_must_be_explicit",
37+
"memory_scope_must_not_be_empty_string",
38+
"memory_scope_must_match_allowed_pattern_or_be_scoped_local"
39+
],
40+
"nonProductionBoundary": {
41+
"claim": "This mirror contract covers dry-run and receipt-only modes only. Live execution scope policy requires a separate contract version.",
42+
"coveredModes": ["dry_run_receipt_preview", "receipt_only"],
43+
"excludedModes": ["live_execution"]
44+
},
45+
"crossRepoTraceability": {
46+
"prophetMeshAdapterRef": {
47+
"repo": "SocioProphet/agentplane",
48+
"path": "contracts/prophet-mesh/prophet-mesh-agentplane-adapter.v0.1.json",
49+
"contractVersion": "v0.1",
50+
"mergeCommit": "faa767f42028ad0f2475c993700cdbef8490a38e",
51+
"contentSha256": "38a3edb62813521a62f257f3f952271255d25dc3a05a14d6b96f04a6ff9b4268",
52+
"mode": "dry_run_receipt_preview"
53+
},
54+
"runtimeReleaseBundleContract": {
55+
"repo": "SocioProphet/prophet-mesh",
56+
"path": "specs/runtime-release-bundle.yaml",
57+
"invariant": "execution_trace_must_include_memory_scope"
58+
}
59+
},
60+
"promotionNotes": [
61+
"Memory-scope authority was self-attested in prophet-mesh only prior to this mirror.",
62+
"This contract closes the symmetry gap: registry mirrors choir authority, model-router mirrors routing policy, agentplane projects execution receipts, memory-mesh now mirrors memory-scope policy.",
63+
"No live execution scope is claimed. Non-production boundary applies."
64+
]
65+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/usr/bin/env node
2+
/**
3+
* Validate the prophet-mesh memory-scope mirror contract.
4+
* Lane G — confirms the mirror is structurally sound and cross-repo refs are present.
5+
*/
6+
import { readFile } from 'fs/promises'
7+
import { fileURLToPath } from 'url'
8+
9+
const CONTRACT_PATH = 'contracts/prophet-mesh/prophet-mesh-memory-scope.v0.1.json'
10+
const REQUIRED_FIELDS = [
11+
'schemaVersion', 'kind', 'contractVersion', 'mirrorId',
12+
'sourceAuthority', 'mirrorAuthority', 'scopePolicy',
13+
'privatePreviewInvariants', 'nonProductionBoundary', 'crossRepoTraceability'
14+
]
15+
const REQUIRED_INVARIANTS = [
16+
'execution_trace_must_include_memory_scope',
17+
'memory_scope_must_be_explicit',
18+
'memory_scope_must_not_be_empty_string'
19+
]
20+
const REQUIRED_MODES = ['dry_run_receipt_preview', 'receipt_only']
21+
22+
function assert(condition, message) {
23+
if (!condition) throw new Error(message)
24+
}
25+
26+
async function main() {
27+
const raw = await readFile(CONTRACT_PATH, 'utf8')
28+
const contract = JSON.parse(raw)
29+
30+
for (const field of REQUIRED_FIELDS) {
31+
assert(field in contract, `missing required field: ${field}`)
32+
}
33+
34+
assert(contract.kind === 'CrossRepoScopeMirror', 'kind must be CrossRepoScopeMirror')
35+
assert(contract.contractVersion === 'v0.1', 'contractVersion must be v0.1')
36+
37+
const policy = contract.scopePolicy
38+
assert(policy.requiredField === 'execution_trace.memory_scope', 'scopePolicy.requiredField must be execution_trace.memory_scope')
39+
assert(policy.enforcement === 'reject_if_absent_or_empty', 'scopePolicy.enforcement must be reject_if_absent_or_empty')
40+
assert(policy.effectBoundary.effectEnabled === false, 'effectBoundary.effectEnabled must be false')
41+
assert(policy.effectBoundary.workspaceWriteEnabled === false, 'effectBoundary.workspaceWriteEnabled must be false')
42+
43+
for (const invariant of REQUIRED_INVARIANTS) {
44+
assert(
45+
contract.privatePreviewInvariants.includes(invariant),
46+
`missing required invariant: ${invariant}`
47+
)
48+
}
49+
50+
const boundary = contract.nonProductionBoundary
51+
for (const mode of REQUIRED_MODES) {
52+
assert(boundary.coveredModes.includes(mode), `nonProductionBoundary.coveredModes must include ${mode}`)
53+
}
54+
assert(!boundary.coveredModes.includes('live_execution'), 'live_execution must not be in coveredModes')
55+
56+
const trace = contract.crossRepoTraceability
57+
assert(typeof trace.prophetMeshAdapterRef === 'object', 'crossRepoTraceability.prophetMeshAdapterRef required')
58+
const ref = trace.prophetMeshAdapterRef
59+
assert(ref.repo === 'SocioProphet/agentplane', 'adapter ref repo must be SocioProphet/agentplane')
60+
assert(typeof ref.contentSha256 === 'string' && ref.contentSha256.length === 64, 'contentSha256 must be 64-char hex')
61+
assert(ref.mode === 'dry_run_receipt_preview', 'adapter ref mode must be dry_run_receipt_preview')
62+
63+
console.log(JSON.stringify({
64+
ok: true,
65+
contractPath: CONTRACT_PATH,
66+
mirrorId: contract.mirrorId,
67+
scopePolicy: contract.scopePolicy.enforcement,
68+
invariantsVerified: REQUIRED_INVARIANTS.length,
69+
adapterRefSha256: ref.contentSha256.slice(0, 16) + '...',
70+
nonProductionBoundary: boundary.coveredModes
71+
}, null, 2))
72+
}
73+
74+
main().catch((error) => {
75+
console.error(error instanceof Error ? error.message : String(error))
76+
process.exit(1)
77+
})
78+
79+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
80+
// already runs via top-level await equivalent above
81+
}

0 commit comments

Comments
 (0)