Skip to content

Commit f89a6c8

Browse files
committed
Follow-up replay
1 parent 86a21b0 commit f89a6c8

7 files changed

Lines changed: 910 additions & 0 deletions
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# Helper Causal Receipts v0.1
2+
3+
Status: Draft
4+
Scope: SourceOS Shell, BearBrowser, TurtleTerm, Office/PDF runtime, preview/rendering helpers
5+
Primary goal: preserve user-legible causal intent across helper-process boundaries.
6+
7+
## Problem
8+
9+
- Modern desktop actions are not single-process events.
10+
- 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.
11+
- 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.
12+
- The useful primitive is not the raw process log. The useful primitive is a root-intent-bound receipt.
13+
- 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?
14+
15+
## Design Principles
16+
17+
- Every helper process carries a `root_intent_id`.
18+
- Every helper spawn has a declared purpose.
19+
- Every sensitive capability request is recorded as a policy decision.
20+
- Every denied capability records whether data was accessed. For a sandbox denial, the default is `data_accessed=false` unless an allow event proves otherwise.
21+
- Every helper exit records completion, duration, and receipt completeness.
22+
- Every teardown race is normalized before user presentation.
23+
- Expected denials are evidence of containment, not automatic alerts.
24+
- Unexpected denials are policy-regression candidates.
25+
- Local preview helpers deny network, DNS, pasteboard, account lookup, analytics, camera, microphone, location, credential stores, and arbitrary file reads by default.
26+
- Web thumbnailing is treated as hostile-content rendering, not as static image generation.
27+
- Native file picker helpers must not inherit browser session authority.
28+
- Terminal preview helpers must not inherit shell secrets.
29+
30+
## Event Types
31+
32+
| Event Type | Purpose | Required Fields |
33+
|---|---|---|
34+
| `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` |
35+
| `helper.spawn` | Record subprocess/helper launch | `event_id`, `parent_event_id`, `root_intent_id`, `parent_process`, `child_process`, `trigger`, `spawn_reason`, `policy_profile` |
36+
| `capability.request` | Record sensitive service/capability lookup | `event_id`, `root_intent_id`, `requestor`, `capability`, `requested_service`, `decision`, `classification`, `policy_rule`, `data_accessed` |
37+
| `helper.exit` | Record termination and cleanup | `event_id`, `root_intent_id`, `process`, `exit_status`, `duration_ms`, `children_cleaned`, `unexpected_denials`, `network_used`, `receipt_complete` |
38+
| `teardown.normalized` | Normalize noisy cleanup/race messages | `raw_message`, `normalized_class`, `severity`, `meaning`, `receipt_complete`, `policy_impact` |
39+
| `policy.decision` | Record policy evaluation | `policy_profile`, `rule_id`, `capability`, `decision`, `reason`, `override_actor`, `override_expiry` |
40+
| `data.touch` | Record data class touched | `object_type`, `object_hash`, `path_policy`, `access_mode`, `retention`, `derived_artifact` |
41+
42+
## Policy Profiles
43+
44+
### `preview.local_only.v1`
45+
46+
- Applies to local PDF, image, office, and generic file previews.
47+
- Allows selected file snapshot reads, thumbnail cache writes, CPU rendering, mediated GPU rendering, allowlisted system font reads, and IPC to the preview broker.
48+
- Denies network, DNS, pasteboard, analytics, account lookup, contacts, calendar, camera, microphone, location, arbitrary file reads, and unrestricted child processes.
49+
50+
### `preview.web_thumbnail.local_only.v1`
51+
52+
- Applies to HTML thumbnails, web archive previews, local browser export previews, and URL snapshot rendering.
53+
- Risk model: hostile-content rendering.
54+
- Allows parsing and rendering the selected local snapshot plus mediated GPU rendering and local thumbnail output.
55+
- Denies network, DNS, cookies, credentials, local/session storage, extension APIs, service workers, remote fonts, pasteboard, account lookup, analytics, camera, microphone, and location.
56+
- Non-negotiable invariant: web thumbnail helpers never inherit browser session authority.
57+
58+
### `cache_cleanup.local_only.v1`
59+
60+
- Applies to browser/app cache cleanup and local cache size accounting.
61+
- Allows cache metadata read, cache entry delete, cache size compute, and local policy report.
62+
- Denies network, DNS, analytics, account lookup, remote sync, and browser session reads.
63+
- 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.
64+
65+
### `file_picker.native_ui.v1`
66+
67+
- Applies to native open/save panels and file picker preview surfaces.
68+
- Allows selected file grants, UI rendering, and preview-broker IPC.
69+
- Denies account lookup, cloud sync triggers, pasteboard access, analytics, browser extension invocation, cookie reads, and browser session reads.
70+
- Special rule: native file picker helpers must not inherit browser session authority.
71+
72+
### `terminal.preview.local_only.v1`
73+
74+
- Applies to TurtleTerm file previews, hyperlink previews, archive listings, and command-output renderers.
75+
- Allows selected file/path preview, local rendering, and local temporary artifacts.
76+
- Denies shell environment reads, shell history reads, SSH key reads, token reads, network fetches, clipboard reads, account lookup, and analytics.
77+
- Special rule: terminal preview helpers must never inherit shell secrets.
78+
79+
## Denial Classification
80+
81+
| Classification | Meaning | Default Severity |
82+
|---|---|---|
83+
| `expected_denial` | Policy intentionally blocked a commonly probed service | notice |
84+
| `unexpected_denial` | Helper requested capability outside declared profile | warning |
85+
| `compatibility_probe` | Framework probed optional service and did not require it | notice |
86+
| `policy_regression` | New build began requesting undeclared capability | error in CI |
87+
| `malicious_probe_candidate` | Request unrelated to purpose and targeting sensitive data | critical |
88+
| `missing_service` | Target service absent or not running | notice |
89+
| `teardown_race` | Request/reply path raced with helper shutdown | trace/notice |
90+
91+
## Teardown Normalization
92+
93+
| Raw Pattern | Normalized Class | Meaning |
94+
|---|---|---|
95+
| `no client port found` | `client_endpoint_missing_after_teardown` | Client disappeared before service reply completed |
96+
| `invalid client reply port -1` | `invalid_reply_endpoint_after_teardown` | Reply endpoint invalid during cleanup |
97+
| `job not found` / `ENOSERVICE` | `service_removed_before_reply` | Service exited before late lookup/reply completed |
98+
| `Operation already in progress` | `duplicate_activation_coalesced` | Duplicate demand while helper already running |
99+
| supervisor `SIGKILL` | `supervisor_worker_lifecycle_kill` | Supervisor ended bounded worker |
100+
101+
## User Inspector Requirements
102+
103+
- Provide a local “Why did this run?” view.
104+
- Group by `root_intent_id`, not raw PID.
105+
- Show visible action, parent surface, helper chain, allowed capabilities, denied capabilities, data touched, network/DNS outcome, exit status, incomplete receipts, and policy regressions.
106+
- Expected denials should be visible on expansion, but not noisy by default.
107+
- Policy regressions and incomplete receipts should be surfaced immediately.
108+
109+
## Acceptance Tests
110+
111+
| Test | Given | Assert |
112+
|---|---|---|
113+
| Root intent propagation | Any helper spawn | `root_intent_id`, `parent_event_id`, `spawn_reason`, and `policy_profile` exist |
114+
| Local preview no-network | Local PDF/image preview | network, DNS, analytics, and account lookup denied |
115+
| Web thumbnail isolation | HTML/web thumbnail render | cookies, storage, extensions, network, and pasteboard denied |
116+
| Cache cleanup transparency | Cache cleanup spawns network-shaped helper | receipt explains reason and egress decision |
117+
| Native file picker isolation | Browser invokes native file panel | no browser session or extension authority inherited |
118+
| Terminal preview isolation | TurtleTerm preview | shell secrets and environment denied |
119+
| Receipt completeness | Completed action | all helper spawns have exit or active-state events |
120+
| Denial classification | Denied capability request | denial classified and `data_accessed` recorded |
121+
| Policy regression CI | New undeclared capability | CI fails unless policy is updated |
122+
| Inspector rendering | Completed DAG | user-readable summary exists |
123+
124+
## Repo Integration
125+
126+
| Repo | Role |
127+
|---|---|
128+
| `SourceOS-Linux/sourceos-shell` | Runtime receipt store, helper wrapper, parser/correlator, local inspector |
129+
| `SourceOS-Linux/BearBrowser` | Browser file picker, cache cleanup, preview and thumbnail helper enforcement |
130+
| `SourceOS-Linux/TurtleTerm` | Terminal preview and command helper secret isolation |
131+
| `SocioProphet/ontogenesis` | Ontology classes, properties, SHACL constraints |
132+
| `SocioProphet/prophet-platform` | Evidence-envelope mapping, evidence-console view, CI trust gates |
133+
134+
## Non-Goals
135+
136+
- Do not alert for every expected denial.
137+
- Do not ban short-lived helpers.
138+
- Do not ban multiprocess rendering.
139+
- Do not assume every denial is malicious.
140+
- Do require causality, classification, policy, and receipts.
141+
142+
## Security Invariants
143+
144+
- Preview helpers are local-only by default.
145+
- Web thumbnails do not inherit browser session state.
146+
- Cache cleanup does not receive network authority by default.
147+
- Native file picker helpers do not inherit browser extension authority.
148+
- Terminal preview helpers do not inherit shell secrets.
149+
- Every sensitive capability decision is recorded.
150+
- Every helper exit is recorded.
151+
- Incomplete receipts degrade trust state.
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
version: 0.1
2+
purpose: >
3+
Conservative mapping from Apple/macOS service-family strings to SourceOS helper receipt phases and policy profiles.
4+
This supports imported-log analysis without claiming private subsystem intent.
5+
default_phase: unknown_or_general_launchd_churn
6+
default_policy_profile: unknown
7+
families:
8+
- match: com.apple.mdworker
9+
phase: spotlight_metadata_indexing
10+
policy_profile: indexer.metadata_local.v1
11+
role: metadata_index_worker
12+
- match: mdworker_shared
13+
phase: spotlight_metadata_indexing
14+
policy_profile: indexer.metadata_local.v1
15+
role: metadata_index_worker
16+
- match: CacheDelete
17+
phase: cache_cleanup
18+
policy_profile: cache_cleanup.local_only.v1
19+
role: cache_cleanup
20+
- match: CacheExtension
21+
phase: cache_cleanup
22+
policy_profile: cache_cleanup.local_only.v1
23+
role: cache_cleanup
24+
- match: WebKit
25+
phase: web_thumbnail_or_webkit_helper
26+
policy_profile: preview.web_thumbnail.local_only.v1
27+
role: web_runtime_helper
28+
- match: WebThumbnail
29+
phase: web_thumbnail_or_webkit_helper
30+
policy_profile: preview.web_thumbnail.local_only.v1
31+
role: web_thumbnail_helper
32+
- match: QuickLook
33+
phase: quicklook_preview_rendering
34+
policy_profile: preview.local_only.v1
35+
role: preview_ui_or_thumbnail
36+
- match: CGPDFService
37+
phase: quicklook_preview_rendering
38+
policy_profile: preview.local_only.v1
39+
role: pdf_rendering_helper
40+
- match: ImageIOXPCService
41+
phase: quicklook_preview_rendering
42+
policy_profile: preview.local_only.v1
43+
role: image_decode_helper
44+
- match: ThumbnailExtension
45+
phase: quicklook_preview_rendering
46+
policy_profile: preview.local_only.v1
47+
role: thumbnail_helper
48+
- match: screencapture
49+
phase: screenshot_capture
50+
policy_profile: screenshot.capture_receipt.v1
51+
role: screenshot_capture_ui
52+
- match: openAndSavePanelService
53+
phase: native_file_picker
54+
policy_profile: file_picker.native_ui.v1
55+
role: native_file_picker
56+
- match: AXVisualSupportAgent
57+
phase: accessibility_ui_support
58+
policy_profile: accessibility.ui_support.v1
59+
role: accessibility_visual_support
60+
- match: com.apple.accessibility
61+
phase: accessibility_ui_support
62+
policy_profile: accessibility.ui_support.v1
63+
role: accessibility_service
64+
- match: com.apple.filesystems.netfs
65+
phase: filesystem_netfs_plugin
66+
policy_profile: filesystem.netfs_plugin.v1
67+
role: network_filesystem_plugin
68+
- match: PlugInLibraryService
69+
phase: filesystem_netfs_plugin
70+
policy_profile: filesystem.netfs_plugin.v1
71+
role: plugin_library_service
72+
- match: iconservices
73+
phase: iconservices_rendering
74+
policy_profile: iconservices.rendering_local.v1
75+
role: icon_rendering_service
76+
- match: AudioComponentRegistrar
77+
phase: audio_component_discovery
78+
policy_profile: audio.component_scan_local.v1
79+
role: audio_component_registry
80+
- match: CarbonComponentScanner
81+
phase: audio_component_discovery
82+
policy_profile: audio.component_scan_local.v1
83+
role: audio_component_scanner
84+
- match: trustd
85+
phase: trust_and_certificate_services
86+
policy_profile: trust.security_local.v1
87+
role: certificate_trust_service
88+
- match: secinitd
89+
phase: trust_and_certificate_services
90+
policy_profile: trust.security_local.v1
91+
role: security_initialization
92+
- match: amfid
93+
phase: security_integrity_sidecar
94+
policy_profile: security.scan_local.v1
95+
role: code_integrity
96+
- match: XProtect
97+
phase: security_integrity_sidecar
98+
policy_profile: security.scan_local.v1
99+
role: malware_protection
100+
- match: sysextd
101+
phase: system_extension_management
102+
policy_profile: system_extension.management_local.v1
103+
role: system_extension_daemon
104+
- match: CloudTelemetry
105+
phase: telemetry_sidecar
106+
policy_profile: telemetry.local_metric.v1
107+
role: telemetry_service
108+
- match: ecosystemanalytics
109+
phase: telemetry_sidecar
110+
policy_profile: telemetry.local_metric.v1
111+
role: ecosystem_analytics
112+
- match: ecosystemd
113+
phase: ecosystem_services
114+
policy_profile: ecosystem.service_local.v1
115+
role: ecosystem_service
116+
- match: biomesyncd
117+
phase: biome_sync_services
118+
policy_profile: biome.sync_local.v1
119+
role: biome_sync_service
120+
- match: geod
121+
phase: location_services
122+
policy_profile: location.service_deny_by_default.v1
123+
role: location_service
124+
- match: appleaccountd
125+
phase: account_identity_services
126+
policy_profile: account.identity_deny_by_default.v1
127+
role: account_identity_service
128+
- match: iCloudNotificationAgent
129+
phase: cloud_notification_services
130+
policy_profile: cloud_notification_deny_by_default.v1
131+
role: icloud_notification_agent
132+
- match: maild
133+
phase: mail_services
134+
policy_profile: mail.service_local.v1
135+
role: mail_service
136+
- match: WorkflowKit
137+
phase: workflow_background_shortcuts
138+
policy_profile: workflow.background_shortcut.v1
139+
role: background_shortcut_runner
140+
- match: BackgroundShortcutRunner
141+
phase: workflow_background_shortcuts
142+
policy_profile: workflow.background_shortcut.v1
143+
role: background_shortcut_runner
144+
- match: naturallanguaged
145+
phase: natural_language_processing
146+
policy_profile: nlp.local_processing.v1
147+
role: natural_language_daemon
148+
- match: cfprefsd
149+
phase: preferences_services
150+
policy_profile: preferences.local_service.v1
151+
role: preferences_daemon
152+
- match: prngseedd
153+
phase: secure_random_seed_services
154+
policy_profile: security.random_seed_local.v1
155+
role: random_seed_service
156+
- match: seputil
157+
phase: secure_enclave_utility
158+
policy_profile: security.secure_enclave_local.v1
159+
role: secure_enclave_utility
160+
- match: MTLCompilerService
161+
phase: metal_shader_compilation
162+
policy_profile: gpu.shader_compile_local.v1
163+
role: metal_compiler_service
164+
- match: swcd
165+
phase: shared_web_credentials
166+
policy_profile: web_credentials_deny_by_default.v1
167+
role: shared_web_credentials_daemon

0 commit comments

Comments
 (0)