- scripts/check-single-memory-mutated-emit.sh — MEM-06 single-emission-site for ReplayEvent.memoryMutation (allowlist: MemoryStore.swift, Replay/ReplayEvent.swift, Replay/Schema.swift; tests + comments excluded). - scripts/check-single-memory-used-emit.sh — D-05 single-emission-site for ReplayEvent.memoryRetrieval (same allowlist shape, MemoryStore.recordRetrieval is the sole emit site). - scripts/check-presence-vision-isolation.sh — VISION-03 three-layer guard: Layer 1 (Vision/Package.swift declares no Voice or AgentOrchestrator dep), Layer 2 (no `import Voice` / `import AgentOrchestrator` and no TTSEngine / AgentOrchestrator.runTurn / cancelAndSubmit token references in packages/Vision/Sources/), Layer 3 (no App/ file co-locates a PresenceSignalBus reference with a forbidden TTS / runTurn token). - scripts/check-embedding-dim-literal.sh — MEM-02 invariant: no literal 768 in packages/Memory/Sources/Memory/ outside Constants.swift; comment-only lines tolerated. - All four scripts wired as Jarvis pre-build phases in project.yml; the generated project.pbxproj reflects the updates. - packages/Memory/Tests/MemoryTests/PhaseSevenGrepGateTests.swift mirrors the four shell gates as XCTest assertions plus a fifth assertion (testAppDelegateInstallOrder) verifying the call order in applicationWillFinishLaunching: installMemory before installVoice before installVision. - App/Voice/NullVoiceAdapters.swift extracted from AppDelegate.swift to honor the Layer 3 boundary cleanly. NullOrchestratorAdapter and NullTTSAdapter are placeholder no-ops mirroring the prior structure; Phase 7 future wiring replaces them with real bridges. - Negative-case demonstration completed: introducing a stray `.memoryMutation(...)` literal in App/AppDelegate.swift made check-single-memory-mutated-emit.sh exit non-zero; the violation was reverted before commit. Documented as evidence of gate sensitivity.
39 lines
1.7 KiB
Bash
Executable File
39 lines
1.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# MEM-06 single-emission-site invariant guard.
|
|
#
|
|
# `ReplayEvent.memoryMutation(...)` (which serializes to the `memory.mutated`
|
|
# DevOverlay row) may only be CONSTRUCTED inside MemoryStore.applyOp.
|
|
# Multiple emit sites would (a) duplicate DevOverlay rows and (b) invalidate
|
|
# the planner-stated invariant in 07-02's must_haves.
|
|
#
|
|
# Allowlist (production):
|
|
# - packages/Memory/Sources/Memory/MemoryStore.swift (sole emit site, in applyOp)
|
|
# - packages/Replay/Sources/Replay/ReplayEvent.swift (case decl + encoded() switch arm)
|
|
# - packages/Replay/Sources/Replay/Schema.swift (case in encoded() switch)
|
|
#
|
|
# Tests are excluded entirely (`/Tests/`). Comment-only lines (after the
|
|
# file:lineno: prefix is stripped) are tolerated so docstrings explaining
|
|
# the rule do not trip the gate.
|
|
set -euo pipefail
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$REPO_ROOT"
|
|
|
|
# Strip the `file:lineno:` prefix and inspect the line content. A comment is
|
|
# a line whose first non-whitespace characters are `//` or `*` or `/*`.
|
|
HITS=$(grep -rn 'memory\.mutated\|\.memoryMutation(' packages/ App/ --include='*.swift' 2>/dev/null \
|
|
| grep -v '/Tests/' \
|
|
| grep -v 'packages/Memory/Sources/Memory/MemoryStore.swift:' \
|
|
| grep -v 'packages/Replay/Sources/Replay/ReplayEvent.swift:' \
|
|
| grep -v 'packages/Replay/Sources/Replay/Schema.swift:' \
|
|
| sed -E 's|^[^:]+:[0-9]+:||' \
|
|
| grep -vE '^[[:space:]]*(//|\*|/\*)' \
|
|
| grep -E 'memory\.mutated|\.memoryMutation\(' || true)
|
|
|
|
if [[ -n "$HITS" ]]; then
|
|
echo "MEM-06 violation: memory.mutated / .memoryMutation constructed outside MemoryStore.applyOp:" >&2
|
|
echo "$HITS" >&2
|
|
exit 1
|
|
fi
|
|
exit 0
|