Skip to content

Latest commit

 

History

History
65 lines (50 loc) · 31.7 KB

EP-compliance-programme.md

File metadata and controls

65 lines (50 loc) · 31.7 KB

Plan EP: Compliance Programme (assessment and remediation plans)

Assessment date: 4 September 2026 Repository baseline: b2b5190f2c3a55064242d6bd45a16c006c65d55b Status: Assessment complete; remediation is in progress; controls and certification have not been approved or attested. Location: these plans live in docs/plans/ as EP–EV, alongside the feature plans.

OpenGlasses has substantial security engineering, but the repository does not establish readiness for SOC 2 attestation or ISO 27001, ISO 27701, or ISO 42001 certification. Concrete product gaps remain alongside organizational evidence that must be obtained from management. EU AI Act applicability requires decisions for each use case and market; it is not established by a product-wide label.

Read in this order

  1. Detailed assessment and evidence: boundary, strengths, 23 findings, risk rationale, and source limitations.
  2. Integrated remediation roadmap: eight workstreams, task acceptance criteria, dependencies, proposed owners, milestones, and evidence collection.
  3. SOC 2 readiness plan: service scope, Trust Services Criteria mapping, examination evidence.
  4. ISO 27001 ISMS plan: management system and Annex A coverage.
  5. ISO 27701 privacy plan: PIMS, controller/processor responsibilities, data lifecycle and privacy rights.
  6. ISO 42001 and EU AI Act plan: intended-use classification, current legal timeline, AI assurance and transparency.

Implementation checkpoint — 6 September 2026, extended 10 September 2026

Implementation checkpoint — 6–10 September 2026

Implementation has started in the uncommitted working tree at repository HEAD b790c5c9129faa191eca4311d22c62073d548ad1. The assessment remains tied to the original baseline above so the original observations are not overwritten by later changes.

Finding Implemented checkpoint Verification completed Work still required before closure
F01 Release builds refuse the legacy MCP Glasses and Web HUD cleartext listeners before token or listener creation, clear their persisted opt-ins and suppress the HUD token URL. As of 10 September both servers construct their listener through an injected LocalListenerFactory rather than inline, publish an explicit production-unavailable state, and retire the stale developer opt-in at the point of refusal; the production factory compiles its socket-opening branch into Debug only, so a Release binary carries a refusal marker instead of a transport marker. Generated the Xcode project and built the app and test bundle with Xcode 27. Composing both real servers over a Release-flavoured policy and a recording factory showed the factory is never invoked, the state is production-unavailable, both opt-ins are cleared and the HUD registration URL is nil, while the Debug cases invoke it once with the expected service and port. LocalServiceExposureCompositionTests (7), LocalServiceExposurePolicyTests (5) and WebHUDMirrorTests (14) passed in a 103-test focused run with 0 failures, and the full suite executed 4,893 tests with 13 skipped and 0 failures. Scripts/check-release-listener-strings.sh passed against the unsigned arm64 Release simulator artefact built in this worktree (Xcode build 27A5228h, x86_64/arm64, SHA-256 3cb8e36a9b1a8a2001b893a230eec31adc7869d5f48a4eb250de68f061cbf0a5), finding no Debug-only listener or internalSkillPack literal and both positive controls present. Inspect a signed installed Release artifact and its network behavior on a device; replace permitted Debug LAN use with authenticated encrypted pairing; add token rotation, capability scopes, replay protection and resource limits.
F02 QR context, signed catalog/archive and public remote-pack fetches now use named bounded profiles in Debug and Release. Each redirect hop is resolved and revalidated, mixed/private/reserved public answers are refused, the connection is pinned to an approved numeric peer while retaining the original TLS hostname, and MIME/coding/streamed-byte limits are enforced. Private HTTP pack loading is Debug-only, private-address-only and redirect-free. Sideload consent is exact-request-bound, single-use and five-minute limited before streaming into protected, backup-excluded staging. Installation hashes and re-extracts the exact reviewed bytes. Strict ZIP parsing checks central/local/descriptors/ranges, paths, count, size, ratio, type, actual streamed output and CRC. Implemented 2026-09-10: each profile also carries a first-byte and an idle deadline inside the total bound, so a peer that accepts the connection and sends nothing, or stalls part-way through the body, fails deterministically as firstByteTimeout or idleTimeout; only bytes actually delivered move the clock, so a response cannot extend its own deadlines. The pinned-peer/verified-name decision is now the PinnedConnectionPlan value the transport consumes, keeping the TLS server name, certificate-policy hostname and Host header on the request's own host for every hop. Skill-pack extraction is manifest-first: entry policy plus skillpack.json only, then decode and validation, then payload materialization — restricted to the files a manifest declares when it declares any. The earlier Xcode-beta containment suite passed 13 tests. Xcode-beta compiled and linked the arm64 Debug app and full test bundle containing the new 60-test focused selection. It also produced and inspected the current unsigned arm64 Release simulator artifact (Xcode build 27A5228h, SHA-256 ec32f1eb275856c43f36e4cf76d116ffa01d3df384f3e5aa4332e299cc84eb1a); public bounded-fetch profile/policy strings were present and the Debug-only internalSkillPack literal was absent. Two runtime attempts ran zero XCTest cases: a new simulator timed out booting, and an existing booted simulator stalled waiting for workers to materialize. On 2026-09-10, on a healthy iOS 27 simulator, the focused five-class selection executed 72 tests, 0 failures (60 before this change) and the full OpenGlassesTests suite executed 4888 tests, 13 skipped, 0 failures; a -configuration Release simulator build of the same tree succeeded with no new warnings in the changed files. New cases cover both deadlines at their boundaries and their non-extension by the response, the pinned-endpoint versus verified-hostname split (including an already-numeric host and the post-redirect hop), and an inflation counter showing that a manifest refused at admission leaves every other archive entry uninflated. This is implementation evidence, not operating-effectiveness evidence. Inspect a signed installed Release artifact and collect physical-device network evidence (DNS, redirect and private-address behaviour); complete the remaining outbound-route inventory.
F03 Enabled privacy filtering distinguishes verified no-face results from detector failure; suspended or failed still-image processing returns an opaque replacement, and outbound relay failures/suspension drop frames. Extended 2026-09-10: a compile-checked consumer roster with a source-scrape guard against new bypasses; voice-started video recording moved off the raw camera publisher onto the shared blur relay; filter availability driven by injectable scene-phase and device-lock signals, with the transition window treated as unavailable and a return forcing fresh detection; and a maxDetectionAge ceiling (three detection intervals) that makes a stale detection drop the frame rather than publish it on an empty mask. Extended again 2026-09-10: every still reader now obtains its frame from CameraService.filteredStill(for:source:), which requires the scope the still is for and returns an explicit unavailable result rather than the source pixels when it cannot filter, so the vision verticals, the guidance loops, the capture and identification tools, the local MCP server's frame endpoint and the dwell-capture crop written to the Photos library are all covered; the scrape guard was extended to raw still reads and to any file that sends camera pixels to a model, a log, Photos or another process. Passed all 27 OutboundFramePrivacyTests, 4 PrivacyFilterScopeTests and 5 AssessmentPrivacyTests, plus 11 OutboundFrameConsumerTests, 23 FilteredStillRoutingTests, 13 PrivacyFilterAvailabilityTests and 12 OutboundFrameStalenessTests, inside a full run of 5222 tests with 13 skipped and no failures; the -configuration Release build succeeded. Collect device evidence for real background/lock transitions and for behavior under real CPU/thermal pressure. Decided 2026-09-10: the deliberate shutter capture (capturePhoto(), saved to the Photos library and sent to the model by the Direct-mode photo paths) stays unfiltered by product decision — it is the wearer's own framed photograph; the blur is for ambient and automatic captures.
F07 Medical-mode enable/disable and audit clearing retain transition and clear records, and clearing is authorized: clearAuditLog(authorization:) takes an OwnerAuthorization with no default and proceeds only on .granted, while denied and no-decision outcomes keep the log and record the refusal with the decision as a fixed token. OwnerGateAuth.authorize is the fail-closed companion to the Simple Mode prompt, whose fail-open default is unchanged. As of 10 September the records themselves are typed: AuditEvent carries an event id, a millisecond-truncated time, a closed event kind, actor and target classes, a purpose from a closed vocabulary, a policy version, a result and a fingerprinted correlation value — no free-text action/detail pair, with pre-schema rows migrated so the old detail survives only as a fingerprint. Each record carries a sequence number and the digest of the one before it, and a sealed head checkpoint in the keychain (this device only, never synced) makes altering, deleting, reordering, truncating and rolling back the log detectable on load; the verdict is recorded as an event appended after the records it judges. The audit log leaves the app only through the protected export store — file-protected, backup-excluded, scavenged when its window passes — and the trail records the export by the digest of the bytes rather than their content. Audit persistence still sits behind an AuditLogStore seam that writes atomically, reports a refused write and quarantines undecodable bytes. The protected operation journal now sits behind its own storage seam, salvages the complete records from a file killed mid-write, quarantines the damaged tail, and exposes unresolvedOperations and reconcile(outcome:) for operations whose fate is open. On 10 September the focused runs passed with 0 failures: 109 tests across AuditEventSchemaTests (13), AuditChainIntegrityTests (18), AuditExportProtectionTests (7), AuditLogIntegrityTests (10) and MedicalComplianceTests (61); 68 tests across the chain, PrivacyCanaryTests (5) and PrivacyLogTests (45), including a new canary probe that drives the audit trail with a canary in every slot a caller can reach; and 33 tests across OperationJournalDurabilityTests (13) and OperationJournalTests (20). The full suite executed 4,944 tests with 13 skipped and 0 failures, and a -configuration Release build succeeded. Add a production call site and on-device evidence for the owner prompt — no UI affordance clears the log today. Wire the audit events whose sources live in other change sets (deletion completion, consent changes, tool-definition changes, model/tool changes) and migrate the remaining free-text bridge callers. Name a reviewer and an approved SLA, and add alerting so a non-intact verdict or a refused clear reaches them; store a checkpoint off-device for managed deployments; and build the journal recovery UX that would read unresolvedOperations.
F04 Deletion now walks the stores together rather than the one in front of the wearer. SubjectErasureCoordinator erases a person, thread or document across 22 registered stores in one order — derived indexes before their sources, staged exports before either — and returns a receipt per store carrying local completion, remote-pending, a removed count, or the reason that store cannot be keyed by subject. DataStoreRegistry is the inventory the walk is checked against: 53 stores with data class, subject linkage, actual protection and backup state, retention trigger and per-store delete availability, rendered into the ISO 27701 plan's data-lifecycle matrix from the code. Stores that had no delete gained one. SubjectErasureTests passed 12 tests and DataStoreRegistryTests 21. The canary seeds one synthetic person into thirteen stores, erases, reopens every disk-backed store from its files, then searches each store's own read API, prompt assembly and a pre-erasure archive; queue tombstone survival and a post-restart retry are covered. Two registry entries naming a non-existent delete API and one real defect (a note delete that lowercased the note but not the query) were caught by these tests. Obtain a peer that acknowledges a queued deletion so remote-pending can become confirmed; add hold semantics once a hold mechanism exists; privacy-owner sign-off on the matrix; device confirmation of the protection values the simulator declines to report; and a production entry point, since no UI starts a subject erasure today.
F05 Retention, at-rest protection and erasure semantics now agree with each other. All seven SQLite stores were sitting in Documents with no protection attribute the app set and no backup exclusion, and the two JSON stores that asked for complete file protection were still copied into every backup; StoreProtection applies the posture at open time and idempotently, so a store already on a device is covered by being opened. Backup exclusion follows one rule — a store the subject-erasure walk can reach must not also exist in a backup — while the wearer's own writing is deliberately left restorable and the registry says so. RetentionPolicyBook gives each of the 15 data classes an explicit period or an explicit reason for not having one, and RetentionScheduler runs at launch and on foreground behind a date comparison: clinical retention whatever the mode, an opt-in period for the wearer's own history that is off by default with a control in Settings, per-record expires_at honoured by deleting rather than by skipping on read, and a fixed short TTL over retired .migrated blobs, salvage backups and abandoned staging sessions. The overwrite-then-remove "secure delete" is gone: deletion is documented as logical, and ScopedKeyring.eraseClass is the stronger operation where a key is scoped, reporting cryptographic coverage only when the bytes really were sealed. ErasureLedger records completed erasures and a launch replay honours one when a store it touched reappears. RetentionSchedulerTests passed 19, ErasureSemanticsTests 20 and the extended DataStoreRegistryTests 27, inside a full run of 5,292 tests with 13 skipped and 0 failures; the -configuration Release build succeeded. Time-controlled cases cover the expiry boundary in both directions, a disabled policy whose target is not even read, locked protected data skipped and reported rather than counted clean, an interrupted run resuming without recounting, a 180-day gap producing one pass, stale .migrated files going while the live store beside them stays, and a receipt carrying no filename or path. Erasure cases cover a snapshot taken before an erasure failing to open afterwards, plaintext never reported as cryptographic, the key destroyed even when file removal fails, ledger persistence with its protection and backup exclusion read back off the file, replay re-erasing a store that came back, and replay removing nothing and touching nothing when there is nothing to remove. A real encrypted restore drill on a physical device — the post-restore claim in ET §2.2 is a design claim and nothing here demonstrates it. The privacy owner's approval of the periods, which are proposed and attributable but unsigned, and the backup and recovery decisions that go with them, including whether the wearer's own writing should stay restorable and whether the history default should stay off. Sealing clinical transcripts behind an explicit export step, so that class becomes cryptographically erasable rather than logically deleted only. Device confirmation of the protection values the simulator declines to report.
F06 The generic AI export, the HECA safety PDF and the Field Assist session record now use the protected export mechanism the clinical bundle already had: a session directory protected and backup-excluded before the first byte, whole-session removal on write or attribute failure, release on completion, cancellation or backgrounding, and a launch scavenge for what a crash abandoned. The agent archive's readable tree is staged inside that protected directory, so the plaintext copy of every memory and conversation no longer passes through the shared temporary directory. The archive's share sheet now releases its lease on every outcome. 19 new staged-export lifecycle tests passed alongside 51 in the existing export suites, covering protect-before-write ordering, backup exclusion read back off the file, attribute and write failures removing the session, staged plaintext not surviving a mid-write failure, all three share outcomes, TTL-bounded crash recovery and revoke-all. MedicalSecretLifecycleTests passes unchanged, so clinical export behaviour is verified as untouched. Exercise the share lifecycle on a physical device, including a provider holding the file across backgrounding; give the HECA export a share surface, since the tool currently stages a PDF with no UI to hand it to; extend portability scope or disclose what the archive omits.
F09 The medical local-only promise is now enforced for every outbound route, not only for model selection. NetworkRouteRegistry names all 50 routes with what each sends and where; MedicalEgressGuard decides allow/refuse from the mode and the flag, and inference asks it rather than re-deriving the answer. Guards sit at the request-construction point of speech-to-text, cloud text-to-speech, both realtime sessions, cloud translation, intent classification, model catalogs, every network-touching native tool, the gateways and bridges, the offline sync sink, browser streaming, the OAuth token exchanges and the LAN listeners. Refusals reuse existing fallbacks — the cloud voice leaves the engine chain, web search returns a sentence, a queued record stays queued. Five model-acquisition and loopback routes are permitted with written justifications; three are recorded as not applicable, including the operator's own FHIR system. MedicalEgressCoordinator ends live sessions when the mode flips on, and the Local Only switch now emits the change signal it previously lacked. EndpointPolicy gives every client one rule for schemes, credential-bearing URLs and Release cleartext, with the private-network exception keyed on the route. A source-scraping registry test fails when any transport-owning type maps to no route, so the inventory cannot silently rot. Synthetic canaries drive each guarded service through its real request point with a counting URLProtocol underneath and assert both halves: nothing leaves with the mode on, and the same drive does leave with it off. Coordinator teardown is driven with fakes. The full suite ran 4,939 tests with 0 failures and 13 skipped, and the Release configuration built clean. Device packet capture under restricted mode; an Apple-rule opinion on whether a user-supplied provider key counts as collection; the canary's known limit that a registered URLProtocol does not observe a session a client constructs itself; and precise Apple Health/workout labelling.
F20 The AI feature inventory now exists as code. AIFeatureRegistry records 13 AI features with the sensitive category each was screened into — biometric, health, worker safety, external actuation, or an explicit none — the switch that disables it, the tools it reaches the model through, the stores it writes to, and what stays on disk when it is off. Eleven new per-feature switches were added; two features keep switches they already had. AIFeatureGate is consulted at twelve tool entry points, so a release can turn a use case off without turning the app off. AIFeatureRegistryTests passed 16 tests: every feature screened and described, every sensitive category covered, every claimed tool name resolved against the tool sources, every switch round-tripped, four entry points refusing when off, and retention claims cross-checked against the stores. Writing it caught an entry naming a vault delete API that does not exist, and a first version of the tool-name check that read a headlessly-built registry reported four false failures, because several of these tools are registered conditionally. The legal classification itself — role, intended use, market and risk tier — which is a determination with a named owner and not a code artifact. Router-level enforcement of the disabled-tool set, which waits on the branch that owns the tool router. Per-feature switches surfaced in Settings.
F21 Safety output no longer states a certainty nobody produced. The hard-coded confidence: 1.0 that made every assessment card print "Confidence 100%" is gone from all six sites and confidence is optional at card, finding and reading level. A banded certainty is produced only where the evidence supports one, from the model's own number, a measured frame-quality verdict (sharpness and luminance) and the partial-view flags every schema now asks for. A frame that does not support an assessment abstains to a "not established" tier rather than clearing the scene, and first-aid triage abstains when the vitals were never observable. Card, HUD, voice and PDF all render the band or its absence, the limitations line and a human-escalation line from one shared presenter. AssessmentCertaintyTests passed 27 tests alongside 159 in the existing assessment, export and registry suites: no path turns an absent confidence into a number or a band, abstention thresholds and band caps hold, abstention does not mask a visible injury, and the PDF text carries the caveat and the escalation. A domain expert's review of the safety and first-aid wording and the workflow around it. Calibration of the sharpness and luminance thresholds against real glasses frames. A decision on whether a model's self-reported confidence should be surfaced at all once evaluation data exists.
F22 AI-produced artifacts now say so in a field a machine can read. AIProvenance carries the model identifier, whether inference ran on the device, a digest of the instruction version, the timestamp, an explicit AI-generated marker and the app build, and is attached to the assessment card, the safety PDF (footer plus PDF document metadata), the field session record (JSON field plus PDF section) and a provenance.json in the agent archive. An interaction disclosure naming the trained human it does not replace is spoken once per session on the first assessment. AIProvenanceTests passed 12 tests. The end-to-end cases seed a prompt and a source document with canary tokens and assert those tokens appear in none of the exported bytes — encoded card, archive manifest, audit JSON or either rendered PDF — while the model identifier, digest and AI marker survive. The disclosure is asserted to fire exactly once per session and to resolve through the string catalog. The documented human-review and exception decisions the criterion also asks for. Disclosure copy for surfaces beyond assessments — free-text chat and live sessions each need their own. The medical export, left untouched here so its lifecycle tests stay unchanged.
F23 The evaluation corpus and safety gate this finding asked for now exist. OpenGlassesTests/Fixtures/SafetyEvalCorpus is a versioned corpus of 52 synthetic cases across the four verticals that produce a safety output, each a model response fixture plus what the app then owes the wearer — tier, abstention, the certainty band it may claim, whether an escalation reaches them, and the words themselves. SafetyEvalHarness runs every case through the real handling path and reports false-negative, overconfidence, abstention-when-required and escalation-present rates per vertical, risk class and subgroup, deliberately producing no combined accuracy figure. SafetyEvalGateTests fails the pull request, with the report attached, when a critical- or high-risk threshold is breached, and .github/workflows/safety-eval.yml runs it on any change to the handling path, the prompt builders or the corpus. PromptVersionRegistryTests snapshots each assessment prompt's instruction digest, so a reworded prompt cannot ship against results measured from the previous wording. SafetyEvalGateTests passed 8 tests, SafetyEvalHarnessTests 9 and PromptVersionRegistryTests 4, over 52 cases with 0 failing: 0 false negatives and 0 overconfident results at critical and high risk, escalation present in all 52, every required abstention delivered, and the gate's failure path exercised against deliberately wrong expectations rather than assumed. Writing the corpus caught three defects and closed them: a confidence outside 0–1 read as high certainty rather than as a malformed field; an impossible instrument reading passing every check and being spoken to the wearer; and the provenance digest hashing a reflected dictionary description, so it identified the process rather than the prompt version. The threshold approval itself — the criterion requires risk-specific thresholds approved by a named owner before evaluation, and these are proposed floors, stated as such in a field the suite asserts. A corpus of real glasses frames, and calibration of the sharpness and luminance thresholds against them. Subgroup breadth: one to three cases behind most values, and hedge detection is English-only. Model-side evaluation — nothing here measures whether a model sees a hazard. Expert labelling and domain review of the cases. The security half of the finding, which this corpus does not touch.

| F11 | Every tool call is classified by effect, and anything above a read is held for an approval bound to the seam, the tool, its definition digest, the canonical argument digest and the approval session — single use, with a distinct refusal class for replay, changed arguments, a different tool, a different server, a changed definition, expiry and cross-session use. The digest last accepted per server is persisted so changed definitions re-quarantine, a quarantined description is replaced with app-authored text before the model sees it, and the outbound egress screen now runs before anybody is asked to approve anything. | The 67 focused approval-binding, effect-class, re-review and consent tests passed inside a full run of 4,943 tests (13 skipped, 0 failures) on the iOS 27 simulator, followed by a clean -configuration Release build. | Adversarial end-to-end exercise against a live hostile MCP server, the user-authored HTTP tool route and the gateway route; a wearer-facing re-review action for a quarantined definition; better-than-unreviewed classification for the gateway and custom HTTP seams; and a decision on whether native writes to the wearer's own stores should also be bound. |

The F04/F06 work adds a full-suite run of the OpenGlasses test target on the iOS 27 simulator; its counts are recorded in EU. The earlier focused checkpoint totals 119 tests passed, 0 failures. The later F02 containment run passed 13 tests, 0 failures; these counts are stated separately because selected suites may overlap. The final F02 source set and its 60 selected tests compile and link, and the current unsigned Release simulator artifact was built and inspected, while beta-simulator execution remains pending due to the two worker/boot failures described above. This is implementation evidence for the listed seams, not operating-effectiveness evidence, certification, or a legal determination. The earlier focused checkpoint totals 119 tests passed, 0 failures. The later F02 containment run passed 13 tests, 0 failures; these counts are stated separately because selected suites may overlap. The F02 selection has since run: on 2026-09-10 its focused five classes executed 72 tests, 0 failures and the full OpenGlassesTests suite executed 4888 tests, 13 skipped, 0 failures, on a healthy iOS 27 simulator after the earlier worker/boot failures were cleared; the unsigned Release simulator artifact was built and inspected on 2026-09-06 and a Release build of the 2026-09-10 tree succeeded, but no signed installed artifact has been inspected. This is implementation evidence for the listed seams, not operating-effectiveness evidence, certification, or a legal determination.

Immediate priorities

Priority Work Findings Accountable role proposed
P0 Preserve privacy filtering or stop outbound frames when backgrounded/processing fails F03 iOS lead
P0 Enforce the medical “Local LLM Only” setting at provider boundaries F09 iOS/privacy leads
P0 Contain cleartext LAN services and unsafe outbound fetches F01–F02 Security lead
P0 Decide EU intended uses, biometric/medical restrictions and AI disclosures F08, F20–F23 Product lead + legal/privacy lead
P0/P1 Correct cross-store deletion, retention, export and audit lifecycle F04–F07 iOS lead
P1 Complete broader data-destination and external-tool permissions F09–F12 Security/privacy leads
P1 Harden build/publication controls and establish the integrated management system F13–F19 Engineering lead + executive sponsor

P0 means start immediately and resolve or restrict the affected release/use case before broader distribution. It does not mean every feature is internet-exposed or that a breach was observed. The roadmap defines provisional delivery targets; none are statutory deadlines or certification promises.

Evidence discipline

  • Observed means a source-level behavior was verified. Partial means some controls exist but do not close the full objective. Not evidenced means the reviewed repository cannot demonstrate the organizational control; it does not prove the organization lacks it.
  • Unit-test sources and CI configuration were reviewed for the original assessment. The remediation checkpoint generated the Xcode project with Xcode-beta, built the app/test bundle, ran the earlier 119 focused tests and then ran the 13-test F02 containment suite. After archive, consent, streaming staging, review and lifecycle hardening, Xcode-beta compiled the complete app/test bundle but its simulator worker failed before newer test execution. No physical-device exercise, packet capture, penetration test, cloud-console inspection or audit observation period was performed.
  • Keep actual personnel records, credentials, incident details, customer data, audit samples, supplier contracts and test captures in a restricted evidence system. These plans contain source-level findings and proposed work only.
  • The current Pages workflow publishes the repository root. Treat files committed here as potentially public until an allowlisted publishing directory is implemented (F15). No deployment, commit or push was performed; remediation code and plan updates are uncommitted working-tree changes.

Baseline editions are SOC 2 using the 2017 TSC with 2022 revised points of focus; ISO/IEC 27001:2022 including Amendment 1:2024; ISO/IEC 27701:2025; and ISO/IEC 42001:2023. Framework mappings are planning aids, subject to verification against licensed standards and the agreed audit scope. The AI plan distinguishes current Commission guidance from article text not yet consolidated for the 2026 AI Omnibus.