Skip to main content

fs-toolchain-and-tests

Recreate the founder-skills working environment from scratch and run or extend its three test suites: the venv procedure (the host Python is PEP-668 externally managed, so the README's test commands fail verbatim), the Node glob-form-only rule for the JS suite, the Function-wrapper harness pattern for testing top-level-await Workflow scripts, how to add a test to each suite, and a symptom-to-triage table for toolchain failures. Use when a maintainer says "run the tests", "pytest says no module named pytest", "node --test can't find the module", "set up the environment", "why do the README test commands fail", "FileNotFoundError matrix.template.html", "how do I test a workflow script", or "add a test for this asset".

Zur Installation springen

Quellinformationen

Repository
craigm26/founder-skills
Letzte Quellaktivität
2. Juli 2026 um 23:29
Erkannte Sprache von SKILL.md
Englisch
Sterne
0
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
fs-toolchain-and-tests
description
Recreate the founder-skills working environment from scratch and run or extend its three test suites: the venv procedure (the host Python is PEP-668 externally managed, so the README's test commands fail verbatim), the Node glob-form-only rule for the JS suite, the Function-wrapper harness pattern for testing top-level-await Workflow scripts, how to add a test to each suite, and a symptom-to-triage table for toolchain failures. Use when a maintainer says "run the tests", "pytest says no module named pytest", "node --test can't find the module", "set up the environment", "why do the README test commands fail", "FileNotFoundError matrix.template.html", "how do I test a workflow script", or "add a test for this asset".
# fs-toolchain-and-tests **Announce at start:** "Loading fs-toolchain-and-tests — environment setup + the three test suites." This skill gets you from a bare clone of `/home/craigm26/projects/craigm26/founder-skills` (public GitHub `craigm26/founder-skills`) to all three test suites green, and teaches you how to extend them. Every command below was copy-paste verified on the host on **2026-07-02**. ## When NOT to use this skill | Your job | Load instead | |---|---| | Orienting in the repo, "which skill covers X" | **fs-orientation** | | Shipping a change (spec → plan → commit pipeline, who commits) | **fs-change-control** | | The pre-push gate script / publishing to the live marketplace | **fs-release-and-publish** | | Plugin directory layout, SKILL.md/plugin.json contract | **fs-plugin-anatomy** | | The history/incidents behind these gotchas (gitignore swallow, PEP-668 README failure, node directory form) | **fs-failure-archaeology** | | Writing a new skill or its house style | **fs-skill-authoring**, **fs-skill-style-guide** | | What `Workflow({scriptPath,args})`, `agent()`, `parallel()` mean at the platform level | **fs-anthropic-primitives** | ## The environment (as of 2026-07-02) | Fact | Value | Why it matters | |---|---|---| | Host | Raspberry Pi, Linux 6.12.75+rpt-rpi-2712 | slow cores; suites are fast anyway (<1s each) | | Python | 3.13.5, **PEP-668 externally managed** | `python3 -m pip install` errors; `python3 -m pytest` → "No module named pytest" | | Node | v24.16.0 | `node --test` glob expansion works (needs ≥ v22); directory form does NOT here | | Packaging | **none** — no package.json, no pyproject.toml, no version pins, no lockfiles | nothing to `npm install`; the only dependency to install anywhere is `pytest` | | CI | **none, by standing rule** (no GitHub Actions ever, since 2026-06-19) | YOU are CI: run all three suites locally before any push (see fs-release-and-publish) | | `claude` CLI | present at `~/.local/bin/claude`, v2.1.198 (environment-specific) | needed only for `claude plugin validate` (add-skill.sh, pre-push gate) — NOT for the test suites | **PEP-668 (define once):** modern Debian-family Pythons mark the system interpreter "externally managed" — `pip install` into it is refused with `error: externally-managed-environment`. The only supported route is a virtual environment (venv). This is why the README's `python3 -m pytest -q tests/` commands (README.md "Develop / test" section, lines ~218–219) **fail verbatim on this host** — a known defect, ledger item #2; fixing the README is fs-change-control scope, don't just patch it. ## Setup from scratch (one time) ```bash # 1. Create a venv anywhere you like and install the ONE dependency. # (~/venvs/founder-skills is a convention, not a requirement — any path works.) python3 -m venv ~/venvs/founder-skills ~/venvs/founder-skills/bin/pip install pytest # pytest 9.1.1 as of 2026-07-02 # 2. Sanity-check ~/venvs/founder-skills/bin/python -m pytest --version node --version # must be >= v22 for node --test glob expansion; host has v24.16.0 ``` No Node setup exists or is needed: the JS suite uses only `node:test`, `node:assert/strict`, `node:fs`, `node:path`, `node:url` builtins. ## The three suites — run them all Set `VENV=~/venvs/founder-skills` (or your path). From the **repo root**: ```bash $VENV/bin/python -m pytest -q plugins/market-validation/tests plugins/build-options/tests # expected: 15 passed (6 + 9) node --test 'plugins/market-validation/tests/js/*.test.mjs' # expected: pass 5, fail 0 ``` Or per-plugin (equivalent; the SKILL.md `## Tests` sections use this form): ```bash cd plugins/market-validation && $VENV/bin/python -m pytest -q tests/ # 6 passed cd plugins/build-options && $VENV/bin/python -m pytest -q tests/ # 9 passed cd plugins/market-validation && node --test 'tests/js/*.test.mjs' # 5 pass ``` | Suite | Location | Count (2026-07-02) | What it proves | |---|---|---|---| | market-validation pytest | `plugins/market-validation/tests/` | 6 | `assets/build_deck.py` renders golden + minimal deck-data; `assets/market-map/emit_market_map.py` shape + referential integrity | | build-options pytest | `plugins/build-options/tests/` | 9 | `assets/build_matrix.py` renders golden + minimal decision matrix; `assets/weighting.py` aggregate/weighting/tie math | | market-validation JS | `plugins/market-validation/tests/js/` | 5 | `assets/research-workflow.js` investigator retry / looser-schema fallback / named-drop behavior, via the harness (below) | ### The glob-form rule (Node) `node --test tests/js/` (directory form) **fails** on this repo with `Error: Cannot find module '…/tests/js'` (`code: 'MODULE_NOT_FOUND'`) — verified 2026-07-02 on Node v24.16.0. Always use the **quoted glob form**: `node --test 'tests/js/*.test.mjs'`. The quotes matter: they hand the glob to Node's own expansion instead of the shell's, which keeps the command portable. This is defect ledger item #3 (the JS suite is absent from the README entirely). Both pytest suites are cwd-tolerant *internally* (test files resolve `ROOT` from `__file__`), but the path argument you pass to pytest is cwd-relative — so either run from the plugin dir with `tests/`, or from repo root with the full `plugins/<name>/tests` path. ## The Function-wrapper harness pattern **Problem:** `assets/research-workflow.js` (and build-options' `assets/build-options-workflow.js`) are **Workflow scripts**, not ES modules. The Workflow tool runs them by wrapping the body in an async function and injecting the globals `agent`, `parallel`, `phase`, `log`, `args`. The scripts legitimately use **top-level `await` and a top-level `return`** — the `return` is illegal in a plain module, so `import()` throws a SyntaxError. You cannot unit-test them the normal way. **Solution:** `plugins/market-validation/tests/js/harness.mjs` replicates the Workflow runtime (~53 lines). Read it — it is the reference implementation. What it does: 1. Reads the **real, unmodified** source from disk (`../../assets/research-workflow.js` relative to the harness) — tests exercise the shipped bytes, never a copy. 2. Strips the one piece of module sugar: `src.replace(/^export\s+const\s+meta/m, 'const meta')`. 3. Wraps: `new Function('agent','parallel','phase','log','args', 'return (async () => {\n' + body + '\n})();')` — top-level `await`/`return` are now legal (they're inside the async wrapper). 4. Injects stubs. `runWorkflow(stubs)` accepts `{ agent, parallel?, phase?, log?, args }`: - `agent(prompt, opts)` — your stub; `opts.label` identifies the call (`investigate:<key>`, `investigate-loose:<key>`, `curate`, `verify:<i>`, `synthesize`). The harness records every label in order. - `parallel` defaults to `Promise.all` over thunks. The real Workflow runtime's `parallel()` semantics are **UNVERIFIED** — the suite's last test deliberately re-runs under an `allSettled`-style stub to prove recovery holds either way. Keep that both-ways discipline in new tests. - `phase`/`log` default to no-ops / a recorder; `args` defaults to `{}`. 5. Returns `{ result, logs, agentCalls }` — assert on the workflow's return value, its log lines (e.g. `DROPPED ANGLE`), and the ordered label list. **Honesty boundary:** the harness proves the script's *logic under stubs*. It does NOT prove the script runs under the real Workflow tool — both workflow scripts are still labeled **"proven on 2026-07-02"** (before that: "syntax-checked only"; the harness remains a simulation — the live-runtime proof lives in the campaign spec) (defect ledger #4; the proving run is **fs-flagship-chain-campaign** scope). ## How to add a test to each suite **Python (either plugin):** drop `test_<thing>.py` in the plugin's `tests/` — pytest auto-discovers, no registration. Follow the existing patterns: - Testing a *script* asset (`build_deck.py`, `build_matrix.py`): copy the script AND its HTML template into a `tempfile.mkdtemp()` dir, run it via `subprocess.run([sys.executable, ...], cwd=work)`, assert on returncode + emitted HTML (see `test_build_matrix.py::_render`). The copy-template step is load-bearing because the test copies the *script itself* into the temp dir: the script resolves its template via `Path(__file__).parent` (never cwd — see fs-plugin-anatomy §6 rule 3), so the template must travel with the copied script. - Testing an *importable* asset (`weighting.py`, `enrich`): `sys.path.insert(0, str(ROOT))` then `from assets import ...` (see `test_weighting.py`). - Golden inputs live in `references/example-shiftmate/` (`deck-data.json`, `decision-data.json`) — reuse them; add a minimal-input test for any new render path. **JS (workflow scripts):** drop `<name>.test.mjs` in `plugins/market-validation/tests/js/` — the glob picks it up. Import `{ runWorkflow } from './harness.mjs'`, build a stateful `agent` stub keyed on `opts.label`, and assert on `logs`/`result`/`agentCalls`. Keep downstream phases trivially valid (return `{claims:[],competitors:[]}` for `curate`, a confirm verdict for `verify:*`) so the run completes and your test stays focused. **Extending the harness to build-options (open/candidate):** `plugins/build-options/assets/build-options-workflow.js` currently has **no JS tests** (verified 2026-07-02 — build-options ships only the pytest suite). It uses the same `export const meta` + injected-globals shape, so the harness pattern transplants: copy `harness.mjs` into a new `plugins/build-options/tests/js/`, change the `WORKFLOW` path constant, and re-derive the label conventions from that script before asserting on them (do NOT assume market-validation's labels). This is an improvement candidate, not an instruction — adding a whole new suite is a change; route it per **fs-change-control**. ## Symptom → triage | Symptom (verbatim) | Cause | Fix | |---|---|---| | `/usr/bin/python3: No module named pytest` | Host Python is PEP-668; pytest was never system-installed | Use the venv: `$VENV/bin/python -m pytest ...` (Setup section) | | `error: externally-managed-environment` from pip | You ran `pip install` against the system Python | Never `--break-system-packages`; create the venv and install there | | `Error: Cannot find module '…/tests/js'` / `code: 'MODULE_NOT_FOUND'` from `node --test` | Directory form; Node here doesn't auto-discover a bare dir arg | Quoted glob form: `node --test 'tests/js/*.test.mjs'` | | `MODULE_NOT_FOUND` naming `tests/js/*.test.mjs` literally | Glob didn't match — wrong cwd (pattern is cwd-relative) | Run from the plugin dir, or use the full `plugins/market-validation/tests/js/*.test.mjs` glob from repo root | | `SyntaxError: Illegal return statement` importing a workflow script | You `import()`ed a Workflow script directly | They aren't modules; test through the Function-wrapper harness | | `FileNotFoundError: … assets/matrix.template.html` (build-options, 2 tests) | The gitignore-swallow defect: `*.html` in the plugin `.gitignore` ate the template; your checkout predates the 2026-07-02 rescue (repo fix uncommitted as of that date) | Confirm `git ls-files` tracks `plugins/build-options/assets/matrix.template.html` and `.gitignore` has the `!assets/matrix.template.html` negation; full story + rescue source in **fs-failure-archaeology** | | `claude: command not found` | Claude Code CLI absent (it lives at `~/.local/bin/claude` on the reference host — environment-specific) | Not needed for any test suite. Needed for `claude plugin validate` in `scripts/add-skill.sh` and the pre-push gate — install Claude Code or skip validate-dependent steps and say so | | pytest collects 0 tests | Wrong path arg (e.g. ran `pytest -q tests/` from repo root) | Pass the real path: `plugins/<name>/tests` from root, or `cd` into the plugin first | | Both pytest suites at once report import collisions | Should not happen — test module names are unique across plugins (verified: combined run = 15 passed, 2026-07-02) | If it appears after adding files, rename the new `test_*.py` to be repo-unique | ## Known limitations (keep your honesty consistent) - Pass counts (6/9/5) are a **2026-07-02 snapshot**; re-verify, don't cite stale numbers. - Green suites ≠ working plugins: `claude plugin validate` is manifest-schema-only and the workflow scripts are unproven under the real Workflow runtime (ledger #4, #7). - The 9/9 build-options result depends on the template rescue, which was **uncommitted** as of 2026-07-02 — a fresh clone may still be broken until the operator commits it. - No lint, no type-check, no coverage tooling exists here — the three suites plus the pre-push gate (**fs-release-and-publish**) are the entire verification surface. ## Provenance and maintenance All claims verified live on 2026-07-02 against repo HEAD `2e4c9dd` (plus the uncommitted template rescue). One-line re-verification for anything that may drift: ```bash python3 --version && node --version # host toolchain (was 3.13.5 / v24.16.0) python3 -m pytest --version # still fails system-wide? (PEP-668 claim) $VENV/bin/python -m pytest -q plugins/market-validation/tests plugins/build-options/tests # was 15 passed node --test 'plugins/market-validation/tests/js/*.test.mjs' # was pass 5 node --test plugins/market-validation/tests/js/ 2>&1 | grep MODULE_NOT_FOUND # directory form still broken? git ls-files plugins/build-options/assets/matrix.template.html # empty output = rescue not committed yet grep -n 'python3 -m pytest' README.md # README still ships the failing verbatim form? ls plugins/build-options/tests/js 2>/dev/null # still absent = harness-transplant candidate still open claude --version # CLI presence (validate steps only) ``` ## References - `plugins/market-validation/tests/js/harness.mjs` — the reference Function-wrapper harness. - `plugins/market-validation/tests/js/research-workflow.retry.test.mjs` — model JS test (stateful stub, both-parallel-semantics discipline).
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen