feat(core): L1 formula context — pure λδ with self (the fx-field enabler)#48
Merged
Merged
Conversation
…abler The first step of surfacing λδ in the product: a **formula** evaluation context (spec §5). `eval_formula(nb, self_id, src)` runs a λδ expression with `self` bound to a note's snapshot map and **only the reader builtins in scope** — no mutators — so a formula can never change the notebook. This is the load-bearing core piece the UI "fx" field will sit on. - Split the notebook host's `register` into `register_readers` / `register_mutators`, so a context can grant exactly the surface spec §5 allows (formula/agent-predicate = readers only; action = readers + mutators). - `WasmNotebook::evalFormula(note_id, src)` — the browser entrypoint; read-only, returns the printed result (the notebook is reclaimed unchanged). Proven end-to-end by a test: `(count (words (content self)))` → the word count; `(:title self)` → the title; and `(set-title! (:id self) …)` fails with Unbound (mutators absent), with the notebook verified unchanged. Verification: `cargo test` 82 lib tests green (+1 formula); clippy `-D warnings` clean (default + wasm); fmt clean; `cargo check --features wasm` clean; production code panic-free. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PAEqVP7Y3bZDhtAaPUTbps
🔍 Hypatia Security ScanFindings: 68 issues detected
View findings[
{
"reason": "Issue in scorecard.yml",
"type": "missing_workflow",
"file": "scorecard.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in boj-build.yml",
"type": "missing_timeout_minutes",
"file": "boj-build.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in codeql.yml",
"type": "missing_timeout_minutes",
"file": "codeql.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
marked this pull request as ready for review
July 17, 2026 05:03
|
🔍 Hypatia Security ScanFindings: 68 issues detected
View findings[
{
"reason": "Issue in scorecard.yml",
"type": "missing_workflow",
"file": "scorecard.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in boj-build.yml",
"type": "missing_timeout_minutes",
"file": "boj-build.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in casket-pages.yml",
"type": "missing_timeout_minutes",
"file": "casket-pages.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in codeql.yml",
"type": "missing_timeout_minutes",
"file": "codeql.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in dogfood-gate.yml",
"type": "missing_timeout_minutes",
"file": "dogfood-gate.yml",
"action": "flag",
"rule_module": "workflow_audit",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



What this is
The first step of surfacing λδ in the product (the "make it visible" work). This PR lands the load-bearing core piece — the UI "fx" field will sit directly on it — while staying small, pure, and headless-testable.
A formula evaluation context (spec §5):
eval_formula(nb, self_id, src)runs a λδ expression withselfbound to a note's snapshot map and only the reader builtins in scope. Mutators are deliberately absent, so a formula cannot change the notebook — formulas are pure by construction.Changes
registerintoregister_readers/register_mutators, so each context grants exactly the surface spec §5 allows:eval_formula— bindsself, installs readers, evaluates, returns the value.WasmNotebook::evalFormula(note_id, src)— the browser entrypoint; read-only, returns the printed result (notebook reclaimed unchanged).Proven end-to-end
A host test exercises the whole stack:
(count (words (content self)))→ the note's word count;(:title self)→ the title (note map isself, keyword access works);(set-title! (:id self) "X")→ Unbound (mutators absent), and the notebook is verified unchanged.What this deliberately does NOT include
No UI and no formula persistence yet — where a note's formulas live is a data-model decision that touches the sensitive
Noteschema, so it deserves its own PR (and a heads-up before I touch it). This PR is purely the safe, reusable capability.Verification
cargo test— 82 lib tests green (+1 formula) + host + golden + invariants + doc-tests.cargo clippy --all-targets -- -D warningsclean (default +--features wasm).cargo fmt --checkclean. Production code panic-free.🤖 Generated with Claude Code
https://claude.ai/code/session_01PAEqVP7Y3bZDhtAaPUTbps
Generated by Claude Code