docs(m1): record three probe findings outside the four gated bullets

Recorded here rather than as extra bullets: the four are gated on a count of
exactly four and Step 31 adds a fifth, so a sixth would break the Verify.
Checked both ways -- the live file still counts 0, a fully answered copy still
counts exactly 4.

O1. Host-side MCP reaches a cloud session through localMcpBridge. research/03
    dimension 4 quoted Anthropic saying local MCP servers do not run in cloud
    sessions, and flagged as unverified whether they still spawn on this Mac.
    They do: main.log records Connecting / negotiated 2025-11-25 / Connected
    (1 tools) / announcing, and ps shows the server as a child of Claude.app on
    the host Python 3.14. The session addresses it as
    mcp__remote-devices__plugin_jobbsok-probe_probe-tools__probe_ping. So
    "host-side server" and "cloud session" are not exclusive here.

O2. Sandbox and host are two different interpreters: 3.11.15 [GCC 13.3.0] Linux
    inside, 3.14.0 macOS outside, with CLAUDE_PLUGIN_ROOT resolving under
    /root/.claude/plugins/synced/. That is also what answers the session-mode
    question -- measured from the paths, not read off a settings screen. It
    matters for M3: guard_ingest.py cannot import the guard in the sandbox, so
    it belongs on the host side of the bridge that O1 shows is reachable.

O3. Cowork's built-in browser rendered a Finn job ad in full, with the operator
    logged in after signing in by hand inside that browser. That is the brief's
    invariant by a shorter route -- no credential handling, manual auth, an
    already-authenticated browser. It raises an M3 question about what
    Playwright over CDP still adds; the question is recorded, not decided.
    Two limits are stated rather than glossed: login persistence across
    sessions was not measured, and the built-in browser leaves no host-side
    trace, so unlike O1 and O2 the operator's observation is the only
    instrument.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-04 19:02:06 +02:00
commit 41854ae01a

View file

@ -237,6 +237,83 @@ at least one bullet is still unanswered or was written in a form the grep does
not recognise -- check that the answer follows the label directly, with a
space, and starts with one of the four allowed words.
## Observations beyond the four questions
Measured 2026-09-04 while running the probe. These are deliberately **not**
extra bullets: the four above are gated on a count of exactly four, and Step 31
already adds a fifth (`- Connector-hook:`). A sixth would break the Verify. They
are recorded here because they answer questions later milestones were going to
ask, and because a finding that lives only in a commit message is lost.
### O1. Host-side MCP reaches a cloud session, through a bridge
The strongest result of the probe, and it contradicts the reading this plan was
built on. `research/03` dimension 4 quotes Anthropic: local MCP servers "don't
run in sessions in the cloud", and flagged as **unverified** whether a
cloud-default session on this Mac still spawns them. It does.
Measured from the host, not recalled from a UI:
```
main.log 2026-09-04 18:48:28
[LocalMcpServerManager] Connecting to plugin:jobbsok-probe:probe-tools
[LocalMcpServerManager] ... negotiated protocol version: 2025-11-25
[LocalMcpServerManager] Connected to plugin:jobbsok-probe:probe-tools (1 tools)
[localMcpBridge] announcing plugin:jobbsok-probe:probe-tools: 1 tool(s)
ps: 12997 Claude.app/Contents/Helpers/disclaimer -- /usr/local/bin/python3
.../rpm/plugin_01NxHfqM495jtJzjVjRvgWDm/probe_tools.py
12998 Python.framework/Versions/3.14/... (the host interpreter)
```
The mechanism is `localMcpBridge`, the same one that announces Claude Desktop's
own `Filesystem` server. The session sees the tool as
`mcp__remote-devices__plugin_jobbsok-probe_probe-tools__probe_ping`. So
"host-side server" and "cloud session" are not exclusive here: the server runs
on the Mac and is bridged in.
One design choice was vindicated by the log. `probe_tools.py` echoes the
client's `protocolVersion` rather than asserting its own default. The client
asked for `2025-11-25`, which is newer than the server's fallback; a hardcoded
version would have made this handshake a different and worse story.
### O2. The sandbox and the host are two different interpreters
| Where | Interpreter | Evidence |
|---|---|---|
| Cowork sandbox (skills, Bash) | Python 3.11.15, `[GCC 13.3.0]`, Linux | reported by `probe-versjon` |
| Host (MCP servers) | Python 3.14.0, macOS framework build | `ps`, and the venv Step 2 built |
`${CLAUDE_PLUGIN_ROOT}` resolves inside the sandbox to
`/root/.claude/plugins/synced/<session>_<account>/jobbsok-probe`. Both facts
matter for M3: `guard_ingest.py` cannot import the guard in the sandbox, so it
belongs on the host side of the bridge, which O1 shows is reachable.
The Linux paths and the GCC build string are also what answer the session-mode
question. It was read off a measurement, not off a settings screen.
### O3. Cowork's built-in browser reads Finn, authenticated
Operator measurement, 2026-09-04. Cowork's built-in browser (shipped
2026-08-26) rendered `www.finn.no/job/ad/474745458` in full -- employer, title,
`Soknadsfrist`, `Mulighet for hjemmekontor`, `Arbeidsspraak`, `Sektor`: the
exact fields the M3 extraction wants, at a clean snapshot-able URL. The
operator was logged in to Finn, having signed in by hand inside that browser.
This is the brief's invariant reached by a shorter route: the plugin handles no
credentials, the operator authenticates manually, and the browser is already
authenticated when it reads. It raises a real M3 question -- if the built-in
browser covers both public and logged-in sources, what does Playwright MCP over
CDP still add? -- but that is an M3 decision and is not taken here.
Not established, and worth knowing before the decision is taken: whether that
login persists across sessions or must be repeated each time. Nothing was
measured about persistence.
Unlike O1 and O2, this one has no host-side trace: the built-in browser writes
nothing to `main.log` (checked for `finn.no`, `webview`, `browserTool` --
no hits). The operator's observation is the only instrument.
## Degradation branch
Written now, so the answer does not get decided under pressure later.