πŸ”‡ Two silent failures found after a green release

Post-release verification of v10.0.0-alpha.23 passed on every axis that had a signal. These two had no signal at all β€” that is what made them worth chasing.
defect 1 Β· PROVEN + FIXED defect 2 Β· HYPOTHESIS root cause found in a 276 MB binary fix size: 1 character class

TL;DR

Defect 1 (proven, fixed here): the three dynamic workflows OrchestKit ships through the plugin workflows/ directory were named .mjs. Claude Code's plugin workflow scanner accepts only .js and discards everything else by returning null β€” no warning, no log, no telemetry. The files shipped, installed, and executed fine by explicit path, but Workflow({name:"ork:skill-fitness"}) answered "not found", because as far as the registry was concerned the workflow never existed.

Defect 2 (hypothesis, fixed separately): the push-gating security suite has a helper that rewrites an empty payload to {}. A transient jq failure therefore turns a deny assertion into a silent abstain β€” a security test that fails open and reports 13/14 instead of crashing.

Both are the same shape: a failure path that produces a plausible-looking success instead of an error.

🧩 Defect 1 β€” the technical mechanism

Claude Code has two loaders that scan a directory for workflow scripts. They are nearly identical. The 24-byte difference between them is the entire bug.

❌ PLUGIN scanner (Xvp) β€” reads plugins/ork/workflows/

if(!(l.isFile()||l.isSymbolicLink()))
    return null;
if(!l.name.endsWith(".js"))
    return null;        // ← silent drop
return Zvp(join(e,l.name), ...)

No near-miss branch. No warning. .mjs ceases to exist.

βœ… USER/PROJECT scanner (nEp) β€” the sibling

if(!a.name.endsWith(".js")){
  if(/\.(mjs|cjs|ts)$/.test(a.name))
      r.nearMissExt++;  // ← counted!
  return null
}

Same mistake, tracked and reported as near_miss_ext in workflow_discover telemetry.

Where our three files fell out

πŸ”¬ How the conclusion was reached (and why the byte offsets matter)

The claim "the plugin loader filters on .js" is only worth anything if you can show which loader is which. The evidence is positional: two of the four endsWith(".js") sites sit 24 bytes before a near-miss regex, and two do not.

Byte offsetWhat is thereNear-miss branch?Which loader
264075910endsWith(".js")noneXvp β€” plugin dir scanner
264077420a.endsWith(".js")noneplugin custom-path branch
264078444endsWith(".js")yes, at 264078468nEp β€” user/project
264079380endsWith(".js")yes, at 264079404UDb β€” userConfigDir

Corroborating strings confirmed present in the same binary by direct probe: nearMissExt, near_miss_ext, workflow_discover, Total plugin workflows loaded.

Then it was proven empirically, not left as decompilation. One shipped skill-fitness.mjs in the installed alpha.23 cache was copied to skill-fitness.js and the plugins reloaded. The name ork:skill-fitness appeared in the skill registry and Workflow({name:"ork:skill-fitness"}) executed. Sixty seconds earlier the identical call returned "not found. Available: deep-research, code-review". Nothing else changed.

πŸ”‡ Why it stayed invisible for a whole release

Every check we ran was structurally incapable of catching it, and each one produced a green result that felt like evidence:

What we verifiedResultWhy it could not have caught this
Files present in the installed cacheβœ… all 3Presence is not registration. The loader reads the directory and discards.
plugin.json has "workflows"βœ… correctField shape was never the problem.
Manifest paths + meta.nameβœ… correctmeta is parsed after the extension filter, so it was never reached.
Workflow executes from the cacheβœ… ran, spawned an agentRan via scriptPath β€” a different loader with no extension filter.
CI: build, manifests, skills, driftβœ… greenNo gate knew plugin workflows existed as a component type.
The lesson worth keeping: absence of an error is not evidence of loading. Every green check above was true and none of them tested the claim that was actually made ("these surface as /ork:<name>"). The only test that could settle it was calling the thing by name.

πŸ§ͺ Defect 2 β€” a security test that fails open

The push-gating suite reported 19 | Passed: 18 | Failed: 1, then 19/19 on an immediate rerun of the identical tree. Standalone the test passes 14/14. There is no inter-test race: the runner is serial and each test gets a private temp dir. The mechanism is a degradation path inside the shared helper.

That chain produces exactly the observed signature: one deny assertion fails, every abstain assertion still passes, no crash, 13/14. Three things make it worse:

βš–οΈ Confidence β€” stated honestly, because they are not equal

Defect 1 β€” PROVEN

  • Loader code re-extracted from the binary independently of the agent that first reported it
  • Byte-offset adjacency distinguishes the two scanners
  • Live reproduction: rename β†’ reload β†’ resolves
  • Fixed in this PR

Defect 2 β€” UNREPRODUCED HYPOTHESIS

  • 250 direct hook probes (100 idle, 150 under 32-way load) β†’ 0 mismatches
  • The empty-payload β†’ abstain step is verified; the transient jq failure that would trigger it is not
  • Cannot name which of the five assertions failed β€” the log was truncated
  • Fixed anyway; see why below
Why fix an unproven hypothesis? Because all four changes are correct under both branches of the uncertainty. If the jq path is real, the fail-loud change eliminates the flake. If it is not, the un-silenced warning and the un-truncated log make the next occurrence diagnosable in one run instead of another multi-hour hunt. There is no version of the truth where these are the wrong edits β€” which is exactly what makes them safe to ship without a reproduction.

πŸ”§ The fixes

#ChangeFile
1Rename the three workflow scripts .mjs β†’ .jssrc/skills/{audit-full,bare-eval,cover}/workflows/*.js
2Update the manifest's workflows[] pathsmanifests/ork.json
3Document the trap: plugin workflows MUST be .js; absence of an error is not evidence of loadingchain-patterns/references/dynamic-workflow-patterns.md
4Teach the docs-drift gate that workflows exist β€” it derived ground truth from skills + agents only, so documenting a real /ork:skill-fitness was reported as a dead reference. Names now come from each script's meta.name.tests/skills/structure/test-docs-site-drift.mjs
5(separate PR) Security harness: fail loudly on an empty payload, stop discarding the watchdog warning, print the failing assertion, chain the cleanup traptests/fixtures/test-helpers.sh Β· tests/security/*

Fix #4 was not planned β€” it surfaced because of fix #3. Writing the correct documentation broke a gate that had silently assumed a two-component world, which is its own small instance of the same theme.