@inhuman.tools/policy 0.0.0-stage → 0.1.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/authorize.scm +4 -0
- package/dist/acknowledge.d.ts +70 -0
- package/dist/acknowledge.d.ts.map +1 -0
- package/dist/acknowledge.js +162 -0
- package/dist/acknowledge.js.map +1 -0
- package/dist/authorize.d.ts +8 -0
- package/dist/authorize.d.ts.map +1 -0
- package/dist/authorize.js +39 -0
- package/dist/authorize.js.map +1 -0
- package/dist/bind.d.ts +6 -0
- package/dist/bind.d.ts.map +1 -0
- package/dist/bind.js +45 -0
- package/dist/bind.js.map +1 -0
- package/dist/check.d.ts +30 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +389 -0
- package/dist/check.js.map +1 -0
- package/dist/classes.d.ts +23 -0
- package/dist/classes.d.ts.map +1 -0
- package/dist/classes.js +139 -0
- package/dist/classes.js.map +1 -0
- package/dist/compile.d.ts +40 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +311 -0
- package/dist/compile.js.map +1 -0
- package/dist/deadline.d.ts +5 -0
- package/dist/deadline.d.ts.map +1 -0
- package/dist/deadline.js +17 -0
- package/dist/deadline.js.map +1 -0
- package/dist/decide.d.ts +64 -0
- package/dist/decide.d.ts.map +1 -0
- package/dist/decide.js +482 -0
- package/dist/decide.js.map +1 -0
- package/dist/error-with-invariant.d.ts +9 -0
- package/dist/error-with-invariant.d.ts.map +1 -0
- package/dist/error-with-invariant.js +12 -0
- package/dist/error-with-invariant.js.map +1 -0
- package/dist/floor.d.ts +9 -0
- package/dist/floor.d.ts.map +1 -0
- package/dist/floor.js +9 -0
- package/dist/floor.js.map +1 -0
- package/dist/glob-expand.d.ts +10 -0
- package/dist/glob-expand.d.ts.map +1 -0
- package/dist/glob-expand.js +132 -0
- package/dist/glob-expand.js.map +1 -0
- package/dist/guards.d.ts +26 -0
- package/dist/guards.d.ts.map +1 -0
- package/dist/guards.js +419 -0
- package/dist/guards.js.map +1 -0
- package/dist/identity.d.ts +11 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +23 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/license-law.d.ts +43 -0
- package/dist/license-law.d.ts.map +1 -0
- package/dist/license-law.js +129 -0
- package/dist/license-law.js.map +1 -0
- package/dist/license.d.ts +3 -0
- package/dist/license.d.ts.map +1 -0
- package/dist/license.js +2 -0
- package/dist/license.js.map +1 -0
- package/dist/lift.d.ts +4 -0
- package/dist/lift.d.ts.map +1 -0
- package/dist/lift.js +14 -0
- package/dist/lift.js.map +1 -0
- package/dist/path-policy.d.ts +53 -0
- package/dist/path-policy.d.ts.map +1 -0
- package/dist/path-policy.js +248 -0
- package/dist/path-policy.js.map +1 -0
- package/dist/peel-cwd.d.ts +8 -0
- package/dist/peel-cwd.d.ts.map +1 -0
- package/dist/peel-cwd.js +120 -0
- package/dist/peel-cwd.js.map +1 -0
- package/dist/prep.d.ts +58 -0
- package/dist/prep.d.ts.map +1 -0
- package/dist/prep.js +690 -0
- package/dist/prep.js.map +1 -0
- package/dist/processor.d.ts +71 -0
- package/dist/processor.d.ts.map +1 -0
- package/dist/processor.js +132 -0
- package/dist/processor.js.map +1 -0
- package/dist/reasonable-defaults.d.ts +1448 -0
- package/dist/reasonable-defaults.d.ts.map +1 -0
- package/dist/reasonable-defaults.js +6 -0
- package/dist/reasonable-defaults.js.map +1 -0
- package/dist/reasonable-defaults.json +1662 -0
- package/dist/run-authorization.d.ts +8 -0
- package/dist/run-authorization.d.ts.map +1 -0
- package/dist/run-authorization.js +16 -0
- package/dist/run-authorization.js.map +1 -0
- package/dist/schemas/tirith.d.ts +58 -0
- package/dist/schemas/tirith.d.ts.map +1 -0
- package/dist/schemas/tirith.js +23 -0
- package/dist/schemas/tirith.js.map +1 -0
- package/dist/tirith-units.d.ts +2 -0
- package/dist/tirith-units.d.ts.map +1 -0
- package/dist/tirith-units.js +227 -0
- package/dist/tirith-units.js.map +1 -0
- package/dist/tirith.d.ts +24 -0
- package/dist/tirith.d.ts.map +1 -0
- package/dist/tirith.js +311 -0
- package/dist/tirith.js.map +1 -0
- package/dist/tool-path.d.ts +8 -0
- package/dist/tool-path.d.ts.map +1 -0
- package/dist/tool-path.js +38 -0
- package/dist/tool-path.js.map +1 -0
- package/dist/types.d.ts +87 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/dist/verdict.d.ts +15 -0
- package/dist/verdict.d.ts.map +1 -0
- package/dist/verdict.js +55 -0
- package/dist/verdict.js.map +1 -0
- package/package.json +62 -3
- package/src/acknowledge.ts +206 -0
- package/src/authorize.ts +38 -0
- package/src/bind.ts +58 -0
- package/src/check.ts +552 -0
- package/src/classes.ts +156 -0
- package/src/compile.ts +370 -0
- package/src/deadline.ts +15 -0
- package/src/floor.ts +16 -0
- package/src/glob-expand.ts +137 -0
- package/src/guards.ts +428 -0
- package/src/identity.ts +26 -0
- package/src/index.ts +24 -0
- package/src/lift.ts +15 -0
- package/src/path-policy.ts +280 -0
- package/src/processor.ts +187 -0
- package/src/reasonable-defaults.json +1662 -0
- package/src/reasonable-defaults.ts +8 -0
- package/src/run-authorization.ts +23 -0
- package/src/tool-path.ts +43 -0
- package/src/types.ts +102 -0
- package/src/verdict.ts +63 -0
- package/README.md +0 -3
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Plugin door: the dist floor and the authorization program. */
|
|
2
|
+
export { authorizationProgram } from "./authorize.js";
|
|
3
|
+
export { authorize } from "./run-authorization.js";
|
|
4
|
+
export { defaultPolicy } from "./bind.js";
|
|
5
|
+
export { JUDGE_DEADLINE_MS, withDeadline } from "./deadline.js";
|
|
6
|
+
export { checkToolPath, normalizeToolPath } from "./tool-path.js";
|
|
7
|
+
export { acknowledgeRequest, acknowledgeRequirement, blockReason, floorVerdictOf, labelOf, mcpOf, mergeAcknowledge, parseAcknowledge, parseAcknowledgeText, requestAcknowledgement, type AckFlag, type AckMatch, type AckRequest, type AckRequirement, type AckSubject, type Acknowledger, } from "./acknowledge.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,OAAO,EACP,KAAK,EACL,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Plugin door: the dist floor and the authorization program. */
|
|
2
|
+
export { authorizationProgram } from "./authorize.js";
|
|
3
|
+
export { authorize } from "./run-authorization.js";
|
|
4
|
+
export { defaultPolicy } from "./bind.js";
|
|
5
|
+
export { JUDGE_DEADLINE_MS, withDeadline } from "./deadline.js";
|
|
6
|
+
export { checkToolPath, normalizeToolPath } from "./tool-path.js";
|
|
7
|
+
export { acknowledgeRequest, acknowledgeRequirement, blockReason, floorVerdictOf, labelOf, mcpOf, mergeAcknowledge, parseAcknowledge, parseAcknowledgeText, requestAcknowledgement, } from "./acknowledge.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,OAAO,EACP,KAAK,EACL,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,GAOvB,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure license decisions. One `LicenseFacts` bag — no jobs.
|
|
3
|
+
* Short-circuit order is the law. Do not reorder.
|
|
4
|
+
* Job readers stay in harness-model.
|
|
5
|
+
*/
|
|
6
|
+
export type LicenseFacts = {
|
|
7
|
+
readonly humanApprove: boolean | null;
|
|
8
|
+
readonly completed: boolean;
|
|
9
|
+
readonly cancelled: boolean;
|
|
10
|
+
readonly commFirst: boolean;
|
|
11
|
+
readonly fileReadGrant: boolean;
|
|
12
|
+
readonly policy: "manual" | "auto" | "yolo";
|
|
13
|
+
readonly policyResult: "policyApprove" | "deny" | "ask" | "block" | null;
|
|
14
|
+
readonly classifierResult: "allow" | "deny" | null;
|
|
15
|
+
readonly classifierAbstain: string | null;
|
|
16
|
+
readonly hatch: boolean;
|
|
17
|
+
readonly clusterGranted: boolean;
|
|
18
|
+
readonly writeClassifierOff: boolean;
|
|
19
|
+
readonly unattended: boolean;
|
|
20
|
+
readonly coverDeny: boolean;
|
|
21
|
+
};
|
|
22
|
+
/** Stored `allow` and `approve` are the previous positive spellings. */
|
|
23
|
+
export declare function asPolicyResult(value: unknown): LicenseFacts["policyResult"];
|
|
24
|
+
/** Floor `ask` and `deny` share remainder `"ask"`. Ignores hatch. `block` is not remainder. */
|
|
25
|
+
export declare function autoRemainderOf(facts: LicenseFacts): "ask" | null;
|
|
26
|
+
/** Auto floor `ask` that allow-sides: not hatch, cluster already granted. */
|
|
27
|
+
export declare function autoAllowSkip(facts: LicenseFacts): boolean;
|
|
28
|
+
/** Floor ask/deny except auto allow-skip. Floor allow is not remainder. */
|
|
29
|
+
export declare function autoRemainder(facts: LicenseFacts): "ask" | null;
|
|
30
|
+
/**
|
|
31
|
+
* Remainder classifier intern. Not the cover. Ungranted write never
|
|
32
|
+
* classifies, including after a fail message. Deny classifies when
|
|
33
|
+
* unattended, when cover is off, or when the cluster is granted.
|
|
34
|
+
*/
|
|
35
|
+
export declare function autoClassifierPending(facts: LicenseFacts): boolean;
|
|
36
|
+
/** Cover predicate. Not a license bit. */
|
|
37
|
+
export declare function needsHuman(facts: LicenseFacts): boolean;
|
|
38
|
+
/** `true` allow / `false` deny / `null` still waiting. Human first, then the floor. */
|
|
39
|
+
export declare function licenseDecision(facts: LicenseFacts): boolean | null;
|
|
40
|
+
export declare function licenseAllows(facts: LicenseFacts): boolean;
|
|
41
|
+
/** Known-safe leaves. Approved and any judge vote stay visible. */
|
|
42
|
+
export declare function tapeFuse(facts: LicenseFacts): boolean;
|
|
43
|
+
//# sourceMappingURL=license-law.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license-law.d.ts","sourceRoot":"","sources":["../src/license-law.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IAC5C,QAAQ,CAAC,YAAY,EAAE,eAAe,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,IAAI,CAAC;IACzE,QAAQ,CAAC,gBAAgB,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;IACnD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAAC,cAAc,CAAC,CAI3E;AAED,+FAA+F;AAC/F,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,KAAK,GAAG,IAAI,CAQjE;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAS1D;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,KAAK,GAAG,IAAI,CAO/D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAYlE;AAED,0CAA0C;AAC1C,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAgBvD;AAED,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,GAAG,IAAI,CA2BnE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAE1D;AAED,mEAAmE;AACnE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAerD"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure license decisions. One `LicenseFacts` bag — no jobs.
|
|
3
|
+
* Short-circuit order is the law. Do not reorder.
|
|
4
|
+
* Job readers stay in harness-model.
|
|
5
|
+
*/
|
|
6
|
+
/** Stored `allow` and `approve` are the previous positive spellings. */
|
|
7
|
+
export function asPolicyResult(value) {
|
|
8
|
+
if (value === "policyApprove" || value === "allow" || value === "approve")
|
|
9
|
+
return "policyApprove";
|
|
10
|
+
if (value === "deny" || value === "ask" || value === "block")
|
|
11
|
+
return value;
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
/** Floor `ask` and `deny` share remainder `"ask"`. Ignores hatch. `block` is not remainder. */
|
|
15
|
+
export function autoRemainderOf(facts) {
|
|
16
|
+
switch (true) {
|
|
17
|
+
case facts.policyResult === "ask":
|
|
18
|
+
case facts.policyResult === "deny":
|
|
19
|
+
return "ask";
|
|
20
|
+
default:
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Auto floor `ask` that allow-sides: not hatch, cluster already granted. */
|
|
25
|
+
export function autoAllowSkip(facts) {
|
|
26
|
+
switch (true) {
|
|
27
|
+
case facts.policy !== "auto":
|
|
28
|
+
case facts.policyResult !== "ask":
|
|
29
|
+
case facts.hatch:
|
|
30
|
+
return false;
|
|
31
|
+
default:
|
|
32
|
+
return facts.clusterGranted;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Floor ask/deny except auto allow-skip. Floor allow is not remainder. */
|
|
36
|
+
export function autoRemainder(facts) {
|
|
37
|
+
switch (true) {
|
|
38
|
+
case autoAllowSkip(facts):
|
|
39
|
+
return null;
|
|
40
|
+
default:
|
|
41
|
+
return autoRemainderOf(facts);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Remainder classifier intern. Not the cover. Ungranted write never
|
|
46
|
+
* classifies, including after a fail message. Deny classifies when
|
|
47
|
+
* unattended, when cover is off, or when the cluster is granted.
|
|
48
|
+
*/
|
|
49
|
+
export function autoClassifierPending(facts) {
|
|
50
|
+
switch (true) {
|
|
51
|
+
case facts.policy !== "auto":
|
|
52
|
+
case autoRemainder(facts) === null || facts.classifierResult !== null:
|
|
53
|
+
case facts.writeClassifierOff:
|
|
54
|
+
return false;
|
|
55
|
+
case facts.classifierAbstain !== null:
|
|
56
|
+
case facts.unattended || facts.policyResult === "ask":
|
|
57
|
+
return true;
|
|
58
|
+
default:
|
|
59
|
+
return facts.policyResult === "deny" && (!facts.coverDeny || facts.clusterGranted);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** Cover predicate. Not a license bit. */
|
|
63
|
+
export function needsHuman(facts) {
|
|
64
|
+
switch (true) {
|
|
65
|
+
case facts.completed || facts.cancelled || facts.humanApprove !== null:
|
|
66
|
+
case facts.commFirst:
|
|
67
|
+
case facts.fileReadGrant:
|
|
68
|
+
return false;
|
|
69
|
+
case facts.policy === "manual" && (facts.policyResult === "ask" || facts.policyResult === "deny"):
|
|
70
|
+
return true;
|
|
71
|
+
case facts.policy !== "auto":
|
|
72
|
+
case autoRemainder(facts) === null || facts.classifierResult !== null:
|
|
73
|
+
return false;
|
|
74
|
+
case autoClassifierPending(facts):
|
|
75
|
+
return facts.classifierAbstain !== null;
|
|
76
|
+
default:
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/** `true` allow / `false` deny / `null` still waiting. Human first, then the floor. */
|
|
81
|
+
export function licenseDecision(facts) {
|
|
82
|
+
switch (true) {
|
|
83
|
+
case facts.humanApprove === true:
|
|
84
|
+
return true;
|
|
85
|
+
case facts.humanApprove === false:
|
|
86
|
+
return false;
|
|
87
|
+
case facts.commFirst:
|
|
88
|
+
return true;
|
|
89
|
+
case facts.policyResult === "block":
|
|
90
|
+
return false;
|
|
91
|
+
case facts.fileReadGrant:
|
|
92
|
+
case facts.policyResult === "policyApprove":
|
|
93
|
+
case facts.policy === "yolo" && (facts.policyResult === "ask" || facts.policyResult === "deny"):
|
|
94
|
+
case autoAllowSkip(facts):
|
|
95
|
+
return true;
|
|
96
|
+
case facts.policy === "auto" && autoRemainderOf(facts) !== null:
|
|
97
|
+
switch (facts.classifierResult) {
|
|
98
|
+
case "allow":
|
|
99
|
+
return true;
|
|
100
|
+
case "deny":
|
|
101
|
+
return false;
|
|
102
|
+
default:
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
default:
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
export function licenseAllows(facts) {
|
|
110
|
+
return licenseDecision(facts) === true;
|
|
111
|
+
}
|
|
112
|
+
/** Known-safe leaves. Approved and any judge vote stay visible. */
|
|
113
|
+
export function tapeFuse(facts) {
|
|
114
|
+
switch (true) {
|
|
115
|
+
case facts.humanApprove !== null:
|
|
116
|
+
case facts.classifierResult !== null:
|
|
117
|
+
return false;
|
|
118
|
+
case facts.commFirst:
|
|
119
|
+
case autoAllowSkip(facts):
|
|
120
|
+
return true;
|
|
121
|
+
case facts.policyResult === "ask":
|
|
122
|
+
case facts.policyResult === "deny":
|
|
123
|
+
case facts.policyResult === "block":
|
|
124
|
+
return false;
|
|
125
|
+
default:
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=license-law.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license-law.js","sourceRoot":"","sources":["../src/license-law.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmBH,wEAAwE;AACxE,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,KAAK,KAAK,eAAe,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,eAAe,CAAC;IAClG,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK,CAAC,YAAY,KAAK,KAAK,CAAC;QAClC,KAAK,KAAK,CAAC,YAAY,KAAK,MAAM;YAChC,OAAO,KAAK,CAAC;QACf;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,aAAa,CAAC,KAAmB;IAC/C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC;QAC7B,KAAK,KAAK,CAAC,YAAY,KAAK,KAAK,CAAC;QAClC,KAAK,KAAK,CAAC,KAAK;YACd,OAAO,KAAK,CAAC;QACf;YACE,OAAO,KAAK,CAAC,cAAc,CAAC;IAChC,CAAC;AACH,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,aAAa,CAAC,KAAmB;IAC/C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,aAAa,CAAC,KAAK,CAAC;YACvB,OAAO,IAAI,CAAC;QACd;YACE,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAmB;IACvD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC;QAC7B,KAAK,aAAa,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,gBAAgB,KAAK,IAAI,CAAC;QACtE,KAAK,KAAK,CAAC,kBAAkB;YAC3B,OAAO,KAAK,CAAC;QACf,KAAK,KAAK,CAAC,iBAAiB,KAAK,IAAI,CAAC;QACtC,KAAK,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,YAAY,KAAK,KAAK;YACnD,OAAO,IAAI,CAAC;QACd;YACE,OAAO,KAAK,CAAC,YAAY,KAAK,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;IACvF,CAAC;AACH,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,UAAU,CAAC,KAAmB;IAC5C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;QACvE,KAAK,KAAK,CAAC,SAAS,CAAC;QACrB,KAAK,KAAK,CAAC,aAAa;YACtB,OAAO,KAAK,CAAC;QACf,KAAK,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,KAAK,IAAI,KAAK,CAAC,YAAY,KAAK,MAAM,CAAC;YAC/F,OAAO,IAAI,CAAC;QACd,KAAK,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC;QAC7B,KAAK,aAAa,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,gBAAgB,KAAK,IAAI;YACnE,OAAO,KAAK,CAAC;QACf,KAAK,qBAAqB,CAAC,KAAK,CAAC;YAC/B,OAAO,KAAK,CAAC,iBAAiB,KAAK,IAAI,CAAC;QAC1C;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK,CAAC,YAAY,KAAK,IAAI;YAC9B,OAAO,IAAI,CAAC;QACd,KAAK,KAAK,CAAC,YAAY,KAAK,KAAK;YAC/B,OAAO,KAAK,CAAC;QACf,KAAK,KAAK,CAAC,SAAS;YAClB,OAAO,IAAI,CAAC;QACd,KAAK,KAAK,CAAC,YAAY,KAAK,OAAO;YACjC,OAAO,KAAK,CAAC;QACf,KAAK,KAAK,CAAC,aAAa,CAAC;QACzB,KAAK,KAAK,CAAC,YAAY,KAAK,eAAe,CAAC;QAC5C,KAAK,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,KAAK,IAAI,KAAK,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC;QAChG,KAAK,aAAa,CAAC,KAAK,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,KAAK,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,IAAI;YAC7D,QAAQ,KAAK,CAAC,gBAAgB,EAAE,CAAC;gBAC/B,KAAK,OAAO;oBACV,OAAO,IAAI,CAAC;gBACd,KAAK,MAAM;oBACT,OAAO,KAAK,CAAC;gBACf;oBACE,OAAO,IAAI,CAAC;YAChB,CAAC;QACH;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAmB;IAC/C,OAAO,eAAe,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AACzC,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,QAAQ,CAAC,KAAmB;IAC1C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;QACjC,KAAK,KAAK,CAAC,gBAAgB,KAAK,IAAI;YAClC,OAAO,KAAK,CAAC;QACf,KAAK,KAAK,CAAC,SAAS,CAAC;QACrB,KAAK,aAAa,CAAC,KAAK,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,KAAK,KAAK,CAAC,YAAY,KAAK,KAAK,CAAC;QAClC,KAAK,KAAK,CAAC,YAAY,KAAK,MAAM,CAAC;QACnC,KAAK,KAAK,CAAC,YAAY,KAAK,OAAO;YACjC,OAAO,KAAK,CAAC;QACf;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license.d.ts","sourceRoot":"","sources":["../src/license.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,aAAa,EACb,eAAe,EACf,UAAU,EACV,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/license.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license.js","sourceRoot":"","sources":["../src/license.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,aAAa,EACb,eAAe,EACf,UAAU,EACV,QAAQ,GACT,MAAM,kBAAkB,CAAC"}
|
package/dist/lift.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lift.d.ts","sourceRoot":"","sources":["../src/lift.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,kFAAkF;AAClF,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,CAWjE"}
|
package/dist/lift.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Match-all / pipeline lattice: any-block > any-deny > any-ask > all-approve. */
|
|
2
|
+
export function lattice(hits) {
|
|
3
|
+
switch (true) {
|
|
4
|
+
case hits.includes("block"):
|
|
5
|
+
return "block";
|
|
6
|
+
case hits.includes("deny"):
|
|
7
|
+
return "deny";
|
|
8
|
+
case hits.includes("ask"):
|
|
9
|
+
return "ask";
|
|
10
|
+
default:
|
|
11
|
+
return "policyApprove";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=lift.js.map
|
package/dist/lift.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lift.js","sourceRoot":"","sources":["../src/lift.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,MAAM,UAAU,OAAO,CAAC,IAA4B;IAClD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YACzB,OAAO,OAAO,CAAC;QACjB,KAAK,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YACxB,OAAO,MAAM,CAAC;QAChB,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YACvB,OAAO,KAAK,CAAC;QACf;YACE,OAAO,eAAe,CAAC;IAC3B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-access cluster: policy.json `read_file` / `write_file` enable lists
|
|
3
|
+
* and `read_block` / `write_block` hard-block lists.
|
|
4
|
+
* Enable `!` is deny (remainder carve-out). Block lists are unliftable.
|
|
5
|
+
* Suffix wildcard is implied — PAT matches itself and descendants.
|
|
6
|
+
* Miss is deny (closed). Unresolvable path is ask.
|
|
7
|
+
* Read enable is approve (silent in-tree). Write enable is ask: the list is
|
|
8
|
+
* what the agent may attempt, not a grant. Yolo rewrites that ask and deny.
|
|
9
|
+
* Realpath / cwd / ~ live on the host; this matcher sees the prepared string.
|
|
10
|
+
*
|
|
11
|
+
* Every rule carries a class (why it votes). Brace and glob words from the shell are expanded
|
|
12
|
+
* lexically against the block rules: if any expansion or match could hit one, the word is `block`.
|
|
13
|
+
*/
|
|
14
|
+
import type { ClassId } from "./classes.js";
|
|
15
|
+
import type { Disposition, FloorVerdict, WriteRemainderKind } from "./types.js";
|
|
16
|
+
type PathRule = {
|
|
17
|
+
readonly id: string;
|
|
18
|
+
readonly polarity: "policyApprove" | "ask" | "deny" | "block";
|
|
19
|
+
readonly stem: string;
|
|
20
|
+
readonly unanchored: boolean;
|
|
21
|
+
readonly class: ClassId;
|
|
22
|
+
};
|
|
23
|
+
export type PathTerm = {
|
|
24
|
+
readonly cluster: "read" | "write";
|
|
25
|
+
readonly rules: PathRule[];
|
|
26
|
+
/** Class of a miss (deny: outside the enable roots). */
|
|
27
|
+
readonly missClass: ClassId;
|
|
28
|
+
};
|
|
29
|
+
export declare function mergePathTerms(cluster: "read" | "write", missClass: ClassId, enable: readonly PathRule[] | undefined, block: readonly PathRule[] | undefined): PathTerm | undefined;
|
|
30
|
+
export declare function checkPath(term: PathTerm, path: string): Disposition;
|
|
31
|
+
/** The disposition of one path with the rules that decided it. */
|
|
32
|
+
export declare function explainPath(term: PathTerm, path: string): FloorVerdict;
|
|
33
|
+
/**
|
|
34
|
+
* Shell words may carry braces and globs. A word the shell would expand is judged as every
|
|
35
|
+
* word it could expand to; a glob is judged as everything it could match. The result is the
|
|
36
|
+
* strictest of those and the word itself, so this can only tighten. Only block rules can be
|
|
37
|
+
* hit by a pattern (an enable root never needs a glob to be understood: the word asks).
|
|
38
|
+
*/
|
|
39
|
+
export declare function explainShellPath(term: PathTerm, word: string, options?: {
|
|
40
|
+
readonly dotglob?: boolean;
|
|
41
|
+
}): FloorVerdict;
|
|
42
|
+
/**
|
|
43
|
+
* Write-deny remainder intern. Null when the floor is not deny.
|
|
44
|
+
* protected: enable `!` inside an enable root. outside: miss, left the
|
|
45
|
+
* enable set. risky: enable `!` and left the enable set. `write_block`
|
|
46
|
+
* never reaches this.
|
|
47
|
+
*/
|
|
48
|
+
export declare function writeRemainderKind(term: PathTerm, path: string): WriteRemainderKind | null;
|
|
49
|
+
/** Undefined = unresolvable (ask). No `..`, `~`, `$`, glob, NUL. */
|
|
50
|
+
export declare function normalizePath(raw: string): string | undefined;
|
|
51
|
+
export { lattice } from "./lift.js";
|
|
52
|
+
export { APPROVE } from "./verdict.js";
|
|
53
|
+
//# sourceMappingURL=path-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-policy.d.ts","sourceRoot":"","sources":["../src/path-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGhF,KAAK,QAAQ,GAAG;IACd,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IAC9D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAC3B,wDAAwD;IACxD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,GAAG,OAAO,EACzB,SAAS,EAAE,OAAO,EAClB,MAAM,EAAE,SAAS,QAAQ,EAAE,GAAG,SAAS,EACvC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,SAAS,GACrC,QAAQ,GAAG,SAAS,CAGtB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAEnE;AAED,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAStE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3C,YAAY,CAsBd;AAwED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAkB1F;AAkED,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAiB7D;AAED,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-access cluster: policy.json `read_file` / `write_file` enable lists
|
|
3
|
+
* and `read_block` / `write_block` hard-block lists.
|
|
4
|
+
* Enable `!` is deny (remainder carve-out). Block lists are unliftable.
|
|
5
|
+
* Suffix wildcard is implied — PAT matches itself and descendants.
|
|
6
|
+
* Miss is deny (closed). Unresolvable path is ask.
|
|
7
|
+
* Read enable is approve (silent in-tree). Write enable is ask: the list is
|
|
8
|
+
* what the agent may attempt, not a grant. Yolo rewrites that ask and deny.
|
|
9
|
+
* Realpath / cwd / ~ live on the host; this matcher sees the prepared string.
|
|
10
|
+
*
|
|
11
|
+
* Every rule carries a class (why it votes). Brace and glob words from the shell are expanded
|
|
12
|
+
* lexically against the block rules: if any expansion or match could hit one, the word is `block`.
|
|
13
|
+
*/
|
|
14
|
+
import { posix } from "node:path";
|
|
15
|
+
import { minimatch } from "minimatch";
|
|
16
|
+
import { expandBraces } from "./glob-expand.js";
|
|
17
|
+
import { cast, join } from "./verdict.js";
|
|
18
|
+
export function mergePathTerms(cluster, missClass, enable, block) {
|
|
19
|
+
if (enable === undefined && block === undefined)
|
|
20
|
+
return undefined;
|
|
21
|
+
return { cluster, missClass, rules: [...(enable ?? []), ...(block ?? [])] };
|
|
22
|
+
}
|
|
23
|
+
export function checkPath(term, path) {
|
|
24
|
+
return explainPath(term, path).disposition;
|
|
25
|
+
}
|
|
26
|
+
/** The disposition of one path with the rules that decided it. */
|
|
27
|
+
export function explainPath(term, path) {
|
|
28
|
+
const resolved = normalizePath(path);
|
|
29
|
+
if (resolved === undefined) {
|
|
30
|
+
return cast("ask", "unmodelled", `${term.cluster}:unresolvable`, { path: { cluster: term.cluster, path } });
|
|
31
|
+
}
|
|
32
|
+
const hits = term.rules.filter((rule) => matchesRule(rule, resolved));
|
|
33
|
+
const where = { path: { cluster: term.cluster, path: resolved } };
|
|
34
|
+
if (hits.length === 0)
|
|
35
|
+
return cast("deny", term.missClass, `${term.cluster}:miss`, where);
|
|
36
|
+
return join(hits.map((rule) => cast(rule.polarity, rule.class, rule.id, where)));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Shell words may carry braces and globs. A word the shell would expand is judged as every
|
|
40
|
+
* word it could expand to; a glob is judged as everything it could match. The result is the
|
|
41
|
+
* strictest of those and the word itself, so this can only tighten. Only block rules can be
|
|
42
|
+
* hit by a pattern (an enable root never needs a glob to be understood: the word asks).
|
|
43
|
+
*/
|
|
44
|
+
export function explainShellPath(term, word, options = {}) {
|
|
45
|
+
const plain = explainPath(term, word);
|
|
46
|
+
if (!/[{*?[]/.test(word))
|
|
47
|
+
return plain;
|
|
48
|
+
const { words: expandedWords, overflow } = expandBraces(word);
|
|
49
|
+
// `a/../.e{nv,x}`: collapse `..` lexically so the block rule sees the name it will open.
|
|
50
|
+
const words = [...expandedWords, ...expandedWords.map(collapseDots).filter((w) => !expandedWords.includes(w))];
|
|
51
|
+
const verdicts = [plain];
|
|
52
|
+
for (const expanded of words) {
|
|
53
|
+
if (!/[*?[]/.test(expanded)) {
|
|
54
|
+
if (expanded !== word)
|
|
55
|
+
verdicts.push(explainPath(term, expanded));
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const hit = globBlockHit(term, expanded, options.dotglob === true);
|
|
59
|
+
if (hit !== undefined)
|
|
60
|
+
verdicts.push(cast("block", hit.class, hit.id, { path: { cluster: term.cluster, path: word } }));
|
|
61
|
+
}
|
|
62
|
+
if (overflow) {
|
|
63
|
+
const hit = globBlockHit(term, wildcardBraces(word), options.dotglob === true);
|
|
64
|
+
if (hit !== undefined)
|
|
65
|
+
verdicts.push(cast("block", hit.class, hit.id, { path: { cluster: term.cluster, path: word } }));
|
|
66
|
+
}
|
|
67
|
+
return join(verdicts);
|
|
68
|
+
}
|
|
69
|
+
function collapseDots(word) {
|
|
70
|
+
return word.includes("..") ? posix.normalize(word) : word;
|
|
71
|
+
}
|
|
72
|
+
/** Every outermost `{...}` group becomes `*`: a superset of whatever the group could expand to. */
|
|
73
|
+
function wildcardBraces(word) {
|
|
74
|
+
let depth = 0;
|
|
75
|
+
let out = "";
|
|
76
|
+
for (const ch of word) {
|
|
77
|
+
if (ch === "{") {
|
|
78
|
+
if (depth === 0)
|
|
79
|
+
out += "*";
|
|
80
|
+
depth += 1;
|
|
81
|
+
}
|
|
82
|
+
else if (ch === "}" && depth > 0) {
|
|
83
|
+
depth -= 1;
|
|
84
|
+
}
|
|
85
|
+
else if (depth === 0) {
|
|
86
|
+
out += ch;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Could a path matching glob `pattern` be blocked? Segment by segment: `*` and `?` do not cross `/`
|
|
93
|
+
* and (like bash without `dotglob`) do not match a leading dot. Case and Unicode form are folded the
|
|
94
|
+
* way the block rules fold them.
|
|
95
|
+
*/
|
|
96
|
+
function globBlockHit(term, pattern, dotglob) {
|
|
97
|
+
const slash = pattern.replaceAll("\\", "/").normalize("NFC").toLowerCase();
|
|
98
|
+
const absolute = slash.startsWith("/");
|
|
99
|
+
const segments = slash.split("/").filter((seg) => seg !== "" && seg !== ".");
|
|
100
|
+
for (const rule of term.rules) {
|
|
101
|
+
if (rule.polarity !== "block")
|
|
102
|
+
continue;
|
|
103
|
+
const stem = rule.stem.normalize("NFC").toLowerCase();
|
|
104
|
+
if (stem === ".")
|
|
105
|
+
continue;
|
|
106
|
+
const stemSegments = stem.split("/").filter((seg) => seg !== "");
|
|
107
|
+
if (rule.unanchored) {
|
|
108
|
+
const name = stemSegments[0];
|
|
109
|
+
const at = name === undefined ? -1 : segments.findIndex((seg) => segmentMatches(seg, name, dotglob));
|
|
110
|
+
// `.claude/worktrees` is not under the `.claude` block, glob or not.
|
|
111
|
+
if (at !== -1 && !(rule.stem === ".claude" && segments[at + 1] === "worktrees"))
|
|
112
|
+
return rule;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (stem.startsWith("/") !== absolute)
|
|
116
|
+
continue;
|
|
117
|
+
if (prefixMatches(segments, stemSegments, dotglob))
|
|
118
|
+
return rule;
|
|
119
|
+
}
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
/** `**` stands for any number of segments (zsh and bash with globstar). */
|
|
123
|
+
function prefixMatches(pattern, stem, dotglob) {
|
|
124
|
+
if (stem.length === 0)
|
|
125
|
+
return true;
|
|
126
|
+
const [head, ...rest] = pattern;
|
|
127
|
+
if (head === undefined)
|
|
128
|
+
return false;
|
|
129
|
+
if (head === "**") {
|
|
130
|
+
return prefixMatches(rest, stem, dotglob) || prefixMatches(pattern, stem.slice(1), dotglob);
|
|
131
|
+
}
|
|
132
|
+
const [name, ...more] = stem;
|
|
133
|
+
return segmentMatches(head, name, dotglob) && prefixMatches(rest, more, dotglob);
|
|
134
|
+
}
|
|
135
|
+
function segmentMatches(pattern, name, dotglob) {
|
|
136
|
+
if (pattern === name)
|
|
137
|
+
return true;
|
|
138
|
+
if (!/[*?[\]{}()!+@]/.test(pattern))
|
|
139
|
+
return false;
|
|
140
|
+
// A segment with nothing literal in it (`*`, `??`, `[ab]`) matches every file name; treating that as a hit
|
|
141
|
+
// would block `cat *`. It still reaches dot-files when `dotglob` is set.
|
|
142
|
+
const literal = pattern.replaceAll(/\[[^\]]*\]|[*?]/g, "");
|
|
143
|
+
if (literal === "" && !(dotglob && name.startsWith(".")))
|
|
144
|
+
return false;
|
|
145
|
+
return minimatch(name, pattern, { dot: dotglob, nocase: true, nocomment: true, nonegate: true, noglobstar: true });
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Write-deny remainder intern. Null when the floor is not deny.
|
|
149
|
+
* protected: enable `!` inside an enable root. outside: miss, left the
|
|
150
|
+
* enable set. risky: enable `!` and left the enable set. `write_block`
|
|
151
|
+
* never reaches this.
|
|
152
|
+
*/
|
|
153
|
+
export function writeRemainderKind(term, path) {
|
|
154
|
+
const resolved = normalizePath(path);
|
|
155
|
+
switch (true) {
|
|
156
|
+
case resolved === undefined:
|
|
157
|
+
case checkPath(term, path) !== "deny":
|
|
158
|
+
return null;
|
|
159
|
+
case !term.rules.some((rule) => resolved !== undefined && rule.polarity === "deny" && matchesRule(rule, resolved)):
|
|
160
|
+
return "outside";
|
|
161
|
+
case term.rules.some((rule) => resolved !== undefined &&
|
|
162
|
+
(rule.polarity === "ask" || rule.polarity === "policyApprove") &&
|
|
163
|
+
matchesRule(rule, resolved)):
|
|
164
|
+
return "protected";
|
|
165
|
+
default:
|
|
166
|
+
return "risky";
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Block / deny rules fold case and Unicode form: macOS (APFS) and Windows open `.ENV` and `.env`
|
|
171
|
+
* as one file, so a case variant must not walk past the rule. A false block is safe; a miss
|
|
172
|
+
* is not. Enable rules stay exact: folding them would approve paths the list never named.
|
|
173
|
+
*/
|
|
174
|
+
function fold(path) {
|
|
175
|
+
return path.normalize("NFC").toLowerCase();
|
|
176
|
+
}
|
|
177
|
+
function matchesRule(rule, exact) {
|
|
178
|
+
const folded = rule.polarity === "block" || rule.polarity === "deny";
|
|
179
|
+
const resolved = folded ? fold(exact) : exact;
|
|
180
|
+
const stem = folded ? fold(rule.stem) : rule.stem;
|
|
181
|
+
switch (true) {
|
|
182
|
+
case rule.stem === ".":
|
|
183
|
+
return isRelative(resolved);
|
|
184
|
+
case rule.unanchored && hasSegment(resolved, stem):
|
|
185
|
+
case !rule.unanchored && isPrefix(resolved, stem):
|
|
186
|
+
return !(rule.polarity === "block" && rule.stem === ".claude" && isClaudeWorktree(resolved));
|
|
187
|
+
default:
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/** `.claude` write_block does not cover `.claude/worktrees` (any depth). */
|
|
192
|
+
function isClaudeWorktree(path) {
|
|
193
|
+
switch (true) {
|
|
194
|
+
case path === ".claude/worktrees":
|
|
195
|
+
case path.startsWith(".claude/worktrees/"):
|
|
196
|
+
case path.includes("/.claude/worktrees/"):
|
|
197
|
+
case path.endsWith("/.claude/worktrees"):
|
|
198
|
+
return true;
|
|
199
|
+
default:
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function isPrefix(path, stem) {
|
|
204
|
+
switch (true) {
|
|
205
|
+
case path === stem:
|
|
206
|
+
return true;
|
|
207
|
+
case stem === "/":
|
|
208
|
+
return path.startsWith("/");
|
|
209
|
+
default:
|
|
210
|
+
return path.startsWith(`${stem}/`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function hasSegment(path, stem) {
|
|
214
|
+
switch (true) {
|
|
215
|
+
case path === stem:
|
|
216
|
+
case path.startsWith(`${stem}/`):
|
|
217
|
+
case path.includes(`/${stem}/`):
|
|
218
|
+
case path.endsWith(`/${stem}`):
|
|
219
|
+
return true;
|
|
220
|
+
default:
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function isRelative(path) {
|
|
225
|
+
return path !== "/" && !path.startsWith("/");
|
|
226
|
+
}
|
|
227
|
+
/** Undefined = unresolvable (ask). No `..`, `~`, `$`, glob, NUL. */
|
|
228
|
+
export function normalizePath(raw) {
|
|
229
|
+
const slash = raw.replaceAll("\\", "/");
|
|
230
|
+
const parts = slash.split("/").filter((seg) => seg !== "" && seg !== ".");
|
|
231
|
+
switch (true) {
|
|
232
|
+
case raw === "" || raw.includes("\0"):
|
|
233
|
+
case /[~$?*`\0]/.test(slash):
|
|
234
|
+
case parts.includes(".."):
|
|
235
|
+
return undefined;
|
|
236
|
+
case slash.startsWith("/") && parts.length === 0:
|
|
237
|
+
return "/";
|
|
238
|
+
case slash.startsWith("/"):
|
|
239
|
+
return `/${parts.join("/")}`;
|
|
240
|
+
case parts.length === 0:
|
|
241
|
+
return ".";
|
|
242
|
+
default:
|
|
243
|
+
return parts.join("/");
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
export { lattice } from "./lift.js";
|
|
247
|
+
export { APPROVE } from "./verdict.js";
|
|
248
|
+
//# sourceMappingURL=path-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-policy.js","sourceRoot":"","sources":["../src/path-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type PeeledCd = {
|
|
2
|
+
readonly cwd: string;
|
|
3
|
+
readonly command: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function peelLeadingCd(source: string): PeeledCd | null;
|
|
6
|
+
/** Keep an explicit `cwd` arg when it names the same leaf; never override a disagreement. */
|
|
7
|
+
export declare function peelShellCwd(command: string, cwdArg?: string): PeeledCd | null;
|
|
8
|
+
//# sourceMappingURL=peel-cwd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peel-cwd.d.ts","sourceRoot":"","sources":["../src/peel-cwd.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAIF,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAyB7D;AAED,6FAA6F;AAC7F,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAU9E"}
|