Skip to content

test(security): add diagnostics contract model foundation#107

Merged
psimaker merged 3 commits into
mainfrom
agent/m1-diagnostics-contract-models-clean
Jul 12, 2026
Merged

test(security): add diagnostics contract model foundation#107
psimaker merged 3 commits into
mainfrom
agent/m1-diagnostics-contract-models-clean

Conversation

@psimaker

@psimaker psimaker commented Jul 12, 2026

Copy link
Copy Markdown
Owner

What & why

Adds the M1 tests-only contract and model foundation required before any Decisions 022-024 runtime carrier. One canonical fixture drives independent Go and Swift verification of the deterministic CBOR subset, exact field registries, signature domains, digest chains, RFC 8032 vectors, the normative bootstrap HMAC, derivations, state-machine properties, privacy snapshots, and v1 wire regressions.

This PR does not implement or authorize a listener, endpoint, credential, pairing action, namespace, probe, Syncthing mutation, upload, controlled download, roundtrip, Cloud Relay contract data, helper release, or production access.

Component(s)

  • go (bridge / Syncthing)
  • ios (test target and fixture only)
  • notify (test files only)
  • docs / CI

Test-only boundary

  • Swift additions are only under ios/VaultSyncTests/; XcodeGen places both model files and the fixture only in VaultSyncTests.xctest.
  • Go additions are only notify/*_test.go; go list leaves the runtime GoFiles set unchanged.
  • A reproducible Notify build from this branch is byte-identical to origin/main: 71a28d60873b190248acf68430d0190e7204d03a496553a334cd18d983a4c012.
  • App and Notify product binaries contain no M1 capability, signature-domain, or model strings.
  • Runtime app, bridge, helper, Relay, project configuration, localization, and release files are unchanged.

Contract and model coverage

  • Exact Decision 022 bootstrap/lifecycle, Decision 023 namespace, and Decision 024 roundtrip field registries.
  • All 41 signature domains and all specified digest-chain relationships.
  • Two RFC 8032 vectors, the normative Decision 022 bootstrap-HMAC vector, key/binding/SPKI/filename derivations, and cross-language canonical bytes.
  • Duplicate/unknown/reordered keys; non-shortest integers and lengths; indefinite forms; wrong types and lengths; tags, floats, deep nesting, truncation, trailing input, oversized input, deterministic arbitrary bytes, and a real Go fuzz target.
  • Causal state properties: roundtrip requires upload then post-authorization fresh-apply download; terminal/restarted operations never upgrade; tuples remain isolated; cleanup never changes evidence; weak diagnostics and tombstones never create evidence.
  • Privacy sentinels and persistence snapshots, Trigger v1 exact request regression, and Cloud Relay v1 status-request regression.

Testing

  • cd go && make patch && go test -tags noassets ./bridge -count=1 — passed
  • gofmt -l go/bridge — empty
  • cd notify && go test ./... -count=1 — passed
  • cd notify && go vet ./... — passed
  • cd notify && go test -race ./... -count=1 — passed
  • gofmt -l notify — empty
  • cd notify && go test -run '^$' -fuzz=FuzzDiagnosticsContractCanonicalCBOR -fuzztime=10s — passed, 666,047 executions
  • ios/scripts/design-token-lint.sh — passed
  • ios/scripts/strings-key-parity.sh — passed, 758 keys
  • notify/scripts/tests/install-dry-run-test.sh — passed without privileged or mutating commands
  • cd ios && xcodegen generate — passed
  • cd ios && xcodebuild test -project VaultSync.xcodeproj -scheme VaultSync -destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=latest' -derivedDataPath /tmp/vaultsync-m1-derived CODE_SIGNING_ALLOWED=NO -quiet — passed
  • GitHub Actions PR checks — passed on exact review-fix head 3aa520656951085e7fee939663ffba55e9720238
  • Independent human review — not claimed

No signing, archive, production service, StoreKit, APNs, Trigger, status, probe, Relay, deployment, or release operation was performed.

Impact, compatibility, privacy, and rollback

  • Existing-user impact: none; product binaries and behavior are unchanged.
  • Wire compatibility: Trigger v1, Cloud Relay v1, APNs, StoreKit, app/bridge/helper contracts, and current passive diagnostics are unchanged.
  • Migration: none; no runtime schema, state, credential, namespace, path, installer, or persisted format is added.
  • Privacy: fixtures use published RFC vectors and synthetic sentinel data only; no user data, real identifiers, paths, credentials, or production bodies are introduced.
  • Rollback: revert the two test commits. There is no runtime, data, credential, namespace, helper, or deployment rollback.
  • Compatibility matrix: existing/new app-helper runtime behavior is unchanged because M1 adds no runtime capability; unavailable/unsupported semantics are not yet published.
  • Namespace/cleanup/backup/tombstones: modeled only; no directory, artifact, cleanup, backup mutation, version, or tombstone is created.
  • Credentials/pairing/rotation/recovery: modeled only; no key or pairing state is created.

Release gate

VaultSync 2.0 remains NO-GO. The strongest implemented proof remains a fresh successful local file ItemFinished apply after cursor, RFC3339-nanosecond time, and stable engine-generation baselines. Upload is not implemented or confirmed. Controlled download is not implemented or confirmed. Roundtrip is not implemented or confirmed. Authenticated correlation is not implemented. Helper-first rollout and rollback remain unproven and mandatory before later runtime work.

Owner approval is required before merge.

psimaker added 2 commits July 13, 2026 00:08
Model the approved Decision 022-024 CBOR registries, signature domains, digest chains, derivations, evidence state machine, and privacy boundaries against one canonical cross-language fixture.

Keep all Go code in _test.go and pin Trigger v1 plus the absence of helper, bridge, and app runtime carriers. The helper binary remains byte-identical to origin/main and no endpoint, credential, namespace, probe, wire, or production behavior is added.
Reproduce the shared CBOR, HMAC, RFC 8032, domain, digest, and derivation fixtures in VaultSyncTests and model parser, state, privacy, and v1 invariants independently in Swift.

Keep the fixture resource and every new symbol confined to the test bundle; the app binary contains no M1 capability, domain, or model strings. No app runtime, localization, persistence, wire, or production-call behavior changes.
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a cross-language diagnostics-contract test foundation with a shared JSON fixture, strict deterministic CBOR handling, cryptographic golden vectors, capability-query validation, evidence-state modeling, privacy/relay assertions, and fuzz/property-based rejection tests.

Changes

Diagnostics contract validation

Layer / File(s) Summary
Fixture and contract model
ios/VaultSyncTests/DiagnosticsContractTestSupport.swift, ios/VaultSyncTests/Fixtures/diagnostics-contract-v1.json, notify/diagnostics_contract_vectors_test.go
Defines the diagnostics fixture schema, loaders, catalog expectations, limits, registries, domains, digest chains, and validation helpers.
Deterministic CBOR implementation
ios/VaultSyncTests/DiagnosticsContractTestSupport.swift, notify/diagnostics_contract_cbor_test.go
Implements strict canonical CBOR encoding and decoding with size, depth, type, UTF-8, ordering, duplicate-key, and round-trip checks.
Cryptographic and query golden vectors
ios/VaultSyncTests/DiagnosticsContractTests.swift, notify/diagnostics_contract_vectors_test.go
Validates HMAC, Ed25519, SHA-256, key IDs, base32 derivations, digest chains, capability-query bodies, signatures, and fixture outputs.
Evidence, privacy, and relay behavior
ios/VaultSyncTests/DiagnosticsContractTests.swift, notify/diagnostics_contract_model_test.go
Tests causal evidence transitions, terminal states, tuple isolation, cleanup counts, privacy snapshots, relay request fidelity, and runtime capability-string absence.
Negative and property-based validation
ios/VaultSyncTests/DiagnosticsContractTests.swift, notify/diagnostics_contract_parser_test.go
Checks rejection of non-canonical or forbidden CBOR, schema mutations, truncation, trailing input, arbitrary bytes, and fuzzed candidates.

Estimated code review effort: 4 (Complex) | ~60 minutes

Poem

Canonical bytes march in line,
Golden hashes brightly shine.
States advance, then softly cease,
Relay wires remain at peace.
Fuzzers guard the contract gate.

🚥 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 Only test-only code and synthetic fixture data were added; no runtime logging or network path now carries real note contents, vault paths, keys, or receipt data.
Bounded Ios Background Work ✅ Passed No iOS background-execution code was added; the Swift changes are test-only CBOR/crypto fixtures with no background tasks, expiration callbacks, or cleanup paths.
Bridge Contract Compatibility ✅ Passed PASS: Full diff is test-only (notify/_test.go, ios/VaultSyncTests/); no go/bridge or SyncBridgeService changes, so the gomobile/JSON/empty-string contract is untouched.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the tests-only diagnostics contract foundation added in this PR.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/m1-diagnostics-contract-models-clean

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 12, 2026 22:38

@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: 2

🤖 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 `@ios/VaultSyncTests/DiagnosticsContractTests.swift`:
- Around line 39-43: Update the signature assertions in the diagnostics contract
tests, including the checks near the generatedSignature and the corresponding
later test block, to compare each generated signature’s raw bytes directly with
the vector’s golden signature bytes. Retain the existing validity checks if
needed, but ensure byte-for-byte equality is explicitly asserted.

In `@notify/diagnostics_contract_model_test.go`:
- Around line 238-254: Update diagnosticsTestLogSnapshot and
diagnosticsTestPersistenceSnapshot to pass vector.Sentinels through a
representative redaction/encoding path instead of discarding them and returning
fixed literals. Ensure TestDiagnosticsPrivacyAndPersistenceSnapshots verifies
the transformed log and persistence outputs contain no sentinel or other
sensitive diagnostic content, including vault paths, private filenames,
credentials, tokens, keys, or bookmark data; if no encoder exists, explicitly
rename or document these helpers as golden placeholders rather than privacy
guards.
🪄 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: 10e30e14-50c2-4aef-8c4b-87af16bd7e8b

📥 Commits

Reviewing files that changed from the base of the PR and between 26f1c88 and 1005956.

📒 Files selected for processing (7)
  • ios/VaultSyncTests/DiagnosticsContractTestSupport.swift
  • ios/VaultSyncTests/DiagnosticsContractTests.swift
  • ios/VaultSyncTests/Fixtures/diagnostics-contract-v1.json
  • notify/diagnostics_contract_cbor_test.go
  • notify/diagnostics_contract_model_test.go
  • notify/diagnostics_contract_parser_test.go
  • notify/diagnostics_contract_vectors_test.go
📜 Review details
🧰 Additional context used
📓 Path-based instructions (8)
**

⚙️ 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:

  • ios/VaultSyncTests/Fixtures/diagnostics-contract-v1.json
  • notify/diagnostics_contract_cbor_test.go
  • ios/VaultSyncTests/DiagnosticsContractTestSupport.swift
  • notify/diagnostics_contract_model_test.go
  • notify/diagnostics_contract_parser_test.go
  • ios/VaultSyncTests/DiagnosticsContractTests.swift
  • notify/diagnostics_contract_vectors_test.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:

  • ios/VaultSyncTests/Fixtures/diagnostics-contract-v1.json
  • notify/diagnostics_contract_cbor_test.go
  • ios/VaultSyncTests/DiagnosticsContractTestSupport.swift
  • notify/diagnostics_contract_model_test.go
  • notify/diagnostics_contract_parser_test.go
  • ios/VaultSyncTests/DiagnosticsContractTests.swift
  • notify/diagnostics_contract_vectors_test.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_contract_cbor_test.go
  • notify/diagnostics_contract_model_test.go
  • notify/diagnostics_contract_parser_test.go
  • notify/diagnostics_contract_vectors_test.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_contract_cbor_test.go
  • ios/VaultSyncTests/DiagnosticsContractTestSupport.swift
  • notify/diagnostics_contract_model_test.go
  • notify/diagnostics_contract_parser_test.go
  • ios/VaultSyncTests/DiagnosticsContractTests.swift
  • notify/diagnostics_contract_vectors_test.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_contract_cbor_test.go
  • notify/diagnostics_contract_model_test.go
  • notify/diagnostics_contract_parser_test.go
  • notify/diagnostics_contract_vectors_test.go
**/*.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/DiagnosticsContractTestSupport.swift
  • ios/VaultSyncTests/DiagnosticsContractTests.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/DiagnosticsContractTestSupport.swift
  • ios/VaultSyncTests/DiagnosticsContractTests.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/DiagnosticsContractTestSupport.swift
  • ios/VaultSyncTests/DiagnosticsContractTests.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/DiagnosticsContractTestSupport.swift
  • ios/VaultSyncTests/DiagnosticsContractTests.swift
🪛 ast-grep (0.44.1)
notify/diagnostics_contract_cbor_test.go

[warning] 140-140: 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: uint16(value)
Note: [CWE-190] Integer Overflow or Wraparound.

(integer-overflow-narrowing-conversion-go)


[warning] 142-142: 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(value)
Note: [CWE-190] Integer Overflow or Wraparound.

(integer-overflow-narrowing-conversion-go)

notify/diagnostics_contract_vectors_test.go

[warning] 365-365: 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(len(vector.FolderID))
Note: [CWE-190] Integer Overflow or Wraparound.

(integer-overflow-narrowing-conversion-go)

🪛 SwiftLint (0.65.0)
ios/VaultSyncTests/DiagnosticsContractTestSupport.swift

[Warning] 375-375: Prefer failable String(bytes:encoding:) initializer when converting Data to String

(optional_data_string_conversion)

🔇 Additional comments (8)
ios/VaultSyncTests/DiagnosticsContractTestSupport.swift (1)

1-467: LGTM!

ios/VaultSyncTests/Fixtures/diagnostics-contract-v1.json (1)

1-297: LGTM!

notify/diagnostics_contract_vectors_test.go (1)

1-501: LGTM!

notify/diagnostics_contract_cbor_test.go (1)

1-333: LGTM!

ios/VaultSyncTests/DiagnosticsContractTests.swift (1)

1-38: LGTM!

Also applies to: 44-124, 128-390

notify/diagnostics_contract_parser_test.go (1)

1-204: LGTM!

notify/diagnostics_contract_model_test.go (2)

3-52: LGTM!

Also applies to: 54-130, 132-236, 256-281, 283-322, 338-352, 354-380


1-1: 🎯 Functional Correctness

notify/diagnostics_contract_model_test.go matches the notify/ package.

			> Likely an incorrect or invalid review comment.

Comment thread ios/VaultSyncTests/DiagnosticsContractTests.swift
Comment thread notify/diagnostics_contract_model_test.go
Document the CryptoKit provider-output boundary while keeping byte-exact RFC and cross-language signatures verified against canonical inputs.

Route every synthetic privacy sentinel through a test-only allowlist redaction before log and persistence snapshot encoding. No runtime logger, persistence carrier, wire behavior, credential, namespace, or production path changes.
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