The public-surface gate refuses any tracked file carrying a URL with a path outside .example, and21d7f5ashipped two: the python.org Windows downloads page and the Git for Windows download. Both are now named as bare domains for the tester to search for, which the scanner allows and which does not rot when a vendor moves a page. The gate found this and I did not, for a reason worth recording:21d7f5awas verified while the file was still UNTRACKED, and that scan reads `git ls-files`. The suite was genuinely green -- of a tree that did not yet contain the file. Verify after `git add`, not before, whenever a gate is scoped to tracked files. Also states the rule in the operator section, so the links are not restored as a courtesy later. Verify: .venv/bin/python -m pytest tests/ -> 223 passed, exit 0, with the file tracked. Scanner denominator 113 files / 609427 bytes, 0 findings; the byte count moved with the edit, so the file is inside the scan. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
20 KiB
Windows smoke test
A checklist for a Windows tester. Follow it from top to bottom, in order, and write down what you actually saw at each step. It assumes nothing: not that you know a terminal, not that you use git, not that you know what an MCP server is.
Nothing here submits an application, sends an email, or types anything into a job site. The whole plugin is read-only by design.
This is not a usability test. It is a platform measurement: seven questions about whether this software can run on Windows at all. A "no" is a result, not a failure, and it is worth more than a polite "worked fine". The most valuable thing you can do is copy the exact text you saw instead of summarising it.
Expect it to take about 30 minutes.
Before you send this out — operator only
The tester can skip this section and start at Step 0.
BLOCKER F1 — do not send this checklist yet. Measured 2026-09-06 on the
development Mac, against a tree assembled from package_plugin.py's own
include list:
ERROR: /private/tmp/jobbsok-installed.EUmgm9/pyproject.toml not found.
Cannot resolve '--group' option.
bootstrap: interpreter /usr/local/bin/python3
bootstrap: environment /tmp/jobbsok-plugindata.lCctG2/venv [plugin-data ...]
exit=1
scripts/bootstrap.py installs its dependencies with
pip install --group <repo root>/pyproject.toml:dev, and pyproject.toml is
not in package_plugin.py's INCLUDE tuple — so it is not in the archive. In
an installed copy the bootstrap therefore creates an empty virtualenv and then
fails, the ingestion guard is never installed, and the O4 gate refuses to
serve:
jobbsok-tools: <...>/venv/bin/python cannot import llm_ingestion_guard.
jobbsok-tools: run 'python scripts/bootstrap.py' against the installed plugin;
the guard is installed with it.
jobbsok-tools: refusing to start rather than serving tools that write without
the ingestion guard. Every skill still works by manual paste.
The refusal names the one command that cannot succeed in an installed copy. This is platform-independent — it would fail identically on the Mac — so sending the checklist now would buy a guaranteed "no" on measurement 2, the one measurement this whole test exists for, for a reason that has nothing to do with Windows. Two testers' time is the scarce resource; a spoiled critical measurement has to be bought back with a second round.
Fixing it is a one-line change to scripts/bootstrap.py's neighbourhood
(INCLUDE), which was outside the fence of the order that produced this file.
Steps 10 and 11 below are already written for the fixed build and name the
pre-fix error by its exact text, so the tester stops rather than reports a
misleading result. Send this out only after that fix is in the build the
tester receives.
Two more things to settle before sending:
- Language. This file is English, following
CLAUDE.md's "docs are English" and matchingREADME.md, which the tester reads anyway. The plugin answers in Norwegian, so the chat phrases in Steps 12–14 are Norwegian verbatim with a gloss. If the testers would be better served in Norwegian, this is cheap to flip — but flip the whole file, not half of it. - What you send. The
.pluginfile, its SHA-256, and the build stamp. The tester compares all three; Steps 7 and 9 depend on you providing them.
Why Steps 1 and 3 name download sites without linking them.
tests/test_public_surface.py refuses any tracked file carrying a URL with a
path outside .example, and this remote is public. A bare domain in prose is
not a finding; https://<site>/<path> is. So the two sites are named for the
tester to search for. Do not "helpfully" restore the links — the gate will fail
the commit, and it is right to.
What you need before you start
- A Windows PC — this test is only meaningful on Windows.
- The Claude desktop app, installed and signed in.
- The file
jobbsok.plugin, sent to you, plus two short strings that came with it: a SHA-256 checksum and a build stamp (seven characters, likec7db9f1). You will compare against both. - About 30 minutes.
Everything you type goes in PowerShell. To open it: press the Windows key,
type PowerShell, press Enter. A blue window opens. Type a command, press
Enter, read what comes back.
Copy each command exactly, including quotes and backslashes.
How to report a problem
At any step where what you saw does not match "Expected", stop and report. Do not work around it, and do not try the next step to see if it fixes itself.
A usable report has four parts. "It didn't work" is not one of them.
- The step number, e.g. "Step 9".
- The command you ran, copied exactly.
- The entire message you got back — all of it, copy-pasted, not retyped, not shortened, not described. If it was a window rather than text, a screenshot.
- Your Windows version, the line you wrote down in Step 0.
To copy text out of PowerShell: select it with the mouse, press Ctrl+C.
Step 0 — Write down which Windows this is
[System.Environment]::OSVersion.VersionString
Expected: one line, something like Microsoft Windows NT 10.0.26100.0.
Write it down. Every report you send needs it — the same command can behave differently on two Windows builds, and without the version a report cannot be reproduced.
Step 1 — Is Python installed, and is it new enough?
python --version
Expected: Python 3.10.0 or any higher number, e.g. Python 3.13.2.
Other outcomes, and what to do:
Python was not found; run without arguments to install from the Microsoft Store...or the Microsoft Store opens — Python is not installed; what answered was Windows' built-in shortcut. Install Python from the official site — search forpython.org, open its Downloads section and take the Windows installer — and tick "Add python.exe to PATH" in the installer. Then close PowerShell, open a new PowerShell window, and run the command again.Python 3.9.xor lower — stop and report. The tool server refuses to run below 3.10 on purpose, so this is a real answer, not a mistake you made.python : The term 'python' is not recognized...— stop and report, including the whole message.
Step 2 — Which Python file actually answered
python -c "import sys; print(sys.executable)"
Expected: an absolute path ending in python.exe, for example
C:\Users\<you>\AppData\Local\Programs\Python\Python313\python.exe.
Write the whole path down. If it contains WindowsApps, note that too: it
means Python came from the Microsoft Store, and the py command will not
exist on your machine. Both are fine for this test; we just need to know which
one you have.
Step 3 — Is git installed?
git --version
Expected: a line like git version 2.51.0.windows.1.
If you get git : The term 'git' is not recognized..., install Git for
Windows from the official site — search for git-scm.com and take the Windows
download. The default answers in the installer are fine. Then open a new
PowerShell window and run the command again.
Git is needed for one thing only: the next step fetches a security component from a code host.
Step 4 — Can this machine reach the security component?
git ls-remote https://git.fromaitochitta.com/open/llm-ingestion-pipeline-security.git v1.3.0
Expected: exactly one line, a long hex string then a tab then the tag name:
748b8f9d846f17e9ab47551b803e62e74af5fb14 refs/tags/v1.3.0
The hash must be exactly that one — it identifies the pinned version.
If instead you get a timeout, a certificate error, a proxy error, or
fatal: unable to access ..., stop and report the whole message. That host
is public and needs no account, so a failure here is usually a corporate
firewall or proxy — and it is worth knowing, because the plugin refuses to run
its tool server without this component.
Step 5 — Tell the plugin what Python is called here
On Windows, Python is normally called python. On Mac and Linux it is called
python3. The plugin has no way to spell it differently per platform, so it
reads one setting:
setx JOBBSOK_LAUNCH_PYTHON python
Expected: SUCCESS: Specified value was saved.
This is permanent and only needs doing once. It takes effect in new windows and newly started programs — a program that is already running does not see it. That is why Step 8 restarts the app.
Step 6 — Choose where your job-search folder lives
The plugin never guesses a location. Name one:
setx JOBBSOK_WORKSPACE "$env:USERPROFILE\jobbsok-workspace"
Expected: SUCCESS: Specified value was saved.
Then create the folder itself:
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\jobbsok-workspace"
Expected: a short table ending with a line naming jobbsok-workspace.
Now open a new PowerShell window (the old one cannot see the setting) and check it:
$env:JOBBSOK_WORKSPACE
Expected: a real path, e.g. C:\Users\anna\jobbsok-workspace.
If it prints the literal text %USERPROFILE%\jobbsok-workspace, the
setting was stored unexpanded. Re-run the setx line above exactly as written
— with $env:USERPROFILE, not %USERPROFILE% — in PowerShell, then check
again in another new window.
Write the path down. You will type it into the chat later.
Step 7 — Install the plugin ▸ measurement 1
First, confirm you are testing the file that was actually sent to you:
Get-FileHash "$env:USERPROFILE\Downloads\jobbsok.plugin" -Algorithm SHA256
(If you saved the file somewhere other than Downloads, change that path.)
Expected: a Hash value identical to the SHA-256 you were given. Compare
the whole string. If it differs, stop and report — the file changed in transit
and nothing measured after this would be about the right build.
Then, in the Claude desktop app: Customize → Plugins, choose the option to
install from a file, and pick jobbsok.plugin.
Expected: jobbsok appears in the plugin list, version 0.1.0.
If there is no way to install a plugin from a file on Windows — no Customize menu, no Plugins page, no upload option — stop, take a screenshot of what you do see, and report. That is this measurement answering "no", and it is a fact about the platform, not a mistake by you.
Step 8 — Restart the app completely
Quit the Claude app fully — not just closing the window. Then start it again.
Programs read settings like the ones from Steps 5 and 6 when they start, so an app that was already running has not seen them. Skipping this restart is the most common way to get a false "no" in the next step.
Step 9 — Does the connector appear? ▸ measurement 2 — the critical one
The plugin ships a small helper program that runs on your PC and that Claude talks to. In the app it shows up as a connector, not as a skill.
In the app: Customize → Plugins → jobbsok, and look at its connectors.
Expected: jobbsok-tools is listed.
Write down exactly one of these three, word for word:
listed— it appears.not listed— it does not appear at all.listed but silent— it appears, but Step 10 gets no answer from it.
Do not try to fix a "no" here, and do not skip ahead. This is the one question the whole test exists to answer, and a "no" is a finding that changes how the rest of this software gets built. Report it to the operator with your Step 0 Windows version and a screenshot of the connectors page. It is not a bug to be worked around in the moment.
Then, whichever you saw, continue — the remaining steps still measure things.
Step 10 — Ask the plugin about itself ▸ measurements 3, 4 and 5
In the Claude chat, type this, replacing the path with the one from Step 6:
Bruk verktøyet
selvsjekkfra jobbsok-tools med workspaceC:\Users\<you>\jobbsok-workspace
("Use the selvsjekk tool from jobbsok-tools with workspace ..." — the
plugin answers in Norwegian.)
Expected: a block of JSON with these fields. Copy the whole thing into your report; the notes below say what each one tells us.
| Field | Expected | What it tells us |
|---|---|---|
server |
jobbsok-tools |
the right program answered |
server_versjon |
0.1.0 |
|
python_executable |
a path ending in python.exe |
measurement 5: which interpreter really served, and whether it is the one from Step 2 |
python_version |
3.10.0 or higher |
|
guard_versjon |
1.3.0 |
the security component is present. null here needs reporting — see below |
plugin_root |
an absolute Windows path with a drive letter and backslashes | measurement 4: what ${CLAUDE_PLUGIN_ROOT} became on Windows. Nobody has ever seen this value; write it down verbatim |
build_stamp |
the seven-character stamp you were given | you are testing the build that was sent, not a cached older one |
workspace |
the path from Step 6 |
Report immediately, without continuing, if:
plugin_rootprints the literal text${CLAUDE_PLUGIN_ROOT}or is empty — the variable did not resolve, which breaks every internal path in the plugin, not just this one.build_stampdiffers from the stamp you were given — the app served a cached older build, so everything measured here is about some other version.guard_versjonisnull— the server is running without the security component. It is supposed to refuse to start at all in that state, sonullshowing up here is itself the finding.
If nothing answers at all, or Claude says the tool is unavailable, go back to
Step 9 and write listed but silent (or keep not listed), then continue at
Step 11.
Step 11 — Build the plugin's Python environment ▸ measurement 6
Find the installed copy on disk:
Get-ChildItem -Path "$env:USERPROFILE\.claude\plugins" -Recurse -Filter "jobbsok_tools_launch.py" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName
Expected: one or more paths ending in \jobbsok\scripts\jobbsok_tools_launch.py.
If it prints nothing, report that — including the command — and skip to Step 12.
If Step 10 gave you a plugin_root, note whether it matches what you find here.
Go to the folder that contains scripts (the part of the path before
\scripts\), replacing the path below with your own:
cd "C:\Users\<you>\.claude\plugins\<...>\jobbsok"
python scripts\bootstrap.py
This downloads a few components and takes a couple of minutes. Let it finish.
Expected: the last lines read approximately:
bootstrap: interpreter C:\...\python.exe
bootstrap: environment C:\...\.venv [repo root (development)]
bootstrap: sys.executable C:\...\.venv\Scripts\python.exe
bootstrap: python 3.13.2
bootstrap: guard 1.3.0
bootstrap: ok
Two notes so you do not report a non-problem:
- The
environmentline may say[repo root (development)]or[plugin-data (survives a plugin update)]. Either is fine here. Which one appears depends on a setting the app passes to its own programs and that your PowerShell window does not have. Write down which one you saw. bootstrap: guard 1.3.0is the line that matters. It is the same version Step 4 checked.
Known failure — stop and report if you see it:
ERROR: ...\pyproject.toml not found. Cannot resolve '--group' option.
That means you were sent a build made before a known fix. It is not your machine and not your mistake. Report it and stop; the rest of the test needs a newer build.
Step 12 — Restart, and check the connector again
Quit the Claude app fully and start it again, then repeat Step 9 and Step 10.
Expected: jobbsok-tools is listed, and guard_versjon is now 1.3.0.
Write down both answers again, side by side with the first pair. A connector that was absent before Step 11 and present after it is a different — and much better — result than one that was never there, and only the two readings together can tell them apart.
Step 13 — Create a case ▸ first half of measurement 7
In the chat, type (Norwegian, verbatim — this phrase is what starts the skill):
Opprett en sak for arbeidsgiver Testbedriften AS, rolle Testrolle
("Create a case for employer Testbedriften AS, role Testrolle".)
Expected: Claude reports that a case was created and names a case id that
looks like 2026-09-testbedriften-as-testrolle.
Check it landed on disk. In PowerShell:
Get-ChildItem "$env:JOBBSOK_WORKSPACE\saker"
Expected: one folder, whose name is the case id Claude reported.
If nothing was created, report what Claude said, in full.
Step 14 — Close everything, then ask again ▸ second half of measurement 7
- Quit the Claude app completely.
- Start it again and open a new chat — not the old one.
- Type:
Hva er status på saken?
("What is the status of the case?")
Expected: Claude names the same case id from Step 13, with status
vurderer and waiting party meg.
If the connector never appeared, you can still measure this half by hand. Run, replacing the path:
python scripts\sak_status.py --workspace "$env:USERPROFILE\jobbsok-workspace" --format tekst
from the plugin folder you found in Step 11.
Expected: a line naming the same case id and the status vurderer.
Say which of the two routes you used. They answer slightly different questions — the chat route also proves the connector works, the command route only proves the files survived.
What each measurement means
| # | Question | Step | What a "no" would mean |
|---|---|---|---|
| 1 | Does the plugin install in Claude on Windows at all? | 7 | Nothing else is measurable; the delivery route itself has to change. |
| 2 | Does jobbsok-tools appear as a connector? |
9, 12 | The critical one. The design assumes Claude can run a helper program on your PC. If Windows cannot, every part of the plugin has to fall back to copy-and-paste, and the next four milestones get built differently. This is reported to the operator, never rounded off as "a bug". |
| 3 | Does selvsjekk answer, and what does it report about the interpreter, the build stamp and the security component? |
10 | A connector that is listed but mute is a different fault from one that is absent, and the two have different causes. |
| 4 | What does ${CLAUDE_PLUGIN_ROOT} actually become on Windows? |
10 | It has never been observed on Windows. If it is not a real path with a drive letter and backslashes, every internal path in the plugin is affected. |
| 5 | Was JOBBSOK_LAUNCH_PYTHON needed, or did it start without? |
5, 10 | If it started without the setting, we need to know whether a real Python answered or the Microsoft Store shortcut did — Step 2's path is what tells them apart. |
| 6 | Does bootstrap.py build a working Python environment the plugin then finds? |
11, 12 | Without it there is no security component, and the tool server refuses to serve. This is also the step that has never run on Windows. |
| 7 | Does it remember a case between two sessions? | 13, 14 | If a case vanishes when the app restarts, the files were written somewhere temporary, and the whole case-folder model does not hold on this platform. |
When you are done
Send back, in one message:
- Your Windows version from Step 0.
- The Python path from Step 2.
- Your Step 9 word (
listed/not listed/listed but silent), both before and after Step 11. - The whole
selvsjekkoutput from Step 10 (and from Step 12, if it changed). - Which
environmentline Step 11 printed. - Which route you used in Step 14, and whether the case was still there.
- Every "stop and report" you hit, with the four parts listed under How to report a problem.
If everything matched, say so plainly and send the list anyway. A pass with the actual values attached is evidence; a pass without them is a memory.