This release includes 2 breaking changes for platform teams planning a safe upgrade.
✓ No known CVEs patched in this version
Topics
Affected surfaces
Summary
AI summaryDeclared returns are now exposed as top‑level R fields with a reserved‑name parse guard and lint regex extended to catch both top‑level and final_vars accesses.
Full changelog
Closes Perry's 0cd2bd5a lint-question finding, which surfaced a
spec/impl gap underneath the regex limitation he initially flagged.
Three coordinated bugs in a row: spec said canonical access was
${R.SUMMARY} (top-level), impl put declared returns inside
R.final_vars, lint regex only caught the explicit ${R.final_vars.X}
path. Together: ${R.BOGUS} resolved to empty at runtime AND wasn't
flagged by lint. Perry's e01f4148 ack confirmed direction (A) with
one non-optional condition: reserved-name guard against envelope
collisions.
(A) Declared returns spread onto R's top level
composition.ts now spreads the filtered # Returns: surface onto
the result envelope's top level alongside outputs/transcript/etc.
${R.SUMMARY} is the canonical named-access path per spec. The
existing R.final_vars map kept populated as the iteration-view of
the same filtered data:
${R.SUMMARY}— canonical named access (what authors reach for)${R.final_vars}— full filtered map forforeach K in ${R.final_vars}introspection
Both paths address the same data — named is documented canonical,
map is for iteration. Per Perry: "skill is a function; declared
returns ARE the result. final_vars is an implementation name —
exposing it is an abstraction leak."
(B) Reserved-name guard at parse time
New RESERVED_ENVELOPE_FIELDS set in parser.ts enumerates the
envelope fields a caller's R always exposes: skill_name, outputs,
transcript, errors, target_order, fallbacks,
agent_delivery_receipts, final_vars. Declared returns colliding
with these are rejected at parse time with a clear error citing the
full reserved set. Without this guard, # Returns: outputs would
silently shadow the envelope field — exactly the silent-wrong class
this whole ring exists to kill. Per Perry's non-optional condition:
"treat the guard as part of the fix, not a follow-up."
RESERVED_ENVELOPE_FIELDS is exported so adopters can introspect /
align downstream tooling. Same source-of-truth aligned with
composition.ts envelope structure — keep in sync if either grows.
(C) Lint regex extended to catch top-level pattern
unexported-final-var-access now scans for both:
${R.final_vars.X}(the v0.17.4 explicit path)${R.<X>}top-level — the canonical access path Perry's repro tested
Top-level matches skip envelope-field sibling access
(${R.outputs.text}, ${R.transcript}, etc.) and bare iteration
access (${R.final_vars} without further descent). Findings include
an extras.access_path discriminator ("top-level" vs "final_vars")
so adopters with cross-skill tooling can distinguish the surfaces.
Test coverage
20 new tests in v0.17.5-returns-top-level.test.ts covering:
- All 8 reserved-name parse-time rejections
- Mixed-declaration partial-acceptance (good names land, reserved names rejected)
RESERVED_ENVELOPE_FIELDSexport shape- Runtime: top-level
${R.X}resolves,R.final_vars.Xstill works (both paths) - Runtime: undeclared scratch never appears at R top level
- Lint: top-level
${R.BOGUS}fires,${R.ALPHA}silent, envelope-field
access silent,${R.final_vars}bare access silent - Lint: existing v0.17.4
${R.final_vars.X}behavior preserved - Lint: both paths fire when both used in same skill (no double-report on same ref)
1664 tests total. Narrow-core LOC ceiling unchanged at 10500.
Breaking Changes
- Declared return values are now spread onto the top level of `R` (e.g., `${R.SUMMARY}`) and remain available via `R.final_vars`; this changes observable behavior for code expecting returns only in `final_vars`.
- Parse‑time guard rejects declared return names that collide with reserved envelope fields: `skill_name`, `outputs`, `transcript`, `errors`, `target_order`, `fallbacks`, `agent_delivery_receipts`, `final_vars`.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About Skillscript
All releases →Related context
Related tools
Earlier breaking changes
- v0.35.0 Editing `# Deadline:` on an approved skill drops it to Draft (signature invalidates).
Beta — feedback welcome: [email protected]