feat(protocol): bump to 1.1 and redefine record traces as state-linked v3

Replace page-indexed record traces with states/steps + FillCommit/hover/scroll,
and raise daemon/extension protocol floors together so old 1.0 peers are rejected.
This commit is contained in:
“haonan”
2026-08-13 19:31:35 +08:00
parent 37fbaacc94
commit 1508839bf9
23 changed files with 1000 additions and 753 deletions
+191 -131
View File
@@ -5,45 +5,65 @@
"type": "object",
"required": [
"entry",
"pages",
"recorded_at",
"steps"
"recorder",
"states",
"steps",
"stopped_by",
"version"
],
"properties": {
"entry": {
"$ref": "#/definitions/TraceEntry"
},
"pages": {
"type": "array",
"items": {
"$ref": "#/definitions/PageRef"
}
},
"purpose": {
"description": "Optional user-provided goal from `--purpose` (metadata only).",
"type": [
"string",
"null"
]
},
"recorded_at": {
"description": "RFC 3339 timestamp when recording stopped.",
"type": "string"
},
"recorder": {
"$ref": "#/definitions/RecorderInfo"
},
"started_at": {
"type": [
"string",
"null"
]
},
"states": {
"type": "array",
"items": {
"$ref": "#/definitions/TraceState"
}
},
"steps": {
"type": "array",
"items": {
"$ref": "#/definitions/Step"
}
},
"stopped_by": {
"$ref": "#/definitions/StopReason"
},
"version": {
"type": "integer",
"format": "uint32",
"minimum": 0.0
}
},
"definitions": {
"FillCommit": {
"type": "string",
"enum": [
"enter",
"suggestion",
"blur"
]
},
"KeyModifier": {
"description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).",
"type": "string",
@@ -54,25 +74,32 @@
"shift"
]
},
"PageRef": {
"description": "Page context dictionary entry — referenced by steps via `page` id.",
"NavigationCause": {
"type": "string",
"enum": [
"user_typed",
"link",
"form_submit",
"reload",
"history",
"script",
"browser"
]
},
"RecorderInfo": {
"type": "object",
"required": [
"id",
"url"
"bsk",
"vom"
],
"properties": {
"id": {
"bsk": {
"type": "string"
},
"title": {
"type": [
"string",
"null"
]
},
"url": {
"type": "string"
"vom": {
"type": "integer",
"format": "uint32",
"minimum": 0.0
}
}
},
@@ -101,21 +128,16 @@
"description": "Fields shared by every step variant (flattened in JSON).",
"type": "object",
"required": [
"cause",
"id",
"op",
"page",
"result",
"state",
"to"
],
"properties": {
"effect": {
"anyOf": [
{
"$ref": "#/definitions/StepEffect"
},
{
"type": "null"
}
]
"cause": {
"$ref": "#/definitions/NavigationCause"
},
"id": {
"type": "integer",
@@ -128,8 +150,11 @@
"navigate"
]
},
"page": {
"description": "Reference into `pages[]`.",
"result": {
"$ref": "#/definitions/StepResult"
},
"state": {
"description": "Observation id immediately before this action.",
"type": "string"
},
"to": {
@@ -143,20 +168,11 @@
"required": [
"id",
"op",
"page",
"result",
"state",
"target"
],
"properties": {
"effect": {
"anyOf": [
{
"$ref": "#/definitions/StepEffect"
},
{
"type": "null"
}
]
},
"id": {
"type": "integer",
"format": "uint32",
@@ -168,8 +184,11 @@
"click"
]
},
"page": {
"description": "Reference into `pages[]`.",
"result": {
"$ref": "#/definitions/StepResult"
},
"state": {
"description": "Observation id immediately before this action.",
"type": "string"
},
"target": {
@@ -183,20 +202,11 @@
"required": [
"id",
"op",
"page",
"result",
"state",
"target"
],
"properties": {
"effect": {
"anyOf": [
{
"$ref": "#/definitions/StepEffect"
},
{
"type": "null"
}
]
},
"id": {
"type": "integer",
"format": "uint32",
@@ -208,8 +218,11 @@
"hover"
]
},
"page": {
"description": "Reference into `pages[]`.",
"result": {
"$ref": "#/definitions/StepResult"
},
"state": {
"description": "Observation id immediately before this action.",
"type": "string"
},
"target": {
@@ -221,22 +234,17 @@
"description": "Fields shared by every step variant (flattened in JSON).",
"type": "object",
"required": [
"commit",
"id",
"op",
"page",
"result",
"state",
"target",
"value"
],
"properties": {
"effect": {
"anyOf": [
{
"$ref": "#/definitions/StepEffect"
},
{
"type": "null"
}
]
"commit": {
"$ref": "#/definitions/FillCommit"
},
"id": {
"type": "integer",
@@ -249,15 +257,15 @@
"fill"
]
},
"page": {
"description": "Reference into `pages[]`.",
"type": "string"
},
"redacted": {
"type": [
"boolean",
"null"
]
"type": "boolean"
},
"result": {
"$ref": "#/definitions/StepResult"
},
"state": {
"description": "Observation id immediately before this action.",
"type": "string"
},
"target": {
"$ref": "#/definitions/TargetDescriptor"
@@ -273,21 +281,11 @@
"required": [
"id",
"op",
"page",
"selection",
"result",
"state",
"target"
],
"properties": {
"effect": {
"anyOf": [
{
"$ref": "#/definitions/StepEffect"
},
{
"type": "null"
}
]
},
"id": {
"type": "integer",
"format": "uint32",
@@ -299,9 +297,8 @@
"select"
]
},
"page": {
"description": "Reference into `pages[]`.",
"type": "string"
"result": {
"$ref": "#/definitions/StepResult"
},
"selection": {
"type": "array",
@@ -309,6 +306,10 @@
"$ref": "#/definitions/SelectedOption"
}
},
"state": {
"description": "Observation id immediately before this action.",
"type": "string"
},
"target": {
"$ref": "#/definitions/TargetDescriptor"
}
@@ -321,19 +322,10 @@
"id",
"key",
"op",
"page"
"result",
"state"
],
"properties": {
"effect": {
"anyOf": [
{
"$ref": "#/definitions/StepEffect"
},
{
"type": "null"
}
]
},
"id": {
"type": "integer",
"format": "uint32",
@@ -357,8 +349,11 @@
"press"
]
},
"page": {
"description": "Reference into `pages[]`.",
"result": {
"$ref": "#/definitions/StepResult"
},
"state": {
"description": "Observation id immediately before this action.",
"type": "string"
},
"target": {
@@ -372,48 +367,74 @@
]
}
}
},
{
"description": "Fields shared by every step variant (flattened in JSON).",
"type": "object",
"required": [
"id",
"op",
"result",
"state"
],
"properties": {
"id": {
"type": "integer",
"format": "uint32",
"minimum": 0.0
},
"op": {
"type": "string",
"enum": [
"scroll"
]
},
"result": {
"$ref": "#/definitions/StepResult"
},
"state": {
"description": "Observation id immediately before this action.",
"type": "string"
}
}
}
]
},
"StepEffect": {
"description": "Observed navigation after a step (objective fact only).",
"StepResult": {
"type": "object",
"required": [
"navigated_to"
"state"
],
"properties": {
"navigated_to": {
"description": "Reference into `pages[]` for the destination page.",
"state": {
"type": "string"
}
}
},
"StopReason": {
"type": "string",
"enum": [
"user_finish",
"cli_stop"
]
},
"TargetDescriptor": {
"description": "Stable semantic handle for an interacted element.\n\n`name` and `nearby_label` are **untrusted page text**.",
"description": "Stable semantic handle for an interacted element within a page observation.",
"type": "object",
"required": [
"tag"
],
"properties": {
"ctx": {
"type": [
"string",
"null"
]
},
"name": {
"type": [
"string",
"null"
]
},
"name_attr": {
"type": [
"string",
"null"
]
},
"nearby_label": {
"type": [
"string",
"null"
]
},
"placeholder": {
"ref": {
"type": [
"string",
"null"
@@ -425,8 +446,8 @@
"null"
]
},
"tag": {
"type": "string"
"unmatched": {
"type": "boolean"
}
}
},
@@ -441,6 +462,45 @@
"type": "string"
}
}
},
"TraceState": {
"description": "Page observation dictionary entry — referenced by steps via `state` / `result.state`.",
"type": "object",
"required": [
"id",
"url"
],
"properties": {
"body": {
"description": "Wire-only: full page observation (front matter + VOM body + annotations).",
"type": [
"string",
"null"
]
},
"id": {
"type": "string"
},
"page": {
"description": "Disk-only: filename under the bundle `pages/` directory.",
"type": [
"string",
"null"
]
},
"title": {
"type": [
"string",
"null"
]
},
"truncated": {
"type": "boolean"
},
"url": {
"type": "string"
}
}
}
}
}