docs(m1): record Cowork verification outcome

This commit is contained in:
Kjell Tore Guttormsen 2026-09-05 20:33:34 +02:00
commit f8c74fa0ac

View file

@ -288,10 +288,13 @@ Stating the risk precisely matters more than stating it darkly, because an
overstated risk gets discounted and takes the real one with it. So: overstated risk gets discounted and takes the real one with it. So:
- **"This Mac is asleep" is not the risk here.** This operator's Mac does not - **"This Mac is asleep" is not the risk here.** This operator's Mac does not
sleep. And there is no wider user population to generalise to: build-brief sleep. **Corrected 2026-09-05:** what stood here also argued there was no
lines 3 and 22 scope this to a single operator searching for their own job, wider user population to generalise to, and that is no longer true. The
and the plugin is not in the marketplace catalog. A concern about "most other project has external adopters, each running their own install on their own
users" would be a concern about people this project does not have. machine. The build brief's single-operator clause means single-TENANT -- one
person searching for their own job, one workspace per install -- and it still
holds; what does not hold is using it to dismiss a question about other
people's machines. Everything measured below is macOS only.
- **"Cowork opened somewhere else" is the risk.** The bridge is named - **"Cowork opened somewhere else" is the risk.** The bridge is named
`remote-devices` and the server is a child of `Claude.app` on this Mac. A `remote-devices` and the server is a child of `Claude.app` on this Mac. A
session started on a phone or a second laptop was **not measured**, and session started on a phone or a second laptop was **not measured**, and
@ -344,6 +347,81 @@ 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` -- nothing to `main.log` (checked for `finn.no`, `webview`, `browserTool` --
no hits). The operator's observation is the only instrument. no hits). The operator's observation is the only instrument.
## M1 verifisert
Operator measurement, 2026-09-05, in a Cowork session on this Mac, against a
`jobbsok.plugin` built by `scripts/package_plugin.sh`.
| Question | Answer |
|---|---|
| Build stamp equals `git rev-parse --short HEAD` | yes -- `8a3320b` |
| `kandidatprofil` and `kandidatvurdering` load and run against a pasted listing | yes, both |
| `jobbsok-tools` appears as a connector | **yes** |
| `selvsjekk` reports an interpreter at 3.10 or newer | yes -- 3.14.0 |
`selvsjekk` returned, with the workspace path withheld because this remote is
public:
| Field | Value |
|---|---|
| `server` | `jobbsok-tools` |
| `server_versjon` | `0.1.0` |
| `python_executable` | the host interpreter, under `/usr/local/bin` |
| `python_version` | `3.14.0` |
| `guard_versjon` | `null` |
| `build_stamp` | `8a3320b` |
| `workspace` | an operator-chosen directory outside this repository |
The version echo reported the build stamp `8a3320b` and manifest version
`0.1.0`.
**The degradation branch did not fire.** `- Host-MCP:` was already `ja` from the
probe, and this milestone's own build confirms it on the real plugin rather than
on a throwaway one: a plugin-declared stdio server appears as a connector and
answers. Operator decision 7 holds on both halves.
**No cached build, and the comparison earned its place.** The tool server runs
from a per-session copy on the Mac; the skill files are read from the synced
copy. Two different locations, and both reported `8a3320b`. That is the pair
this check exists to compare, and it is informative only because it could have
disagreed.
### O4. The launcher gates on interpreter version, not on the guard
`guard_versjon` came back `null`: the server is serving without the ingestion
guard. The cause is measured rather than inferred --
`scripts/jobbsok_tools_launch.sh` contains no reference to the guard at all, and
resolves an interpreter in four steps ending at `python3` on PATH, "only at 3.10
or newer". In an installed copy the first three branches cannot fire:
`JOBBSOK_PYTHON` is unset, no environment has been built under
`${CLAUDE_PLUGIN_DATA}` because `scripts/bootstrap.sh` was not run against the
installed plugin, and the packaged archive deliberately excludes the virtualenv.
So branch four resolved the host interpreter at 3.14.0, which clears the version
floor and serves.
Step 12's stated reason for that floor was that "a server running on 3.9.6
without the guard is worse than no server". The thing being protected is named
there as the guard; the mechanism only checks the version. An interpreter at
3.14.0 without the guard passes a gate written to prevent exactly that outcome.
At M1 this costs nothing, and the reason is narrow rather than reassuring: no
tool at this milestone writes. `annonse_vurder` scores and returns, so the
pasted listing never became a file. Write-freedom is the whole of the
protection. M2 adds the decision log and the case folder, which do write, and
from that point `guard_versjon: null` is a defect rather than an observation.
Two things follow, and they should not be merged into one:
1. **Setup.** Running `scripts/bootstrap.sh` against the installed copy builds
the `${CLAUDE_PLUGIN_DATA}` environment the launcher prefers, and the guard
arrives with it. That route is documented; it was simply not run here.
2. **The gate.** That setup is skippable is the point. A launcher which refuses
an interpreter below 3.10 but serves willingly without the guard leaves the
milestone that introduces writes depending on an operator remembering a step.
Whether `selvsjekk` reporting `null` is sufficient, or whether the launcher
should refuse outright once a writing tool exists, is an M2 decision and is
not taken here.
## Degradation branch ## Degradation branch
Written now, so the answer does not get decided under pressure later. Written now, so the answer does not get decided under pressure later.