diff --git a/.claude/scheduled_tasks.lock b/.claude/scheduled_tasks.lock index 2077752d..958a0e62 100644 --- a/.claude/scheduled_tasks.lock +++ b/.claude/scheduled_tasks.lock @@ -1 +1 @@ -{"sessionId":"c4d97db1-361c-4a04-a99b-c838f9385469","pid":2426590,"procStart":"349789073","acquiredAt":1780789990975} \ No newline at end of file +{"sessionId":"d510140d-6197-40b7-9bd2-125ca304ad7a","pid":697492,"procStart":"125353752","acquiredAt":1783118024555} \ No newline at end of file diff --git a/plans/agent-briefings/sx-gate-loop.md b/plans/agent-briefings/sx-gate-loop.md index 5a0d0797..dd2cc4aa 100644 --- a/plans/agent-briefings/sx-gate-loop.md +++ b/plans/agent-briefings/sx-gate-loop.md @@ -45,7 +45,7 @@ Pin each confirmed-and-fixed finding with a minimal repro. Add suites to `spec/tests/test-gate-pins.sx` (one `defsuite` per finding). - [x] K18 [W7] — `expt` overflow now float-promotes (no 63-bit wrap) -- [ ] K20 [W7] — identify the landed W7 fix and pin it +- [x] K20 [W7] — `contains?` now supports dict key membership - [ ] K09/K11/K39 [W5] — landed special-form fixes, pin each - [ ] K49 [W8] — render depth/cycle guard (infinite recursive component) - [ ] crit-2 [W1] — signal-return frame key (verify the pin is non-vacuous) @@ -77,6 +77,13 @@ Pin each confirmed-and-fixed finding with a minimal repro. Add suites to ## Progress log (newest first) +- 2026-07-03 — **K20 contains?-dict pin (item A.2)**. Mapped K-codes by + core.md severity order (K17 append!, K18 expt, K19 harness-drift, K20 + contains?-dict). Added suite `gate-K20-contains-dict` to + `spec/tests/test-gate-pins.sx` (4 tests): present dict key → true, missing + key → false, list membership unchanged, string substring unchanged. Repro + from core.md ("(contains? {:a 1} :a) threw `contains?: 2 args`"). 8/8 green + across both suites under OCaml run_tests. Test-only. - 2026-07-03 — **K18 expt-overflow pin (item A.1)**. Bootstrapped this briefing from PLAN.md §W14 (the referenced file did not exist yet). Added `spec/tests/test-gate-pins.sx` with suite `gate-K18-expt-overflow` (4 tests): diff --git a/spec/tests/test-gate-pins.sx b/spec/tests/test-gate-pins.sx index a2de6ede..75c74d47 100644 --- a/spec/tests/test-gate-pins.sx +++ b/spec/tests/test-gate-pins.sx @@ -1,10 +1,11 @@ ;; ========================================================================== -;; test-gate-pins.sx — W14 regression pins for dc7aa709's landed fixes +;; test-gate-pins.sx — W14 regression pins for the review's landed fixes ;; -;; The quick-wins batch (commit dc7aa709) landed real semantics fixes but -;; shipped WITHOUT pinning tests, so a regression would pass silently. This -;; file pins each confirmed-and-fixed finding with a minimal repro lifted -;; from the review lane files (plans/sx-review/*.md). One suite per finding. +;; The quick-wins batch (commit dc7aa709 + siblings) landed real semantics +;; fixes but shipped WITHOUT pinning tests, so a regression would pass +;; silently. This file pins each confirmed-and-fixed finding with a minimal +;; repro lifted from the review lane files (plans/sx-review/*.md). One suite +;; per finding. ;; ;; TEST-ONLY: no semantics edits. If a pin fails, the fix regressed — do NOT ;; relax the assertion; investigate the evaluator/primitive change. @@ -31,3 +32,27 @@ (deftest "expt 2^100 promotes to float" (assert (number? (expt 2 100))))) + +;; -------------------------------------------------------------------------- +;; K20 [W7, high] contains? did not support dicts in the real runtime — +;; (contains? {:a 1} :a) threw "contains?: 2 args", contradicting its :doc +;; ("Dicts: key check"). Fixed: dict key membership works; lists/strings +;; unchanged. Repro (core.md). +;; -------------------------------------------------------------------------- +(defsuite + "gate-K20-contains-dict" + (deftest + "contains? finds a present dict key" + (assert (contains? {:a 1 :b 2} :a))) + (deftest + "contains? reports a missing dict key as false" + (assert (not (contains? {:a 1 :b 2} :zz)))) + (deftest + "contains? still works on list membership" + (do + (assert (contains? (list 10 20 30) 20)) + (assert + (not (contains? (list 10 20 30) 99))))) + (deftest + "contains? still works on string substrings" + (assert (contains? "hello" "ell"))))