Skip to content

Commit a030c75

Browse files
khaliqgantclaude
andauthored
feat(contract): add fixture cases for colon paths and empty scope-path segment (#358)
Three gaps exposed by the Phase 2 divergence runs (cloud#2738): - colon-in-scope-path cases pin SplitN(scope, ":", 4) semantics — hosted TS's String.split(":", 4) truncates the remainder, turning /a:b/** into the exact path /a (wrong-allow and wrong-deny potential). - empty-fourth-segment case pins that relayfile:fs:read: (trailing colon) is a narrow grant matching nothing — hosted TS maps it to "*" and grants the whole namespace. - colon-in-segment-valid pins colons as ordinary path bytes in the scope-path grammar with the expected mounts_at. All cases pass against unmodified Go enforcement (behavior pinned, not changed). Additive v1 fixtures; no version bump. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent f1a30b2 commit a030c75

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

contract/fixtures/auth-matching.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,30 @@
255255
"file": "/github/x",
256256
"expect": { "auth_matches": true }
257257
},
258+
{
259+
"name": "colon-in-scope-path-is-preserved",
260+
"description": "Scope splitting is SplitN(scope, \":\", 4): the path segment keeps any further colons (§4). Pins the truncating-split divergence found in hosted TS (String.split with a limit drops the remainder).",
261+
"scopes": ["relayfile:fs:read:/a:b/**"],
262+
"required": "fs:read",
263+
"file": "/a:b/x.json",
264+
"expect": { "auth_matches": true }
265+
},
266+
{
267+
"name": "colon-in-scope-path-does-not-truncate-to-prefix",
268+
"description": "A truncating split turns /a:b/** into the exact path /a; this case fails such an implementation.",
269+
"scopes": ["relayfile:fs:read:/a:b/**"],
270+
"required": "fs:read",
271+
"file": "/a",
272+
"expect": { "auth_matches": false }
273+
},
274+
{
275+
"name": "empty-fourth-segment-is-a-narrow-grant-matching-nothing",
276+
"description": "relayfile:fs:read: (trailing colon, empty scope path) is an invalid narrow grant: it matches no file and, being narrow, still suppresses nothing-else semantics — it must NOT be read as the 3-segment full-namespace form. Pins the hosted-TS empty-path-becomes-* divergence.",
277+
"scopes": ["relayfile:fs:read:"],
278+
"required": "fs:read",
279+
"file": "/src/app.ts",
280+
"expect": { "auth_matches": false }
281+
},
258282
{
259283
"name": "two-segment-scope-is-opaque-literal-not-grant",
260284
"description": "Scopes with <3 segments never act as path grants; they only match as exact literals of the requirement string.",

contract/fixtures/scope-paths.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
{ "name": "deep-recursive-glob-valid", "scope_path": "/slack/channels/c123/messages/**", "expect": { "valid": true, "mounts_at": "/slack/channels/c123/messages" } },
1919
{ "name": "prefix-glob-valid", "scope_path": "/github/repos/acme-*", "expect": { "valid": true, "mounts_at": "/github/repos" } },
2020
{ "name": "top-level-prefix-glob-mounts-at-root", "scope_path": "/github*", "expect": { "valid": true, "mounts_at": "/" } },
21+
{
22+
"name": "colon-in-segment-valid",
23+
"scope_path": "/a:b/**",
24+
"description": "Colons are ordinary path bytes; only the first three colons of the scope string delimit segments (§4).",
25+
"expect": { "valid": true, "mounts_at": "/a:b" }
26+
},
2127
{
2228
"name": "mid-path-segment-globs-invalid",
2329
"scope_path": "/github/repos/*/*/issues/**",

0 commit comments

Comments
 (0)