Skip to content

feat(plugin): 1.4.0 — Job-tier billing is per model reply; lua-cli 3.37.0 cost read-outs (requires lua-cli 3.37.0, publishing today) - #13

Merged
lua-stefan-kruger merged 1 commit into
mainfrom
feat/knowledge-job-billing
Sep 20, 2026
Merged

lua-stefan-kruger merged 1 commit into
mainfrom
feat/knowledge-job-billing

Conversation

@lua-stefan-kruger

Copy link
Copy Markdown
Contributor

⛔ Merge blocker: requires lua-cli 3.37.0 (publishing today)

PINNED_MIN_LUA_CLI is raised to 3.37.0, which is cut (ebcf6689c, release PR #3095) but not yet on npm — the publish follows today's production E2E. scripts/lint-pinned-version.mjs compares the pin with npm's dist-tags.latest and is therefore red by design until then; it was not weakened. Merge after the npm publish: verify npm view lua-cli version = 3.37.0 → re-run npm run lint (18/18 green) → squash-merge.

What this fixes

The plugin told agents a Job-tier attempt costs a flat 4 credits and that every run budget is counted in credits. Both are wrong for a priced run.

The billing rule — platform behaviour, already true in production on 3.36.0 and on every older CLI, so it carries no version marker (marking it ⏳ 3.37.0 would say a Job attempt costs 4 credits until you upgrade your CLI, which is the defect):

  • A Job-tier step is billed per model REPLY, not per attempt — a coding turn that answers two hundred times is charged two hundred times. On a legacy plan a credit is one model reply on a Job step, one agent step otherwise; on a seat plan the unit is actions = the call's price band × the resolved model's multiplier per model call, with cached prompt tokens counted at the fraction of a fresh token the provider charges (uncalibrated, or unsplit, falls back to full weight).
  • The flat rule is kept, scoped: while the platform is still metering a run flat, an inline agent step is 1 credit and a Job attempt is 4 — which is exactly what lua workflows status still prints for such a run.
  • Which model a Job step runs on is not the agent's model: the step's own model, failing that the platform's Job default, failing that the organization's. Every reply bills at that model's multiplier, so leaving model off a Job step is a cost decision.
  • lua workflows raise-budget <runId> --credits <n> keeps its flag name on both plans, but <n> is a cap in the run's OWN unit (actions on a seat plan).

The lua-cli 3.37.0 read-outs — marked ⏳ 3.37.0 and described as "printed only when the server projects it", so a missing line reads as "nobody reported", never as a defect:

  • status: the Tokens: line (run-level), the Uncached / Cached / Output step columns (—, never 0), the ⚙ Job-model line (model · ×multiplier · chosen by leg), the engine-aware Budget: sentence and finished past the cap.
  • Signals, not charges: the token figures never moved the credits or actions, and must never be summed — a cache read is a subset of the input figure on OpenAI-compatible providers.
  • lua workflows logs: step.job_model_resolved plus the three budget events (run.budget_parked / _raised / _exceeded), which below 3.37.0 it printed not at all; the unit inside them is the gate's own word, quoted verbatim.
  • lua workflows deploy: the job-model-default advisory ( ⚠ <message>, advisory only, the deploy still succeeds), beside the older job-tier-not-enabled.
  • raise-budget names the unit it raised; a seat run parked before its first priced call no longer reads the legacy sentence.

Why the pin moves, when no shape changed

lua-cli 3.37.0's entire src/cli/command-definitions.ts diff is the --credits help string — no new command, no new option, no alias change — so every shape the plugin emits runs byte-identically on 3.36.0. The pin moves because the plugin's subagents now read output only 3.37.0 prints. Consequently nothing changed in lib/permissions-template.json, hooks/hooks.json, any other hook, lib/tokenizer.mjs, scripts/lint-knowledge-commands.mjs, scripts/lint-cli-flags.mjs or test/** — editing those would have meant a verb had been invented.

Also recorded, so the next pass does not "fix" them: budget.unit, budget.reserved and usage.engine are not new in 3.37.0 (3.36.0 already sent them; reserved has no printed line at all), and the consent ladder's "≤ 20 credits" is a scoring quantity, not the run's billing unit — deliberately left in credits.

Changed

Knowledge workflows.md (§2 new "Reading what a run cost", §4 metering / Job model / limits, §7, §8), cli-reference.md, decision-trees.md, primitives.md (§11, §12, gotcha 35); commands lua-workflow, lua-logs, lua-status, lua-deploy, lua-push, lua-init, lua-update, lua-doctor; agents lua-architect, lua-debug, lua-deploy-pilot, lua-qa, lua-skill-builder; docs/USER_GUIDE.md (loop step 8, a troubleshooting bullet, an FAQ entry), both READMEs, CHANGELOG.md 1.4.0; hooks/check-lua-version.mjs pin 3.36.0 → 3.37.0; version 1.3.0 → 1.4.0 everywhere with mcp/lua-platform/dist/server.js rebuilt.

Checks (what CI runs)

  • npm run lint — lint-pinned-version ✗ by design (pin 3.37.0 > npm latest 3.36.0). Every other check run individually: all green, including ✓ Knowledge files: 819 lua … reference(s) check out against command-definitions.ts (against ebcf6689c) and ✓ Release version 1.4.0 is consistent.
  • npm test -- --coverage → 18 suites / 428 tests passed; check-coverage.mjs ✓.
  • MCP job: 9 suites / 147 tests passed, bundle rebuilt, check-bundle-size.mjs ✓ (0.10 MB).

Full audit (claim → source anchor → verdict, 27 rows): lua-docs-v2-plan/plan-job-billing/reviews/plugin-audit-2026-09-20.md.

🤖 Generated with Claude Code

@lua-stefan-kruger
lua-stefan-kruger force-pushed the feat/knowledge-job-billing branch from 324aa88 to 6dcb9f3 Compare September 20, 2026 14:25
…a-cli 3.37.0 cost read-outs

The plugin described a Job-tier attempt as a flat 4 credits and every run
budget in "credits". Both are wrong for a priced run. Verified against
lua-core-services main ebcf6689c (the lua-cli 3.37.0 release) — the CLI
renderers, the wire shapes, lua-api's deploy advisory, the Job model legs and
labels in shared-types and lua-core's Job rate module — never the docs.

The rule (platform behaviour, true on every CLI, so NOT marked with a version
gate): a Job step is billed per model REPLY, not per attempt — one credit per
reply on a legacy plan, actions (price band × the model's multiplier per model
call, cached prompt tokens at the fraction the provider charges) on a seat
plan. The flat "1 credit / 4 credits" rule is kept, scoped to a run the
platform is still metering flat, which is what `status` prints verbatim for
such a run. A Job step runs on its own `model`, failing that the platform's Job
default, failing that the org's — never the agent's — so leaving it off is a
cost decision. `raise-budget --credits <n>` keeps its flag name on both plans
but `<n>` is a cap in the run's own unit.

The read-outs (marked ⏳ 3.37.0 and described as printed only when the server
projects them): the `Tokens:` line and the Uncached/Cached/Output step columns
(signals, not charges — never summed: a cache read is a subset of input), the ⚙
Job-model line, the engine-aware budget sentence and `finished past the cap`,
the three budget events in `workflows logs`, the unit-aware `raise-budget`
confirmation and the `job-model-default` deploy advisory.

lua-cli 3.37.0 adds NO command and NO option — its only command-definitions
change is the `--credits` help string — so every shape the plugin emits still
runs on 3.36.0 and only prints less. `PINNED_MIN_LUA_CLI` moves to 3.37.0
because the subagents now read that output. `lint-pinned-version` is therefore
red by design until 3.37.0 is on npm; it was not weakened. No permission rule,
hook, tokenizer or lint verb list changed, because no command surface did.

Audit: lua-docs-v2-plan/plan-job-billing/reviews/plugin-audit-2026-09-20.md

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@lua-stefan-kruger
lua-stefan-kruger force-pushed the feat/knowledge-job-billing branch from 6dcb9f3 to 2dca5ec Compare September 20, 2026 14:27
@lua-stefan-kruger
lua-stefan-kruger merged commit 54f277f into main Sep 20, 2026
10 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant