planr 1.10.0-alpha.13 → 1.10.0-alpha.14

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.
@@ -1,6 +1,8 @@
1
1
  # Browser Harness adapter v1
2
2
 
3
- Status: frozen for `planr-browser-harness-adapter` v1.
3
+ Status: historical. The current adapter hard-cuts to
4
+ `BROWSER_HARNESS_ADAPTER_V2.md`; it does not accept this v1 payload schema or
5
+ its shared-action/final-observation execution shape.
4
6
 
5
7
  This reference defines Planr's first process adapter for the external
6
8
  `browser-harness` tool. The adapter implements
@@ -76,10 +78,7 @@ The adapter does not advertise a visual observation type. Planr therefore
76
78
  rejects it during capability matching for a visual requirement. A recording or
77
79
  screenshot cannot upgrade `com.planr.web.dom_state` into visual Evidence.
78
80
 
79
- ## Canonical live fixture
81
+ ## Historical fixture
80
82
 
81
- `tests/fixtures/evidence/browser-harness/v1/form.html` and
82
- `form-request.json` exercise the provider-free live boundary: one existing HTTP
83
- target, one Browser Harness session, bounded fill/select/click actions, and one
84
- structured DOM postcondition. The fixture requires a dedicated headless browser
85
- endpoint and never starts a model provider.
83
+ The executable v1 fixture was removed with the v2 hard cut. The maintained
84
+ provider-free fixture lives under `tests/fixtures/evidence/browser-harness/v2/`.
@@ -0,0 +1,120 @@
1
+ # Browser Harness adapter v2
2
+
3
+ Status: frozen for `planr-browser-harness-adapter` v2.
4
+
5
+ This reference defines Planr's provider-neutral process adapter for the
6
+ external `browser-harness` tool. The adapter implements
7
+ `EVIDENCE_ADAPTER_PROTOCOL_V1.md`. Planr Core owns execution and trust; this
8
+ adapter owns only the closed browser scenario and its structured observations.
9
+
10
+ ## Capability
11
+
12
+ The adapter supports `com.planr.web.dom_state` observations with payload schema
13
+ `schema://com.planr.web.dom_state.v2`.
14
+
15
+ Every requirement uses a CSS selector in `subject`. Its `expected` object may
16
+ select only these mechanically observed fields:
17
+
18
+ - exact normalized `text` and rendered `visible` state;
19
+ - `contains_text` and `excludes_text` lists;
20
+ - a named local-storage document's presence, transaction count, and equality
21
+ to an earlier scenario snapshot;
22
+ - selected option text keyed by visible select label;
23
+ - unnamed-control and unlabelled-field counts;
24
+ - horizontal page overflow;
25
+ - browser runtime/console error and external-request counts.
26
+
27
+ Exactly one requirement in a batch carries a closed `state_transitions`
28
+ declaration with `scenario_id` and `steps`. Every sibling carries only the
29
+ matching `scenario_ref`; declaration position has no semantic meaning. This
30
+ keeps one sealed scenario in the work packet without making the first
31
+ observation an authority or duplicating a large action list. All requirements
32
+ use the same optional execution method. The scenario contains 1 to 256 steps
33
+ from this exact action set:
34
+
35
+ - `fill` or `select` one control by CSS `subject` or exact visible `label`;
36
+ - `click` one control by accessibility role and name (or the closed
37
+ button-or-link role `control`), optionally within a container containing
38
+ exact scope text;
39
+ - `reset` one named application storage key and navigate the bound target;
40
+ - `snapshot_storage` under one bounded scenario-local ID;
41
+ - `reload` the current document;
42
+ - `viewport` with a bounded width and height;
43
+ - `checkpoint` with one or more sealed requirement IDs and an optional prior
44
+ storage snapshot comparison.
45
+
46
+ There must be exactly one declaration and every reference must resolve to it.
47
+ Checkpoint requirement IDs are unique across the scenario and their union must
48
+ equal the exact sealed batch requirement set. A checkpoint can reference only
49
+ a storage snapshot created earlier in the same scenario. Arbitrary JavaScript,
50
+ unknown actions, unsealed requirements, mixed scenarios, mixed execution
51
+ methods, and foreign targets are rejected before Browser Harness starts.
52
+
53
+ ## Execution
54
+
55
+ An availability probe runs `browser-harness --version`. A real Evidence run
56
+ starts Browser Harness once and sends one generated Python program over stdin.
57
+ The capability manifest can allow the Browser Harness connection variables,
58
+ including `BU_NAME`, `BU_CDP_URL`, and `BU_CDP_WS`. Planr binds the captured
59
+ connection configuration to the capability instance and forwards it through
60
+ the process environment only when the host independently names each variable in
61
+ `PLANR_ADAPTER_ENV_ALLOWLIST`. If no connection variable is present, Browser
62
+ Harness uses its configured default connection. Planr does not infer or start a
63
+ browser product. A host may additionally classify local, non-secret connection
64
+ configuration in `PLANR_ADAPTER_PUBLIC_ENV_ALLOWLIST`. Remote endpoints or
65
+ credentials remain non-public unless the host explicitly decides otherwise.
66
+
67
+ The program:
68
+
69
+ 1. Opens one blank tab and enables Page, Runtime, Network, and Log observation.
70
+ 2. Navigates to the exact Planr-bound HTTP or HTTPS target.
71
+ 3. Executes the one sealed scenario in that tab.
72
+ 4. At each checkpoint, stabilizes and evaluates all named requirements
73
+ together for at most 750 ms.
74
+ 5. Applies one 15-second total scenario deadline; it never applies a separate
75
+ timeout per requirement.
76
+ 6. Returns one structured result containing exactly one actual for every
77
+ sealed requirement.
78
+ 7. Closes the tab on every exit path.
79
+
80
+ The generated program inserts scenario and requirement data only as JSON. A
81
+ requirement cannot add executable Python or JavaScript.
82
+
83
+ ## Result and trust
84
+
85
+ Each actual conforms to
86
+ `docs/contracts/schemas/com.planr.web.dom_state.v2.schema.json`. Planr Core
87
+ validates the schema and evaluates the expected predicate independently for
88
+ each requirement. One failed checkpoint observation therefore produces a
89
+ trusted non-passing receipt without discarding passing siblings.
90
+
91
+ If every requirement selects the `browser-harness` agent skill, the adapter
92
+ also returns the matching supervised invocation record. This record becomes
93
+ trusted only after Planr validates the observed process and every sealed
94
+ binding. It never assigns provenance or coverage itself.
95
+
96
+ ## Capture and resource policy
97
+
98
+ The successful path disables Browser Harness recordings and does not capture
99
+ screenshots or traces. Structured DOM, storage, selection, accessibility,
100
+ layout, runtime, and request observations are the retained proof for this
101
+ non-visual capability. The adapter uses one tab and one Browser Harness process
102
+ per batch.
103
+
104
+ The adapter does not advertise a visual observation type. Screenshots cannot
105
+ upgrade this capability into visual Evidence.
106
+
107
+ ## Version transition
108
+
109
+ V2 is a hard cut. The active adapter accepts only
110
+ `schema://com.planr.web.dom_state.v2` and the exact checkpoint scenario. It has
111
+ no runtime fallback for v1 shared actions followed by independent five-second
112
+ polls. Historical v1 receipts remain immutable records; they do not create a
113
+ second active adapter path.
114
+
115
+ ## Canonical live fixture
116
+
117
+ `tests/fixtures/evidence/browser-harness/v2/form.html` and
118
+ `form-request.json` exercise the provider-free live boundary: one existing HTTP
119
+ target, one Browser Harness session, bounded label-driven actions, one explicit
120
+ checkpoint, one structured DOM postcondition, and no model provider.
@@ -27,10 +27,40 @@ An availability probe starts the same executable with closed, empty stdin. The
27
27
  adapter can use that invocation to check runtime availability. A probe result
28
28
  cannot satisfy an Evidence requirement.
29
29
 
30
- Planr reserves the `PLANR_EVIDENCE_` environment variable namespace. An adapter
30
+ Planr reserves the complete `PLANR_` environment variable namespace. An adapter
31
31
  request does not use environment variables for target, environment, or contract
32
32
  bindings.
33
33
 
34
+ A process capability can declare `permissions.environment` as
35
+ `read_env:NAME[,NAME]`. This repository-authored declaration is necessary but
36
+ not sufficient. The host or user must independently include every requested
37
+ name in `PLANR_ADAPTER_ENV_ALLOWLIST`; repository content cannot change that
38
+ authorization. A manifest that reads host variables must also declare
39
+ `permissions.secrets = host_allowlist` to acknowledge that values remain
40
+ host-authorized even when a variable name appears non-secret.
41
+
42
+ Planr captures only the intersection of the manifest request and the host
43
+ authorization. The capability instance and sealed run index bind the variable
44
+ names, the host's public/non-public classification, and a digest of the present
45
+ values. Planr does not persist the values in that binding. At execution, Planr
46
+ clears the process environment, adds `PATH`, and forwards the captured values. A
47
+ changed value, classification, or host authorization invalidates the sealed run
48
+ before the adapter starts. Requested names in the complete `PLANR_` namespace
49
+ are invalid because only Planr Core can own that namespace.
50
+
51
+ Forwarded values are non-public by default. The host may independently list
52
+ known non-secret configuration names in `PLANR_ADAPTER_PUBLIC_ENV_ALLOWLIST`.
53
+ This list does not authorize access; it must remain a subset of the names that
54
+ the manifest requests and `PLANR_ADAPTER_ENV_ALLOWLIST` authorizes. Before
55
+ result validation, Planr rejects an adapter result that exposes an exact
56
+ non-public value, records `verifier_failed`, and redacts that value from durable
57
+ stdout and stderr excerpts while retaining the digests of the observed output.
58
+ Forwarded adapter values are never passed to a supervised target process.
59
+
60
+ This allowlist configures the adapter transport. It does not replace the
61
+ `target`, `environment`, or `execution_contract_digest` fields in the sealed
62
+ request.
63
+
34
64
  ## `planr.evidence.adapter-request.v1`
35
65
 
36
66
  The request has these fields:
@@ -85,10 +115,22 @@ provenance or coverage.
85
115
  Planr rejects the result if the process fails or if any required binding does
86
116
  not match. This includes a stale request ID, a stale request digest, a wrong
87
117
  target, a wrong environment, a wrong execution contract, missing observations,
88
- extra observations, a schema mismatch, and an unsatisfied expected predicate.
89
-
90
- Planr records the failed attempt. Planr does not create a trusted passing
91
- receipt from that result.
118
+ extra observations, or a schema mismatch.
119
+
120
+ An `actual` object that is valid for its registered payload schema but does not
121
+ satisfy the requirement's expected predicate is a product observation, not a
122
+ protocol rejection. Planr preserves that validated `actual`, assigns `failed`
123
+ only to that observation, records `product_failed` for its coverage gap, and
124
+ creates a trusted non-passing receipt. Other observations from the same exact
125
+ execution retain their own validated outcomes. The containing attempt is
126
+ failed when any selected observation fails.
127
+
128
+ Planr records failed attempts. A runtime target binding failure is
129
+ `target_mismatch`; malformed or schema-invalid observation data is
130
+ `schema_mismatch`. Neither code may replace `product_failed`, and one failed
131
+ observation may not contaminate sibling observations with a receipt-wide gap.
132
+ No non-passing result can create a trusted passing receipt or satisfy complete
133
+ coverage.
92
134
 
93
135
  ## Version transition
94
136
 
@@ -190,7 +190,8 @@ Required fields:
190
190
  - A fresh canonical invocation may append a superseding admission for the same exact active source freeze only when the previously admitted run-index digest already has both a durable Evidence attempt and receipt. The previous admission and execution history remain immutable. A conflicting admission with no execution receipt is pre-receipt state and remains rejected; it cannot bypass Verification Admission Repair.
191
191
  - When source is stale after such a receipt, one canonical broker invocation may perform exactly one observed refresh: invalidate and preserve the old freeze and receipt bindings, release the exact verifier lease, freeze the current source, reacquire verification, and seal again. The broker does not repeat this transition if the replacement source becomes stale.
192
192
  - Process adapters declare a closed `availability_probe.kind = process` contract with executable name, arguments, optional working directory, timeout, stdout/stderr byte limits, and the payload schema binding for emitted observations.
193
- - A repository adapter registration may additionally declare one exact `execution_contract.target_lifecycle` with `kind = supervised_process`, a bare executable, arguments, an optional repository-relative working directory, and bounded TCP readiness. The repository or user owns that command; Planr never infers a framework or package manager. When omitted, the target remains externally managed. When present, Planr requires the sealed loopback endpoint to be unreachable before launch, resolves and starts the declared process only after Evidence admission, waits for that endpoint to become ready, runs the adapter, and tears down the complete target process tree on every exit path. Startup, readiness, or premature-exit failure produces a failed attempt with `external_dependency_unavailable`; it cannot satisfy coverage.
193
+ - A process capability may declare `permissions.environment = read_env:NAME[,NAME]` together with `permissions.secrets = host_allowlist`. The host or user must independently authorize every requested name through `PLANR_ADAPTER_ENV_ALLOWLIST`; a repository declaration alone cannot expose a host value. Planr forwards only present values in that intersection to the Evidence adapter, never to a supervised product target. Forwarded values are non-public by default; the host may classify known non-secret configuration names through `PLANR_ADAPTER_PUBLIC_ENV_ALLOWLIST`, which never grants read access by itself. The capability environment and sealed run index bind the requested names, public classification, and a digest of the values. A value, classification, or authorization change makes the sealed adapter environment stale. The binding never stores raw values, the complete `PLANR_` namespace is reserved, and an adapter output that contains an exact non-public forwarded value fails closed and is redacted before result validation.
194
+ - A repository adapter registration may additionally declare one exact `execution_contract.target_lifecycle` with `kind = supervised_process`, a bare executable, arguments, an optional repository-relative working directory, and bounded TCP readiness. The repository or user owns that command; Planr never infers a framework or package manager. When omitted, the target remains externally managed. When present, Planr requires the sealed loopback endpoint to be unreachable before launch, resolves and starts the declared process only after Evidence admission, waits for that endpoint to become ready, runs the adapter, and tears down the complete target process tree on every exit path. On Unix, Planr observes leader exit without reaping it, terminates the still-identity-anchored process group, and only then reaps the leader; it never signals a released numeric process-group ID. Startup, readiness, or premature-exit failure produces a failed attempt with `external_dependency_unavailable`; it cannot satisfy coverage.
194
195
  - Availability probes cannot declare a target lifecycle. They test only whether the Evidence capability itself is available and never start the product under verification.
195
196
 
196
197
  A manifest is a claim about what a method can observe. It is not proof that the method is available now.
@@ -246,6 +247,16 @@ Required fields:
246
247
 
247
248
  Receipts can satisfy coverage only when trusted, fresh, policy-compliant, target-matched, schema-valid, and observation-equivalent to the requirement.
248
249
 
250
+ `receipt_status = trusted` describes provenance and binding integrity, not a
251
+ passing product result. One Planr-observed execution may produce one trusted
252
+ receipt with mixed observation outcomes. Every schema-valid `actual` is
253
+ preserved and evaluated independently: a satisfied predicate is `passed`; an
254
+ unsatisfied predicate is `failed` with the canonical `product_failed` coverage
255
+ gap. Mixed siblings do not inherit that gap. Complete coverage remains
256
+ unsatisfied until every binding observation is covered by a passing result.
257
+ Target-binding errors remain `target_mismatch`; malformed or schema-invalid
258
+ observation payloads remain `schema_mismatch`.
259
+
249
260
  ### CoverageVerdict
250
261
 
251
262
  The canonical coverage result for a criterion, item, plan, or goal.
@@ -296,6 +307,10 @@ Policy layers may strengthen lower-level requirements. Weakening requires an exp
296
307
 
297
308
  - `trusted`, `rejected`, `untrusted`, `stale`, `superseded`.
298
309
 
310
+ Receipt status and observation outcome are orthogonal. In particular,
311
+ `trusted` never means `passed`; it can identify a trusted non-passing receipt
312
+ whose validated observations include one or more `failed` outcomes.
313
+
299
314
  `VerificationCapabilityInstance.availability.status` values:
300
315
 
301
316
  - `available`, `unavailable`, `degraded`, `permission_denied`, `sandbox_blocked`, `unsupported`, `probe_failed`.
@@ -847,10 +847,17 @@
847
847
  "$ref": "#/$defs/JsonObject"
848
848
  },
849
849
  "state_transitions": {
850
- "type": "array",
851
- "items": {
852
- "$ref": "#/$defs/JsonObject"
853
- }
850
+ "oneOf": [
851
+ {
852
+ "type": "array",
853
+ "items": {
854
+ "$ref": "#/$defs/JsonObject"
855
+ }
856
+ },
857
+ {
858
+ "$ref": "#/$defs/JsonObject"
859
+ }
860
+ ]
854
861
  },
855
862
  "persistence": {
856
863
  "$ref": "#/$defs/JsonObject"
@@ -0,0 +1,139 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "schema://com.planr.web.dom_state.v2",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": [
7
+ "schema_ref",
8
+ "selector",
9
+ "text",
10
+ "visible",
11
+ "contains_text",
12
+ "excludes_text",
13
+ "storage",
14
+ "selected",
15
+ "accessibility",
16
+ "layout",
17
+ "runtime"
18
+ ],
19
+ "properties": {
20
+ "schema_ref": {
21
+ "const": "schema://com.planr.web.dom_state.v2"
22
+ },
23
+ "selector": {
24
+ "type": "string",
25
+ "minLength": 1
26
+ },
27
+ "text": {
28
+ "type": [
29
+ "string",
30
+ "null"
31
+ ]
32
+ },
33
+ "visible": {
34
+ "type": "boolean"
35
+ },
36
+ "contains_text": {
37
+ "type": "array",
38
+ "items": {
39
+ "type": "string"
40
+ }
41
+ },
42
+ "excludes_text": {
43
+ "type": "array",
44
+ "items": {
45
+ "type": "string"
46
+ }
47
+ },
48
+ "storage": {
49
+ "oneOf": [
50
+ {
51
+ "type": "null"
52
+ },
53
+ {
54
+ "type": "object",
55
+ "additionalProperties": false,
56
+ "required": [
57
+ "key",
58
+ "present",
59
+ "transaction_count",
60
+ "matches_snapshot"
61
+ ],
62
+ "properties": {
63
+ "key": {
64
+ "type": "string",
65
+ "minLength": 1
66
+ },
67
+ "present": {
68
+ "type": "boolean"
69
+ },
70
+ "transaction_count": {
71
+ "type": [
72
+ "integer",
73
+ "null"
74
+ ],
75
+ "minimum": 0
76
+ },
77
+ "matches_snapshot": {
78
+ "type": "boolean"
79
+ }
80
+ }
81
+ }
82
+ ]
83
+ },
84
+ "selected": {
85
+ "type": "object",
86
+ "additionalProperties": {
87
+ "type": "string"
88
+ }
89
+ },
90
+ "accessibility": {
91
+ "type": "object",
92
+ "additionalProperties": false,
93
+ "required": [
94
+ "unnamed_controls",
95
+ "unlabelled_fields"
96
+ ],
97
+ "properties": {
98
+ "unnamed_controls": {
99
+ "type": "integer",
100
+ "minimum": 0
101
+ },
102
+ "unlabelled_fields": {
103
+ "type": "integer",
104
+ "minimum": 0
105
+ }
106
+ }
107
+ },
108
+ "layout": {
109
+ "type": "object",
110
+ "additionalProperties": false,
111
+ "required": [
112
+ "horizontal_overflow"
113
+ ],
114
+ "properties": {
115
+ "horizontal_overflow": {
116
+ "type": "boolean"
117
+ }
118
+ }
119
+ },
120
+ "runtime": {
121
+ "type": "object",
122
+ "additionalProperties": false,
123
+ "required": [
124
+ "error_count",
125
+ "external_request_count"
126
+ ],
127
+ "properties": {
128
+ "error_count": {
129
+ "type": "integer",
130
+ "minimum": 0
131
+ },
132
+ "external_request_count": {
133
+ "type": "integer",
134
+ "minimum": 0
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "planr",
3
- "version": "1.10.0-alpha.13",
3
+ "version": "1.10.0-alpha.14",
4
4
  "description": "Local-first planning and execution coordination for coding agents.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "planr",
3
3
  "description": "Skill-driven planning and execution loop for coding agents: one planr entry point, an autonomous planr-loop, and evidence-backed task graph skills powered by the planr CLI.",
4
- "version": "1.10.0-alpha.13",
4
+ "version": "1.10.0-alpha.14",
5
5
  "author": {
6
6
  "name": "instructa"
7
7
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "planr",
3
- "version": "1.10.0-alpha.13",
3
+ "version": "1.10.0-alpha.14",
4
4
  "description": "Skill-driven planning and execution loop for coding agents: one $planr entry point, an autonomous $planr-loop, and evidence-backed task graph skills powered by the planr CLI.",
5
5
  "author": {
6
6
  "name": "instructa",