Skip to content

feat(jlvm): set + unset map opcodes + conformance vectors#57

Merged
scasplte2 merged 1 commit into
Constellation-Labs:devfrom
ottobot-ai:feat/jlvm-map-set-unset
Jun 19, 2026
Merged

feat(jlvm): set + unset map opcodes + conformance vectors#57
scasplte2 merged 1 commit into
Constellation-Labs:devfrom
ottobot-ai:feat/jlvm-map-set-unset

Conversation

@ottobot-ai

@ottobot-ai ottobot-ai commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

New JLVM map opcodes set and unset in the canonical Scala evaluator. Sister PR for the Rust + TS ports + shared vectors: Constellation-Labs/metakit-sdk#63 (branch feat/jlvm-map-set-unset).

Motivation: the fiber-app audit treated dynamic-key map writes (votes[sender]=v, signatures[signer]=…, etc.) as impossible in JLVM → migrate to arrays (its hardest Tier-iii item). But {"merge":{[expr]:v}} is inexpressible only because a JSON object-literal key is a static AST string — a write opcode takes the key as an evaluated argument, so {"set":[{"var":"state.votes.voters"},{"var":"event.agent"},voteRecord]} synthesizes the runtime key. This collapses the Tier-iii refactor into one opcode pair; dicts stay the data model.

Semantics (inline, modeled on get/merge):

  • set [map, key, value]MapValue(m + (k -> value)) (immutable, last-wins).
  • unset [map, key]MapValue(m - k) (immutable; absent key = no-op).
  • Errors (non-map arg0 / non-string key / wrong arity) → JsonLogicException. Gas = GasCost(5) (= merge).

Changes: JsonLogicOp.scala (enum), JsonLogicSemantics.scala (dispatch + handleSetOp/handleUnsetOp), GasMetering.scala + JsonLogicGasEstimator.scala (gas), MapSetUnsetOpsSuite.scala (20 cases) + synced conformance vectors (conformance/json_logic_test_vectors.json → 1.6.0) so Scala runs the same set/unset vectors as Rust + TS.

Verification: 857 json_logic tests + SharedVectorConformanceSuite [set]/[unset] (23/23); scalafmtCheckAll clean. (Pre-existing, unrelated: project/Dependencies.scala scalafmt drift — untouched.)

🤖 Generated with Claude Code

Immutable dynamic-key map write/delete in the canonical Scala evaluator, wired
inline like get/has/merge. `set [map, key, value]` -> MapValue(m + (k -> value))
(immutable, last-wins); `unset [map, key]` -> MapValue(m - k) (no-op if absent).
The key is an evaluated argument, so a computed runtime key is expressible —
closing the audit's "no JLVM op synthesizes a runtime map key" gap. Dicts stay
the data model; apps' setKey/deleteKey become set/unset.

Errors (non-map arg0 / non-string key / wrong arity) -> JsonLogicException.
Gas = GasCost(5) (= merge).

JsonLogicOp.scala (enum), JsonLogicSemantics.scala (dispatch + handleSetOp/
handleUnsetOp), GasMetering.scala + JsonLogicGasEstimator.scala (gas),
test MapSetUnsetOpsSuite.scala (20 cases). Synced the cross-language conformance
vectors (conformance/json_logic_test_vectors.json -> 1.6.0) so Scala runs the
same set/unset vectors as Rust + TS.

Verified: 857 json_logic tests + SharedVectorConformanceSuite [set]/[unset]
(23/23); scalafmtCheckAll clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ottobot-ai ottobot-ai force-pushed the feat/jlvm-map-set-unset branch from 1bebb39 to 9380692 Compare June 19, 2026 16:52
@scasplte2 scasplte2 merged commit 8ac51ac into Constellation-Labs:dev Jun 19, 2026
1 check passed
@scasplte2 scasplte2 deleted the feat/jlvm-map-set-unset branch June 19, 2026 17:32
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.

2 participants