diff --git a/docs/evals/v5.15.0/CREATOR_VALIDATION.md b/docs/evals/v5.15.0/CREATOR_VALIDATION.md new file mode 100644 index 0000000..73625f7 --- /dev/null +++ b/docs/evals/v5.15.0/CREATOR_VALIDATION.md @@ -0,0 +1,188 @@ +# v5.15.0 — Gate 10 creator validation (pre-publish) + +**Date:** 2026-09-25 +**Artifact:** `dist/nodus_lang-5.15.0-py3-none-any.whl`, built from the tagged +tree (`v5.15.0` → `d3e9c07`) +**Verdict:** **PASS.** Both halves green, the first only after a real failure was +fixed. Cleared to publish. + +Gate 10 asks *"what can I make fail?"* against a local wheel, before anything +immutable exists. Two halves, and the first is not optional: 5.0.3 shipped with +32 green probes and broke `nodus-sdk` at construction, because probes validate +nodus-lang against itself and nothing in them constructs a dependent. + +This cycle is the clearest demonstration yet of why 10a runs before the upload, +and of why its verdict is not a formality — it went red twice for two different +reasons, and neither was a nodus-lang regression. + +--- + +## 10a — dependent suites, before the upload + +``` +PYTHONPATH="…/src;…" python -m tools.check_dependent_suites +``` + +Run with nothing else going. No suite, gate or server was running locally; the +release PR's CI had already finished on a remote runner. + +### First run: exit 2 before it started — a checkout that did not resolve + +`nodus-a2a-wire` is registered at `C:\codev\a2a-wire-pub` and that directory no +longer exists; the repo had been moved to `C:\dev\a2a-wire-pub`. A missing +checkout is **exit 2**, which is not a pass — *an unrun suite covers nothing*. + +Verified it was the right repo before repointing the registry rather than +assuming a like-named directory: correct remote +(`Masterplanner25/nodus-a2a-wire`), and `10746ce` at the base of its 17-commit +history, exactly as `CLAUDE.md` records. Registry path corrected, note extended +with when and why the move was noticed. + +**That entry is a canary, not a component.** Its nodus-lang link is a *dev +extra* — published metadata is `nodus-lang>=4.0.0; extra == "dev"` and its +runtime `dependencies` list is empty. It is registered anyway because Gate 10a +runs *suites*, and one of its tests imports nodus-lang under `PYTHONPATH=src`. +Do not remove it for having empty runtime deps. + +### Second run: one NEW failure — and it was not ours + +| companion | verdict | detail | +|---|---|---| +| nodus-mcp | **FAIL** | 2 failed, 363 passed in 41.16s | +| nodus-mcp-server | PASS | 27 passed, 2 warnings in 2.15s | +| nodus-extension | PASS | 126 passed in 24.19s | +| nodus-sdk | PASS | 111 passed, 1 warning in 7.45s | +| nodus-native-memory-engine | PASS | 76 passed in 1.09s | +| nodus-jupyter | PASS | 32 passed in 1.80s | +| nodus-workflow-ai | PASS | 28 passed in 0.51s | +| nodus-a2a-wire | PASS | 188 passed in 13.65s | + +The gate classified them correctly, which is what #528 added it for: + +``` +NEW tests/test_invariants.py::test_version_is_not_dev +known tests/test_phase_m.py::test_m2_bearer_wrong_returns_401 (recorded flake) +``` + +**The NEW one was a real, shipped defect in nodus-mcp with nothing to do with +this release.** `test_version_is_not_dev` asserts the package's two version +sources agree, and they did not: + +``` +AssertionError: version mismatch: __init__.py has '0.1.3', pyproject.toml has '0.1.4' +``` + +`git log -S` pinned it to `3966a56` — the mcp SDK 2.x port, cut as 0.1.4 earlier +in this same session — which bumped `pyproject.toml` and left +`src/nodus_mcp/__init__.py` on the 0.1.3 release value. PyPI has 0.1.4, so **the +published 0.1.4 reports the wrong number**: `nodus-mcp --version` and both serve +banners print 0.1.3. PyPI is immutable, so 0.1.4 keeps it; the repo is correct +now (`51cb91d`) and a future release will be consistent. + +Established as independent of nodus-lang rather than assumed — the test reads +only that package's own two files. The gate refused to publish anyway, and that +is the right rule: it cannot know that from the outside, and 5.0.3 shipped a +broken `nodus-sdk` by not asking. + +The second failure is the recorded port-conflict flake. Per the standard, a +recorded flake changes the advice and never the verdict, so it was re-run +serially: **1 passed in 3.06s**. + +### Third run: clean + +| companion | verdict | detail | +|---|---|---| +| nodus-mcp | PASS | **365** passed, 2 warnings in 37.97s | +| nodus-mcp-server | PASS | 27 passed, 2 warnings in 1.99s | +| nodus-extension | PASS | 126 passed in 22.67s | +| nodus-sdk | PASS | 111 passed, 1 warning in 5.51s | +| nodus-native-memory-engine | PASS | 76 passed in 0.26s | +| nodus-jupyter | PASS | 32 passed in 1.23s | +| nodus-workflow-ai | PASS | 28 passed in 0.45s | +| nodus-a2a-wire | PASS | 188 passed in 13.63s | + +**All 8 dependent suites pass — exit code 0.** 953 tests. nodus-mcp is 365 +rather than 363 because the two previously-failing tests now pass; the flake did +not recur on the clean run either. + +`nodus-sdk` is 111 rather than last cycle's 99: its 0.1.3 (2026-09-20) added the +twelve guest-driven bridge tests that exist because none of its 99 tests had ever +run a `.nd` program through a bridge. + +--- + +## 10b — adversarial validation against the wheel + +```powershell +cd $env:TEMP\...\g10b # outside the repo +venv-val\Scripts\python.exe tests\eval\release_claims_probe.py ` + --repo "C:\dev\Coding Language" --require-installed +``` + +Clean venv, the built wheel installed **with the `[http]` extra** — without it +the #855 trust-store probe refuses rather than passing vacuously, which is why +CI's `probes` job installs it too. + +The header is the first thing printed, and it is the check that matters: + +``` +package …\scratchpad\venv-val\Lib\site-packages\nodus +version 5.15.0 +import …\scratchpad\venv-val\Lib\site-packages\nodus\__init__.py +repo C:\dev\Coding Language +``` + +**`site-packages`, not `src`.** The repo-root `nodus.py` shim inserts `src/` on +`sys.path` and re-execs from there, so any process whose CWD is the checkout +validates the *source tree* no matter what is installed — no `PYTHONPATH`, +nothing in `pip list`. That is how 5.0.3 shipped past 32 green probes, and it +recurred at 5.5.0 and 5.6.0. `--require-installed` exits **2** rather than +relying on anyone reading the header. + +**136/136 probes passed.** + +### Probes written before the tag + +Six new ones this cycle, 130 → 136. They are the only check that reads the +release's *claims* rather than its code, which is why they are written before +step 6 and not after: run after the tag, a correction to the README would be +impossible, and `readme = "README.md"` makes it the permanent PyPI page. + +| probe | what it reads | +|---|---| +| a resumed step reaches the host's tool handler | #868, the reported symptom end to end | +| a parked run older than the scan bound is still findable | #869, across `list_runs`, the sweep and `list_all_runs` | +| a resume inherits the caller's bounds | #873, all four bounds plus the step remainder | +| the terminal record cap can see the records it deletes | #875, a cap of 2 leaves 2 files | +| README names the 5.15.0 surface | the prose this release ships | +| no stale '5.14.0 is current' claim survives | the seven documents that carry a currency claim | + +**The count moving is the wiring check.** `main()` invokes probes from an +explicit list, so a decorated function nobody calls is dead code that reads as +live — 129/129 stayed 129/129 when a probe was added earlier this session, and +only the unchanged count showed it. 130 → 136 here. + +Three of the behavioural ones were falsified against neutered fixes, and each +failed with the symptom it exists to catch: + +``` +FAIL | a resumed step reaches the host's tool handler | returned 'error' +FAIL | a parked run older than the scan bound is findable | aged out of list_runs +FAIL | a resume inherits the caller's bounds | the deadline was not inherited +``` + +--- + +## What this gate did not cover + +**The full local suite is not this cycle's evidence.** The box was at 0.2–0.4 GB +free of 7.7 GB throughout — the thrashing condition `CLAUDE.md` documents, where +process creation stalls on hard page faults and every timeout-shaped failure is +untrustworthy. A local run was started and stopped rather than reported. + +CI on a clean runner is the arbiter, and it ran both `unittest discover` and +`pytest` on the release PR (#881): **all six checks green**, `test` at 12m59s and +13m56s on the two runs. + +Stage 5 (against the published package) and Stage 6 (companions) are still owed +and are recorded separately. diff --git a/docs/evals/v5.15.0/POSTPUBLISH_EVAL.md b/docs/evals/v5.15.0/POSTPUBLISH_EVAL.md new file mode 100644 index 0000000..f82198e --- /dev/null +++ b/docs/evals/v5.15.0/POSTPUBLISH_EVAL.md @@ -0,0 +1,69 @@ +# v5.15.0 — Stage 5 post-publish eval + +**Date:** 2026-09-25 +**Artifact:** `nodus-lang==5.15.0` installed from **PyPI** into a fresh venv +**Verdict:** **PASS — 8/8.** + +Stage 5 asks a different question from Gate 10: not *"what can I make fail?"* +against a local wheel, but *"does this work as a new user would expect?"* against +the published package. It is the stage that caught #662 at 5.7.0 — by using two +new features in one program, where neither was broken alone. + +--- + +## Install + +``` +pip install nodus-lang==5.15.0 +``` + +Resolved from `site-packages`, not a checkout: + +``` +installed from PyPI: 5.15.0 +resolved : …\venv-pub\Lib\site-packages\nodus\__init__.py +``` + +**Index lag this cycle: none.** The install succeeded on the first attempt. That +is worth recording because it varies — 5.13.0's took nine minutes, and after +5.6.0's upload the JSON API reported *zero files* for the version that had just +landed. Only `pip install ==` is authoritative; the JSON API and +the simple index both lag, and `Cache-Control: no-cache` does not prevent it. + +--- + +## Checks + +Each exercises something this release claims, through the surface a user would +touch rather than the internals the tests reach for. + +| # | Check | Result | +|---|---|---| +| 1 | the CLI reports 5.15.0 | `Nodus 5.15.0` | +| 2 | a resumed step reaches a host tool (#868) | handler called once; the step got a record | +| 3 | a 40-day parked run is still listed (#869) | listed and sweepable at 40 days | +| 4 | reject-and-revise works (#870) | replays with the feedback, re-parks, `publish` does not fire | +| 5 | rehydrated data keeps its key order (#871) | `{"web": 1, "code": 2, "data": 3}` | +| 6 | a resume inherits the caller's bounds (#873) | all four bounds carried; steps are the remainder | +| 7 | the terminal cap holds (#875) | a cap of 2 leaves 2 files, aged records included | +| 8 | a plain script still runs (the control) | `hello from 2` | + +**8/8 passed.** + +Check 8 is the control and is not decoration: every other check exercises the +park-and-resume boundary, and without it the set would pass on a build where +ordinary `nodus run` was broken. Checks 4 and 6 each assert a *negative* as well +as a positive — that `publish` does **not** fire on a rejection, and that the +child's step budget is the remainder rather than a fresh allowance — because +both are the difference between the fix and a plausible wrong version of it. + +--- + +## What this stage did not do + +Stage 5 did not construct a dependent, which is Gate 10a's job and was done +before the upload (8 suites, 953 tests). It did not re-run the full nodus-lang +suite; CI did that on the release PR, on a clean runner, in both `unittest` and +`pytest` form. + +No new issues were filed from this stage. diff --git a/docs/evals/v5.15.0/STAGE6_DOWNSTREAM_SWEEP.md b/docs/evals/v5.15.0/STAGE6_DOWNSTREAM_SWEEP.md new file mode 100644 index 0000000..01b9434 --- /dev/null +++ b/docs/evals/v5.15.0/STAGE6_DOWNSTREAM_SWEEP.md @@ -0,0 +1,172 @@ +# v5.15.0 — Stage 6 downstream republish sweep + +**Date:** 2026-09-25 +**Verdict:** **Ranges and drift clean. Two non-PyPI consumers still owed.** + +Four questions, three of them tooled. Stage 6 exists because the first three are +invisible to everything earlier in the sequence: Gate 10 validates nodus-lang +against itself and against companion *suites*, neither of which can see a +published range that no longer resolves or a wiki page nobody has read since +v4.1.1. + +--- + +## 1. Do published ranges still admit the new version? + +``` +python -m tools.check_downstream_constraints +``` + +| companion | published | nodus-lang range | verdict | +|---|---|---|---| +| nodus-a2a-wire | 0.1.0 | `>=4.0.0` | ok | +| nodus-extension | 0.1.2 | `>=4.0.0` | ok | +| nodus-jupyter | 0.1.0 | `>=4.0.0` | ok | +| nodus-mcp | 0.1.4 | `>=4.0.0` | ok | +| nodus-mcp-server | 0.1.14 | `>=4.0.5` | ok | +| nodus-native-memory-engine | 0.1.1 | `>=4.0.0` | ok | +| nodus-sdk | 0.1.3 | `>=4.0.0` | ok | +| nodus-workflow-ai | 0.1.0 | `>=5.8.0` | ok | + +**All 8 admit 5.15.0.** Resolved with `packaging` against *published* metadata, +never read by eye: `>=4.0.0,<5.0.0` reads as "admits 4.x", which is what the eye +checks for, and the clause that forbids the new version sits at the far end of +the string. Five of six companions once published that cap, which made 5.0.0 +`ResolutionImpossible` for anyone with the ecosystem installed — found by the +aindy-runtime team, not by us (#445). + +## 2. Has any companion drifted from what it published? + +``` +python -m tools.check_publish_drift +``` + +**First run: one SKIP and one DRIFT.** + +``` +nodus-a2a-wire SKIP no checkout at C:\codev\a2a-wire-pub +nodus-mcp DRIFT differs: src/nodus_mcp/__init__.py +``` + +### The SKIP was a second copy of a path I had already fixed + +`nodus-a2a-wire` moved from `C:\codev` to `C:\dev`. Gate 10a had already exited +**2** on the stale path in `tools/nodus_lang_dependents.json`, and that was +corrected before the publish — but `check_publish_drift.py` carries its **own** +hardcoded path table, so the same move broke it twice and fixing one left the +other skipping. + +That is the recurring shape at the tooling layer. #810 unified the *membership* +lists — which companions declare a nodus-lang dependency — and left the +**paths** duplicated, so a checkout that moves still has to be corrected in two +places. Both are now correct and the comment at the second site says so rather +than leaving the next reader to rediscover it. + +A skip is not a pass — *a companion that could not be checked is not a companion +that passed* — which is why the tool exits 2 on one. + +**Second run: `nodus-a2a-wire` ok, 9 files identical to 0.1.0.** Every other +companion identical to its published release. + +### The DRIFT is intended, and is the fix for a defect the gate found + +`src/nodus_mcp/__init__.py` differs from published 0.1.4 because Gate 10a caught +nodus-mcp's two version sources disagreeing — `__init__.py` at `0.1.3`, +`pyproject.toml` at `0.1.4` — and it was corrected (`51cb91d`). + +So **the published nodus-mcp 0.1.4 reports the wrong version**: `nodus-mcp +--version` and both serve banners print 0.1.3. PyPI is immutable, so 0.1.4 keeps +it. The drift is the correction sitting unpublished. + +**Owed: a nodus-mcp 0.1.5**, or an explicit decision to leave 0.1.4's banner +wrong until its next release for another reason. Not taken unilaterally here — +it is a second package's publish, and irreversible. + +## 3. Non-PyPI consumers left stale + +``` +python -m tools.nodus_gate.cli --consumers +``` + +| consumer | tracks | state | +|---|---|---| +| nodus-vscode (0.1.5) | `keywords` | **in step** — this release adds no keyword | +| nodus-run-action (**v1.0.16**) | `nodus_version` | **republished** | +| nodus-wiki (**b9550c2**) | `nodus_version` | **republished** | + +Both stale consumers track `nodus_version`, so they go stale at *every* bump by +construction. That is the design and not a nuisance: a wiki nobody has looked at +since the last release is exactly the thing to be told about. The wiki documented +v4.1.1 for twelve minors — across the 5.0.0 major, whose deny-by-default change +breaks embedders — with 1 of its 26 pages mentioning 5.x at all. + +`nodus-vscode` is genuinely in step: it tracks the keyword set, and 5.15.0 adds +no keyword. Its fingerprint is unchanged, so no VSIX is owed. + +**Both are republished, and the flags were cleared only afterwards** — +`fingerprint` and `published` move in this same commit, because a flag cleared +before the work is done is worse than no flag. `--consumers --strict` now reports +**3/3 in step**. + +### nodus-run-action v1.0.16 + +The two pinned `version:` examples moved to 5.15.0 — the pin is what a new user +copies, so a stale one hands them an old runtime. + +It also surfaced something the fingerprint does not track: **the floating `v1` +tag had not moved since the 5.9.0 cycle**, six releases, while the README tells +everyone to use `@v1`. Checked before moving it rather than assumed — +`git diff v1 HEAD` touches `README.md` only and `action.yml` is byte-identical, +so no consumer's behaviour changes and what `@v1` was shipping was a README +pinning 5.9.0. Moved to the new commit. + +### nodus-wiki b9550c2 + +Four currency banners, plus two the version fingerprint caught only indirectly: + +- **`_Sidebar.md` said `## Nodus v5.12`** — stale by three releases, and + invisible to a grep for the *current* version, which is exactly why the gate + tracks a fingerprint rather than scanning for a string. +- **`Security.md`'s supported-versions table named v5.13.x as latest** — stale by + two. On a security page that is the kind of staleness that actively misinforms. + +Content, per the convention that each release's wiki commit carries the thing a +production reader needs: a Security paragraph on #873 (a resume inheriting no +bounds) and #868 (the cross-tenant agent-registry leak through module +functions), and the **reject-and-revise recipe** on the Workflows page, which had +documented `resume_workflow(id, "checkpoint")` as though #482 had never refused +the payload form. + +**The two `Since v5.14.0 …` sentences on Security were deliberately left alone.** +They are *as of* claims — they say when something arrived and stay true — and +bumping them would make the page lie about which release introduced the serve +budget. Same distinction `tools/version_claims.json` encodes upstream. + +`Embedding-API.md` was checked against the real constructor rather than trusted: +**27 documented, 27 in the signature**, all three capability flags present. No +change needed. + +Every claim and the code example on the Workflows page were run against the +**published** 5.15.0 before the push. That wiki has no PR and no CI — a push goes +straight to the reader — so nothing else would have checked them. + +## 4. Work left behind in a checkout + +`git status` across the registered checkouts: clean, except `nodus-mcp`, whose +one-line version fix is committed and pushed (`51cb91d`) and awaits the release +decision above. + +--- + +## Summary + +| Question | Answer | +|---|---| +| ranges admit 5.15.0 | **8/8 yes** | +| companions drifted | **1 — nodus-mcp, intended, needs 0.1.5** | +| non-PyPI consumers stale | **0 — both republished, 3/3 in step** | +| work left in a checkout | none uncommitted | + +Two tooling fixes landed as part of this sweep: the `nodus-a2a-wire` path in +both registries. Neither is a nodus-lang defect; both would have silently +degraded the next release's gates. diff --git a/docs/governance/ECOSYSTEM_READINESS_ASSESSMENT.md b/docs/governance/ECOSYSTEM_READINESS_ASSESSMENT.md index 95ff9c2..19832f5 100644 --- a/docs/governance/ECOSYSTEM_READINESS_ASSESSMENT.md +++ b/docs/governance/ECOSYSTEM_READINESS_ASSESSMENT.md @@ -213,4 +213,4 @@ language features rather than optional library wiring. - `docs/governance/ECOSYSTEM_MATURITY_RUBRIC.md` — the rubric used here - `docs/history/ECOSYSTEM_90_DAY_CHECKLIST.md` — what to complete before production - `docs/governance/LIBRARY_ECOSYSTEM.md` — ecosystem architecture -- `docs/evals/v5.14.0/CREATOR_VALIDATION.md` — most recent Gate 10 results (v5.14.0 cycle) +- `docs/evals/v5.15.0/CREATOR_VALIDATION.md` — most recent Gate 10 results (v5.15.0 cycle) diff --git a/tools/check_publish_drift.py b/tools/check_publish_drift.py index 0e98be1..8e74c4a 100644 --- a/tools/check_publish_drift.py +++ b/tools/check_publish_drift.py @@ -57,7 +57,13 @@ # #477: published 2026-08-26. Module is `nodus_a2a_wire`, deliberately NOT # `nodus_a2a` — the coordinator above ships that one, and both distributions # writing it clobbered each other. - "nodus-a2a-wire": (r"C:\codev\a2a-wire-pub", "src/nodus_a2a_wire"), + # Moved from `C:\codev` to `C:\dev` on 2026-09-25. This path is a SECOND + # copy of a question `tools/nodus_lang_dependents.json` also answers, and the + # two drifted the moment the directory moved: Gate 10a exited 2 on the stale + # path there and was fixed, and this sweep still skipped. #810 unified the + # *membership* lists and left the paths duplicated -- so a checkout that + # moves still has to be corrected twice. + "nodus-a2a-wire": (r"C:\dev\a2a-wire-pub", "src/nodus_a2a_wire"), "nodus-flow": (r"C:\dev\nodus-workflow", "nodus_flow"), # #93: published 2026-08-30, the first companion whose floor required an # unreleased nodus-lang. Added here in the publishing commit -- the diff --git a/tools/consumers.json b/tools/consumers.json index 748c871..8fe54a1 100644 --- a/tools/consumers.json +++ b/tools/consumers.json @@ -30,9 +30,9 @@ "name": "nodus-run-action", "repo": "Masterplanner25/nodus-run-action", "kind": "GitHub Action (not packaged)", - "published": "v1.0.15", + "published": "v1.0.16", "tracks": "nodus_version", - "fingerprint": "5.14.0", + "fingerprint": "5.15.0", "why": "Its README documents a pinned `version:` for reproducible CI. The pin is the version new users copy, so it going stale hands them an old runtime.", "republish": "Update the pinned `version:` in README.md examples, then tag the action." }, @@ -40,9 +40,9 @@ "name": "nodus-wiki", "repo": "Masterplanner25/Nodus.wiki", "kind": "GitHub wiki (git repo; no pull requests, no CI)", - "published": "69300aa", + "published": "b9550c2", "tracks": "nodus_version", - "fingerprint": "5.14.0", + "fingerprint": "5.15.0", "why": "A prominent search result and the first Nodus documentation many people meet, and nothing checked it. It documented v4.1.1 for twelve minors -- across the 5.0.0 major, whose deny-by-default change breaks embedders -- with 1 of its 26 pages mentioning 5.x at all. Its Embedding-API page listed 7 of the constructor's 27 parameters, omitting all three capability flags, and its Security page named v4.0.x as the latest supported release. A wiki has no PR and no CI, so it is the one surface in this project where nothing could fail.", "republish": "Pull the wiki checkout (remote Masterplanner25/Nodus.wiki, branch master; local clone under 'C:/dev/Nodus Wiki/nodus-wiki'). Correct the version banners on Home, Getting-Started, Roadmap, _Footer, _Sidebar and the two agent-skill pages; check Security.md's supported-versions table and Embedding-API.md against the real constructor signature. Push to master -- it goes live immediately, with nothing between you and the reader. Update `fingerprint` and `published` here in the same commit." } diff --git a/tools/nodus_lang_dependents.json b/tools/nodus_lang_dependents.json index 5cb61ab..1569863 100644 --- a/tools/nodus_lang_dependents.json +++ b/tools/nodus_lang_dependents.json @@ -56,12 +56,11 @@ "note": "#93. Declares nodus-lang>=5.8.0 and imports nothing from it -- it emits Nodus source. Missing from Gate 10a until #810; its suite was run by hand at the 5.12.0 cut and passed." }, "nodus-a2a-wire": { - "path": "C:\\codev\\a2a-wire-pub", + "path": "C:\\dev\\a2a-wire-pub", "published": true, - "note": "#477. Missing from BOTH registries until #810. The checkout is a2a-wire-pub; the worktree once named nodus-a2a-wire was the coordinator's old history and was removed 2026-09-07. IMPORTANT: its nodus-lang link is a DEV EXTRA, not a runtime dependency -- published metadata is 'nodus-lang>=4.0.0; extra == \"dev\"' and its `dependencies` list is empty, because the only import is one test that skips without it. Do not remove this entry on the grounds that the runtime deps are empty: Gate 10a runs suites, that suite imports nodus-lang under PYTHONPATH=src, and a nodus-lang change can turn it red. It is a canary, not a component." + "note": "#477. Missing from BOTH registries until #810. The checkout is a2a-wire-pub, moved from C:\\codev to C:\\dev on 2026-09-25 -- Gate 10a exits 2 on a path that does not resolve, which is how the move was noticed; the worktree once named nodus-a2a-wire was the coordinator's old history and was removed 2026-09-07. IMPORTANT: its nodus-lang link is a DEV EXTRA, not a runtime dependency -- published metadata is 'nodus-lang>=4.0.0; extra == \"dev\"' and its `dependencies` list is empty, because the only import is one test that skips without it. Do not remove this entry on the grounds that the runtime deps are empty: Gate 10a runs suites, that suite imports nodus-lang under PYTHONPATH=src, and a nodus-lang change can turn it red. It is a canary, not a component." } }, - "_ignored_comment": [ "Checkouts beside the registered ones that declare nodus-lang and are NOT", "first-party companions of this repo. The sweep in nodus_lang_dependents.py",