Skip to content

Implement CapabilityLedger contract and UI/runtime capability reconciliation#14

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/implement-capabilityledger-contract
Draft

Implement CapabilityLedger contract and UI/runtime capability reconciliation#14
Copilot wants to merge 2 commits intomainfrom
copilot/implement-capabilityledger-contract

Conversation

Copy link
Copy Markdown

Copilot AI commented May 6, 2026

Adds CapabilityLedger as the single source of truth for all capability state across config, UI, runtime, server, plugin, policy, schema, and transport planes — preventing split-brain where a feature is locally claimed enabled but rejected elsewhere.

packages/capability-ledger/ (new)

  • src/schema.jsCAPABILITY_STATES, CAPABILITY_OWNERS, receiptSchema (JSON Schema draft-07), and receiptExample aligned with sourceos-spec#99
  • src/index.jsCapabilityLedger class; every state change emits a receipt with capabilityId, state, owner, timestamp, policyDecisionRef, evidenceRefs, conflictWarnings
    • Full set of transition methods: declare → request → negotiate → setAvailable → enable, plus deny, degrade, setUnsupportedByRuntime/Server, setMissingPlugin/Schema, fail
    • logConflict(id, warning) — appends conflict warnings without mutating state
    • reconcile() — returns { enabled, pending, conflicted }; intended for runtime startup, feature toggle, and plugin load/unload hooks
    • isEnabled(id) — gates feature use; returns true only when ledger state is "enabled"
  • tests/ledger.test.js — 30 tests via node:test covering: enabling, policy denial, unsupported by runtime/server, missing plugin, missing schema, failed reconciliation, conflict accumulation, full lifecycle, and invalid input guards
const ledger = new CapabilityLedger();
ledger.declare('pdf-viewer', 'UI');
ledger.enable('pdf-viewer', 'runtime', 'policy:allow-pdf:v1', ['config:pdf:on']);
ledger.isEnabled('pdf-viewer'); // true

ledger.setMissingPlugin('pdf-sign', 'plugin', ['plugin:ink-sign:not-installed']);
ledger.isEnabled('pdf-sign'); // false

const { enabled, pending, conflicted } = ledger.reconcile();

apps/pdf-viewer-demo/index.html (updated)

  • Capability Ledger table: effective state (color-coded badge), owner, policyDecisionRef, evidenceRefs, conflict warnings per capability
  • Feature Gate Demo: "View PDF" active (enabled), "Sign PDF" disabled (missing_plugin) — demonstrates ledger-gated feature access

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • accounts.google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=network --no-sandbox --use-angle=swiftshader-webgl --crashpad-handler-pid=4628 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/org.chromium.Chromium.scoped_dir.9PvjX6 --change-stack-guard-on-fork=enable --shared-files=network_parent_dirs_pipe:100,v8_context_snapshot_data:101 --field-trial-handle=3,i,3011833886412195176,1120731902717605222,262144 --disable-features=PaintHolding --variations-seed-version --pseudonymization-salt-handle=7,i,872324044727882308,824040626593909651,4 --trace-process-track-uuid=3190708989122997041 (dns block)
    • Triggering command: /usr/bin/chromium-browser chromium-browser --headless --disable-gpu --screenshot=/tmp/capability-ledger-ui.png --window-size=900,700 --no-sandbox file:///home/REDACTED/work/sourceos-shell/sourceos-shell/apps/pdf-viewer-demo/index.html (dns block)
  • clients2.google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=network --no-sandbox --use-angle=swiftshader-webgl --crashpad-handler-pid=4628 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/org.chromium.Chromium.scoped_dir.9PvjX6 --change-stack-guard-on-fork=enable --shared-files=network_parent_dirs_pipe:100,v8_context_snapshot_data:101 --field-trial-handle=3,i,3011833886412195176,1120731902717605222,262144 --disable-features=PaintHolding --variations-seed-version --pseudonymization-salt-handle=7,i,872324044727882308,824040626593909651,4 --trace-process-track-uuid=3190708989122997041 (dns block)
    • Triggering command: /usr/bin/chromium-browser chromium-browser --headless --disable-gpu --screenshot=/tmp/capability-ledger-ui.png --window-size=900,700 --no-sandbox file:///home/REDACTED/work/sourceos-shell/sourceos-shell/apps/pdf-viewer-demo/index.html (dns block)
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=network --no-sandbox --use-angle=swiftshader-webgl --crashpad-handler-pid=4758 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/org.chromium.Chromium.scoped_dir.XGlGX2 --change-stack-guard-on-fork=enable --shared-files=network_parent_dirs_pipe:100,v8_context_snapshot_data:101 --field-trial-handle=3,i,6724706879400872977,18314031558142100396,262144 --disable-features=PaintHolding --variations-seed-version --pseudonymization-salt-handle=7,i,11921452979086232962,14162284320797668367,4 --trace-process-track-uuid=3190708989122997041 (dns block)
  • redirector.gvt1.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=network --no-sandbox --use-angle=swiftshader-webgl --crashpad-handler-pid=4628 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/org.chromium.Chromium.scoped_dir.9PvjX6 --change-stack-guard-on-fork=enable --shared-files=network_parent_dirs_pipe:100,v8_context_snapshot_data:101 --field-trial-handle=3,i,3011833886412195176,1120731902717605222,262144 --disable-features=PaintHolding --variations-seed-version --pseudonymization-salt-handle=7,i,872324044727882308,824040626593909651,4 --trace-process-track-uuid=3190708989122997041 (dns block)
    • Triggering command: /usr/bin/chromium-browser chromium-browser --headless --disable-gpu --screenshot=/tmp/capability-ledger-ui.png --window-size=900,700 --no-sandbox file:///home/REDACTED/work/sourceos-shell/sourceos-shell/apps/pdf-viewer-demo/index.html (dns block)
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=network --no-sandbox --use-angle=swiftshader-webgl --crashpad-handler-pid=4758 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/org.chromium.Chromium.scoped_dir.XGlGX2 --change-stack-guard-on-fork=enable --shared-files=network_parent_dirs_pipe:100,v8_context_snapshot_data:101 --field-trial-handle=3,i,6724706879400872977,18314031558142100396,262144 --disable-features=PaintHolding --variations-seed-version --pseudonymization-salt-handle=7,i,11921452979086232962,14162284320797668367,4 --trace-process-track-uuid=3190708989122997041 (dns block)
  • www.google.com
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=network --no-sandbox --use-angle=swiftshader-webgl --crashpad-handler-pid=4628 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/org.chromium.Chromium.scoped_dir.9PvjX6 --change-stack-guard-on-fork=enable --shared-files=network_parent_dirs_pipe:100,v8_context_snapshot_data:101 --field-trial-handle=3,i,3011833886412195176,1120731902717605222,262144 --disable-features=PaintHolding --variations-seed-version --pseudonymization-salt-handle=7,i,872324044727882308,824040626593909651,4 --trace-process-track-uuid=3190708989122997041 (dns block)
    • Triggering command: /usr/bin/chromium-browser chromium-browser --headless --disable-gpu --screenshot=/tmp/capability-ledger-ui.png --window-size=900,700 --no-sandbox file:///home/REDACTED/work/sourceos-shell/sourceos-shell/apps/pdf-viewer-demo/index.html (dns block)
    • Triggering command: /proc/self/exe /proc/self/exe --type=utility --utility-sub-type=network.mojom.NetworkService --lang=en-US --service-sandbox-type=network --no-sandbox --use-angle=swiftshader-webgl --crashpad-handler-pid=4758 --enable-crash-reporter=, --noerrdialogs --user-data-dir=/tmp/org.chromium.Chromium.scoped_dir.XGlGX2 --change-stack-guard-on-fork=enable --shared-files=network_parent_dirs_pipe:100,v8_context_snapshot_data:101 --field-trial-handle=3,i,6724706879400872977,18314031558142100396,262144 --disable-features=PaintHolding --variations-seed-version --pseudonymization-salt-handle=7,i,11921452979086232962,14162284320797668367,4 --trace-process-track-uuid=3190708989122997041 (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title [WIP] Implement CapabilityLedger contract and UI/runtime capability reconciliation Implement CapabilityLedger contract and UI/runtime capability reconciliation May 6, 2026
Copilot AI requested a review from mdheller May 6, 2026 18:36
Copy link
Copy Markdown
Contributor

mdheller commented May 6, 2026

Review: strong local ledger package, but upstream contract alignment is required

This PR is directionally strong: it adds a reusable ledger package, tests, UI/demo surfacing, and feature-gate behavior. The implementation maps well to the intent of the CapabilityLedger downstream lane.

Blocking remediation before this should be marked ready/merged:

  1. Align the emitted receipt shape with upstream SourceOS-Linux/sourceos-spec PR #101: schemas/CapabilityLedger.json and examples/capabilityledger.json.
  2. The upstream schema uses capabilityRef, sessionRef, agentMachineReceiptRef, declaredBy, negotiatedBy, effectiveState, stateReason, ownerRefs, conflictRefs, causalRefs, policyDecisionRef, non-empty evidenceRefs, and capturedAt.
  3. The PR body describes local fields such as capabilityId, state, owner, timestamp, and conflictWarnings. Those are fine for internal state, but emitted receipts must adapt to upstream names and required fields.
  4. Align owner values with the upstream enum: config, ui, runtime, server, plugin, policy, schema, transport, user, agent, workspace. Internal display labels can remain friendly, but emitted contract payloads should use the upstream values.
  5. Add a schema fixture or sync path from sourceos-spec, and validate generated ledger entries against the upstream schema/canonical example.
  6. Remove or redact the long Copilot firewall diagnostic from the PR body before final review. It creates noise and distracts from the product delta.

Recommendation: keep the local package and UI, then add a toCapabilityLedgerReceipt(...) adapter that emits the SourceOS contract exactly. That preserves good internal ergonomics while keeping the repo aligned to the merged contract layer.

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.

Implement CapabilityLedger contract and UI/runtime capability reconciliation

2 participants