chore: remove dev artifacts; keep only published code/tests/docs

Remove agent/dev tooling and scratch files that aren't part of the published
project:
- .beads/ (issue tracker) and .clj-kondo/ (linter cache) — now gitignored
- AGENTS.md, CLAUDE.md, PLAN.md (agent/planning docs)
- root scratch scripts: fix-core.janet, preprocess.janet, and the loose
  test-*.janet probes (the real tests live under test/)
- clojure-features.clj — its features are already covered by
  test/integration/features-test.janet (dropped the optional smoke-test block)

The repo now tracks only: src/ (interpreter + clojure.core.async + stdlib),
test/ (spec/integration/unit), doc/grammar.ebnf, README, LICENSE, project.janet,
and the vendor/sci submodule. jpm test green.
This commit is contained in:
Yogthos 2026-06-05 15:45:04 -04:00
parent 54db79e927
commit f24c9aa1fd
27 changed files with 7 additions and 1180 deletions

70
.beads/.gitignore vendored
View file

@ -1,70 +0,0 @@
# Dolt database (managed by Dolt, not git)
dolt/
embeddeddolt/
# Runtime files
bd.sock
bd.sock.startlock
sync-state.json
last-touched
.exclusive-lock
# Daemon runtime (lock, log, pid)
daemon.*
# Push state (runtime, per-machine)
push-state.json
# Lock files (various runtime locks)
*.lock
# Credential key (encryption key for federation peer auth — never commit)
.beads-credential-key
# Local version tracking (prevents upgrade notification spam after git ops)
.local_version
# Worktree redirect file (contains relative path to main repo's .beads/)
# Must not be committed as paths would be wrong in other clones
redirect
# Sync state (local-only, per-machine)
# These files are machine-specific and should not be shared across clones
.sync.lock
export-state/
export-state.json
# Ephemeral store (SQLite - wisps/molecules, intentionally not versioned)
ephemeral.sqlite3
ephemeral.sqlite3-journal
ephemeral.sqlite3-wal
ephemeral.sqlite3-shm
# Dolt server management (auto-started by bd)
dolt-server.pid
dolt-server.log
dolt-server.lock
dolt-server.port
dolt-server.activity
# Corrupt backup directories (created by bd doctor --fix recovery)
*.corrupt.backup/
# Backup data (auto-exported JSONL, local-only)
backup/
# Per-project environment file (Dolt connection config, GH#2520)
.env
# Legacy files (from pre-Dolt versions)
*.db
*.db?*
*.db-journal
*.db-wal
*.db-shm
db.sqlite
bd.db
# NOTE: Do NOT add negation patterns here.
# They would override fork protection in .git/info/exclude.
# Config files (metadata.json, config.yaml) are tracked by git by default
# since no pattern above ignores them.

View file

@ -1,81 +0,0 @@
# Beads - AI-Native Issue Tracking
Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code.
## What is Beads?
Beads is issue tracking that lives in your repo, making it perfect for AI coding agents and developers who want their issues close to their code. No web UI required - everything works through the CLI and integrates seamlessly with git.
**Learn more:** [github.com/steveyegge/beads](https://github.com/steveyegge/beads)
## Quick Start
### Essential Commands
```bash
# Create new issues
bd create "Add user authentication"
# View all issues
bd list
# View issue details
bd show <issue-id>
# Update issue status
bd update <issue-id> --claim
bd update <issue-id> --status done
# Sync with Dolt remote
bd dolt push
```
### Working with Issues
Issues in Beads are:
- **Git-native**: Stored in Dolt database with version control and branching
- **AI-friendly**: CLI-first design works perfectly with AI coding agents
- **Branch-aware**: Issues can follow your branch workflow
- **Always in sync**: Auto-syncs with your commits
## Why Beads?
✨ **AI-Native Design**
- Built specifically for AI-assisted development workflows
- CLI-first interface works seamlessly with AI coding agents
- No context switching to web UIs
🚀 **Developer Focused**
- Issues live in your repo, right next to your code
- Works offline, syncs when you push
- Fast, lightweight, and stays out of your way
🔧 **Git Integration**
- Automatic sync with git commits
- Branch-aware issue tracking
- Dolt-native three-way merge resolution
## Get Started with Beads
Try Beads in your own projects:
```bash
# Install Beads
curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
# Initialize in your repo
bd init
# Create your first issue
bd create "Try out Beads"
```
## Learn More
- **Documentation**: [github.com/steveyegge/beads/docs](https://github.com/steveyegge/beads/tree/main/docs)
- **Quick Start Guide**: Run `bd quickstart`
- **Examples**: [github.com/steveyegge/beads/examples](https://github.com/steveyegge/beads/tree/main/examples)
---
*Beads: Issue tracking that moves at the speed of thought* ⚡

View file

@ -1,55 +0,0 @@
# Beads Configuration File
# This file configures default behavior for all bd commands in this repository
# All settings can also be set via environment variables (BD_* prefix)
# or overridden with command-line flags
# Issue prefix for this repository (used by bd init)
# If not set, bd init will auto-detect from directory name
# Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc.
# issue-prefix: ""
# Use no-db mode: JSONL-only, no Dolt database
# When true, bd will use .beads/issues.jsonl as the source of truth
# no-db: false
# Enable JSON output by default
# json: false
# Feedback title formatting for mutating commands (create/update/close/dep/edit)
# 0 = hide titles, N > 0 = truncate to N characters
# output:
# title-length: 255
# Default actor for audit trails (overridden by BEADS_ACTOR or --actor)
# actor: ""
# Export events (audit trail) to .beads/events.jsonl on each flush/sync
# When enabled, new events are appended incrementally using a high-water mark.
# Use 'bd export --events' to trigger manually regardless of this setting.
# events-export: false
# Multi-repo configuration (experimental - bd-307)
# Allows hydrating from multiple repositories and routing writes to the correct database
# repos:
# primary: "." # Primary repo (where this database lives)
# additional: # Additional repos to hydrate from (read-only)
# - ~/beads-planning # Personal planning repo
# - ~/work-planning # Work planning repo
# JSONL backup (periodic export for off-machine recovery)
# Auto-enabled when a git remote exists. Override explicitly:
# backup:
# enabled: false # Disable auto-backup entirely
# interval: 15m # Minimum time between auto-exports
# git-push: false # Disable git push (export locally only)
# git-repo: "" # Separate git repo for backups (default: project repo)
# Integration settings (access with 'bd config get/set')
# Non-secret keys (stored in the database):
# - jira.url, jira.project
# - linear.team_id
# - github.org, github.repo
#
# Secret keys (stored in this file but prefer env vars to avoid git exposure):
# - linear.api_key → use LINEAR_API_KEY env var instead
# - github.token → use GITHUB_TOKEN env var instead

View file

@ -1,24 +0,0 @@
#!/usr/bin/env sh
# --- BEGIN BEADS INTEGRATION v1.0.4 ---
# This section is managed by beads. Do not remove these markers.
if command -v bd >/dev/null 2>&1; then
export BD_GIT_HOOK=1
_bd_timeout=${BEADS_HOOK_TIMEOUT:-300}
if command -v timeout >/dev/null 2>&1; then
timeout "$_bd_timeout" bd hooks run post-checkout "$@"
_bd_exit=$?
if [ $_bd_exit -eq 124 ]; then
echo >&2 "beads: hook 'post-checkout' timed out after ${_bd_timeout}s — continuing without beads"
_bd_exit=0
fi
else
bd hooks run post-checkout "$@"
_bd_exit=$?
fi
if [ $_bd_exit -eq 3 ]; then
echo >&2 "beads: database not initialized — skipping hook 'post-checkout'"
_bd_exit=0
fi
if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
fi
# --- END BEADS INTEGRATION v1.0.4 ---

View file

@ -1,24 +0,0 @@
#!/usr/bin/env sh
# --- BEGIN BEADS INTEGRATION v1.0.4 ---
# This section is managed by beads. Do not remove these markers.
if command -v bd >/dev/null 2>&1; then
export BD_GIT_HOOK=1
_bd_timeout=${BEADS_HOOK_TIMEOUT:-300}
if command -v timeout >/dev/null 2>&1; then
timeout "$_bd_timeout" bd hooks run post-merge "$@"
_bd_exit=$?
if [ $_bd_exit -eq 124 ]; then
echo >&2 "beads: hook 'post-merge' timed out after ${_bd_timeout}s — continuing without beads"
_bd_exit=0
fi
else
bd hooks run post-merge "$@"
_bd_exit=$?
fi
if [ $_bd_exit -eq 3 ]; then
echo >&2 "beads: database not initialized — skipping hook 'post-merge'"
_bd_exit=0
fi
if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
fi
# --- END BEADS INTEGRATION v1.0.4 ---

View file

@ -1,24 +0,0 @@
#!/usr/bin/env sh
# --- BEGIN BEADS INTEGRATION v1.0.4 ---
# This section is managed by beads. Do not remove these markers.
if command -v bd >/dev/null 2>&1; then
export BD_GIT_HOOK=1
_bd_timeout=${BEADS_HOOK_TIMEOUT:-300}
if command -v timeout >/dev/null 2>&1; then
timeout "$_bd_timeout" bd hooks run pre-commit "$@"
_bd_exit=$?
if [ $_bd_exit -eq 124 ]; then
echo >&2 "beads: hook 'pre-commit' timed out after ${_bd_timeout}s — continuing without beads"
_bd_exit=0
fi
else
bd hooks run pre-commit "$@"
_bd_exit=$?
fi
if [ $_bd_exit -eq 3 ]; then
echo >&2 "beads: database not initialized — skipping hook 'pre-commit'"
_bd_exit=0
fi
if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
fi
# --- END BEADS INTEGRATION v1.0.4 ---

View file

@ -1,24 +0,0 @@
#!/usr/bin/env sh
# --- BEGIN BEADS INTEGRATION v1.0.4 ---
# This section is managed by beads. Do not remove these markers.
if command -v bd >/dev/null 2>&1; then
export BD_GIT_HOOK=1
_bd_timeout=${BEADS_HOOK_TIMEOUT:-300}
if command -v timeout >/dev/null 2>&1; then
timeout "$_bd_timeout" bd hooks run pre-push "$@"
_bd_exit=$?
if [ $_bd_exit -eq 124 ]; then
echo >&2 "beads: hook 'pre-push' timed out after ${_bd_timeout}s — continuing without beads"
_bd_exit=0
fi
else
bd hooks run pre-push "$@"
_bd_exit=$?
fi
if [ $_bd_exit -eq 3 ]; then
echo >&2 "beads: database not initialized — skipping hook 'pre-push'"
_bd_exit=0
fi
if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
fi
# --- END BEADS INTEGRATION v1.0.4 ---

View file

@ -1,24 +0,0 @@
#!/usr/bin/env sh
# --- BEGIN BEADS INTEGRATION v1.0.4 ---
# This section is managed by beads. Do not remove these markers.
if command -v bd >/dev/null 2>&1; then
export BD_GIT_HOOK=1
_bd_timeout=${BEADS_HOOK_TIMEOUT:-300}
if command -v timeout >/dev/null 2>&1; then
timeout "$_bd_timeout" bd hooks run prepare-commit-msg "$@"
_bd_exit=$?
if [ $_bd_exit -eq 124 ]; then
echo >&2 "beads: hook 'prepare-commit-msg' timed out after ${_bd_timeout}s — continuing without beads"
_bd_exit=0
fi
else
bd hooks run prepare-commit-msg "$@"
_bd_exit=$?
fi
if [ $_bd_exit -eq 3 ]; then
echo >&2 "beads: database not initialized — skipping hook 'prepare-commit-msg'"
_bd_exit=0
fi
if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
fi
# --- END BEADS INTEGRATION v1.0.4 ---

View file

@ -1,30 +0,0 @@
{"id":"int-621ea914","kind":"field_change","created_at":"2026-06-04T17:50:54.012588Z","actor":"Yogthos","issue_id":"jolt-x8s","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-978620fa","kind":"field_change","created_at":"2026-06-04T17:59:35.53184Z","actor":"Yogthos","issue_id":"jolt-lp5","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-11c77978","kind":"field_change","created_at":"2026-06-04T18:06:01.464313Z","actor":"Yogthos","issue_id":"jolt-tws","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-2eef7613","kind":"field_change","created_at":"2026-06-04T18:06:02.544998Z","actor":"Yogthos","issue_id":"jolt-wec","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-a7573343","kind":"field_change","created_at":"2026-06-04T18:09:14.608401Z","actor":"Yogthos","issue_id":"jolt-alz","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-40cd8348","kind":"field_change","created_at":"2026-06-04T18:09:15.510649Z","actor":"Yogthos","issue_id":"jolt-nte","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-57f4d2b3","kind":"field_change","created_at":"2026-06-04T18:31:23.83434Z","actor":"Yogthos","issue_id":"jolt-9sb","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-f46da620","kind":"field_change","created_at":"2026-06-04T18:33:45.099148Z","actor":"Yogthos","issue_id":"jolt-ytt","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-677fb0a5","kind":"field_change","created_at":"2026-06-04T18:40:42.396722Z","actor":"Yogthos","issue_id":"jolt-40n","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-10c63325","kind":"field_change","created_at":"2026-06-04T18:40:43.31635Z","actor":"Yogthos","issue_id":"jolt-4z9","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-ba29d2c7","kind":"field_change","created_at":"2026-06-04T18:45:52.297233Z","actor":"Yogthos","issue_id":"jolt-gxr","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-b7e06923","kind":"field_change","created_at":"2026-06-04T18:55:10.600885Z","actor":"Yogthos","issue_id":"jolt-7n5","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-0d2b12ab","kind":"field_change","created_at":"2026-06-04T18:56:25.718778Z","actor":"Yogthos","issue_id":"jolt-90c","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-a86d84ba","kind":"field_change","created_at":"2026-06-04T18:57:26.21495Z","actor":"Yogthos","issue_id":"jolt-h0n","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-5ddb241f","kind":"field_change","created_at":"2026-06-04T18:57:27.904474Z","actor":"Yogthos","issue_id":"jolt-7dy","extra":{"field":"status","new_value":"deferred","old_value":"open"}}
{"id":"int-9a5516da","kind":"field_change","created_at":"2026-06-04T19:41:39.048731Z","actor":"Yogthos","issue_id":"jolt-4zg","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-b700eb9e","kind":"field_change","created_at":"2026-06-04T19:48:03.780728Z","actor":"Yogthos","issue_id":"jolt-l8f","extra":{"field":"status","new_value":"closed","old_value":"open"}}
{"id":"int-700a80a8","kind":"field_change","created_at":"2026-06-04T19:56:36.343102Z","actor":"Yogthos","issue_id":"jolt-7dy","extra":{"field":"status","new_value":"closed","old_value":"deferred"}}
{"id":"int-0e80bc4f","kind":"field_change","created_at":"2026-06-04T20:23:37.457452Z","actor":"Yogthos","issue_id":"jolt-cn4","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Closed"}}
{"id":"int-8cd2e476","kind":"field_change","created_at":"2026-06-04T21:28:16.906665Z","actor":"Yogthos","issue_id":"jolt-y29","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Closed"}}
{"id":"int-6042189d","kind":"field_change","created_at":"2026-06-04T23:20:46.565771Z","actor":"Yogthos","issue_id":"jolt-ns4","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Done across 3 rounds (pushed a0c9696): build-time mutable/immutable toggle, structural-sharing persistent vectors (32-way trie), and persistent O(1)-prepend linked lists. Plus bit-clear/get-method and a batch of missing core fns. conformance 206/206, features 78/78, jank 120."}}
{"id":"int-80df5ed4","kind":"field_change","created_at":"2026-06-05T03:35:42.672628Z","actor":"Yogthos","issue_id":"jolt-i3g","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Done — SCI bootstrap now loads 422/422 with 0 failures. Fixed deftype protocol-method registration, with-meta on functions, select-keys over vectors, require :as+:refer, defmethod-on-fn; added clojure.set/join and host-module stubs. test-load-sci asserts 0 failures."}}
{"id":"int-b296d941","kind":"field_change","created_at":"2026-06-05T05:02:01.433529Z","actor":"Yogthos","issue_id":"jolt-do7","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Fixed: PHM/PHS canonicalize collection keys for value-based hashing/comparison; map literals & assoc promote to phm on collection keys; frequencies/group-by use phm base; set = is value-based. Also fixed set literals not evaluating elements and the REPL phm printer. Spec cases added. (commit pushed next)"}}
{"id":"int-885ca071","kind":"field_change","created_at":"2026-06-05T05:02:24.324962Z","actor":"Yogthos","issue_id":"jolt-e4p","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Won't-fix: backreferences and lookbehind are not expressible in a PEG engine (jolt regex compiles to Janet PEG); named groups are rare. Documented as unsupported in README's Regex section. Reopen if a concrete need arises."}}
{"id":"int-45c03ea2","kind":"field_change","created_at":"2026-06-05T05:23:54.397617Z","actor":"Yogthos","issue_id":"jolt-dd5","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Fixed: catch unwraps the :jolt/exception envelope so rethrow doesn't nest; var-set updates the current thread-binding frame (falls back to root). Spec cases restored."}}
{"id":"int-2acb82ed","kind":"field_change","created_at":"2026-06-05T13:05:03.712634Z","actor":"Yogthos","issue_id":"jolt-js6","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Ported clojure-test-suite as baseline-guarded integration battery; surfaced+fixed 2 evaluator macro bugs"}}
{"id":"int-2bd94166","kind":"field_change","created_at":"2026-06-05T13:18:36.785225Z","actor":"Yogthos","issue_id":"jolt-kxb","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"reduce-with-reduced steps lazy seqs incrementally; transducers short-circuit over infinite seqs"}}
{"id":"int-67ed276e","kind":"field_change","created_at":"2026-06-05T13:22:29.396671Z","actor":"Yogthos","issue_id":"jolt-dxx","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"merge follows Clojure (when some identity) (reduce conj ...) semantics; nil/empty/conj-entry cases fixed"}}
{"id":"int-e6dcd4a3","kind":"field_change","created_at":"2026-06-05T13:29:37.738114Z","actor":"Yogthos","issue_id":"jolt-1uw","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Fixed real gaps: invokable transients, assoc! odd args, use-after-persistent! invalidation, pop!-empty. Bad-shape type strictness left as accepted lenient divergence."}}
{"id":"int-ede75de6","kind":"field_change","created_at":"2026-06-05T13:35:45.843368Z","actor":"Yogthos","issue_id":"jolt-fy8","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Added ##Inf/##NaN literals + infinite?/NaN?, fixed intval? for inf; pass 1719->1955. Integer-valued-float ambiguity is a fundamental Janet-number divergence, documented in README."}}

View file

@ -1,33 +0,0 @@
{"_type":"issue","id":"jolt-y29","title":"CRITICAL: map literals don't evaluate values — (let [x 5] {:a x}) =\u003e {:a x}; fixing it eagerly hard-crashes SCI bootstrap (protocol maps ref unloaded sci.impl.core-protocols/records/deftype)","status":"closed","priority":1,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T21:08:30Z","created_by":"Yogthos","updated_at":"2026-06-04T21:28:17Z","closed_at":"2026-06-04T21:28:17Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-lp5","title":"CRITICAL: vec/into over lazy-seq leaks PV struct; into {} builds int keys","status":"closed","priority":1,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T17:46:15Z","created_by":"Yogthos","updated_at":"2026-06-04T17:59:35Z","closed_at":"2026-06-04T17:59:35Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-nte","title":"Build phased Clojure conformance harness (extracted assertions)","status":"closed","priority":1,"issue_type":"task","owner":"yogthos@gmail.com","created_at":"2026-06-04T17:46:15Z","created_by":"Yogthos","updated_at":"2026-06-04T18:09:15Z","closed_at":"2026-06-04T18:09:15Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-tws","title":"CRITICAL: iterate arity bug","status":"closed","priority":1,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T17:46:14Z","created_by":"Yogthos","updated_at":"2026-06-04T18:06:01Z","closed_at":"2026-06-04T18:06:01Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-x8s","title":"CRITICAL: collections not callable as IFn (vector/map/set)","status":"closed","priority":1,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T17:46:14Z","created_by":"Yogthos","updated_at":"2026-06-04T17:50:54Z","closed_at":"2026-06-04T17:50:54Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-alz","title":"CRITICAL: self-referential lazy-seq/lazy-cat yields only literal prefix","status":"closed","priority":1,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T17:46:13Z","created_by":"Yogthos","updated_at":"2026-06-04T18:09:15Z","closed_at":"2026-06-04T18:09:15Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-wec","title":"CRITICAL: multi-collection map returns unrealized thunk","status":"closed","priority":1,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T17:46:12Z","created_by":"Yogthos","updated_at":"2026-06-04T18:06:02Z","closed_at":"2026-06-04T18:06:02Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-5i5","title":"core.async Phase 2: dynamic var binding conveyance","description":"Snapshot/restore the global binding-stack per fiber so dynamic var bindings don't interleave across concurrent go blocks (Clojure binding conveyance).","status":"closed","priority":2,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-05T18:55:08Z","created_by":"Yogthos","updated_at":"2026-06-05T19:22:50Z","closed_at":"2026-06-05T19:22:50Z","close_reason":"Binding stack moved to fiber-local dyn; go-spawn snapshots+installs for conveyance; concurrent isolation + inner shadowing verified (4 spec cases)","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-tkw","title":"core.async on Janet fibers — Phase 1: API layer","description":"Implement clojure.core.async API (chan/go/\u003c!/\u003e!/\u003c!!/\u003e!!/close!/alts!/timeout/put!/take!/buffers) on top of Janet ev/ channels and fibers. go = run body in a fiber (stackful, no CPS macro needed).","status":"closed","priority":2,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-05T18:55:07Z","created_by":"Yogthos","updated_at":"2026-06-05T19:17:25Z","closed_at":"2026-06-05T19:17:25Z","close_reason":"Phase 1 complete: chan/go/\u003c!/\u003e!/close!/alts!/timeout/put!/take! on Janet fibers; two-channel design (values + done) gives drain-then-nil with no leaked fibers; 16 spec cases","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-lko","title":"clojure-test-suite: strictness — throw on malformed calls like Clojure","description":"Make jolt throw where Clojure throws (bad-shape conj!/assoc!, arithmetic on non-numbers, out-of-range indices, etc.) to satisfy the suite's ~292 p/thrown? assertions. Targeted input validation across affected fns; guard against regressing jolt's spec/conformance.","status":"closed","priority":2,"issue_type":"task","assignee":"Yogthos","owner":"yogthos@gmail.com","created_at":"2026-06-05T14:45:20Z","created_by":"Yogthos","updated_at":"2026-06-05T18:07:56Z","started_at":"2026-06-05T14:45:39Z","closed_at":"2026-06-05T18:07:56Z","close_reason":"Implemented Clojure-strict argument validation across ~30 fns; suite pass 3691-\u003e3898, p/thrown? bucket 292-\u003e~60 (remainder is platform: int 32-bit range, subs Unicode, min-key NaN, subvec floats, map-entry-as-2-vector)","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-kxb","title":"clojure-test-suite: transducers don't short-circuit over infinite seqs (hangs)","description":"(into [] (take 5) (range)) and similar transducer-over-infinite forms hang jolt's eager evaluator (no reduced/early-termination). 7 suite files time out. Make transducing honor reduced.","status":"closed","priority":2,"issue_type":"bug","assignee":"Yogthos","owner":"yogthos@gmail.com","created_at":"2026-06-05T13:05:18Z","created_by":"Yogthos","updated_at":"2026-06-05T13:18:37Z","started_at":"2026-06-05T13:09:59Z","closed_at":"2026-06-05T13:18:37Z","close_reason":"reduce-with-reduced steps lazy seqs incrementally; transducers short-circuit over infinite seqs","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-js6","title":"Port clojure-test-suite as integration battery","description":"Build a minimal clojure.test + portability shim so Jolt can load the external ~/src/clojure-test-suite (240 per-fn .cljc files in clojure.test format). Add a baseline-guarded integration runner following the jank-conformance pattern (skip if absent).","status":"closed","priority":2,"issue_type":"task","assignee":"Yogthos","owner":"yogthos@gmail.com","created_at":"2026-06-05T12:22:01Z","created_by":"Yogthos","updated_at":"2026-06-05T13:05:04Z","started_at":"2026-06-05T12:22:14Z","closed_at":"2026-06-05T13:05:04Z","close_reason":"Ported clojure-test-suite as baseline-guarded integration battery; surfaced+fixed 2 evaluator macro bugs","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-i3g","title":"Clear final 2 SCI bootstrap forms (Var/IVar collision + clojure.repl/template)","description":"namespaces.cljc forms 126/127 fail: (126) lang_stubs IVar collides with real vars.cljc IVar so unbind dispatch misses on sci.lang.Var; (127) clojure.repl + clojure.template namespaces missing. Fix: trim bootstrap stubs to let real modules own canonical protocols/types; port clojure.repl + clojure.template.","status":"closed","priority":2,"issue_type":"task","owner":"yogthos@gmail.com","created_at":"2026-06-05T03:21:40Z","created_by":"Yogthos","updated_at":"2026-06-05T03:35:43Z","closed_at":"2026-06-05T03:35:43Z","close_reason":"Done — SCI bootstrap now loads 422/422 with 0 failures. Fixed deftype protocol-method registration, with-meta on functions, select-keys over vectors, require :as+:refer, defmethod-on-fn; added clojure.set/join and host-module stubs. test-load-sci asserts 0 failures.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-ns4","title":"Persistent collections + build-time mutable/immutable toggle","description":"Add JOLT_MUTABLE build flag (config.janet). Fix list-mutation bug (conj mutated original). Round 2: structural-sharing persistent vector (32-way trie) hooked into all core ops. Round 3: persistent lists / HAMT maps.","notes":"R1 (build flag + list mutation fix) and R2 (structural-sharing persistent vectors + mutable toggle) done \u0026 pushed (1eb2843). Immutable: conformance 206/206, features 71/71, jank 119. R3 (persistent linked lists) pending user decision: lists are immutable Janet arrays — O(1) sharing cons, O(n) conj.","status":"closed","priority":2,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T22:15:39Z","created_by":"Yogthos","updated_at":"2026-06-04T23:20:46Z","closed_at":"2026-06-04T23:20:46Z","close_reason":"Done across 3 rounds (pushed a0c9696): build-time mutable/immutable toggle, structural-sharing persistent vectors (32-way trie), and persistent O(1)-prepend linked lists. Plus bit-clear/get-method and a batch of missing core fns. conformance 206/206, features 78/78, jank 120.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-gxr","title":"HIGH: aliased namespace calls (require :as) don't resolve (s/join)","status":"closed","priority":2,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:58Z","created_by":"Yogthos","updated_at":"2026-06-04T18:45:52Z","closed_at":"2026-06-04T18:45:52Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-4z9","title":"HIGH: dispatch — multimethod :default, protocol-on-record, extend-protocol","status":"closed","priority":2,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:57Z","created_by":"Yogthos","updated_at":"2026-06-04T18:40:43Z","closed_at":"2026-06-04T18:40:43Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-40n","title":"HIGH: update/update-in/assoc-in fail on map literals (struct)","status":"closed","priority":2,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:56Z","created_by":"Yogthos","updated_at":"2026-06-04T18:40:42Z","closed_at":"2026-06-04T18:40:42Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-ytt","title":"HIGH: str semantics — (str nil)='nil' should be '', (str :b)='b' should be ':b'","status":"closed","priority":2,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:56Z","created_by":"Yogthos","updated_at":"2026-06-04T18:33:45Z","closed_at":"2026-06-04T18:33:45Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-9sb","title":"HIGH: destructuring gaps (nested seq, :strs, nested map, fn-param)","status":"closed","priority":2,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:55Z","created_by":"Yogthos","updated_at":"2026-06-04T18:31:24Z","closed_at":"2026-06-04T18:31:24Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-x3v","title":"core.async Phase 3: channel transducers","description":"Support (chan n xform) — apply a transducer to values flowing through a channel, plus dropping/sliding buffers.","status":"open","priority":3,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-05T18:55:09Z","created_by":"Yogthos","updated_at":"2026-06-05T18:55:09Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-dxx","title":"clojure-test-suite: merge nil/empty + collection-key semantics","description":"merge.cljc has 18 fail / 11 err — highest in suite. Investigate nil/empty-map merge return values and collection-key behavior.","status":"closed","priority":3,"issue_type":"bug","assignee":"Yogthos","owner":"yogthos@gmail.com","created_at":"2026-06-05T13:05:17Z","created_by":"Yogthos","updated_at":"2026-06-05T13:22:29Z","started_at":"2026-06-05T13:18:50Z","closed_at":"2026-06-05T13:22:29Z","close_reason":"merge follows Clojure (when some identity) (reduce conj ...) semantics; nil/empty/conj-entry cases fixed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-1uw","title":"clojure-test-suite: transient strictness gaps","description":"Transient ops (conj!/assoc!/disj!/pop!) don't throw on misuse (bad shapes, use-after-persistent!) where Clojure does. Surfaced by conj_bang/assoc_bang/pop_bang/persistent_bang/transient suite files (~50 fails). Lenient behavior; decide whether to enforce.","status":"closed","priority":3,"issue_type":"bug","assignee":"Yogthos","owner":"yogthos@gmail.com","created_at":"2026-06-05T13:05:16Z","created_by":"Yogthos","updated_at":"2026-06-05T13:29:38Z","started_at":"2026-06-05T13:22:51Z","closed_at":"2026-06-05T13:29:38Z","close_reason":"Fixed real gaps: invokable transients, assoc! odd args, use-after-persistent! invalidation, pop!-empty. Bad-shape type strictness left as accepted lenient divergence.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-do7","title":"phm-typed maps as set elements / map keys hash by identity","description":"A map produced via hash-map/assoc (a Janet table/phm) used as a set element or map key hashes by identity, so #{{:a 1}} (struct elem) != #{(hash-map :a 1)} (phm elem) and such elements aren't retrievable by value. Map literals (structs) work. Needs value-based hashing for phm keys in PHM/PHS. Edge case; spec covers literal-map cases.","status":"closed","priority":3,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-05T04:07:50Z","created_by":"Yogthos","updated_at":"2026-06-05T05:02:01Z","closed_at":"2026-06-05T05:02:01Z","close_reason":"Fixed: PHM/PHS canonicalize collection keys for value-based hashing/comparison; map literals \u0026 assoc promote to phm on collection keys; frequencies/group-by use phm base; set = is value-based. Also fixed set literals not evaluating elements and the REPL phm printer. Spec cases added. (commit pushed next)","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-7dy","title":"MED: compiler path lacks IFn dispatch (collections-as-fn) — only interpreter fixed","status":"closed","priority":3,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:10:00Z","created_by":"Yogthos","updated_at":"2026-06-04T19:56:36Z","closed_at":"2026-06-04T19:56:36Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-90c","title":"MED: filter/take-while not lazy — infinite-seq (take N (filter p (range))) loops","status":"closed","priority":3,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:10:00Z","created_by":"Yogthos","updated_at":"2026-06-04T18:56:26Z","closed_at":"2026-06-04T18:56:26Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-7n5","title":"MED: REPL display — def/defn should print #'ns/name; lazy-seq printer realizes only head ((0 \u003cfunction\u003e))","status":"closed","priority":3,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:59Z","created_by":"Yogthos","updated_at":"2026-06-04T18:55:11Z","closed_at":"2026-06-04T18:55:11Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-h0n","title":"MED: missing core fns — letfn fnil trampoline doseq cycle partition-all reductions dedupe keep-indexed map-indexed transduce reduce-kv assoc-in peek subvec read-string format","status":"closed","priority":3,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:58Z","created_by":"Yogthos","updated_at":"2026-06-04T18:57:26Z","closed_at":"2026-06-04T18:57:26Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-fy8","title":"clojure-test-suite: float?/double?/number-predicate divergences","description":"jolt doesn't distinguish float vs double (all Janet numbers); float_qmark/double_qmark and str formatting of numbers diverge from Clojure. Documented divergence; track for completeness.","status":"closed","priority":4,"issue_type":"task","assignee":"Yogthos","owner":"yogthos@gmail.com","created_at":"2026-06-05T13:05:19Z","created_by":"Yogthos","updated_at":"2026-06-05T13:35:46Z","started_at":"2026-06-05T13:30:05Z","closed_at":"2026-06-05T13:35:46Z","close_reason":"Added ##Inf/##NaN literals + infinite?/NaN?, fixed intval? for inf; pass 1719-\u003e1955. Integer-valued-float ambiguity is a fundamental Janet-number divergence, documented in README.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-dd5","title":"throw of a caught ex-info rethrows wrapped; var-set on dynamic var in binding no-ops","description":"Edges found via spec: (1) (catch :default e (throw e)) re-wraps the ex-info so the outer catch's (ex-message e) is nil. (2) (var-set #'*v* x) inside (binding [*v* ...] ...) doesn't update the thread-binding. Both rare; core try/catch/ex-info and dynamic binding work.","status":"closed","priority":4,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-05T05:11:04Z","created_by":"Yogthos","updated_at":"2026-06-05T05:23:54Z","closed_at":"2026-06-05T05:23:54Z","close_reason":"Fixed: catch unwraps the :jolt/exception envelope so rethrow doesn't nest; var-set updates the current thread-binding frame (falls back to root). Spec cases restored.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-e4p","title":"regex: lookbehind, backreferences (\\1), named groups (?\u003cn\u003e) unsupported (rare); engine is parse-\u003ePEG with backtracking","status":"closed","priority":4,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T20:23:39Z","created_by":"Yogthos","updated_at":"2026-06-05T05:02:24Z","closed_at":"2026-06-05T05:02:24Z","close_reason":"Won't-fix: backreferences and lookbehind are not expressible in a PEG engine (jolt regex compiles to Janet PEG); named groups are rare. Documented as unsupported in README's Regex section. Reopen if a concrete need arises.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-cn4","title":"regex engine is a common subset (PEG-backed); lookaround/backrefs/named-groups unsupported","status":"closed","priority":4,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T19:27:50Z","created_by":"Yogthos","updated_at":"2026-06-04T20:23:37Z","closed_at":"2026-06-04T20:23:37Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-4zg","title":"char type: chars represented as 1-char strings; (seq \"ab\") yields strings not \\a \\b — deferred design decision","status":"closed","priority":4,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T19:27:49Z","created_by":"Yogthos","updated_at":"2026-06-04T19:41:39Z","closed_at":"2026-06-04T19:41:39Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"jolt-l8f","title":"transduce + transducer arities (1-arg map/filter/take); niche, deferred","status":"closed","priority":4,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:57:27Z","created_by":"Yogthos","updated_at":"2026-06-04T19:48:04Z","closed_at":"2026-06-04T19:48:04Z","dependency_count":0,"dependent_count":0,"comment_count":0}

View file

@ -1,7 +0,0 @@
{
"database": "dolt",
"backend": "dolt",
"dolt_mode": "embedded",
"dolt_database": "jolt",
"project_id": "6ed023e4-ac48-44e7-bb48-4da10fc635d8"
}

View file

@ -1 +0,0 @@
["^ ","~$bucket-count",["^ ","~:row",4,"~:col",1,"~:name","^0","~:ns","~$jolt.lang.persistent-hash-map","~:top-ns","^5","~:type","~:pos-int"],"~$bucket-contains?",["^ ","~:fixed-arities",["~#set",[2]],"~:private",true,"^4","^5","^3","^9","^7","~:fn","^2",1,"^6","^5","^1",71],"~$phm-empty",["^ ","^1",128,"^2",1,"^:",["^;",[1]],"^3","^>","^4","^5","^6","^5","^7","^="],"~$bucket-entries",["^ ","^:",["^;",[1]],"^<",true,"^4","^5","^3","^?","^7","^=","^2",1,"^6","^5","^1",52],"~$bucket-keys",["^ ","^:",["^;",[1]],"^<",true,"^4","^5","^3","^@","^7","^=","^2",1,"^6","^5","^1",59],"~$phm-count",["^ ","^1",125,"^2",1,"^:",["^;",[1]],"^3","^A","^4","^5","^6","^5","^7","^="],"~$copy-buckets",["^ ","^:",["^;",[3]],"^<",true,"^4","^5","^3","^B","^7","^=","^2",1,"^6","^5","^1",88],"~$map?",["^ ","^1",170,"^2",1,"^:",["^;",[1]],"^3","^C","^4","^5","^6","^5","^7","^="],"~$phm-conj",["^ ","^1",167,"^2",1,"^:",["^;",[2]],"^3","^D","^4","^5","^6","^5","^7","^="],"~$phm-dissoc",["^ ","^1",108,"^2",1,"^:",["^;",[2]],"^3","^E","^4","^5","^6","^5","^7","^="],"~$phm-seq",["^ ","^1",131,"^2",1,"^:",["^;",[1]],"^3","^F","^4","^5","^6","^5","^7","^="],"~$bucket-dissoc",["^ ","^:",["^;",[2]],"^<",true,"^4","^5","^3","^G","^7","^=","^2",1,"^6","^5","^1",37],"~$PersistentHashMap",["^ ","^1",6,"^2",1,"^3","^H","^4","^5","^6","^5","~:class",true],"~$phm-assoc",["^ ","^1",97,"^2",1,"^:",["^;",[3]],"^3","^J","^4","^5","^6","^5","^7","^="],"~$phm-from-pairs",["^ ","^:",["^;",[1]],"^<",true,"^4","^5","^3","^K","^7","^=","^2",1,"^6","^5","^1",158],"~$->PersistentHashMap",["^ ","^1",6,"^2",1,"^:",["^;",[3]],"^3","^L","^4","^5","^6","^5"],"~:filename","/Users/yogthos/src/jolt/src/jolt/clojure/lang/persistent_hash_map.clj","~$bucket-vals",["^ ","^:",["^;",[1]],"^<",true,"^4","^5","^3","^N","^7","^=","^2",1,"^6","^5","^1",65],"~$hash-key",["^ ","^:",["^;",[1]],"^<",true,"^4","^5","^3","^O","^7","^=","^2",1,"^6","^5","~:arities",["^ ","~i1",["^ ","~:ret",["^;",["~:number","~:nat-int"]],"~:arglist-str","[k]"]],"^1",10],"~$phm-get",["^ ","^1",79,"^2",1,"^:",["^;",[3,2]],"^3","^U","^4","^5","^6","^5","^7","^="],"~$phm-contains?",["^ ","^1",121,"^2",1,"^:",["^;",[2]],"^3","^V","^4","^5","^6","^5","^P",["^ ","~i2",["^ ","^Q",["^;",["~:boolean"]],"^T","[m k]"]],"^7","^="],"~$hash-map",["^ ","^1",164,"^2",1,"~:varargs-min-arity",0,"^3","^X","^4","^5","^6","^5","^7","^="],"~$phm-keys",["^ ","^1",140,"^2",1,"^:",["^;",[1]],"^3","^Z","^4","^5","^6","^5","^7","^="],"~$bucket-find",["^ ","^:",["^;",[2]],"^<",true,"^4","^5","^3","^[","^7","^=","^2",1,"^6","^5","^1",13],"~$phm-vals",["^ ","^1",149,"^2",1,"^:",["^;",[1]],"^3","^10","^4","^5","^6","^5","^7","^="],"~$bucket-assoc",["^ ","^:",["^;",[3]],"^<",true,"^4","^5","^3","^11","^7","^=","^2",1,"^6","^5","^1",21],"~$EMPTY-PHM",["^ ","^1",8,"^2",1,"^3","^12","^4","^5","^6","^5"]]

File diff suppressed because one or more lines are too long

3
.gitignore vendored
View file

@ -9,3 +9,6 @@ test/_*.janet
.dolt/
*.db
.beads-credential-key
# Beads issue tracker (local dev tooling)
.beads/

View file

@ -1,96 +0,0 @@
# Agent Instructions
This project uses **bd** (beads) for issue tracking. Run `bd prime` for full workflow context.
> **Architecture in one line:** Issues live in a local Dolt database
> (`.beads/dolt/`); cross-machine sync uses `bd dolt push/pull` (a
> git-compatible protocol), stored under `refs/dolt/data` on your git
> remote — separate from `refs/heads/*` where your code lives.
> `.beads/issues.jsonl` is a passive export, not the wire protocol.
>
> See [SYNC_CONCEPTS.md](https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md)
> for the one-screen overview and anti-patterns (don't treat JSONL as the
> source of truth; don't `bd import` during normal operation; don't
> reach for third-party Dolt hosting before trying the default).
## Quick Reference
```bash
bd ready # Find available work
bd show <id> # View issue details
bd update <id> --claim # Claim work atomically
bd close <id> # Complete work
bd dolt push # Push beads data to remote
```
## Non-Interactive Shell Commands
**ALWAYS use non-interactive flags** with file operations to avoid hanging on confirmation prompts.
Shell commands like `cp`, `mv`, and `rm` may be aliased to include `-i` (interactive) mode on some systems, causing the agent to hang indefinitely waiting for y/n input.
**Use these forms instead:**
```bash
# Force overwrite without prompting
cp -f source dest # NOT: cp source dest
mv -f source dest # NOT: mv source dest
rm -f file # NOT: rm file
# For recursive operations
rm -rf directory # NOT: rm -r directory
cp -rf source dest # NOT: cp -r source dest
```
**Other commands that may prompt:**
- `scp` - use `-o BatchMode=yes` for non-interactive
- `ssh` - use `-o BatchMode=yes` to fail instead of prompting
- `apt-get` - use `-y` flag
- `brew` - use `HOMEBREW_NO_AUTO_UPDATE=1` env var
<!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:7510c1e2 -->
## Beads Issue Tracker
This project uses **bd (beads)** for issue tracking. Run `bd prime` to see full workflow context and commands.
### Quick Reference
```bash
bd ready # Find available work
bd show <id> # View issue details
bd update <id> --claim # Claim work
bd close <id> # Complete work
```
### Rules
- Use `bd` for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists
- Run `bd prime` for detailed command reference and session close protocol
- Use `bd remember` for persistent knowledge — do NOT use MEMORY.md files
**Architecture in one line:** issues live in a local Dolt DB; sync uses `refs/dolt/data` on your git remote; `.beads/issues.jsonl` is a passive export. See https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md for details and anti-patterns.
## Session Completion
**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds.
**MANDATORY WORKFLOW:**
1. **File issues for remaining work** - Create issues for anything that needs follow-up
2. **Run quality gates** (if code changed) - Tests, linters, builds
3. **Update issue status** - Close finished work, update in-progress items
4. **PUSH TO REMOTE** - This is MANDATORY:
```bash
git pull --rebase
git push
git status # MUST show "up to date with origin"
```
5. **Clean up** - Clear stashes, prune remote branches
6. **Verify** - All changes committed AND pushed
7. **Hand off** - Provide context for next session
**CRITICAL RULES:**
- Work is NOT complete until `git push` succeeds
- NEVER stop before pushing - that leaves work stranded locally
- NEVER say "ready to push when you are" - YOU must push
- If push fails, resolve and retry until it succeeds
<!-- END BEADS INTEGRATION -->

View file

@ -1,70 +0,0 @@
# Project Instructions for AI Agents
This file provides instructions and context for AI coding agents working on this project.
<!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:7510c1e2 -->
## Beads Issue Tracker
This project uses **bd (beads)** for issue tracking. Run `bd prime` to see full workflow context and commands.
### Quick Reference
```bash
bd ready # Find available work
bd show <id> # View issue details
bd update <id> --claim # Claim work
bd close <id> # Complete work
```
### Rules
- Use `bd` for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists
- Run `bd prime` for detailed command reference and session close protocol
- Use `bd remember` for persistent knowledge — do NOT use MEMORY.md files
**Architecture in one line:** issues live in a local Dolt DB; sync uses `refs/dolt/data` on your git remote; `.beads/issues.jsonl` is a passive export. See https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md for details and anti-patterns.
## Session Completion
**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds.
**MANDATORY WORKFLOW:**
1. **File issues for remaining work** - Create issues for anything that needs follow-up
2. **Run quality gates** (if code changed) - Tests, linters, builds
3. **Update issue status** - Close finished work, update in-progress items
4. **PUSH TO REMOTE** - This is MANDATORY:
```bash
git pull --rebase
git push
git status # MUST show "up to date with origin"
```
5. **Clean up** - Clear stashes, prune remote branches
6. **Verify** - All changes committed AND pushed
7. **Hand off** - Provide context for next session
**CRITICAL RULES:**
- Work is NOT complete until `git push` succeeds
- NEVER stop before pushing - that leaves work stranded locally
- NEVER say "ready to push when you are" - YOU must push
- If push fails, resolve and retry until it succeeds
<!-- END BEADS INTEGRATION -->
## Build & Test
_Add your build and test commands here_
```bash
# Example:
# npm install
# npm test
```
## Architecture Overview
_Add a brief overview of your project architecture_
## Conventions & Patterns
_Add your project-specific conventions here_

170
PLAN.md
View file

@ -1,170 +0,0 @@
# Jolt — Complete Implementation Plan
## Architecture Goal
Minimal Janet bootstrap → SCI/CLJS Clojure source runs on Jolt.
Three layers:
1. **Janet runtime**: types.janet, reader.janet, evaluator.janet, compiler.janet (~4,200 lines)
2. **Clojure core**: core.janet (~1,400 lines), phm.janet (~200 lines)
3. **Clojure source** (.clj files loadable at runtime): stdlib modules, SCI
## Current State
Tests are organized in three layers (see the README "Test" section):
`test/spec/` (the black-box contract), `test/integration/` (cross-cutting and
external-suite regression batteries), and `test/unit/` (white-box component
tests). `jpm test` is green.
| Metric | Value |
|--------|-------|
| Spec contract | ~1,000 cases across 24 `test/spec/` files |
| Integration batteries | 12 (conformance, SCI bootstrap/runtime, jank, clojure-test-suite, compile-mode, API, systematic-coverage) |
| Unit tests | 9 files (reader, evaluator, types, collections, regex, compiler) |
| Clojure conformance | 218/218 |
| clojure-test-suite | ~3,920 assertions pass (remainder are documented platform/design divergences) |
| Source lines | ~8,600 (`src/jolt/*.janet`; core.janet ~4,000) |
| SCI source files loading | 9/9 |
| Reader literals | full numeric syntax (`N`/`M`/ratio/radix/exponent/`##Inf`); see `doc/grammar.ebnf` |
## Phase Plan
### Phase 0-10: Foundation ✓
| Phase | Description | Status |
|-------|-------------|--------|
| 0 | `defn` bug fix, bare symbol resolution | ✓ |
| 1 | Var/Namespace system, ns form extensions | ✓ |
| 2 | PersistentHashMap implementation | ✓ |
| 3 | Var system: var-get/set/?, alter-var-root, intern, binding | ✓ |
| 4 | deftype/defrecord completion | ✓ |
| 5 | Multimethods + Hierarchy | ✓ |
| 6 | Reader extensions: tagged literals, :jolt/tagged handler | ✓ |
| 7 | LazySeq + PersistentHashSet | ✓ |
| 8 | Protocol system: defprotocol, extend-type, extend-protocol, reify, satisfies? | ✓ |
| 9 | REPL fixes: buffer-based output, collection rendering, cond fix | ✓ |
| 10 | Standard Library: clojure.string, clojure.set, clojure.walk, clojure.zip, clojure.edn, clojure.java_io, jolt.interop, jolt.shell, jolt.http | ✓ |
### Phase 11: Fix Pre-existing Failures ✓
- `types.janet`: `ns?` now accepts both structs and tables
- `core.janet`: `comment` macro wired into core-bindings
- `sci/lang_stubs.clj`: minimal SCI type stubs for bootstrap
- `test-load-sci.janet`: load stubs before SCI source files
- **Result: SciVar fixed. 1 remaining (deftype with `#?@` — Phase 15)**
### Phase 12: Core Feature Completion ✓
- `apply` support in evaluator + compiler
- `str` handles nil correctly
- 6 CLJS test files created (~120 assertions)
- `#()` anonymous fn reader with `%`, `%1`, `%2` arg handling
### Phase 13: Protocol Completion ✓
- reify dispatch: protocol methods work on reified objects
- `#()` reader macro with gensym-based `%` arg handling
- IFn protocol support in default invocation arm
- clojure.walk loads and `keywordize-keys` works
- 4 test sections: reify dispatch, anon fn, extend-type, walk loading
### Phase 14: Extend CLJS Ported Tests ✓
- `cljs-port-2.janet` expanded: 10 sections (12-21), 35→60 assertions
- `cljs-port-5.janet` created: sections 22-24, destructuring, metadata, fn composition
- `pr-str` compiler fix: maps to new `core-pr-str` (not `core-str`)
- `every-pred` added to core.janet
- `var-dynamic?` and `with-meta` tests restored
### Phase 15: SCI Bootstrap ✓
- ✅ `sci.lang` namespace loads completely (all 10 forms, including Var, Type, Namespace deftypes)
- ✅ 9 SCI source files load without errors (impl/macros, impl/protocols, impl/types, impl/unrestrict, impl/vars, lang, impl/utils, impl/namespaces, core)
- ✅ `prefer-method`/`remove-method`/`remove-all-methods` promoted to special forms (fix: auto-deref gave functions to `get`/`put`)
- ✅ All 5 pre-existing test failures fixed:
- `cljs-port-1.janet``#{}` Janet comment issue replaced with count-based comparisons
- `cljs-port-2.janet``with-meta` added as core binding with table/setproto
- `cljs-port-3b.janet``load-string` multi-form loader for string.clj and set.clj
- `cljs-port-5.janet``var-dynamic?` core binding + `^:dynamic` def handler fix
- `phase5-test.janet``remove-method` special form fixed to eval-form first arg
- New core infrastructure: `core-with-meta` (supports structs/tables via prototype), `core-var-dynamic?`, `load-string` API, `^:dynamic` propagation in `def` handler
- `core-str` now returns `"nil"` for nil (Clojure-compatible)
- `core-meta` checks `:jolt/meta` for with-meta'd values
- Test suite: **317/317 pass, 0 fail**
### Phase 16: Remaining Core Library + Tests ✅
- ✅ `eval` implemented as special form (interpreter + compiler), tested in `eval-test.janet` (4 assertions)
- ✅ `&` rest destructuring, `seq` nil handling, `vector`/`list` equality verified working
- ✅ `syntax-quote` confirmed working with unquote
- ✅ 5 new CLJS ported test files (cljs-port-6 through -10): anon fns, symbols/keywords/lists, destructuring, range/concat/partition/sort, seq predicates/complement, when/if-let/doto
- ✅ 16 total CLJS ported test files, 440 assertions across 31 test files
- ✅ 317/317 tests pass, 0 failing scripts
### Phase 19: Clojure Conformance Hardening ✅
Added `test/conformance.janet` — a harness that evaluates `(= expected actual)`
inside jolt (using jolt's own `=`, i.e. real Clojure semantics), seeded from
`~/src/clojure/test`. Drove fixes for a large class of real-Clojure idioms the
bespoke `.janet` suite never exercised. **80/80 conformance, 46/46 legacy suite,
0 SCI-load failures.**
CRITICAL (core semantics):
- Collections as IFn (`([v] i)`, `({m} k)`, `(#{s} x)`) via unified `jolt-invoke`
- Unified vector representation on Janet tuples (PersistentVector was broken/disconnected)
- `=`/`reduce`/`vec`/`into` now realize lazy-seqs; `into {}`/`into ()` fixed
- Lazy `iterate`/`range`(infinite)/single-coll `map` (over lazy input)
- Truly lazy `concat` → self-referential `lazy-cat`/`lazy-seq` work (`fib-seq`)
HIGH:
- Unified recursive destructuring (nested seq/map, `:strs`/`:syms`/`:or`/`:as`, fn-params)
- `defn` docstring/attr-map handling (docstring'd fns were silently param-less)
- Clojure `str`/`pr-str` (nil→"", keywords/symbols, collections render readably)
- `update`/`update-in`/`assoc-in` on immutable maps; multimethod `:default` key dispatch
- defrecord inline protocol methods with field scope
- `require` loads stdlib namespaces from disk + aliased-ns resolution (`s/join`)
MED:
- New: peek/pop/subvec/reduce-kv/cycle/partition-all/reductions/dedupe/
keep-indexed/map-indexed/trampoline/format/read-string/fnil + letfn/doseq macros
- Recursive `jolt-equal?` (nested sequential + order-independent map equality)
- Lazy `filter`/`take-while`/`remove` over lazy input
- REPL: lazy-seq printer walks full chain (capped); `def`/`defn` print `#'ns/name`
**Gap-closing batch** (conformance grew to 157 cases): full atoms; typed
volatiles + delays (deref/force/realized?); quot/rem/mod sign semantics; a regex
subsystem (`src/jolt/regex.janet`, regex→PEG, `#"..."` literals, re-find/matches/
seq, string split/replace); sorted-map/sorted-set; `Math/*` statics; ex-info/
ex-data/ex-message; namespaced keywords; ~40 added core fns (split-at, take-nth,
butlast, filterv/mapv, reduced, min/max-key, find, some-fn, sequential?/ifn?/…)
plus defonce/macroexpand-1/letfn/doseq; and fixes to doto, assoc/update-on-vector,
frequencies, coll?, sort, partition.
**Feature batch** (conformance now 184): proper **char type** (`\a` reads to a
char value, char?/char/int/str, string seq/first/nth yield chars, `\a` printing);
**transducers** (map/filter/take/… no-coll arity returns a transducer; transduce/
into-xform/sequence/eduction/reduced; reduce honors reduced); **compiler-path
IFn dispatch** (jolt-call makes collections callable in `:compile?` mode; compiled
set/char literals); and a **multi-line REPL** (accumulates until the form is
balanced).
Deferred: full regex (lookaround/backrefs — the PEG-backed engine covers the
common subset). STM (refs/agents/dosync) intentionally skipped.
### Phase 17: Optimization
- Compiler improvements: inline small core functions
- PersistentHashMap dynamic bucket growth
- Benchmarks
### Phase 18: Standard Library Completion
- Complete EDN reader/writer
- Complete java.io wrappers
- clojure.zip tests
## Implementation Order
1. ✅ Phases 0-16 (completed)
2. Phase 17 (optimization: compiler inlining, PHM bucket growth, benchmarks)
3. Phase 18 (stdlib: EDN reader/writer, java.io wrappers, clojure.zip tests)

View file

@ -1,241 +0,0 @@
;; ============================================================
;; Comprehensive Clojure Features Demo
;; ============================================================
;; 1. Destructuring (sequential & associative)
(defn destructure-demo []
(println "\n--- Destructuring ---")
;; Sequential destructuring
(let [[a b c] [10 20 30]]
(println (str "Seq destructure: a=" a ", b=" b ", c=" c)))
;; Associative destructuring with defaults
(let [{:keys [name age city] :or {city "Unknown"}} {:name "Alice" :age 30}]
(println (str "Map destructure: name=" name ", age=" age ", city=" city)))
;; Nested destructuring
(let [{[x y] :coords} {:coords [1.0 2.5]}]
(println (str "Nested destructure: x=" x ", y=" y))))
;; 2. Atoms state management
(defn atom-demo []
(println "\n--- Atoms ---")
(def counter (atom 0))
;; swap! (function-based update)
(swap! counter inc)
(println (str "After swap! inc: " @counter))
;; reset! (set new value)
(reset! counter 100)
(println (str "After reset! to 100: " @counter))
;; compare-and-set! (CAS)
(let [old @counter]
(if (compare-and-set! counter old (+ old 5))
(println (str "CAS success: " @counter))
(println "CAS failed")))
;; Using atom with swap! and multiple updates
(swap! counter #(-> % (* 2) (+ 3)))
(println (str "After thread-first swap!: " @counter)))
;; 3. Lazy sequences infinite & transformed
(defn lazy-seq-demo []
(println "\n--- Lazy Sequences ---")
;; Infinite lazy seq: natural numbers
(def naturals (iterate inc 0))
;; Take first 10 even numbers using filter (lazy)
(def first-ten-evens (take 10 (filter even? naturals)))
(println (str "First 10 evens: " (pr-str first-ten-evens)))
;; Map and take-while (lazy)
(def squares-under-50
(take-while #(< % 50) (map #(* % %) (range))))
(println (str "Squares under 50: " (pr-str squares-under-50)))
;; Cycle and interpose (lazy)
(def repeated-pattern (take 10 (cycle [:a :b :c])))
(println (str "Cycled pattern: " (pr-str repeated-pattern)))
;; Lazy seq from recursion (not fully lazy, but demonstrates lazy cons)
(defn my-iterate [f x]
(lazy-seq (cons x (my-iterate f (f x)))))
(def powers-of-two (take 8 (my-iterate #(* 2 %) 1)))
(println (str "Powers of two: " (pr-str powers-of-two))))
;; 4. Transducers composable transformations
(defn transducer-demo []
(println "\n--- Transducers ---")
;; Compose mapping and filtering as a transducer
(def xf (comp (map inc) (filter odd?)))
;; Apply to a collection (into)
(def result (into [] xf (range 10)))
(println (str "Transducer result: " (pr-str result)))
;; Use with sequence (sequence)
(def seq-result (sequence xf (range 10)))
(println (str "Transducer seq: " (pr-str seq-result))))
;; 5. Protocols & Records polymorphism
(defprotocol Shape
(area [this])
(description [this]))
(defrecord Circle [radius]
Shape
(area [_] (* Math/PI radius radius))
(description [_] (str "Circle with radius " radius)))
(defrecord Rectangle [width height]
Shape
(area [_] (* width height))
(description [_] (str "Rectangle " width "x" height)))
(defn protocol-demo []
(println "\n--- Protocols & Records ---")
(def c (->Circle 5))
(def r (->Rectangle 3 4))
(println (str (description c) " -> area: " (area c)))
(println (str (description r) " -> area: " (area r))))
;; 6. Multimethods dispatch on arbitrary values
(defmulti shape-type :kind)
(defmethod shape-type :circle [_] "round")
(defmethod shape-type :rectangle [_] "angular")
(defmethod shape-type :default [_] "unknown")
(defn multimethod-demo []
(println "\n--- Multimethods ---")
(def s1 {:kind :circle :radius 5})
(def s2 {:kind :rectangle :width 3 :height 4})
(def s3 {:kind :triangle})
(println (str "Circle type: " (shape-type s1)))
(println (str "Rectangle type: " (shape-type s2)))
(println (str "Triangle type: " (shape-type s3))))
;; 7. Macros compile-time code generation
(defmacro log-call [expr]
`(let [result# ~expr]
(println (str "Called: " (pr-str '~expr) " -> " result#))
result#))
(defn macro-demo []
(println "\n--- Macros ---")
(log-call (* 2 3))
(log-call (map inc [1 2 3]))
(log-call (reduce + (range 1 6))))
;; 8. Recursion linear and tail-recursive
(defn recursion-demo []
(println "\n--- Recursion ---")
;; Linear recursion: factorial
(defn fact [n]
(if (<= n 1) 1 (* n (fact (dec n)))))
(println (str "Factorial 5: " (fact 5)))
;; Tail recursion with recur
(defn fact-tail [n]
(loop [i n acc 1]
(if (zero? i) acc
(recur (dec i) (* acc i)))))
(println (str "Tail-factorial 5: " (fact-tail 5)))
;; Mutual recursion with trampoline
(declare even?)
(defn odd? [n]
(if (zero? n) false (even? (dec n))))
(defn even? [n]
(if (zero? n) true (odd? (dec n))))
(println (str "Is 6 even? " (even? 6))))
;; 9. Higher-order functions partial, comp, juxt
(defn hof-demo []
(println "\n--- Higher-Order Functions ---")
(def add5 (partial + 5))
(println (str "Partial (+5) applied to 10: " (add5 10)))
(def inc-and-double (comp #(* 2 %) inc))
(println (str "Comp (double∘inc) on 3: " (inc-and-double 3)))
(def stats (juxt identity inc dec))
(println (str "Juxt on 5: " (stats 5))))
;; 10. Threading macros (-> and ->>)
(defn threading-demo []
(println "\n--- Threading Macros ---")
(def result
(->> (range 20)
(filter odd?)
(map #(* % 3))
(take 5)
(reduce +)))
(println (str "Threaded pipeline result: " result))
(def threaded-sqrt
(-> 25 Math/sqrt long (+ 10)))
(println (str "Thread-first sqrt: " threaded-sqrt)))
;; 11. Exception handling with try/catch/finally
(defn exception-demo []
(println "\n--- Exception Handling ---")
(try
(throw (ex-info "something broke" {:code 42}))
(catch :default e
(println (str "Caught: " (ex-message e) " " (pr-str (ex-data e)))))
(finally
(println "Finally block executed."))))
;; 12. Clojure's sequence comprehension: for (list comprehension)
(defn for-demo []
(println "\n--- For Comprehension ---")
(def combos
(for [x (range 3)
y (range 3)
:when (not= x y)]
[x y]))
(println (str "Combinations (x!=y): " (pr-str combos))))
;; 13. Clojure's core.async? Not pure Clojure, skip.
;; 14. Janet host interop — Jolt runs on Janet, so host interop is Janet-style:
;; `.` dispatches on a table/struct (the receiver is passed as the first
;; arg), and Janet's standard library is reachable through jolt.interop.
(defn janet-interop-demo []
(println "\n--- Janet Interop ---")
;; Method-style call on a Janet table: self is passed as the first argument.
(def counter {:value 41
:describe (fn [self] (str "counter = " (:value self)))})
(println (str "Method call: " (. counter describe)))
;; Field access sugar: (.-k m) is (. m :k)
(println (str "Field access: " (.-value counter)))
;; Reach Janet's standard library through jolt.interop.
(require '[jolt.interop :as j])
(println (str "Janet type: " (j/janet-type [1 2 3])))
(println (str "Table keys: " (pr-str (j/janet-table-keys {:a 1 :b 2})))))
;; ---------- Main entry point ----------
(defn -main []
(println "=== Clojure Features Demo ===")
(destructure-demo)
(atom-demo)
(lazy-seq-demo)
(transducer-demo)
(protocol-demo)
(multimethod-demo)
(macro-demo)
(recursion-demo)
(hof-demo)
(threading-demo)
(exception-demo)
(for-demo)
(janet-interop-demo)
(println "\n=== Demo Complete ==="))
;; Run if executed as script
(-main)

View file

@ -1,14 +0,0 @@
(def lines (string/split "\n" (slurp "src/jolt/core.janet")))
(def new-lines @[])
(each l lines
(array/push new-lines l)
(if (= l " new-val))")
(do
(array/push new-lines "")
(array/push new-lines "# Hierarchy (minimal stubs for sci bootstrap)")
(array/push new-lines "(defn core-derive [tag parent] nil)")
(array/push new-lines "(defn core-isa? ([child parent] false) ([h child parent] false))")
(array/push new-lines "(defn core-ancestors ([tag] #{}) ([h tag] #{}))")
(array/push new-lines "(defn core-descendants ([tag] #{}) ([h tag] #{}))"))))
(spit "src/jolt/core.janet" (string/join new-lines "\n"))
(print "done")

View file

@ -1,21 +0,0 @@
# Preprocess a cljc file: resolve #?(:clj ...) and #?@(:clj ...) reader conditionals
# at read time. Output a plain .clj file that Jolt can parse without reader conditionals.
(use ./src/jolt/reader)
(defn preprocess [filepath]
(def src (slurp filepath))
(var s src)
(var out @[])
(var count 0)
(while (> (length (string/trim s)) 0)
(def [form rest] (parse-next s))
(set s rest)
(++ count)
(if (nil? form)
nil
(array/push out (string form))))
(string/join out "\n"))
(def filepath (if (> (length (dyn :args @[])) 0) (in (dyn :args) 0) "/Users/yogthos/src/sci/src/sci/impl/utils.cljc"))
(print (preprocess filepath))

View file

@ -1,26 +0,0 @@
(use ./src/jolt/evaluator)
(use ./src/jolt/types)
(use ./src/jolt/reader)
(use ./src/jolt/api)
(def ctx (init))
# Test simple defprotocol expansion
(def proto-name {:jolt/type :symbol :ns nil :name "IBox"})
(def sig1 @[{:jolt/type :symbol :ns nil :name "setVal"} {:jolt/type :symbol :ns nil :name "_this"} {:jolt/type :symbol :ns nil :name "_v"}])
(def sig2 @[{:jolt/type :symbol :ns nil :name "getVal"} {:jolt/type :symbol :ns nil :name "_this"}])
# Call core-defprotocol directly
(use ./src/jolt/core)
(def expanded (core-defprotocol proto-name sig1 sig2))
(print "expanded: " (string expanded))
# Try to eval it
(def [ok err] (protect (eval-form ctx @{} expanded)))
(if ok
(do
(print "eval OK!")
(let [ns (ctx-find-ns ctx (ctx-current-ns ctx))]
(printf "IBox: %q\n" (ns-find ns "IBox"))
(printf "setVal: %q\n" (ns-find ns "setVal"))))
(printf "eval FAIL: %q\n" err))

View file

@ -1,42 +0,0 @@
(use ./src/jolt/evaluator)
(use ./src/jolt/types)
(use ./src/jolt/reader)
(use ./src/jolt/api)
(def ctx (init))
(defn load-all []
(each fp ["/Users/yogthos/src/sci/src/sci/impl/macros.cljc"
"/Users/yogthos/src/sci/src/sci/impl/protocols.cljc"
"/Users/yogthos/src/sci/src/sci/impl/utils.cljc"
"/Users/yogthos/src/sci/src/sci/impl/types.cljc"
"/Users/yogthos/src/sci/src/sci/impl/unrestrict.cljc"]
(def src (slurp fp))
(var s src)
(while (> (length (string/trim s)) 0)
(def [f r] (parse-next s)) (set s r)
(if (not (nil? f)) (protect (eval-form ctx @{} f)))))
(def vs (slurp "/Users/yogthos/src/sci/src/sci/impl/vars.cljc"))
(var s vs) (var c 0)
(while (and (> (length (string/trim s)) 0) (< c 27))
(def [f r] (parse-next s)) (set s r) (++ c)
(if (not (nil? f)) (protect (eval-form ctx @{} f))))
(each fp ["/Users/yogthos/src/sci/src/sci/lang.cljc"
"/Users/yogthos/src/sci/src/sci/core.cljc"]
(def src (slurp fp))
(var s src)
(while (> (length (string/trim s)) 0)
(def [f r] (parse-next s)) (set s r)
(if (not (nil? f)) (protect (eval-form ctx @{} f))))))
(load-all)
(print "=== Testing eval-string ===")
# Call sci.core/eval-string via our own eval
(def src "(do (require (quote [sci.core :as sci])) (sci/eval-string (sci/init) (str (+ 1 2))))")
(printf "eval: %s\n" src)
(try
(def result (eval-form ctx @{} (parse-string src)))
(printf "result: %q\n" result)
([err] (printf "FAIL: %q\n" err)))

View file

@ -1,13 +0,0 @@
(use ./src/jolt/reader)
(def src (slurp "/Users/yogthos/src/sci/src/sci/impl/utils.cljc"))
(var s src)
(for i 1 14
(let [p (parse-next s)]
(set s (in p 1))))
(def [form15 rest] (parse-next s))
(if (array? form15)
(printf "form15: (%s ...)" (get (first form15) :name))
(printf "form15: %q" form15))
(printf " => OK, rest: %d bytes" (length rest))

View file

@ -1,16 +0,0 @@
(use ./src/jolt/evaluator)
(use ./src/jolt/types)
(use ./src/jolt/reader)
(use ./src/jolt/api)
(def ctx (init))
(eval-form ctx @{} (parse-string "(ns sci.lang)"))
(eval-form ctx @{} (parse-string "(definterface IVar)"))
# Resolve sci.lang/IVar by evaluating as a qualified symbol
(def sym (parse-string "sci.lang/IVar"))
(printf "sym: %q\n" sym)
(try
(def v (eval-form ctx @{} sym))
(printf "resolved: %q\n" v)
([err] (printf "error: %q\n" err)))

View file

@ -1,44 +0,0 @@
(use ./src/jolt/evaluator)
(use ./src/jolt/types)
(use ./src/jolt/reader)
(use ./src/jolt/api)
(def ctx (init))
(defn load-file-quiet [ctx fp stop-at]
(def src (slurp fp))
(var s src)
(var c 0)
(var good 0)
(var bad 0)
(while (and (> (length (string/trim s)) 0) (or (not stop-at) (< c stop-at)))
(def pr (protect (parse-next s)))
(if (not (pr 0)) (do (printf "%s PARSE CRASH: %q\n" fp (pr 1)) (break)))
(let [[f r] (pr 1)]
(set s r)
(++ c)
(if (not (nil? f))
(let [pr2 (protect (eval-form ctx @{} f))]
(if (pr2 0) (++ good) (++ bad))))))
{:count c :good good :bad bad})
(each fp ["/Users/yogthos/src/sci/src/sci/impl/macros.cljc"
"/Users/yogthos/src/sci/src/sci/impl/protocols.cljc"
"/Users/yogthos/src/sci/src/sci/impl/utils.cljc"
"/Users/yogthos/src/sci/src/sci/impl/types.cljc"
"/Users/yogthos/src/sci/src/sci/impl/unrestrict.cljc"]
(load-file-quiet ctx fp nil))
(load-file-quiet ctx "/Users/yogthos/src/sci/src/sci/impl/vars.cljc" 27)
(load-file-quiet ctx "/Users/yogthos/src/sci/src/sci/lang.cljc" nil)
# Summary
(printf "\nSummary:\n")
(printf "ns: %s\n" (ctx-current-ns ctx))
# Try loading sci.core
(print "\nLoading sci.core...")
(def r (load-file-quiet ctx "/Users/yogthos/src/sci/src/sci/core.cljc" nil))
(printf "sci.core: %d forms, %d ok, %d fail\n" (r :count) (r :good) (r :bad))
(printf "ns: %s\n" (ctx-current-ns ctx))

View file

@ -1,18 +0,0 @@
(use ./src/jolt/reader)
(def s (slurp "/Users/yogthos/src/sci/src/sci/impl/utils.cljc"))
(var ss s)
(var i 0)
(while (< i 14)
(def [f r] (parse-next ss))
(set ss r)
(++ i))
(try
(def [form rest] (parse-next ss))
(if (array? form)
(let [h (first form)]
(if (and (struct? h) (= :symbol (h :jolt/type)))
(print (string "form: (" (h :name) "...)"))
(print (string "form: array head " (type h)))))
(print (string "form: " (type form) " " (string form))))
(print (string "OK rest: " (string/slice rest 0 80)))
([err] (print (string "FAIL: " err))))

View file

@ -1,6 +1,7 @@
# Regression tests mirroring clojure-features.clj, plus expanded coverage of
# related features. Each case asserts (= expected actual) evaluated inside Jolt
# (so comparisons use Jolt's own Clojure-semantics =). Run via `jpm test`.
# Feature regression tests: a broad sweep of Clojure features (destructuring,
# multimethods, protocols, laziness, …). Each case asserts (= expected actual)
# evaluated inside Jolt (so comparisons use Jolt's own Clojure-semantics =).
# Run via `jpm test`.
(use ../../src/jolt/api)
(var pass 0)
@ -143,11 +144,3 @@
(when (pos? (length fails))
(error (string (length fails) " feature regression(s)")))
(print "All feature tests passed!")
# Smoke test: the demo file itself loads and runs end-to-end without error.
(when (os/stat "clojure-features.clj")
(print "\n--- running clojure-features.clj (smoke test) ---")
(def res (protect (load-string (init) (slurp "clojure-features.clj"))))
(unless (= (res 0) true)
(error (string "clojure-features.clj failed to run: " (res 1))))
(print "--- clojure-features.clj ran cleanly ---"))