Add typed Kotlin JSONObject Long lookup

ober

7add929a45a7bbdfbd50dbea56b943bdcbb72e95

diff --git a/data/anti-patterns.sexp b/data/anti-patterns.sexp
index 5f816fe..8a185d8 100644
--- a/data/anti-patterns.sexp
+++ b/data/anti-patterns.sexp
@@ -4262,4 +4262,83 @@
      "jerboa_howto"
      "jerboa_make"
      "jerboa_verify"
-     "focused binary smoke")))
+     "focused binary smoke"))
+ (("advice"
+    .
+    "Iterate a known collection with in-range and its authoritative length. Add a regression above 100000 elements when complete traversal matters.")
+   ("avoid"
+     .
+     "Do not use zero-argument in-naturals as the index stream for a collection that can exceed 100000 entries; traversal stops and later failures can look unrelated.")
+   ("id" . "assuming-in-naturals-is-unbounded")
+   ("kinds" "implementation" "serialization" "test")
+   ("pattern" . "in-naturals") ("severity" . "high")
+   ("tags"
+     "iterator"
+     "in-naturals"
+     "in-range"
+     "large-collection")
+   ("title" . "Do not assume in-naturals is unbounded")
+   ("tools" "jerboa_howto" "jerboa_verify" "jerboa_run_tests"))
+ (("advice"
+    .
+    "Pause any active pusher, inspect process trees and reflogs, identify the authoritative old_oid/new_oid plan, restore local refs to the recorded new_oid values, query current server refs, then push the exact planned objects with explicit force-with-lease expectations. Verify every local and remote ref against the plan before expiring old history.")
+   ("avoid"
+     .
+     "Do not merge, rebase, reset, or repoint apparently diverged branches until checking for active fast-import/filter-repo processes, ref reflogs, and recorded rewrite/push plans. Remote refs may still be the pre-rewrite generation while local refs are the intended sanitized generation.")
+   ("id" . "repairing-divergence-during-history-rewrite")
+   ("kinds" "all")
+   ("pattern"
+     .
+     "ahead .* behind .*|fast-import|force-with-lease|history rewrite")
+   ("severity" . "high")
+   ("tags" "git" "fast-import" "force-push" "divergence"
+     "history-rewrite" "race")
+   ("title"
+     .
+     "Do Not Repair Divergence During an Active History Rewrite")
+   ("tools" "ps" "git reflog" "git show-ref" "git ls-remote"
+     "git update-ref" "git push --atomic --force-with-lease"))
+ (("advice"
+    .
+    "Benchmark the representative scale tier before and after. Keep the simpler implementation when the direct-write variant does not improve both the intended metric and acceptable runtime.")
+   ("avoid"
+     .
+     "Do not replace small bytevector-copy operations with extra Scheme control flow and assume the serializer improved. Native copies can be cheaper than added dispatch and bookkeeping.")
+   ("id" . "assuming-fewer-bytevector-copies-is-faster")
+   ("kinds" "module" "test")
+   ("pattern" . "direct.*bytevector|bytevector.*direct")
+   ("severity" . "medium")
+   ("tags"
+     "performance"
+     "bytevector-copy"
+     "serialization"
+     "benchmark")
+   ("title"
+     .
+     "Do not assume fewer bytevector copies is faster")
+   ("tools"
+     "jerboa_howto"
+     "jerboa_verify"
+     "capacity benchmark"))
+ (("advice"
+    .
+    "Keep jerboa.sh production binary-only: build the FreeBSD site artifact through the Jerboa project build target, deploy only /usr/local/libexec/jerboa-site/jerboa-site plus rc.d/TLS configuration, and remove any legacy source checkout or runtime-tree artifacts. If the binary build fails, repair the Jerboa build inputs instead of changing production into a multi-file runtime deployment.")
+   ("avoid"
+     .
+     "Do not fix a jerboa-site production deploy by copying compiled runtime library trees, setting interpreter library-path environment variables, or leaving source checkouts on dns2.")
+   ("id" . "jerboa-site-runtime-tree-deploy")
+   ("kinds" "docs" "script")
+   ("pattern"
+     .
+     "jerboa-site.*(CHEZSCHEMELIBDIRS|runtime librar|bundle u-lib|jerboa-site-runtime|/usr/local/lib/jerboa-site)")
+   ("severity" . "high")
+   ("tags" "jerboa-site" "deploy" "dns2" "binary" "runtime"
+     "ansible")
+   ("title"
+     .
+     "Do Not Repair jerboa-site Deploys By Copying Runtime Trees")
+   ("tools"
+     "jerboa_howto"
+     "jerboa_request_advisor"
+     "ansible-playbook --syntax-check"
+     "make -C jerboa-site static-binary")))
diff --git a/data/cookbooks.sexp b/data/cookbooks.sexp
index 56f974e..656285c 100644
--- a/data/cookbooks.sexp
+++ b/data/cookbooks.sexp
@@ -6753,4 +6753,37 @@
      "std-misc-ringbuf" "cursor")
    ("title"
      .
-     "Bounded byte replay ring with absolute offsets")))
+     "Bounded byte replay ring with absolute offsets"))
+ (("code"
+    .
+    "(import (jerboa prelude))\n(def xs (make-vector 100001 0))\n(for ([i (in-range (vector-length xs))])\n  (vector-set! xs i i))\n(displayln (vector-ref xs 100000))") ("id" . "iterate-complete-known-length-collections")
+   ("imports" "(jerboa prelude)")
+   ("notes"
+     .
+     "For complete traversal use in-range with the collection length. Zero-argument in-naturals currently stops after 100000 values, so it is unsuitable as an unbounded serializer index.")
+   ("tags" "in-range" "in-naturals" "vector" "serialization")
+   ("title" . "Iterate a complete large collection"))
+ (("code"
+    .
+    "(import (jerboa prelude))\n(def path \"/tmp/seek-rewrite.bin\")\n(when (file-exists? path) (delete-file path))\n(def p (open-file-output-port path (file-options no-fail)))\n(put-bytevector p (make-bytevector 3 1))\n(set-port-position! p 1)\n(put-bytevector p (make-bytevector 1 9))\n(flush-output-port p)\n(close-port p)\n(delete-file path)") ("id" . "seek-and-rewrite-binary-output-file")
+   ("imports" "(jerboa prelude)")
+   ("notes"
+     .
+     "Seeking rewrites bytes without truncating the remainder. Production code should close with dynamic-wind and publish by renaming a completed temporary file.")
+   ("tags"
+     "binary-io"
+     "set-port-position"
+     "output-port"
+     "checksum")
+   ("title" . "Seek and rewrite binary output"))
+ (("code"
+    .
+    "# Controller-side source stays local. Production gets only the built site binary.\ncd ~/anon/infra_ansible\n\n# Build from local Jerboa projects and deploy the resulting FreeBSD binary.\n# Keep source updates explicit; use false when local checkouts are already at the reviewed commits.\nANSIBLE_SSH_ARGS='-A -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no' \\\n  ansible-playbook -i inventory/hosts playbooks/jerboa_site.yml \\\n  -e jerboa_site_update_sources=false\n\n# Production invariants managed by playbooks/jerboa_site.yml:\n# - /usr/local/libexec/jerboa-site/jerboa-site is the deployable artifact.\n# - /var/db/jerboa-site is only the service user's home.\n# - no jerboa-site source checkout is left on dns2.\n# - no runtime library tree is deployed alongside the site binary.") ("id" . "jerboa-site-dns2-binary-only-deploy") ("imports")
+   ("notes"
+     .
+     "Use the Jerboa project build target and Jerboa-native archive selection already encoded in the playbook. Do not copy a source checkout to dns2. Do not add runtime library directories, interpreter environment variables, or loose compiled module trees to production to work around a failed binary build; fix the Jerboa binary build path instead. The public service should run from the single deployed site binary plus TLS files and rc.d metadata.")
+   ("tags" "jerboa-site" "dns2" "deploy" "binary" "freebsd"
+     "ansible")
+   ("title"
+     .
+     "Deploy jerboa-site to dns2 as a Jerboa-built binary only")))
diff --git a/data/features.sexp b/data/features.sexp
index a192eb4..14b8137 100644
--- a/data/features.sexp
+++ b/data/features.sexp
@@ -3573,4 +3573,53 @@
    ("use_case"
      .
      "Run after feature updates and before embedding MCP data so backlog queries do not treat missing statuses as implicit proposals or completed work as open.")
+   ("votes" . 0))
+ (("description"
+    .
+    "Add a Jerboa API or MCP helper for peak/current RSS, page reclaims, page faults, CPU time, and wall time so capacity benchmarks do not need platform-specific /usr/bin/time output.") ("estimated_token_reduction" . "")
+   ("example_scenario"
+     .
+     "A benchmark records peak RSS and page faults on macOS and Linux using one structured API.")
+   ("id" . "process-resource-usage-metrics")
+   ("impact" . "medium") ("status" . "open")
+   ("tags" "benchmark" "memory" "rss" "page-faults" "process")
+   ("title" . "Expose process resource-usage metrics")
+   ("use_case"
+     .
+     "Measure build and mmap-reader memory independently in repeatable Jerboa benchmarks.")
+   ("votes" . 0))
+ (("description"
+    .
+    "jerboa_check_syntax and jerboa_howto_verify report `invalid syntax begin` for valid top-level examples containing dynamic-wind, while the Jerboa build accepts the same pattern.") ("estimated_token_reduction" . "")
+   ("example_scenario"
+     .
+     "A seekable binary-output cookbook recipe passes after dynamic-wind is removed even though project source builds with it.")
+   ("id" . "check-syntax-dynamic-wind-top-level")
+   ("impact" . "medium") ("status" . "open")
+   ("tags"
+     "verifier"
+     "dynamic-wind"
+     "cookbook"
+     "false-positive")
+   ("title" . "Fix dynamic-wind false syntax failures")
+   ("use_case"
+     .
+     "Verify resource-safe file and port examples without weakening them to explicit close-only snippets.")
+   ("votes" . 0))
+ (("description"
+    .
+    "When the configured Jerboa MCP transport closes, later typed tool calls remain permanently closed even after a healthy jmcp process is available, forcing manual JSON-RPC over a terminal session.")
+   ("estimated_token_reduction"
+     .
+     "~500 tokens per affected session")
+   ("example_scenario"
+     .
+     "Typed module export and verifier calls all return `Transport closed`; a directly initialized jmcp session handles the same requests.")
+   ("id" . "mcp-reconnect-after-transport-close")
+   ("impact" . "high") ("status" . "open")
+   ("tags" "mcp" "transport" "reconnect" "reliability")
+   ("title" . "Reconnect MCP after transport closure")
+   ("use_case"
+     .
+     "Continue mandatory Jerboa verification and knowledge writes after one server transport failure.")
    ("votes" . 0)))
diff --git a/lib/jerboa/typed/checker.ss b/lib/jerboa/typed/checker.ss
index 609252f..dc6c233 100644
--- a/lib/jerboa/typed/checker.ss
+++ b/lib/jerboa/typed/checker.ss
@@ -569,6 +569,9 @@
       (cons 'json-object-opt-float32-default
             (make-typed-call-sig (list 'JSONObject 'String 'Float32) 'Float32 '()
               'jvm-json-object-opt-float32-default '()))
+      (cons 'json-object-opt-int-default
+            (make-typed-call-sig (list 'JSONObject 'String 'Int) 'Int '()
+              'jvm-json-object-opt-int-default '()))
       (cons 'json-object-opt-int32-default
             (make-typed-call-sig (list 'JSONObject 'String 'Int32) 'Int32 '()
               'jvm-json-object-opt-int32-default '()))
diff --git a/lib/jerboa/typed/core.ss b/lib/jerboa/typed/core.ss
index 6fe364b..c020fea 100644
--- a/lib/jerboa/typed/core.ss
+++ b/lib/jerboa/typed/core.ss
@@ -166,6 +166,7 @@
       jvm-json-object-opt-string-default
       jvm-json-object-opt-float32
       jvm-json-object-opt-float32-default
+      jvm-json-object-opt-int-default
       jvm-json-object-opt-int32-default
       jvm-json-object-opt-json-array
       jvm-json-object-opt-json-object
diff --git a/lib/jerboa/typed/kotlin/lower.ss b/lib/jerboa/typed/kotlin/lower.ss
index 1eecd09..81ed387 100644
--- a/lib/jerboa/typed/kotlin/lower.ss
+++ b/lib/jerboa/typed/kotlin/lower.ss
@@ -533,6 +533,8 @@
                (make-kt-member-call (caddr args) 'toDouble '())))
            'toFloat
            '())]
+        [(jvm-json-object-opt-int-default)
+         (make-kt-member-call (car args) 'optLong (cdr args))]
         [(jvm-json-object-opt-int32-default)
          (make-kt-member-call (car args) 'optInt (cdr args))]
         [(jvm-json-object-opt-json-array)
diff --git a/tests/test-typed-kotlin.ss b/tests/test-typed-kotlin.ss
index 6a90fe9..cd45304 100644
--- a/tests/test-typed-kotlin.ss
+++ b/tests/test-typed-kotlin.ss
@@ -814,6 +814,8 @@
        (json-object-opt-float32-default json "x" (float32 1.0)))
      (def (readCount (json : JSONObject)) : Int32
        (json-object-opt-int32-default json "count" (int32 1)))
+     (def (readTimestamp (json : JSONObject)) : Int
+       (json-object-opt-int-default json "generated_at" (int 0)))
      (def (readItems (json : JSONObject)) : (Nullable JSONArray)
        (json-object-opt-json-array json "items"))
      (def (readMeta (json : JSONObject)) : (Nullable JSONObject)
@@ -855,6 +857,9 @@
 (test-contains "JSONObject opt Int32 default lowers to optInt"
   json-object-kotlin
   "json.optInt(\"count\", 1)")
+(test-contains "JSONObject opt Int default lowers to optLong"
+  json-object-kotlin
+  "json.optLong(\"generated_at\", 0L)")
 (test-contains "JSONObject opt JSONArray lowers to nullable optJSONArray"
   json-object-kotlin
   "json.optJSONArray(\"items\")")