diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index d554047..e470c13 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -4,14 +4,19 @@ Copyright (c) Jonathan D.A. Jewell --> ## Machine-Readable Artefacts -The following files in `.machine_readable/` contain structured project metadata: - -- `STATE.scm` - Current project state and progress -- `META.scm` - Architecture decisions and development practices -- `ECOSYSTEM.scm` - Position in the ecosystem and related projects -- `AGENTIC.scm` - AI agent interaction patterns -- `NEUROSYM.scm` - Neurosymbolic integration config -- `PLAYBOOK.scm` - Operational runbook +The following files in `.machine_readable/6a2/` contain structured project metadata +(a2ml form; converted from the original `.scm` sources): + +- `6a2/STATE.a2ml` - Current project state and progress +- `6a2/META.a2ml` - Architecture decisions and development practices +- `6a2/ECOSYSTEM.a2ml` - Position in the ecosystem and related projects +- `6a2/AGENTIC.a2ml` - AI agent interaction patterns +- `6a2/NEUROSYM.a2ml` - Neurosymbolic integration config +- `6a2/PLAYBOOK.a2ml` - Operational runbook + +Also: `anchors/ANCHOR.a2ml` (canonical identity), `contractiles/{must,trust,dust,bust}/` +(contract files), `svc/k9/` (self-validation), `bot_directives/` (fleet/hypatia hooks), +and `0-AI-MANIFEST.a2ml` at repo root (AI entry point — read first). --- diff --git a/.clusterfuzzlite/Containerfile b/.clusterfuzzlite/Containerfile index 2ae30bb..9b874a9 100644 --- a/.clusterfuzzlite/Containerfile +++ b/.clusterfuzzlite/Containerfile @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: PMPL-1.0 +# SPDX-License-Identifier: MPL-2.0 FROM gcr.io/oss-fuzz-base/base-builder-rust@sha256:73c1d5648db54100639339d411a5d192cbc8bf413ee91e843a07cf6f0e319dc7 COPY . $SRC/wokelang diff --git a/.clusterfuzzlite/build.sh b/.clusterfuzzlite/build.sh index cd322d5..8217ffb 100755 --- a/.clusterfuzzlite/build.sh +++ b/.clusterfuzzlite/build.sh @@ -1,5 +1,5 @@ #!/bin/bash -eu -# SPDX-License-Identifier: PMPL-1.0 +# SPDX-License-Identifier: MPL-2.0 cd $SRC/wokelang cargo +nightly fuzz build for target in $(cargo +nightly fuzz list); do diff --git a/.github/workflows/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index c898637..a0ff24f 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -39,7 +39,7 @@ jobs: - name: Validate A2ML manifests if: steps.detect.outputs.count > 0 - uses: hyperpolymath/a2ml-validate-action@6bff6ec134fc977e86d25166a5c522ddea5c1e78 # main + uses: hyperpolymath/a2ml-validate-action@d95da62b50b26e7fef64aaba44e28ef92a56b476 # main (repinned 2026-06-12: 6bff6ec startup-failed the gate) with: path: '.' strict: 'false' @@ -88,7 +88,7 @@ jobs: - name: Validate K9 contracts if: steps.detect.outputs.k9_count > 0 - uses: hyperpolymath/k9-validate-action@2d96f43c538964b097d159ed3a56ba5b5ceca227 # main + uses: hyperpolymath/k9-validate-action@0cd8a79e579a3b5d93d4d5fe114d8f099d5549c9 # main (repinned 2026-06-12 to live HEAD) with: path: '.' strict: 'false' @@ -261,28 +261,30 @@ jobs: echo "has_manifest=true" >> "$GITHUB_OUTPUT" - # Validate TOML structure using Python 3.11+ tomllib + # Validate TOML structure using Python 3.11+ tomllib. + # NOTE: the -c body MUST stay indented inside this `run: |` block scalar. + # A prior flush-left version was invalid YAML and startup-failed the gate. python3 -c " -import tomllib, sys -with open('eclexiaiser.toml', 'rb') as f: - data = tomllib.load(f) -project = data.get('project', {}) -if not project.get('name', '').strip(): - print('ERROR: project.name is required', file=sys.stderr) - sys.exit(1) -functions = data.get('functions', []) -if not functions: - print('ERROR: at least one [[functions]] entry is required', file=sys.stderr) - sys.exit(1) -for fn in functions: - if not fn.get('name', '').strip(): - print('ERROR: function name cannot be empty', file=sys.stderr) - sys.exit(1) - if not fn.get('source', '').strip(): - print(f'ERROR: function {fn[\"name\"]} has no source path', file=sys.stderr) - sys.exit(1) -print(f'Valid: {project[\"name\"]} ({len(functions)} function(s))') -" || { + import tomllib, sys + with open('eclexiaiser.toml', 'rb') as f: + data = tomllib.load(f) + project = data.get('project', {}) + if not project.get('name', '').strip(): + print('ERROR: project.name is required', file=sys.stderr) + sys.exit(1) + functions = data.get('functions', []) + if not functions: + print('ERROR: at least one [[functions]] entry is required', file=sys.stderr) + sys.exit(1) + for fn in functions: + if not fn.get('name', '').strip(): + print('ERROR: function name cannot be empty', file=sys.stderr) + sys.exit(1) + if not fn.get('source', '').strip(): + print(f'ERROR: function {fn[\"name\"]} has no source path', file=sys.stderr) + sys.exit(1) + print(f'Valid: {project[\"name\"]} ({len(functions)} function(s))') + " || { echo "::error file=eclexiaiser.toml::Invalid eclexiaiser.toml — see step output for details" exit 1 } diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 950b68f..cdbffb0 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: PMPL-1.0 +# SPDX-License-Identifier: MPL-2.0 name: Scorecards supply-chain security on: branch_protection_rule: diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 8a89b98..0e3c1c8 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: PMPL-1.0 +# SPDX-License-Identifier: MPL-2.0 name: Secret Scanner on: pull_request: diff --git a/.machine_readable/6a2/ECOSYSTEM.a2ml b/.machine_readable/6a2/ECOSYSTEM.a2ml index 256256a..7770441 100644 --- a/.machine_readable/6a2/ECOSYSTEM.a2ml +++ b/.machine_readable/6a2/ECOSYSTEM.a2ml @@ -1,10 +1,43 @@ # SPDX-License-Identifier: MPL-2.0 # ECOSYSTEM.a2ml — Ecosystem position -# Converted from ECOSYSTEM.scm on 2026-03-15 +# Converted from ECOSYSTEM.scm on 2026-03-15; enriched 2026-06-12. +# Relationships, dependencies, integration points. [metadata] project = "wokelang" ecosystem = "hyperpolymath" +version = "0.1.0" +last-updated = "2026-06-12" + +[project] +name = "wokelang" +purpose = "A human-centered, consent-driven programming language whose type system discharges consent / affine-use safety automatically" +role = "language" # e.g. language, ffi-infrastructure, cli-tool, library, service [position] type = "component" + +[position-in-ecosystem] +tier = "1" # 1 | 2 | infrastructure +notes = "wokelang is a standalone language in the hyperpolymath estate, distinct from the estate-primary AffineScript / my-lang. It consumes echo-types as its formal substrate." + +[related-projects] +projects = [ + { name = "echo-types", relationship = "upstream-dependency", notes = "Constructive Agda formalization of fiber-based structured loss ('echo types'). The source of truth wokelang consumes for consent / affine-loss reasoning; integrated into the typechecker on the frontier workstream." }, + { name = "nextgen-languages", relationship = "sibling-estate", notes = "Home of AffineScript / my-lang, the estate-primary language. Coordination monorepo for the language family." }, + { name = "nextgen-typing", relationship = "sibling-estate", notes = "Coordination monorepo for the hyperpolymath type-theory pipeline; the MAXIMAL reference for these machine-readable governance artefacts." }, + { name = "panll", relationship = "estate-peer", notes = "Three-pane cognitive-relief HTI in the estate; a consumer-facing surface for estate capabilities." }, + { name = "verisimdb", relationship = "estate-peer", notes = "Identity-state capture with filesystem fallback (VeriSim family)." }, + { name = "groove", relationship = "integration-protocol", notes = "HTTP-based service-discovery protocol; lets estate capabilities announce themselves for automatic detection. Part of wokelang's dogfooding gate." }, + { name = "hypatia", relationship = "security-tooling", notes = "Neurosymbolic security scanner; runs as the hypatia-scan CI gate." }, + { name = "gitbot-fleet", relationship = "automation", notes = "Estate gitbot / agent fleet that operates across repositories." }, + { name = "standards", relationship = "governance-upstream", notes = "hyperpolymath/standards supplies the thin-wrapper reusable workflows and the Hyperpolymath Standard language policy wokelang follows." }, +] + +[integration-points] +integrations = [ + { system = "echo-types", direction = "inbound", protocol = "formalization-consume", notes = "wokelang's typechecker integrates echo-types' fiber-based structured-loss formalization; an Isabelle proof narrative backs the consent-safety guarantees." }, + { system = "groove", direction = "bidirectional", protocol = "service-discovery", notes = "Groove discovery is exercised by the dogfooding gate so wokelang capabilities are announceable to the estate." }, + { system = "hypatia", direction = "inbound", protocol = "security-scan", notes = "hypatia-scan analyses the repository as part of CI (neurosymbolic / symbolic-rule scanning)." }, + { system = "standards", direction = "inbound", protocol = "reusable-workflow", notes = "CI gates are thin wrappers over hyperpolymath/standards reusable workflows." }, +] diff --git a/.machine_readable/6a2/META.a2ml b/.machine_readable/6a2/META.a2ml index cd6d83a..6e4efda 100644 --- a/.machine_readable/6a2/META.a2ml +++ b/.machine_readable/6a2/META.a2ml @@ -1,9 +1,78 @@ # SPDX-License-Identifier: MPL-2.0 # META.a2ml — Project meta-information -# Converted from META.scm on 2026-03-15 +# Converted from META.scm on 2026-03-15; enriched 2026-06-12. +# Architecture decisions, design rationale, governance. [metadata] project = "wokelang" author = "Jonathan D.A. Jewell " license = "MPL-2.0" standard = "RSR 2026" +version = "0.1.0" +last-updated = "2026-06-12" + +[project-info] +type = "monorepo" # library | binary | monorepo | service | website +tagline = "A human-centered, consent-driven programming language" +languages = ["rust", "ocaml"] +primary-language = "rust" + +[implementation] +primary = "Rust toolchain in src/" +rust-components = "lexer, parser, typechecker, bytecode VM (compiler + machine), tree-walking interpreter, LSP (woke-lsp), DAP (woke-dap), formatter, linter, REPL, stdlib, codegen, ABI/FFI, security" +rust-lib-tests = "173 passing" +binaries = "woke, woke-lsp, woke-dap" +ocaml-core = "core/ reference implementation: ocamllex lexer + menhir parser + evaluator (dune)" + +[architecture-decisions] +adrs = [ + { id = "ADR-001", title = "Rust is the primary toolchain; OCaml core is the reference", status = "accepted", date = "2026-03-15", + rationale = "The production toolchain (lexer, parser, typechecker, VM, interpreter, LSP, DAP, tooling) is implemented in Rust under src/. A smaller OCaml implementation in core/ (ocamllex + menhir + evaluator) serves as an independent reference for the language semantics and an end-to-end cross-check. Both are first-class; the OCaml core grounds the e2e CI gate." }, + { id = "ADR-002", title = "Consent / affine safety is the defining language feature", status = "accepted", date = "2026-03-15", + rationale = "wokelang is human-centered and consent-driven: the type system discharges consent and affine-use obligations so users never reason about them manually. This is the architectural invariant the whole toolchain serves." }, + { id = "ADR-003", title = "Echo types are the formal substrate for consent / affine safety", status = "accepted", date = "2026-06-12", + rationale = "wokelang consumes hyperpolymath/echo-types (constructive Agda formalization of fiber-based structured loss) as the source of truth for the loss / consent reasoning. The frontier workstream integrates echo types into the typechecker, with an end-to-end, near-first-principles machine-checked proof narrative (Isabelle preferred) backing it." }, + { id = "ADR-004", title = "Hyperpolymath Standard governance via thin-wrapper reusables", status = "accepted", date = "2026-06-12", + rationale = "CI is 20 GitHub Actions workflows built on thin-wrapper reusable workflows from hyperpolymath/standards, plus a dogfooding gate (a2ml / k9 / empty-lint / groove / eclexiaiser), clusterfuzzlite fuzzing, and a hypatia security scan. Machine state lives only under .machine_readable/ (never the repo root)." }, +] + +[development-practices] +build-tool = "just" # Justfile at repo root; contractile.just for contracts +rust-build = "cargo" +ocaml-build = "dune" +container-runtime = "podman" # Containerfile present +ci-platform = "github-actions" +package-manager = "guix" # guix.scm primary; flake.nix fallback + +[maintenance-axes] +scoping-first = true +execution-order = "axis-1 > axis-2 > axis-3" +axis-1 = "must > intend > like" +axis-2 = "corrective > adaptive > perfective" +axis-3 = "systems > compliance > effects" + +[scoping] +sources = "README, ROADMAP, status docs, maintenance checklist, CI/security docs" +marker-scan = "TODO/FIXME/XXX/HACK/STUB/PARTIAL" +proof-escape-scan = "believe_me/assert_total/sorry/Admitted/unsafeCoerce/Obj.magic" + +[axis-2-maintenance-rules] +corrective-first = true +adaptive-second = true +adaptive-focus = "scope-change reconciliation, stale-reference removal, obsolete-work culling" +perfective-third = true +perfective-source = "axis-1 honest state after corrective/adaptive updates" + +[axis-3-audit-rules] +audit-focus = "systems in place, documentation explains actual state, consent/affine-safety and security accounted for, observed effects reviewed" +compliance-focus = "seams/compromises/exception register, bounded exceptions, anti-drift checks" +drift-risk-example = "a single banned-language exception (e.g. ReScript/TypeScript) broadening into a policy violation" +effects-evidence = "test-suite execution/results (Rust + OCaml e2e) and maintainer status dialogue/review" + +[design-rationale] +summary = [ + "wokelang is a human-centered, consent-driven language: the type system does the hard consent/affine-safety reasoning so users never have to.", + "Rust under src/ is the production toolchain; the OCaml core/ is the independent reference implementation and e2e cross-check.", + "Echo types (hyperpolymath/echo-types) are the formal substrate; the frontier is integrating them into the typechecker with a machine-checked Isabelle proof narrative.", + "Governance follows the Hyperpolymath Standard: MPL-2.0, allowed/banned language policy, dogfooding gate, and machine state confined to .machine_readable/.", +] diff --git a/.machine_readable/6a2/STATE.a2ml b/.machine_readable/6a2/STATE.a2ml index 151d975..e2f9b4b 100644 --- a/.machine_readable/6a2/STATE.a2ml +++ b/.machine_readable/6a2/STATE.a2ml @@ -1,14 +1,38 @@ # SPDX-License-Identifier: MPL-2.0 # STATE.a2ml — Project state checkpoint -# Converted from STATE.scm on 2026-03-15 +# Converted from STATE.scm on 2026-03-15; refreshed 2026-06-12. [metadata] project = "wokelang" version = "0.1.0" -last-updated = "2026-03-15" +last-updated = "2026-06-12" status = "active" [project-context] name = "wokelang" -completion-percentage = 5 -phase = "concept" +completion-percentage = 35 +phase = "implementation" +tagline = "A human-centered, consent-driven programming language" + +[implementation] +primary = "Rust toolchain in src/" +rust-components = "lexer, parser, typechecker, bytecode VM (compiler + machine), tree-walking interpreter, LSP, DAP, formatter, linter, REPL, stdlib, codegen, ABI/FFI, security" +rust-lib-tests = "173 passing (0 failing)" +binaries = "woke, woke-lsp, woke-dap" +ocaml-core = "core/ reference: ocamllex lexer + menhir parser + evaluator (dune)" + +[frontier] +focus = "integrate echo-types into the type checker + an end-to-end, near-first-principles machine-checked proof narrative" +proof-assistant = "Isabelle (preferred)" +echo-types-source = "hyperpolymath/echo-types (constructive Agda formalization of fiber-based structured loss)" +goal = "the language sorts the hard consent/affine-safety reasoning so users never have to" +typechecker-note = "TypeChecker::new seeds a ~64-binding builtin prelude (incl. Result/echo constructors)" + +[ci] +workflows = "20 GitHub Actions; thin-wrapper reusables from hyperpolymath/standards" +gates = "rust-ci, dogfood-gate, e2e (Rust+OCaml), governance, security, codeql, scorecard, secret-scanner, hypatia-scan, clusterfuzzlite, mirror, instant-sync" +last-shepherd = "2026-06-12 PR #77: fixed 3 Rust tests, empty wokelang.opam, removed banned ReScript VSCode client (governance); issue #78 tracks AffineScript reimpl" + +[spec] +location = "spec/ — grammar.ebnf, axiomatic-semantics.md, system-specs.md, SPEC.core.scm" +paper = "arxiv-consent-aware-programming.tex (+ references.bib)" diff --git a/.machine_readable/6a2/anchor/ANCHOR.a2ml b/.machine_readable/6a2/anchor/ANCHOR.a2ml index ffb8e4d..72989b9 100644 --- a/.machine_readable/6a2/anchor/ANCHOR.a2ml +++ b/.machine_readable/6a2/anchor/ANCHOR.a2ml @@ -3,7 +3,7 @@ id: "org.hyperpolymath.wokelang" version: "1.0.0" -clade: "unknown" +clade: "nl" # nextgen-languages clade (per .machine_readable/CLADE.a2ml) status: "active" # SSG Configuration (Unified boj-server build) @@ -15,4 +15,5 @@ ssg: # Relationships parents: - - "org.hyperpolymath.boj-server" + - "org.hyperpolymath.boj-server" # SSG / publish parent (boj build trigger) + - "org.hyperpolymath.nextgen-languages" # code lineage (monorepo-child, clade nl) diff --git a/.machine_readable/bot_directives/git-private-farm.a2ml b/.machine_readable/bot_directives/git-private-farm.a2ml new file mode 100644 index 0000000..ff2ccad --- /dev/null +++ b/.machine_readable/bot_directives/git-private-farm.a2ml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: MPL-2.0 +# Copyright (c) 2026 Jonathan D.A. Jewell +# +# git-private-farm.a2ml — directive for the private mirror / build farm on this +# repository. The farm mirrors the repository to estate-private infrastructure +# and runs reproducible builds there. + +[metadata] +bot = "git-private-farm" +project = "wokelang" +version = "0.1.0" +last-updated = "2026-06-12" + +[hook] +# The farm is driven by the mirror / sync / publish workflows. +related-workflows = [ + ".github/workflows/mirror.yml", # mirror the repository + ".github/workflows/instant-sync.yml", # propagate changes on push + ".github/workflows/ghcr-publish.yml", # publish the container image + ".github/workflows/boj-build.yml", # SSG / publish build (boj-server trigger) +] +build-tooling = ["cargo", "dune", "podman"] # Rust + OCaml + container builds + +[purpose] +summary = "Private mirroring and reproducible builds of the repository." +responsibilities = [ + "mirror the public repository to estate-private hosting", + "run reproducible builds (Guix primary, Nix fallback) of the toolchain", + "build and publish the container image (Containerfile / stapeln.toml)", + "keep the private mirror in sync with the default branch", +] + +[direction] +# The farm consumes this repo; it does not write source changes back. +flow = "outbound-mirror" # public repo -> private farm +writes-back-to-public = false + +[constraints] +reproducible-builds = true # guix.scm primary; flake.nix fallback +preserve-spdx-headers = true +no-secrets-in-image = true # no credentials baked into published images +sha-pinned-dependencies = true +https-only = true + +[notes] +# Private endpoints, registry coordinates, and credentials live in the farm +# infrastructure, NOT in this file. This directive only declares repo-local +# scope and the build/mirror policy the farm must honour. diff --git a/.machine_readable/bot_directives/gitbot-fleet.a2ml b/.machine_readable/bot_directives/gitbot-fleet.a2ml new file mode 100644 index 0000000..f2a3355 --- /dev/null +++ b/.machine_readable/bot_directives/gitbot-fleet.a2ml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: MPL-2.0 +# Copyright (c) 2026 Jonathan D.A. Jewell +# +# gitbot-fleet.a2ml — directive for the hyperpolymath gitbot / agent fleet on +# this repository. The fleet is the estate's automation that operates across +# repositories (housekeeping, governance sync, dependency hygiene, label and +# issue triage). + +[metadata] +bot = "gitbot-fleet" +project = "wokelang" +version = "0.1.0" +last-updated = "2026-06-12" + +[hook] +# The fleet acts through pull requests and issue actions on this repo. +mechanism = "pull-request" +governance-upstream = "hyperpolymath/standards" # reusable workflows + policy +related-workflows = [ + ".github/workflows/governance.yml", + ".github/workflows/workflow-linter.yml", +] + +[purpose] +summary = "Cross-repository automation and governance synchronisation." +responsibilities = [ + "keep CI thin-wrapper reusables in sync with hyperpolymath/standards", + "repository hygiene (stale references, empty files, formatting)", + "issue / label triage and cross-repo coordination", + "open maintenance PRs (never direct pushes to the default branch)", +] + +[permissions] +can-open-pull-requests = true +can-comment-on-issues = true +can-push-to-default-branch = false +can-edit-source = false # source changes go through human-reviewed PRs +can-edit-machine-readable = false # .machine_readable/ is maintainer-curated + +[constraints] +respect-language-policy = true # Hyperpolymath Standard allowed/banned set +respect-contractiles = true # must / trust / dust / bust +require-dogfood-gate-green = true # changes must keep the dogfooding gate passing +preserve-spdx-headers = true +no-secrets-in-commits = true + +[notes] +# Fleet identity, tokens, and scheduling are managed by the fleet infrastructure +# and are NOT committed here. This file is the repo-local scope/policy surface. diff --git a/.machine_readable/bot_directives/hypatia.a2ml b/.machine_readable/bot_directives/hypatia.a2ml new file mode 100644 index 0000000..b5c1bca --- /dev/null +++ b/.machine_readable/bot_directives/hypatia.a2ml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: MPL-2.0 +# Copyright (c) 2026 Jonathan D.A. Jewell +# +# hypatia.a2ml — directive for the Hypatia security bot on this repository. +# Hypatia is the estate's neurosymbolic security scanner. It runs as the +# `hypatia-scan` CI gate and the `hypatia-autofix` bot. + +[metadata] +bot = "hypatia" +project = "wokelang" +version = "0.1.0" +last-updated = "2026-06-12" + +[hook] +# CI gate workflow that invokes Hypatia. +ci-workflow = ".github/workflows/hypatia-scan.yml" +# Local activity ledger Hypatia writes to (see repo root). +activity-log = ".hypatia/activity.jsonl" +last-visit = ".hypatia/last-visit.json" +agents = ["hypatia-scan", "hypatia-autofix"] + +[purpose] +summary = "Symbolic / neurosymbolic security scanning of the repository." +scans = [ + "banned-language patterns (Hyperpolymath Standard policy)", + "dangerous / unsafe usage in Rust", + "proof escape hatches (believe_me, assert_total, sorry, Admitted, unsafeCoerce, Obj.magic)", + "secret / credential leakage (complements secret-scanner)", +] + +[autofix-policy] +# hypatia-autofix may propose fixes, but only within these bounds. +mode = "propose" # propose | apply +allow-source-edits = false # never silently edit src/ — open a PR instead +open-pull-request = true +require-human-review = true +never-touch = [ + ".machine_readable/", # machine state is maintainer-curated + "LICENSE", "NOTICE", "LICENSES/", +] + +[constraints] +# Hard invariants Hypatia must not violate. +must-not-weaken-consent-safety = true +must-not-add-escape-hatches = true +must-preserve-spdx-headers = true +fail-closed = true # a scan error blocks, it does not pass silently + +[notes] +# Endpoints and credentials are supplied by the Hypatia service, not committed here. +# This directive only declares repo-local scope and policy. diff --git a/EXPLAINME.adoc b/EXPLAINME.adoc index 306a620..4d5ef03 100644 --- a/EXPLAINME.adoc +++ b/EXPLAINME.adoc @@ -18,15 +18,23 @@ commitment. == What WokeLang Is -WokeLang is a programming language in `nextgen-languages` designed around +WokeLang is a standalone language in the hyperpolymath estate, designed around three principles: human-readable syntax (English-like keywords), ethical scaffolding (consent gates, gratitude blocks, empathy annotations), and type safety with dimensional analysis (units of measure enforced at compile time). The primary implementation is a Rust compiler/interpreter (`src/`, `Cargo.toml`) -that can run WokeLang programs via a tree-walking interpreter, compile to -bytecode for the WokeLang VM, or export a WASM target for browser execution. -An OCaml frontend (`dune-project`, `wokelang.opam`) provides an alternative -AST pipeline used for research and verification. +that runs WokeLang programs via a tree-walking interpreter or compiles them to +bytecode for the WokeLang VM. A WASM target is a design commitment (see Claim 2). +An OCaml reference core (`core/`, built with `dune` + `menhir`) provides an +independent AST + evaluator pipeline used for research, semantics +cross-checking, and the end-to-end CI gate. (Note: `wokelang.opam` is currently +an intentionally empty stub; the OCaml core builds from `dune-project`.) + +The *frontier* workstream integrates *echo types* — `hyperpolymath/echo-types`, +a constructive Agda formalization of fiber-based structured loss — into the type +checker, backed by a near-first-principles machine-checked proof narrative +(Isabelle preferred), so the language discharges consent / affine-use safety for +the user automatically. == Claim 1: Rust compiler with lexer, parser, type checker, and VM @@ -79,24 +87,24 @@ blockchain ops. WASM Target: Compile to run in browsers/Node.js. Portable and fast. ____ -*How it works.* -`src/codegen/` contains the WASM backend: it consumes the typed AST and emits -WebAssembly binary format consumable by browsers and Deno. -`src/stdlib/` includes the Vyper FFI bridge: `vyper call` statements in -WokeLang source are lowered to calls against a Vyper contract ABI at the -code-generation phase, allowing blockchain operations to be invoked with the -same `only if okay` consent-gate syntax as local side effects. -`examples/` contains `.woke` files demonstrating the full feature set including -`thanks to` gratitude blocks, `@feeling` empathy annotations, and pipeline -syntax (`data then clean then analyze`). -`fuzz/` contains fuzzing harnesses for the parser and typechecker. +*How it works (and what is real).* +`src/codegen/` declares a `WasmCompiler` scaffold for a future WASM backend. +`examples/` contains `.woke` files demonstrating the *implemented* feature set +including `only if okay` consent gates (`08_consent.woke`, `22_consent_system.woke`), +`thanks to` gratitude blocks (`17_gratitude.woke`), and security examples. +`src/stdlib/` provides the standard library (`array`, `chan`, `io`, `json`, +`math`, `net`, `string`, `time`), where `io` and `net` route side effects +through the consent machinery. +`fuzz/` contains fuzzing harnesses (driven by ClusterFuzzLite in CI). `verification/` holds formal verification artefacts. *Honest caveat.* -The Vyper FFI is a design feature present in the README feature table; its -integration with live contract ABIs requires a running Ethereum node and is -not covered by the existing test suite — it is a research capability, not a -production-ready integration. +The Vyper / blockchain FFI and the WASM target are *design commitments* described +in the README feature table, the language spec, and the research paper — they are +*not* working implementations in the current tree. There is no `vyper` bridge in +`src/stdlib/`, and the `src/codegen/` WASM module is a scaffold that is not yet +wired into the build or emitting binaries. Treat both as research capabilities on +the roadmap, not production-ready integrations. == Dogfooded Across The Account @@ -114,16 +122,16 @@ production-ready integration. | Container build manifest for the WokeLang compiler image (Chainguard Wolfi base) | `nextgen-languages` -| WokeLang is a sub-project of the `nextgen-languages` monorepo; this repo is checked out as a submodule +| Sibling estate (home of AffineScript / my-lang). WokeLang is a *standalone* repository in the hyperpolymath estate, not a submodule of `nextgen-languages`. | `ABI-FFI-README.md` -| Idris2 ABI + Zig FFI standard applied: `src/abi/` and `ffi/` directories follow the account-wide ABI/FFI convention +| Account-wide ABI/FFI convention applied: `src/abi/` holds the Idris2 ABI definitions (`Foreign.idr`, `Layout.idr`, `Types.idr`) and `src/ffi/` holds the Rust C-ABI bridge (`c_api.rs`). | `grammar/` -| WokeLang grammar files feed `tree-sitter generate` for editor syntax support +| WokeLang grammar source feeding editor syntax support (TextMate / tree-sitter). | `editors/` -| Editor integration packages (Neovim, VS Code) built from the tree-sitter grammar +| Editor integration: a TextMate grammar plus a VS Code extension. The VS Code extension is currently *syntax-only* — its ReScript LSP client was removed (banned estate-wide) and an AffineScript reimplementation is tracked in issue #78. The Rust `woke-lsp` server binary is unaffected and works with any LSP-capable editor. | `arxiv-consent-aware-programming.tex` | Research paper on consent-aware programming; wokelang is the reference implementation @@ -169,13 +177,13 @@ production-ready integration. | Bytecode optimiser: constant folding, dead code elimination | `src/codegen/` -| WASM code generation backend +| Code-generation scaffolding (`WasmCompiler`); a future WASM backend, not yet wired into the build | `src/lsp/` -| Language Server Protocol implementation for editor integration +| Language Server Protocol implementation (built as the `woke-lsp` binary) | `src/dap/` -| Debug Adapter Protocol implementation +| Debug Adapter Protocol implementation (built as the `woke-dap` binary) | `src/repl.rs` | Interactive REPL loop @@ -184,7 +192,7 @@ production-ready integration. | S-expression AST dump (for debugging and tooling) | `src/stdlib/` -| Standard library: built-in functions, Vyper FFI bridge, I/O primitives +| Standard library: `array`, `chan`, `io`, `json`, `math`, `net`, `string`, `time` (consent-routed I/O and networking) | `src/linter/` | Static linter: style rules, consent-gate usage checks @@ -199,16 +207,16 @@ production-ready integration. | Module system: import resolution and namespace management | `src/abi/` -| Idris2 ABI definitions for the Rust/Zig FFI boundary +| Idris2 ABI definitions (`Foreign.idr`, `Layout.idr`, `Types.idr`, `wokelang-abi.ipkg`) for the FFI boundary -| `ffi/` -| Zig FFI implementation: C-ABI-compatible bridge +| `src/ffi/` +| Rust C-ABI FFI bridge (`c_api.rs`, `mod.rs`) | `grammar/` | Tree-sitter grammar source for WokeLang syntax | `editors/` -| Editor integration packages built from the grammar +| TextMate grammar + VS Code extension (currently syntax-only; ReScript LSP client removed, AffineScript reimpl tracked in issue #78) | `examples/` | `.woke` example programs: hello world through fibonacci, unit arithmetic, consent gates, gratitude blocks @@ -225,8 +233,11 @@ production-ready integration. | `bench/` / `benches/` | Criterion benchmarks: interpreter and VM throughput -| `compiler/` -| OCaml alternative frontend (dune-project, wokelang.opam) +| `core/` +| OCaml reference core: `lexer.mll` (ocamllex) + `parser.mly` (menhir) + `ast.ml` + `eval.ml`, built with `dune` + +| `compiler/wokelang-wasm/` +| Standalone Rust crate for the WASM compilation experiment (`lib.rs`) | `conformance/` | Conformance test suite against the language specification @@ -241,7 +252,7 @@ production-ready integration. | Rust workspace manifest | `dune-project` / `wokelang.opam` -| OCaml build configuration for the alternative frontend +| OCaml build configuration for the `core/` reference (`dune-project` drives the build; `wokelang.opam` is currently an empty stub) | `Justfile` / `Mustfile` | Developer recipes: `build`, `test`, `bench`, `fuzz`, `check-conformance` @@ -259,7 +270,7 @@ production-ready integration. | Container build manifest | `flake.nix` / `guix.scm` -| Reproducible build environments (Rust nightly + OCaml + Deno toolchain) +| Reproducible build environments (Rust + OCaml toolchain); Guix primary, Nix fallback |=== == Questions? diff --git a/README.adoc b/README.adoc index 9b5fcf3..60dca5b 100644 --- a/README.adoc +++ b/README.adoc @@ -12,208 +12,299 @@ image:https://img.shields.io/badge/License-MPL_2.0-blue.svg[License: MPL-2.0,lin :icons: font :source-highlighter: highlight.js -WokeLang: A Human-Centered Programming Language +image:https://img.shields.io/badge/License-MPL--2.0-brightgreen.svg[License: MPL-2.0,link="LICENSE"] +image:https://github.com/hyperpolymath/wokelang/actions/workflows/rust-ci.yml/badge.svg[Rust CI,link="https://github.com/hyperpolymath/wokelang/actions/workflows/rust-ci.yml"] +image:https://img.shields.io/badge/Rust-stable-orange.svg[Rust] +image:https://img.shields.io/badge/OCaml-reference%20core-blueviolet.svg[OCaml] -[![Build Status](https://github.com/hyperpolymath/wokelang/actions/workflows/ci.yml/badge.svg)](https://github.com/hyperpolymath/wokelang/actions) -[![OCaml](https://img.shields.io/badge/OCaml-5.0-blue)](https://ocaml.org) -[![Rust](https://img.shields.io/badge/Rust-1.70-red)](https://rust-lang.org) -[![Vyper](https://img.shields.io/badge/Vyper-0.3.10-green)](https://vyper.readthedocs.io) +*WokeLang: A human-centered, consent-driven programming language.* -WokeLang is a programming language designed for **human collaboration**, **empathy**, and **safety**—without sacrificing power or performance. It combines: +WokeLang is a programming language designed for *human collaboration*, *consent*, +and *affine-use safety* — without sacrificing power or performance. The defining +idea is that the *type system discharges the hard consent and affine-use reasoning +for you*, so dangerous or destructive operations are scaffolded at the language +level rather than left to convention. -- **Python's readability** with **Rust's performance**. -- **Hindley-Milner type inference** with **JavaScript's expressiveness**. -- **Unique features** like `thanks to`, `only if okay`, and `measured in` for **ethical, self-documenting code**. +It combines: -## Table of Contents -- [🚀 Quick Start](#-quick-start) -- [🌟 Key Features](#-key-features) -- [📦 Project Structure](#-project-structure) -- [🛠 Development](#-development) -- [📚 Examples](#-examples) -- [🎯 Next Steps](#-next-steps) -- [🤝 Community](#-community) +- Readable, English-like syntax with a statically typed core. +- Hindley-Milner-style type inference (scalar and unit types today; broader + polymorphic inference is a roadmap item). +- Consent-aware features like `only if okay`, `thanks to`, and `measured in` + (units of measure) for ethical, self-documenting code. -## 🚀 Quick Start +The primary implementation is a *Rust toolchain* in `src/`; a smaller *OCaml +reference core* in `core/` cross-checks the language semantics end-to-end. -### 1. Install -```bash +toc::[] + +== Project status + +[cols="1,3", options="header"] +|=== +| Aspect | State + +| Phase +| Implementation (~35% complete; version 0.1.0). + +| Primary implementation +| Rust toolchain in `src/`: lexer, parser, typechecker, bytecode VM (compiler + + machine), tree-walking interpreter, LSP (`woke-lsp`), DAP (`woke-dap`), + formatter, linter, REPL, stdlib, codegen, ABI/FFI, security. + +| Reference core +| OCaml in `core/`: `ocamllex` lexer + `menhir` parser + evaluator, built with + `dune`. Grounds the end-to-end CI cross-check. + +| Tests +| 173 Rust library tests passing. + +| Binaries +| `woke` (CLI + REPL), `woke-lsp` (editor language server), `woke-dap` (debug + adapter). + +| Frontier +| Integrating *echo types* (`hyperpolymath/echo-types`) into the type checker, + with a near-first-principles machine-checked proof narrative (Isabelle + preferred), so consent / affine-safety is handled automatically. + +| Editor support +| Tree-sitter / TextMate grammar drives passive syntax highlighting. The VS Code + extension is currently *syntax-only* (see `editors/vscode/`). +|=== + +== Quick start + +=== 1. Install + +[source,bash] +---- git clone https://github.com/hyperpolymath/wokelang.git cd wokelang -# Install dependencies (asdf + tools) -asdf install # installs rust, deno, idris2, zig - -# Build +# Build the Rust toolchain (Rust stable; see .tool-versions) cargo build --release +---- + +To build the OCaml reference core as well: + +[source,bash] +---- +dune build ./core +---- -2. Run the REPL +=== 2. Run the REPL -cargo run --release -- repl +[source,bash] +---- +cargo run --release --bin woke -- repl +---- -Example REPL Session: +Example REPL session: +---- wokelang> remember x = 5 measured in km wokelang> x + 3 measured in km Result: 8 measured in km +---- -3. Run Examples +Adding mismatched units (`5 measured in km + 3 measured in kg`) is a compile-time +type error. +=== 3. Run examples + +[source,bash] +---- # Hello World -cargo run --release -- run examples/01_hello.woke +cargo run --release --bin woke -- run examples/01_hello.woke # Fibonacci -cargo run --release -- run examples/13_fibonacci.woke +cargo run --release --bin woke -- run examples/13_fibonacci.woke -# All examples +# List all examples ls examples/*.woke +---- -4. Build & Execute +=== 4. Compile and execute on the VM +[source,bash] +---- # Compile to bytecode -cargo run --release -- compile examples/01_hello.woke -o hello.wbc +cargo run --release --bin woke -- compile examples/01_hello.woke -o hello.wbc + +# Run the bytecode on the VM +cargo run --release --bin woke -- run-vm hello.wbc +---- + +== Key features + +[cols="1,2,2", options="header"] +|=== +| Feature | Example | Why it matters + +| Human syntax +| `to add(a, b) -> a + b` +| Reads like plain English. -# Run on VM -cargo run --release -- run-vm hello.wbc +| Consent gates +| `only if okay "Delete?" { ... }` +| Ethical scaffolding for dangerous operations. -```markdown -## 🌟 Key Features +| Gratitude blocks +| `thanks to { "Alice" -> "Fixed X!" }` +| Acknowledges contributors in the code itself. -| Feature | Example | Why It’s Special | -|-----------------------|------------------------------------------|-------------------------------------------| -| **Human Syntax** | `to add(a, b) -> a + b` | Reads like plain English. | -| **Empathy Annotations** | `@feeling(confident=true)` | Codes with emotional context. | -| **Consent Gates** | `only if okay "Delete?" { ... }` | Ethical scaffolding for dangerous ops. | -| **Gratitude Blocks** | `thanks to { "Alice" → "Fixed X!" }` | Acknowledges contributors in code. | -| **Units of Measure** | `5 measured in km` | Prevents unit-related bugs. | -| **Pipelines** | `data then clean then analyze` | Intuitive data transformations. | -| **Vyper FFI** | `vyper call "gratitude.add_entry"` | Immutable, auditable blockchain ops. | -| **WASM Target** | Compile to run in browsers/Node.js. | Portable and fast. | +| Units of measure +| `5 measured in km` +| Dimensional analysis prevents unit-mismatch bugs at compile time. -## 📦 Project Structure +| Pipelines +| `data then clean then analyze` +| Intuitive left-to-right data transformations. -```bash +| Empathy annotations +| `@feeling(confident=true)` +| Carries emotional / authorial context alongside code. +|=== + +NOTE: Some surface features described in the language spec and research paper +(for example a blockchain FFI bridge and a WASM target) are *design commitments* +rather than production-ready integrations. See `EXPLAINME.adoc` for the honest +"what is implemented vs. what is designed" breakdown. + +== Project structure + +[source] +---- wokelang/ -├── .bot_directives/ # Bot constraint files for gitbot-fleet -├── .claude/ # Project-specific AI instructions -├── .github/workflows/ # CI/CD (Hypatia, CodeQL, Scorecard) -├── .machine_readable/ # Machine-readable metadata -│ └── 6scm/ # SCM checkpoint files -├── contractiles/ # Contractile definitions -│ ├── dust/ # External dependencies -│ ├── k9/ # Security constraints -│ ├── lust/ # Desired features -│ ├── must/ # Required features & must runner -│ └── trust/ # Trust boundaries -├── docs/ # Documentation -│ ├── architecture/ # Architecture docs (COMPILER-ROADMAP.adoc) -│ ├── sessions/ # Development session reports -│ ├── ABI-FFI-README.adoc # ABI/FFI integration guide -│ ├── DEPLOYMENT.adoc # Deployment documentation -│ ├── GAP-ANALYSIS.adoc # Implementation gaps -│ ├── NEXT-STEPS.adoc # Development roadmap -│ ├── PALIMPSEST.adoc # License philosophy -│ ├── PROVEN.md # proven library integration -│ └── WORKERS.adoc # Worker documentation -├── examples/ # Example WokeLang programs -├── ffi/ -│ └── zig/ # Zig FFI implementation (C ABI) -│ └── src/ -├── license/ # License files -│ └── MPL-2.0.txt -├── scripts/ -│ ├── install-hooks.sh # Install git hooks -│ └── setup.sh # Setup script -├── site/ # wokelang.org website -│ ├── content/ # Markdown content -│ ├── templates/ # Tera templates -│ └── config.yaml # Site configuration -├── src/ -│ ├── abi/ # Idris2 ABI definitions with formal proofs -│ │ ├── Foreign.idr -│ │ ├── Layout.idr -│ │ └── Types.idr -│ ├── ast/ # Abstract Syntax Tree -│ ├── interpreter/ # Tree-walking interpreter -│ ├── lexer/ # Token generation (logos) -│ ├── parser/ # Parser (tokens → AST) -│ ├── stdlib/ # Standard library modules -│ │ ├── array.rs -│ │ ├── chan.rs # Go-style channels -│ │ ├── io.rs # File I/O with consent -│ │ ├── math.rs -│ │ ├── net.rs # HTTP with consent -│ │ ├── string.rs -│ │ └── time.rs -│ ├── typechecker/ # Hindley-Milner type inference -│ ├── vm/ # Bytecode VM -│ │ ├── bytecode.rs -│ │ ├── compiler.rs -│ │ ├── machine.rs -│ │ └── optimizer.rs -│ ├── main.rs # CLI entry point -│ └── repl.rs # REPL -├── tests/ # Test suite -├── .tool-versions # asdf tool versions (rust, deno, idris2, zig) -├── AI.a2ml # AI assistant instructions -├── Cargo.toml # Rust dependencies -├── .machine_readable/6a2/ECOSYSTEM.a2ml # Ecosystem relationships -├── .machine_readable/6a2/META.a2ml # Architectural decisions -├── .machine_readable/6a2/STATE.a2ml # Current project state -└── README.adoc # This file - -## 🛠 Development - -### Must Runner (Contractile Enforcement) - -WokeLang uses a **Mustfile** (in `contractiles/must/`) to enforce mandatory checks: - -```bash -# Run all mandatory checks (security, tests, format) -must run - -# Individual checks -just lint # Security checks -just test # Test suite -just fmt # Code formatting -``` - -**Mustfile** defines requirements that MUST pass before commits/releases. See `contractiles/` for full contractile system: -- `must/` - Mandatory requirements (MUST pass) -- `lust/` - Desired features (WANT to have) -- `dust/` - External dependencies -- `trust/` - Trust boundaries -- `k9/` - Security constraints - -## 🛠 Development - -### Development Environment - -**Required Tools** (managed via asdf): -- Rust 1.84.0 - Compiler infrastructure -- Deno 2.1.4 - Runtime (NO Node.js/npm) -- Idris2 0.7.0 - ABI with formal proofs -- Zig 0.13.0 - FFI C-compatible implementation - -```bash -# Install asdf -git clone https://github.com/asdf-vm/asdf.git ~/.asdf - -# Install plugins -asdf plugin add rust -asdf plugin add deno -asdf plugin add idris2 -asdf plugin add zig - -# Install versions (from .tool-versions) -asdf install - -# Build +├── src/ # PRIMARY Rust toolchain +│ ├── lexer/ # Tokeniser (logos): remember, measured in, only if okay, thanks to, then +│ ├── parser/ # Recursive-descent parser → AST +│ ├── ast/ # AST node definitions +│ ├── typechecker/ # Hindley-Milner-style inference + Unit dimensional analysis +│ ├── interpreter/ # Tree-walking interpreter (woke run) +│ ├── vm/ # Bytecode VM: compiler, machine, optimizer +│ ├── codegen/ # Code generation backend +│ ├── lsp/ # Language Server Protocol (binary: woke-lsp) +│ ├── dap/ # Debug Adapter Protocol (binary: woke-dap) +│ ├── formatter/ # Canonical-style formatter +│ ├── linter/ # Style + consent-gate lint rules +│ ├── security/ # Security analysis passes +│ ├── stdlib/ # Standard library modules +│ ├── abi/ ffi/ # ABI / FFI boundary +│ ├── modules.rs # Module system +│ ├── main.rs repl.rs # CLI entry point + REPL +│ └── bin/ # woke-lsp.rs, wokelang-dap.rs +├── core/ # OCaml reference core: lexer.mll + parser.mly + eval.ml (dune) +├── spec/ # Language specification: grammar.ebnf, axiomatic-semantics, SPEC.core.scm +├── examples/ # .woke example programs +├── conformance/ # Conformance test suite +├── fuzz/ # ClusterFuzzLite fuzzing harnesses +├── verification/ # Formal verification artefacts +├── editors/ # Editor integration (TextMate grammar; VS Code = syntax-only) +├── wiki/ # In-tree project wiki (start at wiki/Home.adoc) +├── docs/ # Documentation (architecture, sessions, PALIMPSEST, …) +├── contractiles/ # Contractile definitions (must / trust / dust / bust) +├── .machine_readable/ # Structured project metadata (6a2/, anchors/, svc/k9, bot_directives/, …) +├── .github/workflows/ # CI/CD (rust-ci, dogfood-gate, e2e, governance, hypatia-scan, …) +├── Cargo.toml # Rust workspace manifest +├── dune-project # OCaml build configuration +├── Justfile / Mustfile # Developer recipes + mandatory-check runner +└── README.adoc # This file +---- + +== Development + +=== Toolchain + +WokeLang's production toolchain needs only *Rust stable* (`.tool-versions` pins +`rust stable`). The OCaml reference core additionally needs OCaml + `dune` + +`menhir`. Reproducible environments are provided via Guix (`guix.scm`, primary) +and Nix (`flake.nix`, fallback). + +[source,bash] +---- +# Rust toolchain cargo build --release +cargo test # 173 library tests + +# OCaml reference core +dune build ./core +dune runtest ./core +---- + +=== Must runner (contractile enforcement) + +WokeLang uses a *Mustfile* to enforce mandatory checks before commits and +releases: + +[source,bash] +---- +must run # all mandatory checks (security, tests, format) + +just lint # lint / security checks +just test # test suite +just fmt # formatting +---- + +The contractile system lives under `contractiles/` (and the machine-readable +mirror under `.machine_readable/contractiles/`): + +- `must/` — mandatory requirements (MUST pass) +- `trust/` — trust boundaries +- `dust/` — external dependencies +- `bust/` — teardown / cleanup contracts + +Self-validation (K9) templates live under `.machine_readable/svc/k9/`. + +== Governance + +WokeLang follows the *Hyperpolymath Standard*: + +- *Licence:* MPL-2.0 (SPDX header on every file). +- *Language policy:* an allowed / banned language set (for example, no + TypeScript, Node.js, Go, or Python) enforced by the `governance` workflow. +- *CI:* a multi-workflow GitHub Actions suite (`rust-ci`, `ocaml-core`, `e2e`, + `dogfood-gate`, `governance`, `security`, `codeql`, `scorecard`, + `secret-scanner`, `hypatia-scan`, ClusterFuzzLite, mirror, instant-sync, …). +- *Dogfooding gate:* the repo applies its own tooling (a2ml lint, K9 + self-validation, empty-lint, Groove discovery, eclexiaiser). + +See `wiki/CI-and-Governance.adoc` for the full picture, and `.machine_readable/` +for the structured project state. + +== Documentation + +- `wiki/Home.adoc` — in-tree project wiki (Overview, Architecture, CI & + Governance, Roadmap). +- `EXPLAINME.adoc` — honest "claims vs. receipts" walkthrough of the codebase. +- `spec/` — the language specification. +- `docs/` — architecture notes, session reports, and the Palimpsest licence + philosophy. +- `arxiv-consent-aware-programming.tex` — the research paper on consent-aware + programming, for which WokeLang is the reference implementation. + +== Next steps + +- Eliminate proof escape hatches; tighten the formal-verification story. +- Integrate echo types into the typechecker (frontier workstream). +- Restore a full LSP client for the VS Code extension once the estate ABI/FFI + layer lands (the Rust `woke-lsp` server already works with any LSP-capable + editor). +- Broaden Hindley-Milner inference over closures and module types. + +See `ROADMAP.adoc` and `wiki/Roadmap.adoc`. +== Community -== License +- *Author / maintainer:* Jonathan D.A. Jewell +- *Issues:* https://github.com/hyperpolymath/wokelang/issues +- *Contributing:* see `CONTRIBUTING.adoc`. +- *Code of Conduct:* see `CODE_OF_CONDUCT.md`. -This project is licensed under the Mozilla Public License, v. 2.0. See the `LICENSE` file for details. +== Licence -SPDX-License-Identifier: MPL-2.0 +WokeLang is released under the *Mozilla Public License 2.0* (`MPL-2.0`); the SPDX +identifier on every file is `MPL-2.0`. The project additionally describes its +ethical-use and provenance philosophy via the Palimpsest framing — see +`docs/PALIMPSEST.adoc`. diff --git a/editors/vscode/.gitignore b/editors/vscode/.gitignore index c893915..e976033 100644 --- a/editors/vscode/.gitignore +++ b/editors/vscode/.gitignore @@ -13,3 +13,6 @@ deps/ Thumbs.db build/ dist/ + +# ReScript/bsb build cache (never track — regenerated by `rescript build`) +lib/ diff --git a/editors/vscode/README.md b/editors/vscode/README.md index 01e9196..865bb7f 100644 --- a/editors/vscode/README.md +++ b/editors/vscode/README.md @@ -4,100 +4,39 @@ Copyright (c) Jonathan D.A. Jewell --> # WokeLang for Visual Studio Code -Official VS Code extension for WokeLang - a human-centered programming language with consent-driven capabilities. - -## Features - -- **Syntax Highlighting** - Full syntax highlighting for `.woke` files -- **Auto-Completion** - Intelligent code completion for: - - Keywords (to, give, remember, when, attempt, worker, etc.) - - Standard library modules (std.math, std.string, std.array, etc.) - - Standard library functions (55+ functions with signatures) - - Local variables and functions (from type inference) -- **Hover Documentation** - Rich markdown documentation on hover - - Keyword explanations with syntax examples - - Type information for variables and functions - - Function signatures for stdlib functions -- **Go-to-Definition** - Jump to definition with F12 or Cmd+Click - - Functions, types, constants, variables - - Nested scope support -- **Real-time Diagnostics** - Instant error detection - - Lexer errors (syntax errors) - - Parser errors (structural errors) - - Linter warnings (code quality) -- **Document Formatting** - Format code with Shift+Alt+F - - Consistent indentation - - AST-based formatting +VS Code language support for WokeLang — a human-centered programming language +with consent-driven capabilities. + +> **Status (2026-06): syntax support only.** +> This extension currently provides **syntax highlighting** and **language +> configuration** for `.woke` files. The full LSP client (completion, hover, +> diagnostics, go-to-definition, formatting) has been **removed** because its +> previous implementation was in ReScript, which is banned estate-wide. +> +> The intended reimplementation language is **AffineScript** (estate-primary), +> but AffineScript currently has no host-FFI mechanism and compiles to WASM +> rather than the JS extension host, so a faithful client cannot be written +> yet. It is **blocked on the planned estate ABI/FFI layer** and tracked in the +> repository issues. The `woke-lsp` server binary itself (Rust) is unaffected +> and continues to build via `cargo build --bin woke-lsp`. + +## Features (current) + +- **Syntax highlighting** — TextMate grammar for `.woke` files + (`syntaxes/wokelang.tmLanguage.json`). +- **Language configuration** — brackets, comments, auto-closing pairs + (`language-configuration.json`). ## Installation -### Prerequisites +No build step is required for the passive extension. Copy it into your VS Code +extensions directory: -1. Install WokeLang and build the LSP server: - ```bash - cd /path/to/wokelang - cargo build --bin woke-lsp --release - ``` - -2. Make `woke-lsp` available in your PATH, or note the full path to the binary. - -### Install Extension - -**Option 1: From Source** -```bash -cd /path/to/wokelang/editors/vscode -npm install -npm run compile -code --install-extension . -``` - -**Option 2: Copy to Extensions Directory** ```bash cp -r /path/to/wokelang/editors/vscode ~/.vscode/extensions/wokelang-0.1.0/ ``` -## Configuration - -Open VS Code settings (Cmd+,) and configure: - -```json -{ - "wokelang.serverPath": "/path/to/woke-lsp", - "wokelang.trace.server": "off" -} -``` - -### Settings - -- `wokelang.serverPath` - Path to the `woke-lsp` executable (default: `woke-lsp`) -- `wokelang.trace.server` - LSP server logging level: - - `off` - No logging (default) - - `messages` - Log messages only - - `verbose` - Verbose logging - -## Usage - -1. Open a `.woke` file in VS Code -2. The WokeLang LSP server will start automatically -3. You'll see "WokeLang LSP connected" in the status bar - -### Features in Action - -**Auto-Completion:** -- Type `std.` → See all stdlib modules -- Type `std.math.` → See all math functions -- Type `rem` → See `remember` keyword suggestion - -**Hover:** -- Hover over `to` → See function definition syntax -- Hover over a variable → See its inferred type - -**Go-to-Definition:** -- Press F12 on a function call → Jump to function definition -- Cmd+Click on a variable → Jump to declaration - -**Formatting:** -- Press Shift+Alt+F → Format entire document +Then reload VS Code. Open any `.woke` file to get syntax highlighting. ## Example @@ -107,11 +46,8 @@ to calculateArea(width, height) { give back width * height; } -// Use standard library to main() { remember result = calculateArea(5, 10); - remember rounded = std.math.round(3.7); - when result > 20 { print("Large area"); } otherwise { @@ -120,44 +56,13 @@ to main() { } ``` -## Troubleshooting - -### Extension Not Activating -- Ensure the file has `.woke` extension -- Check that `woke-lsp` is in your PATH or configured in settings - -### No Completions/Hover -- Check the Output panel (View → Output → WokeLang Language Server) -- Verify `woke-lsp` is running: `ps aux | grep woke-lsp` - -### Server Crashes -- Check LSP server logs for errors -- Try increasing trace level: `"wokelang.trace.server": "verbose"` - -## Development - -### Build Extension -```bash -cd editors/vscode -npm install -npm run compile -``` +## Roadmap -### Watch Mode (for development) -```bash -npm run watch -``` - -### Package Extension -```bash -npm install -g vsce -vsce package -``` - -This creates `wokelang-0.1.0.vsix` that can be installed with: -```bash -code --install-extension wokelang-0.1.0.vsix -``` +- **LSP client (AffineScript)** — restore completion / hover / diagnostics / + go-to-definition / formatting by driving the Rust `woke-lsp` server from an + AffineScript-authored client, once the estate ABI/FFI layer lands. Until then + the server can be used with any LSP-capable editor that lets you point at the + `woke-lsp` binary directly. ## License @@ -167,9 +72,7 @@ MPL-2.0 - [WokeLang Repository](https://github.com/hyperpolymath/wokelang) - [Report Issues](https://github.com/hyperpolymath/wokelang/issues) -- [Documentation](https://wokelang.org) ## Credits **Author:** Jonathan D.A. Jewell -**Co-Authored-By:** Claude Sonnet 4.5 diff --git a/editors/vscode/deno.json b/editors/vscode/deno.json deleted file mode 100644 index 0a90ca0..0000000 --- a/editors/vscode/deno.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "wokelang", - "version": "0.1.0", - "tasks": { - "vscode:prepublish": "rescript build", - "compile": "rescript build", - "watch": "rescript build -w", - "clean": "rescript clean" - }, - "imports": { - "vscode-languageclient": "npm:vscode-languageclient@^9.0.0", - "@rescript/core": "npm:@rescript/core@^1.5.0", - "rescript": "^12.0.0" - } -} \ No newline at end of file diff --git a/editors/vscode/lib/bs/.bsbuild b/editors/vscode/lib/bs/.bsbuild deleted file mode 100644 index deec221..0000000 --- a/editors/vscode/lib/bs/.bsbuild +++ /dev/null @@ -1,6 +0,0 @@ -2 -VSCode -Extension -src -1 -0 diff --git a/editors/vscode/lib/bs/.bsdeps b/editors/vscode/lib/bs/.bsdeps deleted file mode 100644 index 718a22f..0000000 --- a/editors/vscode/lib/bs/.bsdeps +++ /dev/null @@ -1,8 +0,0 @@ -11.1.4 -/var$REPOS_DIR/wokelang/editors/vscode -0 -0 -rescript.json 0x1.a5fb2b9d95036p+30 -src 0x1.a5fb2bebfb661p+30 -=== -/var$REPOS_DIR/wokelang/editors/vscode/node_modules/rescript/linux/rescript.exe 0x1.a5fb2d148a7aep+30 diff --git a/editors/vscode/lib/bs/.ninja_log b/editors/vscode/lib/bs/.ninja_log deleted file mode 100644 index 36253d9..0000000 --- a/editors/vscode/lib/bs/.ninja_log +++ /dev/null @@ -1,11 +0,0 @@ -# ninja log v6 -0 9 1769917253146234860 src/Extension.ast a299d631916658e7 -0 9 1769917253146234860 src/VSCode.ast dd13fb3938ebc585 -9 11 1769917253149234970 src/Extension.d 7f789596cdf19d39 -9 11 1769917253149234970 src/VSCode.d e65c06ef7edb2d0d -11 23 1769917253160235375 src/VSCode.cmj a6e7132f5d25b4ee -11 23 1769917253160235375 src/VSCode.cmi a6e7132f5d25b4ee -11 23 1769917253160235375 ../../src/VSCode.res.js a6e7132f5d25b4ee -23 37 1769917253174235890 src/Extension.cmj 3db99c41a11fa27c -23 37 1769917253174235890 src/Extension.cmi 3db99c41a11fa27c -23 37 1769917253174235890 ../../src/Extension.res.js 3db99c41a11fa27c diff --git a/editors/vscode/lib/bs/.sourcedirs.json b/editors/vscode/lib/bs/.sourcedirs.json deleted file mode 100644 index 1f1e629..0000000 --- a/editors/vscode/lib/bs/.sourcedirs.json +++ /dev/null @@ -1 +0,0 @@ -{"cmt_scan":[{"also_scan_build_root":true,"build_root":"lib/bs","scan_dirs":["src"]}],"dirs":["src"],"generated":[],"pkgs":[],"version":2} \ No newline at end of file diff --git a/editors/vscode/lib/bs/build.ninja b/editors/vscode/lib/bs/build.ninja deleted file mode 100644 index e69de29..0000000 diff --git a/editors/vscode/lib/bs/compiler-info.json b/editors/vscode/lib/bs/compiler-info.json deleted file mode 100644 index 884db78..0000000 --- a/editors/vscode/lib/bs/compiler-info.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "version": "12.1.0", - "bsc_path": "/var/home/hyper/.local/lib/node_modules/rescript/node_modules/@rescript/linux-x64/bin/bsc.exe", - "bsc_hash": "e71a4b341d54d39d77ed040eac08d002633dac2437fe69da2e0aa643219947ff", - "rescript_config_hash": "d6431ed02b6bb256367d12b4984ae134498b3cc367a2013c679564aaf60b59b9", - "runtime_path": "/var/home/hyper/.local/lib/node_modules/rescript/node_modules/@rescript/runtime", - "generated_at": "1769918070488" -} \ No newline at end of file diff --git a/editors/vscode/lib/bs/install.ninja b/editors/vscode/lib/bs/install.ninja deleted file mode 100644 index b09f15e..0000000 --- a/editors/vscode/lib/bs/install.ninja +++ /dev/null @@ -1,14 +0,0 @@ -rescript = 1 -rule cp - command = cp $i $out -rule touch - command = touch $out -o VSCode.cmi : cp ../bs/src/VSCode.cmi -o VSCode.cmj : cp ../bs/src/VSCode.cmj -o VSCode.cmt : cp ../bs/src/VSCode.cmt -o VSCode.res : cp ../../src/VSCode.res -o Extension.cmi : cp ../bs/src/Extension.cmi -o Extension.cmj : cp ../bs/src/Extension.cmj -o Extension.cmt : cp ../bs/src/Extension.cmt -o Extension.res : cp ../../src/Extension.res -build install.stamp : touch VSCode.cmi VSCode.cmj Extension.cmi Extension.cmj diff --git a/editors/vscode/lib/bs/src/Extension.ast b/editors/vscode/lib/bs/src/Extension.ast deleted file mode 100644 index f181543..0000000 Binary files a/editors/vscode/lib/bs/src/Extension.ast and /dev/null differ diff --git a/editors/vscode/lib/bs/src/Extension.cmj b/editors/vscode/lib/bs/src/Extension.cmj deleted file mode 100644 index b8222ad..0000000 Binary files a/editors/vscode/lib/bs/src/Extension.cmj and /dev/null differ diff --git a/editors/vscode/lib/bs/src/Extension.d b/editors/vscode/lib/bs/src/Extension.d deleted file mode 100644 index 47e8f2d..0000000 --- a/editors/vscode/lib/bs/src/Extension.d +++ /dev/null @@ -1 +0,0 @@ -src/Extension.cmj : src/VSCode.cmj src/VSCode.cmi diff --git a/editors/vscode/lib/bs/src/Extension.res b/editors/vscode/lib/bs/src/Extension.res deleted file mode 100644 index 7886847..0000000 --- a/editors/vscode/lib/bs/src/Extension.res +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// WokeLang VSCode Extension - ReScript Implementation - -open VSCode - -let client: ref> = ref(None) - -let startLanguageClient = (_context: extensionContext) => { - let config = Workspace.getConfiguration("wokelang") - let serverPath = switch Workspace.get(config, "serverPath") { - | Some(path) => path - | None => "woke-lsp" - } - - let serverOptions: LanguageClient.serverOptions = { - run: { - command: serverPath, - transport: Stdio, - }, - debug: { - command: serverPath, - transport: Stdio, - options: {env: Js.Dict.fromArray([("RUST_BACKTRACE", "1")])}, - }, - } - - let clientOptions: LanguageClient.clientOptions = { - documentSelector: [{scheme: "file", language: "wokelang"}], - synchronize: { - fileEvents: Workspace.createFileSystemWatcher("**/*.woke"), - }, - } - - let languageClient = LanguageClient.make( - "wokelang", - "WokeLang Language Server", - serverOptions, - clientOptions, - ) - - client := Some(languageClient) - let _ = LanguageClient.start(languageClient) - () -} - -let restartServer = (context: extensionContext) => { - switch client.contents { - | Some(c) => - let _ = LanguageClient.stop(c) - startLanguageClient(context) - | None => startLanguageClient(context) - } -} - -let showInfo = () => { - let _ = Window.showInformationMessage("WokeLang LSP extension v0.1.0 - Consent-aware programming language") - () -} - -let checkConsent = () => { - let _ = Window.showInformationMessage("Consent safety check: Analyzing capability usage patterns...") - () -} - -let formatDocument = () => { - let _ = Window.showInformationMessage("Formatting with WokeLang formatter...") - () -} - -let activate = (context: extensionContext) => { - startLanguageClient(context) - - // Register commands - let restartCmd = Commands.registerCommand("wokelang.restartServer", () => - Js.Promise.make((~resolve, ~reject as _) => { - restartServer(context) - resolve(.) - }) - ) - let infoCmd = Commands.registerCommand("wokelang.showInfo", () => - Js.Promise.make((~resolve, ~reject as _) => { - showInfo() - resolve(.) - }) - ) - let consentCmd = Commands.registerCommand("wokelang.checkConsent", () => - Js.Promise.make((~resolve, ~reject as _) => { - checkConsent() - resolve(.) - }) - ) - let formatCmd = Commands.registerCommand("wokelang.formatDocument", () => - Js.Promise.make((~resolve, ~reject as _) => { - formatDocument() - resolve(.) - }) - ) - - let _ = Js.Array2.push(context.subscriptions, restartCmd) - let _ = Js.Array2.push(context.subscriptions, infoCmd) - let _ = Js.Array2.push(context.subscriptions, consentCmd) - let _ = Js.Array2.push(context.subscriptions, formatCmd) - () -} - -let deactivate = () => { - switch client.contents { - | Some(c) => Some(LanguageClient.stop(c)) - | None => None - } -} diff --git a/editors/vscode/lib/bs/src/Extension.res.js b/editors/vscode/lib/bs/src/Extension.res.js deleted file mode 100644 index daf66f4..0000000 --- a/editors/vscode/lib/bs/src/Extension.res.js +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE - -import * as Vscode from "vscode"; -import * as Js_dict from "@rescript/runtime/lib/es6/Js_dict.js"; -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; -import * as Node from "vscode-languageclient/node"; - -let client = { - contents: undefined -}; - -function startLanguageClient(_context) { - let config = Vscode.workspace.getConfiguration("wokelang"); - let path = config.get("serverPath"); - let serverPath = path !== undefined ? path : "woke-lsp"; - let serverOptions_run = { - command: serverPath, - transport: 0 - }; - let serverOptions_debug = { - command: serverPath, - transport: 0, - options: { - env: Js_dict.fromArray([[ - "RUST_BACKTRACE", - "1" - ]]) - } - }; - let serverOptions = { - run: serverOptions_run, - debug: serverOptions_debug - }; - let clientOptions_documentSelector = [{ - scheme: "file", - language: "wokelang" - }]; - let clientOptions_synchronize = { - fileEvents: Vscode.workspace.createFileSystemWatcher("**/*.woke") - }; - let clientOptions = { - documentSelector: clientOptions_documentSelector, - synchronize: clientOptions_synchronize - }; - let languageClient = new Node.LanguageClient("wokelang", "WokeLang Language Server", serverOptions, clientOptions); - client.contents = Primitive_option.some(languageClient); - languageClient.start(); -} - -function restartServer(context) { - let c = client.contents; - if (c !== undefined) { - Primitive_option.valFromOption(c).stop(); - return startLanguageClient(context); - } else { - return startLanguageClient(context); - } -} - -function showInfo() { - Vscode.window.showInformationMessage("WokeLang LSP extension v0.1.0 - Consent-aware programming language"); -} - -function checkConsent() { - Vscode.window.showInformationMessage("Consent safety check: Analyzing capability usage patterns..."); -} - -function formatDocument() { - Vscode.window.showInformationMessage("Formatting with WokeLang formatter..."); -} - -function activate(context) { - startLanguageClient(context); - let restartCmd = Vscode.commands.registerCommand("wokelang.restartServer", () => new Promise((resolve, param) => { - restartServer(context); - resolve(); - })); - let infoCmd = Vscode.commands.registerCommand("wokelang.showInfo", () => new Promise((resolve, param) => { - Vscode.window.showInformationMessage("WokeLang LSP extension v0.1.0 - Consent-aware programming language"); - resolve(); - })); - let consentCmd = Vscode.commands.registerCommand("wokelang.checkConsent", () => new Promise((resolve, param) => { - Vscode.window.showInformationMessage("Consent safety check: Analyzing capability usage patterns..."); - resolve(); - })); - let formatCmd = Vscode.commands.registerCommand("wokelang.formatDocument", () => new Promise((resolve, param) => { - Vscode.window.showInformationMessage("Formatting with WokeLang formatter..."); - resolve(); - })); - context.subscriptions.push(restartCmd); - context.subscriptions.push(infoCmd); - context.subscriptions.push(consentCmd); - context.subscriptions.push(formatCmd); -} - -function deactivate() { - let c = client.contents; - if (c !== undefined) { - return Primitive_option.valFromOption(c).stop(); - } -} - -export { - client, - startLanguageClient, - restartServer, - showInfo, - checkConsent, - formatDocument, - activate, - deactivate, -} -/* vscode Not a pure module */ diff --git a/editors/vscode/lib/bs/src/VSCode.ast b/editors/vscode/lib/bs/src/VSCode.ast deleted file mode 100644 index 885efa5..0000000 Binary files a/editors/vscode/lib/bs/src/VSCode.ast and /dev/null differ diff --git a/editors/vscode/lib/bs/src/VSCode.cmj b/editors/vscode/lib/bs/src/VSCode.cmj deleted file mode 100644 index d3f4fa2..0000000 Binary files a/editors/vscode/lib/bs/src/VSCode.cmj and /dev/null differ diff --git a/editors/vscode/lib/bs/src/VSCode.d b/editors/vscode/lib/bs/src/VSCode.d deleted file mode 100644 index e69de29..0000000 diff --git a/editors/vscode/lib/bs/src/VSCode.res b/editors/vscode/lib/bs/src/VSCode.res deleted file mode 100644 index 7ee3614..0000000 --- a/editors/vscode/lib/bs/src/VSCode.res +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: MIT OR Apache-2.0 -// VSCode API bindings for ReScript - -type disposable -type fileSystemWatcher - -type extensionContext = { - subscriptions: array, -} - -module Workspace = { - type configuration - - @module("vscode") @scope("workspace") - external getConfiguration: string => configuration = "getConfiguration" - - @send external get: (configuration, string) => option = "get" - - @module("vscode") @scope("workspace") - external createFileSystemWatcher: string => fileSystemWatcher = "createFileSystemWatcher" -} - -module Window = { - @module("vscode") @scope("window") - external showInformationMessage: string => promise> = "showInformationMessage" - - @module("vscode") @scope("window") - external showErrorMessage: string => promise> = "showErrorMessage" -} - -module Commands = { - @module("vscode") @scope("commands") - external registerCommand: (string, unit => promise) => disposable = "registerCommand" -} - -module LanguageClient = { - type transportKind = | @as(0) Stdio - - type optionsType = {env?: Js.Dict.t} - - type runOptions = { - command: string, - transport: transportKind, - options?: optionsType, - } - - type serverOptions = { - run: runOptions, - debug: runOptions, - } - - type documentFilter = { - scheme: string, - language: string, - } - - type synchronizeOptions = {fileEvents: fileSystemWatcher} - - type clientOptions = { - documentSelector: array, - synchronize: synchronizeOptions, - } - - type t - - @module("vscode-languageclient/node") @new - external make: (string, string, serverOptions, clientOptions) => t = "LanguageClient" - - @send external start: t => promise = "start" - @send external stop: t => promise = "stop" -} diff --git a/editors/vscode/lib/bs/src/VSCode.res.js b/editors/vscode/lib/bs/src/VSCode.res.js deleted file mode 100644 index ee9914e..0000000 --- a/editors/vscode/lib/bs/src/VSCode.res.js +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE - - -let Workspace = {}; - -let Window = {}; - -let Commands = {}; - -let LanguageClient = {}; - -export { - Workspace, - Window, - Commands, - LanguageClient, -} -/* No side effect */ diff --git a/editors/vscode/lib/ocaml/Extension.cmj b/editors/vscode/lib/ocaml/Extension.cmj deleted file mode 100644 index b8222ad..0000000 Binary files a/editors/vscode/lib/ocaml/Extension.cmj and /dev/null differ diff --git a/editors/vscode/lib/ocaml/Extension.res b/editors/vscode/lib/ocaml/Extension.res deleted file mode 100644 index 7886847..0000000 --- a/editors/vscode/lib/ocaml/Extension.res +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// WokeLang VSCode Extension - ReScript Implementation - -open VSCode - -let client: ref> = ref(None) - -let startLanguageClient = (_context: extensionContext) => { - let config = Workspace.getConfiguration("wokelang") - let serverPath = switch Workspace.get(config, "serverPath") { - | Some(path) => path - | None => "woke-lsp" - } - - let serverOptions: LanguageClient.serverOptions = { - run: { - command: serverPath, - transport: Stdio, - }, - debug: { - command: serverPath, - transport: Stdio, - options: {env: Js.Dict.fromArray([("RUST_BACKTRACE", "1")])}, - }, - } - - let clientOptions: LanguageClient.clientOptions = { - documentSelector: [{scheme: "file", language: "wokelang"}], - synchronize: { - fileEvents: Workspace.createFileSystemWatcher("**/*.woke"), - }, - } - - let languageClient = LanguageClient.make( - "wokelang", - "WokeLang Language Server", - serverOptions, - clientOptions, - ) - - client := Some(languageClient) - let _ = LanguageClient.start(languageClient) - () -} - -let restartServer = (context: extensionContext) => { - switch client.contents { - | Some(c) => - let _ = LanguageClient.stop(c) - startLanguageClient(context) - | None => startLanguageClient(context) - } -} - -let showInfo = () => { - let _ = Window.showInformationMessage("WokeLang LSP extension v0.1.0 - Consent-aware programming language") - () -} - -let checkConsent = () => { - let _ = Window.showInformationMessage("Consent safety check: Analyzing capability usage patterns...") - () -} - -let formatDocument = () => { - let _ = Window.showInformationMessage("Formatting with WokeLang formatter...") - () -} - -let activate = (context: extensionContext) => { - startLanguageClient(context) - - // Register commands - let restartCmd = Commands.registerCommand("wokelang.restartServer", () => - Js.Promise.make((~resolve, ~reject as _) => { - restartServer(context) - resolve(.) - }) - ) - let infoCmd = Commands.registerCommand("wokelang.showInfo", () => - Js.Promise.make((~resolve, ~reject as _) => { - showInfo() - resolve(.) - }) - ) - let consentCmd = Commands.registerCommand("wokelang.checkConsent", () => - Js.Promise.make((~resolve, ~reject as _) => { - checkConsent() - resolve(.) - }) - ) - let formatCmd = Commands.registerCommand("wokelang.formatDocument", () => - Js.Promise.make((~resolve, ~reject as _) => { - formatDocument() - resolve(.) - }) - ) - - let _ = Js.Array2.push(context.subscriptions, restartCmd) - let _ = Js.Array2.push(context.subscriptions, infoCmd) - let _ = Js.Array2.push(context.subscriptions, consentCmd) - let _ = Js.Array2.push(context.subscriptions, formatCmd) - () -} - -let deactivate = () => { - switch client.contents { - | Some(c) => Some(LanguageClient.stop(c)) - | None => None - } -} diff --git a/editors/vscode/lib/ocaml/VSCode.cmj b/editors/vscode/lib/ocaml/VSCode.cmj deleted file mode 100644 index d3f4fa2..0000000 Binary files a/editors/vscode/lib/ocaml/VSCode.cmj and /dev/null differ diff --git a/editors/vscode/lib/ocaml/VSCode.res b/editors/vscode/lib/ocaml/VSCode.res deleted file mode 100644 index 7ee3614..0000000 --- a/editors/vscode/lib/ocaml/VSCode.res +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: MIT OR Apache-2.0 -// VSCode API bindings for ReScript - -type disposable -type fileSystemWatcher - -type extensionContext = { - subscriptions: array, -} - -module Workspace = { - type configuration - - @module("vscode") @scope("workspace") - external getConfiguration: string => configuration = "getConfiguration" - - @send external get: (configuration, string) => option = "get" - - @module("vscode") @scope("workspace") - external createFileSystemWatcher: string => fileSystemWatcher = "createFileSystemWatcher" -} - -module Window = { - @module("vscode") @scope("window") - external showInformationMessage: string => promise> = "showInformationMessage" - - @module("vscode") @scope("window") - external showErrorMessage: string => promise> = "showErrorMessage" -} - -module Commands = { - @module("vscode") @scope("commands") - external registerCommand: (string, unit => promise) => disposable = "registerCommand" -} - -module LanguageClient = { - type transportKind = | @as(0) Stdio - - type optionsType = {env?: Js.Dict.t} - - type runOptions = { - command: string, - transport: transportKind, - options?: optionsType, - } - - type serverOptions = { - run: runOptions, - debug: runOptions, - } - - type documentFilter = { - scheme: string, - language: string, - } - - type synchronizeOptions = {fileEvents: fileSystemWatcher} - - type clientOptions = { - documentSelector: array, - synchronize: synchronizeOptions, - } - - type t - - @module("vscode-languageclient/node") @new - external make: (string, string, serverOptions, clientOptions) => t = "LanguageClient" - - @send external start: t => promise = "start" - @send external stop: t => promise = "stop" -} diff --git a/editors/vscode/lib/rescript.lock b/editors/vscode/lib/rescript.lock deleted file mode 100644 index 2fa643e..0000000 --- a/editors/vscode/lib/rescript.lock +++ /dev/null @@ -1 +0,0 @@ -515149 \ No newline at end of file diff --git a/editors/vscode/package.json b/editors/vscode/package.json index c79230a..9cf5a5d 100644 --- a/editors/vscode/package.json +++ b/editors/vscode/package.json @@ -1,7 +1,7 @@ { "name": "wokelang", "displayName": "WokeLang", - "description": "Language support for WokeLang with LSP integration", + "description": "Syntax highlighting and language configuration for WokeLang (.woke). The LSP client is temporarily removed pending reimplementation in AffineScript — see the repository issues.", "version": "0.1.0", "publisher": "hyperpolymath", "license": "MPL-2.0", @@ -22,10 +22,6 @@ "capabilities", "programming language" ], - "activationEvents": [ - "onLanguage:wokelang" - ], - "main": "./src/Extension.res.js", "contributes": { "languages": [ { @@ -46,110 +42,6 @@ "scopeName": "source.wokelang", "path": "./syntaxes/wokelang.tmLanguage.json" } - ], - "configuration": { - "type": "object", - "title": "WokeLang", - "properties": { - "wokelang.serverPath": { - "type": "string", - "default": "woke-lsp", - "description": "Path to woke-lsp executable" - }, - "wokelang.enableDiagnostics": { - "type": "boolean", - "default": true, - "description": "Enable real-time diagnostics" - }, - "wokelang.enableCompletion": { - "type": "boolean", - "default": true, - "description": "Enable code completion" - }, - "wokelang.enableHover": { - "type": "boolean", - "default": true, - "description": "Enable hover information" - }, - "wokelang.enableFormatting": { - "type": "boolean", - "default": true, - "description": "Enable document formatting" - }, - "wokelang.trace.server": { - "type": "string", - "enum": [ - "off", - "messages", - "verbose" - ], - "default": "off", - "description": "Traces the communication between VS Code and the language server" - } - } - }, - "commands": [ - { - "command": "wokelang.restartServer", - "title": "Restart Language Server", - "category": "WokeLang" - }, - { - "command": "wokelang.showInfo", - "title": "Show Extension Info", - "category": "WokeLang" - }, - { - "command": "wokelang.formatDocument", - "title": "Format Document", - "category": "WokeLang" - }, - { - "command": "wokelang.checkConsent", - "title": "Check Consent Safety", - "category": "WokeLang" - } - ], - "menus": { - "editor/context": [ - { - "when": "editorLangId == wokelang", - "command": "wokelang.checkConsent", - "group": "wokelang" - }, - { - "when": "editorLangId == wokelang", - "command": "wokelang.formatDocument", - "group": "wokelang" - } - ] - }, - "keybindings": [ - { - "command": "wokelang.formatDocument", - "key": "ctrl+shift+f", - "mac": "cmd+shift+f", - "when": "editorLangId == wokelang" - }, - { - "command": "wokelang.checkConsent", - "key": "ctrl+shift+c", - "mac": "cmd+shift+c", - "when": "editorLangId == wokelang" - } ] - }, - "scripts": { - "vscode:prepublish": "rescript build", - "compile": "rescript build", - "watch": "rescript build -w", - "clean": "rescript clean" - }, - "devDependencies": { - "rescript": "^12.0.0" - }, - "dependencies": { - "vscode-languageclient": "^9.0.0", - "@rescript/core": "^1.5.0" } } diff --git a/editors/vscode/rescript.json b/editors/vscode/rescript.json deleted file mode 100644 index 74cf823..0000000 --- a/editors/vscode/rescript.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "wokelang-vscode", - "version": "0.1.0", - "sources": [ - { - "dir": "src", - "subdirs": true - } - ], - "package-specs": [ - { - "module": "esmodule", - "in-source": true - } - ], - "suffix": ".res.js", - "bs-dependencies": [], - "warnings": { - "error": "+101" - } -} diff --git a/editors/vscode/src/Extension.res b/editors/vscode/src/Extension.res deleted file mode 100644 index 7886847..0000000 --- a/editors/vscode/src/Extension.res +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// WokeLang VSCode Extension - ReScript Implementation - -open VSCode - -let client: ref> = ref(None) - -let startLanguageClient = (_context: extensionContext) => { - let config = Workspace.getConfiguration("wokelang") - let serverPath = switch Workspace.get(config, "serverPath") { - | Some(path) => path - | None => "woke-lsp" - } - - let serverOptions: LanguageClient.serverOptions = { - run: { - command: serverPath, - transport: Stdio, - }, - debug: { - command: serverPath, - transport: Stdio, - options: {env: Js.Dict.fromArray([("RUST_BACKTRACE", "1")])}, - }, - } - - let clientOptions: LanguageClient.clientOptions = { - documentSelector: [{scheme: "file", language: "wokelang"}], - synchronize: { - fileEvents: Workspace.createFileSystemWatcher("**/*.woke"), - }, - } - - let languageClient = LanguageClient.make( - "wokelang", - "WokeLang Language Server", - serverOptions, - clientOptions, - ) - - client := Some(languageClient) - let _ = LanguageClient.start(languageClient) - () -} - -let restartServer = (context: extensionContext) => { - switch client.contents { - | Some(c) => - let _ = LanguageClient.stop(c) - startLanguageClient(context) - | None => startLanguageClient(context) - } -} - -let showInfo = () => { - let _ = Window.showInformationMessage("WokeLang LSP extension v0.1.0 - Consent-aware programming language") - () -} - -let checkConsent = () => { - let _ = Window.showInformationMessage("Consent safety check: Analyzing capability usage patterns...") - () -} - -let formatDocument = () => { - let _ = Window.showInformationMessage("Formatting with WokeLang formatter...") - () -} - -let activate = (context: extensionContext) => { - startLanguageClient(context) - - // Register commands - let restartCmd = Commands.registerCommand("wokelang.restartServer", () => - Js.Promise.make((~resolve, ~reject as _) => { - restartServer(context) - resolve(.) - }) - ) - let infoCmd = Commands.registerCommand("wokelang.showInfo", () => - Js.Promise.make((~resolve, ~reject as _) => { - showInfo() - resolve(.) - }) - ) - let consentCmd = Commands.registerCommand("wokelang.checkConsent", () => - Js.Promise.make((~resolve, ~reject as _) => { - checkConsent() - resolve(.) - }) - ) - let formatCmd = Commands.registerCommand("wokelang.formatDocument", () => - Js.Promise.make((~resolve, ~reject as _) => { - formatDocument() - resolve(.) - }) - ) - - let _ = Js.Array2.push(context.subscriptions, restartCmd) - let _ = Js.Array2.push(context.subscriptions, infoCmd) - let _ = Js.Array2.push(context.subscriptions, consentCmd) - let _ = Js.Array2.push(context.subscriptions, formatCmd) - () -} - -let deactivate = () => { - switch client.contents { - | Some(c) => Some(LanguageClient.stop(c)) - | None => None - } -} diff --git a/editors/vscode/src/Extension.res.js b/editors/vscode/src/Extension.res.js deleted file mode 100644 index daf66f4..0000000 --- a/editors/vscode/src/Extension.res.js +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE - -import * as Vscode from "vscode"; -import * as Js_dict from "@rescript/runtime/lib/es6/Js_dict.js"; -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; -import * as Node from "vscode-languageclient/node"; - -let client = { - contents: undefined -}; - -function startLanguageClient(_context) { - let config = Vscode.workspace.getConfiguration("wokelang"); - let path = config.get("serverPath"); - let serverPath = path !== undefined ? path : "woke-lsp"; - let serverOptions_run = { - command: serverPath, - transport: 0 - }; - let serverOptions_debug = { - command: serverPath, - transport: 0, - options: { - env: Js_dict.fromArray([[ - "RUST_BACKTRACE", - "1" - ]]) - } - }; - let serverOptions = { - run: serverOptions_run, - debug: serverOptions_debug - }; - let clientOptions_documentSelector = [{ - scheme: "file", - language: "wokelang" - }]; - let clientOptions_synchronize = { - fileEvents: Vscode.workspace.createFileSystemWatcher("**/*.woke") - }; - let clientOptions = { - documentSelector: clientOptions_documentSelector, - synchronize: clientOptions_synchronize - }; - let languageClient = new Node.LanguageClient("wokelang", "WokeLang Language Server", serverOptions, clientOptions); - client.contents = Primitive_option.some(languageClient); - languageClient.start(); -} - -function restartServer(context) { - let c = client.contents; - if (c !== undefined) { - Primitive_option.valFromOption(c).stop(); - return startLanguageClient(context); - } else { - return startLanguageClient(context); - } -} - -function showInfo() { - Vscode.window.showInformationMessage("WokeLang LSP extension v0.1.0 - Consent-aware programming language"); -} - -function checkConsent() { - Vscode.window.showInformationMessage("Consent safety check: Analyzing capability usage patterns..."); -} - -function formatDocument() { - Vscode.window.showInformationMessage("Formatting with WokeLang formatter..."); -} - -function activate(context) { - startLanguageClient(context); - let restartCmd = Vscode.commands.registerCommand("wokelang.restartServer", () => new Promise((resolve, param) => { - restartServer(context); - resolve(); - })); - let infoCmd = Vscode.commands.registerCommand("wokelang.showInfo", () => new Promise((resolve, param) => { - Vscode.window.showInformationMessage("WokeLang LSP extension v0.1.0 - Consent-aware programming language"); - resolve(); - })); - let consentCmd = Vscode.commands.registerCommand("wokelang.checkConsent", () => new Promise((resolve, param) => { - Vscode.window.showInformationMessage("Consent safety check: Analyzing capability usage patterns..."); - resolve(); - })); - let formatCmd = Vscode.commands.registerCommand("wokelang.formatDocument", () => new Promise((resolve, param) => { - Vscode.window.showInformationMessage("Formatting with WokeLang formatter..."); - resolve(); - })); - context.subscriptions.push(restartCmd); - context.subscriptions.push(infoCmd); - context.subscriptions.push(consentCmd); - context.subscriptions.push(formatCmd); -} - -function deactivate() { - let c = client.contents; - if (c !== undefined) { - return Primitive_option.valFromOption(c).stop(); - } -} - -export { - client, - startLanguageClient, - restartServer, - showInfo, - checkConsent, - formatDocument, - activate, - deactivate, -} -/* vscode Not a pure module */ diff --git a/editors/vscode/src/VSCode.res b/editors/vscode/src/VSCode.res deleted file mode 100644 index 7ee3614..0000000 --- a/editors/vscode/src/VSCode.res +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: MIT OR Apache-2.0 -// VSCode API bindings for ReScript - -type disposable -type fileSystemWatcher - -type extensionContext = { - subscriptions: array, -} - -module Workspace = { - type configuration - - @module("vscode") @scope("workspace") - external getConfiguration: string => configuration = "getConfiguration" - - @send external get: (configuration, string) => option = "get" - - @module("vscode") @scope("workspace") - external createFileSystemWatcher: string => fileSystemWatcher = "createFileSystemWatcher" -} - -module Window = { - @module("vscode") @scope("window") - external showInformationMessage: string => promise> = "showInformationMessage" - - @module("vscode") @scope("window") - external showErrorMessage: string => promise> = "showErrorMessage" -} - -module Commands = { - @module("vscode") @scope("commands") - external registerCommand: (string, unit => promise) => disposable = "registerCommand" -} - -module LanguageClient = { - type transportKind = | @as(0) Stdio - - type optionsType = {env?: Js.Dict.t} - - type runOptions = { - command: string, - transport: transportKind, - options?: optionsType, - } - - type serverOptions = { - run: runOptions, - debug: runOptions, - } - - type documentFilter = { - scheme: string, - language: string, - } - - type synchronizeOptions = {fileEvents: fileSystemWatcher} - - type clientOptions = { - documentSelector: array, - synchronize: synchronizeOptions, - } - - type t - - @module("vscode-languageclient/node") @new - external make: (string, string, serverOptions, clientOptions) => t = "LanguageClient" - - @send external start: t => promise = "start" - @send external stop: t => promise = "stop" -} diff --git a/editors/vscode/src/VSCode.res.js b/editors/vscode/src/VSCode.res.js deleted file mode 100644 index ee9914e..0000000 --- a/editors/vscode/src/VSCode.res.js +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE - - -let Workspace = {}; - -let Window = {}; - -let Commands = {}; - -let LanguageClient = {}; - -export { - Workspace, - Window, - Commands, - LanguageClient, -} -/* No side effect */ diff --git a/src/parser/mod.rs b/src/parser/mod.rs index ac1a8b6..5cbd821 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -36,6 +36,11 @@ pub struct Parser<'a> { tokens: Vec>, source: &'a str, current: usize, + /// When true, a `{` following an identifier is not treated as the start of + /// a record literal. Used in positions like a `decide based on` scrutinee + /// where the `{` opens the match block, not a record (cf. how Rust + /// disambiguates `if x { }` from a struct literal). + no_struct_literal: bool, } /// Operator precedence levels (higher = tighter binding) @@ -60,6 +65,7 @@ impl<'a> Parser<'a> { tokens, source, current: 0, + no_struct_literal: false, } } @@ -245,8 +251,10 @@ impl<'a> Parser<'a> { self.advance(); let end = self.tokens[self.current - 1].span.end; - // Check if it's a record literal (Type { field: value, ... }) - if matches!(self.peek(), Token::LBrace) { + // Check if it's a record literal (Type { field: value, ... }). + // Suppressed in `no_struct_literal` positions so the `{` can + // instead open an enclosing block (e.g. a match block). + if !self.no_struct_literal && matches!(self.peek(), Token::LBrace) { self.parse_record_literal(name, start) } // Check if it's a function call @@ -892,7 +900,12 @@ impl<'a> Parser<'a> { self.expect(Token::Decide, "decide")?; self.expect(Token::Based, "based")?; self.expect(Token::On, "on")?; + // Parse the scrutinee with record-literal syntax suppressed, so the `{` + // that follows opens the match block rather than a record literal. + let prev_no_struct_literal = self.no_struct_literal; + self.no_struct_literal = true; let scrutinee = self.parse_expression()?; + self.no_struct_literal = prev_no_struct_literal; self.expect(Token::LBrace, "{")?; let mut arms = Vec::new(); diff --git a/src/typechecker/mod.rs b/src/typechecker/mod.rs index d4e4d3a..2314a9b 100644 --- a/src/typechecker/mod.rs +++ b/src/typechecker/mod.rs @@ -1494,7 +1494,11 @@ mod tests { #[test] fn test_type_checker_new() { let checker = TypeChecker::new(); - assert_eq!(checker.env.bindings.len(), 0); + // The type checker seeds a prelude of builtin bindings on construction. + assert!(!checker.env.bindings.is_empty()); + assert!(checker.env.bindings.contains_key("print")); + assert!(checker.env.bindings.contains_key("toString")); + assert!(checker.env.bindings.contains_key("Okay")); } #[test] diff --git a/src/vm/bytecode.rs b/src/vm/bytecode.rs index 1f4b237..a27d320 100644 --- a/src/vm/bytecode.rs +++ b/src/vm/bytecode.rs @@ -63,7 +63,9 @@ pub enum OpCode { JumpIfTrue(usize), // Functions - /// Call a function with N arguments + /// Call the function at the given index in the program's function table. + /// Arguments are expected on top of the stack in parameter order; the + /// callee's arity is read from its definition. Call(usize), /// Return from function Return, diff --git a/src/vm/compiler.rs b/src/vm/compiler.rs index 484c856..d14e14d 100644 --- a/src/vm/compiler.rs +++ b/src/vm/compiler.rs @@ -483,13 +483,21 @@ impl BytecodeCompiler { } Expr::Call(func_name, args) => { - // Compile arguments + // Resolve the callee to its function-table index. The arity is + // recovered at runtime from the called function's definition. + let func_idx = *self + .function_indices + .get(func_name) + .ok_or_else(|| CompileError::UndefinedFunction(func_name.clone()))?; + + // Compile arguments left-to-right so they sit on top of the + // stack in parameter order, ready to become the callee's locals. for arg in args { self.compile_expr(&arg.node, func)?; } - // Emit call - func.emit(OpCode::Call(args.len())); + // Emit call to the resolved function index. + func.emit(OpCode::Call(func_idx)); Ok(()) } diff --git a/src/vm/machine.rs b/src/vm/machine.rs index 02f24e5..737f01b 100644 --- a/src/vm/machine.rs +++ b/src/vm/machine.rs @@ -285,11 +285,36 @@ impl VirtualMachine { } } + OpCode::Call(callee_idx) => { + let callee = self + .program + .get_function(callee_idx) + .ok_or(VMError::InvalidFunctionIndex(callee_idx))?; + let arity = callee.arity; + + // Arguments sit on top of the stack in parameter order; the + // new frame's base points at the first argument so that + // locals 0..arity coincide with the arguments. + let bp = self + .stack + .len() + .checked_sub(arity) + .ok_or(VMError::StackUnderflow)?; + + self.frames.push(CallFrame { + function_idx: callee_idx, + ip: 0, + bp, + }); + } + OpCode::Return => { let return_value = self.pop()?; - // Pop call frame - self.frames.pop(); + // Pop call frame and discard its locals/arguments by + // truncating the stack back to the frame's base pointer. + let frame = self.frames.pop().ok_or(VMError::InvalidIP)?; + self.stack.truncate(frame.bp); // If no more frames, we're done if self.frames.is_empty() { diff --git a/wiki/Architecture.adoc b/wiki/Architecture.adoc new file mode 100644 index 0000000..f8d497f --- /dev/null +++ b/wiki/Architecture.adoc @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: MPL-2.0 +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell += WokeLang — Architecture +:toc: macro +:icons: font + +link:Home.adoc[← Wiki home] + +toc::[] + +WokeLang has two implementations and one proof frontier: + +. a *primary Rust toolchain* (`src/`) — the production compiler/interpreter and + tooling; +. an *OCaml reference core* (`core/`) — an independent semantics implementation + and end-to-end cross-check; +. the *echo-types / Isabelle frontier* — a machine-checked grounding of the + consent / affine-safety guarantees. + +== 1. The primary Rust toolchain (`src/`) + +The production toolchain compiles and runs WokeLang. It builds three binaries: +`woke` (CLI + REPL), `woke-lsp` (language server), and `woke-dap` (debug +adapter). It has *173 library tests passing*. + +=== Compiler pipeline + +[source] +---- +.woke source + │ + ▼ +src/lexer/ tokeniser (logos): remember, measured in, only if okay, + │ thanks to, then, … + ▼ +src/parser/ recursive-descent parser + │ + ▼ +src/ast/ WokeLang AST + │ + ▼ +src/typechecker/ Hindley-Milner-style inference + Unit dimensional analysis + │ (e.g. km + km is valid; km + kg is a type error) + │ + ├──► src/interpreter/ tree-walking interpreter → woke run + │ + └──► src/vm/ bytecode compiler + stack machine + optimizer + → woke compile / woke run-vm +---- + +=== Component map + +[cols="1,3", options="header"] +|=== +| Module | Responsibility + +| `src/lexer/` +| Tokenises `.woke` text (using `logos`), including WokeLang-specific tokens. + +| `src/parser/` + `src/ast/` +| Recursive-descent parsing into the WokeLang AST. + +| `src/typechecker/` +| Static inference and the `Unit` enum for dimensional analysis. + `TypeChecker::new` seeds a ~64-binding builtin prelude (including `Result` / + echo constructors). + +| `src/interpreter/` +| Tree-walking evaluation for `woke run`. + +| `src/vm/` +| Bytecode VM: `compiler`, `machine`, `bytecode`, `optimizer`. + +| `src/lsp/` +| Language Server Protocol (built as `woke-lsp`). + +| `src/dap/` +| Debug Adapter Protocol (built as `woke-dap`). + +| `src/formatter/` · `src/linter/` · `src/security/` +| Canonical formatter, style + consent-gate lints, and security analysis passes. + +| `src/stdlib/` +| Standard library: `array`, `chan`, `io`, `json`, `math`, `net`, `string`, + `time`. `io` and `net` route side effects through the consent machinery. + +| `src/abi/` +| Idris2 ABI definitions (`Foreign.idr`, `Layout.idr`, `Types.idr`). + +| `src/ffi/` +| Rust C-ABI FFI bridge (`c_api.rs`). + +| `src/codegen/` +| Code-generation scaffolding (`WasmCompiler`) for a future WASM backend — not + yet wired into the build. + +| `src/modules.rs` · `src/repl.rs` · `src/sexpr.rs` +| Module system, REPL loop, and an S-expression AST dump. +|=== + +NOTE: `compiler/wokelang-wasm/` is a separate experimental Rust crate exploring +WASM compilation. Like `src/codegen/`, the WASM target is a design commitment, +not a working backend. + +== 2. The OCaml reference core (`core/`) + +`core/` is a smaller, independent implementation of the language semantics, +built with `dune`: + +[cols="1,3", options="header"] +|=== +| File | Role + +| `core/lexer.mll` +| `ocamllex` lexer. + +| `core/parser.mly` +| `menhir` parser (the project's `dune-project` declares `(using menhir 2.1)`). + +| `core/ast.ml` +| AST definitions. + +| `core/eval.ml` +| Evaluator. + +| `core/main.ml` +| Entry point. +|=== + +The OCaml core exists to *cross-check the Rust toolchain*: running the same +programs through both implementations grounds the end-to-end (`e2e`) CI gate and +gives an independent reference for the language's semantics. (Note: +`wokelang.opam` is currently an empty stub; the core builds from `dune-project`.) + +== 3. The echo-types / Isabelle frontier + +The frontier workstream makes the consent / affine-safety guarantees +*machine-checked from near first principles*: + +* *Substrate.* WokeLang consumes `hyperpolymath/echo-types` — a constructive + Agda formalization of *fiber-based structured loss* ("echo types", + `Echo f y := Σ (x : A) , (f x ≡ y)`). This is the source of truth for the + loss / consent reasoning. +* *Integration.* Echo types are being integrated into the typechecker so the + language can reason about what information is *lost* (and therefore what + consent / affine-use obligations arise) without the user doing it by hand. +* *Proof narrative.* The goal is an end-to-end, near-first-principles + machine-checked proof narrative — *Isabelle preferred* — that backs the + axiomatic guarantees in `spec/axiomatic-semantics.md` (consent safety, + consent monotonicity, worker isolation, gentle error handling). + +This is the architectural payoff: *the language sorts the hard consent / +affine-safety reasoning so users never have to.* + +== Build at a glance + +[source,bash] +---- +# Rust toolchain +cargo build --release # → woke, woke-lsp, woke-dap +cargo test # 173 library tests + +# OCaml reference core +dune build ./core +dune runtest ./core +---- + +Reproducible environments are provided by Guix (`guix.scm`, primary) and Nix +(`flake.nix`, fallback). The production toolchain needs only *Rust stable* +(`.tool-versions` pins `rust stable`). + +== Specification + +The canonical language definition lives in `spec/`: + +* `grammar.ebnf` — the EBNF grammar. +* `axiomatic-semantics.md` — consent Hoare logic and the key theorems. +* `system-specs.md` — system-level specification. +* `SPEC.core.scm` — the core spec in the RSR meta-format. + +See also link:Overview.adoc[Overview] for the language features and +link:CI-and-Governance.adoc[CI & Governance] for how the toolchain is gated. diff --git a/wiki/CI-and-Governance.adoc b/wiki/CI-and-Governance.adoc new file mode 100644 index 0000000..9e06164 --- /dev/null +++ b/wiki/CI-and-Governance.adoc @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: MPL-2.0 +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell += WokeLang — CI & Governance +:toc: macro +:icons: font + +link:Home.adoc[← Wiki home] + +toc::[] + +WokeLang follows the *Hyperpolymath Standard*: an MPL-2.0 licence, a strict +allowed/banned language policy, a multi-workflow CI suite built on thin-wrapper +reusable workflows from `hyperpolymath/standards`, and a *dogfooding gate* in +which the repository applies its own tooling to itself. + +== CI workflow suite + +The CI suite is described in the project state (`.machine_readable/6a2/STATE.a2ml`) +as a *20-workflow* GitHub Actions suite. The workflow files currently present +under `.github/workflows/` are: + +[cols="1,3", options="header"] +|=== +| Workflow | Purpose + +| `rust-ci.yml` +| Build and test the Rust toolchain (the 173 library tests). + +| `ocaml-core.yml` +| Build and test the OCaml reference core (`dune`). + +| `e2e.yml` +| End-to-end cross-check (Rust toolchain ↔ OCaml core). + +| `dogfood-gate.yml` +| The dogfooding gate — applies WokeLang's own tooling (see below). + +| `governance.yml` +| Enforces the Hyperpolymath Standard language policy and repo conventions. + +| `security.yml` +| Security checks. + +| `cargo-audit.yml` +| Audits Rust dependencies for known advisories. + +| `codeql.yml` +| CodeQL static analysis. + +| `scorecard.yml` · `scorecard-enforcer.yml` +| OpenSSF Scorecard supply-chain posture, plus enforcement. + +| `secret-scanner.yml` +| Scans for committed secrets. + +| `hypatia-scan.yml` +| Hypatia neurosymbolic / symbolic-rule security scan. + +| `cflite_pr.yml` · `cflite_batch.yml` +| ClusterFuzzLite fuzzing (per-PR and batch) over the `fuzz/` harnesses. + +| `workflow-linter.yml` +| Lints the workflow definitions themselves. + +| `boj-build.yml` +| Static-site / publish build (boj-server trigger; see `anchors/ANCHOR.a2ml`). + +| `ghcr-publish.yml` +| Publishes the container image. + +| `mirror.yml` +| Mirrors the repository. + +| `instant-sync.yml` +| Propagates changes across the estate on push. +|=== + +NOTE: The count of literal `.yml` files may differ slightly from the headline +"20 workflows" figure recorded in the machine-readable state, as some gates are +composed of multiple jobs or split across files. Treat +`.machine_readable/6a2/STATE.a2ml` and `PLAYBOOK.a2ml` as the canonical record of +the intended gate set. + +== The dogfooding gate + +The `dogfood-gate` workflow has WokeLang *apply its own ecosystem tooling to its +own repository*. Per `PLAYBOOK.a2ml`, the gate runs: + +* *a2ml lint* — validates the machine-readable artefacts under + `.machine_readable/`. +* *K9 self-validation* — the K9 self-validating contractiles + (`.machine_readable/svc/k9/`). +* *empty-lint* — catches empty / placeholder files. +* *Groove discovery* — exercises the Groove HTTP service-discovery protocol so + WokeLang's capabilities are announceable to the estate. +* *eclexiaiser* — repository hygiene checks. + +This is the practical expression of WokeLang being a first-class member of the +hyperpolymath estate rather than a passive consumer of standards. + +== Language policy (Hyperpolymath Standard) + +Governance is enforced, not just documented. The policy is enforced by the +`governance` workflow and recorded in `.machine_readable/6a2/AGENTIC.a2ml` and +the root `CLAUDE.md`. + +=== Allowed + +Rust (primary toolchain), OCaml (the reference core and the AffineScript-compiler +lineage), AffineScript (estate-primary application language), Deno (runtime / +package management), Gleam, Bash/POSIX, Nickel (config), Guile Scheme (state +files), Julia (batch/data), Ada (safety-critical), and Tauri / Dioxus for mobile. + +=== Banned (with replacements) + +[cols="1,1", options="header"] +|=== +| Banned | Replacement + +| TypeScript | AffineScript +| Node.js / npm / Bun / pnpm / yarn | Deno +| Go | Rust +| Python | Julia / Rust +| Java / Kotlin / Swift | Rust / Tauri / Dioxus +| React Native / Flutter / Dart | Tauri / Dioxus +|=== + +This policy is *live*: the VS Code extension's LSP client was *removed* because +it was written in ReScript (banned estate-wide); the AffineScript +reimplementation is tracked in issue #78. The single-exception drift risk — one +banned-language exception broadening into a policy violation — is an explicit +anti-drift concern in `META.a2ml`. + +== Security and proof-cleanliness requirements + +* SPDX `MPL-2.0` header on *every* file. +* No MD5/SHA1 for security (SHA-256+); HTTPS-only; no hardcoded secrets; + SHA-pinned dependencies. +* No proof / unsafe escape hatches anywhere: `believe_me`, `assert_total`, + `sorry`, `Admitted`, `unsafeCoerce`, `Obj.magic` — these would silently void + the echo-types / Isabelle consent-safety proofs. +* Machine-readable files (`.scm` / `.a2ml`) live *only* under + `.machine_readable/`, never the repository root. + +== Contractiles and self-validation + +WokeLang uses the hyperpolymath *contractile* system. The verb contractiles live +under `contractiles/` (mirrored in `.machine_readable/contractiles/`): + +* `must/` — mandatory requirements (the `Mustfile`; `must run` gates commits and + releases). +* `trust/` — trust boundaries. +* `dust/` — external dependencies. +* `bust/` — teardown / cleanup contracts. + +*K9 self-validation* templates (Kennel / Yard / Hunt trust levels) live under +`.machine_readable/svc/k9/`. Per ADR-001, K9 lives in `svc/` rather than +`contractiles/` so the contractile directory stays a pure verb set. + +== Where the canonical state lives + +[cols="1,3", options="header"] +|=== +| Artefact | Contents + +| `.machine_readable/6a2/STATE.a2ml` +| Current project state, completion %, CI gate list, last shepherd note. + +| `.machine_readable/6a2/META.a2ml` +| Architecture decisions (ADRs), governance, maintenance axes. + +| `.machine_readable/6a2/ECOSYSTEM.a2ml` +| Position in the estate, related projects, integration points. + +| `.machine_readable/6a2/PLAYBOOK.a2ml` +| Build / deploy / incident-response / release runbook. + +| `.machine_readable/bot_directives/` +| Automation-fleet hooks (hypatia, gitbot-fleet, git-private-farm). + +| `0-AI-MANIFEST.a2ml` +| AI agent entry point (read first). +|=== + +See link:Architecture.adoc[Architecture] for the build details and +link:Roadmap.adoc[Roadmap] for what is gated next. diff --git a/wiki/Home.adoc b/wiki/Home.adoc new file mode 100644 index 0000000..02bdf11 --- /dev/null +++ b/wiki/Home.adoc @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MPL-2.0 +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell += WokeLang Wiki +:toc: macro +:icons: font + +Welcome to the in-tree wiki for *WokeLang* — a human-centered, consent-driven +programming language. This wiki distils the README, `EXPLAINME.adoc`, the +language spec, and the machine-readable project state into a short, accurate set +of pages. It is the bleeding-edge entry point for understanding the project. + +[IMPORTANT] +==== +WokeLang is at version *0.1.0*, phase *implementation* (~35% complete). The pages +below distinguish *what is implemented* from *what is designed*. Where a feature +is a design commitment rather than working code, it is labelled as such. +==== + +== Navigation + +[cols="1,3", options="header"] +|=== +| Page | What it covers + +| link:Overview.adoc[Overview] +| What WokeLang is, who it is for, its defining consent / affine-safety idea, and + the signature language features. + +| link:Architecture.adoc[Architecture] +| The primary Rust toolchain (`src/`), the OCaml reference core (`core/`), and the + echo-types / Isabelle proof frontier. + +| link:CI-and-Governance.adoc[CI & Governance] +| The GitHub Actions workflow suite, the dogfooding gate, and the Hyperpolymath + Standard language policy. + +| link:Roadmap.adoc[Roadmap] +| Current state, near-term work, and long-term direction. +|=== + +== One-paragraph summary + +WokeLang makes *consent* and *affine-use safety* first-class: the type system is +intended to discharge the hard reasoning about destructive or sensitive +operations so the user does not have to. The production implementation is a Rust +toolchain (lexer, parser, typechecker, bytecode VM, tree-walking interpreter, +LSP, DAP, formatter, linter, REPL, stdlib); an OCaml reference core provides an +independent semantics cross-check. The frontier workstream integrates *echo +types* — a constructive Agda formalization of fiber-based structured loss — into +the typechecker, backed by a machine-checked proof narrative. + +== Source documents + +This wiki is derived from, and should stay consistent with: + +* `README.adoc` — project overview and quick start. +* `EXPLAINME.adoc` — "claims vs. receipts" honesty pass over the codebase. +* `ROADMAP.adoc` — the headline roadmap. +* `spec/` — `grammar.ebnf`, `axiomatic-semantics.md`, `system-specs.md`. +* `.machine_readable/6a2/` — structured project state (`STATE`, `META`, + `ECOSYSTEM`, `AGENTIC`, `NEUROSYM`, `PLAYBOOK`). +* `arxiv-consent-aware-programming.tex` — the research paper. + +== Author + +Jonathan D.A. Jewell · Licence: MPL-2.0 diff --git a/wiki/Overview.adoc b/wiki/Overview.adoc new file mode 100644 index 0000000..1107be9 --- /dev/null +++ b/wiki/Overview.adoc @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: MPL-2.0 +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell += WokeLang — Overview +:toc: macro +:icons: font + +link:Home.adoc[← Wiki home] + +toc::[] + +== What WokeLang is + +WokeLang is a *human-centered, consent-driven* programming language. Its defining +goal is that the *type system discharges the hard consent and affine-use safety +reasoning for the user*: dangerous or sensitive operations are scaffolded at the +language level so they cannot happen silently, and the programmer is not left to +enforce these properties by convention. + +Three design principles run through the language: + +. *Human-readable syntax* — English-like keywords (`to`, `remember`, `when`, + `otherwise`, `give back`). +. *Ethical scaffolding* — consent gates, gratitude blocks, and empathy + annotations are part of the language, not comments. +. *Type safety with dimensional analysis* — units of measure are checked at + compile time. + +== Who it is for + +WokeLang targets settings where *the consequences of code matter to people*: +software that performs destructive actions, accesses external resources, or +operates on sensitive data. The language is also the reference implementation for +research on consent-aware programming (`arxiv-consent-aware-programming.tex`). + +== The consent / affine-safety idea + +WokeLang's axiomatic semantics extend Hoare logic with *consent preconditions*. +A consent Hoare triple `{P, C} S {Q, C'}` carries a set `C` of active consents +alongside the usual pre/post-conditions. The core guarantees (from +`spec/axiomatic-semantics.md`) include: + +* *Consent safety* — no operation that requires consent can execute unless the + corresponding consent is in `C`; the consent gate (`only if okay`) is the only + way to add to `C`. +* *Consent monotonicity* — within a session, `C` only grows: + `{P, C} S {Q, C'} ⟹ C ⊆ C'`. +* *Worker isolation* — spawned workers cannot touch the parent's mutable state; + they communicate only through channels. +* *Gentle error handling* — an `attempt safely` block never terminates the + program; errors are caught and a reassurance message is shown. + +On the *frontier*, these guarantees are being grounded in *echo types* +(`hyperpolymath/echo-types`), a constructive Agda formalization of fiber-based +structured loss, integrated into the typechecker — see +link:Architecture.adoc[Architecture]. + +== Signature language features + +[cols="1,2,2", options="header"] +|=== +| Feature | Syntax | Status + +| Consent gates +| `only if okay "Delete?" { ... }` +| Implemented (see `examples/08_consent.woke`, `22_consent_system.woke`) + +| Gratitude blocks +| `thanks to { "Alice" -> "Fixed X!" }` +| Implemented (`examples/17_gratitude.woke`); pure metadata, no side effects + +| Units of measure +| `remember x = 5 measured in km` +| Implemented; mismatched units are a compile-time type error + +| Pipelines +| `data then clean then analyze` +| Implemented + +| Empathy annotations +| `@feeling(confident=true)` +| Implemented as authorial metadata + +| Result type +| `Okay(v)` / `Oops(e)`, `unwrap` +| Implemented + +| Pragmas +| `#care on`, `#strict on` +| Implemented (extra validation / warnings-as-errors) + +| WASM target +| compile to WebAssembly +| *Design commitment* — codegen scaffold only, not wired into the build + +| Blockchain / Vyper FFI +| `vyper call "..."` +| *Design commitment* — described in the spec/paper; no bridge in the tree +|=== + +== A taste of the syntax + +[source] +---- +to calculateArea(width, height) { + give back width * height; +} + +to main() { + remember result = calculateArea(5, 10) measured in m; + when result > 20 { + print("Large area"); + } otherwise { + print("Small area"); + } + + only if okay "Write the result to disk?" { + save(result); + } + + thanks to { "Reviewer" -> "Caught a unit bug" } +} +---- + +== Honesty note + +WokeLang is early (~35% complete). The README and `EXPLAINME.adoc` are +deliberately explicit about the gap between *stated design principles* and +*current implementation*; `PROOF-NEEDS.md` and `PHRONESIS-ALIGNMENT-GAP.md` +track the outstanding obligations. This wiki follows the same discipline. diff --git a/wiki/Roadmap.adoc b/wiki/Roadmap.adoc new file mode 100644 index 0000000..7db0a24 --- /dev/null +++ b/wiki/Roadmap.adoc @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: MPL-2.0 +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell += WokeLang — Roadmap +:toc: macro +:icons: font + +link:Home.adoc[← Wiki home] + +toc::[] + +This page distils `ROADMAP.adoc`, the frontier described in +`.machine_readable/6a2/STATE.a2ml`, and the honest caveats in `EXPLAINME.adoc`. +WokeLang is at *version 0.1.0*, phase *implementation* (~35% complete). + +== Current + +* *Rust toolchain* (`src/`): lexer, parser, typechecker, bytecode VM + (compiler + machine + optimizer), tree-walking interpreter, LSP (`woke-lsp`), + DAP (`woke-dap`), formatter, linter, REPL, stdlib, ABI/FFI, security — *173 + library tests passing*. +* *OCaml reference core* (`core/`): `ocamllex` + `menhir` + evaluator, grounding + the end-to-end CI cross-check. +* *Implemented language features*: consent gates, gratitude blocks, units of + measure, pipelines, empathy annotations, the `Result` type (`Okay`/`Oops`), + and `#care` / `#strict` pragmas. +* *Specification*: EBNF grammar, consent-extended axiomatic semantics, and the + research paper. +* *Governance*: the GitHub Actions CI suite, the dogfooding gate, and the + enforced language policy (see link:CI-and-Governance.adoc[CI & Governance]). + +== Near-term + +* *Frontier — echo types in the typechecker.* Integrate + `hyperpolymath/echo-types` (fiber-based structured loss) into the type checker + so the language reasons about consent / affine-use automatically. +* *Frontier — machine-checked proof narrative.* Stand up an end-to-end, + near-first-principles proof of the consent-safety guarantees (Isabelle + preferred), consuming the echo-types Agda formalization. +* *Eliminate proof escape hatches.* Drive out any remaining + `sorry` / `Admitted`-style gaps; tighten the formal-verification story + (`PROOF-NEEDS.md`). +* *Restore the VS Code LSP client.* Re-enable completion / hover / diagnostics / + go-to-definition / formatting via an *AffineScript* client driving the Rust + `woke-lsp` server, once the estate ABI/FFI layer lands. Tracked in issue #78. + (The `woke-lsp` server already works with any LSP-capable editor.) +* *Broaden type inference.* Extend Hindley-Milner inference beyond scalars and + units to closures and module types. + +== Long-term + +* *WASM backend.* Turn the `src/codegen/` `WasmCompiler` scaffold (and the + `compiler/wokelang-wasm/` experiment) into a working WebAssembly target. This + is currently a *design commitment*, not a working backend. +* *Blockchain / Vyper FFI.* Realise the `vyper call` design feature described in + the spec and the research paper. Currently a *design commitment* with no bridge + in the tree. +* *Self-hosting and tooling.* Continue toward a more complete toolchain + (formatter / linter / package-management ergonomics), self-hosting where + appropriate. + +== Implemented vs. designed + +To keep expectations calibrated, the following are explicitly *not yet* +implemented and should be treated as roadmap items: + +[cols="1,2", options="header"] +|=== +| Item | Status + +| WASM compilation target +| Design commitment — `src/codegen/` scaffold not wired into the build + +| Blockchain / Vyper FFI +| Design commitment — no `vyper` bridge in `src/stdlib/` + +| Full polymorphic HM inference +| Partial — scalar and unit inference today + +| VS Code LSP client (completion/hover/etc.) +| Removed (was ReScript); AffineScript reimpl blocked on ABI/FFI (issue #78) +|=== + +== Tracking documents + +* `ROADMAP.adoc` — the headline roadmap. +* `PROOF-NEEDS.md` — outstanding formal proof obligations. +* `PHRONESIS-ALIGNMENT-GAP.md` — gaps between stated principles and current + implementation. +* `TEST-NEEDS.md` · `TOOLCHAIN-WISHLIST.md` — desired test coverage and + toolchain improvements. +* `.machine_readable/6a2/STATE.a2ml` — the canonical, dated project state. diff --git a/wokelang.opam b/wokelang.opam index e69de29..6250f94 100644 --- a/wokelang.opam +++ b/wokelang.opam @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: MPL-2.0 +# SPDX-FileCopyrightText: 2026 Hyperpolymath +opam-version: "2.0" +name: "wokelang" +version: "0.1.0" +synopsis: "A human-centered, consent-driven programming language" +description: """ +WokeLang is a human-centered, consent-driven programming language. +This package builds the OCaml reference core (lexer / parser / evaluator) +under core/ via dune + menhir. The Rust toolchain (compiler, VM, LSP, +DAP) is built separately via Cargo. +""" +maintainer: "Jonathan D.A. Jewell " +authors: "Jonathan D.A. Jewell " +license: "MPL-2.0" +homepage: "https://github.com/hyperpolymath/wokelang" +bug-reports: "https://github.com/hyperpolymath/wokelang/issues" +dev-repo: "git+https://github.com/hyperpolymath/wokelang.git" +depends: [ + "ocaml" {>= "4.14"} + "dune" {>= "3.0"} + "menhir" {>= "2.1"} +] +build: [ + ["dune" "subst"] {dev} + ["dune" "build" "-p" name "-j" jobs] +]