@miller-tech/uap 2.21.3 → 2.36.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -10
- package/config/model-profiles/qwen38-coder390.json +46 -0
- package/config/model-profiles/qwen38.json +3 -2
- package/config/model-registry.json +110 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/benchmarks/paired/types.d.ts +2 -2
- package/dist/bin/cli.js +315 -20
- package/dist/bin/cli.js.map +1 -1
- package/dist/cli/attention.d.ts +6 -0
- package/dist/cli/attention.d.ts.map +1 -0
- package/dist/cli/attention.js +115 -0
- package/dist/cli/attention.js.map +1 -0
- package/dist/cli/bench-report.d.ts +82 -0
- package/dist/cli/bench-report.d.ts.map +1 -0
- package/dist/cli/bench-report.js +237 -0
- package/dist/cli/bench-report.js.map +1 -0
- package/dist/cli/clients.d.ts +6 -0
- package/dist/cli/clients.d.ts.map +1 -0
- package/dist/cli/clients.js +142 -0
- package/dist/cli/clients.js.map +1 -0
- package/dist/cli/dashboard-grants.d.ts +26 -0
- package/dist/cli/dashboard-grants.d.ts.map +1 -0
- package/dist/cli/dashboard-grants.js +69 -0
- package/dist/cli/dashboard-grants.js.map +1 -0
- package/dist/cli/dashboard-pace.d.ts +31 -0
- package/dist/cli/dashboard-pace.d.ts.map +1 -0
- package/dist/cli/dashboard-pace.js +42 -0
- package/dist/cli/dashboard-pace.js.map +1 -0
- package/dist/cli/dashboard-session.d.ts +25 -0
- package/dist/cli/dashboard-session.d.ts.map +1 -0
- package/dist/cli/dashboard-session.js +814 -0
- package/dist/cli/dashboard-session.js.map +1 -0
- package/dist/cli/dashboard-types.d.ts +18 -0
- package/dist/cli/dashboard-types.d.ts.map +1 -0
- package/dist/cli/dashboard-types.js +9 -0
- package/dist/cli/dashboard-types.js.map +1 -0
- package/dist/cli/dashboard.d.ts +2 -18
- package/dist/cli/dashboard.d.ts.map +1 -1
- package/dist/cli/dashboard.js +43 -793
- package/dist/cli/dashboard.js.map +1 -1
- package/dist/cli/deliver.d.ts +35 -0
- package/dist/cli/deliver.d.ts.map +1 -1
- package/dist/cli/deliver.js +93 -9
- package/dist/cli/deliver.js.map +1 -1
- package/dist/cli/diff.d.ts +85 -0
- package/dist/cli/diff.d.ts.map +1 -0
- package/dist/cli/diff.js +293 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/eta.d.ts +35 -0
- package/dist/cli/eta.d.ts.map +1 -0
- package/dist/cli/eta.js +101 -0
- package/dist/cli/eta.js.map +1 -0
- package/dist/cli/handsfree.d.ts +7 -0
- package/dist/cli/handsfree.d.ts.map +1 -1
- package/dist/cli/handsfree.js +27 -0
- package/dist/cli/handsfree.js.map +1 -1
- package/dist/cli/hooks.d.ts.map +1 -1
- package/dist/cli/hooks.js +126 -5
- package/dist/cli/hooks.js.map +1 -1
- package/dist/cli/loops.d.ts +24 -5
- package/dist/cli/loops.d.ts.map +1 -1
- package/dist/cli/loops.js +92 -12
- package/dist/cli/loops.js.map +1 -1
- package/dist/cli/models.d.ts +62 -0
- package/dist/cli/models.d.ts.map +1 -0
- package/dist/cli/models.js +567 -0
- package/dist/cli/models.js.map +1 -0
- package/dist/cli/plan.d.ts +9 -0
- package/dist/cli/plan.d.ts.map +1 -1
- package/dist/cli/plan.js +57 -4
- package/dist/cli/plan.js.map +1 -1
- package/dist/cli/proxy-relay.d.ts +55 -0
- package/dist/cli/proxy-relay.d.ts.map +1 -0
- package/dist/cli/proxy-relay.js +116 -0
- package/dist/cli/proxy-relay.js.map +1 -0
- package/dist/cli/proxy.d.ts +4 -0
- package/dist/cli/proxy.d.ts.map +1 -1
- package/dist/cli/proxy.js +26 -1
- package/dist/cli/proxy.js.map +1 -1
- package/dist/cli/sandbox.d.ts +101 -4
- package/dist/cli/sandbox.d.ts.map +1 -1
- package/dist/cli/sandbox.js +393 -44
- package/dist/cli/sandbox.js.map +1 -1
- package/dist/cli/self.d.ts +13 -0
- package/dist/cli/self.d.ts.map +1 -0
- package/dist/cli/self.js +94 -0
- package/dist/cli/self.js.map +1 -0
- package/dist/cli/systemd-services.d.ts +2 -8
- package/dist/cli/systemd-services.d.ts.map +1 -1
- package/dist/cli/systemd-services.js +5 -20
- package/dist/cli/systemd-services.js.map +1 -1
- package/dist/cli/task.js +1 -1
- package/dist/cli/task.js.map +1 -1
- package/dist/cli/wizard-config.d.ts.map +1 -1
- package/dist/cli/wizard-config.js +31 -2
- package/dist/cli/wizard-config.js.map +1 -1
- package/dist/config/settings-registry.d.ts +1 -1
- package/dist/config/settings-registry.d.ts.map +1 -1
- package/dist/config/settings-registry.js +108 -0
- package/dist/config/settings-registry.js.map +1 -1
- package/dist/coordination/capability-router.js +2 -2
- package/dist/coordination/capability-router.js.map +1 -1
- package/dist/coordination/database.d.ts +13 -0
- package/dist/coordination/database.d.ts.map +1 -1
- package/dist/coordination/database.js +63 -7
- package/dist/coordination/database.js.map +1 -1
- package/dist/coordination/eta-inject.d.ts +32 -0
- package/dist/coordination/eta-inject.d.ts.map +1 -0
- package/dist/coordination/eta-inject.js +64 -0
- package/dist/coordination/eta-inject.js.map +1 -0
- package/dist/coordination/reactor.d.ts.map +1 -1
- package/dist/coordination/reactor.js +14 -0
- package/dist/coordination/reactor.js.map +1 -1
- package/dist/coordination/service.d.ts +18 -8
- package/dist/coordination/service.d.ts.map +1 -1
- package/dist/coordination/service.js +38 -28
- package/dist/coordination/service.js.map +1 -1
- package/dist/dashboard/client-registry.d.ts +163 -0
- package/dist/dashboard/client-registry.d.ts.map +1 -0
- package/dist/dashboard/client-registry.js +549 -0
- package/dist/dashboard/client-registry.js.map +1 -0
- package/dist/dashboard/controls.d.ts.map +1 -1
- package/dist/dashboard/controls.js +33 -4
- package/dist/dashboard/controls.js.map +1 -1
- package/dist/dashboard/data-seeder.d.ts +10 -7
- package/dist/dashboard/data-seeder.d.ts.map +1 -1
- package/dist/dashboard/data-seeder.js +31 -75
- package/dist/dashboard/data-seeder.js.map +1 -1
- package/dist/dashboard/data-service.d.ts +9 -0
- package/dist/dashboard/data-service.d.ts.map +1 -1
- package/dist/dashboard/data-service.js +32 -3
- package/dist/dashboard/data-service.js.map +1 -1
- package/dist/dashboard/placement-routes.d.ts +119 -0
- package/dist/dashboard/placement-routes.d.ts.map +1 -0
- package/dist/dashboard/placement-routes.js +331 -0
- package/dist/dashboard/placement-routes.js.map +1 -0
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +408 -2
- package/dist/dashboard/server.js.map +1 -1
- package/dist/delivery/attention.d.ts +130 -0
- package/dist/delivery/attention.d.ts.map +1 -0
- package/dist/delivery/attention.js +341 -0
- package/dist/delivery/attention.js.map +1 -0
- package/dist/delivery/decompose.d.ts +18 -0
- package/dist/delivery/decompose.d.ts.map +1 -1
- package/dist/delivery/decompose.js +22 -1
- package/dist/delivery/decompose.js.map +1 -1
- package/dist/delivery/eta-estimate.d.ts +111 -0
- package/dist/delivery/eta-estimate.d.ts.map +1 -0
- package/dist/delivery/eta-estimate.js +171 -0
- package/dist/delivery/eta-estimate.js.map +1 -0
- package/dist/delivery/eta.d.ts +23 -0
- package/dist/delivery/eta.d.ts.map +1 -0
- package/dist/delivery/eta.js +59 -0
- package/dist/delivery/eta.js.map +1 -0
- package/dist/delivery/orchestrated-mission.d.ts +10 -0
- package/dist/delivery/orchestrated-mission.d.ts.map +1 -1
- package/dist/delivery/orchestrated-mission.js +15 -1
- package/dist/delivery/orchestrated-mission.js.map +1 -1
- package/dist/delivery/plan-check.d.ts +7 -1
- package/dist/delivery/plan-check.d.ts.map +1 -1
- package/dist/delivery/plan-check.js +23 -2
- package/dist/delivery/plan-check.js.map +1 -1
- package/dist/delivery/run-state.d.ts +1 -1
- package/dist/delivery/run-state.d.ts.map +1 -1
- package/dist/delivery/run-state.js +8 -1
- package/dist/delivery/run-state.js.map +1 -1
- package/dist/delivery/task-orchestrator.d.ts +8 -3
- package/dist/delivery/task-orchestrator.d.ts.map +1 -1
- package/dist/delivery/task-orchestrator.js +75 -43
- package/dist/delivery/task-orchestrator.js.map +1 -1
- package/dist/delivery/task-sync.d.ts +21 -0
- package/dist/delivery/task-sync.d.ts.map +1 -1
- package/dist/delivery/task-sync.js +44 -8
- package/dist/delivery/task-sync.js.map +1 -1
- package/dist/delivery/task-workspace.d.ts +3 -3
- package/dist/delivery/task-workspace.js +3 -3
- package/dist/generators/self-card.d.ts +65 -0
- package/dist/generators/self-card.d.ts.map +1 -0
- package/dist/generators/self-card.js +256 -0
- package/dist/generators/self-card.js.map +1 -0
- package/dist/inference/probe.js +1 -1
- package/dist/inference/probe.js.map +1 -1
- package/dist/memory/prepopulate.d.ts.map +1 -1
- package/dist/memory/prepopulate.js +2 -0
- package/dist/memory/prepopulate.js.map +1 -1
- package/dist/models/analytics.d.ts +32 -0
- package/dist/models/analytics.d.ts.map +1 -1
- package/dist/models/analytics.js +68 -5
- package/dist/models/analytics.js.map +1 -1
- package/dist/models/plan-readability.d.ts +55 -0
- package/dist/models/plan-readability.d.ts.map +1 -0
- package/dist/models/plan-readability.js +339 -0
- package/dist/models/plan-readability.js.map +1 -0
- package/dist/placement/admission.d.ts +59 -0
- package/dist/placement/admission.d.ts.map +1 -0
- package/dist/placement/admission.js +197 -0
- package/dist/placement/admission.js.map +1 -0
- package/dist/placement/auto.d.ts +44 -0
- package/dist/placement/auto.d.ts.map +1 -0
- package/dist/placement/auto.js +212 -0
- package/dist/placement/auto.js.map +1 -0
- package/dist/placement/enforce.d.ts +128 -0
- package/dist/placement/enforce.d.ts.map +1 -0
- package/dist/placement/enforce.js +655 -0
- package/dist/placement/enforce.js.map +1 -0
- package/dist/placement/idle.d.ts +50 -0
- package/dist/placement/idle.d.ts.map +1 -0
- package/dist/placement/idle.js +213 -0
- package/dist/placement/idle.js.map +1 -0
- package/dist/placement/ledger.d.ts +323 -0
- package/dist/placement/ledger.d.ts.map +1 -0
- package/dist/placement/ledger.js +263 -0
- package/dist/placement/ledger.js.map +1 -0
- package/dist/placement/preview.d.ts +51 -0
- package/dist/placement/preview.d.ts.map +1 -0
- package/dist/placement/preview.js +61 -0
- package/dist/placement/preview.js.map +1 -0
- package/dist/placement/probes.d.ts +47 -0
- package/dist/placement/probes.d.ts.map +1 -0
- package/dist/placement/probes.js +207 -0
- package/dist/placement/probes.js.map +1 -0
- package/dist/placement/proxy-env.d.ts +21 -0
- package/dist/placement/proxy-env.d.ts.map +1 -0
- package/dist/placement/proxy-env.js +42 -0
- package/dist/placement/proxy-env.js.map +1 -0
- package/dist/placement/registry.d.ts +1038 -0
- package/dist/placement/registry.d.ts.map +1 -0
- package/dist/placement/registry.js +274 -0
- package/dist/placement/registry.js.map +1 -0
- package/dist/policies/liveness.d.ts +6 -8
- package/dist/policies/liveness.d.ts.map +1 -1
- package/dist/policies/liveness.js +6 -25
- package/dist/policies/liveness.js.map +1 -1
- package/dist/policies/sandbox-anchor.d.ts +91 -0
- package/dist/policies/sandbox-anchor.d.ts.map +1 -0
- package/dist/policies/sandbox-anchor.js +187 -0
- package/dist/policies/sandbox-anchor.js.map +1 -0
- package/dist/policies/sandbox-grants.d.ts +131 -0
- package/dist/policies/sandbox-grants.d.ts.map +1 -0
- package/dist/policies/sandbox-grants.js +562 -0
- package/dist/policies/sandbox-grants.js.map +1 -0
- package/dist/state/manifest.d.ts +4 -2
- package/dist/state/manifest.d.ts.map +1 -1
- package/dist/state/manifest.js +32 -16
- package/dist/state/manifest.js.map +1 -1
- package/dist/utils/checkout-root.d.ts +2 -0
- package/dist/utils/checkout-root.d.ts.map +1 -0
- package/dist/utils/checkout-root.js +43 -0
- package/dist/utils/checkout-root.js.map +1 -0
- package/dist/utils/resolve-uap-bin.d.ts +5 -0
- package/dist/utils/resolve-uap-bin.d.ts.map +1 -0
- package/dist/utils/resolve-uap-bin.js +33 -0
- package/dist/utils/resolve-uap-bin.js.map +1 -0
- package/dist/utils/terminal-safe.d.ts +12 -0
- package/dist/utils/terminal-safe.d.ts.map +1 -0
- package/dist/utils/terminal-safe.js +53 -0
- package/dist/utils/terminal-safe.js.map +1 -0
- package/docs/ATTRIBUTION.md +1 -0
- package/docs/DASHBOARD_UPLIFT_SPEC.md +8 -8
- package/docs/INDEX.md +6 -5
- package/docs/architecture/OVERVIEW.md +15 -3
- package/docs/architecture/PROTOCOL.md +7 -1
- package/docs/architecture/adr/0006-operator-directed-model-placement.md +86 -0
- package/docs/architecture/adr/0007-auto-displacement-allowlist-as-standing-consent.md +79 -0
- package/docs/architecture/adr/0008-fleet-clients-link-out.md +92 -0
- package/docs/architecture/adr/0009-completion-triggered-dispatch-and-per-leaf-model-dials.md +71 -0
- package/docs/architecture/adr/0010-attention-queue-and-afk-auto-decider.md +159 -0
- package/docs/architecture/adr/0011-sandbox-grants-and-network-egress-boundary.md +219 -0
- package/docs/architecture/adr/0012-operator-legibility-surfaces.md +175 -0
- package/docs/getting-started/INSTALLATION.md +1 -1
- package/docs/guides/AUTOMATIC_FEATURES.md +8 -0
- package/docs/guides/LOCAL_MODELS.md +1 -1
- package/docs/guides/PROXY.md +2 -1
- package/docs/guides/SANDBOX.md +91 -4
- package/docs/integrations/MCP_ROUTER.md +1 -1
- package/docs/plans/model-performance-proof-options.md +176 -0
- package/docs/reference/API.md +1 -1
- package/docs/reference/CLI.md +169 -4
- package/docs/reference/COMPARISON.md +1 -1
- package/docs/reference/CONFIGURATION.md +12 -3
- package/docs/reference/CONFIGURATION_REFERENCE.md +269 -14
- package/docs/reference/DATABASE_SCHEMA.md +1 -1
- package/docs/reference/FEATURES.md +15 -3
- package/docs/reference/PATTERNS.md +1 -1
- package/docs/reference/PLATFORMS.md +14 -1
- package/docs/specs/operator-model-placement.md +1314 -0
- package/docs/specs/operator-model-placement.review.md +339 -0
- package/package.json +2 -2
- package/scripts/maintenance/publish-npm.sh +23 -11
- package/scripts/version-bump.sh +6 -51
- package/src/policies/enforcers/__pycache__/_common.cpython-311.pyc +0 -0
- package/src/policies/enforcers/__pycache__/expert_review_required.cpython-311.pyc +0 -0
- package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-311.pyc +0 -0
- package/src/policies/schemas/policies/mandatory-testing-deployment.md +2 -5
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-311.pyc +0 -0
- package/templates/hooks/session-start.sh +44 -0
- package/tools/agents/UAP/cli.py +14 -3
- package/tools/agents/UAP/paths.py +50 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-311.pyc +0 -0
- package/tools/agents/scripts/anthropic_proxy.py +1386 -99
- package/tools/agents/scripts/toolcall_path_normalizer.py +46 -1
- package/tools/agents/tests/test_anthropic_proxy_streaming.py +29 -6
- package/tools/agents/tests/test_doubling_break.py +64 -5
- package/tools/agents/tests/test_error_loop_break.py +10 -4
- package/tools/agents/tests/test_error_loop_ignores_correctives.py +13 -2
- package/tools/agents/tests/test_lockstep_escalation.py +280 -9
- package/tools/agents/tests/test_path_containment.py +94 -0
- package/tools/agents/tests/test_proxy_unix_socket.py +162 -0
- package/tools/agents/tests/test_signature_quality.py +349 -0
- package/tools/agents/tests/test_uap_compliance.py +11 -1
- package/web/dash/core.js +1 -0
- package/web/dash/tab-clients.js +196 -0
- package/web/dash/tab-models.js +387 -8
- package/web/dash/tab-policies.js +87 -4
- package/web/dash/tabs.js +77 -73
- package/web/dashboard.html +6 -0
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/expert_review_required.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-312.pyc +0 -0
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
- package/web/dash/tab-agents.js +0 -21
- package/web/dash/tab-deliver.js +0 -12
- package/web/dash/tab-memory.js +0 -12
- package/web/dash/tab-orchestration.js +0 -21
- package/web/dash/tab-overview.js +0 -21
- package/web/dash/tab-tasks.js +0 -21
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sandbox-consent trust anchor (ADR 0011's named operator-surface follow-up).
|
|
3
|
+
*
|
|
4
|
+
* The grant ledger and audit trail live under the MAIN checkout root —
|
|
5
|
+
* writable by the operator side of every run. The kernel ro-bind closes the
|
|
6
|
+
* *sandboxed* side, and the load path re-validates shape, but neither
|
|
7
|
+
* can prove WHO wrote a row: a process with the checkout's write reach can
|
|
8
|
+
* plant a well-formed grant and claim the operator consented.
|
|
9
|
+
*
|
|
10
|
+
* This module is the honest increment: **tamper-evidence, not tamper-proofing**.
|
|
11
|
+
* A 0600 anchor file OUTSIDE the checkout's write reach records the hash of
|
|
12
|
+
* the sanitized ledger as of the last recorded consent operation. On load,
|
|
13
|
+
* the on-disk ledger is re-hashed and compared: a match proves the ledger is
|
|
14
|
+
* exactly the state a recorded grant/renew/revoke produced; a mismatch means
|
|
15
|
+
* something with checkout write access altered it — which fails CLOSED (no
|
|
16
|
+
* extra holes, loud warning) at the sandbox launch and refuses new grants.
|
|
17
|
+
*
|
|
18
|
+
* What this does NOT do (kept explicit, not hidden): the anchor lives in the
|
|
19
|
+
* user's state dir, so a *same-user* process outside the checkout can still
|
|
20
|
+
* write it. The boundary it draws is exactly the ADR's frame — the
|
|
21
|
+
* checkout's write reach vs. outside it. True origin proof (a different uid
|
|
22
|
+
* or a hardware key) remains open and is not claimed.
|
|
23
|
+
*/
|
|
24
|
+
import { createHash } from 'crypto';
|
|
25
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'fs';
|
|
26
|
+
import { homedir } from 'os';
|
|
27
|
+
import { join, sep } from 'path';
|
|
28
|
+
import { randomBytes } from 'crypto';
|
|
29
|
+
import { mainCheckoutRoot } from '../utils/checkout-root.js';
|
|
30
|
+
import { termSafe } from '../utils/terminal-safe.js';
|
|
31
|
+
/** Anchor file version — future shape changes bump this and re-anchor. */
|
|
32
|
+
export const ANCHOR_VERSION = 1;
|
|
33
|
+
/** The anchor dir: OUTSIDE the checkout's write reach by construction. */
|
|
34
|
+
export function anchorDir() {
|
|
35
|
+
const pinned = process.env.UAP_SANDBOX_ANCHOR_DIR;
|
|
36
|
+
if (pinned) {
|
|
37
|
+
warnIfPinnedInsideCheckout(pinned);
|
|
38
|
+
return pinned;
|
|
39
|
+
}
|
|
40
|
+
const xdg = process.env.XDG_STATE_HOME;
|
|
41
|
+
const base = xdg || join(homedir(), '.local', 'state');
|
|
42
|
+
return join(base, 'uap', 'sandbox-anchors');
|
|
43
|
+
}
|
|
44
|
+
/** Warn once when the pin points INSIDE the checkout the anchor vouches for:
|
|
45
|
+
* the "verified against its trust anchor" verdict would then be false
|
|
46
|
+
* assurance — the anchor is exactly as tamperable as the ledger it hashes.
|
|
47
|
+
* The pin exists for tests and non-standard layouts; a real checkout root
|
|
48
|
+
* (a dir whose git toplevel resolves) using it in-tree is operator error
|
|
49
|
+
* worth a loud line, not a silent green. */
|
|
50
|
+
let warnedPinInside = false;
|
|
51
|
+
function warnIfPinnedInsideCheckout(pinned) {
|
|
52
|
+
if (warnedPinInside)
|
|
53
|
+
return;
|
|
54
|
+
try {
|
|
55
|
+
const root = mainCheckoutRoot(pinned);
|
|
56
|
+
// Only meaningful for a real git checkout; non-git tmp pins (tests) pass.
|
|
57
|
+
const isGitCheckout = existsSync(join(root, '.git')) || root !== pinned;
|
|
58
|
+
const inside = pinned === root || pinned.startsWith(root + sep);
|
|
59
|
+
if (isGitCheckout && inside && root.length > 1) {
|
|
60
|
+
warnedPinInside = true;
|
|
61
|
+
console.warn(`[sandbox-anchor] UAP_SANDBOX_ANCHOR_DIR is INSIDE the checkout (${root}) it vouches for — ` +
|
|
62
|
+
'the tamper-evidence verdict is meaningless for this session; pin a dir outside the tree');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
/* the pin still works; this is advisory */
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** One anchor per MAIN-checkout root (keyed by its hash, never its literal
|
|
70
|
+
* path — the path can contain spaces/usernames that must not reach a
|
|
71
|
+
* filename). Keying by `mainCheckoutRoot` — NOT the raw argument — is the
|
|
72
|
+
* whole point: every surface passes a cwd (often a `.worktrees/NNN-*`
|
|
73
|
+
* subdir), and the LEDGER already resolves through the same helper, so
|
|
74
|
+
* keying the anchor by the raw cwd would give the shared ledger one anchor
|
|
75
|
+
* per cwd string: worktree sessions would silently run UNANCHORED, and a
|
|
76
|
+
* grant recorded from one cwd would look tampered from another. All three
|
|
77
|
+
* P-debt reviewers caught this independently; the fix is to key exactly
|
|
78
|
+
* the way the ledger does. */
|
|
79
|
+
export function anchorPath(projectRoot) {
|
|
80
|
+
const key = createHash('sha256').update(mainCheckoutRoot(projectRoot)).digest('hex').slice(0, 16);
|
|
81
|
+
return join(anchorDir(), `${key}.json`);
|
|
82
|
+
}
|
|
83
|
+
/** True when a granted writable path would cover the anchor dir — the one
|
|
84
|
+
* grant that must be refused, because a hole over the anchor lets the
|
|
85
|
+
* sandboxed side delete or corrupt the tamper evidence itself. */
|
|
86
|
+
export function pathCoversAnchorDir(grantPath) {
|
|
87
|
+
const dir = anchorDir();
|
|
88
|
+
return dir === grantPath || dir.startsWith(grantPath + sep);
|
|
89
|
+
}
|
|
90
|
+
/** The tamper-evidence hash of a ledger state: over the SANITIZED rows (the
|
|
91
|
+
* same shape the load path enforces), in stored order. */
|
|
92
|
+
export function ledgerHeadOf(grants) {
|
|
93
|
+
return createHash('sha256').update(JSON.stringify(grants)).digest('hex');
|
|
94
|
+
}
|
|
95
|
+
/** Read the anchor; null when absent or malformed (absent = unanchored).
|
|
96
|
+
* The metadata fields are termSafe'd here — they are interpolated into the
|
|
97
|
+
* mismatch banners on the dashboard/CLI/launch stderr, and whoever can
|
|
98
|
+
* write the anchor can plant control bytes in them. */
|
|
99
|
+
export function readAnchor(projectRoot) {
|
|
100
|
+
try {
|
|
101
|
+
const raw = JSON.parse(readFileSync(anchorPath(projectRoot), 'utf-8'));
|
|
102
|
+
// Unknown future versions read as unanchored rather than being coerced
|
|
103
|
+
// into v1 shape — the anchor's own honesty rule.
|
|
104
|
+
if (raw.v !== ANCHOR_VERSION)
|
|
105
|
+
return null;
|
|
106
|
+
if (typeof raw.ledgerHead !== 'string' || !/^[0-9a-f]{64}$/.test(raw.ledgerHead))
|
|
107
|
+
return null;
|
|
108
|
+
return {
|
|
109
|
+
v: ANCHOR_VERSION,
|
|
110
|
+
ledgerHead: raw.ledgerHead,
|
|
111
|
+
mutations: typeof raw.mutations === 'number' ? raw.mutations : 0,
|
|
112
|
+
seqHi: typeof raw.seqHi === 'number' && Number.isSafeInteger(raw.seqHi) && raw.seqHi >= 0
|
|
113
|
+
? raw.seqHi
|
|
114
|
+
: undefined,
|
|
115
|
+
updatedAt: typeof raw.updatedAt === 'string' ? termSafe(raw.updatedAt).slice(0, 64) : '',
|
|
116
|
+
updatedBy: typeof raw.updatedBy === 'string' ? termSafe(raw.updatedBy).slice(0, 64) : '',
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** Write the anchor atomically with tight permissions (0600, 0700 dirs).
|
|
124
|
+
* Best-effort: a failure is reported by return value, never a throw — the
|
|
125
|
+
* ledger itself stays the operative record; without an anchor there is
|
|
126
|
+
* simply nothing to verify against yet. `seqHi` is the audit high-water the
|
|
127
|
+
* caller witnessed AFTER the operation's audit line landed (the recorded
|
|
128
|
+
* mutations run audit-then-anchor for exactly this reason). */
|
|
129
|
+
export function writeAnchor(projectRoot, ledgerHead, mutations, seqHi) {
|
|
130
|
+
try {
|
|
131
|
+
const dir = anchorDir();
|
|
132
|
+
if (!existsSync(dir)) {
|
|
133
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
chmodSync(dir, 0o700); // pin the dir every time — a pre-existing loose-perm dir must not stay loose
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
/* non-fatal: the write still lands */
|
|
140
|
+
}
|
|
141
|
+
const state = {
|
|
142
|
+
v: ANCHOR_VERSION,
|
|
143
|
+
ledgerHead,
|
|
144
|
+
mutations,
|
|
145
|
+
seqHi,
|
|
146
|
+
updatedAt: new Date().toISOString(),
|
|
147
|
+
updatedBy: process.env.USER || process.env.LOGNAME || 'unknown',
|
|
148
|
+
};
|
|
149
|
+
const path = anchorPath(projectRoot);
|
|
150
|
+
const tmp = `${path}.${process.pid}-${randomBytes(3).toString('hex')}.tmp`;
|
|
151
|
+
writeFileSync(tmp, JSON.stringify(state, null, 2), { encoding: 'utf-8', mode: 0o600 });
|
|
152
|
+
try {
|
|
153
|
+
chmodSync(tmp, 0o600); // pin against umask
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
/* non-fatal */
|
|
157
|
+
}
|
|
158
|
+
renameSync(tmp, path);
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Verify the on-disk ledger against the anchor. 'unanchored' is not a
|
|
167
|
+
* failure — it is the pre-bootstrap state (existing ledgers predate the
|
|
168
|
+
* anchor; the first recorded mutation anchors them). 'mismatch' is the
|
|
169
|
+
* tamper signal: something changed the ledger outside a recorded consent
|
|
170
|
+
* operation.
|
|
171
|
+
*/
|
|
172
|
+
export function verifyLedger(projectRoot, onDiskHead) {
|
|
173
|
+
const anchor = readAnchor(projectRoot);
|
|
174
|
+
if (!anchor) {
|
|
175
|
+
return {
|
|
176
|
+
state: 'unanchored',
|
|
177
|
+
detail: 'ledger not yet anchored — the first grant/renew/revoke records the trust anchor',
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
if (anchor.ledgerHead === onDiskHead)
|
|
181
|
+
return { state: 'ok', detail: '' };
|
|
182
|
+
return {
|
|
183
|
+
state: 'mismatch',
|
|
184
|
+
detail: `ledger does not match its trust anchor (anchored ${anchor.updatedAt} by ${anchor.updatedBy}) — it was changed outside a recorded consent operation`,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=sandbox-anchor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-anchor.js","sourceRoot":"","sources":["../../src/policies/sandbox-anchor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-session sandbox grants (the D2 consent ledger).
|
|
3
|
+
*
|
|
4
|
+
* `uap sandbox` is all-or-nothing authority: the workdir + scratch are
|
|
5
|
+
* writable, everything else is EROFS. That default is right, but real work
|
|
6
|
+
* sometimes needs one more hole (a config dir, a build cache outside the
|
|
7
|
+
* tree) — and the legacy answer, `UAP_SANDBOX_ALLOW=path:path`, was
|
|
8
|
+
* UNRECORDED authority: an env var nobody audited, invisible to the
|
|
9
|
+
* operator, surviving in shell histories and hook templates forever.
|
|
10
|
+
*
|
|
11
|
+
* This ledger is the fix: every extra hole is a GRANT — bounded by a
|
|
12
|
+
* session, a TTL, and a stated reason, recorded with who consented, and
|
|
13
|
+
* audit-logged on use. "Every new authority must state who consented"
|
|
14
|
+
* (ADR 0011, the P4 bar).
|
|
15
|
+
*
|
|
16
|
+
* Design rules (inherited from the attention-queue store, review-hardened):
|
|
17
|
+
* - the ledger is shared-write state in `.uap/`, so every string is
|
|
18
|
+
* sanitized at INGEST and the load path re-applies the same sanitizer —
|
|
19
|
+
* a planted row must not become a kernel-writable hole or reach
|
|
20
|
+
* operator terminals;
|
|
21
|
+
* - atomic writes with unique tmp names (no fixed `.tmp` in shared dirs);
|
|
22
|
+
* - corrupt/unreadable ledger ⇒ EMPTY ledger: the safe direction for an
|
|
23
|
+
* authority store is least authority (the sandbox itself stays the real
|
|
24
|
+
* kernel boundary — a lost grant just means EROFS, not a breach);
|
|
25
|
+
* - every grant expires (default 8h, hard cap 7d): authority is bounded
|
|
26
|
+
* by construction, and revocation is a single command;
|
|
27
|
+
* - fail-OPEN for the sandbox, fail-CLOSED for the holes: load problems
|
|
28
|
+
* never crash a sandboxed run, they just yield no holes.
|
|
29
|
+
*/
|
|
30
|
+
import type { Verification } from './sandbox-anchor.js';
|
|
31
|
+
/** Audit-log retention: the trail is append-only history, but an unbounded
|
|
32
|
+
* JSONL under the shared-write `.uap/` grows forever — past
|
|
33
|
+
* the trigger it is compacted to the newest AUDIT_MAX_LINES event lines
|
|
34
|
+
* (plus the triggering event and one `audit-compaction` marker), so the
|
|
35
|
+
* file lands at AUDIT_MAX_LINES + 2. The compaction is itself audited, so
|
|
36
|
+
* a pruned trail is an EXPECTED state, never a silent one. */
|
|
37
|
+
export declare const AUDIT_MAX_LINES = 10000;
|
|
38
|
+
export declare const AUDIT_PRUNE_TRIGGER = 12000;
|
|
39
|
+
/** One consented extra authority for one session. */
|
|
40
|
+
export interface SandboxGrant {
|
|
41
|
+
id: string;
|
|
42
|
+
/** Session this grant is scoped to (UAP_SESSION_ID / --session). */
|
|
43
|
+
sessionId: string;
|
|
44
|
+
/** Absolute paths made writable inside the sandbox for this session. */
|
|
45
|
+
paths: string[];
|
|
46
|
+
/** WHY — operator-facing, required. Empty reason = refused at ingest. */
|
|
47
|
+
reason: string;
|
|
48
|
+
/** Who consented (username at grant time). */
|
|
49
|
+
grantedBy: string;
|
|
50
|
+
grantedAt: string;
|
|
51
|
+
/** ISO timestamp after which the grant is inert (hard-bounded). */
|
|
52
|
+
expiresAt: string;
|
|
53
|
+
}
|
|
54
|
+
export interface GrantInput {
|
|
55
|
+
sessionId: string;
|
|
56
|
+
paths: string[];
|
|
57
|
+
reason: string;
|
|
58
|
+
ttlSecs?: number;
|
|
59
|
+
}
|
|
60
|
+
/** A session's resolved, ACTIVE authority. */
|
|
61
|
+
export interface ResolvedGrants {
|
|
62
|
+
grants: SandboxGrant[];
|
|
63
|
+
paths: string[];
|
|
64
|
+
}
|
|
65
|
+
/** Default grant TTL: 8h — long enough for a working session, short enough
|
|
66
|
+
* that a forgotten hole closes itself before the next one. */
|
|
67
|
+
export declare const DEFAULT_GRANT_TTL_SECS = 28800;
|
|
68
|
+
/** Hard cap on grant TTL: authority must be re-consented weekly at most. */
|
|
69
|
+
export declare const MAX_GRANT_TTL_SECS = 604800;
|
|
70
|
+
/** Paths per grant cap: a grant is a scoped exception, not a hole list. */
|
|
71
|
+
export declare const MAX_PATHS_PER_GRANT = 8;
|
|
72
|
+
/**
|
|
73
|
+
* Ledger file: `<mainCheckoutRoot>/.uap/sandbox-grants.json` — ONE ledger
|
|
74
|
+
* per checkout, not per cwd, anchored at the main checkout root like the
|
|
75
|
+
* attention queue (ADR 0010): the CLI can be invoked from any worktree
|
|
76
|
+
* subdir, and a per-cwd ledger would give the same session different
|
|
77
|
+
* authority depending on where the operator happened to stand. Today the
|
|
78
|
+
* CLI is the only consumer; the anchoring also keeps a future dashboard
|
|
79
|
+
* grants view (a natural P5 surface) reading the same file.
|
|
80
|
+
* `UAP_SANDBOX_GRANTS` pins an explicit file (tests, odd layouts).
|
|
81
|
+
*/
|
|
82
|
+
export declare function sandboxGrantsPath(projectRoot: string): string;
|
|
83
|
+
/** Audit trail: append-only JSONL, one line per grant/revoke/sandbox-use. */
|
|
84
|
+
export declare function sandboxAuditPath(projectRoot: string): string;
|
|
85
|
+
/**
|
|
86
|
+
* A grantable path must be ABSOLUTE, must exist (you grant a real hole, not
|
|
87
|
+
* a speculative one), and must not be an over-broad root — checked AFTER
|
|
88
|
+
* symlink resolution: `/tmp/link -> $HOME` passes a string-only refusal and
|
|
89
|
+
* bwrap's `--bind` follows the link, so the check that matters is against
|
|
90
|
+
* the REALPATH (`/`, `/home`, $HOME itself — the same refusal the sandbox
|
|
91
|
+
* applies to a too-broad workdir: an over-broad grant IS a sandbox escape).
|
|
92
|
+
* Returns the RESOLVED path (what the bind will actually target), or null.
|
|
93
|
+
*/
|
|
94
|
+
export declare function validateGrantPath(p: string): string | null;
|
|
95
|
+
/** Verify the SANITIZED on-disk ledger against the out-of-checkout anchor.
|
|
96
|
+
* 'unanchored' is the pre-bootstrap state, not a failure. When `grants` is
|
|
97
|
+
* passed (an already-loaded sanitized snapshot), the SAME snapshot is
|
|
98
|
+
* verified and then acted on — the torn-read fix (a review finding):
|
|
99
|
+
* loading the file twice left a window where the hash saw one state and
|
|
100
|
+
* the resolver acted on another. */
|
|
101
|
+
export declare function verifyLedgerIntegrity(projectRoot: string, grants?: SandboxGrant[]): Verification;
|
|
102
|
+
/** Create a grant. Returns the grant, or a refusal reason. */
|
|
103
|
+
export declare function grantAuthority(projectRoot: string, input: GrantInput): {
|
|
104
|
+
ok: true;
|
|
105
|
+
grant: SandboxGrant;
|
|
106
|
+
} | {
|
|
107
|
+
ok: false;
|
|
108
|
+
error: string;
|
|
109
|
+
};
|
|
110
|
+
/** List grants, optionally scoped to one session. Expired rows are inert. */
|
|
111
|
+
export declare function listAuthority(projectRoot: string, sessionId?: string): SandboxGrant[];
|
|
112
|
+
/** Revoke one grant by id. Returns true only when it was found AND removed
|
|
113
|
+
* from the ledger — a failed persist leaves the grant active, and reporting
|
|
114
|
+
* success over a live grant would be a false consent record. */
|
|
115
|
+
export declare function revokeAuthority(projectRoot: string, grantId: string): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Resolve the ACTIVE authority for a session — what `uap sandbox` will
|
|
118
|
+
* actually open. Expired or malformed rows are invisible here; the sandbox
|
|
119
|
+
* never has to reason about them.
|
|
120
|
+
*/
|
|
121
|
+
export declare function resolveSessionGrants(projectRoot: string, sessionId: string): ResolvedGrants;
|
|
122
|
+
/** Record that a sandbox run USED its grants (the "who consented, when used" line).
|
|
123
|
+
* `netMode` is the network mode the run ACTUALLY engaged ('off' = the kernel
|
|
124
|
+
* egress boundary): the audit line is the consent record, so it must state
|
|
125
|
+
* the boundary that was really on. The legacy-env record states what the
|
|
126
|
+
* run actually OPENED (`legacyBound`, the resolved targets that were bound)
|
|
127
|
+
* separately from what plan time REFUSED (`legacyRefused`) — recording a
|
|
128
|
+
* refused entry as the run's allow would attribute authority the run never
|
|
129
|
+
* had, and the durable record must agree with the launch banner. */
|
|
130
|
+
export declare function auditSandboxUse(projectRoot: string, sessionId: string, used: ResolvedGrants, legacyBound: string[], legacyRefused: string[], netMode: 'shared' | 'off'): void;
|
|
131
|
+
//# sourceMappingURL=sandbox-grants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-grants.d.ts","sourceRoot":"","sources":["../../src/policies/sandbox-grants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAQH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;;;+DAK+D;AAC/D,eAAO,MAAM,eAAe,QAAS,CAAC;AACtC,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAE1C,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,8CAA8C;AAC9C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;+DAC+D;AAC/D,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAC7C,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,SAAU,CAAC;AAC1C,2EAA2E;AAC3E,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAI7D;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAI5D;AAeD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY1D;AAyMD;;;;;qCAKqC;AACrC,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,EAAE,GAAG,YAAY,CAGhG;AAmCD,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAiHvI;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAIrF;AAED;;iEAEiE;AACjE,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CA+B7E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,cAAc,CA+B3F;AAED;;;;;;;qEAOqE;AACrE,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,cAAc,EACpB,WAAW,EAAE,MAAM,EAAE,EACrB,aAAa,EAAE,MAAM,EAAE,EACvB,OAAO,EAAE,QAAQ,GAAG,KAAK,GACxB,IAAI,CAeN"}
|