Skip to content

feat(notify): prove dormant diagnostics namespace isolation - #110

Merged
psimaker merged 4 commits into
mainfrom
agent/m4-namespace-isolation
Jul 13, 2026
Merged

feat(notify): prove dormant diagnostics namespace isolation#110
psimaker merged 4 commits into
mainfrom
agent/m4-namespace-isolation

Conversation

@psimaker

@psimaker psimaker commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • Implement the fixed Decision 023 ownership schemas, signatures, digest chains, stable installation bindings, and canonical namespace names.
  • Add a dedicated atomic namespace state store plus Linux descriptor-relative confinement with root, inode, device, ownership, mode, link-count, allocation, and mount-identity checks.
  • Add explicit test-only preparation, collision refusal, create-once records, complete persistent-chain validation, and bounded idempotent cleanup.
  • Add four-language dormant consent snapshots and privacy documentation covering visibility and retention.
  • Add a local Docker host-bind proof and run it as a separate pull-request CI job.

Safety boundaries

The installed helper and app do not call this foundation. There is no listener, endpoint, capability advertisement, automatic discovery, automatic namespace creation, Syncthing configuration mutation, Relay call, production service, deployment, or product flow. Decision 024 is unchanged. Trigger v1 and Cloud Relay v1 remain unchanged. Upload attestation, controlled download, roundtrip evidence, and authenticated operational correlation remain unimplemented.

Real Syncthing-matcher integration and a production installer are intentionally absent, so runtime support is not claimed. The dormant preparation primitive only accepts an externally evaluated fail-closed ignore verdict plus explicit operator confirmation. Swift remains test-only for the new records and consent copy.

Docker evidence

notify/tests/m4-docker/run.sh proves one narrow shape:

  • an explicit installer phase receives one selected test folder and creates the exact fixed child;
  • the dormant runtime receives only the exact existing VaultSync Diagnostics host bind, separate state, and read-only config;
  • the container root is read-only, networking is disabled, all capabilities are dropped, no-new-privileges is set, and no parent-vault path is visible; and
  • a bind mount placed over the fixed installations child is rejected by Linux mount identity.

Docker named volumes, rootless Docker, NAS packages, Linux host packaging, macOS, and Windows remain unsupported for this capability.

Compatibility, privacy, and rollback

Existing users receive no folder, mount, state, pairing, credential, migration, or configuration change. The wire surface is unchanged because no installed entrypoint references the new code. Namespace state is separate from credential state and contains only opaque bindings, a fixed mount alias, manifest digest, device, and inode.

Cleanup targets at most three exact authenticated operation files and never upgrades evidence. Missing files are idempotent success; changed, linked, raced, sparse, unknown, conflict, or unverified entries remain untouched. Root records, authorizations, credentials, backups, versions, conflict copies, remote history, and tombstones are never cleanup targets. Rollback removes only future capability availability; it does not delete state or synchronized history.

Validation

  • cd notify && go test ./... -count=1
  • cd notify && go test -race ./... -count=1
  • cd notify && go vet ./...
  • Linux and Windows cross-compilation of the Notify test binary
  • Linux namespace attack suite in a read-only, networkless, capability-free container
  • notify/tests/m4-docker/run.sh
  • Shellcheck 0.10.0 and sh -n for the Docker harness
  • 15-second fuzz runs for Decision 023 components and fixed path shapes
  • govulncheck 1.6.0 for Notify and the Go bridge
  • cd go && make patch && go test -tags noassets ./bridge -count=1
  • full iOS build/test: 394 tests passed, 0 failed, 0 skipped
  • strings parity: 759 keys in en/de/es/zh-Hans, no duplicates
  • design-token lint, privacy lint, installer dry-run, YAML parse, gofmt, and git diff --check

psimaker added 3 commits July 13, 2026 13:26
Document the future opt-in namespace's visibility across synchronized peers, file browsers, backups, versions, conflicts, remote history, and tombstones.

Record that the M4 foundation is dormant and test-only, uses a separate helper state store, changes no Syncthing configuration, creates no namespace automatically, and sends no contract data to Cloud Relay.

Limit currently tested support to an explicit Docker host bind mount and mark other packaging targets unsupported until isolation and rollback are proven.
Implement the fixed Decision 023 deterministic CBOR schemas, dual-signature ownership chains, stable installation bindings, and canonical namespace filenames as an unreachable internal foundation.

Add shared Go/Swift golden records and four-language consent snapshots that disclose visibility and retention while remaining unreferenced by the app product flow.

Keep the installed helper and app unchanged: no endpoint, listener, namespace creation, filesystem access, Syncthing mutation, Relay call, evidence transition, deployment, or rollout is introduced.
Add a separate crash-safe namespace state store and Linux descriptor-relative filesystem foundation with fixed protocol paths, create-once records, root and mount identity checks, complete ownership-chain validation, fail-closed collisions, and bounded idempotent cleanup.

Add an explicit test-only preparation flow and Docker host-bind harness proving a read-only container root, separate state, read-only config, no parent-vault access, dropped capabilities, no network, and child-mount rejection. Run the harness in pull-request CI.

Document visibility, retention, unsupported deployment targets, existing-user behavior, and rollback. Keep installed helper, app, Syncthing, Trigger v1, and Cloud Relay paths unchanged.
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a dormant diagnostics namespace foundation with signed CBOR records, secure Linux filesystem operations, atomic state storage, installer preparation, extensive tests, localized disclosure copy, Docker confinement checks, and CI integration. Runtime and product activation remain explicitly blocked.

Changes

Diagnostics namespace foundation

Layer / File(s) Summary
Protocol contract and cross-language fixtures
notify/diagnostics_namespace_protocol.go, notify/diagnostics_namespace_protocol_test.go, ios/VaultSyncTests/...
Defines signed CBOR records, canonical naming, chain validation, golden fixtures, and Swift cross-language consistency and consent-copy tests.
Secure namespace filesystem operations
notify/diagnostics_namespace_filesystem*.go, notify/diagnostics_namespace_linux_test.go
Adds identity-checked Linux filesystem access, immutable artifacts, bounded cleanup, fixed-layout validation, race detection, and unsupported-platform stubs.
Persistent state and installation preparation
notify/diagnostics_namespace_store*.go, notify/diagnostics_namespace_installer*.go
Adds private atomic state persistence, ignore preflight validation, namespace preparation, helper epochs, authorization records, and fail-closed installation behavior.
Dormancy and runtime boundary checks
notify/diagnostics_contract_model_test.go, notify/README.md, CHANGELOG.md, PRIVACY.md, docs/architecture.md, ios/VaultSync/*/Localizable.strings
Documents dormant behavior and disclosure text while enforcing that installed runtime paths cannot activate, mutate Syncthing, or reach the network.
Docker confinement proof and CI wiring
notify/tests/m4-docker/*, .github/workflows/ci.yml
Adds installer, runtime, and mount-swap Docker phases with hardened container settings, then runs the proof and shellcheck in CI.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Poem

Signed records hum in vaults below,
While guarded paths refuse to stray.
Docker binds the tests in tow,
And dormant flows remain at bay.
CI watches, locks align—
A quiet namespace, safely signed.

🚥 Pre-merge checks | ✅ 7
✅ Passed checks (7 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No Private Note Leakage ✅ Passed Changed code is local filesystem/test harness logic; I found no logging, analytics, crash reporting, or network paths that emit note contents, vault paths, keys, or receipts.
Bounded Ios Background Work ✅ Passed PASS: The iOS diff only adds tests/localizations; the new Swift test file has no BGTask/beginBackgroundTask/expirationHandler code, so no background-work risk is introduced.
Bridge Contract Compatibility ✅ Passed PR only adds dormant diagnostics-namespace code/docs/tests; no go/bridge or Swift bridge-service files changed, so bridge contracts stay untouched.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise, conventional-commit style, and accurately reflects the dormant diagnostics namespace isolation work.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/m4-namespace-isolation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@psimaker
psimaker marked this pull request as ready for review July 13, 2026 13:07

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Line 96: Update the actions/checkout step to set persist-credentials to false,
ensuring this read-only job does not store the GITHUB_TOKEN in the repository’s
Git configuration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c0d855db-5773-465a-ad70-ab79f3861c92

📥 Commits

Reviewing files that changed from the base of the PR and between 5932325 and ad4677e.

📒 Files selected for processing (27)
  • .github/workflows/ci.yml
  • CHANGELOG.md
  • PRIVACY.md
  • docs/architecture.md
  • ios/VaultSync/de.lproj/Localizable.strings
  • ios/VaultSync/en.lproj/Localizable.strings
  • ios/VaultSync/es.lproj/Localizable.strings
  • ios/VaultSync/zh-Hans.lproj/Localizable.strings
  • ios/VaultSyncTests/DiagnosticsNamespaceM4GoldenTests.swift
  • ios/VaultSyncTests/Fixtures/diagnostics-namespace-m4.json
  • notify/README.md
  • notify/diagnostics_contract_model_test.go
  • notify/diagnostics_namespace_filesystem.go
  • notify/diagnostics_namespace_filesystem_linux.go
  • notify/diagnostics_namespace_filesystem_test.go
  • notify/diagnostics_namespace_filesystem_unsupported.go
  • notify/diagnostics_namespace_installer.go
  • notify/diagnostics_namespace_installer_linux.go
  • notify/diagnostics_namespace_installer_unsupported.go
  • notify/diagnostics_namespace_linux_test.go
  • notify/diagnostics_namespace_protocol.go
  • notify/diagnostics_namespace_protocol_test.go
  • notify/diagnostics_namespace_store.go
  • notify/diagnostics_namespace_store_test.go
  • notify/tests/m4-docker/Dockerfile
  • notify/tests/m4-docker/README.md
  • notify/tests/m4-docker/run.sh
📜 Review details
🧰 Additional context used
📓 Path-based instructions (12)
**

⚙️ CodeRabbit configuration file

**:

VaultSync

VaultSync

Self-hosted Obsidian vault sync for iPhone and iPad.

Your notes sync peer-to-peer over Syncthing, straight into Obsidian's iOS sandbox — no note cloud, no account, no tracking.

Download on the App Store



Stars
License: MPL-2.0
iOS 18+
CI

VaultSync welcome screen VaultSync home screen

🔭 Why VaultSync

  • Peer-to-peer & private — syncs directly between your own devices over Syncthing. No note cloud, no account, no tracking.
  • Lands in Obsidian — files sync into Obsidian's iOS sandbox, where the app already looks for them.
  • Pair by QR, resolve conflicts — connect your server in seconds; settle Markdown conflicts with side-by-side diffs.
  • Server changes can wake your iPhone — optional Cloud Relay asks iOS to wake the app after the helper observes a server change. T...

Files:

  • notify/tests/m4-docker/Dockerfile
  • ios/VaultSync/zh-Hans.lproj/Localizable.strings
  • notify/diagnostics_namespace_installer_unsupported.go
  • ios/VaultSync/de.lproj/Localizable.strings
  • notify/tests/m4-docker/README.md
  • PRIVACY.md
  • ios/VaultSyncTests/Fixtures/diagnostics-namespace-m4.json
  • ios/VaultSync/es.lproj/Localizable.strings
  • notify/diagnostics_namespace_filesystem_test.go
  • notify/diagnostics_namespace_filesystem_unsupported.go
  • CHANGELOG.md
  • ios/VaultSync/en.lproj/Localizable.strings
  • notify/README.md
  • notify/diagnostics_namespace_installer.go
  • docs/architecture.md
  • notify/tests/m4-docker/run.sh
  • notify/diagnostics_namespace_store_test.go
  • notify/diagnostics_namespace_filesystem.go
  • ios/VaultSyncTests/DiagnosticsNamespaceM4GoldenTests.swift
  • notify/diagnostics_contract_model_test.go
  • notify/diagnostics_namespace_protocol_test.go
  • notify/diagnostics_namespace_installer_linux.go
  • notify/diagnostics_namespace_store.go
  • notify/diagnostics_namespace_protocol.go
  • notify/diagnostics_namespace_linux_test.go
  • notify/diagnostics_namespace_filesystem_linux.go
**/*

⚙️ CodeRabbit configuration file

**/*: VaultSync syncs private Obsidian notes through Syncthing. Treat data loss,
privacy leaks, security regressions, and broken sync behavior as high priority.
Do not nitpick formatting unless it affects maintainability, correctness, or public API clarity.
Flag any accidental logging, telemetry, crash reporting, or network transfer of note contents,
vault paths, filenames with private context, API keys, APNs tokens, relay keys, or security-scoped bookmark data.

Files:

  • notify/tests/m4-docker/Dockerfile
  • ios/VaultSync/zh-Hans.lproj/Localizable.strings
  • notify/diagnostics_namespace_installer_unsupported.go
  • ios/VaultSync/de.lproj/Localizable.strings
  • notify/tests/m4-docker/README.md
  • PRIVACY.md
  • ios/VaultSyncTests/Fixtures/diagnostics-namespace-m4.json
  • ios/VaultSync/es.lproj/Localizable.strings
  • notify/diagnostics_namespace_filesystem_test.go
  • notify/diagnostics_namespace_filesystem_unsupported.go
  • CHANGELOG.md
  • ios/VaultSync/en.lproj/Localizable.strings
  • notify/README.md
  • notify/diagnostics_namespace_installer.go
  • docs/architecture.md
  • notify/tests/m4-docker/run.sh
  • notify/diagnostics_namespace_store_test.go
  • notify/diagnostics_namespace_filesystem.go
  • ios/VaultSyncTests/DiagnosticsNamespaceM4GoldenTests.swift
  • notify/diagnostics_contract_model_test.go
  • notify/diagnostics_namespace_protocol_test.go
  • notify/diagnostics_namespace_installer_linux.go
  • notify/diagnostics_namespace_store.go
  • notify/diagnostics_namespace_protocol.go
  • notify/diagnostics_namespace_linux_test.go
  • notify/diagnostics_namespace_filesystem_linux.go
notify/**/*.{sh,go}

📄 CodeRabbit inference engine (README.md)

The optional notify sidecar must support server-side wake-up requests and must not receive notes, file or folder names, or vault structure.

Files:

  • notify/diagnostics_namespace_installer_unsupported.go
  • notify/diagnostics_namespace_filesystem_test.go
  • notify/diagnostics_namespace_filesystem_unsupported.go
  • notify/diagnostics_namespace_installer.go
  • notify/tests/m4-docker/run.sh
  • notify/diagnostics_namespace_store_test.go
  • notify/diagnostics_namespace_filesystem.go
  • notify/diagnostics_contract_model_test.go
  • notify/diagnostics_namespace_protocol_test.go
  • notify/diagnostics_namespace_installer_linux.go
  • notify/diagnostics_namespace_store.go
  • notify/diagnostics_namespace_protocol.go
  • notify/diagnostics_namespace_linux_test.go
  • notify/diagnostics_namespace_filesystem_linux.go
**/*.{md,sh,go,swift}

📄 CodeRabbit inference engine (README.md)

Keep Relay-side request observation and wake-ups received on the iPhone as separate diagnostics evidence; one must not be treated as proof of the other.

Files:

  • notify/diagnostics_namespace_installer_unsupported.go
  • notify/tests/m4-docker/README.md
  • PRIVACY.md
  • notify/diagnostics_namespace_filesystem_test.go
  • notify/diagnostics_namespace_filesystem_unsupported.go
  • CHANGELOG.md
  • notify/README.md
  • notify/diagnostics_namespace_installer.go
  • docs/architecture.md
  • notify/tests/m4-docker/run.sh
  • notify/diagnostics_namespace_store_test.go
  • notify/diagnostics_namespace_filesystem.go
  • ios/VaultSyncTests/DiagnosticsNamespaceM4GoldenTests.swift
  • notify/diagnostics_contract_model_test.go
  • notify/diagnostics_namespace_protocol_test.go
  • notify/diagnostics_namespace_installer_linux.go
  • notify/diagnostics_namespace_store.go
  • notify/diagnostics_namespace_protocol.go
  • notify/diagnostics_namespace_linux_test.go
  • notify/diagnostics_namespace_filesystem_linux.go
notify/**/*.go

⚙️ CodeRabbit configuration file

notify/**/*.go: Review goroutine lifecycle, context cancellation, HTTP timeouts, signal handling, debounce behavior,
Syncthing REST API polling, relay API calls, error classification, and API-key handling.
Flag leaked request bodies, note metadata, Syncthing API keys, relay keys, or APNs-related secrets.

Files:

  • notify/diagnostics_namespace_installer_unsupported.go
  • notify/diagnostics_namespace_filesystem_test.go
  • notify/diagnostics_namespace_filesystem_unsupported.go
  • notify/diagnostics_namespace_installer.go
  • notify/diagnostics_namespace_store_test.go
  • notify/diagnostics_namespace_filesystem.go
  • notify/diagnostics_contract_model_test.go
  • notify/diagnostics_namespace_protocol_test.go
  • notify/diagnostics_namespace_installer_linux.go
  • notify/diagnostics_namespace_store.go
  • notify/diagnostics_namespace_protocol.go
  • notify/diagnostics_namespace_linux_test.go
  • notify/diagnostics_namespace_filesystem_linux.go
**/*.md

⚙️ CodeRabbit configuration file

**/*.md: Review public documentation for technical accuracy, privacy/security claims, App Store-facing wording,
setup correctness, and consistency with the free app plus optional Cloud Relay subscription model.

Files:

  • notify/tests/m4-docker/README.md
  • PRIVACY.md
  • CHANGELOG.md
  • notify/README.md
  • docs/architecture.md
docs/**/*.md

📄 CodeRabbit inference engine (docs/troubleshooting.md)

docs/**/*.md: After applying each troubleshooting fix, retry from the app to confirm whether the issue is resolved.
For a missing Device ID or “Sync Engine Not Running,” force-close and reopen VaultSync, keep it foregrounded for 20–30 seconds, confirm the Device ID, rescan the vault, and reboot if necessary.
vaultsync-notify must read the Syncthing API key from config.xml; permission or authentication failures should be diagnosed as wrong-file or read-permission problems before changing credentials.
Run vaultsync-notify as the user owning Syncthing’s mode-0600 config.xml, or configure the appropriate container PUID/PGID.
Set SYNCTHING_CONFIG when the Syncthing configuration is not auto-detected, and remove or correct SYNCTHING_API_KEY overrides that replace automatic detection.
For relay failures, verify internet access, RELAY_URL, server egress rules, relay health with curl, and the app’s relay diagnostics; confirm delivery through an updated “Last Trigger Received” timestamp.
A relay HTTP 429 from --doctor counts as success because it proves the trigger endpoint is reachable; an inactive subscription is a warning fixed through app subscription or provisioning.
Peer-state warnings from --doctor must not fail the command: offline peers are normal, and --healthcheck must skip peer-state diagnostics.
For missing pending shares, verify the desktop folder shares the exact iOS Device ID, ensure Syncthing is online and unpaused, refresh pending shares, and re-share if needed.
For APNs issues, retry APNs registration, verify a token appears, retry provisioning, and confirm delivery with “Last Trigger Received”; notification permission is not required for silent wake-ups.
When connecting Obsidian storage, choose On My iPhone → Obsidian or the vault root containing .obsidian, then confirm detected vaults or pending shares.
VaultSync must not move, recreate, or delete vault folders automatically; recovery from moved or deleted folders requires ma...

Files:

  • docs/architecture.md
docs/**

⚙️ CodeRabbit configuration file

docs/**: # Architecture

VaultSync embeds Syncthing's Go reference implementation as an iOS library via gomobile — no reimplementation of the protocol in Swift, and guaranteed wire compatibility.

┌─────────────────────────────────┐
│         SwiftUI Frontend        │   iOS-native UI, Swift 6
├─────────────────────────────────┤
│       Swift ↔ Go Bridge         │   thin API via gomobile
│                                 │   → exported as .xcframework
├─────────────────────────────────┤
│        syncthing/lib (Go)       │   protocol, discovery, sync
└─────────────────────────────────┘
              ↕ filesystem
┌─────────────────────────────────┐
│    Obsidian Vault (direct)      │   Obsidian's iOS sandbox
└─────────────────────────────────┘

🔄 Sync strategy

  • Foreground — Syncthing runs unrestricted: immediate, continuous sync.
  • BackgroundBGAppRefreshTask (requested ~15 min out; iOS decides the actual timing) + BGProcessingTask (overnight catch-up: multi-minute budget while charging with network) + BGContinuedProcessingTask (iOS 26+, longer runtime for user-initiated tasks). A ~30s grace window after backgrounding lets in-flight work finish.
  • Push (Cloud Relay) — optional. Near-realtime server → iPhone wake-ups via APNs silent push. See relay-spec.md.

VaultSync is intentionally asymmetric:

Direction Path
Server → iPhone vaultsync-notify spots outgoing changes → Cloud Relay silent push → VaultSync wakes and pulls.
iPhone → Server iOS doesn't guarantee timely background execution for local edits. The reliable path is to open VaultSync and let embedded Syncthing run in the foreground — a Shortcuts automation can do that automatically whenever you leave Obsidian.

Cloud Relay is a server → iPhone acceleration path, not a guarantee of symmetric real-time background sync.

Relay and sync proof hierarchy

VaultSync models proof as independent fi...

Files:

  • docs/architecture.md
.github/workflows/**/*.yml

⚙️ CodeRabbit configuration file

.github/workflows/**/*.yml: Review CI for correct Go test tags, Xcode/iOS simulator assumptions, secret scoping,
dependency integrity, permissions, Docker publishing safety, and unnecessary privilege escalation.

Files:

  • .github/workflows/ci.yml
**/*.swift

📄 CodeRabbit inference engine (Custom checks)

For Swift background execution changes, pass if work is bounded, cancellation-aware, handles expiration callbacks, and records errors without leaking private vault data. Fail only when background work can continue unbounded, miss cleanup, or violate iOS background execution constraints.

Files:

  • ios/VaultSyncTests/DiagnosticsNamespaceM4GoldenTests.swift
ios/**/*.swift

📄 CodeRabbit inference engine (README.md)

ios/**/*.swift: Develop the iOS/iPadOS app using Swift 6 and SwiftUI, targeting iOS/iPadOS 18 or later.
Use VoiceOver and Dynamic Type throughout the iOS/iPadOS app.
Support localization in English, German, Spanish, and Simplified Chinese.

Files:

  • ios/VaultSyncTests/DiagnosticsNamespaceM4GoldenTests.swift

⚙️ CodeRabbit configuration file

ios/**/*.swift: Focus on Swift 6 strict concurrency, Sendable/MainActor correctness, Task cancellation,
retain cycles, memory pressure, SwiftUI observation state, StoreKit/APNs flows, and iOS background execution limits.
Pay special attention to BGAppRefreshTask and BGContinuedProcessingTask behavior, expiration handling,
bounded work, and cleanup when the app is suspended or terminated.

Files:

  • ios/VaultSyncTests/DiagnosticsNamespaceM4GoldenTests.swift
ios/**/*.{swift,plist}

📄 CodeRabbit inference engine (README.md)

ios/**/*.{swift,plist}: Use BGAppRefreshTask and BGContinuedProcessingTask when available for background processing, while allowing iOS to decide whether and when the app runs.
Implement APNs silent push handling for optional Cloud Relay wake-ups.

Files:

  • ios/VaultSyncTests/DiagnosticsNamespaceM4GoldenTests.swift
🧠 Learnings (1)
📚 Learning: 2026-07-12T23:03:04.680Z
Learnt from: psimaker
Repo: psimaker/vaultsync PR: 107
File: ios/VaultSyncTests/DiagnosticsContractTests.swift:39-46
Timestamp: 2026-07-12T23:03:04.680Z
Learning: In iOS Swift tests that use CryptoKit’s `Curve25519.Signing.PrivateKey.signature(for:)` (Ed25519), don’t assert that a generated signature’s bytes exactly match deterministic “golden”/fixture signatures. CryptoKit signatures may be randomized (different but valid for the same key+message). Instead, verify correctness by calling `isValidSignature` (or equivalent) against (1) the golden bytes and (2) the freshly generated signature, and avoid byte-for-byte equality assertions between CryptoKit output and reference vectors.

Applied to files:

  • ios/VaultSyncTests/DiagnosticsNamespaceM4GoldenTests.swift
🪛 ast-grep (0.44.1)
notify/diagnostics_namespace_filesystem_linux.go

[warning] 617-617: Narrowing a non-constant integer to a smaller fixed-width type (int8/int16/int32, uint8/uint16/uint32) can silently overflow or wrap, yielding negative or truncated values that are dangerous in size, length, or index logic. Validate the source value is within the target type's range before converting (e.g. bounds-check, or use a checked helper), and avoid narrowing untrusted or len()/parsed values.
Context: uint32(os.Geteuid())
Note: [CWE-190] Integer Overflow or Wraparound.

(integer-overflow-narrowing-conversion-go)


[warning] 632-632: Narrowing a non-constant integer to a smaller fixed-width type (int8/int16/int32, uint8/uint16/uint32) can silently overflow or wrap, yielding negative or truncated values that are dangerous in size, length, or index logic. Validate the source value is within the target type's range before converting (e.g. bounds-check, or use a checked helper), and avoid narrowing untrusted or len()/parsed values.
Context: uint32(os.Geteuid())
Note: [CWE-190] Integer Overflow or Wraparound.

(integer-overflow-narrowing-conversion-go)


[warning] 659-659: File path is assembled with fmt.Sprintf and passed straight into a file read (os.ReadFile / os.Open / ioutil.ReadFile). Interpolating untrusted segments into a path format string permits '../' traversal. Validate and sanitize each path segment before use (e.g. reject inputs containing '..', resolve with filepath.Clean and enforce a directory-bound check with filepath.Rel, rejecting any result that escapes the allowed base directory) instead of formatting the path with fmt.Sprintf.
Context: os.ReadFile(fmt.Sprintf("/proc/self/fdinfo/%d", file.Fd()))
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal').

(os-readfile-sprintf-path-go)

🪛 zizmor (1.26.1)
.github/workflows/ci.yml

[warning] 96-96: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🔇 Additional comments (33)
notify/diagnostics_namespace_protocol.go (1)

101-658: LGTM!

notify/diagnostics_namespace_protocol_test.go (1)

17-432: LGTM!

ios/VaultSyncTests/Fixtures/diagnostics-namespace-m4.json (1)

1-7: LGTM!

ios/VaultSyncTests/DiagnosticsNamespaceM4GoldenTests.swift (2)

33-82: LGTM!

Also applies to: 157-182


85-118: LGTM!

ios/VaultSync/en.lproj/Localizable.strings (1)

811-812: LGTM!

ios/VaultSync/es.lproj/Localizable.strings (1)

811-812: LGTM!

ios/VaultSync/zh-Hans.lproj/Localizable.strings (1)

811-812: LGTM!

notify/diagnostics_contract_model_test.go (3)

289-289: LGTM!


311-320: 🎯 Functional Correctness

Allow-list extension mirrors the existing pairing pattern — looks correct.

Scoping is symmetric with the pre-existing pairing/pairingProtocolCarrier handling, which is the right shape for adding a new dormant carrier. The exact fixture.Capabilities/fixture.Domains key names ("namespace" / "namespace.*") live in a fixture not included in this review batch, so I can't fully confirm the string match here, but the structure is sound.


348-396: LGTM! Good defense-in-depth: the new TestDiagnosticsNamespaceFoundationCannotMutateSyncthingOrReachNetwork glob-scans every non-test diagnostics_namespace_*.go file for network/Syncthing/Relay carriers, which is exactly the kind of automated guardrail that keeps a "dormant" foundation honestly dormant as it grows.

notify/README.md (1)

130-154: LGTM!

CHANGELOG.md (2)

11-11: LGTM!


22-22: LGTM!

PRIVACY.md (2)

3-3: LGTM!


76-117: LGTM! Solid, honest privacy disclosure — it correctly gets ahead of the feature by disclosing visibility/retention risk before any runtime wiring exists, consistent with the dormancy guarantees enforced in the Go tests.

docs/architecture.md (2)

114-133: LGTM!


144-152: LGTM!

ios/VaultSync/de.lproj/Localizable.strings (1)

810-812: LGTM! Placeholder count, quoting style, and terminology all check out against the English source string.

notify/diagnostics_namespace_filesystem.go (1)

1-197: LGTM!

notify/diagnostics_namespace_filesystem_test.go (1)

1-63: LGTM!

notify/diagnostics_namespace_installer.go (1)

1-63: LGTM!

notify/diagnostics_namespace_installer_linux.go (2)

1-76: LGTM!

Also applies to: 83-274


77-82: 🔒 Security & Privacy

Reopen path is already fenced

openDiagnosticsNamespaceRoot() Lstat-checks the full alias, opens it as an os.Root, and SameFile-checks the alias/root/anchor identities, so the filepath.Join reopen does not bypass the existing confinement checks.

			> Likely an incorrect or invalid review comment.
notify/diagnostics_namespace_installer_unsupported.go (1)

1-19: LGTM!

notify/diagnostics_namespace_store_test.go (1)

1-206: LGTM!

notify/tests/m4-docker/Dockerfile (1)

1-10: LGTM!

notify/diagnostics_namespace_filesystem_linux.go (1)

29-408: LGTM!

notify/diagnostics_namespace_filesystem_unsupported.go (1)

5-39: LGTM!

notify/diagnostics_namespace_store.go (1)

56-333: LGTM!

notify/tests/m4-docker/README.md (1)

1-26: LGTM!

notify/tests/m4-docker/run.sh (1)

1-69: LGTM!

notify/diagnostics_namespace_linux_test.go (1)

16-653: LGTM!

Comment thread .github/workflows/ci.yml
Disable checkout credential persistence in the read-only M4 Docker confinement job.

Keep the proof behavior and all runtime surfaces unchanged.
@psimaker
psimaker merged commit 4525c91 into main Jul 13, 2026
23 of 25 checks passed
@psimaker
psimaker deleted the agent/m4-namespace-isolation branch July 13, 2026 15:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant