Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions docs/architecture/helper-causal-receipts-v0.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Helper Causal Receipts v0.1

Status: Draft
Scope: SourceOS Shell, BearBrowser, TurtleTerm, Office/PDF runtime, preview/rendering helpers
Primary goal: preserve user-legible causal intent across helper-process boundaries.

## Problem

- Modern desktop actions are not single-process events.
- A visible action such as previewing a file, opening a native file picker, rendering a thumbnail, taking a screenshot, cleaning browser cache, or indexing metadata can spawn a hidden helper-process cascade.
- The macOS unified-log sample that motivated this spec shows repeated helper lifecycle patterns: demand spawn, `xpcproxy` materialization, source attachment, running/init transitions, sandbox-denied lookups, clean exits, supervisor kills, and teardown races.
- The useful primitive is not the raw process log. The useful primitive is a root-intent-bound receipt.
- SourceOS must not repeat the opaque pattern where users see helper churn but cannot answer: why did this run, what requested it, what data did it touch, what was denied, and did network/clipboard/account/analytics access occur?

## Design Principles

- Every helper process carries a `root_intent_id`.
- Every helper spawn has a declared purpose.
- Every sensitive capability request is recorded as a policy decision.
- Every denied capability records whether data was accessed. For a sandbox denial, the default is `data_accessed=false` unless an allow event proves otherwise.
- Every helper exit records completion, duration, and receipt completeness.
- Every teardown race is normalized before user presentation.
- Expected denials are evidence of containment, not automatic alerts.
- Unexpected denials are policy-regression candidates.
- Local preview helpers deny network, DNS, pasteboard, account lookup, analytics, camera, microphone, location, credential stores, and arbitrary file reads by default.
- Web thumbnailing is treated as hostile-content rendering, not as static image generation.
- Native file picker helpers must not inherit browser session authority.
- Terminal preview helpers must not inherit shell secrets.

## Event Types

| Event Type | Purpose | Required Fields |
|---|---|---|
| `root_intent.created` | Start a causal graph for a visible or scheduled action | `event_id`, `root_intent_id`, `timestamp`, `surface`, `actor`, `declared_purpose`, `data_scope`, `default_policy`, `receipt_required` |
| `helper.spawn` | Record subprocess/helper launch | `event_id`, `parent_event_id`, `root_intent_id`, `parent_process`, `child_process`, `trigger`, `spawn_reason`, `policy_profile` |
| `capability.request` | Record sensitive service/capability lookup | `event_id`, `root_intent_id`, `requestor`, `capability`, `requested_service`, `decision`, `classification`, `policy_rule`, `data_accessed` |
| `helper.exit` | Record termination and cleanup | `event_id`, `root_intent_id`, `process`, `exit_status`, `duration_ms`, `children_cleaned`, `unexpected_denials`, `network_used`, `receipt_complete` |
| `teardown.normalized` | Normalize noisy cleanup/race messages | `raw_message`, `normalized_class`, `severity`, `meaning`, `receipt_complete`, `policy_impact` |
| `policy.decision` | Record policy evaluation | `policy_profile`, `rule_id`, `capability`, `decision`, `reason`, `override_actor`, `override_expiry` |
| `data.touch` | Record data class touched | `object_type`, `object_hash`, `path_policy`, `access_mode`, `retention`, `derived_artifact` |

## Policy Profiles

### `preview.local_only.v1`

- Applies to local PDF, image, office, and generic file previews.
- Allows selected file snapshot reads, thumbnail cache writes, CPU rendering, mediated GPU rendering, allowlisted system font reads, and IPC to the preview broker.
- Denies network, DNS, pasteboard, analytics, account lookup, contacts, calendar, camera, microphone, location, arbitrary file reads, and unrestricted child processes.

### `preview.web_thumbnail.local_only.v1`

- Applies to HTML thumbnails, web archive previews, local browser export previews, and URL snapshot rendering.
- Risk model: hostile-content rendering.
- Allows parsing and rendering the selected local snapshot plus mediated GPU rendering and local thumbnail output.
- Denies network, DNS, cookies, credentials, local/session storage, extension APIs, service workers, remote fonts, pasteboard, account lookup, analytics, camera, microphone, and location.
- Non-negotiable invariant: web thumbnail helpers never inherit browser session authority.

### `cache_cleanup.local_only.v1`

- Applies to browser/app cache cleanup and local cache size accounting.
- Allows cache metadata read, cache entry delete, cache size compute, and local policy report.
- Denies network, DNS, analytics, account lookup, remote sync, and browser session reads.
- Special rule: if a network-shaped helper is spawned, its receipt must state whether network authority was actually granted or whether only local cache metadata was inspected.

### `file_picker.native_ui.v1`

- Applies to native open/save panels and file picker preview surfaces.
- Allows selected file grants, UI rendering, and preview-broker IPC.
- Denies account lookup, cloud sync triggers, pasteboard access, analytics, browser extension invocation, cookie reads, and browser session reads.
- Special rule: native file picker helpers must not inherit browser session authority.

### `terminal.preview.local_only.v1`

- Applies to TurtleTerm file previews, hyperlink previews, archive listings, and command-output renderers.
- Allows selected file/path preview, local rendering, and local temporary artifacts.
- Denies shell environment reads, shell history reads, SSH key reads, token reads, network fetches, clipboard reads, account lookup, and analytics.
- Special rule: terminal preview helpers must never inherit shell secrets.

## Denial Classification

| Classification | Meaning | Default Severity |
|---|---|---|
| `expected_denial` | Policy intentionally blocked a commonly probed service | notice |
| `unexpected_denial` | Helper requested capability outside declared profile | warning |
| `compatibility_probe` | Framework probed optional service and did not require it | notice |
| `policy_regression` | New build began requesting undeclared capability | error in CI |
| `malicious_probe_candidate` | Request unrelated to purpose and targeting sensitive data | critical |
| `missing_service` | Target service absent or not running | notice |
| `teardown_race` | Request/reply path raced with helper shutdown | trace/notice |

## Teardown Normalization

| Raw Pattern | Normalized Class | Meaning |
|---|---|---|
| `no client port found` | `client_endpoint_missing_after_teardown` | Client disappeared before service reply completed |
| `invalid client reply port -1` | `invalid_reply_endpoint_after_teardown` | Reply endpoint invalid during cleanup |
| `job not found` / `ENOSERVICE` | `service_removed_before_reply` | Service exited before late lookup/reply completed |
| `Operation already in progress` | `duplicate_activation_coalesced` | Duplicate demand while helper already running |
| supervisor `SIGKILL` | `supervisor_worker_lifecycle_kill` | Supervisor ended bounded worker |

## User Inspector Requirements

- Provide a local “Why did this run?” view.
- Group by `root_intent_id`, not raw PID.
- Show visible action, parent surface, helper chain, allowed capabilities, denied capabilities, data touched, network/DNS outcome, exit status, incomplete receipts, and policy regressions.
- Expected denials should be visible on expansion, but not noisy by default.
- Policy regressions and incomplete receipts should be surfaced immediately.

## Acceptance Tests

| Test | Given | Assert |
|---|---|---|
| Root intent propagation | Any helper spawn | `root_intent_id`, `parent_event_id`, `spawn_reason`, and `policy_profile` exist |
| Local preview no-network | Local PDF/image preview | network, DNS, analytics, and account lookup denied |
| Web thumbnail isolation | HTML/web thumbnail render | cookies, storage, extensions, network, and pasteboard denied |
| Cache cleanup transparency | Cache cleanup spawns network-shaped helper | receipt explains reason and egress decision |
| Native file picker isolation | Browser invokes native file panel | no browser session or extension authority inherited |
| Terminal preview isolation | TurtleTerm preview | shell secrets and environment denied |
| Receipt completeness | Completed action | all helper spawns have exit or active-state events |
| Denial classification | Denied capability request | denial classified and `data_accessed` recorded |
| Policy regression CI | New undeclared capability | CI fails unless policy is updated |
| Inspector rendering | Completed DAG | user-readable summary exists |

## Repo Integration

| Repo | Role |
|---|---|
| `SourceOS-Linux/sourceos-shell` | Runtime receipt store, helper wrapper, parser/correlator, local inspector |
| `SourceOS-Linux/BearBrowser` | Browser file picker, cache cleanup, preview and thumbnail helper enforcement |
| `SourceOS-Linux/TurtleTerm` | Terminal preview and command helper secret isolation |
| `SocioProphet/ontogenesis` | Ontology classes, properties, SHACL constraints |
| `SocioProphet/prophet-platform` | Evidence-envelope mapping, evidence-console view, CI trust gates |

## Non-Goals

- Do not alert for every expected denial.
- Do not ban short-lived helpers.
- Do not ban multiprocess rendering.
- Do not assume every denial is malicious.
- Do require causality, classification, policy, and receipts.

## Security Invariants

- Preview helpers are local-only by default.
- Web thumbnails do not inherit browser session state.
- Cache cleanup does not receive network authority by default.
- Native file picker helpers do not inherit browser extension authority.
- Terminal preview helpers do not inherit shell secrets.
- Every sensitive capability decision is recorded.
- Every helper exit is recorded.
- Incomplete receipts degrade trust state.
167 changes: 167 additions & 0 deletions policies/helper-receipts/apple_service_family_taxonomy.v0.1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
version: 0.1
purpose: >
Conservative mapping from Apple/macOS service-family strings to SourceOS helper receipt phases and policy profiles.
This supports imported-log analysis without claiming private subsystem intent.
default_phase: unknown_or_general_launchd_churn
default_policy_profile: unknown
families:
- match: com.apple.mdworker
phase: spotlight_metadata_indexing
policy_profile: indexer.metadata_local.v1
role: metadata_index_worker
- match: mdworker_shared
phase: spotlight_metadata_indexing
policy_profile: indexer.metadata_local.v1
role: metadata_index_worker
- match: CacheDelete
phase: cache_cleanup
policy_profile: cache_cleanup.local_only.v1
role: cache_cleanup
- match: CacheExtension
phase: cache_cleanup
policy_profile: cache_cleanup.local_only.v1
role: cache_cleanup
- match: WebKit
phase: web_thumbnail_or_webkit_helper
policy_profile: preview.web_thumbnail.local_only.v1
role: web_runtime_helper
- match: WebThumbnail
phase: web_thumbnail_or_webkit_helper
policy_profile: preview.web_thumbnail.local_only.v1
role: web_thumbnail_helper
- match: QuickLook
phase: quicklook_preview_rendering
policy_profile: preview.local_only.v1
role: preview_ui_or_thumbnail
- match: CGPDFService
phase: quicklook_preview_rendering
policy_profile: preview.local_only.v1
role: pdf_rendering_helper
- match: ImageIOXPCService
phase: quicklook_preview_rendering
policy_profile: preview.local_only.v1
role: image_decode_helper
- match: ThumbnailExtension
phase: quicklook_preview_rendering
policy_profile: preview.local_only.v1
role: thumbnail_helper
- match: screencapture
phase: screenshot_capture
policy_profile: screenshot.capture_receipt.v1
role: screenshot_capture_ui
- match: openAndSavePanelService
phase: native_file_picker
policy_profile: file_picker.native_ui.v1
role: native_file_picker
- match: AXVisualSupportAgent
phase: accessibility_ui_support
policy_profile: accessibility.ui_support.v1
role: accessibility_visual_support
- match: com.apple.accessibility
phase: accessibility_ui_support
policy_profile: accessibility.ui_support.v1
role: accessibility_service
- match: com.apple.filesystems.netfs
phase: filesystem_netfs_plugin
policy_profile: filesystem.netfs_plugin.v1
role: network_filesystem_plugin
- match: PlugInLibraryService
phase: filesystem_netfs_plugin
policy_profile: filesystem.netfs_plugin.v1
role: plugin_library_service
- match: iconservices
phase: iconservices_rendering
policy_profile: iconservices.rendering_local.v1
role: icon_rendering_service
- match: AudioComponentRegistrar
phase: audio_component_discovery
policy_profile: audio.component_scan_local.v1
role: audio_component_registry
- match: CarbonComponentScanner
phase: audio_component_discovery
policy_profile: audio.component_scan_local.v1
role: audio_component_scanner
- match: trustd
phase: trust_and_certificate_services
policy_profile: trust.security_local.v1
role: certificate_trust_service
- match: secinitd
phase: trust_and_certificate_services
policy_profile: trust.security_local.v1
role: security_initialization
- match: amfid
phase: security_integrity_sidecar
policy_profile: security.scan_local.v1
role: code_integrity
- match: XProtect
phase: security_integrity_sidecar
policy_profile: security.scan_local.v1
role: malware_protection
- match: sysextd
phase: system_extension_management
policy_profile: system_extension.management_local.v1
role: system_extension_daemon
- match: CloudTelemetry
phase: telemetry_sidecar
policy_profile: telemetry.local_metric.v1
role: telemetry_service
- match: ecosystemanalytics
phase: telemetry_sidecar
policy_profile: telemetry.local_metric.v1
role: ecosystem_analytics
- match: ecosystemd
phase: ecosystem_services
policy_profile: ecosystem.service_local.v1
role: ecosystem_service
- match: biomesyncd
phase: biome_sync_services
policy_profile: biome.sync_local.v1
role: biome_sync_service
- match: geod
phase: location_services
policy_profile: location.service_deny_by_default.v1
role: location_service
- match: appleaccountd
phase: account_identity_services
policy_profile: account.identity_deny_by_default.v1
role: account_identity_service
- match: iCloudNotificationAgent
phase: cloud_notification_services
policy_profile: cloud_notification_deny_by_default.v1
role: icloud_notification_agent
- match: maild
phase: mail_services
policy_profile: mail.service_local.v1
role: mail_service
- match: WorkflowKit
phase: workflow_background_shortcuts
policy_profile: workflow.background_shortcut.v1
role: background_shortcut_runner
- match: BackgroundShortcutRunner
phase: workflow_background_shortcuts
policy_profile: workflow.background_shortcut.v1
role: background_shortcut_runner
- match: naturallanguaged
phase: natural_language_processing
policy_profile: nlp.local_processing.v1
role: natural_language_daemon
- match: cfprefsd
phase: preferences_services
policy_profile: preferences.local_service.v1
role: preferences_daemon
- match: prngseedd
phase: secure_random_seed_services
policy_profile: security.random_seed_local.v1
role: random_seed_service
- match: seputil
phase: secure_enclave_utility
policy_profile: security.secure_enclave_local.v1
role: secure_enclave_utility
- match: MTLCompilerService
phase: metal_shader_compilation
policy_profile: gpu.shader_compile_local.v1
role: metal_compiler_service
- match: swcd
phase: shared_web_credentials
policy_profile: web_credentials_deny_by_default.v1
role: shared_web_credentials_daemon
Loading