Skip to content

docs(privacy): size the counsel packet for counterparty-portal automation - #161

Merged
myselfsiddharth merged 2 commits into
mainfrom
wave0/b0-counsel-packet
Aug 14, 2026
Merged

docs(privacy): size the counsel packet for counterparty-portal automation#161
myselfsiddharth merged 2 commits into
mainfrom
wave0/b0-counsel-packet

Conversation

@myselfsiddharth

Copy link
Copy Markdown
Contributor

Summary

This is a sizing brief, not legal advice and not a legal position — pivot brief §5 is explicit that the counsel-packet requirement "does not need to be solved this week. It needs to be sized." Track 2 (vertical search) is a documented FAIL with no anchor locked (ADR-0004), and #103 already records the ToS-position requirement as "inapplicable, not merely undone." No anchor, vertical, or portal is invented anywhere in this PR.

New doc: docs/privacy/counsel-packet-sizing.md, filed as a brief and linked from docs/README.md's Privacy section. It is written as a template + trigger condition — what gets filled in, by whom, the moment an anchor is locked — covering all four acceptance criteria from #36:

  • Position outline: authorized-user automation vs. prohibited automated access — the distinction as the product understands it (not a legal conclusion), the questions counsel must answer once a portal is locked, and background sources (CFAA text, Van Buren v. United States, hiQ Labs v. LinkedIn) cited with URLs and access dates, explicitly marked as background for counsel rather than assertions.
  • Architecture note: every claim grounded in src/ at HEAD (commit b722676) with file/line citations — how the agent authenticates and acts (src/recorder/preamble.ts, src/runner/actions.ts), why there's no bulk extraction (src/runner/page-state.ts, src/recorder/fingerprint.ts), and the honest finding that no rate limiter exists anywhere in the codebase today (verified by repo-wide search; the one "rate limit" hit is an Anthropic API error comment, unrelated to portal request pacing). Stated plainly rather than glossed over, per the task's own warning that an overstated posture is worse than no note.
  • Storage decision: explicit — yes, the product stores locator/assertion/topology content from any site it automates, but never raw content, screenshots, HAR, or session material; whether it's shared cross-tenant is routed entirely through docs/privacy/boundary-spec.md's §6 allowlist, with a flagged caveat that closed counterparty portals don't get ADR-0017's vocabulary widening (so they fail closed harder than the self-hosted test-bed), plus a note on the separate repair-egress boundary (ADR-0012).
  • Filed under docs/, no client names, no portal screenshots, no third-party data — the whole point of the template-not-position framing.

Also includes a sizing section (§5): the dependency chain from anchor-lock through counsel engagement, explicitly declining to invent an attorney-hours or fee estimate (none exists), and a preconditions list (§6).

Verification

npm run lint:docs   → lint-docs: clean (62 docs)
npm run ci           → all green: secret-scan, validate:contracts, lint, lint:docs, typecheck,
                        test (453 passed), test:integration (26 passed)

Closes #36

🤖 Generated with Claude Code

…tion

Pivot brief §5 flags a written ToS position, an architecture note, and a
storage decision as required before any paid pilot, but Track 2 is a
documented FAIL with no anchor locked (ADR-0004) — there is no specific
portal to write a position for yet. This is the sizing brief pivot brief
§5 asks for instead: a template and trigger condition (filled in the
moment an anchor locks), the authorized-user-automation vs.
prohibited-automated-access question outline counsel will need to
answer, an architecture note grounded in src/ at HEAD (including the
honest gap that no rate limiter exists today), and an explicit storage
decision routed through boundary-spec.md's §6 allowlist. Not legal
advice; no anchor is invented.

Closes #36

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@myselfsiddharth
myselfsiddharth requested a review from a team as a code owner August 14, 2026 18:54
@github-actions
github-actions Bot requested a review from OM152002 August 14, 2026 18:54
@github-actions github-actions Bot added size/L <= 600 changed lines documentation Improvements or additions to documentation privacy-boundary Touches the privacy boundary — canary is merge-blocking labels Aug 14, 2026
@myselfsiddharth

Copy link
Copy Markdown
Contributor Author

Opus review — changes requested (1 must-fix)

Reviewed the full brief and independently verified the falsifiable parts.

Code citations check out. I read each one against HEAD rather than trusting the summary:

  • src/runner/replay.ts:270 — is the for (const step of program.steps) loop. The "strictly sequential, never concurrent" claim is correct.
  • src/recorder/locators.ts:79 — is the .slice(0, 120) text truncation. Correct.
  • src/runner/repair-anthropic.ts:281 — is a comment about handling a rate-limit error response from the Anthropic API, not a portal throttle. The §3.3 finding that this is the only rate-limit-shaped hit in the repo, and that it is unrelated, is accurate.
  • ADR-0004, ADR-0017 — both resolve.

The §3.3 finding is the most valuable thing in this document and it is reported the right way round: no rate limiter exists, pivot brief §5 names "respects rate limits" as part of the required architecture defense, and that defense does not exist in code. Distinguishing ADR-0011's per-run wall-clock budget and the per-step timeouts as upper bounds on patience, not lower bounds on spacing is a precise and non-obvious distinction, and it is exactly what stops a reader mistaking them for pacing. Declining to invent an attorney-hours figure under CONTRIBUTING rule 3 is also correct — an unsourced cost estimate in this document would have been the worst possible line to write.

Handling the no-anchor problem as a template plus trigger condition, rather than inventing a portal to have a position about, is the right structural call and keeps this consistent with #103.

Must fix — §4's repair-egress paragraph is stale, and it understates live third-party transmission

Lines 320–322 state the egress becomes live "once #27 replaces the current StubRepairModelClient … this egress is not live yet."

#27 is closed. AnthropicRepairModelClient exists at src/runner/repair-anthropic.ts, landed by #151 — in the very commit this brief cites as its HEAD (b722676). What is still true is narrower and needs saying that way: the stub remains the default (src/runner/replay.ts:193), the real client is opt-in, and it throws at construction on a missing key rather than silently degrading to the stub.

"No third-party egress exists yet" versus "third-party egress exists, is opt-in, and is off by default" are materially different facts to hand counsel, and the error runs in the direction this document itself warns against — §3 opens by saying an architecture note that overstates our posture is worse than none. The same standard applies to understating live transmission to a third-party model provider.

The surrounding material is fine and should stay: the ADR-0012 bound on what a repair payload may carry, the merge-blocking tests/canary/repair-egress.test.ts, and the unresolved accessible-name question boundary-spec.md flags for closed portals.

Not blocking

confidence: HIGH on a document whose §2 is composed of open legal questions. I read the field as scoped to the doc's own verifiable claims — the architecture note, which is well sourced — so this is the author's call, not a change request.

Verdict: hold for the #27 correction, then merge. The architecture note is otherwise accurate and the legal material is properly framed as background rather than conclusion.

Review caught that §4 described the third-party repair egress as not
yet live, citing StubRepairModelClient and issue #27 as open. #27 is
closed and PR #151 merged AnthropicRepairModelClient on the commit this
branch is based on (b722676) — the client is real, makes an actual
Anthropic API call, and is bounded by serializeRepairContext() /
ADR-0012, canary-enforced by tests/canary/repair-egress.test.ts.

What's still true, and now stated precisely instead of overstated in
the safe direction: the stub remains ReplayRunner's default
(src/runner/replay.ts:193) so no egress fires unless a caller opts in,
and the real client fails loudly (MissingAnthropicKeyError) rather than
silently degrading when misconfigured. Understating a live third-party
transmission in a counsel packet is the same class of error the doc's
own §3 preamble warns against for the architecture note.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@myselfsiddharth

Copy link
Copy Markdown
Contributor Author

Follow-up commit 3db4c67 in response to review: §4's repair-egress paragraph was stale. It described the third-party repair egress (ADR-0012, Anthropic) as not yet live, citing StubRepairModelClient and open issue #27. #27 is closed — PR #151 merged AnthropicRepairModelClient (src/runner/repair-anthropic.ts) on b722676, the commit this branch is based on.

Corrected to state what's actually true at HEAD: the real client exists and makes an actual Anthropic API call, bounded by serializeRepairContext() / ADR-0012 and canary-enforced (tests/canary/repair-egress.test.ts); ReplayRunner still defaults to the stub (src/runner/replay.ts:193) so no egress fires unless a caller opts in; and the real client fails loudly (MissingAnthropicKeyError) rather than silently degrading when misconfigured. Swept the rest of the doc for the same staleness — no other reference assumed #27 was open.

npm run lint:docs and npm run ci both re-run clean after the fix.

@myselfsiddharth

Copy link
Copy Markdown
Contributor Author

Opus re-review — approved

The §4 correction is verified against HEAD, and the rewrite is better than what I asked for. All three new citations check out: repair-anthropic.ts:238 is the AnthropicRepairModelClient class, :226-236 is MissingAnthropicKeyError, replay.ts:193 is the stub default.

The passage now lands the distinction correctly for a counsel reader — the egress exists and is real, it is canary-bounded to serializeRepairContext()'s output, and it is off by default rather than unbuilt. The added forward-looking sentence is the part that earns its place:

The moment any run against a real counterparty portal opts into the real client, that run is sending role + accessible name of visible interactive elements on that portal's pages to Anthropic.

That is exactly the fact counsel needs and it was not in the original draft.

Standing by the rest of the review: the §3.3 rate-limiter finding is the most valuable thing in this document, the code citations hold, and framing the whole brief as a template plus trigger condition — rather than inventing a portal to have a position about — is the right structural call given ADR-0004.

Required checks green. Merging via admin bypass.

@myselfsiddharth
myselfsiddharth merged commit 2cb885a into main Aug 14, 2026
12 checks passed
@myselfsiddharth
myselfsiddharth deleted the wave0/b0-counsel-packet branch August 14, 2026 19:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation privacy-boundary Touches the privacy boundary — canary is merge-blocking size/L <= 600 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Size counsel packet: authorized-user automation of third-party portals

1 participant