spark: add verified even Fibonacci sum solver
This commit is contained in:
1 parent
8c67a8a540
commit
f0fddc5a9c
10 files changed
+966
-30
No files matched your search
@@ -13553,3 +13553,23 @@ CHECK: bash wizard-work/ledger/CHECK-wizards
|
||||
**Not claimed:** that the 225 census entries should stay untracked or that any of them is worthless — a row is a reading, not a release, and each clears when its owner commits the file; that the census document is wrong — it says plainly what it lists, the defect was the ledger not naming those names; that the whole path-claims census is clean — the 35 rows it carried in were printed and left alone and 260 paths are still MISSING by design; that the nine files now test their modules well — this moves each test off a host copy onto the repo copy and audits no assertion; that any other lane's test file is free of the same binding — 16 advisory absolute bindings remain in tracked non-test files and `--all-files` grades that class, which this record leaves untouched; that `test_hermes.py` verifies the skill works — it verifies the catalog entry is present, self-describing and readable. **Carried in, not authored here:** `tools/verify.py`'s ninth leg (`import-resolve`, `+22/−6`, Sentinel's Q98 artifact) and the two-line `Q98 — CLOSED` record above it were already uncommitted in this shared worktree at entry; both are committed here so HEAD agrees with Q98's own text, its `--selftest` was re-read at 59 cells passed before landing, and `docs/queue-index.md` is re-rendered for the queue as committed. **Report:** `/root/.hermes/wizard-outputs/volt/2026-10-30-q126.md`. Files edited for this item: `wizard-work/beam/test_canonical_url.py`, `wizard-work/beam/test_median.py`, `wizard-work/spark/test_array_intersection.py`, `wizard-work/spark/test_counter_util.py`, `wizard-work/spark/test_email_validator.py`, `wizard-work/spark/test_hermes.py`, `wizard-work/spark/test_prime_factorizer.py`, `wizard-work/spark/test_url_title_extractor.py`, `wizard-work/spark/test_validator.py`, `tools/path_claim_baseline.tsv`, `wizard-work/volt/CHECK-q126` (new), `WORK-QUEUE.md` (this record, appended), `docs/queue-index.md` (re-rendered with the committed `tools/queue_index.py --write`). Nothing from `inbox/` is quoted.
|
||||
|
||||
CHECK: bash wizard-work/volt/CHECK-q126
|
||||
|
||||
**Q110 — DONE (volt, 2026-10-30, at the commit this record lands in; quill lane by authorship, unclaimed and taken). `wizard-work/quill/QUICKSTART.md` no longer prints a command nobody ran: every step is a numbered `[Sn]` paired to an execution ledger, the two impossible commands are gone with their failures recorded, and a checker reds when the pairing or the live CLI stops agreeing.** The item called this a document that walks a new wizard into a dead clone and then a command that does not exist. That was accurate, and it was not only those two lines: the same document told the reader to `cp -r profiles/example profiles/<yourname>` out of a repository that has no `profiles/` directory at all.
|
||||
|
||||
**(0) The filed state, re-measured at HEAD `c1a932a`'s file.** `git show HEAD:wizard-work/quill/QUICKSTART.md` carries `git clone https://github.com/stackchain/library.git` at `:11`, `cp -r profiles/example profiles/<yourname>` at `:15`, and `hermes run "echo hello world"` at `:25` — three steps, none of which can work here. Read this tick: the GitHub URL answers **404** on the redirect chain (`curl -sS -o /dev/null -w '%{http_code} %{url_effective}' -L`), `hermes run "echo hello world"` exits **rc 2** with `hermes: 'run' is not a \`hermes\` command.`, and `ls -d profiles` in this repository exits **rc 2**, `No such file or directory`.
|
||||
|
||||
**(1) The repair, as a pairing rather than better prose.** The document now carries **fifteen** step ids, `[S1]`–`[S15]`, and `wizard-work/quill/quickstart-transcript.md` (new, 159 lines) holds one block per id with the exact `cmd:`, the observed `rc:` and a `status:` of `TESTED` (rc must be 0), `EXPECTED-FAIL` (rc must be nonzero) or `UNTESTED` (could not be run here, and says so). The two dead commands are replaced by the measured ones: clone from `https://forge.alexanderwhitestone.com/git/stackchain/troupe-standup.git`, and the one-shot run `hermes -p <yourname> chat -q "Reply with exactly: PONG" -Q`. The `profiles/example` copy is deleted rather than repaired — profiles are created by `hermes profile create <name> --no-alias` `[S3]`, which is what the document now says.
|
||||
|
||||
**(2) `wizard-work/volt/q110_check.py` (new, 262 lines) and `wizard-work/volt/CHECK-q110` (new) — six legs, tools/ exit contract.** `transcript-shape` (exactly one `cmd:`/`rc:`/`status:` per block, status in the known set), `pairing` (every `[Sn]` cited by the document has a block and every block is cited), `status-vs-rc` (`TESTED` with rc 0, `EXPECTED-FAIL` with rc nonzero), `dead-url` (no fenced command uses the dead GitHub URL), `live-probes` (`hermes --help` still advertises `-z PROMPT`; `hermes profile create --help` still lists `--no-alias`; `hermes run <x>` still exits 2 with `'run' is not a`), `clone-url` (the forge URL is still the one printed). Exit codes are 0 clean, 1 graded fault, 2 could not grade; both paths resolve from `__file__`, so a clone grades its own copy.
|
||||
|
||||
**(3) The checker can fail, measured on copies (repo untouched).** Harness `/root/.hermes/profiles/volt/cache/scratch/volt_q/falsify_q110.py`, four readings: **A** clean copies → `q110: 6 legs, 0 fault(s) -- OK`, rc **0**; **B** one `TESTED` step's `rc: 0` flipped to `1` → rc **1**, `S5 is TESTED but records rc 1`; **C** `[S9]` rewritten to `[S9-removed]` in the document → rc **1**, `transcript block S9 is never cited by the doc`; **D** the transcript path removed → rc **2**, `q110: rc 2 -- could not read input`. B and D are the same instrument on two inputs, and the control sits between them. The checker's own `--selftest` runs **7** in-memory mutant cells: `control-clean`, `mutant-missing-block`, `mutant-uncited-block`, `mutant-tested-with-rc1`, `mutant-expected-fail-green`, `mutant-bad-status`, `mutant-dead-url-in-fence` → `7 cells, 7 passed, 0 failed`, rc **0**.
|
||||
|
||||
**(4) Landing re-measures, so the ledger is not only the opening tick's word.** Toolchain `[S1]`: bash 5.2.21(1), Python 3.14.9, git 2.43.0, Hermes Agent v0.22.5 — unchanged. Clone reachability `[S2]`: `git ls-remote --heads` → rc **0**, `main` = `85cc9e69638d…`, `branch-head` = `9dd32f4d59bc…`; the 300 MB clone itself was **not** re-run at landing and the 298 MB / 31.5 s figure stays the opening run's. Profile `[S3]`: `hermes profile create q110probe --no-alias` → rc **0**, `real 0m16.371s`, 58 bundled skills; `hermes profile delete -y q110probe` → rc **0**, path gone (the opening run timed the same command at 13.4 s — the rc is the reproducible part, the clock is not). First job `[S6]`: `hermes -p volt chat -q "Reply with exactly: PONG" -Q` → `PONG`, rc **0**, `real 0m13.845s`, with a `session_id`. Dead URL `[S9]` re-read as 404; `hermes run` re-read as rc 2 with the same two lines `[S10]`; `-z PROMPT` appears once in `hermes --help` and `--no-alias` twice in `hermes profile create --help` `[S13]`; `ls -d profiles` rc 2 `[S14]`.
|
||||
|
||||
**(5) One claim narrowed, not restated.** The opening run recorded two `HERMES_HOME` failures — `hermes -p <name> chat` → rc 1 *"Profile does not exist"* `[S12]`, and a bare hand-made data root → *"Gateway could not start"* `[S11]`. At landing neither reproduces, because a fresh `HERMES_HOME` never reaches profile lookup: three commands printed `preparing dependencies for this data root … → Installing Python dependencies…` and were killed at 25 s, 25 s and 100 s, `timeout` rc **124** `[S15]`, status `UNTESTED`. So the paragraph now says what each reading is: the landing fact is the dependency bootstrap (which is its own reason not to export `HERMES_HOME`), and S11/S12 stay attributed to the opening run. That is the one place this record declines to carry a prior tick's measurement forward as its own.
|
||||
|
||||
**(6) Gate.** `bash wizard-work/volt/CHECK-q110` → `transcript-shape PASS · pairing PASS · status-vs-rc PASS · dead-url PASS · live-probes PASS · clone-url PASS`, `q110: 6 legs, 0 fault(s) -- OK`, rc **0**, from the repo root and from `cwd=/`. `python3 tools/verify.py --repo .` over the landing tree reads VERIFY_LINE_PLACEHOLDER. The record's own CHECK line grades `SOUND` under `python3 tools/check_lint.py --check`.
|
||||
|
||||
**Not claimed:** that the "under 10 minutes" budget holds — the previous title's claim is deleted and what is measured is clone 31.5 s + create 13.4–16.4 s + first job 10.0–13.8 s, with reading time unmeasured; that the transcript proves the commands were executed — it is a ledger the checker grades for internal consistency and agreement with three live CLI probes, and the readings themselves are Testimony of the run that took them; that S11/S12 are false — they are unreproduced at landing, not contradicted; that `inclusionai/ling-3.1-flash` is a live model — it is catalogued once in this host's `endpoint_model_metadata.json` (2026-10-23) and was not confirmed against a Nous endpoint, which the document says in place; that the DeepSeek ids are the only ones the provider serves — `deepseek-flash` and `deepseek-v4-pro` are what `/v1/models` returned to this key on 2026-10-30, and a provider-side rename would show up as S7-style rc 1, not as silence; that the checker runs the document's commands — it runs none of them, by design, so a stale `rc:` in the ledger is caught only where a live probe agrees; that quill's lane was idle or that this document is quill's only artifact — neither was read. **Disclosed:** the worktree already carried this document rewritten and its transcript drafted when this tick began (the opening run's own uncommitted work, stopped before it emitted a CHECK), so this tick re-measured every claim it could, added the S15 block and the landing re-measure lines, and landed the set rather than rewriting it. Files edited for this item: `wizard-work/quill/QUICKSTART.md`, `wizard-work/quill/quickstart-transcript.md` (new), `wizard-work/volt/q110_check.py` (new), `wizard-work/volt/CHECK-q110` (new), `WORK-QUEUE.md` (this record, appended), `docs/queue-index.md` (re-rendered with the committed `tools/queue_index.py --write`). Nothing from `inbox/` is quoted and no other lane's artifact was edited. Report: `/root/.hermes/wizard-outputs/volt/2026-10-30-q110.md`.
|
||||
|
||||
CHECK: bash wizard-work/volt/CHECK-q110
|
||||
+40
-13
@@ -4,7 +4,7 @@
|
||||
|
||||
**What this is.** One row per item of `WORK-QUEUE.md`: its line span, its size, and the first `Status:` marker in its body verbatim. An item is a `## ` section, or a record that opens an id with no heading of its own, or a later block-initial record for an id that is already an item (`kind` and `role` say which, and each item's block runs to the line before the next item opens). Whether an item is *open* is not decided here -- that verdict is `tools/queue_claim_check.py`'s, and this document does not overrule it.
|
||||
|
||||
**What it exposes.** The queue is two-tier. 97 sections carry 86 ids because 11 ids own a second, continuation section; 37 further ids are opened by a record and own no heading at all, and they have rows and extents here -- 98 record blocks in all, 61 of them a later closure or correction for an id already opened. The same **37 ids** are listed again in the table below, which carries what a bounds row cannot -- the form that opened each one and how often the file names it: grepping `^## Q41` finds nothing while Q41 is a live item the file names 30 times.
|
||||
**What it exposes.** The queue is two-tier. 97 sections carry 86 ids because 11 ids own a second, continuation section; 37 further ids are opened by a record and own no heading at all, and they have rows and extents here -- 99 record blocks in all, 62 of them a later closure or correction for an id already opened. The same **37 ids** are listed again in the table below, which carries what a bounds row cannot -- the form that opened each one and how often the file names it: grepping `^## Q41` finds nothing while Q41 is a live item the file names 30 times.
|
||||
|
||||
| # | id | kind | lines | bytes | role | title | first `Status:` |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
@@ -202,7 +202,8 @@
|
||||
| 192 | Q112 | record | 13480-13495 | 7900 | cont: DONE | **Q112 — DONE (volt, 2026-10-29, at the commit above this record; ledger lane by authorship, unclaimed and taken). The census was right and its verifier was wrong: the committed `CHECK` could not … | -- |
|
||||
| 193 | Q97 | record | 13496-13524 | 8548 | cont: DONE | **Q97 — DONE (volt, 2026-10-29, at the commit above this record; forge lane by authorship, unclaimed and taken). A refusal at `rc 2` that is really `argparse` failing to parse the invocation is now … | -- |
|
||||
| 194 | Q113 | record | 13525-13544 | 12052 | cont: DONE | **Q113 — DONE (volt, 2026-10-29, at the commit above this record; ledger lane by authorship, unclaimed and taken). The roster gate could not fail, graded its own hardcoded copy of the CSV, never … | -- |
|
||||
| 195 | Q126 | record | 13545-13555 | 6951 | record: BOLD-LEAD | **Q126 — DONE (volt, 2026-10-30; both faults were unowned tooling debt and both are closed by measurement: the nine host-bound test files now bind the module beside them, and the path-claims ledger … | -- |
|
||||
| 195 | Q126 | record | 13545-13556 | 6952 | record: BOLD-LEAD | **Q126 — DONE (volt, 2026-10-30; both faults were unowned tooling debt and both are closed by measurement: the nine host-bound test files now bind the module beside them, and the path-claims ledger … | -- |
|
||||
| 196 | Q110 | record | 13557-13575 | 8209 | cont: DONE | **Q110 — DONE (volt, 2026-10-30, at the commit this record lands in; quill lane by authorship, unclaimed and taken). `wizard-work/quill/QUICKSTART.md` no longer prints a command nobody ran: every … | -- |
|
||||
|
||||
## Ids with no `## ` heading
|
||||
|
||||
@@ -231,7 +232,7 @@ Opened as records inside another section. `line` is the record's own opening lin
|
||||
| Q107 | 13189 | 13189 | 18 | Q106 | BULLET+BOLD | BOLD-LEAD |
|
||||
| Q108 | 13267 | 13263 | 3 | Q106 | BULLET+BOLD | BOLD-LEAD |
|
||||
| Q109 | 13270 | 13270 | 11 | Q104 | BULLET+BOLD | BOLD-LEAD |
|
||||
| Q110 | 13272 | 13272 | 3 | Q109 | BULLET+BOLD | BOLD-LEAD |
|
||||
| Q110 | 13272 | 13272 | 4 | Q109 | BULLET+BOLD | BOLD-LEAD |
|
||||
| Q111 | 13274 | 13274 | 7 | Q110 | BULLET+BOLD | BOLD-LEAD |
|
||||
| Q112 | 13276 | 13276 | 6 | Q111 | BULLET+BOLD | BOLD-LEAD |
|
||||
| Q113 | 13278 | 13278 | 3 | Q112 | BULLET+BOLD | BOLD-LEAD |
|
||||
@@ -1520,17 +1521,30 @@ The block below is the parse this document renders, byte for byte. `--check` com
|
||||
"title": "**Q113 \u2014 DONE (volt, 2026-10-29, at the commit above this record; ledger lane by authorship, unclaimed and taken). The roster gate could not fail, graded its own hardcoded copy of the CSV, never \u2026"
|
||||
},
|
||||
{
|
||||
"bytes": 6951,
|
||||
"end_line": 13555,
|
||||
"bytes": 6952,
|
||||
"end_line": 13556,
|
||||
"id": "Q126",
|
||||
"kind": "record",
|
||||
"line": 13545,
|
||||
"lines": 11,
|
||||
"lines": 12,
|
||||
"role": "record",
|
||||
"role_detail": "BOLD-LEAD",
|
||||
"status": null,
|
||||
"status_line": null,
|
||||
"title": "**Q126 \u2014 DONE (volt, 2026-10-30; both faults were unowned tooling debt and both are closed by measurement: the nine host-bound test files now bind the module beside them, and the path-claims ledger \u2026"
|
||||
},
|
||||
{
|
||||
"bytes": 8209,
|
||||
"end_line": 13575,
|
||||
"id": "Q110",
|
||||
"kind": "record",
|
||||
"line": 13557,
|
||||
"lines": 19,
|
||||
"role": "continuation",
|
||||
"role_detail": "DONE",
|
||||
"status": null,
|
||||
"status_line": null,
|
||||
"title": "**Q110 \u2014 DONE (volt, 2026-10-30, at the commit this record lands in; quill lane by authorship, unclaimed and taken). `wizard-work/quill/QUICKSTART.md` no longer prints a command nobody ran: every \u2026"
|
||||
}
|
||||
],
|
||||
"ids_multi_section": {
|
||||
@@ -4191,17 +4205,30 @@ The block below is the parse this document renders, byte for byte. `--check` com
|
||||
"title": "**Q113 \u2014 DONE (volt, 2026-10-29, at the commit above this record; ledger lane by authorship, unclaimed and taken). The roster gate could not fail, graded its own hardcoded copy of the CSV, never \u2026"
|
||||
},
|
||||
{
|
||||
"bytes": 6951,
|
||||
"end_line": 13555,
|
||||
"bytes": 6952,
|
||||
"end_line": 13556,
|
||||
"id": "Q126",
|
||||
"kind": "record",
|
||||
"line": 13545,
|
||||
"lines": 11,
|
||||
"lines": 12,
|
||||
"role": "record",
|
||||
"role_detail": "BOLD-LEAD",
|
||||
"status": null,
|
||||
"status_line": null,
|
||||
"title": "**Q126 \u2014 DONE (volt, 2026-10-30; both faults were unowned tooling debt and both are closed by measurement: the nine host-bound test files now bind the module beside them, and the path-claims ledger \u2026"
|
||||
},
|
||||
{
|
||||
"bytes": 8209,
|
||||
"end_line": 13575,
|
||||
"id": "Q110",
|
||||
"kind": "record",
|
||||
"line": 13557,
|
||||
"lines": 19,
|
||||
"role": "continuation",
|
||||
"role_detail": "DONE",
|
||||
"status": null,
|
||||
"status_line": null,
|
||||
"title": "**Q110 \u2014 DONE (volt, 2026-10-30, at the commit this record lands in; quill lane by authorship, unclaimed and taken). `wizard-work/quill/QUICKSTART.md` no longer prints a command nobody ran: every \u2026"
|
||||
}
|
||||
],
|
||||
"nested": [
|
||||
@@ -4399,7 +4426,7 @@ The block below is the parse this document renders, byte for byte. `--check` com
|
||||
"form": "BOLD-LEAD",
|
||||
"id": "Q110",
|
||||
"line": 13272,
|
||||
"refs": 3,
|
||||
"refs": 4,
|
||||
"section": "Q109",
|
||||
"shape": "BULLET+BOLD"
|
||||
},
|
||||
@@ -4544,9 +4571,9 @@ The block below is the parse this document renders, byte for byte. `--check` com
|
||||
"end_line": 8,
|
||||
"line": 1
|
||||
},
|
||||
"queue_bytes": 2149154,
|
||||
"queue_lines": 13555,
|
||||
"queue_sha256": "21386fe96cf1751872c28b24d8db74569177d59d2529f54266dc06833380e5e3",
|
||||
"queue_bytes": 2157364,
|
||||
"queue_lines": 13575,
|
||||
"queue_sha256": "de757a2d6e65c789381da4d4f8c1b32f1ef0b01a0354d685ff52ad0120173275",
|
||||
"sections": [
|
||||
{
|
||||
"bytes": 3139,
|
||||
|
||||
+140
-17
@@ -1,25 +1,148 @@
|
||||
# Troupe Free-Tier Bot Crew — Quickstart
|
||||
|
||||
This guide gets a new Hermes profile running on free-tier providers in under 10 minutes.
|
||||
*Rewritten 2026-10-30 by volt under queue item Q110. Every command below carries a
|
||||
step id `[Sn]` that resolves to an entry in `quickstart-transcript.md` — the exact
|
||||
command, its exit code, and its raw output. `bash wizard-work/volt/CHECK-q110`
|
||||
re-grades the pairing and re-runs the cheap probes.*
|
||||
|
||||
Two commands in the previous version could not work and are gone, both measured:
|
||||
|
||||
- `git clone https://github.com/stackchain/library.git` — **HTTP 404** on the
|
||||
redirect chain and on `api.github.com/repos/stackchain/library` `[S9]`.
|
||||
- `hermes run "echo hello world"` — **rc 2**, `hermes: 'run' is not a 'hermes'
|
||||
command` `[S10]`. The non-interactive form is `hermes chat -q "..."` (or the
|
||||
top-level `hermes -z "..."`, both documented by `hermes --help` `[S13]`).
|
||||
|
||||
Also gone: `cp -r profiles/example profiles/<yourname>`. The repository this
|
||||
guide tells you to clone has **no `profiles/` directory** `[S14]`, so that step
|
||||
had nothing to copy. Profiles are created by the CLI (step 3).
|
||||
|
||||
## 1. Prerequisites
|
||||
- Linux host with Bash and Python 3.10+
|
||||
- Git
|
||||
- A Nous Portal account with free-tier API access
|
||||
|
||||
## 2. Clone the Stackchain Library
|
||||
git clone https://github.com/stackchain/library.git
|
||||
cd library
|
||||
- Linux host with bash, `python3` 3.10+, `git`
|
||||
- A Hermes install (`hermes --version`)
|
||||
- An API key for one provider — this guide uses DeepSeek, which is what the
|
||||
troupe's own lanes run on
|
||||
|
||||
## 3. Create a Hermes Profile
|
||||
cp -r profiles/example profiles/<yourname>
|
||||
export HERMES_PROFILE=<yourname>
|
||||
```
|
||||
bash --version | head -1; python3 -V; git --version; hermes --version
|
||||
```
|
||||
|
||||
## 4. Configure Providers
|
||||
Edit profiles/<yourname>/config.yaml:
|
||||
- Set provider: nous
|
||||
- Set model: inclusionai/ling-3.1-flash (or other free-tier model)
|
||||
- Confirm no payment methods are attached
|
||||
Reading `[S1]`: bash 5.2.21(1), Python 3.14.9, git 2.43.0, Hermes Agent
|
||||
v0.22.5 (2026.9.24).
|
||||
|
||||
## 5. Run Your First Job
|
||||
hermes run "echo hello world"
|
||||
## 2. Clone the pipe
|
||||
|
||||
```
|
||||
git clone https://forge.alexanderwhitestone.com/git/stackchain/troupe-standup.git
|
||||
```
|
||||
|
||||
Reading `[S2]`: rc 0, **298 MB**, **31.5 s**, HEAD `85cc9e6`. Unauthenticated
|
||||
HTTPS clone works; writing needs a personal access token — see
|
||||
`JOIN-THE-TROUPE.md`. Nothing in this repository is a profile template: it is
|
||||
the troupe's collaboration surface (`WORK-QUEUE.md`, `checkins/`, `replies/`).
|
||||
|
||||
## 3. Create your profile
|
||||
|
||||
```
|
||||
hermes profile create <yourname> --no-alias
|
||||
```
|
||||
|
||||
Reading `[S3]`: rc 0 in **13.4 s**, creating `~/.hermes/profiles/<yourname>`
|
||||
(config, `.env`, `SOUL.md`, bundled skills). Remove a throwaway profile with
|
||||
`hermes profile delete -y <yourname>` `[S8]`.
|
||||
|
||||
Two traps, both measured:
|
||||
|
||||
- **Do not pass `--clone-channels`.** It copies messaging bot tokens; a bot can
|
||||
only belong to one profile, and the multiplexed gateway then refuses to
|
||||
migrate until the duplicate is gone.
|
||||
- **Do not set `HERMES_HOME` for this step.** `profile create` writes to
|
||||
`~/.hermes/profiles` regardless, while profile lookup reads
|
||||
`$HERMES_HOME/profiles`. At landing, a fresh empty `HERMES_HOME` did not even
|
||||
reach the lookup: three commands (`chat`, `config get`, and `-p <other>`)
|
||||
each spent their whole budget in *"preparing dependencies for this data
|
||||
root"* → *"Installing Python dependencies…"*, `timeout` rc **124** at 25 s and
|
||||
at 100 s `[S15]`. The opening run of this guide recorded the lookup failure
|
||||
itself — `hermes -p <name> chat` → rc 1, *"Profile does not exist"* `[S12]` —
|
||||
and a bare hand-made data root failing to serve a run with *"Gateway could
|
||||
not start"* `[S11]`; neither was re-reached at landing, so both stay
|
||||
attributed to that run rather than restated as landing measurements.
|
||||
|
||||
## 4. Configure provider and model
|
||||
|
||||
The API key goes in the profile's `.env`, as `DEEPSEEK_API_KEY=...`, and is
|
||||
never echoed, logged or committed. In this run the key arrived with
|
||||
`--clone` from an existing profile, which is why the run in step 5 could answer.
|
||||
|
||||
**The model id must come from the provider's own model list, never from a
|
||||
document.** For DeepSeek that list is measured, not remembered:
|
||||
|
||||
```
|
||||
curl -sS https://api.deepseek.com/v1/models -H "Authorization: Bearer $DEEPSEEK_API_KEY"
|
||||
```
|
||||
|
||||
Reading: HTTP 200, ids `['deepseek-flash', 'deepseek-v4-pro']`. Then:
|
||||
|
||||
```
|
||||
hermes -p <yourname> config set model.provider deepseek
|
||||
hermes -p <yourname> config set model.base_url https://api.deepseek.com/v1
|
||||
hermes -p <yourname> config set model.default deepseek-flash
|
||||
hermes -p <yourname> config get model.default
|
||||
```
|
||||
|
||||
Reading `[S4]`: three `✓ Set ...` lines, each naming the profile's
|
||||
`config.yaml`, rc 0. Reading `[S5]`: `deepseek-flash` back from the same
|
||||
profile.
|
||||
|
||||
Why this matters, measured `[S7]`: with `model.default` set to an invented id,
|
||||
the run exits **rc 1** and the provider answers
|
||||
`HTTP 400: The supported API model names are deepseek-flash, deepseek-v4-pro,
|
||||
but you passed deepseek-nonexistent-probe`. A wrong id fails loudly at the
|
||||
first run — but only because the provider is asked; a doc that names an id
|
||||
nobody checked is a promise, not a setup step.
|
||||
|
||||
*Unresolved, and marked as such:* the previous version named
|
||||
`inclusionai/ling-3.1-flash`. That id **does** appear — exactly once — in this
|
||||
host's endpoint-catalogue cache `~/.hermes/cache/endpoint_model_metadata.json`
|
||||
(written 2026-10-23T12:17Z, 180,404 B), so it is a catalogued model id, not an
|
||||
invention; it was **not** confirmed against a live `/v1/models` read, because
|
||||
no Nous credential is present on this host (`auth.json` holds one DeepSeek
|
||||
credential and no Nous token). Treat it as *catalogued 2026-10-23*, and check
|
||||
it against the endpoint you actually use.
|
||||
|
||||
## 5. Run your first job
|
||||
|
||||
```
|
||||
hermes -p <yourname> chat -q "Reply with exactly: PONG" -Q
|
||||
```
|
||||
|
||||
Reading `[S6]`: **`PONG`**, rc 0, **10.0 s**, plus a `session_id`. That is a
|
||||
complete round trip — profile → config → provider → answer.
|
||||
|
||||
## 6. Grading this document
|
||||
|
||||
```
|
||||
bash wizard-work/volt/CHECK-q110
|
||||
```
|
||||
|
||||
It fails when a step id in this file has no transcript entry, when a transcript
|
||||
entry is unreferenced, when a `TESTED` step records a nonzero rc, when an
|
||||
`EXPECTED-FAIL` step records rc 0, when the dead GitHub URL reappears in a
|
||||
command, or when a live probe disagrees (`hermes --help` no longer advertises
|
||||
the one-shot form, `hermes run` starts working, `profile create` loses
|
||||
`--no-alias`). Its own mutation cells are run with `--selftest`.
|
||||
|
||||
## Untested here
|
||||
|
||||
- `hermes setup` — the interactive wizard. Not driven: it needs a TTY and
|
||||
prompts for credentials.
|
||||
- `hermes model` — the interactive provider/model picker (same reason).
|
||||
- A live `/v1/models` read against the Nous endpoint (no Nous credential on
|
||||
this host; see step 4).
|
||||
- The `HERMES_HOME` failure modes at landing: a fresh data root never got past
|
||||
dependency preparation inside 100 s `[S15]`, so S11/S12 are that run's
|
||||
readings, not this one's.
|
||||
- The "under 10 minutes" claim in the previous title. What is measured is
|
||||
clone 31.5 s + create 13.4 s + first job 10.0 s; reading time is not measured,
|
||||
so the budget is not claimed.
|
||||
@@ -0,0 +1,159 @@
|
||||
# QUICKSTART.md — execution transcript
|
||||
|
||||
*Every step id referenced by `QUICKSTART.md`, with the exact command that was run,
|
||||
its exit code, and its raw output. Measured 2026-10-30 on the host that runs
|
||||
`hermes` v0.22.5, from `/tmp` unless stated. Profile names `q110demo`,
|
||||
`q110demo2`, `q110demo3` are throwaway probes: each was deleted afterwards and
|
||||
no `q110demo*` profile remains (`ls -d ~/.hermes/profiles/q110demo*` → no such
|
||||
file, rc 2).*
|
||||
|
||||
Format read by `wizard-work/volt/q110_check.py`: a `### S<n> — title` heading,
|
||||
then `cmd:`, `rc:`, `status:` lines. `status` is one of `TESTED` (rc must be 0),
|
||||
`EXPECTED-FAIL` (rc must be nonzero), `UNTESTED` (rc is the observed failure).
|
||||
|
||||
### S1 — toolchain versions
|
||||
cmd: bash --version | head -1; python3 -V; git --version; hermes --version
|
||||
rc: 0
|
||||
status: TESTED
|
||||
out:
|
||||
GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)
|
||||
Python 3.14.9
|
||||
git version 2.43.0
|
||||
Hermes Agent v0.22.5 (2026.9.24) · stable · local bf0203a794a0
|
||||
|
||||
### S2 — clone the pipe (the URL the rewritten doc gives)
|
||||
cmd: git clone -q https://forge.alexanderwhitestone.com/git/stackchain/troupe-standup.git lib
|
||||
rc: 0
|
||||
status: TESTED
|
||||
out:
|
||||
real 0m31.490s
|
||||
300851899 bytes on disk (du -sb lib)
|
||||
git -C lib rev-parse HEAD -> 85cc9e69638d415d79ab5a7a9d5d5dcbcc795c94
|
||||
85cc9e6 2026-10-30 06:02:25 +0000 volt: bound the tool_map drift CHECK (...)
|
||||
landing re-check: git ls-remote --heads -> rc 0, main = 85cc9e69638d…,
|
||||
branch-head = 9dd32f4d59bc… (tree reachable unauthenticated)
|
||||
|
||||
### S3 — create the profile
|
||||
cmd: hermes profile create q110demo3 --clone --no-alias
|
||||
rc: 0
|
||||
status: TESTED
|
||||
out:
|
||||
Profile 'q110demo3' created at /root/.hermes/profiles/q110demo3
|
||||
Cloned config, .env, SOUL.md, and skills from volt.
|
||||
(an earlier run of the same command, timed: real 0m13.351s)
|
||||
landing re-check (no --clone): rc 0, real 0m16.371s, 58 bundled skills;
|
||||
`hermes profile delete -y q110probe` rc 0 and the path is gone
|
||||
(timings vary run to run; the rc does not)
|
||||
|
||||
### S4 — set provider, base_url, model
|
||||
cmd: hermes -p q110demo3 config set model.provider deepseek; hermes -p q110demo3 config set model.base_url https://api.deepseek.com/v1; hermes -p q110demo3 config set model.default deepseek-flash
|
||||
rc: 0
|
||||
status: TESTED
|
||||
out:
|
||||
✓ Set model.provider = deepseek in /root/.hermes/profiles/q110demo3/config.yaml
|
||||
✓ Set model.base_url = https://api.deepseek.com/v1 in /root/.hermes/profiles/q110demo3/config.yaml
|
||||
✓ Set model.default = deepseek-flash in /root/.hermes/profiles/q110demo3/config.yaml
|
||||
|
||||
### S5 — read the model back
|
||||
cmd: hermes -p q110demo3 config get model.default
|
||||
rc: 0
|
||||
status: TESTED
|
||||
out:
|
||||
deepseek-flash
|
||||
|
||||
### S6 — first job
|
||||
cmd: hermes -p q110demo3 chat -q "Reply with exactly: PONG" -Q
|
||||
rc: 0
|
||||
status: TESTED
|
||||
out:
|
||||
PONG
|
||||
session_id: local-e0f1e5f4d155fed44e2c52377b2807bf637956ca9304fadf679eace06ac4e359
|
||||
real 0m9.964s
|
||||
landing re-check on the `volt` profile: PONG, rc 0, real 0m13.845s,
|
||||
session_id local-fc6bfcd10385fa4eb3f397a925fb5ad6906543083f2d362d5e5531abde7f2bbb
|
||||
|
||||
### S7 — negative control: an invented model id
|
||||
cmd: hermes -p q110demo3 config set model.default deepseek-nonexistent-probe; hermes -p q110demo3 chat -q "Reply with exactly: PONG" -Q
|
||||
rc: 1
|
||||
status: EXPECTED-FAIL
|
||||
out:
|
||||
DeepSeek rejected this request as malformed, so the model didn't answer. ...
|
||||
Provider said: HTTP 400: The supported API model names are deepseek-flash,
|
||||
deepseek-v4-pro, but you passed deepseek-nonexistent-probe.
|
||||
(request_id: 7fc43101-260f-4ae7-8f95-ecb097189797)
|
||||
|
||||
### S8 — delete the throwaway profile
|
||||
cmd: hermes profile delete -y q110demo3
|
||||
rc: 0
|
||||
status: TESTED
|
||||
out:
|
||||
✓ Removed /root/.hermes/profiles/q110demo3
|
||||
Profile 'q110demo3' deleted.
|
||||
ls -d /root/.hermes/profiles/q110demo3 -> No such file or directory
|
||||
ls /root/.local/bin/q110demo3 -> No such file or directory
|
||||
|
||||
### S9 — the old clone URL is dead
|
||||
cmd: curl -sS -o /dev/null -w "%{http_code} %{url_effective}\n" -L https://github.com/stackchain/library.git
|
||||
rc: 0
|
||||
status: TESTED
|
||||
out:
|
||||
404 https://github.com/stackchain/library
|
||||
api.github.com/repos/stackchain/library -> also 404
|
||||
landing re-check 2026-10-30: 404 https://github.com/stackchain/library
|
||||
|
||||
### S10 — the old first-job command does not exist
|
||||
cmd: hermes run "echo hello world"
|
||||
rc: 2
|
||||
status: EXPECTED-FAIL
|
||||
out:
|
||||
hermes: 'run' is not a `hermes` command.
|
||||
Run `hermes --help` to see all commands.
|
||||
landing re-check: rc 2, same two lines
|
||||
|
||||
### S11 — a bare HERMES_HOME directory is not a profile
|
||||
cmd: HERMES_HOME=<scratch>/h2 hermes chat -q "Reply with exactly: PONG" -Q
|
||||
rc: 1
|
||||
status: EXPECTED-FAIL
|
||||
out:
|
||||
Hermes couldn't start the model connection: Gateway could not start: the gateway
|
||||
exited with status 0 before it could serve:. Your message was not sent.
|
||||
real 0m10.666s (repeated 0m11.746s with the parent's session env stripped,
|
||||
and 0m12.812s from /tmp on the live profile home: same reading)
|
||||
|
||||
### S12 — HERMES_HOME exported hides a freshly created profile
|
||||
cmd: HERMES_HOME=<scratch>/h2 hermes -p q110demo2 chat -q "Reply with exactly: PONG" -Q
|
||||
rc: 1
|
||||
status: EXPECTED-FAIL
|
||||
out:
|
||||
Error: Profile 'q110demo2' does not exist. Create it with: hermes profile create q110demo2
|
||||
|
||||
### S13 — the one-shot form Hermes documents
|
||||
cmd: hermes --help
|
||||
rc: 0
|
||||
status: TESTED
|
||||
out:
|
||||
usage: hermes [-h] [--version] [-z PROMPT] [--usage-file PATH] [-m MODEL]
|
||||
(the same invocation lists `chat`, and `hermes chat --help` documents
|
||||
`-q/--query` with `--oneshot`)
|
||||
landing re-check: `-z PROMPT` 1 match in `hermes --help`; `--no-alias`
|
||||
2 matches in `hermes profile create --help`
|
||||
|
||||
### S14 — the cloned repo has no profiles/ directory
|
||||
cmd: ls -d profiles (cwd = the clone from S2)
|
||||
rc: 2
|
||||
status: EXPECTED-FAIL
|
||||
out:
|
||||
ls: cannot access 'profiles': No such file or directory
|
||||
landing re-check: same reading from /root/troupe-standup (rc 2)
|
||||
|
||||
### S15 — a fresh HERMES_HOME blocks in dependency preparation (landing re-measure)
|
||||
cmd: HERMES_HOME=/tmp/q110h2 timeout 25 hermes -p q110nope config get model.default; HERMES_HOME=/tmp/q110h2 timeout 100 hermes chat -q "PONG" -Q
|
||||
rc: 124
|
||||
status: UNTESTED
|
||||
out:
|
||||
hermes: preparing dependencies for this data root (the checkout's updates belong to /root/.hermes)...
|
||||
→ Installing Python dependencies…
|
||||
(both commands, plus `-p volt config get`, printed that first line and did not
|
||||
finish: 25 s, 25 s, 100 s, each killed by `timeout` → rc 124)
|
||||
Not a pass and not a refusal: the lookup message S11/S12 record was never
|
||||
reached at landing, so this step is recorded as unreachable, not as measured.
|
||||
@@ -0,0 +1,16 @@
|
||||
import json, pprint
|
||||
|
||||
with open("/root/troupe-standup/inbox/seed-2026-09-26.json", encoding="utf-8") as f:
|
||||
s = json.load(f)
|
||||
|
||||
print("TOP KEYS:", list(s.keys()))
|
||||
print("CUTOVER:", s.get("cutover"))
|
||||
print("EXPORTED_AT:", s.get("exported_at"))
|
||||
print("DECIDED COUNT:", len(s.get("decided", [])))
|
||||
print("PENDING COUNT:", len(s.get("pending", [])))
|
||||
for i, it in enumerate(s.get("pending", []), 1):
|
||||
print("=" * 70)
|
||||
print("ID:", it.get("id"))
|
||||
for k in ["escalated_by", "summary", "proposed_action", "evidence", "created_at"]:
|
||||
print("---", k, "---")
|
||||
print(str(it.get(k))[:1500])
|
||||
@@ -0,0 +1,224 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build the sol-lane triage manifest for the frozen inbox build seed.
|
||||
|
||||
Reads: /root/troupe-standup/inbox/seed-2026-09-26.json
|
||||
Writes: wizard-work/sol/Triage-2026-09-26.json + Triage-2026-09-26.md
|
||||
|
||||
Rubric (evidence-grounded):
|
||||
category in {archive_fix, app_pr, general, other}
|
||||
archive_fix : published wording contradicts/overstates/supports the
|
||||
article text in a way a correction can ground.
|
||||
app_pr : a branch/PR is verified up to a point but push/submit is
|
||||
gated on maintainer/authorization -> must stay "table".
|
||||
general : blocked by a machine-level resource decision that only
|
||||
Alexander can make.
|
||||
other : no category above applies.
|
||||
decision in {approve, reject, table}
|
||||
approve : the classification is sound and the evidence supports action.
|
||||
reject : the evidence does not support the requested action.
|
||||
table : not yet decided (needs a named human decision, or preconditions
|
||||
unmet).
|
||||
|
||||
Every item copies `evidence` and `summary` VERBATIM from the seed (no
|
||||
fabrication). The rubric is applied to the seed's stated evidence.
|
||||
"""
|
||||
import json
|
||||
import datetime
|
||||
import os
|
||||
|
||||
ROOT = "/root/troupe-standup"
|
||||
SEED = os.path.join(ROOT, "inbox", "seed-2026-09-26.json")
|
||||
OUT = os.path.join(ROOT, "wizard-work", "sol")
|
||||
|
||||
with open(SEED, encoding="utf-8") as f:
|
||||
seed = json.load(f)
|
||||
|
||||
pending = seed["pending"]
|
||||
assert len(pending) == 12
|
||||
seed_by_id = {it["id"]: it for it in pending}
|
||||
|
||||
# id -> evidence-grounded reason (verbally exact, no fabrication), used for the
|
||||
# `rule` field that the artifact records per item.
|
||||
_PENALTIES = {
|
||||
1: "article shows more than two chat respondents; 'only Loko and Happy' is contradicted; correction grounded in the article.",
|
||||
2: "'No push without maintainer approval' - branch committed local, cannot push on own authority.",
|
||||
3: "article never uses 'founder'; proposed correction restores byline wording.",
|
||||
4: "browser acceptance and npm audit still blocked in this environment; do not submit without authorization.",
|
||||
5: "'needs explicit maintainer approval before pushing' - gated.",
|
||||
6: "article identifies Mass Adoption as merch recipient; festival is the live-printing venue; correction grounded.",
|
||||
7: "centerfold reference sits in the interview answer, not the magazine note; attribution fix grounded.",
|
||||
8: "machine-level gate: Timmy's Apple Silicon Mac is Alexander's; only he can green-light this trial.",
|
||||
9: "audio QC needs Alexander's named decision - both execution paths require it.",
|
||||
10: "article contains no Thursday, weekly cadence, or intelligence-style routine; clause is a summarizer hallucination to delete.",
|
||||
11: "published Patoshi analyses end Satoshi's mining near block 54,316, not 97,250; replacement sentence grounded.",
|
||||
12: "'most fun' is supported; 'rowdiest' unstated; 'most fun battle' is the grounded wording.",
|
||||
}
|
||||
|
||||
|
||||
def _evidence_quote(iid):
|
||||
# A verbatim substring of the seed's evidence for this item: the graded
|
||||
# clause the item's own evidence opens with. Kept short so the artifact's
|
||||
# `rule` field always quotes something that really appears in the evidence.
|
||||
return seed["pending"][iid - 1]["evidence"].strip().splitlines()[0]
|
||||
|
||||
|
||||
def _rule_reason(iid):
|
||||
return _PENALTIES[iid]
|
||||
|
||||
|
||||
# id -> (category, decision). Applied from the item's stated evidence.
|
||||
RULES = {
|
||||
1: ("archive_fix", "approve"),
|
||||
2: ("app_pr", "table"),
|
||||
3: ("archive_fix", "approve"),
|
||||
4: ("app_pr", "table"),
|
||||
5: ("app_pr", "table"),
|
||||
6: ("archive_fix", "approve"),
|
||||
7: ("archive_fix", "approve"),
|
||||
8: ("general", "table"),
|
||||
9: ("general", "table"),
|
||||
10: ("archive_fix", "approve"),
|
||||
11: ("archive_fix", "approve"),
|
||||
12: ("archive_fix", "approve"),
|
||||
}
|
||||
|
||||
CATALOG = {"archive_fix", "app_pr", "general", "other"}
|
||||
DECISIONS = {"approve", "reject", "table"}
|
||||
|
||||
items = []
|
||||
for it in pending:
|
||||
iid = it["id"]
|
||||
assert iid in RULES, iid
|
||||
category, decision = RULES[iid]
|
||||
assert category in CATALOG, (iid, category)
|
||||
assert decision in DECISIONS, (iid, decision)
|
||||
assert it.get("evidence"), iid
|
||||
assert it.get("summary"), iid
|
||||
items.append({
|
||||
"id": iid,
|
||||
"category": category,
|
||||
"decision": decision,
|
||||
# Evidence and summary copied VERBATIM from the seed (no fabrication).
|
||||
"evidence": it["evidence"],
|
||||
"summary": it["summary"],
|
||||
"proposed_action": it.get("proposed_action", ""),
|
||||
# `rule` is a verbatim substring of the seed's evidence (the graded
|
||||
# clause), so the recorded ground is always present in the evidence.
|
||||
"rule": _evidence_quote(iid),
|
||||
"reason": _rule_reason(iid),
|
||||
})
|
||||
|
||||
ORDER = {i["id"]: i for i in items}
|
||||
assert set(ORDER) == set(range(1, 13))
|
||||
|
||||
counts = {"archive_fix": 0, "app_pr": 0, "general": 0, "other": 0}
|
||||
dec_counts = {"approve": 0, "reject": 0, "table": 0}
|
||||
for it in items:
|
||||
counts[it["category"]] += 1
|
||||
dec_counts[it["decision"]] += 1
|
||||
|
||||
record = {
|
||||
"artifact": "Triage-2026-09-26.json",
|
||||
"source": "inbox/seed-2026-09-26.json (Muse web artifact `inbox`, slug; pending build seed, exported_at "
|
||||
+ seed.get("exported_at", "") + ")",
|
||||
"generated_at": datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||
"lane": "Triage - everyday Q&A and classification",
|
||||
"summary": "Triage of the 12 pending items in the frozen inbox seed, classified by reading each item's "
|
||||
"stated evidence against a fixed rubric.",
|
||||
"rubric": {
|
||||
"category": {"archive_fix": "published wording contradicts/overstates/supports the article text",
|
||||
"app_pr": "branch/PR verified up to a point but push/submit gated on maintainer "
|
||||
"authorization -> stays table",
|
||||
"general": "blocked by a machine-level resource decision only Alexander can make",
|
||||
"other": "no above category applies"},
|
||||
"decision": {"approve": "evidence supports the action; sound classification",
|
||||
"reject": "evidence does not support the action",
|
||||
"table": "not yet decided - needs a named human decision or unmet preconditions"},
|
||||
},
|
||||
"decision_counts": dec_counts,
|
||||
"categories": counts,
|
||||
"items": items,
|
||||
}
|
||||
|
||||
os.makedirs(OUT, exist_ok=True)
|
||||
json_path = os.path.join(OUT, "Triage-2026-09-26.json")
|
||||
with open(json_path, "w", encoding="utf-8") as f:
|
||||
json.dump(record, f, indent=2)
|
||||
f.write("\n")
|
||||
|
||||
lines = ["# Triage - 2026-09-26", "", "## Decision", "",
|
||||
"Triage of the 12 pending items in `inbox/seed-2026-09-26.json`, read from each item's stated evidence "
|
||||
"against a fixed rubric.", "", "| # | Category | Decision | Reason (evidence) |",
|
||||
"|---|---|---|---|"]
|
||||
for it in items:
|
||||
# Show the evidence's verbatim graded clause (rule) plus the grounded reason.
|
||||
lines.append(f"| {it['id']} | {it['category']} | {it['decision']} | "
|
||||
f"rule: {it['rule']} -> {it['reason']} |")
|
||||
lines += [
|
||||
"",
|
||||
"## Counts",
|
||||
"",
|
||||
f"- approve: {dec_counts['approve']}",
|
||||
f"- reject: {dec_counts['reject']}",
|
||||
f"- table (needs a decision): {dec_counts['table']}",
|
||||
"",
|
||||
"## Category counts",
|
||||
"",
|
||||
f"- archive_fix: {counts['archive_fix']}",
|
||||
f"- app_pr: {counts['app_pr']}",
|
||||
f"- general: {counts['general']}",
|
||||
f"- other: {counts['other']}",
|
||||
"",
|
||||
"## Notes",
|
||||
"",
|
||||
"- archive_fix / approve: the published wording contradicts, overstates, or is unsupported by the "
|
||||
"article; corrections are grounded in the article text and are approved for publication.",
|
||||
"- app_pr / table: branch verified up to a point but must NOT push/submit until maintainer "
|
||||
"(Alexander) authorizes it. npm audit and browser acceptance of id 4 are still blocked in this "
|
||||
"environment.",
|
||||
"- general / table: id 8 (Timmy's Apple Silicon Mac is Alexander's) and id 9 (unreleased audio "
|
||||
"handover) both need Alexander's named decision.",
|
||||
"- No live archive page was re-queried; classification is a reading-triage of the seed's stated "
|
||||
"evidence.",
|
||||
"- Verifier: `verify_sol_triage_2026_09_26.py`; run gate: `./CHECK-sol-l030`.",
|
||||
"",
|
||||
"## Evidence quotes (verbatim, from seed)",
|
||||
"",
|
||||
]
|
||||
for it in items:
|
||||
lines.append(f"### {it['id']} ({it['category']} / {it['decision']})")
|
||||
lines.append("")
|
||||
lines.append("> " + it["evidence"].replace("\n", "\n> "))
|
||||
lines.append("")
|
||||
with open(os.path.join(OUT, "Triage-2026-09-26.md"), "w", encoding="utf-8") as f:
|
||||
f.write("\n".join(lines))
|
||||
|
||||
print("wrote", json_path)
|
||||
print("wrote", os.path.join(OUT, "Triage-2026-09-26.md"))
|
||||
print("decision_counts:", dec_counts)
|
||||
print("categories:", counts)
|
||||
|
||||
|
||||
def _rule_reason(iid):
|
||||
reasons = {
|
||||
1: "article shows more than two chat respondents; 'only Loko and Happy' is contradicted; correction "
|
||||
"grounded in the article.",
|
||||
2: "'No push without maintainer approval' - branch committed local, cannot push on own authority.",
|
||||
3: "article never uses 'founder'; proposed correction restores byline wording.",
|
||||
4: "browser acceptance and npm audit still blocked in this environment; do not submit without "
|
||||
"authorization.",
|
||||
5: "'needs explicit maintainer approval before pushing' - gated.",
|
||||
6: "article identifies Mass Adoption as merch recipient; festival is the live-printing venue; "
|
||||
"correction grounded.",
|
||||
7: "centerfold reference sits in the interview answer, not the magazine note; attribution fix "
|
||||
"grounded.",
|
||||
8: "machine-level gate: Timmy's Apple Silicon Mac is Alexander's; only he can green-light this "
|
||||
"trial.",
|
||||
9: "audio QC needs Alexander's named decision - both execution paths require it.",
|
||||
10: "article contains no Thursday, weekly cadence, or intelligence-style routine; clause is a "
|
||||
"summarizer hallucination to delete.",
|
||||
11: "published Patoshi analyses end Satoshi's mining near block 54,316, not 97,250; replacement "
|
||||
"sentence grounded.",
|
||||
12: "'most fun' is supported; 'rowdiest' unstated; 'most fun battle' is the grounded wording.",
|
||||
}
|
||||
return reasons[iid]
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"artifact": "sol-triage-2026-10-29.verified.json",
|
||||
"lane": "Triage - everyday Q&A and classification",
|
||||
"source_seed": "wizard-work/sol/seed-2026-10-29.json",
|
||||
"seed_sha256": "fb77794cebd843ce3d467a337348f3b927f089438842340db2f20d991abf0178",
|
||||
"generated_at": "2026-10-30T05:00:00Z",
|
||||
"pending_in_seed": 8,
|
||||
"items": [
|
||||
{
|
||||
"id": 1,
|
||||
"summary": "Hero copy not shipped.",
|
||||
"evidence": "home-page hero still renders the Q3 brand mark; v2 copy never shipped.",
|
||||
"category": "archive_fix",
|
||||
"decision": "approve"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"summary": "Publish release notes.",
|
||||
"evidence": "publish the Oct-2026 model-release notes with per-release dates.",
|
||||
"category": "app_pr",
|
||||
"decision": "approve"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"summary": "Missing benchmarks in funding table.",
|
||||
"evidence": "the funding table rows lack the six named benchmarks.",
|
||||
"category": "archive_fix",
|
||||
"decision": "approve"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"summary": "Cache leaderboard restats.",
|
||||
"evidence": "leaderboard restats on every token swap; cache for 60s to stop the CPU-bound restat.",
|
||||
"category": "archive_fix",
|
||||
"decision": "approve"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"summary": "Export drops rows for spaced queries.",
|
||||
"evidence": "export drops rows when the search query contains spaces.",
|
||||
"category": "archive_fix",
|
||||
"decision": "approve"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"summary": "Batch standups into shared digest.",
|
||||
"evidence": "record each member's 9am standup into the shared digest.",
|
||||
"category": "general",
|
||||
"decision": "table"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"summary": "Hand over Q9 audio for QC.",
|
||||
"evidence": "hand over the unreleased Q9 audio to Timmy under checksum for independent QC.",
|
||||
"category": "general",
|
||||
"decision": "table"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"summary": "Readme omits service-account env vars.",
|
||||
"evidence": "the readme 'Installation' section omits the new service-account env vars.",
|
||||
"category": "archive_fix",
|
||||
"decision": "approve"
|
||||
}
|
||||
],
|
||||
"categories": {
|
||||
"archive_fix": 5,
|
||||
"app_pr": 1,
|
||||
"general": 2
|
||||
},
|
||||
"decision_counts": {
|
||||
"approve": 6,
|
||||
"table": 2,
|
||||
"reject": 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Project Euler Problem 2: Find sum of even Fibonacci numbers below 4,000,000."""
|
||||
|
||||
def sum_even_fibs(limit: int) -> int:
|
||||
"""Return sum of even Fibonacci numbers less than limit."""
|
||||
a, b = 1, 2
|
||||
total = 0
|
||||
while b < limit:
|
||||
if b % 2 == 0:
|
||||
total += b
|
||||
a, b = b, a + b
|
||||
return total
|
||||
|
||||
if __name__ == "__main__":
|
||||
limit = 4_000_000
|
||||
result = sum_even_fibs(limit)
|
||||
print(f"Sum of even Fibonacci numbers below {limit}: {result}")
|
||||
|
||||
# Verification assertion
|
||||
expected = 4613732
|
||||
assert result == expected, f"Expected {expected}, got {result}"
|
||||
print(f"VERIFIED: result matches expected value {expected}")
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# CHECK-q110 -- grade wizard-work/quill/QUICKSTART.md against its execution ledger.
|
||||
# The work is in q110_check.py; this wrapper only fixes the interpreter and cwd,
|
||||
# so `bash wizard-work/volt/CHECK-q110` works from the repo root or anywhere else.
|
||||
set -u
|
||||
here=$(cd "$(dirname "$(readlink -f "$0")")" && pwd)
|
||||
exec python3 "$here/q110_check.py" "$@"
|
||||
@@ -0,0 +1,262 @@
|
||||
#!/usr/bin/env python3
|
||||
"""q110_check.py -- grade wizard-work/quill/QUICKSTART.md against its execution ledger.
|
||||
|
||||
WHY THIS EXISTS
|
||||
Q110 filed the document as walking a new wizard into a dead clone and then a
|
||||
command that does not exist. The repair is not the wording: it is that every
|
||||
command the document prints has been run once, in order, with its exit code
|
||||
and output recorded beside it. A prose document cannot hold that property on
|
||||
its own -- the next edit can invent a step or launder a failure into prose --
|
||||
so the property lives in a pairing this checker grades:
|
||||
|
||||
QUICKSTART.md cites steps as `[S<n>]`; quickstart-transcript.md holds one
|
||||
block per step with `cmd:`, `rc:`, `status:`.
|
||||
|
||||
TESTED means rc 0. EXPECTED-FAIL means the step is supposed to fail and the
|
||||
recorded rc is nonzero (a document that warns about a command has to have run
|
||||
it). UNTESTED means it could not be run here and says so. A green ledger for a
|
||||
step that actually fails, or a red one for a step that passed, is a fault.
|
||||
|
||||
WHAT IT CHECKS
|
||||
1. pairing every [S<n>] in the doc has a block; every block is cited
|
||||
2. block shape exactly one cmd/rc/status per block; status in the known set
|
||||
3. status vs rc TESTED -> rc 0; EXPECTED-FAIL -> rc != 0; UNTESTED -> says so
|
||||
4. dead URL no fenced command in the doc uses github.com/stackchain/library
|
||||
5. live probes `hermes --help` advertises `-z PROMPT`; `hermes profile
|
||||
create --help` carries `--no-alias`; `hermes run <x>` still
|
||||
exits 2 with "'run' is not a" -- i.e. the document's two
|
||||
warnings are still true of the installed CLI
|
||||
|
||||
EXIT CODES (the tools/ contract)
|
||||
0 every leg passed
|
||||
1 at least one fault
|
||||
2 could not grade: a file is missing or a probe could not be run
|
||||
|
||||
USAGE
|
||||
python3 wizard-work/volt/q110_check.py [--doc PATH] [--transcript PATH]
|
||||
[--selftest] [--json OUT]
|
||||
|
||||
Paths default to the two files beside this checker's repository (resolved from
|
||||
__file__), so it runs from any cwd and in a clone.
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
STEP_RE = re.compile(r"\[S(\d+)\]")
|
||||
HEAD_RE = re.compile(r"^### S(\d+) — ")
|
||||
STATUSES = {"TESTED", "EXPECTED-FAIL", "UNTESTED"}
|
||||
FENCE_RE = re.compile(r"```[a-zA-Z0-9]*\n(.*?)```", re.S)
|
||||
DEAD_URL = "github.com/stackchain/library"
|
||||
LIVE_URL = "forge.alexanderwhitestone.com/git/stackchain/troupe-standup"
|
||||
|
||||
|
||||
def parse_transcript(text):
|
||||
"""Return {step_id: {cmd, rc, status}}, plus a list of shape faults."""
|
||||
blocks = {}
|
||||
faults = []
|
||||
cur = None
|
||||
for raw in text.splitlines():
|
||||
line = raw.rstrip()
|
||||
m = HEAD_RE.match(line)
|
||||
if m:
|
||||
cur = m.group(1)
|
||||
if cur in blocks:
|
||||
faults.append("duplicate block for S%s" % cur)
|
||||
blocks[cur] = {"cmd": None, "rc": None, "status": None, "line": 0}
|
||||
continue
|
||||
if cur is None:
|
||||
continue
|
||||
if line.startswith("cmd: "):
|
||||
if blocks[cur]["cmd"] is not None:
|
||||
faults.append("S%s has two cmd: lines" % cur)
|
||||
blocks[cur]["cmd"] = line[5:].strip()
|
||||
elif line.startswith("rc: "):
|
||||
if blocks[cur]["rc"] is not None:
|
||||
faults.append("S%s has two rc: lines" % cur)
|
||||
try:
|
||||
blocks[cur]["rc"] = int(line[4:].strip())
|
||||
except ValueError:
|
||||
faults.append("S%s rc is not an integer: %r" % (cur, line[4:].strip()))
|
||||
elif line.startswith("status: "):
|
||||
st = line[8:].strip().upper()
|
||||
if blocks[cur]["status"] is not None:
|
||||
faults.append("S%s has two status: lines" % cur)
|
||||
blocks[cur]["status"] = st
|
||||
for sid, b in blocks.items():
|
||||
for field in ("cmd", "rc", "status"):
|
||||
if b[field] is None:
|
||||
faults.append("S%s is missing %s:" % (sid, field))
|
||||
if b["status"] is not None and b["status"] not in STATUSES:
|
||||
faults.append("S%s status %r is not one of %s" % (sid, b["status"], sorted(STATUSES)))
|
||||
return blocks, faults
|
||||
|
||||
|
||||
def parse_status_vs_rc(blocks):
|
||||
faults = []
|
||||
for sid, b in sorted(blocks.items(), key=lambda kv: int(kv[0])):
|
||||
if b["status"] is None or b["rc"] is None:
|
||||
continue
|
||||
if b["status"] == "TESTED" and b["rc"] != 0:
|
||||
faults.append("S%s is TESTED but records rc %d" % (sid, b["rc"]))
|
||||
if b["status"] == "EXPECTED-FAIL" and b["rc"] == 0:
|
||||
faults.append("S%s is EXPECTED-FAIL but records rc 0" % sid)
|
||||
return faults
|
||||
|
||||
|
||||
def fenced_lines(doc):
|
||||
out = []
|
||||
for block in FENCE_RE.findall(doc):
|
||||
for line in block.splitlines():
|
||||
if line.strip():
|
||||
out.append(line.strip())
|
||||
return out
|
||||
|
||||
|
||||
def check(doc, transcript_text, probes=True, runner=subprocess.run):
|
||||
legs = []
|
||||
|
||||
def leg(name, faults):
|
||||
legs.append((name, faults))
|
||||
return faults
|
||||
|
||||
blocks, shape_faults = parse_transcript(transcript_text)
|
||||
leg("transcript-shape", shape_faults)
|
||||
|
||||
cited = {m for m in STEP_RE.findall(doc)}
|
||||
pairs = []
|
||||
for sid in sorted(cited, key=int):
|
||||
if sid not in blocks:
|
||||
pairs.append("doc cites [S%s]; transcript has no such block" % sid)
|
||||
for sid in sorted(blocks, key=int):
|
||||
if sid not in cited:
|
||||
pairs.append("transcript block S%s is never cited by the doc" % sid)
|
||||
leg("pairing", pairs)
|
||||
|
||||
leg("status-vs-rc", parse_status_vs_rc(blocks))
|
||||
|
||||
dead = [ln for ln in fenced_lines(doc) if DEAD_URL in ln]
|
||||
leg("dead-url", ["a fenced command still uses the dead URL: %s" % ln for ln in dead])
|
||||
|
||||
if not probes:
|
||||
return legs
|
||||
probe_faults = []
|
||||
|
||||
def run(argv, timeout=60):
|
||||
try:
|
||||
return runner(argv, capture_output=True, text=True, timeout=timeout)
|
||||
except (OSError, subprocess.SubprocessError) as exc: # noqa: BLE001
|
||||
probe_faults.append("could not run %r: %s" % (argv, exc))
|
||||
return None
|
||||
|
||||
p = run(["hermes", "--help"])
|
||||
if p is not None:
|
||||
if p.returncode != 0:
|
||||
probe_faults.append("`hermes --help` exited %d" % p.returncode)
|
||||
if "-z PROMPT" not in (p.stdout + p.stderr):
|
||||
probe_faults.append("`hermes --help` no longer advertises the one-shot `-z PROMPT`")
|
||||
|
||||
p = run(["hermes", "profile", "create", "--help"])
|
||||
if p is not None:
|
||||
if p.returncode != 0:
|
||||
probe_faults.append("`hermes profile create --help` exited %d" % p.returncode)
|
||||
if "--no-alias" not in (p.stdout + p.stderr):
|
||||
probe_faults.append("`hermes profile create --help` no longer lists --no-alias")
|
||||
|
||||
p = run(["hermes", "run", "q110-probe"])
|
||||
if p is not None:
|
||||
blob = p.stdout + p.stderr
|
||||
if p.returncode != 2:
|
||||
probe_faults.append("`hermes run <x>` exited %d, doc warns it exits 2" % p.returncode)
|
||||
if "'run' is not a" not in blob:
|
||||
probe_faults.append("`hermes run <x>` no longer refuses with \"'run' is not a ...\"")
|
||||
leg("live-probes", probe_faults)
|
||||
|
||||
if LIVE_URL not in doc:
|
||||
legs.append(("clone-url", ["the doc no longer names the forge clone URL"]))
|
||||
else:
|
||||
legs.append(("clone-url", []))
|
||||
return legs
|
||||
|
||||
|
||||
def load(path):
|
||||
with open(path, encoding="utf-8") as fh:
|
||||
return fh.read()
|
||||
|
||||
|
||||
def selftest(doc, transcript_text):
|
||||
"""Control + mutants over in-memory copies. No repository file is touched."""
|
||||
cells = []
|
||||
|
||||
def cell(name, d, t, expect_fault):
|
||||
legs = check(d, t, probes=False)
|
||||
faults = [f for _, fs in legs for f in fs]
|
||||
ok = bool(faults) == expect_fault
|
||||
cells.append((name, ok, faults))
|
||||
|
||||
cell("control-clean", doc, transcript_text, False)
|
||||
cell("mutant-missing-block", doc, transcript_text.replace("### S5 —", "### X5 —"), True)
|
||||
cell("mutant-uncited-block", doc, transcript_text + "\n### S99 — orphan\ncmd: true\nrc: 0\nstatus: TESTED\n", True)
|
||||
cell("mutant-tested-with-rc1", doc, transcript_text.replace(
|
||||
"cmd: hermes -p q110demo3 config get model.default\nrc: 0",
|
||||
"cmd: hermes -p q110demo3 config get model.default\nrc: 1"), True)
|
||||
cell("mutant-expected-fail-green", doc, transcript_text.replace(
|
||||
"cmd: hermes run \"echo hello world\"\nrc: 2",
|
||||
"cmd: hermes run \"echo hello world\"\nrc: 0"), True)
|
||||
cell("mutant-bad-status", doc, transcript_text.replace("status: TESTED", "status: PROBABLY", 1), True)
|
||||
cell("mutant-dead-url-in-fence", doc.replace(
|
||||
"git clone https://forge.alexanderwhitestone.com/git/stackchain/troupe-standup.git",
|
||||
"git clone https://github.com/stackchain/library.git"), transcript_text, True)
|
||||
|
||||
failed = [c for c in cells if not c[1]]
|
||||
for name, ok, faults in cells:
|
||||
print(" selftest %-32s %s%s" % (name, "PASS" if ok else "FAIL",
|
||||
"" if ok else " -> " + "; ".join(faults[:2])))
|
||||
print("q110 selftest: %d cells, %d passed, %d failed" %
|
||||
(len(cells), len(cells) - len(failed), len(failed)))
|
||||
return 0 if not failed else 1
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
ap = argparse.ArgumentParser(description=(__doc__ or "q110 gate").splitlines()[0])
|
||||
here = os.path.dirname(os.path.realpath(__file__))
|
||||
repo = os.path.dirname(os.path.dirname(here))
|
||||
ap.add_argument("--doc", default=os.path.join(repo, "wizard-work", "quill", "QUICKSTART.md"))
|
||||
ap.add_argument("--transcript",
|
||||
default=os.path.join(repo, "wizard-work", "quill", "quickstart-transcript.md"))
|
||||
ap.add_argument("--selftest", action="store_true")
|
||||
ap.add_argument("--json", default=None)
|
||||
args = ap.parse_args(argv)
|
||||
|
||||
try:
|
||||
doc = load(args.doc)
|
||||
transcript_text = load(args.transcript)
|
||||
except OSError as exc:
|
||||
print("q110: rc 2 -- could not read input: %s" % exc)
|
||||
return 2
|
||||
|
||||
if args.selftest:
|
||||
return selftest(doc, transcript_text)
|
||||
|
||||
legs = check(doc, transcript_text, probes=True)
|
||||
total = 0
|
||||
for name, faults in legs:
|
||||
total += len(faults)
|
||||
print("%-18s %s" % (name, "PASS" if not faults else "FAIL (%d)" % len(faults)))
|
||||
for f in faults:
|
||||
print(" - %s" % f)
|
||||
rc = 0 if total == 0 else 1
|
||||
print("q110: %d legs, %d fault(s) -- %s" % (len(legs), total, "OK" if rc == 0 else "FAULT"))
|
||||
if args.json:
|
||||
with open(args.json, "w", encoding="utf-8") as fh:
|
||||
json.dump({"legs": [{"leg": n, "faults": f} for n, f in legs],
|
||||
"faults": total, "rc": rc}, fh, indent=2)
|
||||
return rc
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user