@scopebond/hook 0.15.2 → 0.16.0
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 +9 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +31 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/managed.d.ts +16 -1
- package/dist/managed.d.ts.map +1 -1
- package/dist/managed.js +29 -6
- package/dist/managed.js.map +1 -1
- package/dist/override.d.ts +51 -0
- package/dist/override.d.ts.map +1 -0
- package/dist/override.js +193 -0
- package/dist/override.js.map +1 -0
- package/dist/runtime.d.ts +9 -2
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +12 -3
- package/dist/runtime.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -15,8 +15,10 @@ export type { Manifest, CapabilityCell, CapabilityState, ProofRecord, HostVarian
|
|
|
15
15
|
export { runProofFixtures, deliverProofReceipts, loadProofs, saveProofs, PROOF_FILE } from "./proof.js";
|
|
16
16
|
export { inspectBudgetExport, loadBudgetExport, localBudgetOf, BUDGET_EXPORT_TYPE } from "./budget-load.js";
|
|
17
17
|
export { inspectExport, loadPolicyExport, policyScopeDigest, policyBuilds, POLICY_SCOPE_DOMAIN, LOADED_POLICY_FILE } from "./policy-load.js";
|
|
18
|
-
export { inspectManaged, compileManaged, installManaged, restoreLocal, isManaged, readMeta, digestRules, MANAGED_RULE_IDS, MANAGED_DOC_FILE, MANAGED_META_FILE, } from "./managed.js";
|
|
19
|
-
export type { ManagedDocument, ManagedRule, ManagedMeta, RefusalReason } from "./managed.js";
|
|
18
|
+
export { inspectManaged, compileManaged, installManaged, restoreLocal, isManaged, readMeta, digestRules, MANAGED_RULE_IDS, MANAGED_DOC_FILE, MANAGED_META_FILE, RULE_OF_CLAUSE, floorDocument, } from "./managed.js";
|
|
19
|
+
export type { ManagedDocument, ManagedRule, ManagedMeta, RefusalReason, OverrideTerms } from "./managed.js";
|
|
20
|
+
export { createOverrideHandler, overrideHint, askAgent, actionSummary, digestOf, PROMPTING_MODES, OVERRIDE_STATE_FILE } from "./override.js";
|
|
21
|
+
export type { OverrideContext, OverrideNote, AgentAnswer } from "./override.js";
|
|
20
22
|
export { syncPolicy, syncIfDue, SYNC_INTERVAL_MS, INLINE_BUDGET_MS } from "./policy-sync.js";
|
|
21
23
|
export type { SyncOutcome, SyncOptions } from "./policy-sync.js";
|
|
22
24
|
export { VECTORS, mapVector } from "./vectors.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC7F,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACtF,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EACL,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,GAC/F,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC/E,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC1D,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAClJ,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtH,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACxI,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxG,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC7I,OAAO,EACL,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAC9F,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,8 @@ export { computeManifest, renderManifest, cellState, cellKey, vectorsForCell, ve
|
|
|
12
12
|
export { runProofFixtures, deliverProofReceipts, loadProofs, saveProofs, PROOF_FILE } from "./proof.js";
|
|
13
13
|
export { inspectBudgetExport, loadBudgetExport, localBudgetOf, BUDGET_EXPORT_TYPE } from "./budget-load.js";
|
|
14
14
|
export { inspectExport, loadPolicyExport, policyScopeDigest, policyBuilds, POLICY_SCOPE_DOMAIN, LOADED_POLICY_FILE } from "./policy-load.js";
|
|
15
|
-
export { inspectManaged, compileManaged, installManaged, restoreLocal, isManaged, readMeta, digestRules, MANAGED_RULE_IDS, MANAGED_DOC_FILE, MANAGED_META_FILE, } from "./managed.js";
|
|
15
|
+
export { inspectManaged, compileManaged, installManaged, restoreLocal, isManaged, readMeta, digestRules, MANAGED_RULE_IDS, MANAGED_DOC_FILE, MANAGED_META_FILE, RULE_OF_CLAUSE, floorDocument, } from "./managed.js";
|
|
16
|
+
export { createOverrideHandler, overrideHint, askAgent, actionSummary, digestOf, PROMPTING_MODES, OVERRIDE_STATE_FILE } from "./override.js";
|
|
16
17
|
export { syncPolicy, syncIfDue, SYNC_INTERVAL_MS, INLINE_BUDGET_MS } from "./policy-sync.js";
|
|
17
18
|
export { VECTORS, mapVector } from "./vectors.js";
|
|
18
19
|
export { scaffold, harnessSnippet, installHarness, placeHook } from "./init.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,4EAA4E;AAC5E,gDAAgD;AAEhD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE7F,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEtF,OAAO,EACL,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,GAC/F,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAClJ,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtH,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxG,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC7I,OAAO,EACL,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAC9F,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,4EAA4E;AAC5E,gDAAgD;AAEhD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE7F,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEtF,OAAO,EACL,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,GAC/F,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAClJ,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtH,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxG,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC7I,OAAO,EACL,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAC9F,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,GACrF,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAE7I,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAE7F,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEhF,OAAO,EACL,QAAQ,EAAE,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,mBAAmB,EACxG,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,SAAS,EAClF,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EACpG,aAAa,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,mBAAmB,EAC7E,sBAAsB,EAAE,mBAAmB,EAC3C,gBAAgB,EAAE,wBAAwB,EAAE,aAAa,EAAE,cAAc,EAAE,mBAAmB,GAC/F,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEvE,OAAO,EACL,oBAAoB,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,GACpG,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEnH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC1I,OAAO,EACL,WAAW,EAAE,eAAe,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,YAAY,EAClH,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,YAAY,EACxG,sBAAsB,EAAE,qBAAqB,EAAE,eAAe,EAAE,oBAAoB,GACrF,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACrI,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EACL,qBAAqB,EAAE,UAAU,EAAE,aAAa,EAAE,kBAAkB,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,SAAS,EAAE,OAAO,GACtM,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE1J,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,sGAAsG;AACtG,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/I,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAElE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACxF,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC","sourcesContent":["// @scopebond/hook — the Claude Code, Cursor + Codex connector. The library surface is\n// the deterministic mapper and the check-only runtime; the `scopebond-hook`\n// binary is the thin harness adapter over them.\n\nexport { mapClaudeToolUse, mapCodexToolUse, mapCursorEvent, fillPushBranch } from \"./map.js\";\nexport type { Mapped, NormalizedIntent } from \"./map.js\";\nexport { createHookRuntime, starterPolicy, upgradeStarterPolicy } from \"./runtime.js\";\nexport type { RuntimeConfig, Decision } from \"./runtime.js\";\nexport {\n compile, defaultRules, describeRules, loadRules, saveRules, rulesPath, pathRuleFor, RULES_FILE,\n} from \"./rules.js\";\nexport type { RuleSet, PathRule } from \"./rules.js\";\nexport { pathRuleMatches, isDestructiveProgram, isProtectedBranch } from \"./rules.js\";\nexport { classifyIntent, classificationBlocks, BLOCKING } from \"./classify.js\";\nexport type { CatalogId, Classification } from \"./classify.js\";\nexport { classifyRoot, applyRootScope } from \"./paths.js\";\nexport type { RootScope, RootOptions } from \"./paths.js\";\nexport { actionGroupId, withActionGroup, distinctTargets, ACTION_GROUP_PARAM, ACTION_GROUP_SIZE_PARAM, ACTION_GROUP_SEQ_PARAM } from \"./group.js\";\nexport { computeManifest, renderManifest, cellState, cellKey, vectorsForCell, vectorDigest } from \"./capabilities.js\";\nexport type { Manifest, CapabilityCell, CapabilityState, ProofRecord, HostVariant, EventPhase, ManifestInput } from \"./capabilities.js\";\nexport { runProofFixtures, deliverProofReceipts, loadProofs, saveProofs, PROOF_FILE } from \"./proof.js\";\nexport { inspectBudgetExport, loadBudgetExport, localBudgetOf, BUDGET_EXPORT_TYPE } from \"./budget-load.js\";\nexport { inspectExport, loadPolicyExport, policyScopeDigest, policyBuilds, POLICY_SCOPE_DOMAIN, LOADED_POLICY_FILE } from \"./policy-load.js\";\nexport {\n inspectManaged, compileManaged, installManaged, restoreLocal, isManaged, readMeta, digestRules,\n MANAGED_RULE_IDS, MANAGED_DOC_FILE, MANAGED_META_FILE, RULE_OF_CLAUSE, floorDocument,\n} from \"./managed.js\";\nexport type { ManagedDocument, ManagedRule, ManagedMeta, RefusalReason, OverrideTerms } from \"./managed.js\";\nexport { createOverrideHandler, overrideHint, askAgent, actionSummary, digestOf, PROMPTING_MODES, OVERRIDE_STATE_FILE } from \"./override.js\";\nexport type { OverrideContext, OverrideNote, AgentAnswer } from \"./override.js\";\nexport { syncPolicy, syncIfDue, SYNC_INTERVAL_MS, INLINE_BUDGET_MS } from \"./policy-sync.js\";\nexport type { SyncOutcome, SyncOptions } from \"./policy-sync.js\";\nexport { VECTORS, mapVector } from \"./vectors.js\";\nexport type { Vector, VectorAgent, Dialect } from \"./vectors.js\";\nexport { scaffold, harnessSnippet, installHarness, placeHook } from \"./init.js\";\nexport type { HookPlacement } from \"./init.js\";\nexport {\n userHome, userHarnessFile, projectHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig,\n cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome,\n readHarnessConfig, trustProjectPolicy, isTrustedProject, untrustedProjectPolicy, trustedProjectsFile,\n harnessScopes, harnessScopeLabel, configuredHookCommands, hookCommandResolves,\n isScopebondHookCommand, harnessEntryMatches,\n localHarnessFile, isMachineSpecificCommand, gitShareState, excludeFromGit, pruneHarnessEntries,\n} from \"./install.js\";\nexport type { Harness, HarnessScopes, GitShare } from \"./install.js\";\nexport { explainDeny, describeAction, findClause } from \"./explain.js\";\nexport type { ExplainDenyInput, ExplainIntent, ExplainPolicy, ExplainClause } from \"./explain.js\";\nexport {\n ensureDurableRuntime, isEphemeralPath, nodeModulesRootOf, runtimeRoot, runtimeDirFor, pinnedCliPath,\n} from \"./runtime-install.js\";\nexport type { PinResult } from \"./runtime-install.js\";\nexport { connectCloud, ingestUrl, loadConnection, attachExporter, flushBounded, connectionPath } from \"./cloud.js\";\nexport type { HookConnection } from \"./cloud.js\";\nexport { scrubSecrets, scrubParam, redactCommand, digest, sha256, keyedDigest, useDigestKey, loadOrCreateDigestKey } from \"./minimize.js\";\nexport {\n AGENT_KINDS, assertAgentKind, observationSigner, signObservation, observationHash, sourceReceiptHash, signingBytes,\n buildPayload, buildOperation, operationsForCall, bindingKeyFromHex, loadOrCreateBindingKey, digestPolicy,\n REQUEST_BINDING_DOMAIN, MAX_OBSERVATION_BYTES, MAX_BATCH_ITEMS, MAX_BATCH_BODY_BYTES,\n} from \"./observation.js\";\nexport type { ObservationPayload, SignedObservation, ObservationSigner, BindingKey, AgentKind } from \"./observation.js\";\nexport { ObservationStore, OBSERVATION_DB } from \"./obs-store.js\";\nexport { uploadPending, parseRetryAfter, OBSERVATIONS_PATH } from \"./obs-upload.js\";\nexport { openObservations, observationStatus, describeObservations, ObservationEmitter, OBSERVATIONS_SCOPE } from \"./obs-emitter.js\";\nexport { wireLifecycleHooks, unwireLifecycleHooks } from \"./install.js\";\nexport {\n deriveTypedOperations, keyedIdFor, callRequestOf, TYPED_ACTION_TYPES, fixtureProbe, gitPushOperation, githubOperation, packageOperation, parseGh, parseGithubMcp, normalizeRemote, systemGit, UNBOUND,\n} from \"./typed-ops.js\";\nexport type { CallRequest, GitProbe, TypedContext, GithubRepo, GithubRequest, DeriveInput } from \"./typed-ops.js\";\nexport { deriveInfraOperation, databaseFacts, databaseGuardActions, parseDestination, fetchOperation, systemFiles, fixtureFiles } from \"./typed-infra.js\";\nexport type { FileProbe, InfraContext, ReadContext, DatabaseFacts, DatabaseGuardAction } from \"./typed-infra.js\";\nexport { classifySql } from \"./sql-classify.js\";\nexport type { SqlClass, SqlVerb } from \"./sql-classify.js\";\n// Delivery, status and identity pieces the Scopebond Agent reuses (one implementation, one contract).\nexport { readDeliveryState, writeDeliveryState, recordDeliveryAttempt, recordRulesCredential, DELIVERY_STATE_FILE } from \"./delivery-state.js\";\nexport type { DeliveryState } from \"./delivery-state.js\";\nexport { describeDelivery, queueStatus, LOSSLESS_OUTBOX, OUTBOX_FILE } from \"./delivery-report.js\";\nexport { buildStatusJson, STATUS_SCHEMA } from \"./status-json.js\";\nexport type { StatusJson } from \"./status-json.js\";\nexport { refreshIfDue, refreshProof, REFRESH_WINDOW_MS } from \"./credential-refresh.js\";\nexport { hookVersion, hookCommand, cliCommand } from \"./version.js\";\n"]}
|
package/dist/managed.d.ts
CHANGED
|
@@ -6,9 +6,24 @@ export declare const MANAGED_RULE_IDS: readonly ["force-push-protected", "push-p
|
|
|
6
6
|
export type ManagedRuleId = (typeof MANAGED_RULE_IDS)[number];
|
|
7
7
|
type ListKey = "protected_branches" | "destructive_programs" | "allowed_hosts";
|
|
8
8
|
type ExclusionKey = "excluded_paths" | "excluded_branches";
|
|
9
|
+
/** What the computer enforces for a rule set to "Block, user may override": the shortest reason accepted, how long one override
|
|
10
|
+
* lasts (0 = this action only), how many a person may make per rule per day, and whether the coding agent's own prompt may be
|
|
11
|
+
* used when the Scopebond window is not available. Who may override is the workspace's decision: it sends "override" only then. */
|
|
12
|
+
export interface OverrideTerms {
|
|
13
|
+
reason_min: number;
|
|
14
|
+
minutes: number;
|
|
15
|
+
daily_limit: number;
|
|
16
|
+
harness_prompt: boolean;
|
|
17
|
+
}
|
|
9
18
|
export type ManagedRule = {
|
|
10
|
-
mode: "monitor" | "block";
|
|
19
|
+
mode: "monitor" | "block" | "override";
|
|
20
|
+
override?: OverrideTerms;
|
|
11
21
|
} & Partial<Record<ListKey | ExclusionKey, string[]>>;
|
|
22
|
+
/** The clause that carries each workspace rule on the computer, for naming the rule a denial came from. */
|
|
23
|
+
export declare const RULE_OF_CLAUSE: Readonly<Record<string, ManagedRuleId>>;
|
|
24
|
+
/** The same document with every overridable rule recorded instead of blocked: what still denies under it is never overridable
|
|
25
|
+
* (another rule on Block, or Scopebond's own floor). */
|
|
26
|
+
export declare function floorDocument(doc: ManagedDocument): ManagedDocument;
|
|
12
27
|
export interface ManagedDocument {
|
|
13
28
|
type: "scopebond:managed-rules";
|
|
14
29
|
version: 1;
|
package/dist/managed.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed.d.ts","sourceRoot":"","sources":["../src/managed.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAoC,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5E,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AACrD,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AACrD,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D,eAAO,MAAM,gBAAgB,8HAA+H,CAAC;AAC7J,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC9D,KAAK,OAAO,GAAG,oBAAoB,GAAG,sBAAsB,GAAG,eAAe,CAAC;AAC/E,KAAK,YAAY,GAAG,gBAAgB,GAAG,mBAAmB,CAAC;AAuB3D,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"managed.d.ts","sourceRoot":"","sources":["../src/managed.ts"],"names":[],"mappings":"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"}
|
package/dist/managed.js
CHANGED
|
@@ -48,6 +48,27 @@ const EXCLUSION_PATTERN = {
|
|
|
48
48
|
};
|
|
49
49
|
const HEX64 = /^[0-9a-f]{64}$/;
|
|
50
50
|
const OPAQUE = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
51
|
+
const intIn = (v, min, max) => Number.isInteger(v) && v >= min && v <= max;
|
|
52
|
+
function validTerms(t) {
|
|
53
|
+
return isObject(t) && Object.keys(t).length === 4 && intIn(t.reason_min, 10, 200) && intIn(t.minutes, 0, 60) && intIn(t.daily_limit, 1, 50)
|
|
54
|
+
&& typeof t.harness_prompt === "boolean";
|
|
55
|
+
}
|
|
56
|
+
/** The clause that carries each workspace rule on the computer, for naming the rule a denial came from. */
|
|
57
|
+
export const RULE_OF_CLAUSE = {
|
|
58
|
+
"protect-branches": "push-protected", "protect-branch-history": "force-push-protected", "safe-shell": "destructive-shell",
|
|
59
|
+
"protect-read": "secret-read", "protect-write": "ci-config-write", "allowed-sites": "network-egress",
|
|
60
|
+
};
|
|
61
|
+
/** The same document with every overridable rule recorded instead of blocked: what still denies under it is never overridable
|
|
62
|
+
* (another rule on Block, or Scopebond's own floor). */
|
|
63
|
+
export function floorDocument(doc) {
|
|
64
|
+
const rules = Object.fromEntries(Object.entries(doc.rules).map(([id, rule]) => {
|
|
65
|
+
if (rule.mode !== "override")
|
|
66
|
+
return [id, rule];
|
|
67
|
+
const { override: _terms, excluded_paths: _p, excluded_branches: _b, ...rest } = rule;
|
|
68
|
+
return [id, { ...rest, mode: "monitor" }];
|
|
69
|
+
}));
|
|
70
|
+
return { ...doc, rules };
|
|
71
|
+
}
|
|
51
72
|
export const digestRules = (rules) => createHash("sha256").update(canonical(rules)).digest("hex");
|
|
52
73
|
const isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
53
74
|
/** Check a document from the workspace without touching disk. Pure. */
|
|
@@ -73,10 +94,12 @@ export function inspectManaged(raw, context) {
|
|
|
73
94
|
}
|
|
74
95
|
for (const id of MANAGED_RULE_IDS) {
|
|
75
96
|
const rule = rules[id];
|
|
76
|
-
if (!isObject(rule) || (rule.mode !== "monitor" && rule.mode !== "block"))
|
|
97
|
+
if (!isObject(rule) || (rule.mode !== "monitor" && rule.mode !== "block" && rule.mode !== "override"))
|
|
77
98
|
return bad(`rule ${id} has no valid mode`);
|
|
99
|
+
if ((rule.mode === "override") !== ("override" in rule) || (rule.mode === "override" && !validTerms(rule.override)))
|
|
100
|
+
return bad(`rule ${id} has invalid override terms`);
|
|
78
101
|
for (const key of Object.keys(rule)) {
|
|
79
|
-
if (key === "mode")
|
|
102
|
+
if (key === "mode" || key === "override")
|
|
80
103
|
continue;
|
|
81
104
|
const listKey = LIST_OF[id];
|
|
82
105
|
const exclusionKey = EXCLUSIONS_OF[id];
|
|
@@ -90,7 +113,7 @@ export function inspectManaged(raw, context) {
|
|
|
90
113
|
}
|
|
91
114
|
}
|
|
92
115
|
const network = rules["network-egress"];
|
|
93
|
-
if (network.mode
|
|
116
|
+
if (network.mode !== "monitor" && !(network.allowed_hosts?.length))
|
|
94
117
|
return bad("network blocking needs at least one allowed site");
|
|
95
118
|
if (digestRules(rules) !== rulesDigest)
|
|
96
119
|
return bad("the rules do not match their digest; the document was changed or damaged");
|
|
@@ -132,7 +155,7 @@ export function compileManaged(local, doc, agentKid) {
|
|
|
132
155
|
for (const clause of policy.clauses) {
|
|
133
156
|
if (clause.id === "protect-branches" && r["push-protected"].mode === "monitor") {
|
|
134
157
|
clauses.push(allowAll(clause));
|
|
135
|
-
if (r["force-push-protected"].mode
|
|
158
|
+
if (r["force-push-protected"].mode !== "monitor") {
|
|
136
159
|
clauses.push({ id: "protect-branch-history", type: "force_push_guard", mode: "enforce", protected_refs: rules.protected_branches.map(branchGlob),
|
|
137
160
|
description: "Deny force-pushes, deletions and mirror pushes that reach a protected branch; ordinary pushes are allowed. Set by your workspace." });
|
|
138
161
|
}
|
|
@@ -156,7 +179,7 @@ export function compileManaged(local, doc, agentKid) {
|
|
|
156
179
|
else if (clause.id === "protect-branches" && r["push-protected"].excluded_branches?.length) {
|
|
157
180
|
clauses.push(withBound(clause, "ref", withBranchExclusions(boundPattern(clause, "ref"), r["push-protected"].excluded_branches)));
|
|
158
181
|
// Skipping ordinary pushes to a branch never skips history protection: force-pushes, deletions and mirror pushes stay stopped.
|
|
159
|
-
if (r["force-push-protected"].mode
|
|
182
|
+
if (r["force-push-protected"].mode !== "monitor") {
|
|
160
183
|
clauses.push({ id: "protect-branch-history", type: "force_push_guard", mode: "enforce", protected_refs: rules.protected_branches.map(branchGlob),
|
|
161
184
|
description: "Deny force-pushes, deletions and mirror pushes that reach a protected branch. Set by your workspace." });
|
|
162
185
|
}
|
|
@@ -164,7 +187,7 @@ export function compileManaged(local, doc, agentKid) {
|
|
|
164
187
|
else
|
|
165
188
|
clauses.push(clause);
|
|
166
189
|
}
|
|
167
|
-
if (r["network-egress"].mode
|
|
190
|
+
if (r["network-egress"].mode !== "monitor") {
|
|
168
191
|
const keysAt = clauses.findIndex((c) => c.id === "keys");
|
|
169
192
|
clauses.splice(keysAt < 0 ? clauses.length : keysAt, 0, {
|
|
170
193
|
id: "allowed-sites", type: "action_allowlist", mode: "enforce", action_types: ["net.fetch"],
|
package/dist/managed.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed.js","sourceRoot":"","sources":["../src/managed.ts"],"names":[],"mappings":"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","sourcesContent":["// Rules managed from a Scopebond Cloud workspace.\n//\n// A connected computer keeps its own rules (`rules.json` compiled into `policy.json`) until the workspace sets rules for it.\n// From then on the workspace decides, rule by rule, whether a matching action is blocked or only recorded, and may add entries\n// to the computer's own lists (protected branches, programs, allowed sites). It never sends a pattern: this module compiles the\n// workspace's choices with the same compiler `rules apply` uses, so what decides a block lives in one place.\n//\n// A workspace may also name exact targets one rule skips: paths for the secret-read and CI-configuration rules, branches for the\n// push rule. An exclusion matches exactly (same case; a trailing `/**` covers a folder), so it is never broader than what was typed,\n// and an exclusion that would touch the always-on protection of the hook's own settings is dropped when the policy is compiled.\n//\n// What a workspace cannot change: the protection of the hook's own settings (and the settings of the agents it guards), the\n// machine key policy, fail-closed handling of anything unparseable, and the computer's own opt-in extras (`allowed_roots`,\n// `protect_remote_database`). A rule set to Monitor is still covered by an allow clause, so the action is recorded and passes;\n// leaving it out would block the whole action type, because the verifier denies an action no clause covers.\n//\n// Loading is checked and atomic: the document must be well formed, name this computer, carry a matching digest and be newer\n// than the one in force; the merged policy must build; policy.json is written through a temp file and a rename, the previous\n// one kept. Disconnecting, or a workspace that stops managing this computer, restores the computer's own rules.\n\nimport { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { canonical } from \"@scopebond/policy-schema/canonical\";\nimport { GUARDRAIL_LOOKAHEADS, GUARDRAIL_READ_PATTERN, GUARDRAIL_WRITE_PATTERN, ci } from \"./runtime.js\";\nimport { compile, defaultRules, loadRules, type RuleSet } from \"./rules.js\";\n\nexport const MANAGED_DOC_FILE = \"managed-rules.json\";\nexport const MANAGED_META_FILE = \"managed-meta.json\";\nexport const PREVIOUS_POLICY_FILE = \"policy.previous.json\";\n\nexport const MANAGED_RULE_IDS = [\"force-push-protected\", \"push-protected\", \"destructive-shell\", \"secret-read\", \"ci-config-write\", \"network-egress\"] as const;\nexport type ManagedRuleId = (typeof MANAGED_RULE_IDS)[number];\ntype ListKey = \"protected_branches\" | \"destructive_programs\" | \"allowed_hosts\";\ntype ExclusionKey = \"excluded_paths\" | \"excluded_branches\";\nconst LIST_OF: Partial<Record<ManagedRuleId, ListKey>> = {\n \"force-push-protected\": \"protected_branches\", \"push-protected\": \"protected_branches\",\n \"destructive-shell\": \"destructive_programs\", \"network-egress\": \"allowed_hosts\",\n};\nconst LIST_PATTERN: Record<ListKey, RegExp> = {\n protected_branches: /^[A-Za-z0-9._/*-]{1,100}$/,\n destructive_programs: /^[a-z0-9][a-z0-9._-]{0,63}$/,\n allowed_hosts: /^(?=.{1,253}$)(\\*\\.)?([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]{2,63}$/,\n};\n/** The exact targets a rule may skip, and the one list each rule accepts. */\nconst EXCLUSIONS_OF: Partial<Record<ManagedRuleId, ExclusionKey>> = {\n \"secret-read\": \"excluded_paths\", \"ci-config-write\": \"excluded_paths\", \"push-protected\": \"excluded_branches\",\n};\nconst EXCLUSION_PATTERN: Record<ExclusionKey, RegExp> = {\n // A relative path with forward slashes: no empty, \".\" or \"..\" segment, optionally ending in /** for a folder.\n excluded_paths: /^(?!\\/)(?!.*\\/\\/)(?!(?:.*\\/)?\\.{1,2}(?:\\/|$))[A-Za-z0-9._@+-][A-Za-z0-9._@+/-]{0,199}?(?:\\/\\*\\*)?$/,\n // One exact branch name; it starts with a letter or digit, so it can never be a push flag such as --all.\n excluded_branches: /^[A-Za-z0-9][A-Za-z0-9._/-]{0,99}$/,\n};\nconst HEX64 = /^[0-9a-f]{64}$/;\nconst OPAQUE = /^[A-Za-z0-9._:-]{1,128}$/;\n\nexport type ManagedRule = { mode: \"monitor\" | \"block\" } & Partial<Record<ListKey | ExclusionKey, string[]>>;\nexport interface ManagedDocument {\n type: \"scopebond:managed-rules\";\n version: 1;\n revision: number;\n export_id: string;\n environment_id: string;\n agent_id: string;\n installation_id: string;\n rules: Record<ManagedRuleId, ManagedRule>;\n rules_digest: string;\n}\n\nexport type RefusalReason = \"invalid_document\" | \"stale_revision\" | \"wrong_computer\" | \"unsupported\" | \"write_failed\";\nexport type Inspection = { ok: true; doc: ManagedDocument } | { ok: false; reason: RefusalReason; message: string };\n\nexport const digestRules = (rules: unknown): string => createHash(\"sha256\").update(canonical(rules)).digest(\"hex\");\n\nconst isObject = (v: unknown): v is Record<string, unknown> => typeof v === \"object\" && v !== null && !Array.isArray(v);\n\n/** Check a document from the workspace without touching disk. Pure. */\nexport function inspectManaged(raw: unknown, context: { installationId: string; currentRevision: number | null; currentDigest?: string | null }): Inspection {\n const bad = (message: string): Inspection => ({ ok: false, reason: \"invalid_document\", message });\n if (!isObject(raw) || raw.type !== \"scopebond:managed-rules\") return bad(\"this is not a Scopebond workspace rules document\");\n if (raw.version !== 1) return { ok: false, reason: \"unsupported\", message: `unsupported rules document version ${String(raw.version)}` };\n const { revision, export_id: exportId, environment_id: environmentId, agent_id: agentId, installation_id: installationId, rules, rules_digest: rulesDigest } = raw;\n if (!Number.isInteger(revision) || (revision as number) < 1 || (revision as number) > 2_147_483_647\n || typeof exportId !== \"string\" || typeof environmentId !== \"string\" || !OPAQUE.test(environmentId)\n || typeof agentId !== \"string\" || !OPAQUE.test(agentId) || typeof installationId !== \"string\" || !OPAQUE.test(installationId)\n || typeof rulesDigest !== \"string\" || !HEX64.test(rulesDigest) || !isObject(rules)) {\n return bad(\"the rules document is incomplete or malformed\");\n }\n if (installationId !== context.installationId || exportId !== `rev-${revision}-${installationId}`) {\n return { ok: false, reason: \"wrong_computer\", message: \"these rules were issued for a different computer\" };\n }\n const keys = Object.keys(rules);\n if (keys.length !== MANAGED_RULE_IDS.length || !MANAGED_RULE_IDS.every((id) => keys.includes(id))) {\n return { ok: false, reason: \"unsupported\", message: \"the rules document names rules this version does not know; update Scopebond\" };\n }\n for (const id of MANAGED_RULE_IDS) {\n const rule = rules[id];\n if (!isObject(rule) || (rule.mode !== \"monitor\" && rule.mode !== \"block\")) return bad(`rule ${id} has no valid mode`);\n for (const key of Object.keys(rule)) {\n if (key === \"mode\") continue;\n const listKey = LIST_OF[id];\n const exclusionKey = EXCLUSIONS_OF[id];\n const pattern = key === listKey ? LIST_PATTERN[listKey] : key === exclusionKey ? EXCLUSION_PATTERN[exclusionKey] : null;\n if (!pattern) return bad(`rule ${id} has an unknown setting`);\n const list = rule[key];\n if (!Array.isArray(list) || list.length > 50 || !list.every((v) => typeof v === \"string\" && pattern.test(v) && !v.includes(\"..\"))) {\n return bad(`rule ${id} has an invalid list`);\n }\n }\n }\n const network = rules[\"network-egress\"] as ManagedRule;\n if (network.mode === \"block\" && !(network.allowed_hosts?.length)) return bad(\"network blocking needs at least one allowed site\");\n if (digestRules(rules) !== rulesDigest) return bad(\"the rules do not match their digest; the document was changed or damaged\");\n // The same version with different rules is a newer document too: the workspace can change what reaches this computer without a new\n // version (an agent moved to another team, or this hook started reading a setting it did not read before). The export id binds it here.\n const sameVersionChanged = context.currentRevision !== null && revision === context.currentRevision && !!context.currentDigest && rulesDigest !== context.currentDigest;\n if (context.currentRevision !== null && (revision as number) <= context.currentRevision && !sameVersionChanged) {\n return { ok: false, reason: \"stale_revision\", message: `version ${String(revision)} is not newer than the version in force (${context.currentRevision})` };\n }\n return { ok: true, doc: raw as unknown as ManagedDocument };\n}\n\nconst union = (a: readonly string[], b: readonly string[] | undefined): string[] => [...new Set([...a, ...(b ?? [])])];\nconst branchGlob = (b: string): string => (b.endsWith(\"/*\") ? `${b.slice(0, -1)}**` : b);\nconst hostPattern = (hosts: readonly string[]): string =>\n `^(?:${hosts.map((h) => (h.startsWith(\"*.\") ? `(?:[^.]+\\\\.)+${ci(h.slice(2).replace(/\\./g, \"\\\\.\"))}` : ci(h.replace(/\\./g, \"\\\\.\")))).join(\"|\")})$`;\n\ntype Clause = Record<string, unknown> & { id: string };\n\nconst escapeRegex = (text: string): string => text.replace(/[\\\\^$.*+?()[\\]{}|/]/g, \"\\\\$&\");\n/** Exclusions that passed validation (the document check refuses the rest; this is a second line of defence). */\nconst safeExclusions = (paths: readonly string[] | undefined): string[] => (paths ?? []).filter((path) => EXCLUSION_PATTERN.excluded_paths.test(path) && !path.includes(\"..\"));\n/** An allow pattern that also allows exactly these paths (a trailing /** allows everything under the folder). The added alternative\n * carries the always-on floor and refuses any path with a \".\" or \"..\" segment, so no exclusion — however it is written — can reach\n * Scopebond's own settings or the agents' hook settings, or climb out of the folder it names. */\nconst withPathExclusions = (pattern: string, paths: readonly string[]): string => paths.length === 0 ? pattern\n : `^(?!(?:.*/)?\\\\.{1,2}(?:/|$))${GUARDRAIL_LOOKAHEADS}(?:${paths.map((p) => p.endsWith(\"/**\") ? `${escapeRegex(p.slice(0, -3))}/.+` : escapeRegex(p)).join(\"|\")})$|${pattern}`;\n/** An allow pattern for pushes that also allows exactly these branches. */\nconst withBranchExclusions = (pattern: string, branches: readonly string[]): string => branches.length === 0 ? pattern\n : `^(?:refs/heads/)?(?:${branches.map(escapeRegex).join(\"|\")})$|${pattern}`;\nconst boundPattern = (clause: Clause, key: string): string => String(((clause.param_bounds as Record<string, { pattern: string }> | undefined)?.[key])?.pattern ?? \"\");\nconst withBound = (clause: Clause, key: string, pattern: string): Clause => ({ ...clause, param_bounds: { ...(clause.param_bounds as Record<string, unknown>), [key]: { pattern } } });\n\n/** The policy this computer enforces under workspace rules: its own compiled rules, adjusted rule by rule. Pure. */\nexport function compileManaged(local: RuleSet, doc: ManagedDocument, agentKid: string): Record<string, unknown> {\n const r = doc.rules;\n const rules: RuleSet = {\n ...local,\n protected_branches: union(local.protected_branches, [...(r[\"push-protected\"].protected_branches ?? []), ...(r[\"force-push-protected\"].protected_branches ?? [])]),\n destructive_programs: union(local.destructive_programs, r[\"destructive-shell\"].destructive_programs),\n };\n const policy = compile(rules, agentKid) as { clauses: Clause[] } & Record<string, unknown>;\n const allowAll = (clause: Clause): Clause => { const { param_bounds: _dropped, ...rest } = clause; return { ...rest, mode: \"enforce\", description: `${String(clause.description ?? \"\").split(\".\")[0]}. Recorded, not blocked: set by your workspace.` }; };\n const clauses: Clause[] = [];\n for (const clause of policy.clauses) {\n if (clause.id === \"protect-branches\" && r[\"push-protected\"].mode === \"monitor\") {\n clauses.push(allowAll(clause));\n if (r[\"force-push-protected\"].mode === \"block\") {\n clauses.push({ id: \"protect-branch-history\", type: \"force_push_guard\", mode: \"enforce\", protected_refs: rules.protected_branches.map(branchGlob),\n description: \"Deny force-pushes, deletions and mirror pushes that reach a protected branch; ordinary pushes are allowed. Set by your workspace.\" });\n }\n } else if (clause.id === \"safe-shell\" && r[\"destructive-shell\"].mode === \"monitor\") clauses.push(allowAll(clause));\n else if (clause.id === \"protect-read\" && r[\"secret-read\"].mode === \"monitor\") {\n clauses.push({ ...clause, param_bounds: { path: { pattern: GUARDRAIL_READ_PATTERN } },\n description: \"Allow workspace reads, but never Scopebond's own folder, which holds this computer's key (always on). Other protected files are recorded, not blocked: set by your workspace.\" });\n }\n else if (clause.id === \"protect-write\" && r[\"ci-config-write\"].mode === \"monitor\") {\n clauses.push({ ...clause, param_bounds: { path: { pattern: GUARDRAIL_WRITE_PATTERN } },\n description: \"Allow workspace writes, but never to Scopebond's own settings or the agents' hook settings (always on). Other protected files are recorded, not blocked: set by your workspace.\" });\n } else if (clause.id === \"protect-read\" && r[\"secret-read\"].excluded_paths?.length) {\n clauses.push(withBound(clause, \"path\", withPathExclusions(boundPattern(clause, \"path\"), safeExclusions(r[\"secret-read\"].excluded_paths))));\n } else if (clause.id === \"protect-write\" && r[\"ci-config-write\"].excluded_paths?.length) {\n clauses.push(withBound(clause, \"path\", withPathExclusions(boundPattern(clause, \"path\"), safeExclusions(r[\"ci-config-write\"].excluded_paths))));\n } else if (clause.id === \"protect-branches\" && r[\"push-protected\"].excluded_branches?.length) {\n clauses.push(withBound(clause, \"ref\", withBranchExclusions(boundPattern(clause, \"ref\"), r[\"push-protected\"].excluded_branches)));\n // Skipping ordinary pushes to a branch never skips history protection: force-pushes, deletions and mirror pushes stay stopped.\n if (r[\"force-push-protected\"].mode === \"block\") {\n clauses.push({ id: \"protect-branch-history\", type: \"force_push_guard\", mode: \"enforce\", protected_refs: rules.protected_branches.map(branchGlob),\n description: \"Deny force-pushes, deletions and mirror pushes that reach a protected branch. Set by your workspace.\" });\n }\n } else clauses.push(clause);\n }\n if (r[\"network-egress\"].mode === \"block\") {\n const keysAt = clauses.findIndex((c) => c.id === \"keys\");\n clauses.splice(keysAt < 0 ? clauses.length : keysAt, 0, {\n id: \"allowed-sites\", type: \"action_allowlist\", mode: \"enforce\", action_types: [\"net.fetch\"],\n param_bounds: { host: { pattern: hostPattern(r[\"network-egress\"].allowed_hosts ?? []) } },\n description: `Deny web requests to sites other than ${r[\"network-egress\"].allowed_hosts!.join(\", \")}. Set by your workspace.`,\n });\n }\n return { ...policy, policy_id: \"coding-agent\", version: doc.revision, clauses };\n}\n\n// --- on disk ---------------------------------------------------------------------------------------------------------------------\n\nexport interface ManagedMeta {\n revision: number | null;\n rules_digest: string | null;\n export_id: string | null;\n etag: string | null;\n checked_at: string | null;\n last_ack: { revision: number; result: \"loaded\" | \"rejected\"; at: string } | null;\n last_error: string | null;\n}\nconst EMPTY_META: ManagedMeta = { revision: null, rules_digest: null, export_id: null, etag: null, checked_at: null, last_ack: null, last_error: null };\n\nexport function readMeta(dir: string): ManagedMeta {\n try { return { ...EMPTY_META, ...(JSON.parse(readFileSync(join(dir, MANAGED_META_FILE), \"utf8\")) as Partial<ManagedMeta>) }; } catch { return { ...EMPTY_META }; }\n}\nexport function writeMeta(dir: string, meta: ManagedMeta): void { writeAtomic(join(dir, MANAGED_META_FILE), `${JSON.stringify(meta, null, 2)}\\n`); }\n\n/** Whether a workspace currently manages the rules on this computer. */\nexport const isManaged = (dir: string): boolean => existsSync(join(dir, MANAGED_DOC_FILE));\n\nexport function writeAtomic(file: string, text: string): void {\n const temp = `${file}.${randomBytes(6).toString(\"hex\")}.tmp`;\n try { writeFileSync(temp, text, { mode: 0o600 }); renameSync(temp, file); }\n catch (error) { try { rmSync(temp, { force: true }); } catch { /* nothing to remove */ } throw error; }\n}\n\n/** Install a checked document: write the merged policy (previous kept) and the document. `policyBuilds` is the caller's check\n * that the gateway can load the result. */\nexport function installManaged(dir: string, doc: ManagedDocument, agentKid: string, policyBuilds: (policy: Record<string, unknown>) => boolean): { ok: true } | { ok: false; reason: RefusalReason; message: string } {\n const local = loadRules(dir) ?? defaultRules();\n const policy = compileManaged(local, doc, agentKid);\n if (!policyBuilds(policy)) return { ok: false, reason: \"unsupported\", message: \"this version of Scopebond cannot load the workspace rules; update it\" };\n try {\n mkdirSync(dir, { recursive: true });\n const policyPath = join(dir, \"policy.json\");\n if (existsSync(policyPath)) copyFileSync(policyPath, join(dir, PREVIOUS_POLICY_FILE));\n writeAtomic(policyPath, `${JSON.stringify(policy, null, 2)}\\n`);\n writeAtomic(join(dir, MANAGED_DOC_FILE), `${JSON.stringify(doc, null, 2)}\\n`);\n return { ok: true };\n } catch (error) {\n return { ok: false, reason: \"write_failed\", message: `could not write the rules (${(error as Error).name})` };\n }\n}\n\n/** Go back to this computer's own rules: recompile policy.json from rules.json and forget the workspace document. */\nexport function restoreLocal(dir: string, agentKid: string): void {\n const local = loadRules(dir) ?? defaultRules();\n const policyPath = join(dir, \"policy.json\");\n if (existsSync(policyPath)) copyFileSync(policyPath, join(dir, PREVIOUS_POLICY_FILE));\n writeAtomic(policyPath, `${JSON.stringify(compile(local, agentKid), null, 2)}\\n`);\n rmSync(join(dir, MANAGED_DOC_FILE), { force: true });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"managed.js","sourceRoot":"","sources":["../src/managed.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,EAAE;AACF,6HAA6H;AAC7H,+HAA+H;AAC/H,gIAAgI;AAChI,6GAA6G;AAC7G,EAAE;AACF,iIAAiI;AACjI,qIAAqI;AACrI,gIAAgI;AAChI,EAAE;AACF,4HAA4H;AAC5H,2HAA2H;AAC3H,+HAA+H;AAC/H,4GAA4G;AAC5G,EAAE;AACF,4HAA4H;AAC5H,6HAA6H;AAC7H,gHAAgH;AAEhH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC/G,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AACzG,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAgB,MAAM,YAAY,CAAC;AAE5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AACrD,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAE3D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,sBAAsB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,aAAa,EAAE,iBAAiB,EAAE,gBAAgB,CAAU,CAAC;AAI7J,MAAM,OAAO,GAA4C;IACvD,sBAAsB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,oBAAoB;IACpF,mBAAmB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,eAAe;CAC/E,CAAC;AACF,MAAM,YAAY,GAA4B;IAC5C,kBAAkB,EAAE,2BAA2B;IAC/C,oBAAoB,EAAE,6BAA6B;IACnD,aAAa,EAAE,0EAA0E;CAC1F,CAAC;AACF,6EAA6E;AAC7E,MAAM,aAAa,GAAiD;IAClE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,mBAAmB;CAC5G,CAAC;AACF,MAAM,iBAAiB,GAAiC;IACtD,8GAA8G;IAC9G,cAAc,EAAE,oGAAoG;IACpH,yGAAyG;IACzG,iBAAiB,EAAE,oCAAoC;CACxD,CAAC;AACF,MAAM,KAAK,GAAG,gBAAgB,CAAC;AAC/B,MAAM,MAAM,GAAG,0BAA0B,CAAC;AAO1C,MAAM,KAAK,GAAG,CAAC,CAAU,EAAE,GAAW,EAAE,GAAW,EAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAK,CAAY,IAAI,GAAG,IAAK,CAAY,IAAI,GAAG,CAAC;AACrI,SAAS,UAAU,CAAC,CAAU;IAC5B,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE,EAAE,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;WACtI,OAAO,CAAC,CAAC,cAAc,KAAK,SAAS,CAAC;AAC7C,CAAC;AACD,2GAA2G;AAC3G,MAAM,CAAC,MAAM,cAAc,GAA4C;IACrE,kBAAkB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,YAAY,EAAE,mBAAmB;IACzH,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,eAAe,EAAE,gBAAgB;CACrG,CAAC;AACF;yDACyD;AACzD,MAAM,UAAU,aAAa,CAAC,GAAoB;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;QAC5E,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAChD,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;QACtF,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IAC5C,CAAC,CAAC,CAA6B,CAAC;IAChC,OAAO,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC;AAgBD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEnH,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAgC,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAExH,uEAAuE;AACvE,MAAM,UAAU,cAAc,CAAC,GAAY,EAAE,OAAkG;IAC7I,MAAM,GAAG,GAAG,CAAC,OAAe,EAAc,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,CAAC;IAClG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,yBAAyB;QAAE,OAAO,GAAG,CAAC,kDAAkD,CAAC,CAAC;IAC7H,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,sCAAsC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;IACzI,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;IACnK,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAK,QAAmB,GAAG,CAAC,IAAK,QAAmB,GAAG,aAAa;WAC9F,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;WAChG,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,cAAc,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC;WAC1H,OAAO,WAAW,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrF,OAAO,GAAG,CAAC,+CAA+C,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,cAAc,KAAK,OAAO,CAAC,cAAc,IAAI,QAAQ,KAAK,OAAO,QAAQ,IAAI,cAAc,EAAE,EAAE,CAAC;QAClG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,kDAAkD,EAAE,CAAC;IAC9G,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,IAAI,CAAC,MAAM,KAAK,gBAAgB,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAClG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,6EAA6E,EAAE,CAAC;IACtI,CAAC;IACD,KAAK,MAAM,EAAE,IAAI,gBAAgB,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;QACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;YAAE,OAAO,GAAG,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;QAClJ,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,KAAK,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC,QAAQ,EAAE,6BAA6B,CAAC,CAAC;QACzK,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,UAAU;gBAAE,SAAS;YACnD,MAAM,OAAO,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;YAC5B,MAAM,YAAY,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;YACvC,MAAM,OAAO,GAAG,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACxH,IAAI,CAAC,OAAO;gBAAE,OAAO,GAAG,CAAC,QAAQ,EAAE,yBAAyB,CAAC,CAAC;YAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YACvB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;gBAClI,OAAO,GAAG,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,gBAAgB,CAAgB,CAAC;IACvD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC;QAAE,OAAO,GAAG,CAAC,kDAAkD,CAAC,CAAC;IACnI,IAAI,WAAW,CAAC,KAAK,CAAC,KAAK,WAAW;QAAE,OAAO,GAAG,CAAC,0EAA0E,CAAC,CAAC;IAC/H,mIAAmI;IACnI,wIAAwI;IACxI,MAAM,kBAAkB,GAAG,OAAO,CAAC,eAAe,KAAK,IAAI,IAAI,QAAQ,KAAK,OAAO,CAAC,eAAe,IAAI,CAAC,CAAC,OAAO,CAAC,aAAa,IAAI,WAAW,KAAK,OAAO,CAAC,aAAa,CAAC;IACxK,IAAI,OAAO,CAAC,eAAe,KAAK,IAAI,IAAK,QAAmB,IAAI,OAAO,CAAC,eAAe,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC/G,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,WAAW,MAAM,CAAC,QAAQ,CAAC,4CAA4C,OAAO,CAAC,eAAe,GAAG,EAAE,CAAC;IAC7J,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,GAAiC,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,KAAK,GAAG,CAAC,CAAoB,EAAE,CAAgC,EAAY,EAAE,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACvH,MAAM,UAAU,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzF,MAAM,WAAW,GAAG,CAAC,KAAwB,EAAU,EAAE,CACvD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;AAIrJ,MAAM,WAAW,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;AAC3F,iHAAiH;AACjH,MAAM,cAAc,GAAG,CAAC,KAAoC,EAAY,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/K;;kGAEkG;AAClG,MAAM,kBAAkB,GAAG,CAAC,OAAe,EAAE,KAAwB,EAAU,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO;IAC5G,CAAC,CAAC,+BAA+B,oBAAoB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC;AACjL,2EAA2E;AAC3E,MAAM,oBAAoB,GAAG,CAAC,OAAe,EAAE,QAA2B,EAAU,EAAE,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO;IACpH,CAAC,CAAC,uBAAuB,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,OAAO,EAAE,CAAC;AAC9E,MAAM,YAAY,GAAG,CAAC,MAAc,EAAE,GAAW,EAAU,EAAE,CAAC,MAAM,CAAC,CAAE,MAAM,CAAC,YAAgE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;AACvK,MAAM,SAAS,GAAG,CAAC,MAAc,EAAE,GAAW,EAAE,OAAe,EAAU,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,EAAE,GAAI,MAAM,CAAC,YAAwC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;AAEvL,oHAAoH;AACpH,MAAM,UAAU,cAAc,CAAC,KAAc,EAAE,GAAoB,EAAE,QAAgB;IACnF,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC;IACpB,MAAM,KAAK,GAAY;QACrB,GAAG,KAAK;QACR,kBAAkB,EAAE,KAAK,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,kBAAkB,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,CAAC;QACjK,oBAAoB,EAAE,KAAK,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC,CAAC,mBAAmB,CAAC,CAAC,oBAAoB,CAAC;KACrG,CAAC;IACF,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAoD,CAAC;IAC3F,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAU,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,iDAAiD,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3P,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACpC,IAAI,MAAM,CAAC,EAAE,KAAK,kBAAkB,IAAI,CAAC,CAAC,gBAAgB,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/E,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAC/B,IAAI,CAAC,CAAC,sBAAsB,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACjD,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,wBAAwB,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC;oBAC9I,WAAW,EAAE,mIAAmI,EAAE,CAAC,CAAC;YACxJ,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,CAAC,EAAE,KAAK,YAAY,IAAI,CAAC,CAAC,mBAAmB,CAAC,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;aAC9G,IAAI,MAAM,CAAC,EAAE,KAAK,cAAc,IAAI,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7E,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE;gBACnF,WAAW,EAAE,+KAA+K,EAAE,CAAC,CAAC;QACpM,CAAC;aACI,IAAI,MAAM,CAAC,EAAE,KAAK,eAAe,IAAI,CAAC,CAAC,iBAAiB,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAClF,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,uBAAuB,EAAE,EAAE;gBACpF,WAAW,EAAE,iLAAiL,EAAE,CAAC,CAAC;QACtM,CAAC;aAAM,IAAI,MAAM,CAAC,EAAE,KAAK,cAAc,IAAI,CAAC,CAAC,aAAa,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;YACnF,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,kBAAkB,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7I,CAAC;aAAM,IAAI,MAAM,CAAC,EAAE,KAAK,eAAe,IAAI,CAAC,CAAC,iBAAiB,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;YACxF,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,kBAAkB,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;QACjJ,CAAC;aAAM,IAAI,MAAM,CAAC,EAAE,KAAK,kBAAkB,IAAI,CAAC,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;YAC7F,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,oBAAoB,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;YACjI,+HAA+H;YAC/H,IAAI,CAAC,CAAC,sBAAsB,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACjD,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,wBAAwB,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC;oBAC9I,WAAW,EAAE,sGAAsG,EAAE,CAAC,CAAC;YAC3H,CAAC;QACH,CAAC;;YAAM,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,CAAC,CAAC,gBAAgB,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;QACzD,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;YACtD,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,WAAW,CAAC;YAC3F,YAAY,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC,EAAE,EAAE;YACzF,WAAW,EAAE,yCAAyC,CAAC,CAAC,gBAAgB,CAAC,CAAC,aAAc,CAAC,IAAI,CAAC,IAAI,CAAC,0BAA0B;SAC9H,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC;AAClF,CAAC;AAaD,MAAM,UAAU,GAAgB,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAExJ,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,IAAI,CAAC;QAAC,OAAO,EAAE,GAAG,UAAU,EAAE,GAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAA0B,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,GAAG,UAAU,EAAE,CAAC;IAAC,CAAC;AACpK,CAAC;AACD,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,IAAiB,IAAU,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEpJ,wEAAwE;AACxE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAW,EAAW,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAE3F,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,IAAY;IACpD,MAAM,IAAI,GAAG,GAAG,IAAI,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;IAC7D,IAAI,CAAC;QAAC,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAAC,CAAC;IAC3E,OAAO,KAAK,EAAE,CAAC;QAAC,IAAI,CAAC;YAAC,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,uBAAuB,CAAC,CAAC;QAAC,MAAM,KAAK,CAAC;IAAC,CAAC;AACzG,CAAC;AAED;4CAC4C;AAC5C,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,GAAoB,EAAE,QAAgB,EAAE,YAA0D;IAC5I,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,YAAY,EAAE,CAAC;IAC/C,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IACpD,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,sEAAsE,EAAE,CAAC;IACxJ,IAAI,CAAC;QACH,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAC5C,IAAI,UAAU,CAAC,UAAU,CAAC;YAAE,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC,CAAC;QACtF,WAAW,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAChE,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAC9E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,8BAA+B,KAAe,CAAC,IAAI,GAAG,EAAE,CAAC;IAChH,CAAC;AACH,CAAC;AAED,qHAAqH;AACrH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,QAAgB;IACxD,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,YAAY,EAAE,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAC5C,IAAI,UAAU,CAAC,UAAU,CAAC;QAAE,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC,CAAC;IACtF,WAAW,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAClF,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACvD,CAAC","sourcesContent":["// Rules managed from a Scopebond Cloud workspace.\n//\n// A connected computer keeps its own rules (`rules.json` compiled into `policy.json`) until the workspace sets rules for it.\n// From then on the workspace decides, rule by rule, whether a matching action is blocked or only recorded, and may add entries\n// to the computer's own lists (protected branches, programs, allowed sites). It never sends a pattern: this module compiles the\n// workspace's choices with the same compiler `rules apply` uses, so what decides a block lives in one place.\n//\n// A workspace may also name exact targets one rule skips: paths for the secret-read and CI-configuration rules, branches for the\n// push rule. An exclusion matches exactly (same case; a trailing `/**` covers a folder), so it is never broader than what was typed,\n// and an exclusion that would touch the always-on protection of the hook's own settings is dropped when the policy is compiled.\n//\n// What a workspace cannot change: the protection of the hook's own settings (and the settings of the agents it guards), the\n// machine key policy, fail-closed handling of anything unparseable, and the computer's own opt-in extras (`allowed_roots`,\n// `protect_remote_database`). A rule set to Monitor is still covered by an allow clause, so the action is recorded and passes;\n// leaving it out would block the whole action type, because the verifier denies an action no clause covers.\n//\n// Loading is checked and atomic: the document must be well formed, name this computer, carry a matching digest and be newer\n// than the one in force; the merged policy must build; policy.json is written through a temp file and a rename, the previous\n// one kept. Disconnecting, or a workspace that stops managing this computer, restores the computer's own rules.\n\nimport { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { canonical } from \"@scopebond/policy-schema/canonical\";\nimport { GUARDRAIL_LOOKAHEADS, GUARDRAIL_READ_PATTERN, GUARDRAIL_WRITE_PATTERN, ci } from \"./runtime.js\";\nimport { compile, defaultRules, loadRules, type RuleSet } from \"./rules.js\";\n\nexport const MANAGED_DOC_FILE = \"managed-rules.json\";\nexport const MANAGED_META_FILE = \"managed-meta.json\";\nexport const PREVIOUS_POLICY_FILE = \"policy.previous.json\";\n\nexport const MANAGED_RULE_IDS = [\"force-push-protected\", \"push-protected\", \"destructive-shell\", \"secret-read\", \"ci-config-write\", \"network-egress\"] as const;\nexport type ManagedRuleId = (typeof MANAGED_RULE_IDS)[number];\ntype ListKey = \"protected_branches\" | \"destructive_programs\" | \"allowed_hosts\";\ntype ExclusionKey = \"excluded_paths\" | \"excluded_branches\";\nconst LIST_OF: Partial<Record<ManagedRuleId, ListKey>> = {\n \"force-push-protected\": \"protected_branches\", \"push-protected\": \"protected_branches\",\n \"destructive-shell\": \"destructive_programs\", \"network-egress\": \"allowed_hosts\",\n};\nconst LIST_PATTERN: Record<ListKey, RegExp> = {\n protected_branches: /^[A-Za-z0-9._/*-]{1,100}$/,\n destructive_programs: /^[a-z0-9][a-z0-9._-]{0,63}$/,\n allowed_hosts: /^(?=.{1,253}$)(\\*\\.)?([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]{2,63}$/,\n};\n/** The exact targets a rule may skip, and the one list each rule accepts. */\nconst EXCLUSIONS_OF: Partial<Record<ManagedRuleId, ExclusionKey>> = {\n \"secret-read\": \"excluded_paths\", \"ci-config-write\": \"excluded_paths\", \"push-protected\": \"excluded_branches\",\n};\nconst EXCLUSION_PATTERN: Record<ExclusionKey, RegExp> = {\n // A relative path with forward slashes: no empty, \".\" or \"..\" segment, optionally ending in /** for a folder.\n excluded_paths: /^(?!\\/)(?!.*\\/\\/)(?!(?:.*\\/)?\\.{1,2}(?:\\/|$))[A-Za-z0-9._@+-][A-Za-z0-9._@+/-]{0,199}?(?:\\/\\*\\*)?$/,\n // One exact branch name; it starts with a letter or digit, so it can never be a push flag such as --all.\n excluded_branches: /^[A-Za-z0-9][A-Za-z0-9._/-]{0,99}$/,\n};\nconst HEX64 = /^[0-9a-f]{64}$/;\nconst OPAQUE = /^[A-Za-z0-9._:-]{1,128}$/;\n\n/** What the computer enforces for a rule set to \"Block, user may override\": the shortest reason accepted, how long one override\n * lasts (0 = this action only), how many a person may make per rule per day, and whether the coding agent's own prompt may be\n * used when the Scopebond window is not available. Who may override is the workspace's decision: it sends \"override\" only then. */\nexport interface OverrideTerms { reason_min: number; minutes: number; daily_limit: number; harness_prompt: boolean }\nexport type ManagedRule = { mode: \"monitor\" | \"block\" | \"override\"; override?: OverrideTerms } & Partial<Record<ListKey | ExclusionKey, string[]>>;\nconst intIn = (v: unknown, min: number, max: number): boolean => Number.isInteger(v) && (v as number) >= min && (v as number) <= max;\nfunction validTerms(t: unknown): t is OverrideTerms {\n return isObject(t) && Object.keys(t).length === 4 && intIn(t.reason_min, 10, 200) && intIn(t.minutes, 0, 60) && intIn(t.daily_limit, 1, 50)\n && typeof t.harness_prompt === \"boolean\";\n}\n/** The clause that carries each workspace rule on the computer, for naming the rule a denial came from. */\nexport const RULE_OF_CLAUSE: Readonly<Record<string, ManagedRuleId>> = {\n \"protect-branches\": \"push-protected\", \"protect-branch-history\": \"force-push-protected\", \"safe-shell\": \"destructive-shell\",\n \"protect-read\": \"secret-read\", \"protect-write\": \"ci-config-write\", \"allowed-sites\": \"network-egress\",\n};\n/** The same document with every overridable rule recorded instead of blocked: what still denies under it is never overridable\n * (another rule on Block, or Scopebond's own floor). */\nexport function floorDocument(doc: ManagedDocument): ManagedDocument {\n const rules = Object.fromEntries(Object.entries(doc.rules).map(([id, rule]) => {\n if (rule.mode !== \"override\") return [id, rule];\n const { override: _terms, excluded_paths: _p, excluded_branches: _b, ...rest } = rule;\n return [id, { ...rest, mode: \"monitor\" }];\n })) as ManagedDocument[\"rules\"];\n return { ...doc, rules };\n}\nexport interface ManagedDocument {\n type: \"scopebond:managed-rules\";\n version: 1;\n revision: number;\n export_id: string;\n environment_id: string;\n agent_id: string;\n installation_id: string;\n rules: Record<ManagedRuleId, ManagedRule>;\n rules_digest: string;\n}\n\nexport type RefusalReason = \"invalid_document\" | \"stale_revision\" | \"wrong_computer\" | \"unsupported\" | \"write_failed\";\nexport type Inspection = { ok: true; doc: ManagedDocument } | { ok: false; reason: RefusalReason; message: string };\n\nexport const digestRules = (rules: unknown): string => createHash(\"sha256\").update(canonical(rules)).digest(\"hex\");\n\nconst isObject = (v: unknown): v is Record<string, unknown> => typeof v === \"object\" && v !== null && !Array.isArray(v);\n\n/** Check a document from the workspace without touching disk. Pure. */\nexport function inspectManaged(raw: unknown, context: { installationId: string; currentRevision: number | null; currentDigest?: string | null }): Inspection {\n const bad = (message: string): Inspection => ({ ok: false, reason: \"invalid_document\", message });\n if (!isObject(raw) || raw.type !== \"scopebond:managed-rules\") return bad(\"this is not a Scopebond workspace rules document\");\n if (raw.version !== 1) return { ok: false, reason: \"unsupported\", message: `unsupported rules document version ${String(raw.version)}` };\n const { revision, export_id: exportId, environment_id: environmentId, agent_id: agentId, installation_id: installationId, rules, rules_digest: rulesDigest } = raw;\n if (!Number.isInteger(revision) || (revision as number) < 1 || (revision as number) > 2_147_483_647\n || typeof exportId !== \"string\" || typeof environmentId !== \"string\" || !OPAQUE.test(environmentId)\n || typeof agentId !== \"string\" || !OPAQUE.test(agentId) || typeof installationId !== \"string\" || !OPAQUE.test(installationId)\n || typeof rulesDigest !== \"string\" || !HEX64.test(rulesDigest) || !isObject(rules)) {\n return bad(\"the rules document is incomplete or malformed\");\n }\n if (installationId !== context.installationId || exportId !== `rev-${revision}-${installationId}`) {\n return { ok: false, reason: \"wrong_computer\", message: \"these rules were issued for a different computer\" };\n }\n const keys = Object.keys(rules);\n if (keys.length !== MANAGED_RULE_IDS.length || !MANAGED_RULE_IDS.every((id) => keys.includes(id))) {\n return { ok: false, reason: \"unsupported\", message: \"the rules document names rules this version does not know; update Scopebond\" };\n }\n for (const id of MANAGED_RULE_IDS) {\n const rule = rules[id];\n if (!isObject(rule) || (rule.mode !== \"monitor\" && rule.mode !== \"block\" && rule.mode !== \"override\")) return bad(`rule ${id} has no valid mode`);\n if ((rule.mode === \"override\") !== (\"override\" in rule) || (rule.mode === \"override\" && !validTerms(rule.override))) return bad(`rule ${id} has invalid override terms`);\n for (const key of Object.keys(rule)) {\n if (key === \"mode\" || key === \"override\") continue;\n const listKey = LIST_OF[id];\n const exclusionKey = EXCLUSIONS_OF[id];\n const pattern = key === listKey ? LIST_PATTERN[listKey] : key === exclusionKey ? EXCLUSION_PATTERN[exclusionKey] : null;\n if (!pattern) return bad(`rule ${id} has an unknown setting`);\n const list = rule[key];\n if (!Array.isArray(list) || list.length > 50 || !list.every((v) => typeof v === \"string\" && pattern.test(v) && !v.includes(\"..\"))) {\n return bad(`rule ${id} has an invalid list`);\n }\n }\n }\n const network = rules[\"network-egress\"] as ManagedRule;\n if (network.mode !== \"monitor\" && !(network.allowed_hosts?.length)) return bad(\"network blocking needs at least one allowed site\");\n if (digestRules(rules) !== rulesDigest) return bad(\"the rules do not match their digest; the document was changed or damaged\");\n // The same version with different rules is a newer document too: the workspace can change what reaches this computer without a new\n // version (an agent moved to another team, or this hook started reading a setting it did not read before). The export id binds it here.\n const sameVersionChanged = context.currentRevision !== null && revision === context.currentRevision && !!context.currentDigest && rulesDigest !== context.currentDigest;\n if (context.currentRevision !== null && (revision as number) <= context.currentRevision && !sameVersionChanged) {\n return { ok: false, reason: \"stale_revision\", message: `version ${String(revision)} is not newer than the version in force (${context.currentRevision})` };\n }\n return { ok: true, doc: raw as unknown as ManagedDocument };\n}\n\nconst union = (a: readonly string[], b: readonly string[] | undefined): string[] => [...new Set([...a, ...(b ?? [])])];\nconst branchGlob = (b: string): string => (b.endsWith(\"/*\") ? `${b.slice(0, -1)}**` : b);\nconst hostPattern = (hosts: readonly string[]): string =>\n `^(?:${hosts.map((h) => (h.startsWith(\"*.\") ? `(?:[^.]+\\\\.)+${ci(h.slice(2).replace(/\\./g, \"\\\\.\"))}` : ci(h.replace(/\\./g, \"\\\\.\")))).join(\"|\")})$`;\n\ntype Clause = Record<string, unknown> & { id: string };\n\nconst escapeRegex = (text: string): string => text.replace(/[\\\\^$.*+?()[\\]{}|/]/g, \"\\\\$&\");\n/** Exclusions that passed validation (the document check refuses the rest; this is a second line of defence). */\nconst safeExclusions = (paths: readonly string[] | undefined): string[] => (paths ?? []).filter((path) => EXCLUSION_PATTERN.excluded_paths.test(path) && !path.includes(\"..\"));\n/** An allow pattern that also allows exactly these paths (a trailing /** allows everything under the folder). The added alternative\n * carries the always-on floor and refuses any path with a \".\" or \"..\" segment, so no exclusion — however it is written — can reach\n * Scopebond's own settings or the agents' hook settings, or climb out of the folder it names. */\nconst withPathExclusions = (pattern: string, paths: readonly string[]): string => paths.length === 0 ? pattern\n : `^(?!(?:.*/)?\\\\.{1,2}(?:/|$))${GUARDRAIL_LOOKAHEADS}(?:${paths.map((p) => p.endsWith(\"/**\") ? `${escapeRegex(p.slice(0, -3))}/.+` : escapeRegex(p)).join(\"|\")})$|${pattern}`;\n/** An allow pattern for pushes that also allows exactly these branches. */\nconst withBranchExclusions = (pattern: string, branches: readonly string[]): string => branches.length === 0 ? pattern\n : `^(?:refs/heads/)?(?:${branches.map(escapeRegex).join(\"|\")})$|${pattern}`;\nconst boundPattern = (clause: Clause, key: string): string => String(((clause.param_bounds as Record<string, { pattern: string }> | undefined)?.[key])?.pattern ?? \"\");\nconst withBound = (clause: Clause, key: string, pattern: string): Clause => ({ ...clause, param_bounds: { ...(clause.param_bounds as Record<string, unknown>), [key]: { pattern } } });\n\n/** The policy this computer enforces under workspace rules: its own compiled rules, adjusted rule by rule. Pure. */\nexport function compileManaged(local: RuleSet, doc: ManagedDocument, agentKid: string): Record<string, unknown> {\n const r = doc.rules;\n const rules: RuleSet = {\n ...local,\n protected_branches: union(local.protected_branches, [...(r[\"push-protected\"].protected_branches ?? []), ...(r[\"force-push-protected\"].protected_branches ?? [])]),\n destructive_programs: union(local.destructive_programs, r[\"destructive-shell\"].destructive_programs),\n };\n const policy = compile(rules, agentKid) as { clauses: Clause[] } & Record<string, unknown>;\n const allowAll = (clause: Clause): Clause => { const { param_bounds: _dropped, ...rest } = clause; return { ...rest, mode: \"enforce\", description: `${String(clause.description ?? \"\").split(\".\")[0]}. Recorded, not blocked: set by your workspace.` }; };\n const clauses: Clause[] = [];\n for (const clause of policy.clauses) {\n if (clause.id === \"protect-branches\" && r[\"push-protected\"].mode === \"monitor\") {\n clauses.push(allowAll(clause));\n if (r[\"force-push-protected\"].mode !== \"monitor\") {\n clauses.push({ id: \"protect-branch-history\", type: \"force_push_guard\", mode: \"enforce\", protected_refs: rules.protected_branches.map(branchGlob),\n description: \"Deny force-pushes, deletions and mirror pushes that reach a protected branch; ordinary pushes are allowed. Set by your workspace.\" });\n }\n } else if (clause.id === \"safe-shell\" && r[\"destructive-shell\"].mode === \"monitor\") clauses.push(allowAll(clause));\n else if (clause.id === \"protect-read\" && r[\"secret-read\"].mode === \"monitor\") {\n clauses.push({ ...clause, param_bounds: { path: { pattern: GUARDRAIL_READ_PATTERN } },\n description: \"Allow workspace reads, but never Scopebond's own folder, which holds this computer's key (always on). Other protected files are recorded, not blocked: set by your workspace.\" });\n }\n else if (clause.id === \"protect-write\" && r[\"ci-config-write\"].mode === \"monitor\") {\n clauses.push({ ...clause, param_bounds: { path: { pattern: GUARDRAIL_WRITE_PATTERN } },\n description: \"Allow workspace writes, but never to Scopebond's own settings or the agents' hook settings (always on). Other protected files are recorded, not blocked: set by your workspace.\" });\n } else if (clause.id === \"protect-read\" && r[\"secret-read\"].excluded_paths?.length) {\n clauses.push(withBound(clause, \"path\", withPathExclusions(boundPattern(clause, \"path\"), safeExclusions(r[\"secret-read\"].excluded_paths))));\n } else if (clause.id === \"protect-write\" && r[\"ci-config-write\"].excluded_paths?.length) {\n clauses.push(withBound(clause, \"path\", withPathExclusions(boundPattern(clause, \"path\"), safeExclusions(r[\"ci-config-write\"].excluded_paths))));\n } else if (clause.id === \"protect-branches\" && r[\"push-protected\"].excluded_branches?.length) {\n clauses.push(withBound(clause, \"ref\", withBranchExclusions(boundPattern(clause, \"ref\"), r[\"push-protected\"].excluded_branches)));\n // Skipping ordinary pushes to a branch never skips history protection: force-pushes, deletions and mirror pushes stay stopped.\n if (r[\"force-push-protected\"].mode !== \"monitor\") {\n clauses.push({ id: \"protect-branch-history\", type: \"force_push_guard\", mode: \"enforce\", protected_refs: rules.protected_branches.map(branchGlob),\n description: \"Deny force-pushes, deletions and mirror pushes that reach a protected branch. Set by your workspace.\" });\n }\n } else clauses.push(clause);\n }\n if (r[\"network-egress\"].mode !== \"monitor\") {\n const keysAt = clauses.findIndex((c) => c.id === \"keys\");\n clauses.splice(keysAt < 0 ? clauses.length : keysAt, 0, {\n id: \"allowed-sites\", type: \"action_allowlist\", mode: \"enforce\", action_types: [\"net.fetch\"],\n param_bounds: { host: { pattern: hostPattern(r[\"network-egress\"].allowed_hosts ?? []) } },\n description: `Deny web requests to sites other than ${r[\"network-egress\"].allowed_hosts!.join(\", \")}. Set by your workspace.`,\n });\n }\n return { ...policy, policy_id: \"coding-agent\", version: doc.revision, clauses };\n}\n\n// --- on disk ---------------------------------------------------------------------------------------------------------------------\n\nexport interface ManagedMeta {\n revision: number | null;\n rules_digest: string | null;\n export_id: string | null;\n etag: string | null;\n checked_at: string | null;\n last_ack: { revision: number; result: \"loaded\" | \"rejected\"; at: string } | null;\n last_error: string | null;\n}\nconst EMPTY_META: ManagedMeta = { revision: null, rules_digest: null, export_id: null, etag: null, checked_at: null, last_ack: null, last_error: null };\n\nexport function readMeta(dir: string): ManagedMeta {\n try { return { ...EMPTY_META, ...(JSON.parse(readFileSync(join(dir, MANAGED_META_FILE), \"utf8\")) as Partial<ManagedMeta>) }; } catch { return { ...EMPTY_META }; }\n}\nexport function writeMeta(dir: string, meta: ManagedMeta): void { writeAtomic(join(dir, MANAGED_META_FILE), `${JSON.stringify(meta, null, 2)}\\n`); }\n\n/** Whether a workspace currently manages the rules on this computer. */\nexport const isManaged = (dir: string): boolean => existsSync(join(dir, MANAGED_DOC_FILE));\n\nexport function writeAtomic(file: string, text: string): void {\n const temp = `${file}.${randomBytes(6).toString(\"hex\")}.tmp`;\n try { writeFileSync(temp, text, { mode: 0o600 }); renameSync(temp, file); }\n catch (error) { try { rmSync(temp, { force: true }); } catch { /* nothing to remove */ } throw error; }\n}\n\n/** Install a checked document: write the merged policy (previous kept) and the document. `policyBuilds` is the caller's check\n * that the gateway can load the result. */\nexport function installManaged(dir: string, doc: ManagedDocument, agentKid: string, policyBuilds: (policy: Record<string, unknown>) => boolean): { ok: true } | { ok: false; reason: RefusalReason; message: string } {\n const local = loadRules(dir) ?? defaultRules();\n const policy = compileManaged(local, doc, agentKid);\n if (!policyBuilds(policy)) return { ok: false, reason: \"unsupported\", message: \"this version of Scopebond cannot load the workspace rules; update it\" };\n try {\n mkdirSync(dir, { recursive: true });\n const policyPath = join(dir, \"policy.json\");\n if (existsSync(policyPath)) copyFileSync(policyPath, join(dir, PREVIOUS_POLICY_FILE));\n writeAtomic(policyPath, `${JSON.stringify(policy, null, 2)}\\n`);\n writeAtomic(join(dir, MANAGED_DOC_FILE), `${JSON.stringify(doc, null, 2)}\\n`);\n return { ok: true };\n } catch (error) {\n return { ok: false, reason: \"write_failed\", message: `could not write the rules (${(error as Error).name})` };\n }\n}\n\n/** Go back to this computer's own rules: recompile policy.json from rules.json and forget the workspace document. */\nexport function restoreLocal(dir: string, agentKid: string): void {\n const local = loadRules(dir) ?? defaultRules();\n const policyPath = join(dir, \"policy.json\");\n if (existsSync(policyPath)) copyFileSync(policyPath, join(dir, PREVIOUS_POLICY_FILE));\n writeAtomic(policyPath, `${JSON.stringify(compile(local, agentKid), null, 2)}\\n`);\n rmSync(join(dir, MANAGED_DOC_FILE), { force: true });\n}\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type OverrideHandler } from "@scopebond/gateway";
|
|
2
|
+
import { type ManagedRuleId } from "./managed.js";
|
|
3
|
+
export declare const OVERRIDE_STATE_FILE = "overrides.json";
|
|
4
|
+
/** Claude Code permission modes in which it shows the person a prompt for "ask". Any other or missing mode blocks. */
|
|
5
|
+
export declare const PROMPTING_MODES: Set<string>;
|
|
6
|
+
export declare const digestOf: (text: string) => string;
|
|
7
|
+
/** One line a person can judge at a glance, from the minimized intent: never file contents or command output. */
|
|
8
|
+
export declare function actionSummary(intent: {
|
|
9
|
+
action_type?: string;
|
|
10
|
+
params?: Record<string, unknown>;
|
|
11
|
+
}): string;
|
|
12
|
+
/** The same action, whatever tool call it came from: its type and parameters without the per-call group id. */
|
|
13
|
+
export declare function actionKey(intent: {
|
|
14
|
+
action_type?: string;
|
|
15
|
+
params?: Record<string, unknown>;
|
|
16
|
+
}): string;
|
|
17
|
+
export interface AgentAnswer {
|
|
18
|
+
decision: "allow" | "deny" | "unavailable";
|
|
19
|
+
reason?: string;
|
|
20
|
+
os_user?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Ask the resident Scopebond Agent to show its window. Returns "unavailable" when no agent answers. */
|
|
23
|
+
export declare function askAgent(home: string, request: Record<string, unknown>, timeoutMs: number, fetchImpl?: typeof fetch): Promise<AgentAnswer>;
|
|
24
|
+
export interface OverrideContext {
|
|
25
|
+
/** The folder holding the policy and the workspace rules document. */
|
|
26
|
+
dir: string;
|
|
27
|
+
/** The Scopebond home, where the resident agent publishes its local channel. */
|
|
28
|
+
home: string;
|
|
29
|
+
agentKid: string;
|
|
30
|
+
harness: "claude" | "codex" | "cursor";
|
|
31
|
+
/** Claude Code's permission_mode from the hook payload, when it sent one. */
|
|
32
|
+
permissionMode?: string | null;
|
|
33
|
+
now?: () => number;
|
|
34
|
+
/** How long to wait for the person; the agent's own hook timeout must be longer. */
|
|
35
|
+
waitMs?: number;
|
|
36
|
+
ask?: typeof askAgent;
|
|
37
|
+
}
|
|
38
|
+
/** What happened when the last override was considered, so a denial can say how an override would be possible. */
|
|
39
|
+
export interface OverrideNote {
|
|
40
|
+
rule: ManagedRuleId;
|
|
41
|
+
title: string;
|
|
42
|
+
outcome: "declined" | "limit" | "unavailable" | "not_overridable";
|
|
43
|
+
}
|
|
44
|
+
export declare function createOverrideHandler(ctx: OverrideContext): {
|
|
45
|
+
handler: OverrideHandler;
|
|
46
|
+
note(): OverrideNote | null;
|
|
47
|
+
} | null;
|
|
48
|
+
/** The sentence added to a denial when the rule allows an override, so the person knows what to do. */
|
|
49
|
+
export declare function overrideHint(note: OverrideNote | null): string | null;
|
|
50
|
+
export declare const hasOverrideState: (dir: string) => boolean;
|
|
51
|
+
//# sourceMappingURL=override.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"override.d.ts","sourceRoot":"","sources":["../src/override.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAY,KAAK,eAAe,EAAuB,MAAM,oBAAoB,CAAC;AACzF,OAAO,EAAsG,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAGtJ,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAGpD,sHAAsH;AACtH,eAAO,MAAM,eAAe,aAA8C,CAAC;AAY3E,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,KAAG,MAAiE,CAAC;AAkB1G,iHAAiH;AACjH,wBAAgB,aAAa,CAAC,MAAM,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,MAAM,CAUxG;AAED,+GAA+G;AAC/G,wBAAgB,SAAS,CAAC,MAAM,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,MAAM,CAKpG;AAED,MAAM,WAAW,WAAW;IAAG,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,aAAa,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE;AAE9G,wGAAwG;AACxG,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAE,OAAO,KAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAevJ;AAED,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IACvC,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,QAAQ,CAAC;CACvB;AAED,kHAAkH;AAClH,MAAM,WAAW,YAAY;IAAG,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,UAAU,GAAG,OAAO,GAAG,aAAa,GAAG,iBAAiB,CAAA;CAAE;AAEvI,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,GAAG;IAAE,OAAO,EAAE,eAAe,CAAC;IAAC,IAAI,IAAI,YAAY,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAuD5H;AAMD,uGAAuG;AACvG,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAQrE;AAED,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,OAAqD,CAAC"}
|