From 226b0b4359b8c63de9b47e28badd9ed1d54ec1d9 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 18 Jun 2026 10:30:35 +0000 Subject: [PATCH 1/3] =?UTF-8?q?docs(theory):=20add=20correspondence=20mode?= =?UTF-8?q?l=20=E2=80=94=20the=20engine=20that=20classifies,=20not=20trans?= =?UTF-8?q?lates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Canonical design spec for the comprehension/transfer engine: the Concept/Form/Transition object model, the levels-of-objects strata, the Dyadic+Echo formal carrier, and the Rosetta false-friends taxonomy (cognate / false-friend / antonym / alien-realization / novel / vanished) as graded Echo fibres. Also records the engine<->cartridge division of labour, the overlay-protocol / accessibility / PanLL-emit downstream contracts, and the knot-theory honesty caveat. JTV grammar v2 is stubbed pending repo access. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01A1BaAhqxUjkgVb1yg1sZap --- docs/theory/CORRESPONDENCE-MODEL.adoc | 237 ++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 docs/theory/CORRESPONDENCE-MODEL.adoc diff --git a/docs/theory/CORRESPONDENCE-MODEL.adoc b/docs/theory/CORRESPONDENCE-MODEL.adoc new file mode 100644 index 0000000..b3bd7a0 --- /dev/null +++ b/docs/theory/CORRESPONDENCE-MODEL.adoc @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: MPL-2.0 += Correspondence Model: the engine that *classifies*, not translates +:toc: macro +:toclevels: 3 +:icons: font + +[NOTE] +==== +*Status: living design spec.* This is the conceptual foundation for the engine — +authored ahead of the toolchain (AffineScript/Idris2/Zig not yet installable here), so +it is verified by inspection against estate exemplars, not yet by build. One worked +example (JTV grammar v2) is stubbed pending repository access; see <>. +==== + +toc::[] + +== What this engine is (and is not) + +This is *Duolingo / Rosetta Stone for programming languages* — a +language-*comprehension and transfer* engine. It works **one layer above text +editing**, on *syntactic and semantic intention*, so that the effort a person spent +learning language A *transfers* when they move to B (JS → TypeScript, Ruby, Prolog, C, +or exotic targets like QPL, Arrow, JTV). *Transfer learning across languages is the +product.* + +It is *not*: + +* *Not "the next best IDE."* It does not compete on contrast, project-management + widgets, pop-up notepads, shortcuts, or well-trodden attention/memory/workflow + ergonomics. That is **PanLL**'s job (PanLL + eNSAID = the _contact_ between human, + tool, task, and environment). This engine *feeds* PanLL; it is not PanLL. +* *Not a linter.* "Proximal/distal scope-colouring" and "spot the missing `;` / extra + `)`" are precisely what this is *not*. The differentiator is an engine that + **computes and classifies cross-language equivalence**, not one that looks it up. +* *Not a universal translator.* A verified any-language→any-language compiler with full + Curry–Howard fidelity would be nice; it is *not the goal*. We do not need — and will + not attempt — to do this "to the dot" on everything. + +== Division of labour + +[cols="1,3"] +|=== +| *We build* | the general engine + the interface + the classification vocabulary + +the residue model + a reference language pack. +| *The community builds* | the *per-language modules* — which pairs of constructs are +cognate vs. false-friend vs. novel, with their residues. These are authored as +**cartridges** (see `standards/cartridges/`). +|=== + +The engine is language-agnostic. The nextgen-language collection is merely the +substrate we dogfood. + +== The object model: Concept / Form / Transition + +[cols="1,3"] +|=== +| *Concept* | The invariant / equivalence-class — the recurring _trope_ (e.g. +"bind a name to a value", "iterate a collection", "fail recoverably"). +| *Form* | A representative of a Concept *in one language* (e.g. `let` in ReScript, +`=` in Erlang, `def` in Python). A Concept has many Forms across many languages. +| *Transition* | A directed correspondence Form(A) → Form(B): the Echo-refined map +plus its *residue* (what is lost, added, or inverted in crossing). +|=== + +A *lesson* is a Concept presented through the learner's known Form, the target Form, +and the Transition between them — narrated without shame ("you already know this; +here's the catch"). + +== Levels of objects (strata) + +Classification runs *per stratum of meaning*, not on flat text: + +. *Surface* — tokens, lexemes (`=`, `def`, `match`). +. *Structure* — AST shape, scoping, arity. +. *Semantic intention* — what the construct _does_ (bind? mutate? branch?). +. *Abstraction / trope* — the Concept it instantiates. +. *Cross-language invariant* — the preserved quantity certifying "same idea". + +The interface lets a learner move *up and down* these strata and *across* view-modes. +A correspondence can hold at one stratum and break at another — and that divergence is +itself the most valuable signal (see false friends, below). + +== The formal carrier + +The model is grounded in the estate's own formalism, not a bespoke mapping table. + +* *Carrier = Dyadic `Relation`* + (`proven-tests-and-benches/src/ProvenTests/TypeSafe/Dyadic.idr`): + `{ relates; reflexive; symmetric; transitive }`. Equivalence = refl ∧ sym ∧ trans — + the symmetries and transitivities, as a checkable structure. +* *Crossings are lossy-with-residue = Echo fibre* + (`Echo f y := Σ (x : A), f x ≡ y`, `hyperpolymath/echo-types`, Agda): the residue + (a proof term) is precisely _what is lost or added_ going A→B. A non-isomorphic + Transition (e.g. the absence of `return` in ReScript) is a map whose residue we + *surface*, never hide. +* *Typed residue-lenses = the three Echo bridges* (`Bridge.idr`): `EchoChoreo` + (protocol/sequencing), `EchoEpistemic` (visibility/knowledge), `EchoTropical` + (cost, min-plus). Extensible. +* *Composition = transitivity; symmetry distinguishes iso from retraction.* A clean + isomorphism ⇒ no residue (true equivalence); a retraction ⇒ one-way loss + (residue = the delta). +* *`invariant-path` = the governance front-end.* It anchors each equivalence _claim_ to + its two code locations plus a witness (proof/test), human-in-the-loop and editable. + +[IMPORTANT] +==== +*Honesty note on "knot theory."* The owner's framing — *types → carrier · tropes → +recurring equivalence-figures · knot theory → certificate* — is load-bearing for +intuition, but there is *no literal knot-invariant computation* here, and the +knot-theory lens is flagged (by the owner) as "perceived as rhetoric, pending +historical confirmation". We use *invariant* in the precise sense of a _preserved +quantity that certifies "same idea"_, and keep knot theory as an aspirational lens, not +a faked dependency. +==== + +[#taxonomy] +== The Rosetta false-friends taxonomy + +The one judgement that matters is *"is this safe to transfer, or is it a trap?"* +`def` → `define` might be _nothing but a rename_ — or it might look like that and not +be. So the Dyadic relation is not a boolean `relates`; it is a *typed/graded* +`CorrespondenceKind`, realised as grades of the Echo fibre: + +[cols="1,3,2"] +|=== +| Kind | Signature | Pedagogy + +| *Cognate / true friend* +| Intention + behaviour coincide; residue ≈ ∅. _Example:_ `def` → `define`. + But "just a rename" is a hypothesis to *verify*, never assume. +| *Transfer directly.* + +| *False friend / homonym* +| Surface matches, semantics diverge. _Example:_ BASIC `=` (mutable assignment) vs. + Erlang `=` (single-assignment bind/unify). Detected by *per-stratum* classification: + surface-corresponds ∧ semantics-diverge **is** the false-friend signature. +| *Flag the trap.* + +| *Antonym / inverted* +| Related but behaves oppositely. _Examples:_ 0- vs. 1-indexing; truthiness + conventions; stack-growth direction. Residue = the flip. +| *Remap the intuition.* + +| *Alien realization* +| Same intention, foreign mechanism, large residue. _Example:_ subtraction in a + reversible/add-only language (JTV) is `add` run backwards; divide via reversed + repeated-add. Also: recursion-only languages, CPS, monadic IO for "just print". +| *Bridge with effort; explain the machinery.* + +| *Novel / no anchor* +| Forward fibre empty: `∄ x. f x ≡ y`. The target has a concept with nothing to map + _from_. _Examples:_ static types coming from assembly + JS; ownership/borrowing; + affine/linear use-once; Prolog `cut`; JTV totality and information-flow labels. +| *Teach de novo — there is no transfer.* + +| *Vanished* +| Backward fibre empty: `∄ y`. A concept the learner relied on is _gone_. + _Examples:_ `return` in ReScript; `null` in a null-free language; mutable variables + in a pure language. +| *Un-learn / re-route.* +|=== + +The residue therefore ranges from ∅ (true iso) through inverted/large to +empty-in-either-direction (novel / vanished). This taxonomy *is* the Duolingo/Rosetta +pedagogy: transfer cognates, warn on false friends, remap antonyms, bridge the alien, +teach the novel, re-route the vanished. + +== Engine ↔ cartridge boundary + +We cannot do this "to the dot", and we do not try. Responsibilities split cleanly: + +* *Engine (ours):* the `CorrespondenceKind` vocabulary, the residue/fibre model, the + per-stratum classifier, the Dyadic/Echo carrier, and the certifiable Idris2/Echo math + — applied *where it pays* (high-value or dangerous correspondences), not everywhere. +* *Cartridge (per-language, community):* the _facts_ — for this language, which Forms + instantiate which Concepts, and for each Transition the kind + residue + a witness. + +A cartridge fact, sketched: + +[source] +---- +(transition + (concept "name-binding") + (from (lang "basic") (form "X = 5")) + (to (lang "erlang") (form "X = 5")) + (kind false-friend) ; surface-cognate, semantic-divergent + (strata (surface corresponds) (semantic diverges)) + (residue "BASIC rebinds destructively; Erlang binds once and unifies — \ + re-`=` fails unless the value matches") + (witness "proofs/erlang_single_assignment.idr")) ; optional, where it pays +---- + +== Rendering: "levels of objects", not chrome + +The view-modes are the rendered strata, switchable and non-destructive (each conforms +to the estate *overlay-protocol* — additive, non-modifying, idempotent, Idris2-ABI +proved): + +* *focus* — show only what's needed now; +* *glyph* — Makaton-style symbols (accessible, low-cognitive-load); +* *blockly / scratch* — flowchart of structure; +* *raw code* — the text itself; +* *side-by-side* — multi-language diff with step-sync. + +Accessibility is a first-class contract, not a coat of paint: Hyperpolymath +Accessibility Standard, Level *A* minimum → *AA* (keyboard-only operation, ≥4.5:1 +contrast, colourblind-safe palettes, ARIA/screen-reader, reduced-motion, plain-language +mode, high-contrast glyph variants). + +== Downstream: feeding PanLL + +The engine *emits*, it does not own the IDE. Analyses become `octads` written to +VeriSimDB (`:8097`) plus `Groove` signals; PanLL panels subscribe and re-render. +Relevant octad types: `inline-annotation` (per-construct claims), +`ecosystem-link` (intra-program relationships), `proof-status` (where a Transition +carries a witness). Ergonomics are read from `.machine_readable/ENSAID_CONFIG.a2ml`. + +[#open-questions] +== Open questions / placeholders + +* *JTV grammar v2* — the canonical worked example for *alien-realization* and + *novel/no-anchor* kinds. The `julia-the-viper` repo is a not-checked-out submodule + and currently outside session scope; constructs to be tagged against <> + once the grammar is available. From the T1 proof spec, JTV is reversible + total + + effect-typed (I/O, state, crypto) + information-flow-typed (public/private/secret) + + capability-secured — i.e. dense with novel-concept correspondences. +* *Stratum granularity* — whether 5 strata suffice, or "intention" needs splitting + (operational vs. denotational). +* *Where the math pays* — the policy for when a Transition _must_ carry an Idris2/Echo + witness vs. an asserted-but-unproven classification. + +== References + +* `proven-tests-and-benches/src/ProvenTests/TypeSafe/Dyadic.idr`, `…/Bridge.idr` +* `hyperpolymath/echo-types` — loss-with-residue (Agda) +* `standards/overlay-protocol/`, `standards/ensaid-config/`, + `standards/accessibility/`, `standards/cartridges/`, `standards/panll-panels/` From ddd3d4444282b9d669b45b821c996c0f04b68e08 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 18 Jun 2026 11:02:31 +0000 Subject: [PATCH 2/3] chore(standards): complete 6a2 manifest set + panic-attack gate + eNSAID config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add the missing .machine_readable/6a2 manifests — AGENTIC, NEUROSYM, PLAYBOOK — completing the canonical six alongside STATE/META/ECOSYSTEM, tuned to the correspondence-engine identity (no-shame voice, classify-not- translate, toolchain-deferred build honesty, no-relicense guardrail). - Add .github/workflows/static-analysis-gate.yml: panic-attack assail + hypatia scan + patch-bridge triage. Fails only on critical findings and skips gracefully when the binaries are unavailable in the runner. - Add .machine_readable/ENSAID_CONFIG.a2ml: PanLL / eNSAID per-repo config with a correspondence-engine view-layer portfolio. - Justfile: fix stale panic-attacker -> panic-attack references (tool renamed 2026-02-08). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01A1BaAhqxUjkgVb1yg1sZap --- .github/workflows/static-analysis-gate.yml | 400 +++++++++++++++++++++ .machine_readable/6a2/AGENTIC.a2ml | 43 +++ .machine_readable/6a2/NEUROSYM.a2ml | 33 ++ .machine_readable/6a2/PLAYBOOK.a2ml | 31 ++ .machine_readable/ENSAID_CONFIG.a2ml | 65 ++++ Justfile | 4 +- 6 files changed, 574 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/static-analysis-gate.yml create mode 100644 .machine_readable/6a2/AGENTIC.a2ml create mode 100644 .machine_readable/6a2/NEUROSYM.a2ml create mode 100644 .machine_readable/6a2/PLAYBOOK.a2ml create mode 100644 .machine_readable/ENSAID_CONFIG.a2ml diff --git a/.github/workflows/static-analysis-gate.yml b/.github/workflows/static-analysis-gate.yml new file mode 100644 index 0000000..8bd1606 --- /dev/null +++ b/.github/workflows/static-analysis-gate.yml @@ -0,0 +1,400 @@ +# SPDX-License-Identifier: MPL-2.0 +# Static Analysis Gate — Required by branch protection rules. +# Runs panic-attack and hypatia, deposits findings for gitbot-fleet learning. +name: Static Analysis Gate +on: + pull_request: + branches: ['**'] + push: + branches: [main, master] +permissions: + contents: read +jobs: + # --------------------------------------------------------------------------- + # Job 1: panic-attack assail + # --------------------------------------------------------------------------- + panic-attack-assail: + name: panic-attack assail + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + - name: Install panic-attack (if available) + id: install + run: | + # Try to fetch the latest release binary from the org + PA_URL="https://github.com/hyperpolymath/panic-attack/releases/latest/download/panic-attack-linux-x86_64" + if curl -fsSL --head "$PA_URL" >/dev/null 2>&1; then + curl -fsSL -o /usr/local/bin/panic-attack "$PA_URL" + chmod +x /usr/local/bin/panic-attack + echo "installed=true" >> "$GITHUB_OUTPUT" + else + echo "::notice::panic-attack binary not available — skipping assail" + echo "installed=false" >> "$GITHUB_OUTPUT" + fi + - name: Run panic-attack assail + id: assail + if: steps.install.outputs.installed == 'true' + run: | + set +e + panic-attack assail --format json . > panic-attack-findings.json 2>&1 + PA_EXIT=$? + set -e + + if [ ! -s panic-attack-findings.json ]; then + echo "[]" > panic-attack-findings.json + fi + + # Parse finding counts + TOTAL=$(jq '. | length' panic-attack-findings.json 2>/dev/null || echo 0) + CRITICAL=$(jq '[.[] | select(.severity == "critical")] | length' panic-attack-findings.json 2>/dev/null || echo 0) + HIGH=$(jq '[.[] | select(.severity == "high")] | length' panic-attack-findings.json 2>/dev/null || echo 0) + MEDIUM=$(jq '[.[] | select(.severity == "medium")] | length' panic-attack-findings.json 2>/dev/null || echo 0) + LOW=$(jq '[.[] | select(.severity == "low")] | length' panic-attack-findings.json 2>/dev/null || echo 0) + + echo "total=$TOTAL" >> "$GITHUB_OUTPUT" + echo "critical=$CRITICAL" >> "$GITHUB_OUTPUT" + echo "high=$HIGH" >> "$GITHUB_OUTPUT" + echo "medium=$MEDIUM" >> "$GITHUB_OUTPUT" + echo "low=$LOW" >> "$GITHUB_OUTPUT" + echo "exit_code=$PA_EXIT" >> "$GITHUB_OUTPUT" + - name: Emit check annotations + if: steps.install.outputs.installed == 'true' + run: | + # Convert JSON findings into GitHub Actions annotations + jq -r '.[] | select(.file != null) | + if .severity == "critical" then + "::error file=\(.file),line=\(.line // 1)::[panic-attack] \(.message)" + elif .severity == "high" then + "::error file=\(.file),line=\(.line // 1)::[panic-attack] \(.message)" + else + "::warning file=\(.file),line=\(.line // 1)::[panic-attack] \(.message)" + end + ' panic-attack-findings.json || true + - name: Write step summary + if: steps.install.outputs.installed == 'true' + run: | + cat <> "$GITHUB_STEP_SUMMARY" + ## panic-attack assail Results + + | Severity | Count | + |----------|-------| + | Critical | ${{ steps.assail.outputs.critical }} | + | High | ${{ steps.assail.outputs.high }} | + | Medium | ${{ steps.assail.outputs.medium }} | + | Low | ${{ steps.assail.outputs.low }} | + | **Total**| ${{ steps.assail.outputs.total }} | + EOF + - name: Create stub findings (when panic-attack unavailable) + if: steps.install.outputs.installed != 'true' + run: | + echo "[]" > panic-attack-findings.json + echo "## panic-attack assail" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + echo "Skipped: panic-attack not available in this environment." >> "$GITHUB_STEP_SUMMARY" + - name: Upload panic-attack findings + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: panic-attack-findings + path: panic-attack-findings.json + retention-days: 90 + - name: Fail on critical findings + if: steps.install.outputs.installed == 'true' && steps.assail.outputs.critical > 0 + run: | + echo "::error::panic-attack found ${{ steps.assail.outputs.critical }} critical issue(s) — blocking merge" + exit 1 + # --------------------------------------------------------------------------- + # Job 2: hypatia-scan + # --------------------------------------------------------------------------- + hypatia-scan: + name: Hypatia neurosymbolic scan + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + - name: Setup Elixir for Hypatia scanner + id: beam + continue-on-error: true + uses: erlef/setup-beam@e6d7c94229049569db56a7ad5a540c051a010af9 # v1.18.2 + with: + elixir-version: '1.19.4' + otp-version: '28.3' + - name: Clone and build Hypatia + id: build + continue-on-error: true + run: | + git clone https://github.com/hyperpolymath/hypatia.git "$HOME/hypatia" 2>/dev/null || true + if [ -f "$HOME/hypatia/mix.exs" ]; then + cd "$HOME/hypatia" + # Build escript if neither hypatia nor hypatia-v2 exists + if [ ! -f hypatia ] && [ ! -f hypatia-v2 ]; then + mix deps.get + mix escript.build + fi + echo "ready=true" >> "$GITHUB_OUTPUT" + else + echo "::notice::Hypatia scanner not available — skipping scan" + echo "ready=false" >> "$GITHUB_OUTPUT" + fi + - name: Run Hypatia scan + id: scan + if: steps.build.outputs.ready == 'true' + run: | + set +e + HYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . > hypatia-findings.json 2>&1 + HYP_EXIT=$? + set -e + + if [ ! -s hypatia-findings.json ] || ! jq empty hypatia-findings.json 2>/dev/null; then + echo "[]" > hypatia-findings.json + fi + + TOTAL=$(jq '. | length' hypatia-findings.json 2>/dev/null || echo 0) + CRITICAL=$(jq '[.[] | select(.severity == "critical")] | length' hypatia-findings.json 2>/dev/null || echo 0) + HIGH=$(jq '[.[] | select(.severity == "high")] | length' hypatia-findings.json 2>/dev/null || echo 0) + MEDIUM=$(jq '[.[] | select(.severity == "medium")] | length' hypatia-findings.json 2>/dev/null || echo 0) + LOW=$(jq '[.[] | select(.severity == "low")] | length' hypatia-findings.json 2>/dev/null || echo 0) + + echo "total=$TOTAL" >> "$GITHUB_OUTPUT" + echo "critical=$CRITICAL" >> "$GITHUB_OUTPUT" + echo "high=$HIGH" >> "$GITHUB_OUTPUT" + echo "medium=$MEDIUM" >> "$GITHUB_OUTPUT" + echo "low=$LOW" >> "$GITHUB_OUTPUT" + - name: Emit check annotations + if: steps.build.outputs.ready == 'true' + run: | + jq -r '.[] | select(.file != null) | + if .severity == "critical" then + "::error file=\(.file),line=\(.line // 1)::[hypatia] \(.message)" + elif .severity == "high" then + "::error file=\(.file),line=\(.line // 1)::[hypatia] \(.message)" + else + "::warning file=\(.file),line=\(.line // 1)::[hypatia] \(.message)" + end + ' hypatia-findings.json || true + - name: Write step summary + if: steps.build.outputs.ready == 'true' + run: | + cat <> "$GITHUB_STEP_SUMMARY" + ## Hypatia Scan Results + + | Severity | Count | + |----------|-------| + | Critical | ${{ steps.scan.outputs.critical }} | + | High | ${{ steps.scan.outputs.high }} | + | Medium | ${{ steps.scan.outputs.medium }} | + | Low | ${{ steps.scan.outputs.low }} | + | **Total**| ${{ steps.scan.outputs.total }} | + EOF + - name: Create stub findings (when Hypatia unavailable) + if: steps.build.outputs.ready != 'true' + run: | + echo "[]" > hypatia-findings.json + echo "## Hypatia Scan" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + echo "Skipped: Hypatia scanner not available in this environment." >> "$GITHUB_STEP_SUMMARY" + - name: Upload hypatia findings + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: hypatia-findings + path: hypatia-findings.json + retention-days: 90 + - name: Fail on critical security findings + if: steps.build.outputs.ready == 'true' && steps.scan.outputs.critical > 0 + run: | + echo "::error::Hypatia found ${{ steps.scan.outputs.critical }} critical security issue(s) — blocking merge" + exit 1 + # --------------------------------------------------------------------------- + # Job 3: patch-bridge triage (CVE contextual assessment) + # --------------------------------------------------------------------------- + patch-bridge-triage: + name: Patch Bridge CVE triage + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + - name: Install panic-attack (if available) + id: install + run: | + PA_URL="https://github.com/hyperpolymath/panic-attack/releases/latest/download/panic-attack-linux-x86_64" + if curl -fsSL --head "$PA_URL" >/dev/null 2>&1; then + curl -fsSL -o /usr/local/bin/panic-attack "$PA_URL" + chmod +x /usr/local/bin/panic-attack + echo "installed=true" >> "$GITHUB_OUTPUT" + else + echo "::notice::panic-attack binary not available — skipping Patch Bridge" + echo "installed=false" >> "$GITHUB_OUTPUT" + fi + - name: Run Patch Bridge triage + id: triage + if: steps.install.outputs.installed == 'true' + run: | + set +e + panic-attack bridge triage --format json . > bridge-report.json 2>&1 + PB_EXIT=$? + set -e + + if [ ! -s bridge-report.json ] || ! jq empty bridge-report.json 2>/dev/null; then + echo '{"cves":[],"mitigated":0,"unmitigable":0,"concatenative":0,"informational":0}' > bridge-report.json + fi + + UNMITIGABLE=$(jq '.unmitigable // 0' bridge-report.json) + MITIGATED=$(jq '.mitigated // 0' bridge-report.json) + CONCATENATIVE=$(jq '.concatenative // 0' bridge-report.json) + INFORMATIONAL=$(jq '.informational // 0' bridge-report.json) + + echo "unmitigable=$UNMITIGABLE" >> "$GITHUB_OUTPUT" + echo "mitigated=$MITIGATED" >> "$GITHUB_OUTPUT" + echo "concatenative=$CONCATENATIVE" >> "$GITHUB_OUTPUT" + echo "informational=$INFORMATIONAL" >> "$GITHUB_OUTPUT" + - name: Write step summary + if: steps.install.outputs.installed == 'true' + run: | + cat <> "$GITHUB_STEP_SUMMARY" + ## Patch Bridge CVE Triage + + | Classification | Count | + |----------------|-------| + | Unmitigable | ${{ steps.triage.outputs.unmitigable }} | + | Mitigated | ${{ steps.triage.outputs.mitigated }} | + | Concatenative | ${{ steps.triage.outputs.concatenative }} | + | Informational | ${{ steps.triage.outputs.informational }} | + + Unmitigable CVEs require dependency replacement or rearchitecture. + Mitigated CVEs have active controls with soundness proofs. + Concatenative risks are CVE combinations that multiply severity. + EOF + - name: Create stub report (when unavailable) + if: steps.install.outputs.installed != 'true' + run: | + echo '{"cves":[],"mitigated":0,"unmitigable":0,"concatenative":0,"informational":0}' > bridge-report.json + echo "## Patch Bridge CVE Triage" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + echo "Skipped: panic-attack not available in this environment." >> "$GITHUB_STEP_SUMMARY" + - name: Upload bridge report + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: bridge-report + path: bridge-report.json + retention-days: 90 + - name: Fail on unmitigable CVEs in critical paths + if: steps.install.outputs.installed == 'true' && steps.triage.outputs.unmitigable > 0 + run: | + echo "::warning::Patch Bridge found ${{ steps.triage.outputs.unmitigable }} unmitigable CVE(s) — review required" + # Warning only, not blocking. Unmitigable means the developer needs + # to make an architectural decision, not that the PR is wrong. + # --------------------------------------------------------------------------- + # Job 4: deposit-findings (combines + archives for gitbot-fleet) + # --------------------------------------------------------------------------- + deposit-findings: + name: Deposit findings for gitbot-fleet + runs-on: ubuntu-latest + timeout-minutes: 15 + needs: [panic-attack-assail, hypatia-scan, patch-bridge-triage] + if: always() + steps: + - name: Download panic-attack findings + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 + with: + name: panic-attack-findings + path: findings/ + - name: Download hypatia findings + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 + with: + name: hypatia-findings + path: findings/ + - name: Download bridge report + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 + with: + name: bridge-report + path: findings/ + - name: Combine findings into unified report + id: combine + run: | + PA_FILE="findings/panic-attack-findings.json" + HYP_FILE="findings/hypatia-findings.json" + + # Ensure both files exist and are valid JSON arrays + for f in "$PA_FILE" "$HYP_FILE"; do + if [ ! -s "$f" ] || ! jq empty "$f" 2>/dev/null; then + echo "[]" > "$f" + fi + done + + # Tag each finding with its source scanner + jq '[.[] | . + {"scanner": "panic-attack"}]' "$PA_FILE" > /tmp/pa-tagged.json + jq '[.[] | . + {"scanner": "hypatia"}]' "$HYP_FILE" > /tmp/hyp-tagged.json + + # Read bridge report (CVE triage, not findings array) + BRIDGE_FILE="findings/bridge-report.json" + if [ ! -s "$BRIDGE_FILE" ] || ! jq empty "$BRIDGE_FILE" 2>/dev/null; then + echo '{"cves":[],"mitigated":0,"unmitigable":0,"concatenative":0,"informational":0}' > "$BRIDGE_FILE" + fi + + # Build unified report envelope + jq -n \ + --arg repo "${{ github.repository }}" \ + --arg sha "${{ github.sha }}" \ + --arg ref "${{ github.ref }}" \ + --arg run_id "${{ github.run_id }}" \ + --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ + --slurpfile pa /tmp/pa-tagged.json \ + --slurpfile hyp /tmp/hyp-tagged.json \ + --slurpfile bridge "$BRIDGE_FILE" \ + '{ + schema_version: "1.1.0", + repository: $repo, + commit_sha: $sha, + ref: $ref, + run_id: $run_id, + timestamp: $ts, + findings: ($pa[0] + $hyp[0]), + patch_bridge: $bridge[0] + }' > findings/unified-findings.json + + TOTAL=$(jq '.findings | length' findings/unified-findings.json) + CRITICAL=$(jq '[.findings[] | select(.severity == "critical")] | length' findings/unified-findings.json) + HIGH=$(jq '[.findings[] | select(.severity == "high")] | length' findings/unified-findings.json) + MEDIUM=$(jq '[.findings[] | select(.severity == "medium")] | length' findings/unified-findings.json) + LOW=$(jq '[.findings[] | select(.severity == "low")] | length' findings/unified-findings.json) + + echo "total=$TOTAL" >> "$GITHUB_OUTPUT" + echo "critical=$CRITICAL" >> "$GITHUB_OUTPUT" + echo "high=$HIGH" >> "$GITHUB_OUTPUT" + echo "medium=$MEDIUM" >> "$GITHUB_OUTPUT" + echo "low=$LOW" >> "$GITHUB_OUTPUT" + - name: Upload unified findings (fleet scanner picks these up) + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: unified-findings + path: findings/unified-findings.json + retention-days: 90 + - name: Write deposit summary + run: | + cat <> "$GITHUB_STEP_SUMMARY" + ## Unified Findings Deposit + + **Repository:** ${{ github.repository }} + **Commit:** \`${{ github.sha }}\` + **Deposited at:** $(date -u +"%Y-%m-%d %H:%M:%S UTC") + + | Severity | Count | + |----------|-------| + | Critical | ${{ steps.combine.outputs.critical }} | + | High | ${{ steps.combine.outputs.high }} | + | Medium | ${{ steps.combine.outputs.medium }} | + | Low | ${{ steps.combine.outputs.low }} | + | **Total**| ${{ steps.combine.outputs.total }} | + + Findings saved as \`unified-findings\` artifact. + The gitbot-fleet scanner will ingest these on its next pass. + EOF diff --git a/.machine_readable/6a2/AGENTIC.a2ml b/.machine_readable/6a2/AGENTIC.a2ml new file mode 100644 index 0000000..433bdc4 --- /dev/null +++ b/.machine_readable/6a2/AGENTIC.a2ml @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: MPL-2.0 +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +# +# AGENTIC.a2ml — AI agent constraints and capabilities +[metadata] +version = "0.1.0" +last-updated = "2026-06-18" +project = "nextgen-languages-evangeliser" + +[agent-permissions] +can-edit-source = true +can-edit-tests = true +can-edit-docs = true +can-edit-config = true +can-create-files = true + +[agent-constraints] +# What AI agents must NOT do in this repo: +# - Never relicense. This is a sole-owner repo; keep SPDX = MPL-2.0 on every +# file. No bulk SPDX sweeps (estate licence guardrail). +# - Never use banned languages (TypeScript, Python, Go, V) or Makefiles (use +# the Justfile). +# - Never reframe this as a universal translator or a Curry-Howard-fidelity +# compiler. It *classifies* cross-language correspondences and teaches the +# transfer; see docs/theory/CORRESPONDENCE-MODEL.adoc. +# - Never shame the source language. Narratives keep the +# celebrate / minimise / better / safety / example voice. +# - Never claim a green build from an untooled environment. AffineScript, +# Idris2, Zig and Deno may be absent here — author now, verify in CI. +# - Never place state files in the repository root (must live in +# .machine_readable/). + +[maintenance-integrity] +fail-closed = true +require-evidence-per-step = true +allow-silent-skip = false +require-rerun-after-fix = true +release-claim-requires-hard-pass = true + +[automation-hooks] +# on-enter: Read 0-AI-MANIFEST.a2ml, then .machine_readable/6a2/STATE.a2ml +# on-exit: Update 6a2/STATE.a2ml with session outcomes +# on-commit: Run `just validate-rsr` diff --git a/.machine_readable/6a2/NEUROSYM.a2ml b/.machine_readable/6a2/NEUROSYM.a2ml new file mode 100644 index 0000000..d33f7f5 --- /dev/null +++ b/.machine_readable/6a2/NEUROSYM.a2ml @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: MPL-2.0 +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +# +# NEUROSYM.a2ml — Neurosymbolic integration metadata +[metadata] +version = "0.1.0" +last-updated = "2026-06-18" +project = "nextgen-languages-evangeliser" + +[hypatia-config] +scan-enabled = true +scan-depth = "standard" # quick | standard | deep +report-format = "logtalk" + +[static-analysis-gate] +# panic-attack assail runs in .github/workflows/static-analysis-gate.yml. +# It fails the build only on critical findings and skips gracefully when the +# binary is unavailable in the runner. +panic-attack-enabled = true +fail-on = "critical" + +[symbolic-rules] +# Project-specific symbolic rules (illustrative): +# - { name = "no-shame-narrative", pattern = "stupid|wrong code|bad code", severity = "high" } +# - { name = "no-universal-translator-claim", pattern = "universal translator|curry-?howard fidelity", severity = "medium" } + +[neural-config] +# The engine's own correspondence classifier IS this repo's domain +# neurosymbolic surface: a symbolic Dyadic relation + a graded Echo +# loss-with-residue fibre -> a typed CorrespondenceKind +# (cognate / false-friend / antonym / alien-realization / novel / vanished). +# See docs/theory/CORRESPONDENCE-MODEL.adoc. +# confidence-threshold = 0.85 diff --git a/.machine_readable/6a2/PLAYBOOK.a2ml b/.machine_readable/6a2/PLAYBOOK.a2ml new file mode 100644 index 0000000..f1ee58a --- /dev/null +++ b/.machine_readable/6a2/PLAYBOOK.a2ml @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: MPL-2.0 +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +# +# PLAYBOOK.a2ml — Operational playbook +[metadata] +version = "0.1.0" +last-updated = "2026-06-18" +project = "nextgen-languages-evangeliser" + +[deployment] +# Host: ReScript today (compiles to JS, run under Deno); AffineScript after the +# Phase-3 host port. Surfaces: Deno CLI (bin/evangeliser.js) and the browser +# GUI (gui/server.js + gui/app.js). +# method = "ci-triggered" +# target = "library + cli + browser-gui" + +[incident-response] +# 1. Read .machine_readable/6a2/STATE.a2ml for current status. +# 2. Review recent commits and CI (Static Analysis Gate, RSR Compliance). +# 3. Run `just validate-rsr` to check compliance. +# 4. Run `just assail` for the panic-attack static-analysis scan. + +[release-process] +# 1. Update version in 6a2/STATE.a2ml and 6a2/META.a2ml. +# 2. Run `just validate-rsr` and `just crg-grade`. +# 3. Tag and push. + +[maintenance-operations] +# RSR validation: just validate-rsr +# Static-analysis scan: just assail +# Component readiness: just crg-grade diff --git a/.machine_readable/ENSAID_CONFIG.a2ml b/.machine_readable/ENSAID_CONFIG.a2ml new file mode 100644 index 0000000..3bfbd3f --- /dev/null +++ b/.machine_readable/ENSAID_CONFIG.a2ml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: MPL-2.0 +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +# +# ENSAID_CONFIG.a2ml — eNSAID Environment Configuration +# Per-repo configuration for PanLL and eNSAID-compatible tools. +# Spec: https://github.com/hyperpolymath/standards/tree/main/ensaid-config +# +# This engine *emits into* PanLL (octads -> VeriSimDB -> panels) and renders its +# "levels of objects" through overlay-protocol view-layers. See +# docs/theory/CORRESPONDENCE-MODEL.adoc, "Rendering" and "Downstream: feeding PanLL". + +# ───────────────────────────────────────────────────────────────── +# [ensaid] — Core eNSAID identity and version +# ───────────────────────────────────────────────────────────────── +[ensaid] +version = "1.0.0" +tool = "panll" + +# ───────────────────────────────────────────────────────────────── +# [workspace] — Workspace mode, protection, and execution policy +# ───────────────────────────────────────────────────────────────── +[workspace] +mode = "rhodium" # rhodium | gold | silver | bronze +protection = "open" # open | guarded | locked +execution = "live" # live | dry-run | approval-required + +# ───────────────────────────────────────────────────────────────── +# [preferences] — Display and behaviour preferences +# ───────────────────────────────────────────────────────────────── +[preferences] +humidity = "medium" # high | medium | low (drift aura intensity) +default-arrangement = "correspondence-3-panel" +auto-connect = true + +# ───────────────────────────────────────────────────────────────── +# [panels] — View-layers render the engine's "levels of objects": +# focus | glyph | blockly | raw-code | side-by-side (overlay-protocol). +# ───────────────────────────────────────────────────────────────── +[panels] +version = "1.0.0" + +# ───────────────────────────────────────────────────────────────── +# [workflows] — Automation Router event-driven cross-panel rules +# ───────────────────────────────────────────────────────────────── +[workflows] +version = "1.0.0" + +# ───────────────────────────────────────────────────────────────── +# [clades] — Panel clade trait/capability overrides +# ───────────────────────────────────────────────────────────────── +[clades] +version = "1.0.0" + +# ───────────────────────────────────────────────────────────────── +# [portfolios] — Custom panel bundles for this repo's workflow +# ───────────────────────────────────────────────────────────────── +[portfolios] +version = "1.0.0" + +[[portfolios.custom]] +id = "correspondence-dev" +name = "Correspondence Engine Development" +description = "Cross-language correspondence panes: side-by-side + residue + glyph + focus" +panels = ["raw-code", "side-by-side", "glyph", "focus"] +default-isolation = "native" diff --git a/Justfile b/Justfile index a7caa0e..ae32a1f 100644 --- a/Justfile +++ b/Justfile @@ -237,9 +237,9 @@ help-me: @echo "" @echo "Include the output of 'just doctor' in your report." -# Run panic-attacker pre-commit scan +# Run panic-attack pre-commit scan assail: - @command -v panic-attack >/dev/null 2>&1 && panic-attack assail . || echo "panic-attack not found — install from https://github.com/hyperpolymath/panic-attacker" + @command -v panic-attack >/dev/null 2>&1 && panic-attack assail . || echo "panic-attack not found — install from https://github.com/hyperpolymath/panic-attack" # Print the current CRG grade (reads from READINESS.md '**Current Grade:** X' line) From 734c4b058448c9d7d0d88986c5522c1da26fd132 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 18 Jun 2026 11:45:23 +0000 Subject: [PATCH 3/3] docs(identity): re-point repo to the correspondence (classify-not-translate) engine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring the public + machine-readable identity into line with the merged correspondence-model spec (docs/theory/CORRESPONDENCE-MODEL.adoc): - README.adoc, EXPLAINME.adoc, ROADMAP.adoc — Duolingo/Rosetta-Stone-for-PLs framing: a comprehension+transfer engine that *classifies* cross-language correspondences (Concept/Form/Transition + six CorrespondenceKinds), not an IDE / linter / universal translator. Engine-vs-cartridge split; feeds PanLL; no-shame transfer-first pedagogy; HAS accessibility; toolchain honesty. - CLAUDE.md, .claude/CLAUDE.md — corrected overview + notes; policy tables preserved (Deno/Justfile/Zig/Idris2; ReScript banned in new code). - .machine_readable/{STATE,META,ECOSYSTEM}.a2ml (+ 6a2/ copies) — corrected identity/purpose/ADRs/related-projects; filled empty + corrupted fields. Licence labels left untouched (no relicensing): the pre-existing PMPL badge, "Palimpsest License (MPL-2.0)" text, and ROADMAP "MPL-2.0-or-later" are flagged to the owner, not edited. No SPDX identifiers changed. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01A1BaAhqxUjkgVb1yg1sZap --- .claude/CLAUDE.md | 11 +- .machine_readable/6a2/ECOSYSTEM.a2ml | 16 +- .machine_readable/6a2/META.a2ml | 12 +- .machine_readable/6a2/STATE.a2ml | 32 +-- .machine_readable/ECOSYSTEM.a2ml | 21 +- .machine_readable/META.a2ml | 18 +- .machine_readable/STATE.a2ml | 49 +++-- CLAUDE.md | 239 ++++++--------------- EXPLAINME.adoc | 259 ++++++++++++++++++++-- README.adoc | 308 ++++++++++++++------------- ROADMAP.adoc | 123 ++++++----- 11 files changed, 645 insertions(+), 443 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 22c75e6..a6b7e7b 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -2,8 +2,15 @@ ## Project: Nextgen Languages Evangeliser -Flagship target: **AffineScript**. Legacy target: **ReScript**. More targets planned (Rust, Gleam, Zig). -Current host application language: ReScript (migration to AffineScript planned in Phase 3). +**Duolingo / Rosetta Stone for programming languages** — a language-*comprehension and transfer* engine that **classifies** cross-language correspondences (it does not translate, lint, or build IDEs) so learning transfers from a known language to a new one. Canonical design: `docs/theory/CORRESPONDENCE-MODEL.adoc`. + +- **Not** an IDE (that is **PanLL + eNSAID**; this engine *feeds* PanLL), **not** a linter, **not** a universal translator (no Curry–Howard-fidelity goal), **not** a shame-the-JS pattern matcher. +- **Model:** Concept / Form / Transition; six `CorrespondenceKind`s (cognate / false-friend / antonym / alien-realization / novel / vanished) as graded Echo fibres; classification runs per stratum. Carrier = Dyadic relation + Echo loss-with-residue (`proven-tests-and-benches` + `echo-types`). +- **Division of labour:** we build the engine + interface + vocabulary; the community authors per-language **cartridges** (`standards/cartridges/`). + +Host: **ReScript today** (legacy host, being migrated; banned in *new* code per estate policy → AffineScript `.affine`). **AffineScript** is the future host and a first-class target (Zig FFI + Idris2 ABI seams). + +When working here: classify-don't-translate; keep the no-shame voice; lead with the correspondence model (AffineScript is one first-class target/host, not the sole pitch); author-now / verify-in-CI when the toolchain is absent; **MPL-2.0 SPDX on new files, never relicense or sweep SPDX (licence-label drift is FLAG-ONLY to the owner)**. ## Language Policy (Hyperpolymath Standard) diff --git a/.machine_readable/6a2/ECOSYSTEM.a2ml b/.machine_readable/6a2/ECOSYSTEM.a2ml index b11c904..846d1a2 100644 --- a/.machine_readable/6a2/ECOSYSTEM.a2ml +++ b/.machine_readable/6a2/ECOSYSTEM.a2ml @@ -3,18 +3,24 @@ # # ECOSYSTEM.a2ml — Nextgen Languages Evangeliser ecosystem position [metadata] -version = "1.0" -last-updated = "2026-04-11" +version = "1.2" +last-updated = "2026-06-18" [project] name = "Nextgen Languages Evangeliser" -purpose = "image:https://img.shields.io/badge/license-Palimpsest--MPL--1.0-purple.svg[Palim" +purpose = "Duolingo/Rosetta-Stone for programming languages — a comprehension+transfer engine that classifies cross-language correspondences; emits into PanLL; extended by community language cartridges." role = "project" [position-in-ecosystem] -category = "" +category = "application" +description = "Cross-language correspondence engine; classify-not-translate; feeds PanLL" [related-projects] projects = [ - # No related projects recorded + "hyperpolymath/panll — downstream IDE / contact layer this engine feeds (+ eNSAID)", + "hyperpolymath/proven-tests-and-benches — Dyadic relation carrier", + "hyperpolymath/echo-types — loss-with-residue (Agda)", + "hyperpolymath/standards — cartridges, overlay-protocol, ensaid-config, accessibility", + "hyperpolymath/affinescript — first-class target + future host", + "hyperpolymath/typed-wasm — AffineScript codegen layer", ] diff --git a/.machine_readable/6a2/META.a2ml b/.machine_readable/6a2/META.a2ml index 36ae5e3..5883426 100644 --- a/.machine_readable/6a2/META.a2ml +++ b/.machine_readable/6a2/META.a2ml @@ -2,10 +2,9 @@ # Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # # META.a2ml — Nextgen Languages Evangeliser meta-level information -# Renamed from Rescript Evangeliser on 2026-04-16 [metadata] -version = "1.0.0" -last-updated = "2026-04-11" +version = "1.1.0" +last-updated = "2026-06-18" [project-info] license = "MPL-2.0" @@ -13,7 +12,12 @@ author = "Jonathan D.A. Jewell (hyperpolymath)" [architecture-decisions] decisions = [ - # No ADRs recorded + "ADR-1 Classify, don't translate — name the CorrespondenceKind + residue; no universal translator, no Curry-Howard-fidelity goal", + "ADR-2 Carrier = Dyadic relation + Echo loss-with-residue (proven-tests-and-benches + echo-types); invariant-path is the governance front-end", + "ADR-3 Engine vs cartridge — we build the engine/interface/vocabulary; per-language facts are cartridges (standards/cartridges)", + "ADR-4 Host ReScript -> AffineScript (Zig FFI + Idris2 ABI seams); ReScript banned in new code", + "ADR-5 Emit into PanLL (octads -> VeriSimDB -> panels); not itself the IDE", + "ADR-6 Knot-theory framing is an aspirational lens, not a literal computation", ] [development-practices] diff --git a/.machine_readable/6a2/STATE.a2ml b/.machine_readable/6a2/STATE.a2ml index c04e05d..e0ab148 100644 --- a/.machine_readable/6a2/STATE.a2ml +++ b/.machine_readable/6a2/STATE.a2ml @@ -4,35 +4,43 @@ # STATE.a2ml — Nextgen Languages Evangeliser project state [metadata] project = "nextgen-languages-evangeliser" -version = "1.0.0" -last-updated = "2026-01-10T13:50:33+00:00" +version = "1.2.0" +last-updated = "2026-06-18" status = "active" -session = "converted from scheme — 2026-04-11" [project-context] name = "Nextgen Languages Evangeliser" -purpose = """""" -completion-percentage = 50 +purpose = "Duolingo/Rosetta-Stone for programming languages — a comprehension+transfer engine that classifies cross-language correspondences so learning transfers from a known language to a new one." +completion-percentage = 58 [position] -phase = "Active Development" # design | implementation | testing | maintenance | archived -maturity = "experimental" # experimental | alpha | beta | production | lts +phase = "Re-point: correspondence engine + abstraction-model pivot" # design | implementation | testing | maintenance | archived +maturity = "alpha" # experimental | alpha | beta | production | lts [route-to-mvp] milestones = [ - # No milestones recorded + "M0 correspondence-model spec — complete", + "M1 standards/repo hygiene — complete", + "M2 identity re-point + abstraction-model pivot — in progress", + "M3 browser multi-pane GUI + overlay view-layers — pending", + "M4 AffineScript host port (Zig FFI + Idris2 ABI) — gated", + "M5 cartridge contract + 2nd language pack — pending", + "M6 proofs/benches + PanLL octad emission — pending", ] [blockers-and-issues] issues = [ - # No blockers recorded + "AffineScript/Idris2/Zig/Deno toolchain absent in some environments — author now, verify in CI", + "JTV grammar-v2 worked example stubbed pending julia-the-viper repo access", + "Licence-label drift to flag to owner vs MPL-2.0 SPDX — FLAG-ONLY, manual", ] [critical-next-actions] actions = [ - # No actions recorded + "Abstraction-model pivot: Concept/Form/Transition + CorrespondenceKind in src", + "Browser multi-pane GUI surface", ] [maintenance-status] -last-run-utc = "2026-01-10T13:50:33+00:00T00:00:00Z" -last-result = "unknown" # unknown | pass | warn | fail +last-run-utc = "2026-06-18T00:00:00Z" +last-result = "pass" # unknown | pass | warn | fail diff --git a/.machine_readable/ECOSYSTEM.a2ml b/.machine_readable/ECOSYSTEM.a2ml index d368e8d..badfe41 100644 --- a/.machine_readable/ECOSYSTEM.a2ml +++ b/.machine_readable/ECOSYSTEM.a2ml @@ -2,26 +2,33 @@ ;; ECOSYSTEM.a2ml — nextgen-languages-evangeliser ecosystem position ;; Migrated from root ECOSYSTEM.scm on 2026-04-12 ;; Renamed from rescript-evangeliser on 2026-04-16 +;; Updated for the correspondence re-point on 2026-06-18 (ecosystem - (version "1.1") + (version "1.2") (name "nextgen-languages-evangeliser") (predecessor "rescript-evangeliser") (type "project") - (purpose "Nextgen typed-language evangelism — educational materials, examples, and tools for adopting AffineScript (flagship), ReScript (legacy), and future targets") + (purpose "Duolingo/Rosetta-Stone for programming languages — a comprehension+transfer engine that classifies cross-language correspondences so learning transfers from a known language to a new one") (position-in-ecosystem (role "component") (layer "application") - (description "Multi-target advocacy and resource hub for next-generation typed languages within the hyperpolymath estate")) + (description "Cross-language correspondence engine; classify-not-translate; emits into PanLL; extended by community language cartridges")) (related-projects + (downstream-ide "hyperpolymath/panll (+ eNSAID contact layer this engine feeds)") + (carrier-relation "hyperpolymath/proven-tests-and-benches (Dyadic.idr)") + (carrier-residue "hyperpolymath/echo-types (loss-with-residue, Agda)") + (cartridge-home "hyperpolymath/standards (cartridges, overlay-protocol, ensaid-config, accessibility)") (flagship-target "hyperpolymath/affinescript") (codegen-layer "hyperpolymath/typed-wasm") (legacy-target "rescript-lang/rescript")) - (what-this-is "Educational materials, worked examples, and advocacy tools for affine/linear-typed and other next-generation languages (flagship: AffineScript)") + (what-this-is "A language-comprehension and transfer engine: it classifies cross-language correspondences (cognate/false-friend/antonym/alien-realization/novel/vanished) and teaches the transfer without shame") (what-this-is-not - "A compiler" - "A type-checker" - "A language-server (see affinescript repo for LSP)")) + "An IDE (that is PanLL)" + "A linter" + "A universal translator (no Curry-Howard-fidelity goal)" + "A compiler or type-checker" + "A shame-the-JavaScript pattern matcher")) diff --git a/.machine_readable/META.a2ml b/.machine_readable/META.a2ml index 406ddf1..94a53cb 100644 --- a/.machine_readable/META.a2ml +++ b/.machine_readable/META.a2ml @@ -1,15 +1,25 @@ ;; SPDX-License-Identifier: MPL-2.0 ;; META.a2ml — nextgen-languages-evangeliser meta-information ;; Migrated from root META.scm on 2026-04-12 +;; Updated for the correspondence re-point on 2026-06-18 (meta - (version "1.0.0") + (version "1.1.0") (project "nextgen-languages-evangeliser") - (architecture-decisions ()) + (architecture-decisions + (adr-1 "Classify, don't translate — the engine names the kind of cross-language correspondence (CorrespondenceKind) and its residue; it is not a universal translator and claims no Curry-Howard fidelity") + (adr-2 "Formal carrier = Dyadic relation + Echo loss-with-residue (proven-tests-and-benches Dyadic.idr + hyperpolymath/echo-types); invariant-path is the governance front-end") + (adr-3 "Engine vs cartridge — we build the general engine, interface and vocabulary; per-language facts are authored as cartridges (standards/cartridges)") + (adr-4 "Host moves ReScript -> AffineScript with Zig FFI + Idris2 ABI seams; ReScript banned in new code per estate policy") + (adr-5 "The engine emits into PanLL (octads -> VeriSimDB -> panels); it is not itself the IDE") + (adr-6 "Knot-theory framing is an aspirational lens, not a literal computation — documented honestly")) (development-practices (code-style "standard") - (security "openssf-scorecard") + (security "openssf-scorecard + panic-attack static-analysis-gate") (versioning "semver") (documentation "asciidoc") (branching "trunk-based")) - (design-rationale ())) + (design-rationale + (no-shame "celebrate / minimise / better / safety / example — transfer-first pedagogy") + (levels-of-objects "classification runs per stratum: surface -> structure -> intention -> trope -> invariant") + (accessibility "Hyperpolymath Accessibility Standard, Level A -> AA"))) diff --git a/.machine_readable/STATE.a2ml b/.machine_readable/STATE.a2ml index 2a3c6ab..c252f0e 100644 --- a/.machine_readable/STATE.a2ml +++ b/.machine_readable/STATE.a2ml @@ -2,41 +2,52 @@ ;; STATE.a2ml — nextgen-languages-evangeliser project state ;; Migrated from root STATE.scm on 2026-04-12 ;; Renamed from rescript-evangeliser on 2026-04-16 +;; Re-pointed to the correspondence (classify-not-translate) model on 2026-06-18 (state (metadata - (version "1.1.0") + (version "1.2.0") (project "nextgen-languages-evangeliser") (predecessor "rescript-evangeliser") - (last-updated "2026-04-16")) + (last-updated "2026-06-18")) + + (identity + (is "Duolingo/Rosetta-Stone for programming languages — a comprehension+transfer engine that classifies cross-language correspondences so learning transfers from a known language to a new one") + (is-not "an IDE (that is PanLL), a linter, a universal translator, or a shame-the-JS pattern matcher") + (model "Concept/Form/Transition + six CorrespondenceKinds (cognate/false-friend/antonym/alien-realization/novel/vanished) as graded Echo fibres") + (division "we build the engine + interface + vocabulary; the community authors per-language cartridges")) (current-position - (phase "Migration: Phase 1 — rebrand + engine generalisation") - (overall-completion 55) + (phase "Re-point: cross-language correspondence engine + abstraction-model pivot") + (overall-completion 58) (working-features - "ReScript target catalogue (52 patterns, 21 categories)" - "Scanner + Analyser detection engine" - "Narrative generation with 'You were close!' voice" - "Makaton-inspired glyph system" + "Correspondence-model design spec (docs/theory/CORRESPONDENCE-MODEL.adoc) — merged" + "Standards/machine-readable hygiene (6a2 manifests, panic-attack gate, eNSAID config) — merged" + "Scanner + Analyser detection engine (ReScript host)" + "Narrative generation (no-shame voice)" + "Makaton-inspired glyph view-layer" "CLI: scan / patterns / legend / stats" "RAW/FOLDED/GLYPHED view layers; plain/markdown/html outputs")) (route-to-mvp (milestones - (phase-0 (status "complete") (items "Decide pivot strategy" "Verify AffineScript toolchain")) - (phase-1 (status "in-progress") (items "Rebrand docs+metadata" "Generalise Types.res for multi-target")) - (phase-2 (status "pending") (items "Author AffineScript pattern catalogue (affine/linear safety)")) - (phase-3 (status "gated") (items "Host port ReScript -> AffineScript" "Gate: AffineScript->typed-wasm->WASM proof-of-life")) - (phase-4 (status "pending") (items "Policy perimeter flip" "ts-blocker + .res exception for legacy")) - (phase-5 (status "pending") (items "Additional targets: Rust, Gleam, Zig")))) + (m0 (status "complete") (items "Correspondence-model spec: Concept/Form/Transition + six kinds + Dyadic/Echo carrier")) + (m1 (status "complete") (items "Standards/repo hygiene: 6a2 manifests, panic-attack gate, eNSAID config")) + (m2 (status "in-progress") (items "Identity re-point" "Abstraction-model pivot: Concept/Form/Transition + CorrespondenceKind in src")) + (m3 (status "pending") (items "Browser multi-pane GUI + overlay view-layers + HAS accessibility")) + (m4 (status "gated") (items "AffineScript host port (.res -> .affine) + Zig FFI + Idris2 ABI seams")) + (m5 (status "pending") (items "Cartridge contract + 2nd language pack")) + (m6 (status "pending") (items "Idris2/Echo witnesses + benches + PanLL octad emission")))) (blockers-and-issues - "AffineScript WASM codegen backend parity incomplete (Phase 3 gate)" - "GitHub repo rename still needs manual action by maintainer") + "AffineScript/Idris2/Zig/Deno toolchain absent in some environments — author now, verify in CI" + "JTV grammar-v2 worked example stubbed pending julia-the-viper repo access" + "Licence-label drift to flag to owner (PMPL badge / 'Palimpsest License (MPL-2.0)' / ROADMAP 'MPL-2.0-or-later') vs MPL-2.0 SPDX — FLAG-ONLY, manual") (critical-next-actions - "Complete Phase 1a rebrand commit" - "Complete Phase 1b engine generalisation (Types.res -> multi-target)") + "Abstraction-model pivot: recast Types/Patterns/Narrative/Analyser to Concept/Form/Transition + CorrespondenceKind" + "Browser multi-pane GUI surface") (session-history - (2026-04-16 "Phase 0 decisions locked; Phase 1 started; branch claude/migrate-to-affinescript-zig-U0iYX"))) + (2026-04-16 "Phase 0 decisions locked; Phase 1 started") + (2026-06-18 "Re-point: correspondence-model spec merged (#19); standards hygiene merged (#20); identity re-point"))) diff --git a/CLAUDE.md b/CLAUDE.md index a488c17..2367d39 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,209 +2,108 @@ ## Project Overview -**Nextgen Languages Evangeliser** is a pattern detection engine, CLI, and educational toolkit that teaches JavaScript developers next-generation type-safe languages through progressive code transformation — without shame. +**Nextgen Languages Evangeliser** is **Duolingo / Rosetta Stone for programming languages** — a language-*comprehension and transfer* engine. It works one layer above text editing, on *syntactic and semantic intention*, and **classifies** cross-language correspondences so the effort spent learning one language **transfers** to the next. *Transfer learning across languages is the product.* -**Flagship target:** AffineScript (affine/linear type system, borrow checking, quantity checking, WASM backend). +Canonical design: `docs/theory/CORRESPONDENCE-MODEL.adoc` — this file mirrors it. The repo began as *ReScript Evangeliser*; ReScript is now a legacy host (being migrated) and a legacy target. -**Supported targets:** AffineScript (flagship), ReScript (legacy), with more to follow (Rust, Gleam, Zig being the likely next additions). +### What it is NOT +- **Not an IDE** — that is **PanLL + eNSAID** (the *contact* between human, tool, task, environment). This engine *feeds* PanLL; it is not PanLL. +- **Not a linter** — not scope-colouring or spotting a missing `;` / extra `)`. +- **Not a universal translator** — no Curry–Howard-fidelity goal ("nice, not the point"). +- **Not a shame-the-JavaScript pattern matcher.** -This project is the successor to *ReScript Evangeliser*. The ReScript pattern library is preserved as a legacy target; active pattern authorship now centres on affine/linear safety concerns teachable from idiomatic JavaScript. +## The Model: Concept / Form / Transition -## Project Purpose +- **Concept** — the invariant / equivalence-class (the recurring *trope*). +- **Form** — a representative of a Concept in one language (`let` in ReScript, `=` in Erlang, `def` in Python). +- **Transition** — a directed Form(A)→Form(B) correspondence plus its *residue* (what is lost, added, or inverted). -This repository serves as a resource hub for: -- Educational materials about next-generation type-safe languages (AffineScript first) -- Pattern catalogues showing equivalent transformations from JavaScript to target languages -- Tools that detect amenable patterns in existing JS and encourage adoption -- Community content that evangelises type-safe coding without shaming incumbent code +Classification is a **graded `CorrespondenceKind`**, not a boolean — six grades of the Echo fibre, each with a pedagogy: +**cognate** (transfer) · **false-friend** (warn) · **antonym** (remap) · **alien-realization** (bridge) · **novel / no-anchor** (teach de novo) · **vanished** (re-route). Classification runs *per stratum* (surface → structure → intention → trope → invariant). -## Technology Stack +Carrier = **Dyadic relation + Echo loss-with-residue** (`proven-tests-and-benches` `Dyadic.idr` + `hyperpolymath/echo-types`); `invariant-path` is the governance front-end. "Knot theory" is an aspirational lens, **not** a literal computation. -### Core Technologies -- **AffineScript** — flagship target language (teaching subject) -- **typed-wasm** — separate repo; AffineScript's downstream codegen layer (AffineScript → typed-wasm → WASM) -- **ReScript** — current host application language (during Phase 1/2 of migration), legacy target -- **Deno** — runtime & package management (replaces Node/npm/bun) -- **Nickel** — configuration language -- **Zig** — FFI bridge (canonical, per `0-AI-MANIFEST.a2ml`) +## Engine vs. Cartridge -### Language Policy (Hyperpolymath Standard) +- **We build** the general engine + interface + classification vocabulary + residue model + a reference language pack. +- **The community builds** per-language modules as **cartridges** (`standards/cartridges/`). + +The engine is language-agnostic; the nextgen-language collection is merely the substrate we dogfood. + +## Downstream -**ALLOWED:** -- AffineScript (application code, once Phase 3 port completes) -- ReScript (current application code; demoted to legacy target after Phase 3) -- Deno (runtime & package management) -- Zig (FFI, systems code) -- Bash/POSIX Shell (scripts, automation) -- JavaScript (only where ReScript/AffineScript cannot — minimal glue code) -- Nickel (configuration) +Emits `octads` → VeriSimDB (`:8097`) + Groove signals → **PanLL** panels; view-layers conform to the estate **overlay-protocol**; ergonomics read `.machine_readable/ENSAID_CONFIG.a2ml`; accessibility meets the **Hyperpolymath Accessibility Standard** (Level A → AA). -**BANNED:** -- TypeScript (use AffineScript or ReScript) -- Node.js (use Deno) -- npm/bun (use Deno) -- Makefile (use Justfile) -- V (use Zig, except inside V-ecosystem-specific projects) +## Technology Stack + +- **ReScript** — current / legacy host (being ported; banned in *new* code per estate policy: `.res` → `.affine`) +- **AffineScript** — future host + first-class target (Zig FFI + Idris2 ABI seams; OCaml 5.1+; emits typed-wasm IR → WebAssembly) +- **Deno** — runtime & package management (not npm/bun) +- **Zig** — FFI layer; **Idris2** — ABI / proofs +- **Nickel** — configuration -### Key Features to Evangelise +### Language Policy (Hyperpolymath Standard) -Per target, the pitch differs. The engine is target-aware: +**ALLOWED:** AffineScript (future host), ReScript (legacy host/target), Deno, Zig (FFI), Idris2 (ABI/proofs), Bash/POSIX shell, JavaScript (glue only — see exemptions in `.claude/CLAUDE.md`), Nickel. -- **AffineScript (flagship):** affine/linear types, use-at-most-once guarantees, borrow checking, quantity type theory, compile-time resource safety, WASM deployment. -- **ReScript (legacy):** sound type inference, Option/Result, pattern matching, pipe operator, zero-cost JS interop. +**BANNED:** TypeScript, Node.js, npm/bun, Makefile (use Justfile), V (outside the V ecosystem), Python, Go. **ReScript is banned in _new_ code** — migrate `.res` → `.affine` directly. ## Project Structure ``` nextgen-languages-evangeliser/ -├── src/ # Application source (ReScript today, AffineScript post-Phase 3) -│ ├── Types.res # Core type model — multi-target pattern representation -│ ├── Glyphs.res # Makaton-inspired glyph system (target-agnostic) -│ ├── Narrative.res # "You were close!" narrative generation (target-aware) -│ ├── Patterns.res # Pattern library (multi-target) -│ ├── Scanner.res # Regex pattern detection engine -│ ├── Analyser.res # Result aggregation and reporting -│ ├── Output.res # RAW/FOLDED/GLYPHED rendering (multi-target) -│ └── Cli.res # CLI entry point +├── src/ # Host source (ReScript today; AffineScript target) +│ ├── Types.res # Core type model (→ Concept / Form / Transition) +│ ├── Glyphs.res # Makaton-inspired glyph view-layer +│ ├── Narrative.res # Shame-free narrative (per CorrespondenceKind) +│ ├── Patterns.res # Correspondence catalogue (→ reference language pack) +│ ├── Scanner.res # Detection engine +│ ├── Analyser.res # Classification + aggregation +│ ├── Output.res # focus/glyph/blockly/raw/side-by-side view-layers +│ └── Cli.res # CLI entry point (offline fallback) +├── gui/ # Browser multi-pane workspace (primary surface) +├── docs/theory/CORRESPONDENCE-MODEL.adoc # Canonical design spec ├── test/ # Test suites -├── docs/ # Documentation -├── rescript.json # Host build config (current) -├── deno.json # Deno configuration ├── Justfile # Task orchestration (NOT Makefile) -├── Mustfile.epx # Deployment contract -└── config.ncl # Nickel configuration +└── deno.json # Deno configuration ``` -## Development Guidelines - -### Code Style -- Follow the host language's official style guide (ReScript today; AffineScript post-Phase 3) -- Use meaningful names; prefer pattern matching over if/else -- Leverage the type system to make invalid states unrepresentable -- Write interface files (.resi) for public APIs -- Add SPDX license headers to all source files - -### Best Practices -1. **Type-First Design** — Design types before implementation -2. **Immutability** — Prefer immutable data structures -3. **Pure Functions** — Write pure functions when possible -4. **Documentation** — Document complex type definitions and public APIs -5. **Error Handling** — Use Result and Option types (not exceptions) - ## Common Commands ```bash -# Install dependencies -just install - -# Build the project -just build - -# Watch mode for development -just watch - -# Clean build artifacts -just clean - -# Run tests -just test - -# Validate project structure and policy -just validate - -# Format code -just fmt - -# Full validation -just validate-rsr +just install # Install dependencies (Deno) +just build # Build host sources +just watch # Watch mode +just test # Run tests +just assail # panic-attack static-analysis scan +just validate-rsr # RSR compliance +just fmt # Format ``` -## Build System - -This project uses: -- **Deno**: For build scripts and task running -- **justfile**: For task orchestration (NOT Makefile) -- **ReScript**: Current host compiler (bsb) -- **AffineScript**: Planned host compiler post-Phase 3 (OCaml 5.1+, Dune 3.14+; emits typed-wasm IR, which compiles to WASM) - -## Dependencies - -### Runtime -- Deno (latest stable) -- ReScript 12.2+ (current host) -- @rescript/core -- AffineScript compiler (planned, Phase 3+) - -### Package Management -- **Primary**: Guix (guix.scm) -- **Fallback**: Nix (flake.nix) -- **JS deps**: Deno (deno.json imports) - -## Evangelism Goals - -1. **Demonstrate Value** — Show concrete benefits of each supported target -2. **Lower Barriers** — Make adoption as easy as possible -3. **Share Success Stories** — Document real-world wins -4. **Build Community** — Foster a welcoming environment -5. **Create Resources** — Provide learning materials and tools - -## Philosophy: "Celebrate Good, Minimize Bad, Show Better" - -We **never** shame developers. Instead: - -1. **Celebrate** — Recognize what their JavaScript does well -2. **Minimize** — Gently acknowledge minor limitations -3. **Better** — Show how the target language enhances the pattern -4. **Safety** — Explain type-level (and affine/linear) guarantees -5. **Example** — Provide concrete, encouraging examples - -## Migration Status (ReScript → AffineScript) - -This repo is mid-migration from ReScript Evangeliser to Nextgen Languages Evangeliser. Phases: - -- **Phase 0** ✅ — Decide (option A content rewrite, multilang future, rename repo, toolchain verified) -- **Phase 1** 🚧 — Rebrand + generalise engine for multi-target (host stays ReScript) -- **Phase 2** — Pattern catalogue pivot: affine/linear-safety-focused AffineScript patterns -- **Phase 3** — Host language port ReScript → AffineScript (gated on toolchain WASM maturity) -- **Phase 4** — Policy perimeter flip (ts-blocker extended, affinescript linter added) -- **Phase 5** — Zig/V policy text formalisation +## Philosophy: no shame, transfer-first -## Resources +We **never** shame developers. The voice stays **celebrate / minimise / better / safety / example**. The six kinds map to: transfer cognates, warn on false friends, remap antonyms, bridge the alien, teach the novel, re-route the vanished. -### AffineScript -- Compiler: https://github.com/hyperpolymath/affinescript -- Toolchain: OCaml 5.1+, Dune 3.14+ -- Downstream codegen: typed-wasm (separate repo) → WebAssembly +## Re-point Status (was the ReScript → AffineScript "migration") -### ReScript (legacy target) -- [ReScript Documentation](https://rescript-lang.org/docs) -- [ReScript Forum](https://forum.rescript-lang.org) -- [ReScript GitHub](https://github.com/rescript-lang) +- ✅ Correspondence-model spec merged (Concept/Form/Transition + six kinds + Dyadic/Echo carrier) +- ✅ Standards / repo hygiene merged (6a2 manifests, panic-attack gate, eNSAID config) +- 🚧 Identity re-point + abstraction-model pivot (classify, not translate) +- → Browser multi-pane GUI (overlay view-layers) +- → AffineScript host port (Zig FFI + Idris2 ABI) +- → Cartridge contract + second language pack +- → Proofs/benches + PanLL octad emission ## Notes for Claude -When working on this project: -- Prioritize type safety and correctness -- Suggest idiomatic patterns for whichever target is being discussed -- Treat AffineScript as the flagship target; ReScript as a well-supported legacy target -- When adding patterns, lead with the AffineScript transformation and keep ReScript as secondary -- Help maintain clear documentation -- Encourage best practices in evangelism materials -- **Use Deno, not npm/bun** -- **Use Justfile, not Makefile** -- **Use Zig for FFI, not V (except inside V-ecosystem projects)** -- **Source host language: ReScript during Phases 1-2, AffineScript from Phase 3 onward** -- Add SPDX license headers to new source files - -## Project Philosophy - -**Make next-generation languages approachable**: The goal is to help developers discover and adopt affine/linear type systems and other nextgen features by: -- Showing practical examples from code they already write -- Addressing common concerns -- Demonstrating real benefits -- Providing migration paths -- Building confidence through education +- Lead with the **correspondence model**; AffineScript is one first-class target/host, not the sole pitch. +- **Classify, don't translate.** No universal-translator or Curry–Howard-fidelity claims. +- **No shame.** Keep the celebrate / minimise / better / safety / example voice. +- **Use Deno, not npm/bun. Use Justfile, not Makefile. Use Zig for FFI, Idris2 for ABI/proofs.** +- **ReScript is banned in new code** → AffineScript (`.affine`). +- Toolchain may be absent in this environment — **author now, verify in CI**; never claim a green build you did not run. +- **Licence: MPL-2.0 (sole-owner repo). Add SPDX `MPL-2.0` to new files. NEVER relicense or bulk-sweep SPDX; licence-label drift is FLAG-ONLY to the owner.** --- -*This document should be updated as the project evolves and new patterns emerge.* +*Keep this in sync with `docs/theory/CORRESPONDENCE-MODEL.adoc` as the engine evolves.* diff --git a/EXPLAINME.adoc b/EXPLAINME.adoc index c22e74b..fb6fc0e 100644 --- a/EXPLAINME.adoc +++ b/EXPLAINME.adoc @@ -2,48 +2,269 @@ = Nextgen Languages Evangeliser — EXPLAINME -== Celebrate good, minimize bad, show better +== Learn — to love it! -[quote, README.adoc] +[quote, docs/theory/CORRESPONDENCE-MODEL.adoc] ____ -A pattern detection engine, CLI, and educational toolkit that teaches JavaScript developers next-generation type-safe languages through progressive code transformation, without shame. +Duolingo / Rosetta Stone for programming languages — a language-comprehension and transfer engine that works one layer above text editing, on syntactic and semantic intention, so that the effort a person spent learning language A transfers when they move to B. ____ -The evangeliser detects patterns in existing JavaScript amenable to transformation, then shows equivalent code in one or more target languages — with encouragement rather than criticism. -It uses progressive disclosure (RAW, FOLDED, GLYPHED views) and Makaton-inspired glyphs to make concepts visual. -See link:README.adoc[] for the full pattern catalogue and quick start. +This is the long-form "why". For the precise, canonical version, read +link:docs/theory/CORRESPONDENCE-MODEL.adoc[docs/theory/CORRESPONDENCE-MODEL.adoc] — +this document mirrors it and may not lead it. -**Current state:** this repo is the successor to *ReScript Evangeliser* and is mid-migration. -The ReScript catalogue (originally 52 patterns across 21 categories) is preserved as a legacy target. -Active pattern authorship has pivoted to *AffineScript*, focusing on affine/linear-safety concerns — use-after-free analogs, double-cleanup, aliasing of owned state, missing disposal. -See link:ROADMAP.adoc[] for migration phases. +=== The one-sentence pitch -**Caveat:** During Phases 1–2 the host language of this toolkit is still ReScript; Phase 3 ports it to AffineScript once the AffineScript → typed-wasm → WASM toolchain is stable enough to carry 2,400+ LOC of production code. +You already learned to program. When you pick up your next language, most of what +you know is still true — but some of it is a *trap*, and a little of it has *no analog +at all*. This engine tells you which is which. *Transfer learning across languages is +the product.* + +=== What it is + +A *language-comprehension and transfer* engine. It works *one layer above text +editing*, on *syntactic and semantic intention* — not characters, not tokens-as-text. +Given a Form you know in language A and a Form in language B, it *computes and +classifies* the correspondence between them, and surfaces the *residue*: what is lost, +added, or inverted in the crossing. That classification is the lesson. + +The substrate we dogfood is the nextgen-language collection (AffineScript and friends), +but the engine is *language-agnostic*: JS → TypeScript, Ruby, Prolog, C, or exotic +targets like QPL, Arrow, JTV. + +=== What it is *not* (stated plainly) + +* *Not "the next best IDE."* Contrast, project widgets, pop-up notepads, shortcuts, + attention/memory/workflow ergonomics — that is the job of *PanLL* (PanLL + eNSAID = + the _contact_ between human, tool, task, and environment). This engine *feeds* PanLL. + It is not PanLL. +* *Not a linter.* It is not about proximal/distal scope-colouring or spotting a missing + `;` / extra `)`. A linter *looks up* rules; this engine *computes and classifies* + cross-language equivalence. +* *Not a universal translator.* A verified any-language→any-language compiler with full + Curry–Howard fidelity would be nice — it is *not the goal*, and we will not attempt it + "to the dot". +* *Not a shame-the-JavaScript pattern matcher.* The voice is celebrate / minimise / + better / safety / example, always. + +=== The model: Concept / Form / Transition + +* *Concept* — the invariant / equivalence-class, the recurring _trope_: "bind a name to + a value", "iterate a collection", "fail recoverably". +* *Form* — a representative of a Concept _in one language_: `let` in ReScript, `=` in + Erlang, `def` in Python. One Concept, many Forms. +* *Transition* — a directed correspondence Form(A) → Form(B): the Echo-refined map plus + its *residue*. + +A *lesson* presents a Concept through the learner's known Form, the target Form, and the +Transition between them — narrated without shame: "you already know this; here's the +catch". + +=== Levels of objects (strata) + +Classification runs *per stratum of meaning*, not on flat text: + +. *Surface* — tokens, lexemes (`=`, `def`, `match`). +. *Structure* — AST shape, scoping, arity. +. *Semantic intention* — what the construct _does_ (bind? mutate? branch?). +. *Abstraction / trope* — the Concept it instantiates. +. *Cross-language invariant* — the preserved quantity certifying "same idea". + +The interface lets a learner move *up and down* the strata and *across* view-modes. A +correspondence can hold at one stratum and break at another — and *that divergence is the +most valuable signal*. It is, literally, the false-friend detector. + +=== The false-friends pedagogy (where it earns its keep) + +The one judgement that matters is *"is this safe to transfer, or is it a trap?"* So the +relation is not a boolean — it is a *graded* `CorrespondenceKind`, one of six, each with +its own teaching move: + +[cols="2,3,2", options="header"] +|=== +| Kind | What it means | Teaching move + +| *Cognate / true friend* +| Intention + behaviour coincide; residue ≈ ∅. _e.g._ `def` → `define`. But "just a + rename" is a hypothesis to *verify*, never assume. +| *Transfer directly.* + +| *False friend / homonym* +| Surface matches, semantics diverge. _e.g._ BASIC `=` (destructive assignment) vs. + Erlang `=` (bind-once / unify). Detected as: surface-corresponds ∧ semantics-diverge. +| *Flag the trap.* + +| *Antonym / inverted* +| Related but behaves oppositely. _e.g._ 0- vs. 1-indexing; truthiness conventions; + stack-growth direction. Residue = the flip. +| *Remap the intuition.* + +| *Alien realization* +| Same intention, foreign mechanism, large residue. _e.g._ in JTV (reversible / add-only) + subtraction is `add` run backwards; divide via reversed repeated-add. Also: recursion- + only languages, CPS, monadic IO just to print. +| *Bridge with effort; explain the machinery.* + +| *Novel / no anchor* +| Forward fibre empty (`∄ x. f x ≡ y`) — the target has a concept with nothing to map + _from_. _e.g._ static types coming from assembly + JS; ownership/borrowing; affine/ + linear use-once; Prolog `cut`; JTV totality and information-flow labels. +| *Teach de novo — there is no transfer.* + +| *Vanished* +| Backward fibre empty (`∄ y`) — a concept the learner relied on is _gone_. _e.g._ + `return` in ReScript; `null` in a null-free language; mutable variables in a pure one. +| *Un-learn / re-route.* +|=== + +The residue ranges from ∅ (true iso) through inverted/large to empty-in-either-direction +(novel / vanished). This taxonomy *is* the Duolingo/Rosetta pedagogy. + +==== A walk through the false friend + +BASIC and Erlang both write `X = 5`. Surface: identical. Structure: both an +infix `=` between a name and a literal. A naïve tool calls them cognate. They are not. + +* In BASIC, `=` *destructively assigns* — `X = 5` then `X = 6` is fine; `X` is now 6. +* In Erlang, `=` *binds once and unifies* — `X = 5` binds `X`; a later `X = 6` is not an + overwrite, it is a *match that fails*. + +The engine sees `surface corresponds` ∧ `semantic diverges` across strata and emits +*false friend*. The lesson does not say "you wrote it wrong". It says: "you already know +`=`; here is the one thing that will bite you." That is the whole product in miniature. + +=== The formal carrier (and an honesty caveat) + +The model is grounded in the estate's own formalism, not a bespoke lookup table: + +* *Carrier = Dyadic `Relation`* (`proven-tests-and-benches` `Dyadic.idr`): + `{ relates; reflexive; symmetric; transitive }`. Equivalence = refl ∧ sym ∧ trans. +* *Crossings are lossy-with-residue = Echo fibre* (`hyperpolymath/echo-types`, Agda): + `Echo f y := Σ (x : A), f x ≡ y`. The residue (a proof term) is exactly _what is lost + or added_ A→B. A retraction (one-way loss) is distinguished from an isomorphism (no + residue) by symmetry. +* *Typed residue-lenses = the three Echo bridges* (`Bridge.idr`): `EchoChoreo` + (protocol/sequencing), `EchoEpistemic` (visibility/knowledge), `EchoTropical` + (cost, min-plus). Extensible. +* *`invariant-path`* is the governance front-end: it anchors each equivalence _claim_ to + its two code locations plus a witness (proof/test), human-in-the-loop and editable. + +[IMPORTANT] +==== +*"Knot theory" is an aspirational lens, not a computation.* The framing _types → carrier +· tropes → recurring equivalence-figures · knot theory → certificate_ is load-bearing for +intuition, but there is *no literal knot-invariant computation here*. We use *invariant* +in the precise sense of a _preserved quantity that certifies "same idea"_, and we make no +Curry–Howard-fidelity claim. +==== + +=== Engine vs. cartridge — the division of labour + +We cannot do this "to the dot", and we do not try. Responsibilities split cleanly: + +* *We build* — the general engine, the interface, the classification vocabulary + (`CorrespondenceKind`), the residue/fibre model, the Dyadic/Echo carrier, and a + *reference language pack*. The certifiable Idris2/Echo math is applied *where it pays* + (high-value or dangerous correspondences), not everywhere. +* *The community builds* — the *per-language modules as cartridges* + (`standards/cartridges/`): the _facts_, i.e. which Forms instantiate which Concepts, + and for each Transition the kind + residue + an optional witness. + +A cartridge fact, sketched: + +[source] +---- +(transition + (concept "name-binding") + (from (lang "basic") (form "X = 5")) + (to (lang "erlang") (form "X = 5")) + (kind false-friend) + (strata (surface corresponds) (semantic diverges)) + (residue "BASIC rebinds destructively; Erlang binds once and unifies") + (witness "proofs/erlang_single_assignment.idr")) ; optional, where it pays +---- + +=== The interface: overlay view-layers + +The "levels of objects" are rendered as *overlay view-layers* — switchable and +non-destructive, each conforming to the estate *overlay-protocol* (additive, +non-modifying, idempotent, Idris2-ABI proved): + +* *focus* — show only what's needed now +* *glyph* — Makaton-style symbols (accessible, low cognitive load) +* *blockly / scratch* — flowchart of structure +* *raw code* — the text itself +* *side-by-side* — multi-language diff with step-sync + +The primary surface is a *browser multi-pane workspace*; the CLI/TUI is the offline +fallback. Accessibility is a contract, not a coat of paint: *Hyperpolymath Accessibility +Standard, Level A minimum → AA* (keyboard-only operation, ≥4.5:1 contrast, colourblind- +safe palettes, ARIA/screen-reader, reduced-motion, plain-language mode, high-contrast +glyph variants). + +=== Downstream: it emits, it does not own the IDE + +Analyses become `octads` written to VeriSimDB (`:8097`) plus `Groove` signals; PanLL +panels subscribe and re-render. Relevant octad types: `inline-annotation` (per-construct +claims), `ecosystem-link` (intra-program relationships), `proof-status` (where a +Transition carries a witness). Ergonomics are read from +`.machine_readable/ENSAID_CONFIG.a2ml`. + +=== Where the host language is going + +The host *today* is ReScript — now a *legacy host being migrated*, and a legacy +*target*. Per estate policy ReScript is banned in *new* code (`.res` → `.affine`). The +host is moving to *AffineScript*, with *Zig FFI + Idris2 ABI* seams. AffineScript stays a +first-class teaching target and the future host — but the project's frame is no longer +"evangelise AffineScript specifically". It is "teach *any* language by transfer, with +AffineScript among the first-class targets". + +=== Toolchain honesty + +AffineScript / Idris2 / Zig / Deno may be absent in some environments. The design and the +proofs are *authored now and verified in CI* — we do not claim local green builds we +cannot run. The correspondence-model spec itself is verified by inspection against estate +exemplars, with one worked example (JTV grammar v2) stubbed pending repository access. + +=== Status + +* Correspondence-model spec: *merged* (canonical design). +* Standards / repo hygiene: *merged*. +* Now: identity re-point + abstraction-model pivot (Concept/Form/Transition + + CorrespondenceKind in the engine). +* Next: browser multi-pane GUI; AffineScript host port; cartridge contract + a second + language pack; proofs/benches + PanLL octad emission. + +See link:ROADMAP.adoc[ROADMAP.adoc] for the sequenced plan, and +link:README.adoc[README.adoc] for the front-door summary. === Evidence [cols="2,3", options="header"] |=== -| Path | Proves +| Path | Role + +| `docs/theory/CORRESPONDENCE-MODEL.adoc` +| Canonical design spec — Concept/Form/Transition, six CorrespondenceKinds, strata, Dyadic+Echo carrier | `src/Patterns.res` -| Multi-target pattern library — ReScript (legacy) and AffineScript (flagship) transformations, plus slots for future targets +| Correspondence / pattern catalogue (target source for cartridge facts) | `src/Analyser.res` / `src/Analyser.resi` -| Pattern analysis engine with public interface — takes JS, returns matches (target-aware) +| Classification + aggregation engine with public interface (per-stratum, kind-aware) | `src/Narrative.res` -| "You were close!" encouragement narratives, per target — the shame-free philosophy in code +| Shame-free narratives keyed by CorrespondenceKind (transfer / flag / remap / bridge / teach / re-route) | `src/Glyphs.res` -| Makaton-inspired glyph system — visual concept representation (target-agnostic) +| Makaton-inspired glyph view-layer — accessible, low-cognitive-load symbol mode | `src/Scanner.res` / `src/Scanner.resi` -| File/project scanner with public interface — batch analysis entry point +| File/project scanner with public interface — offline analysis entry point | `src/Output.res` -| Three output formats (plain, markdown, html) and three view layers (RAW, FOLDED, GLYPHED), per target +| Overlay view-layers (focus / glyph / blockly / raw / side-by-side) | `src/Cli.res` -| CLI entry point: `scan`, `patterns`, `legend`, `stats` with `--target` selection +| CLI entry point (offline fallback): `scan`, `patterns`, `legend`, `stats` |=== diff --git a/README.adoc b/README.adoc index 8115637..83778e4 100644 --- a/README.adoc +++ b/README.adoc @@ -6,44 +6,113 @@ image:https://img.shields.io/badge/License-PMPL--1.0--or--later-blue.svg[License // SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell image:[TPCF: Perimeter 3,link=docs/TPCF.md] -image:[AffineScript First] +image:[Learn — to love it!] image:https://img.shields.io/badge/Deno-Runtime-000000.svg[Deno Runtime] -> *Celebrate good, minimize bad, show better* -- A pattern detection engine, CLI, and educational toolkit that teaches JavaScript developers next-generation type-safe languages through progressive code transformation, without shame. +> *Learn — to love it!* -- Duolingo / Rosetta Stone for programming languages. A language-comprehension and transfer engine that *classifies* cross-language correspondences so what you learned in one language carries to the next — without shame. -NOTE: This project is the successor to *ReScript Evangeliser*. The ReScript catalogue is preserved as a legacy target while we pivot the flagship to *AffineScript*. See link:ROADMAP.adoc[ROADMAP.adoc] for migration phases. +NOTE: The canonical design is link:docs/theory/CORRESPONDENCE-MODEL.adoc[docs/theory/CORRESPONDENCE-MODEL.adoc]. This README mirrors it. The repo began as *ReScript Evangeliser*; ReScript is now a legacy host (being migrated) and a legacy target. See link:ROADMAP.adoc[ROADMAP.adoc] for the re-point. == What is This? -Nextgen Languages Evangeliser is a library and toolkit that helps JavaScript developers learn affine/linear-typed and other next-generation languages by: +Nextgen Languages Evangeliser is *Duolingo / Rosetta Stone for programming languages* — a language-*comprehension and transfer* engine. It works *one layer above text editing*, on *syntactic and semantic intention*, so the effort you spent learning language A *transfers* when you move to B (JS → TypeScript, Ruby, Prolog, C, or exotic targets like QPL, Arrow, JTV). -* *Detecting patterns* in existing JS code amenable to transformation -* *Showing transformations* to equivalent code in each supported target -* *Explaining with encouragement* using the "You were close!" philosophy -* *Visualizing concepts* with Makaton-inspired glyphs -* *Progressive disclosure* through 3 view layers (RAW -> FOLDED -> GLYPHED) and 3 output formats (plain, markdown, html) +*Transfer learning across languages is the product.* The engine *computes and classifies* cross-language correspondences and surfaces what carries cleanly, what is a trap, and what has no analog at all. -*We never shame developers.* Your JavaScript is good! Next-generation type systems just make some things even safer. +*We never shame developers.* Your JavaScript is good — the engine tells you which of your existing intuitions transfer, and warns you before one bites. -=== Supported targets +=== What it is NOT -[cols="2,2,3"] +* *Not "the next best IDE."* It does not compete on contrast, project widgets, pop-up notepads, shortcuts, or attention/memory/workflow ergonomics. That is *PanLL* (PanLL + eNSAID = the _contact_ between human, tool, task, and environment). This engine *feeds* PanLL; it is not PanLL. +* *Not a linter.* It is not about colouring scopes or spotting a missing `;` / extra `)`. The differentiator is an engine that *computes and classifies* cross-language equivalence, not one that looks it up. +* *Not a universal translator.* A verified any-language→any-language compiler with full Curry–Howard fidelity would be nice; it is *not the goal*. +* *Not a shame-the-JavaScript pattern matcher.* + +== The Model: Concept / Form / Transition + +[cols="1,3"] +|=== +| *Concept* | The invariant / equivalence-class — the recurring _trope_ ("bind a name to a value", "iterate a collection", "fail recoverably"). +| *Form* | A representative of a Concept _in one language_ (`let` in ReScript, `=` in Erlang, `def` in Python). A Concept has many Forms. +| *Transition* | A directed correspondence Form(A) → Form(B): the Echo-refined map plus its *residue* — what is lost, added, or inverted in crossing. |=== -|*Target* |*Status* |*Pitch* -|*AffineScript* |Flagship |Affine/linear types, borrow checking, quantity type theory; emits typed-wasm (separate repo) -> WebAssembly -|*ReScript* |Legacy (maintained) |Sound inference, Option/Result, pattern matching, JS interop -|*Rust, Gleam, Zig, …* |Planned |Roadmap — see link:ROADMAP.adoc[ROADMAP.adoc] +A *lesson* is a Concept shown through the learner's known Form, the target Form, and the Transition between — narrated without shame: "you already know this; here's the catch". + +=== The six CorrespondenceKinds + +Classification is not a boolean "relates"; it is a *graded* `CorrespondenceKind`, realised as grades of the Echo fibre. Each maps to a pedagogy: + +[cols="2,3,2"] |=== +| Kind | Signature | Pedagogy + +| *Cognate / true friend* | Intention + behaviour coincide; residue ≈ ∅. _e.g._ `def` → `define`. | *Transfer directly.* +| *False friend / homonym* | Surface matches, semantics diverge. _e.g._ BASIC `=` (assignment) vs. Erlang `=` (single-assignment bind/unify). | *Flag the trap.* +| *Antonym / inverted* | Related but opposite. _e.g._ 0- vs. 1-indexing; truthiness; stack-growth direction. | *Remap the intuition.* +| *Alien realization* | Same intention, foreign mechanism, large residue. _e.g._ subtraction in JTV (reversible/add-only) is `add` run backwards. | *Bridge with effort.* +| *Novel / no anchor* | Forward fibre empty. _e.g._ static types coming from assembly + JS; ownership/borrowing; Prolog `cut`. | *Teach de novo.* +| *Vanished* | Backward fibre empty. _e.g._ `return` in ReScript; `null` in a null-free language. | *Un-learn / re-route.* +|=== + +Classification runs *per stratum* — surface → structure → semantic intention → abstraction/trope → cross-language invariant. A correspondence can hold at one stratum and break at another, and that divergence is itself the most valuable signal (it _is_ the false-friend signature). + +=== The formal carrier (honest) + +* *Carrier = Dyadic `Relation`* (`proven-tests-and-benches` `Dyadic.idr`): `{ relates; reflexive; symmetric; transitive }`. Equivalence = refl ∧ sym ∧ trans. +* *Crossings are lossy-with-residue = Echo fibre* (`hyperpolymath/echo-types`, Agda): `Echo f y := Σ (x : A), f x ≡ y`. The residue is precisely what is lost or added going A→B. +* *`invariant-path`* is the governance front-end: it anchors each equivalence _claim_ to two code locations plus a witness, human-in-the-loop. -For those on TypeScript or CoffeeScript: we want to help you reach type-safety guarantees the incumbent tooling cannot give you — without making you throw your existing code away. For the adventurous who want to explore AffineScript's affine/linear guarantees from scratch, this repo is aimed at you. +NOTE: "Knot theory" is an aspirational lens for intuition, not a literal computation. "Invariant" here means a _preserved quantity that certifies "same idea"_ — no knot-invariant is computed, and we do not claim Curry–Howard fidelity. + +== Engine vs. Cartridge + +[cols="1,3"] +|=== +| *We build* | the general engine + the interface + the classification vocabulary (`CorrespondenceKind`) + the residue/fibre model + a reference language pack. +| *The community builds* | the *per-language modules as cartridges* (estate `standards/cartridges/`) — which Forms instantiate which Concepts, and for each Transition the kind + residue + an optional witness. +|=== + +The engine is *language-agnostic*. The nextgen-language collection is merely the substrate we dogfood. + +== Interface: levels of objects, not chrome + +The "levels of objects" are rendered as *overlay view-layers* — switchable, non-destructive, each conforming to the estate *overlay-protocol* (additive, idempotent, Idris2-ABI proved): + +* *focus* — show only what's needed now +* *glyph* — Makaton-style symbols (accessible, low cognitive load) +* *blockly / flowchart* — structure as blocks +* *raw code* — the text itself +* *side-by-side* — multi-language diff with step-sync + +The primary surface is a *browser multi-pane workspace*; a CLI/TUI is the offline fallback. Accessibility is first-class: *Hyperpolymath Accessibility Standard, Level A minimum → AA* (keyboard-only, ≥4.5:1 contrast, colourblind-safe palettes, ARIA/screen-reader, reduced-motion, plain-language mode). + +== Downstream: feeding PanLL + +The engine *emits*; it does not own the IDE. Analyses become `octads` written to VeriSimDB (`:8097`) plus `Groove` signals; PanLL panels subscribe and re-render. Ergonomics are read from `.machine_readable/ENSAID_CONFIG.a2ml`. View-layers conform to the overlay-protocol. + +== Worked examples + +[cols="2,2,3"] +|=== +| Example | Kind | Note + +| `def` → `define` | cognate | "just a rename" — a hypothesis to verify, not assume +| BASIC `=` vs. Erlang `=` | false friend / homonym | surface-corresponds ∧ semantics-diverge +| 0- vs. 1-indexing | antonym | residue = the flip +| JTV reversible/add-only (subtraction = reversed add) | alien realization | JTV is a security-focused, reversible, total, effect/info-flow/capability-typed language +| static types (coming from assembly + JS) | novel / no anchor | nothing to transfer _from_ +| `return` in ReScript | vanished | a concept the learner relied on is gone +|=== == Quick Start === Prerequisites * https://deno.land[Deno] (latest stable) -* https://rescript-lang.org[ReScript] 12.2+ (current host language; see link:ROADMAP.adoc[ROADMAP.adoc] for AffineScript port) +* https://rescript-lang.org[ReScript] 12.2+ (current/legacy host; the host is being ported to AffineScript — see link:ROADMAP.adoc[ROADMAP.adoc]) + +NOTE: AffineScript / Idris2 / Zig may be absent in some environments. Material is authored now and verified in CI — we do not claim local green builds we cannot run. === Installation @@ -64,16 +133,16 @@ just build [source,bash] ---- -# Scan a JavaScript file for patterns -deno run --allow-read bin/evangeliser.js scan +# Scan a source file (offline CLI fallback) +deno run --allow-read bin/evangeliser.js scan -# List all available patterns (with their target languages) +# List available correspondences / patterns deno run --allow-read bin/evangeliser.js patterns # Show the glyph legend deno run --allow-read bin/evangeliser.js legend -# Display detection statistics +# Display statistics deno run --allow-read bin/evangeliser.js stats ---- @@ -81,77 +150,31 @@ deno run --allow-read bin/evangeliser.js stats [source,bash] ---- -# Run tests -just test - -# Watch mode for development -just watch - -# Format code -just fmt - -# Full CI simulation -just ci +just test # Run tests +just watch # Watch mode +just fmt # Format code +just ci # Full CI simulation ---- -== Features - -=== Multi-target Pattern Catalogue - -Each pattern carries example transformations for multiple target languages. Categories include: - -* Null safety -> Option types (ReScript) / total functions (AffineScript) -* Resource management -> affine ownership (AffineScript) / explicit disposal -* Aliasing of mutable state -> borrow checking (AffineScript) -* Async/await -> Promise types / effect systems -* Try/catch -> Result types / typed error channels -* Array operations -> pipe operator / iterator patterns -* Conditionals -> pattern matching / total case analysis -* OOP -> functional programming / records over classes -* ...and more - -The AffineScript catalogue prioritises affine/linear-safety patterns: use-after-free analogs, double-cleanup, detached references, accidental aliasing of owned state, missing `using`/disposal, and similar concerns that the type system can make unrepresentable. - -=== Three View Layers - -1. *RAW*: Side-by-side JavaScript/target comparison with narrative -2. *FOLDED*: Organized sections with collapsible regions -3. *GLYPHED*: Symbol-annotated code showing semantic meaning - -=== Three Output Formats - -* *Plain text*: Terminal-friendly output -* *Markdown*: For documentation and READMEs -* *HTML*: For web integration and reports - -=== Makaton-Inspired Glyphs - -Visual symbols that transcend syntax across 21 glyph categories: +== Targets -* Shield (null safety) -* Transform (data transformation) -* Flow (pipe operator) -* Branch (pattern matching) -* Crystal (immutability) -* Seal (affine ownership) -* ...and more +The engine is language-agnostic; targets are the languages a learner moves *to*. AffineScript is a first-class teaching target and the future host, but the frame is no longer "evangelise AffineScript specifically" — it is "teach _any_ language by transfer, with AffineScript among the first-class targets." -=== Scanner + Analyser Detection Engine - -Regex-based pattern matching engine that scans JavaScript source files and identifies patterns amenable to transformation. The Analyser aggregates Scanner results into categorised reports with narrative explanations per-target. - -=== CLI Interface +[cols="2,2,3"] +|=== +|*Target* |*Status* |*Why interesting for transfer* -Four commands: `scan`, `patterns`, `legend`, `stats`. Supports RAW/FOLDED/GLYPHED view layers, plain/markdown/html output formats, and `--target` selection. +|*AffineScript* |First-class; future host |Affine/linear use-once, borrow checking, QTT — dense with _novel/no-anchor_ correspondences; emits typed-wasm → WebAssembly +|*ReScript* |Legacy target + legacy host |Sound inference, Option/Result, pattern matching; source of the _vanished_ `return` example +|*TypeScript, Ruby, Prolog, C, JTV, …* |Reference / planned |Cartridge-authored; JTV is the canonical _alien-realization_ + _novel_ worked example +|=== == Technology Stack -=== Primary Technologies - -* *ReScript 12.2* (current host): All application logic (Types, Glyphs, Narrative, Patterns, Scanner, Analyser, Output, CLI) -* *AffineScript* (planned host, Phase 3+): OCaml 5.1+ toolchain; emits typed-wasm IR (separate repo) -> WebAssembly -* *Deno*: Runtime and package management -* *Zig*: FFI layer (canonical per manifest) +* *ReScript 12.2* — current/legacy host (being migrated; banned in _new_ code per estate policy: `.res` → `.affine`) +* *AffineScript* — future host (Zig FFI + Idris2 ABI seams); OCaml 5.1+ toolchain; emits typed-wasm IR → WebAssembly +* *Deno* — runtime and package management +* *Zig* — FFI layer (canonical per manifest); *Idris2* — ABI / proofs === Language Policy @@ -161,34 +184,33 @@ Per Hyperpolymath Standard: |=== |*Allowed* |*Banned* -|AffineScript, ReScript |TypeScript +|AffineScript (future host), ReScript (legacy) |TypeScript |Deno |Node.js/npm/bun |justfile |Makefile -|Zig (FFI) |V (outside V ecosystem) +|Zig (FFI), Idris2 (ABI/proofs) |V (outside V ecosystem) |=== -See link:CLAUDE.md[CLAUDE.md] and link:.claude/CLAUDE.md[.claude/CLAUDE.md] for the full policy. +ReScript is banned in _new_ code; existing `.res` migrates to `.affine`. See link:CLAUDE.md[CLAUDE.md] and link:.claude/CLAUDE.md[.claude/CLAUDE.md] for the full policy. == Project Structure [source] ---- nextgen-languages-evangeliser/ -+-- src/ # Host source (ReScript today, AffineScript post-Phase 3) -| +-- Types.res # Core type model (multi-target) -| +-- Glyphs.res # Makaton-inspired symbol system -| +-- Narrative.res # Encouraging message generation (target-aware) -| +-- Patterns.res # Multi-target transformation patterns -| +-- Scanner.res # Pattern detection engine -| +-- Scanner.resi # Scanner interface -| +-- Analyser.res # Result aggregation and reporting -| +-- Analyser.resi # Analyser interface -| +-- Output.res # RAW/FOLDED/GLYPHED formatting (multi-target) -| +-- Cli.res # CLI entry point (scan/patterns/legend/stats) ++-- src/ # Host source (ReScript today; AffineScript target) +| +-- Types.res # Core type model +| +-- Glyphs.res # Makaton-inspired glyph view-layer +| +-- Narrative.res # Shame-free narrative (per CorrespondenceKind) +| +-- Patterns.res # Correspondence / pattern catalogue +| +-- Scanner.res(i) # Detection engine + interface +| +-- Analyser.res(i) # Classification + aggregation + interface +| +-- Output.res # focus/glyph/blockly/raw/side-by-side view-layers +| +-- Cli.res # CLI entry point (offline fallback) ++-- gui/ # Browser multi-pane workspace (primary surface) +-- test/ # Test suites -+-- bin/ -| +-- evangeliser.js # CLI entry point ++-- bin/evangeliser.js # Deno CLI shim +-- docs/ # Documentation +| +-- theory/CORRESPONDENCE-MODEL.adoc # Canonical design spec +-- rescript.json # Host (ReScript) configuration +-- deno.json # Deno configuration +-- Justfile # Task orchestration @@ -197,44 +219,28 @@ nextgen-languages-evangeliser/ +-- CLAUDE.md # AI context ---- -== Philosophy: "Celebrate Good, Minimize Bad, Show Better" - -We *never* shame developers. Instead: +== Philosophy: no shame, transfer-first -1. *Celebrate*: Recognize what their JavaScript does well -2. *Minimize*: Gently acknowledge minor limitations -3. *Better*: Show how the target language enhances the pattern -4. *Safety*: Explain type-level (and affine/linear) guarantees -5. *Example*: Provide concrete, encouraging examples - -Example narrative (ReScript target): - -____ -*You were close!* You're already thinking about null and undefined - that's great defensive programming! - -The only small thing is that it's easy to forget one of these checks somewhere... - -*Even better:* ReScript's Option type makes null safety automatic - you literally can't forget a check! -____ +We *never* shame developers. The six kinds map to: transfer cognates, warn on false friends, remap antonyms, bridge the alien, teach the novel, re-route the vanished. The narrative voice stays *celebrate / minimise / better / safety / example*. -Example narrative (AffineScript target): +Example narrative (a _false friend_): ____ -*You were close!* You're already disposing of the resource in a `finally` block - that's careful code! +*You already know this!* You've used `=` for assignment for years — that intuition is real. -The only small thing is that if another closure still holds a reference, the dispose runs but the alias lives on... +*Here's the catch:* in Erlang `=` doesn't assign, it binds-once and unifies. Re-`=` with a different value _fails_ a match rather than overwriting. -*Even better:* AffineScript's affine types make the resource vanish from the type environment at disposal - no alias can survive, no double-free can compile. +*Re-route:* read `X = 5` as "assert X equals 5 (binding it if unbound)", not "store 5 in X". ____ == RSR Compliance This project follows the *Rhodium Standard Repository (RSR)* framework: -* *Type Safety*: ReScript 12.2 host today; AffineScript (affine/linear types, borrow checking) post-Phase 3 -* *Offline First*: Zero network dependencies -* *Complete Documentation*: See link:docs/[docs/] -* *Security First*: See link:SECURITY.md[SECURITY.md] +* *Type Safety*: ReScript 12.2 host today; AffineScript (affine/linear types, borrow checking) as the host target. Correspondence carrier is Idris2/Agda-grounded (Dyadic + Echo). +* *Offline First*: CLI/TUI fallback; zero network dependency to scan +* *Complete Documentation*: see link:docs/[docs/] and link:docs/theory/CORRESPONDENCE-MODEL.adoc[the design spec] +* *Security First*: see link:SECURITY.md[SECURITY.md] * *Open Governance*: TPCF Perimeter 3 (Community Sandbox) * *Licensed*: MPL-2.0 * *Build Reproducibility*: Deno + Justfile @@ -243,13 +249,14 @@ See link:docs/RSR_COMPLIANCE.md[RSR_COMPLIANCE.md] for full details. == Documentation -* link:CONTRIBUTING.md[CONTRIBUTING.md] - How to contribute +* link:docs/theory/CORRESPONDENCE-MODEL.adoc[CORRESPONDENCE-MODEL.adoc] - Canonical design spec +* link:CONTRIBUTING.md[CONTRIBUTING.md] - How to contribute (incl. cartridge authoring) * link:CODE_OF_CONDUCT.md[CODE_OF_CONDUCT.md] - Community guidelines * link:SECURITY.md[SECURITY.md] - Security policies * link:CHANGELOG.md[CHANGELOG.md] - Version history * link:docs/RSR_COMPLIANCE.md[RSR_COMPLIANCE.md] - RSR framework compliance * link:docs/TPCF.md[TPCF.md] - Contribution framework -* link:ROADMAP.adoc[ROADMAP.adoc] - Migration phases & future targets +* link:ROADMAP.adoc[ROADMAP.adoc] - Re-point sequence & milestones == Contributing @@ -257,7 +264,7 @@ We welcome contributions! See link:CONTRIBUTING.md[CONTRIBUTING.md] for: * Code of Conduct * Development setup -* Pattern authoring guide (multi-target) +* Cartridge authoring guide (per-language correspondence modules) * Testing requirements * Pull request process @@ -273,12 +280,13 @@ See link:LICENSE[LICENSE] for the full license text. == Roadmap -* [x] Phase 0: Decide migration path (option A content rewrite, multilanguage future) -* [-] Phase 1: Rebrand + generalise engine for multi-target (host stays ReScript) -* [ ] Phase 2: Pattern catalogue pivot — affine/linear-safety-focused AffineScript patterns -* [ ] Phase 3: Host language port (ReScript -> AffineScript), gated on toolchain WASM maturity -* [ ] Phase 4: Policy perimeter flip (ts-blocker extended, affinescript linter added) -* [ ] Phase 5: Zig/V policy formalisation; additional targets (Rust, Gleam) +* [x] Correspondence-model spec merged (Concept/Form/Transition + six CorrespondenceKinds) +* [x] Standards / repo hygiene merged +* [-] Identity re-point + abstraction-model pivot (classify, not translate) +* [ ] Browser multi-pane GUI (overlay view-layers) +* [ ] AffineScript host port (Zig FFI + Idris2 ABI) +* [ ] Cartridge contract + 2nd language pack +* [ ] Proofs/benches + PanLL octad emission See link:ROADMAP.adoc[ROADMAP.adoc] for detailed milestones. @@ -289,11 +297,11 @@ If you use this project in academic research, please cite: [source,bibtex] ---- @software{nextgen_languages_evangeliser_2026, - title = {Nextgen Languages Evangeliser: Progressive Code Transformation for Affine/Linear-Typed Languages}, + title = {Nextgen Languages Evangeliser: Cross-Language Correspondence Classification for Transfer Learning}, author = {Jonathan D.A. Jewell}, year = {2026}, url = {https://github.com/hyperpolymath/nextgen-languages-evangeliser}, - note = {Successor to rescript-evangeliser; RSR Bronze-compliant, TPCF Perimeter 3} + note = {Duolingo/Rosetta Stone for programming languages; successor to rescript-evangeliser; RSR Bronze-compliant, TPCF Perimeter 3} } ---- @@ -305,24 +313,22 @@ If you use this project in academic research, please cite: == Acknowledgments -* *AffineScript Team*: For the flagship target — affine/linear types, borrow checker, QTT -* *ReScript Team*: For seeding this evangeliser's original catalogue and philosophy -* *Makaton*: Inspiration for the glyph system -* *Deno Team*: For the excellent runtime -* *Contributors*: See link:.well-known/humans.txt[humans.txt] +* *Dyadic / Echo*: `proven-tests-and-benches` and `hyperpolymath/echo-types` for the formal carrier (relation + loss-with-residue) +* *PanLL / eNSAID*: the downstream contact layer this engine feeds +* *Makaton*: inspiration for the glyph view-layer +* *Deno Team*: for the excellent runtime +* *Contributors*: see link:.well-known/humans.txt[humans.txt] == Status -* *Version*: 0.6.0-alpha (migrating from rescript-evangeliser 0.5.x) +* *Version*: 0.6.0-alpha (re-pointed from rescript-evangeliser 0.5.x) * *RSR Level*: Bronze -* *Targets*: 2 active (AffineScript flagship, ReScript legacy), more planned -* *Tests*: 38 across 6 suites (being updated for multi-target) -* *CI Workflows*: 16, all passing -* *Build Status*: Passing -* *Last Updated*: 2026-04-16 +* *Design*: correspondence-model spec merged; hygiene merged; abstraction-model pivot next +* *Toolchain*: AffineScript/Idris2/Zig deferred — authored now, verified in CI +* *Last Updated*: 2026-06-18 --- -Made with care for JavaScript developers curious about next-generation languages. +Made with care for developers learning a new language. -*Remember*: You were close! +*Remember*: Learn — to love it! diff --git a/ROADMAP.adoc b/ROADMAP.adoc index 8522978..d290e82 100644 --- a/ROADMAP.adoc +++ b/ROADMAP.adoc @@ -3,60 +3,83 @@ == Current Status -Migration from *ReScript Evangeliser* to *Nextgen Languages Evangeliser* — Phase 1 in progress. - -See link:CLAUDE.md[CLAUDE.md] and link:README.adoc[README.adoc] for project overview. - -== Migration Phases - -=== Phase 0 — Decide -* [x] Pick pivot strategy: Option A (content rewrite, not mechanical translation) -* [x] Commit to multilanguage future (flagship AffineScript, legacy ReScript, more to follow) -* [x] Rename repo: `rescript-evangeliser` -> `nextgen-languages-evangeliser` -* [x] Verify AffineScript toolchain buildable today (OCaml 5.1+, Dune 3.14+) -* [x] Note: typed-wasm is a separate repo (downstream of AffineScript) - -=== Phase 1 — Rebrand + generalise engine -* [-] Rebrand docs, metadata, contractiles, config files -* [ ] Generalise `src/Types.res` for multi-target pattern representation -* [ ] Thread multi-target through Narrative / Output / Analyser / CLI -* [ ] Convert `src/Patterns.res` to multi-target shape (ReScript + AffineScript stub) -* [ ] Update tests -* [ ] Host language stays ReScript throughout - -=== Phase 2 — Pattern catalogue pivot -* [ ] Design AffineScript-first catalogue around affine/linear safety concerns: - ** Use-after-free analogs (stale closures, detached refs) - ** Double-cleanup / double-free analogs - ** Accidental aliasing of owned state - ** Missing `using`/disposal, leaky listeners/timers - ** Resource sharing across async boundaries -* [ ] Target ~12 curated patterns initially (depth over breadth) -* [ ] Demote ReScript catalogue to legacy support -* [ ] Preserve "You were close!" narrative voice - -=== Phase 3 — Host language port (gated on toolchain) -* [ ] End-to-end "hello world -> typed-wasm -> WASM" proof-of-life -* [ ] Port `src/` ReScript -> AffineScript module-by-module: - Types, Glyphs, Narrative, Scanner, Analyser, Output, Cli, Patterns (last) +*Identity re-point in progress.* The project is now *Duolingo / Rosetta Stone for +programming languages* — a language-comprehension and transfer engine that *classifies* +cross-language correspondences (it does not translate, lint, or build IDEs). The +correspondence-model spec and standards hygiene have landed; the abstraction-model pivot +is next. + +See link:docs/theory/CORRESPONDENCE-MODEL.adoc[CORRESPONDENCE-MODEL.adoc] (canonical +design), link:CLAUDE.md[CLAUDE.md], and link:README.adoc[README.adoc] for overview. + +== Milestones + +=== M0 — Correspondence-model spec ✅ +* [x] Establish the engine identity: *classify, not translate* (and not an IDE, not a linter) +* [x] Concept / Form / Transition object model +* [x] Six `CorrespondenceKind`s (cognate / false-friend / antonym / alien-realization / novel / vanished) as graded Echo fibres +* [x] Strata ("levels of objects": surface → structure → intention → trope → invariant) +* [x] Formal carrier: Dyadic `Relation` + Echo loss-with-residue; `invariant-path` as governance front-end +* [x] Honesty caveat recorded: "knot theory" is an aspirational lens, not a computation + +=== M1 — Standards / repo hygiene ✅ +* [x] Repo renamed `rescript-evangeliser` → `nextgen-languages-evangeliser` +* [x] Estate machine-readable artefacts + SPDX present +* [x] Language-policy perimeter aligned (Deno, Justfile, Zig FFI; TS/Python/Go/V banned; ReScript legacy) + +=== M2 — Identity re-point + abstraction-model pivot → +* [-] Re-point identity documentation to the corrected purpose (this pass) +* [ ] Implement Concept / Form / Transition in `src/Types.res` (engine model, not pattern-list) +* [ ] Implement `CorrespondenceKind` + per-stratum classification in Analyser +* [ ] Thread kind-aware, shame-free narratives through `src/Narrative.res` +* [ ] Reframe `src/Patterns.res` as a *reference language pack* (Forms + Transitions, not "JS→AffineScript patterns") +* [ ] Update tests for the classify-not-translate model + +=== M3 — Browser multi-pane GUI → +* [ ] Browser multi-pane workspace as the primary surface +* [ ] Overlay view-layers: focus / glyph / blockly-flowchart / raw-code / side-by-side +* [ ] View-layers conform to the estate overlay-protocol (additive, idempotent) +* [ ] Accessibility: Hyperpolymath Accessibility Standard Level A → AA (keyboard-only, ≥4.5:1 contrast, ARIA, reduced-motion, plain-language mode) +* [ ] CLI/TUI retained as the offline fallback + +=== M4 — AffineScript host port (Zig FFI + Idris2 ABI) → +* [ ] End-to-end "hello world → typed-wasm → WASM" proof-of-life +* [ ] Port `src/` ReScript → AffineScript (`.res` → `.affine`), module-by-module +* [ ] Zig FFI seam + Idris2 ABI seam for the certifiable carrier * [ ] Port `test/` in lockstep +* [ ] Note: ReScript banned in _new_ code; AffineScript remains a first-class teaching target and the future host + +=== M5 — Cartridge contract + 2nd language pack → +* [ ] Specify the cartridge fact format (concept / from / to / kind / strata / residue / witness) +* [ ] Wire `standards/cartridges/` as the community authoring surface +* [ ] Ship the reference language pack as the worked exemplar +* [ ] Author a second language pack to validate the engine is language-agnostic (JTV is the canonical alien-realization / novel exemplar) + +=== M6 — Proofs/benches + PanLL octad emission → +* [ ] Carry Idris2/Echo witnesses where the math pays (high-value / dangerous Transitions) +* [ ] Benches via `proven-tests-and-benches` +* [ ] Emit `octads` → VeriSimDB (`:8097`) + `Groove` signals; PanLL panels subscribe +* [ ] Read ergonomics from `.machine_readable/ENSAID_CONFIG.a2ml` + +== Division of labour + +* *We build* — the general engine + interface + classification vocabulary + residue model + a reference language pack. +* *The community builds* — the per-language modules as *cartridges* (`standards/cartridges/`). + +The engine is language-agnostic; the nextgen-language collection is merely the substrate we dogfood. -=== Phase 4 — Policy perimeter flip -* [ ] Extend `ts-blocker.yml` to also reject new `.res` files outside `legacy/` -* [ ] Add `affinescript-linter.yml` workflow -* [ ] `justfile` recipe names stable, invocations swapped -* [ ] Retire `rescript.json` (or demote to legacy) +== Toolchain honesty -=== Phase 5 — Policy text + additional targets -* [ ] `.claude/CLAUDE.md`: formalise V-in-ecosystem-only carveout -* [ ] Zig as canonical FFI (no code change — already true per manifest) -* [ ] Additional target backends: Rust, Gleam, Zig +AffineScript / Idris2 / Zig / Deno may be absent in some environments. Material is +*authored now and verified in CI* — we do not claim local green builds we cannot run. The +JTV grammar-v2 worked example remains stubbed pending repository access. == Future Directions -After Phase 5, the project becomes a general-purpose evangelisation platform for nextgen typed languages, with: +Beyond M6, the project is a general transfer-learning platform across programming +languages: -* A shared engine (Scanner, Analyser, Output, Narrative) target-agnostic -* Per-target catalogues authored by language advocates -* Glyph system treated as a lingua franca across targets -* Citation-stable URL via GitHub redirect from legacy `rescript-evangeliser` slug +* A shared, language-agnostic engine (scan → classify → narrate → emit) feeding PanLL +* Per-language correspondence cartridges authored by language advocates +* The glyph view-layer as an accessible lingua franca across targets +* Citation-stable URL via GitHub redirect from the legacy `rescript-evangeliser` slug