fix(specs): settle every workflow spec on python3, one Windows note at first use (#678)

* fix(specs): settle every workflow spec on python3 with one Windows note at first use

* fix(specs): finish python3 in the specs /apply reads; Windows note says run as python

- 04-job-evaluation (salary lookup), 05-cv-templates (verify_pdf x2) and
  CLAUDE.md now spell python3 like apply.md; framework_version bumped on 04
  (1.2.7) and 05 (1.4.8), each with its own Windows note at first use.
- The note now covers Windows generally: python3 is either the exit-49 Store
  stub or a separate Store Python without pip's packages, so run as python.
- tests/test_python_command_specs.py globs commands, skills and agents
  instead of naming four files.
- CHANGELOG entry matches the final scope.

* changelog: place the #678 entry under [Unreleased]

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

---------

Co-authored-by: Mads Lorentzen <madslorentzen_17@hotmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-10-20 08:27:21 +02:00
1 parent d621ebe635
commit 8fb34c6cb7
11 files changed
+168 -17

No files matched your search

@@ -1,5 +1,5 @@
---
framework_version: 1.1.5
framework_version: 1.1.6
---
# Web Research and Fetching
@@ -35,6 +35,8 @@ Do **not** respond to a 403 by softening the cover letter to vague generalities,
The retry command below runs this check itself and refuses to fetch when it fails - there is no flag to skip it. The standalone checker is still there for diagnosing a refusal:
> **Windows:** run these tools as `python`, not `python3`. A python.org install ships no `python3`, so that name reaches the Microsoft Store alias, which either exits 49 with no output (#669) or starts a separate Store Python without the packages `pip` installed (such as pypdf). `.claude/settings.json` allows both spellings.
```bash
python3 tools/robots_check.py '<URL>'
```
@@ -52,7 +54,7 @@ Two details worth knowing, both covered by `tests/test_robots_check.py`:
python3 tools/fetch_page.py '<URL>' --out "${SCRATCHPAD:?set this to the session scratchpad directory from your system prompt}/page.html" --text
```
One command does the whole retry: it runs the `robots.txt` gate above (exit `1` and no fetch when the policy says no), GETs the page with browser headers, saves the body to `--out`, prints `HTTP <code> size=<bytes> saved=<path>`, and with `--text` prints the tag-stripped text (script, style, noscript, svg and comments removed, entities unescaped) capped at `--max-chars` (default 6000). It is GET-only with a fixed argv, http(s) only, bounded to 45 s, 5 redirects and 10 MB, and it refuses an `--out` inside the repo - fetched content is untrusted and belongs in the scratchpad. That fixed shape is why the workflow pre-approves `python tools/fetch_page.py` and not `curl`.
One command does the whole retry: it runs the `robots.txt` gate above (exit `1` and no fetch when the policy says no), GETs the page with browser headers, saves the body to `--out`, prints `HTTP <code> size=<bytes> saved=<path>`, and with `--text` prints the tag-stripped text (script, style, noscript, svg and comments removed, entities unescaped) capped at `--max-chars` (default 6000). It is GET-only with a fixed argv, http(s) only, bounded to 45 s, 5 redirects and 10 MB, and it refuses an `--out` inside the repo - fetched content is untrusted and belongs in the scratchpad. That fixed shape is why the workflow pre-approves `python3 tools/fetch_page.py` and not `curl`.
The HTTP status is information, not a verdict: a `403` body still tells you what the site answered. Only exit `2` (unsupported scheme, transport failure, oversized response) means nothing was retrieved.