@ai-ecoverse/slicc-browsers 1.18.22 → 1.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,7 +7,7 @@ The browser knowledge that SLICC's tools share. SLICC drives a real Chromium bro
7
7
  - which origins browser control must **never** touch, starting with seven's own origin and the vault;
8
8
  - how to prove that a CDP guard really keeps a client away from them.
9
9
 
10
- These programs can't share code, so they share data: one catalog, three sets of test vectors and their JSON schemas, published as a Go module, a Rust crate and an npm package at the same version.
10
+ These programs can't share code, so they share data: one catalog, four sets of test vectors and their JSON schemas, published as a Go module, a Rust crate and an npm package at the same version.
11
11
 
12
12
  | who | uses it for |
13
13
  | --- | --- |
@@ -24,6 +24,7 @@ These programs can't share code, so they share data: one catalog, three sets of
24
24
  | [`corpus/`](corpus), `corpus.json` | discovery conformance cases: a fake machine each, with the ranked browser list it must produce |
25
25
  | [`protected.json`](protected.json), [`protected.mjs`](protected.mjs) | protected-origin test vectors, and a reference matcher in JavaScript |
26
26
  | [`guard-vectors.json`](guard-vectors.json) | the CDP scenarios every guard must pass |
27
+ | [`debugger-stage1.json`](debugger-stage1.json) | shared Stage 1 debugger conformance data |
27
28
  | [`guard-runner.mjs`](guard-runner.mjs), [`guard-driver.mjs`](guard-driver.mjs), [`fixture-server.mjs`](fixture-server.mjs) | a reference runner for the guard vectors, its helpers, and the test server they run against |
28
29
  | [`schema/`](schema) | JSON Schema (2020-12) for each file above, and for the `--json` output of `slicc browsers` and `playwright-cli list` |
29
30
 
@@ -45,8 +46,8 @@ rank := c.Priority("chrome")
45
46
 
46
47
  The files are embedded, so nothing is read from disk at run time.
47
48
  - `Default()` parses the embedded catalog once and panics if it can't, which CI rules out; `Load()` returns the error instead, and `Parse(b)` reads another copy.
48
- - `Corpus()`, `Protected()` and `Guard()` return the vectors as typed structs.
49
- - `CatalogJSON()`, `CorpusJSON()`, `ProtectedJSON()`, `GuardVectorsJSON()` and the `…SchemaJSON()` functions return the raw files.
49
+ - `Corpus()`, `Protected()`, `Guard()` and `DebuggerStage1()` return the vectors as typed structs.
50
+ - `CatalogJSON()`, `CorpusJSON()`, `ProtectedJSON()`, `GuardVectorsJSON()`, `DebuggerStage1JSON()` and the `…SchemaJSON()` functions return the raw files.
50
51
 
51
52
  ### Rust
52
53
 
@@ -62,7 +63,7 @@ slicc-browsers = { version = "1", features = ["corpus"] }
62
63
  | --- | --- |
63
64
  | none | `CATALOG` and the schemas as `&str` constants, with no dependencies |
64
65
  | `serde` | typed `Catalog`, `catalog()`, `Catalog::browser` and `Catalog::priority` |
65
- | `corpus` | the vectors (`CORPUS`, `PROTECTED`, `GUARD_VECTORS`) and the modules `corpus`, `protected` and `guard`, for tests |
66
+ | `corpus` | the vectors (`CORPUS`, `PROTECTED`, `GUARD_VECTORS`, `DEBUGGER_STAGE1`) and the modules `corpus`, `protected`, `guard` and `debugger_stage1`, for tests |
66
67
 
67
68
  Every feature builds for `wasm32-wasip1`. Keep `corpus` in `[dev-dependencies]` so it stays out of release builds.
68
69
 
@@ -79,7 +80,7 @@ import { protectedOrigins } from '@ai-ecoverse/slicc-browsers/protected.mjs';
79
80
 
80
81
  | export | what it is |
81
82
  | --- | --- |
82
- | `.`, `./catalog.json`, `./corpus.json`, `./protected.json`, `./guard-vectors.json` | the data |
83
+ | `.`, `./catalog.json`, `./corpus.json`, `./protected.json`, `./guard-vectors.json`, `./debugger-stage1.json` | the data |
83
84
  | `./schema/<name>.schema.json` | the schemas |
84
85
  | `./protected.mjs` | the protected-origin matcher |
85
86
  | `./seven.mjs` | `isSevenLabel(seven, label)`: whether a `sliccy.ai` host label can be a seven instance |
@@ -0,0 +1,168 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "methods": [
4
+ { "method": "Debugger.enable", "lifetime": "persistent", "admitted": true },
5
+ { "method": "Debugger.disable", "lifetime": "cleanup", "admitted": true },
6
+ { "method": "Debugger.resume", "lifetime": "pause-control", "admitted": true },
7
+ { "method": "Debugger.getScriptSource", "lifetime": "document", "admitted": false },
8
+ { "method": "Debugger.evaluateOnCallFrame", "lifetime": "document", "admitted": false },
9
+ {
10
+ "method": "Debugger.setInstrumentationBreakpoint",
11
+ "lifetime": "persistent",
12
+ "admitted": true
13
+ },
14
+ { "method": "Debugger.removeBreakpoint", "lifetime": "cleanup", "admitted": true },
15
+ {
16
+ "method": "Debugger.pause",
17
+ "lifetime": "document",
18
+ "admitted": false,
19
+ "ownedInstrumentationOnly": true
20
+ },
21
+ { "method": "Debugger.setBreakpoint", "lifetime": "persistent", "admitted": false },
22
+ { "method": "Debugger.setBreakpointByUrl", "lifetime": "persistent", "admitted": false },
23
+ { "method": "Debugger.stepInto", "lifetime": "document", "admitted": false },
24
+ { "method": "Debugger.stepOut", "lifetime": "document", "admitted": false },
25
+ { "method": "Debugger.stepOver", "lifetime": "document", "admitted": false },
26
+ {
27
+ "method": "DOMDebugger.setEventListenerBreakpoint",
28
+ "lifetime": "persistent",
29
+ "admitted": false
30
+ },
31
+ {
32
+ "method": "EventBreakpoints.setInstrumentationBreakpoint",
33
+ "lifetime": "persistent",
34
+ "admitted": false
35
+ },
36
+ {
37
+ "method": "Page.addScriptToEvaluateOnNewDocument",
38
+ "lifetime": "persistent",
39
+ "admitted": false
40
+ },
41
+ { "method": "Runtime.addBinding", "lifetime": "persistent", "admitted": false },
42
+ { "method": "Debugger.stage1Unknown", "lifetime": "unknown", "admitted": false }
43
+ ],
44
+ "rows": [
45
+ {
46
+ "id": "document-change-before-install",
47
+ "mode": "document-change-before-install",
48
+ "destination": "ordinary",
49
+ "expected": {
50
+ "admitted": true,
51
+ "published": true,
52
+ "installed": false,
53
+ "liveReads": true,
54
+ "released": true
55
+ },
56
+ "requires": [
57
+ "publishedPause",
58
+ "documentChange",
59
+ "noSourceInNewDocument",
60
+ "privateRescueAudit"
61
+ ]
62
+ },
63
+ {
64
+ "id": "stage2-methods-at-published-pause",
65
+ "mode": "stage2-refusal",
66
+ "destination": "ordinary",
67
+ "expected": { "admitted": false, "published": true, "forwarded": false, "released": true },
68
+ "requires": [
69
+ "publishedPause",
70
+ "getScriptSourceRefused",
71
+ "evaluateOnCallFrameRefused",
72
+ "privateRescueAudit"
73
+ ]
74
+ },
75
+ {
76
+ "id": "ordinary-install",
77
+ "mode": "install",
78
+ "destination": "ordinary",
79
+ "expected": { "admitted": true, "converted": true, "liveReads": true, "released": true },
80
+ "requires": ["privateRescueAudit"]
81
+ },
82
+ {
83
+ "id": "holder-death",
84
+ "mode": "holder-death",
85
+ "destination": "ordinary",
86
+ "expected": { "admitted": true, "converted": true, "liveReads": true, "released": true },
87
+ "requires": ["clientExit", "privateRescueAudit"]
88
+ },
89
+ {
90
+ "id": "session-loss",
91
+ "mode": "session-loss",
92
+ "destination": "ordinary",
93
+ "expected": { "admitted": true, "converted": true, "liveReads": true, "released": true },
94
+ "requires": ["privateRescueAudit"]
95
+ },
96
+ {
97
+ "id": "worker-restart",
98
+ "mode": "worker-restart",
99
+ "destination": "ordinary",
100
+ "expected": { "admitted": true, "converted": true, "liveReads": true, "released": true },
101
+ "requires": ["restartGuard", "privateRescueAudit"]
102
+ },
103
+ {
104
+ "id": "protected-seven-hop",
105
+ "mode": "protected-hop",
106
+ "destination": "seven",
107
+ "expected": { "admitted": true, "published": false, "committed": false, "released": true },
108
+ "requires": ["privateRescueAudit"]
109
+ },
110
+ {
111
+ "id": "protected-vault-hop",
112
+ "mode": "protected-hop",
113
+ "destination": "vault",
114
+ "expected": { "admitted": true, "published": false, "committed": false, "released": true },
115
+ "requires": ["privateRescueAudit"]
116
+ },
117
+ {
118
+ "id": "protected-error-page",
119
+ "mode": "protected-hop",
120
+ "destination": "seven",
121
+ "expected": { "admitted": true, "published": false, "committed": false, "released": true },
122
+ "requires": ["protectedErrorPage", "privateRescueAudit"]
123
+ },
124
+ {
125
+ "id": "late-foreign-world",
126
+ "mode": "late-foreign-world",
127
+ "destination": "ordinary",
128
+ "expected": { "admitted": true, "published": false, "released": true },
129
+ "requires": ["extensionWorld", "privateRescueAudit"]
130
+ },
131
+ {
132
+ "id": "pending-protected-hop",
133
+ "mode": "pending-pause-hop",
134
+ "destination": "seven",
135
+ "expected": { "admitted": true, "published": false, "committed": false, "released": true },
136
+ "requires": ["pendingPauseGate", "privateRescueAudit"]
137
+ }
138
+ ],
139
+ "navigation": [
140
+ "navigate",
141
+ "href",
142
+ "replace",
143
+ "redirect",
144
+ "reload",
145
+ "history",
146
+ "bfcache",
147
+ "prerender"
148
+ ],
149
+ "leaseRefusals": [
150
+ "protected-top",
151
+ "protected-subframe",
152
+ "nested-protected-subframe",
153
+ "protected-world",
154
+ "foreign-extension-world",
155
+ "protected-worker",
156
+ "unplaced-frame",
157
+ "unplaced-world",
158
+ "unplaced-worker",
159
+ "incomplete-read"
160
+ ],
161
+ "rescueEvidence": {
162
+ "origin": "guard",
163
+ "noObserverResume": true,
164
+ "ownerUnchanged": true,
165
+ "generationUnchanged": true,
166
+ "deadlineUnchanged": true
167
+ }
168
+ }
package/guard-driver.mjs CHANGED
@@ -354,11 +354,25 @@ export const skipReason = (vector, target, scope) => {
354
354
 
355
355
  export const inapplicable = (vector, target, scope) => skipReason(vector, target, scope) !== null;
356
356
 
357
+ const trustedEmulationMethods = new Set([
358
+ 'Emulation.setLocaleOverride',
359
+ 'Emulation.setTimezoneOverride',
360
+ ]);
361
+
362
+ const canTrustedEmulation = (vector) =>
363
+ flatten(named([...(vector?.setup ?? []), ...(vector?.trigger ?? [])])).some((step) =>
364
+ trustedEmulationMethods.has(step.cdp)
365
+ );
366
+
357
367
  function skipWhy(vector, row, known, guard) {
358
368
  const { reason } = row;
359
369
  if (typeof reason !== 'string' || reason === '') return 'skip without a reason';
360
370
  if (reason === skipReason(vector, row.target, guard)) return null;
361
371
  if (originReason(vector, row, reason)) return null;
372
+ if (reason === 'not-supported:trustedEmulation')
373
+ return canTrustedEmulation(vector)
374
+ ? null
375
+ : `skip with a reason the runner never gives: ${reason}`;
362
376
  if (reason.startsWith('not-supported:') && known.has(reason.slice('not-supported:'.length)))
363
377
  return null;
364
378
  return `skip with a reason the runner never gives: ${reason}`;
@@ -369,6 +383,7 @@ function forgeries(set, results, guard) {
369
383
  const known = new Set([
370
384
  'browserSession',
371
385
  'unguarded-observer',
386
+ 'trustedEmulation',
372
387
  ...capabilities(set.vectors).filter((c) => typeof c === 'string' && c !== ''),
373
388
  ]);
374
389
  return results.flatMap((row) => {
@@ -430,3 +445,25 @@ export function parseURL(value, base) {
430
445
 
431
446
  export const owned = (entries, tag) =>
432
447
  (entries ?? []).filter((entry) => typeof entry?.url === 'string' && entry.url.includes(tag));
448
+
449
+ export const debuggerCleanup = (vector, step, phase) =>
450
+ ['E4.instrumentation', 'E4.event-listener'].includes(vector.id) &&
451
+ phase === 'trigger' &&
452
+ step.cdp === 'Debugger.resume';
453
+
454
+ export const idleDebuggerCleanup = (vector, step, phase, out) =>
455
+ debuggerCleanup(vector, step, phase) &&
456
+ !out.ok &&
457
+ out.error?.message === 'Can only perform operation while paused.';
458
+
459
+ export const debuggerPaused = (events, session) =>
460
+ events.some((event) => event.sessionId === session && event.method === 'Debugger.paused');
461
+
462
+ export const trustedClientOnly = (step, out) =>
463
+ trustedEmulationMethods.has(step.cdp) &&
464
+ !out.ok &&
465
+ Number(out.error?.code) === -32000 &&
466
+ /only available to trusted clients/i.test(String(out.error?.message ?? ''));
467
+
468
+ export const refusalError = (step, out, refused, gone, phase, vector) =>
469
+ step.refusable && !out.ok && !refused && !gone && !idleDebuggerCleanup(vector, step, phase, out);
package/guard-runner.mjs CHANGED
@@ -8,6 +8,8 @@ import { frameRead } from './frame-read.mjs';
8
8
  import {
9
9
  beacon,
10
10
  canary,
11
+ debuggerCleanup,
12
+ debuggerPaused,
11
13
  expand,
12
14
  hop,
13
15
  inapplicable,
@@ -18,10 +20,12 @@ import {
18
20
  outcome,
19
21
  owned,
20
22
  parseURL,
23
+ refusalError,
21
24
  summary as report,
22
25
  result,
23
26
  skipReason,
24
27
  steps,
28
+ trustedClientOnly,
25
29
  waitFor,
26
30
  } from './guard-driver.mjs';
27
31
  import { createObserverTarget, discoveryViolation } from './observer-target.mjs';
@@ -142,6 +146,7 @@ class Execution {
142
146
  this.pending = [];
143
147
  this.errors = [];
144
148
  this.incomplete = [];
149
+ this.unsupported = undefined;
145
150
  this.preSent = [];
146
151
  this.notes = [];
147
152
  this.answers = [];
@@ -682,8 +687,10 @@ class Execution {
682
687
  !refused &&
683
688
  /timeout|timed out|no answer/i.test(String(out.error?.message ?? out.error));
684
689
  if (step.refusable) this.refused[step.refusal.name] = unanswered ? 'incomplete' : refused;
685
- if (unanswered) this.incomplete.push(`${step.refusal.name}: no answer`);
686
- else if (step.refusable && !out.ok && !refused && !gone)
690
+ const trusted = this.side === 'control' && trustedClientOnly(step, out);
691
+ if (trusted) this.unsupported = 'trustedEmulation';
692
+ else if (unanswered) this.incomplete.push(`${step.refusal.name}: no answer`);
693
+ else if (refusalError(step, out, refused, gone, phase, this.vector))
687
694
  this.errors.push(
688
695
  `${step.refusal.name} failed without a refusal: ${String(out.error?.message ?? out.error)}`
689
696
  );
@@ -895,7 +902,7 @@ class Execution {
895
902
  })
896
903
  );
897
904
  if (step.guess) return this.guess(step.guess, session);
898
- if (step.cdp) return this.cdp(step, session);
905
+ if (step.cdp) return this.cdp(step, session, phase);
899
906
  if (step.page) return this.page(step, session, phase);
900
907
  throw new Error('Unknown step kind');
901
908
  }
@@ -965,7 +972,12 @@ class Execution {
965
972
  return { ok: true, result: attempts };
966
973
  }
967
974
 
968
- async cdp(step, sessionId) {
975
+ async cdp(step, sessionId, phase) {
976
+ if (
977
+ debuggerCleanup(this.vector, step, phase) &&
978
+ !debuggerPaused(this.client.events.slice(this.eventStart), sessionId)
979
+ )
980
+ return { ok: true, result: { cleanup: 'never paused' } };
969
981
  if (step.cdp === 'Target.detachFromTarget') await sleep(this.delay);
970
982
  if (step.cdp === 'Target.setAutoAttach' && step.params?.autoAttach === false)
971
983
  this.cleanupEventStart = this.client.events.length;
@@ -1433,6 +1445,7 @@ class Execution {
1433
1445
  errors: this.errors,
1434
1446
  notes: this.notes,
1435
1447
  incomplete: this.incomplete,
1448
+ unsupported: this.unsupported,
1436
1449
  evidence: Object.fromEntries(
1437
1450
  Object.entries(this.calls)
1438
1451
  .filter(
@@ -1744,6 +1757,8 @@ async function executeRow(job, opts, made, set, slot, index, flights) {
1744
1757
  flight.abandoned = true;
1745
1758
  return timedOut(stuck, base, made, sides, opts);
1746
1759
  }
1760
+ if (legs.control.unsupported === 'trustedEmulation')
1761
+ return skipRow(base, 'not-supported:trustedEmulation');
1747
1762
  const row = {
1748
1763
  ...result(vector, {
1749
1764
  ...base,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "setVersion": "1.18.22",
3
+ "setVersion": "1.19.1",
4
4
  "sources": [
5
5
  {
6
6
  "repo": "ai-ecoverse/slicc-cli",
@@ -15587,7 +15587,9 @@
15587
15587
  "cdp": "Page.enable"
15588
15588
  },
15589
15589
  {
15590
- "cdp": "Debugger.enable"
15590
+ "cdp": "Debugger.enable",
15591
+ "refusable": true,
15592
+ "refusal": { "match": "refused" }
15591
15593
  },
15592
15594
  {
15593
15595
  "cdp": "Debugger.setBreakpointByUrl",
@@ -15613,14 +15615,21 @@
15613
15615
  }
15614
15616
  },
15615
15617
  {
15616
- "cdp": "Debugger.disable"
15618
+ "cdp": "Debugger.disable",
15619
+ "refusable": true,
15620
+ "refusal": { "match": "refused" }
15617
15621
  }
15618
15622
  ],
15619
15623
  "targets": ["seven", "vault", "vault-x", "apex"],
15620
15624
  "observe": {
15625
+ "admissionRefused": {
15626
+ "means": "the URL-condition method is refused on the ordinary control",
15627
+ "dependsOn": [],
15628
+ "check": { "registration": "any", "observer": "client" }
15629
+ },
15621
15630
  "condition": {
15622
15631
  "means": "a beacon from the breakpoint condition evaluated in {target}/listener.js?n={tag}",
15623
- "dependsOn": ["refused.3"],
15632
+ "dependsOn": [],
15624
15633
  "check": {
15625
15634
  "beacon": "{target}",
15626
15635
  "observer": "fixture"
@@ -15628,7 +15637,7 @@
15628
15637
  },
15629
15638
  "paused": {
15630
15639
  "means": "a Debugger.paused in {target}/listener.js?n={tag}",
15631
- "dependsOn": ["refused.3"],
15640
+ "dependsOn": [],
15632
15641
  "check": {
15633
15642
  "any": [
15634
15643
  {
@@ -15671,9 +15680,10 @@
15671
15680
  "live": "the runner's own CDP sees {target}'s document load (title, marker or URL), or the guard returned its refusal for a refusable step",
15672
15681
  "control": {
15673
15682
  "origin": "ordinary",
15674
- "via": "guard",
15683
+ "via": "unguarded",
15675
15684
  "expected": {
15676
- "condition": true
15685
+ "condition": true,
15686
+ "admissionRefused": false
15677
15687
  }
15678
15688
  },
15679
15689
  "expected": {
@@ -15748,7 +15758,9 @@
15748
15758
  "cdp": "Page.enable"
15749
15759
  },
15750
15760
  {
15751
- "cdp": "Debugger.enable"
15761
+ "cdp": "Debugger.enable",
15762
+ "refusable": true,
15763
+ "refusal": { "match": "refused" }
15752
15764
  },
15753
15765
  {
15754
15766
  "cdp": "Debugger.setInstrumentationBreakpoint",
@@ -15776,17 +15788,21 @@
15776
15788
  "wait": 2000
15777
15789
  },
15778
15790
  {
15779
- "cdp": "Debugger.resume"
15791
+ "cdp": "Debugger.resume",
15792
+ "refusable": true,
15793
+ "refusal": { "match": "refused" }
15780
15794
  },
15781
15795
  {
15782
- "cdp": "Debugger.disable"
15796
+ "cdp": "Debugger.disable",
15797
+ "refusable": true,
15798
+ "refusal": { "match": "refused" }
15783
15799
  }
15784
15800
  ],
15785
15801
  "targets": ["seven", "vault", "vault-x", "apex"],
15786
15802
  "observe": {
15787
15803
  "paused": {
15788
15804
  "means": "a Debugger.paused before {target}/listener.js?n={tag}, which names a source map in its SourceMap header",
15789
- "dependsOn": ["refused.3"],
15805
+ "dependsOn": [],
15790
15806
  "check": {
15791
15807
  "any": [
15792
15808
  {
@@ -15824,14 +15840,24 @@
15824
15840
  "served": "{target}/doc?n={tag}&listener=1",
15825
15841
  "observer": "fixture"
15826
15842
  }
15843
+ },
15844
+ "convertedPause": {
15845
+ "means": "the guard converts the ordinary instrumentation pause to reason other",
15846
+ "dependsOn": [],
15847
+ "check": {
15848
+ "event": "Debugger.paused",
15849
+ "where": { "params": { "reason": "other" } },
15850
+ "observer": "client"
15851
+ }
15827
15852
  }
15828
15853
  },
15829
15854
  "live": "the runner's own CDP sees {target}'s document load (title, marker or URL), or the guard returned its refusal for a refusable step",
15830
15855
  "control": {
15831
15856
  "origin": "ordinary",
15832
- "via": "guard",
15857
+ "via": "unguarded",
15833
15858
  "expected": {
15834
- "paused": true
15859
+ "paused": true,
15860
+ "convertedPause": false
15835
15861
  }
15836
15862
  },
15837
15863
  "expected": {
@@ -15905,7 +15931,9 @@
15905
15931
  "cdp": "Page.enable"
15906
15932
  },
15907
15933
  {
15908
- "cdp": "Debugger.enable"
15934
+ "cdp": "Debugger.enable",
15935
+ "refusable": true,
15936
+ "refusal": { "match": "refused" }
15909
15937
  },
15910
15938
  {
15911
15939
  "cdp": "DOMDebugger.setEventListenerBreakpoint",
@@ -15933,17 +15961,21 @@
15933
15961
  "wait": 2000
15934
15962
  },
15935
15963
  {
15936
- "cdp": "Debugger.resume"
15964
+ "cdp": "Debugger.resume",
15965
+ "refusable": true,
15966
+ "refusal": { "match": "refused" }
15937
15967
  },
15938
15968
  {
15939
- "cdp": "Debugger.disable"
15969
+ "cdp": "Debugger.disable",
15970
+ "refusable": true,
15971
+ "refusal": { "match": "refused" }
15940
15972
  }
15941
15973
  ],
15942
15974
  "targets": ["seven", "vault", "vault-x", "apex"],
15943
15975
  "observe": {
15944
15976
  "paused": {
15945
15977
  "means": "a Debugger.paused in a window load listener, which only {target}/doc?n={tag}&listener=1 registers",
15946
- "dependsOn": ["refused.3"],
15978
+ "dependsOn": [],
15947
15979
  "check": {
15948
15980
  "event": "Debugger.paused",
15949
15981
  "where": {
@@ -15964,14 +15996,20 @@
15964
15996
  "served": "{target}/doc?n={tag}&listener=1",
15965
15997
  "observer": "fixture"
15966
15998
  }
15999
+ },
16000
+ "admissionRefused": {
16001
+ "means": "the listener breakpoint method is refused on the ordinary control",
16002
+ "dependsOn": [],
16003
+ "check": { "registration": "any", "observer": "client" }
15967
16004
  }
15968
16005
  },
15969
16006
  "live": "the runner's own CDP sees {target}'s document load (title, marker or URL), or the guard returned its refusal for a refusable step",
15970
16007
  "control": {
15971
16008
  "origin": "ordinary",
15972
- "via": "guard",
16009
+ "via": "unguarded",
15973
16010
  "expected": {
15974
- "paused": true
16011
+ "paused": true,
16012
+ "admissionRefused": false
15975
16013
  }
15976
16014
  },
15977
16015
  "expected": {
@@ -17331,7 +17369,7 @@
17331
17369
  "targets": ["seven", "vault", "vault-x", "apex"],
17332
17370
  "observe": {
17333
17371
  "locale": {
17334
- "means": "{target}/doc?n={tag} formats in the fr-CH locale",
17372
+ "means": "when the client can override locale, {target}/doc?n={tag} formats in fr-CH",
17335
17373
  "dependsOn": ["refused.2"],
17336
17374
  "check": {
17337
17375
  "expression": "(location.href === '{target}/doc?n={tag}') ? Intl.DateTimeFormat().resolvedOptions().locale : 'elsewhere'",
@@ -17349,7 +17387,7 @@
17349
17387
  }
17350
17388
  }
17351
17389
  },
17352
- "live": "the runner's own CDP sees {target}'s document load (title, marker or URL), or the guard returned its refusal for a refusable step",
17390
+ "live": "the runner's own CDP sees {target}'s document load (title, marker or URL), or the guard returned its refusal for a refusable step; Chrome's trusted-client-only refusal of Emulation.setLocaleOverride on the ordinary control is not-supported:trustedEmulation",
17353
17391
  "control": {
17354
17392
  "origin": "ordinary",
17355
17393
  "via": "guard",
@@ -17452,7 +17490,7 @@
17452
17490
  "targets": ["seven", "vault", "vault-x", "apex"],
17453
17491
  "observe": {
17454
17492
  "timezone": {
17455
- "means": "{target}/doc?n={tag} runs in the Pacific/Chatham time zone",
17493
+ "means": "when the client can override the time zone, {target}/doc?n={tag} runs in Pacific/Chatham",
17456
17494
  "dependsOn": ["refused.2"],
17457
17495
  "check": {
17458
17496
  "expression": "(location.href === '{target}/doc?n={tag}') ? Intl.DateTimeFormat().resolvedOptions().timeZone : 'elsewhere'",
@@ -17470,7 +17508,7 @@
17470
17508
  }
17471
17509
  }
17472
17510
  },
17473
- "live": "the runner's own CDP sees {target}'s document load (title, marker or URL), or the guard returned its refusal for a refusable step",
17511
+ "live": "the runner's own CDP sees {target}'s document load (title, marker or URL), or the guard returned its refusal for a refusable step; Chrome's trusted-client-only refusal of Emulation.setTimezoneOverride on the ordinary control is not-supported:trustedEmulation",
17474
17512
  "control": {
17475
17513
  "origin": "ordinary",
17476
17514
  "via": "guard",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc-browsers",
3
- "version": "1.18.22",
3
+ "version": "1.19.1",
4
4
  "description": "SLICC's shared browser catalog, JSON schemas and discovery conformance corpus",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -26,6 +26,7 @@
26
26
  "./catalog.json": "./catalog.json",
27
27
  "./corpus.json": "./corpus.json",
28
28
  "./protected.json": "./protected.json",
29
+ "./debugger-stage1.json": "./debugger-stage1.json",
29
30
  "./protected.mjs": "./protected.mjs",
30
31
  "./guard-vectors.json": "./guard-vectors.json",
31
32
  "./guard-driver.mjs": "./guard-driver.mjs",
@@ -35,6 +36,7 @@
35
36
  "./schema/corpus.schema.json": "./schema/corpus.schema.json",
36
37
  "./schema/protected.schema.json": "./schema/protected.schema.json",
37
38
  "./schema/guard-vectors.schema.json": "./schema/guard-vectors.schema.json",
39
+ "./schema/debugger-stage1.schema.json": "./schema/debugger-stage1.schema.json",
38
40
  "./package.json": "./package.json",
39
41
  "./guard-runner.mjs": "./guard-runner.mjs",
40
42
  "./guard-runner": "./guard-runner.mjs",
@@ -45,6 +47,7 @@
45
47
  "catalog.json",
46
48
  "corpus.json",
47
49
  "protected.json",
50
+ "debugger-stage1.json",
48
51
  "protected.mjs",
49
52
  "guard-vectors.json",
50
53
  "guard-driver.mjs",
@@ -68,7 +71,7 @@
68
71
  "validate": "node scripts/validate.mjs",
69
72
  "lint": "slicc-lint && test -z \"$(gofmt -l .)\" && go mod tidy -diff && go vet ./... && GOOS=darwin go vet ./... && GOOS=windows go vet ./... && golangci-lint run && cargo fmt --check && cargo clippy --all-features --all-targets -- -D warnings && cargo check --target wasm32-wasip1 --no-default-features && cargo check --target wasm32-wasip1 --features serde && cargo check --target wasm32-wasip1 --all-features",
70
73
  "format": "biome check --write . && gofmt -w . && cargo fmt",
71
- "test": "export PATH=\"$HOME/.cargo/bin:$PATH\" && node --test --test-concurrency=1 test/integration/self-contained.test.mjs test/integration/seven-corpus.test.mjs test/integration/browser-runner.test.mjs test/integration/fixture-client.test.mjs test/integration/guard-redirect-carrier.test.mjs test/integration/guard-redirect-session-end.test.mjs test/integration/guard-redirect-history.test.mjs test/integration/guard-redirect-iframe.test.mjs test/integration/guard-incomplete.test.mjs test/integration/guard-unparseable-wipe.test.mjs test/integration/guard-browser-ui.test.mjs test/integration/guard-snapshot-settle.test.mjs test/integration/guard-stall.test.mjs test/integration/guard-forged.test.mjs test/integration/guard-exit-steps.test.mjs test/integration/guard-exit-refusal.test.mjs test/integration/guard-frame-read.test.mjs test/integration/guard-bfcache.test.mjs test/integration/guard-bfcache-marker.test.mjs test/integration/guard-bfcache-history.test.mjs test/integration/guard-bfcache-review.test.mjs test/integration/guard-bfcache-quarantine.test.mjs test/integration/guard-error-page-navigation.test.mjs test/integration/guard-error-page-events.test.mjs test/integration/guard-error-page-reload.test.mjs test/integration/guard-world-paint.test.mjs test/integration/gates.test.mjs test/integration/validate.test.mjs test/integration/go.test.mjs test/integration/cargo.test.mjs test/integration/workflows.test.mjs test/integration/guard-sweep-union.test.mjs && node --test --test-concurrency=2 test/integration/guard-lifecycle.test.mjs test/integration/chromium-launch.test.mjs test/integration/guard-fit.test.mjs test/integration/guard-chain.test.mjs test/integration/guard-validation.test.mjs test/integration/guard-liveness.test.mjs test/integration/guard-observations.test.mjs test/integration/guard-child-latency.test.mjs test/integration/guard-adoption.test.mjs test/integration/guard-scoping.test.mjs test/integration/guard-late-pause.test.mjs test/integration/guard-legs.test.mjs test/integration/guard-fetch-enable.test.mjs test/integration/guard-diagnostics.test.mjs test/integration/guard-chrome.test.mjs test/integration/guard-worlds.test.mjs test/integration/guard-world-discovery.test.mjs test/integration/guard-world-guesses.test.mjs test/integration/guard-unparseable.test.mjs test/integration/guard-redirect-secret.test.mjs test/integration/guard-error-page.test.mjs test/integration/guard-discovery.test.mjs test/integration/guard-bfcache-chrome.test.mjs test/integration/guard-browser-page.test.mjs test/integration/guard-scales.test.mjs test/integration/guard-shared-log.test.mjs test/integration/guard-pre-beacon.test.mjs test/integration/guard-world-pause.test.mjs test/integration/guard-parallel.test.mjs test/integration/guard-client-exit.test.mjs test/integration/guard-runner.test.mjs test/integration/guard-sweep-ordinary.test.mjs test/integration/guard-sweep-seven.test.mjs test/integration/guard-sweep-vault.test.mjs test/integration/guard-sweep-vault-x.test.mjs test/integration/guard-sweep-apex.test.mjs test/integration/guard-sweep-others.test.mjs",
74
+ "test": "export PATH=\"$HOME/.cargo/bin:$PATH\" && node --test --test-concurrency=1 test/integration/debugger-stage1-packaging.test.mjs test/integration/debugger-raw-control.test.mjs test/integration/debugger-cleanup.test.mjs test/integration/debugger-stage1-install-vectors.test.mjs test/integration/protected-premise.test.mjs test/integration/debugger-stage1-vectors.test.mjs test/integration/self-contained.test.mjs test/integration/seven-corpus.test.mjs test/integration/browser-runner.test.mjs test/integration/fixture-client.test.mjs test/integration/guard-redirect-carrier.test.mjs test/integration/guard-redirect-session-end.test.mjs test/integration/guard-redirect-history.test.mjs test/integration/guard-redirect-iframe.test.mjs test/integration/guard-incomplete.test.mjs test/integration/guard-unparseable-wipe.test.mjs test/integration/guard-browser-ui.test.mjs test/integration/guard-snapshot-settle.test.mjs test/integration/guard-stall.test.mjs test/integration/guard-forged.test.mjs test/integration/guard-trusted-emulation.test.mjs test/integration/guard-exit-steps.test.mjs test/integration/guard-exit-refusal.test.mjs test/integration/guard-frame-read.test.mjs test/integration/guard-bfcache.test.mjs test/integration/guard-bfcache-marker.test.mjs test/integration/guard-bfcache-history.test.mjs test/integration/guard-bfcache-review.test.mjs test/integration/guard-bfcache-quarantine.test.mjs test/integration/guard-error-page-navigation.test.mjs test/integration/guard-error-page-events.test.mjs test/integration/guard-error-page-reload.test.mjs test/integration/guard-world-paint.test.mjs test/integration/gates.test.mjs test/integration/validate.test.mjs test/integration/go.test.mjs test/integration/cargo.test.mjs test/integration/workflows.test.mjs test/integration/guard-sweep-union.test.mjs && node --test --test-concurrency=2 test/integration/guard-lifecycle.test.mjs test/integration/chromium-launch.test.mjs test/integration/guard-fit.test.mjs test/integration/guard-chain.test.mjs test/integration/guard-validation.test.mjs test/integration/guard-liveness.test.mjs test/integration/guard-observations.test.mjs test/integration/guard-child-latency.test.mjs test/integration/guard-adoption.test.mjs test/integration/guard-scoping.test.mjs test/integration/guard-late-pause.test.mjs test/integration/guard-legs.test.mjs test/integration/guard-fetch-enable.test.mjs test/integration/guard-diagnostics.test.mjs test/integration/guard-chrome.test.mjs test/integration/guard-worlds.test.mjs test/integration/guard-world-discovery.test.mjs test/integration/guard-world-guesses.test.mjs test/integration/guard-unparseable.test.mjs test/integration/guard-redirect-secret.test.mjs test/integration/guard-error-page.test.mjs test/integration/guard-discovery.test.mjs test/integration/guard-bfcache-chrome.test.mjs test/integration/guard-browser-page.test.mjs test/integration/guard-scales.test.mjs test/integration/guard-shared-log.test.mjs test/integration/guard-pre-beacon.test.mjs test/integration/guard-world-pause.test.mjs test/integration/guard-parallel.test.mjs test/integration/guard-client-exit.test.mjs test/integration/guard-runner.test.mjs test/integration/guard-sweep-ordinary.test.mjs test/integration/guard-sweep-seven.test.mjs test/integration/guard-sweep-vault.test.mjs test/integration/guard-sweep-vault-x.test.mjs test/integration/guard-sweep-apex.test.mjs test/integration/guard-sweep-others.test.mjs",
72
75
  "test:unit": "mkdir -p coverage/unit && node --experimental-test-coverage --test --test-concurrency=1 --test-reporter=lcov --test-reporter-destination=coverage/unit/lcov.info test/unit/*.test.mjs && go test -race -cover ./...",
73
76
  "build": "go build ./... && cargo build --all-features && cargo build --target wasm32-wasip1 --all-features && npm pack --dry-run",
74
77
  "prepublishOnly": "node scripts/set-crate-version.mjs \"$npm_package_version\"",
@@ -79,8 +82,8 @@
79
82
  "test:unit:guard": "mkdir -p coverage/unit && node --experimental-vm-modules --no-warnings --experimental-test-coverage --test --test-concurrency=1 --test-coverage-include=guard-runner.mjs --test-coverage-include=guard-driver.mjs --test-coverage-include=fixture-server.mjs --test-coverage-include=fixture-client.mjs --test-coverage-include=observer-target.mjs --test-coverage-include=frame-read.mjs --test-coverage-include=bfcache-restore.mjs --test-coverage-include=protected-error-page.mjs --test-coverage-include=unparseable-url.mjs --test-coverage-include=scripts/browser-runner.mjs --test-coverage-include=scripts/validate.mjs --test-reporter=lcov --test-reporter-destination=coverage/unit/guard.lcov test/unit/guard-*.test.mjs && slicc-diff-cover coverage/unit/guard.lcov"
80
83
  },
81
84
  "devDependencies": {
82
- "@ai-ecoverse/slicc-cdp": "1.44.2",
83
- "@ai-ecoverse/slicc-shared-web": "2.13.8",
85
+ "@ai-ecoverse/slicc-cdp": "1.45.0",
86
+ "@ai-ecoverse/slicc-shared-web": "2.13.10",
84
87
  "@biomejs/biome": "2.6.3",
85
88
  "ajv": "8.20.0",
86
89
  "ajv-formats": "3.0.1",
package/protected.json CHANGED
@@ -5,6 +5,16 @@
5
5
  "unparseableRefusal": "slicc: refused: slicc can't parse this URL, so it could be a protected page",
6
6
  "origins": ["http://127.0.0.1:5710", "https://seven.example.test"],
7
7
  "urls": [
8
+ { "url": "http://sliccy.ai/cdp-premise", "protected": true },
9
+ { "url": "https://sliccy.ai/cdp-premise", "protected": true },
10
+ { "url": "http://www.sliccy.ai/cdp-premise", "protected": true },
11
+ { "url": "https://www.sliccy.ai/cdp-premise", "protected": true },
12
+ { "url": "http://seven.sliccy.ai/cdp-premise", "protected": true },
13
+ { "url": "https://seven.sliccy.ai/cdp-premise", "protected": true },
14
+ { "url": "http://vault.sliccy.ai/cdp-premise", "protected": true },
15
+ { "url": "https://vault.sliccy.ai/cdp-premise", "protected": true },
16
+ { "url": "http://arbitrary-premise.sliccy.ai/cdp-premise", "protected": true },
17
+ { "url": "https://arbitrary-premise.sliccy.ai/cdp-premise", "protected": true },
8
18
  {
9
19
  "url": "http://exa mple.sliccy.ai/",
10
20
  "protected": true
@@ -739,6 +749,16 @@
739
749
  }
740
750
  ],
741
751
  "targets": [
752
+ { "url": "http://sliccy.ai/cdp-premise", "type": "page", "protected": true },
753
+ { "url": "https://sliccy.ai/cdp-premise", "type": "page", "protected": true },
754
+ { "url": "http://www.sliccy.ai/cdp-premise", "type": "page", "protected": true },
755
+ { "url": "https://www.sliccy.ai/cdp-premise", "type": "page", "protected": true },
756
+ { "url": "http://seven.sliccy.ai/cdp-premise", "type": "page", "protected": true },
757
+ { "url": "https://seven.sliccy.ai/cdp-premise", "type": "page", "protected": true },
758
+ { "url": "http://vault.sliccy.ai/cdp-premise", "type": "page", "protected": true },
759
+ { "url": "https://vault.sliccy.ai/cdp-premise", "type": "page", "protected": true },
760
+ { "url": "http://arbitrary-premise.sliccy.ai/cdp-premise", "type": "page", "protected": true },
761
+ { "url": "https://arbitrary-premise.sliccy.ai/cdp-premise", "type": "page", "protected": true },
742
762
  {
743
763
  "url": "https://seven.sliccy.ai/path?secret=query#fragment",
744
764
  "documentURL": "chrome-error://chromewebdata/",
@@ -0,0 +1,87 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/ai-ecoverse/slicc-browsers/schema/debugger-stage1.schema.json",
4
+ "title": "slicc-browsers Stage 1 debugger conformance vectors, schema 1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "methods", "rows", "navigation", "leaseRefusals", "rescueEvidence"],
8
+ "properties": {
9
+ "schemaVersion": { "const": 1 },
10
+ "methods": {
11
+ "type": "array",
12
+ "minItems": 1,
13
+ "uniqueItems": true,
14
+ "items": {
15
+ "type": "object",
16
+ "additionalProperties": false,
17
+ "required": ["method", "lifetime", "admitted"],
18
+ "properties": {
19
+ "method": { "$ref": "#/$defs/name" },
20
+ "lifetime": { "enum": ["persistent", "document", "cleanup", "pause-control", "unknown"] },
21
+ "admitted": { "type": "boolean" },
22
+ "ownedInstrumentationOnly": { "type": "boolean" }
23
+ }
24
+ }
25
+ },
26
+ "rows": {
27
+ "type": "array",
28
+ "minItems": 1,
29
+ "uniqueItems": true,
30
+ "items": {
31
+ "type": "object",
32
+ "additionalProperties": false,
33
+ "required": ["id", "mode", "destination", "expected", "requires"],
34
+ "properties": {
35
+ "id": { "$ref": "#/$defs/name" },
36
+ "mode": { "$ref": "#/$defs/name" },
37
+ "destination": { "$ref": "#/$defs/name" },
38
+ "expected": {
39
+ "type": "object",
40
+ "additionalProperties": false,
41
+ "required": ["admitted", "released"],
42
+ "properties": {
43
+ "admitted": { "type": "boolean" },
44
+ "published": { "type": "boolean" },
45
+ "installed": { "type": "boolean" },
46
+ "liveReads": { "type": "boolean" },
47
+ "released": { "type": "boolean" },
48
+ "converted": { "type": "boolean" },
49
+ "committed": { "type": "boolean" },
50
+ "forwarded": { "type": "boolean" }
51
+ }
52
+ },
53
+ "requires": { "$ref": "#/$defs/names" }
54
+ }
55
+ }
56
+ },
57
+ "navigation": { "$ref": "#/$defs/names" },
58
+ "leaseRefusals": { "$ref": "#/$defs/names" },
59
+ "rescueEvidence": {
60
+ "type": "object",
61
+ "additionalProperties": false,
62
+ "required": [
63
+ "origin",
64
+ "noObserverResume",
65
+ "ownerUnchanged",
66
+ "generationUnchanged",
67
+ "deadlineUnchanged"
68
+ ],
69
+ "properties": {
70
+ "origin": { "$ref": "#/$defs/name" },
71
+ "noObserverResume": { "type": "boolean" },
72
+ "ownerUnchanged": { "type": "boolean" },
73
+ "generationUnchanged": { "type": "boolean" },
74
+ "deadlineUnchanged": { "type": "boolean" }
75
+ }
76
+ }
77
+ },
78
+ "$defs": {
79
+ "name": { "type": "string", "minLength": 1 },
80
+ "names": {
81
+ "type": "array",
82
+ "minItems": 1,
83
+ "uniqueItems": true,
84
+ "items": { "$ref": "#/$defs/name" }
85
+ }
86
+ }
87
+ }