diff --git a/.machine_readable/6a2/STATE.a2ml b/.machine_readable/6a2/STATE.a2ml index 018b1f70..f52ebf21 100644 --- a/.machine_readable/6a2/STATE.a2ml +++ b/.machine_readable/6a2/STATE.a2ml @@ -4,10 +4,11 @@ [metadata] project = "affinescript" version = "0.1.1" -last-updated = "2026-06-02" +last-updated = "2026-06-21" status = "active" authoritative-status-doc = "docs/CAPABILITY-MATRIX.adoc" drift-flag = "STALE as of 2026-05-23 PM: this file's [components]/[features]/[project-context] still predate landed PRs since 2026-05-19. It MIRRORS, it does not LEAD. Authoritative sources by topic — readiness: docs/CAPABILITY-MATRIX.adoc; spine + AS↔typed-wasm contract: docs/ECOSYSTEM.adoc; coordination ledger / critical path: docs/TECH-DEBT.adoc; test taxonomy + PR-level gates: docs/standards/TESTING.adoc (added 2026-05-23); panic-attack SOP: docs/standards/PANIC-ATTACK.adoc (added 2026-05-23). Gate baseline: CAPABILITY-MATRIX records 260/260 at 2026-05-19 reconstruction; subsequent borrow-checker work has lifted it (#240 → 263, return-escape → 271/274, &mut surface → 278/281). The exact live number for any given commit comes from `dune runtest --force` — do not hard-code it here. (DOC-05, issue #176.)" +session-note-2026-06-21 = "SESSION: release-binaries pipeline repair + downstream gap triage + onboarding polish. (1) RELEASE — PR #641 (merged b8ba479) fixed .github/workflows/release.yml, which had been shipping v0.2.0 SOURCE-ONLY (regression from v0.1.1). Two bugs, both confirmed from the failed v0.2.0 run 26694097435: (a) immutable releases now forbid adding assets to a PUBLISHED release (linux leg died HTTP 422), and (b) the v0.2.0-added version-bake step used GNU `sed -i` which BSD/macOS sed rejects (extra characters at the end of l command), so both mac legs failed before building. Fix: create the release as a DRAFT, upload all binaries + SHA256SUMS into it, then publish (--draft=false --latest) last so it seals atomically; portable `sed -i.bak`. Compiler verified to build in release mode locally; --version/check/eval/compile work. v0.2.0 is immutable+assetless and cannot be amended, so binaries ship via a fresh v0.2.1 tag — OWNER action: a Claude-Code-web session cannot push v* tags (HTTP 403). Tracked in #646 (incl. downstream quandledb re-pin). (2) WASM cross-module constructor-link task was ALREADY LANDED before this session: #602 / ac98c81 (Closes #138) — register_imported_types in Codegen.gen_imports registers imported public enum constructors into variant_tags via the local gen_decl path; core-Wasm regression test in test_stdlib_aot.ml; verified locally 534/534. Downstream stapeln re-pins to ac98c81 and drops its carried git apply. (3) svalinn-gateway compiler gaps confirmed + filed: #642 (compile has no module search-path / project mode for nested src/**), #643 (float_to_string raises UnboundVariable at core-Wasm compile; wired only in resolve/typecheck/interp/Deno), #644 (empty match-arm body Pat => {} is a parse error). `pub extern fn` was checked and is SUPPORTED — not a gap. (4) ONBOARDING POLISH (this change): added tutorial lesson-01 (the docs/tutorial track previously started at lesson-02), an audience router (developers / maintainers / end-users) in README + NAVIGATION, and this note. Docs consolidation (two overlapping lesson tracks, wiki sync) tracked in #647. Note: guides/lessons/01-hello bare-println example is stale (parse error on current compiler) — folded into #647. This file MIRRORS; authoritative sources unchanged (see drift-flag)." session-note-2026-05-26-publish-104 = "ISSUE #104 CLOSED — FIRST NPM PUBLISH LANDED. @hyperpolymath/affine-vscode@0.1.0 is now on registry.npmjs.org. Owner-action sequence completed today: (1) npm org `hyperpolymath` created on free public-package tier; (2) Granular Access Token generated for scope @hyperpolymath/* with Read+Write, uploaded to repo secret NPM_TOKEN; (3) signed annotated tag affine-vscode-v0.1.0 pushed at origin/main (RSA key 9639451754496E51D6B537CAD119017EBF695AB1); (4) .github/workflows/affine-vscode-publish.yml ran green — `npm publish --access public` succeeded; (5) `npm view @hyperpolymath/affine-vscode` resolves. Downstream consumers (my-lang#66, standards#160) which un-vendored their adapters on 2026-05-21 now have a working `npm install` path; vscode-smoke workflow (skipped per #381 while package was unpublished) will start exercising the live package on its next PR run. Lineage for future @hyperpolymath/* publishes: org+token are reusable; mirror `affine-vscode-publish.yml`'s shape (tag trigger, version-match guard, .npmrc write from secret, npm publish --access public). NPM_TOKEN rotation advised post-publish (token value transited a session transcript during wire-up); see .machine_readable/6a2/PLAYBOOK.a2ml [npm-publish] for the runbook." session-note-2026-05-30 = "DOC-16 + DOC-17 — DOC-TRUTHING MONITOR FULLY MECHANICAL (issue #176). Two complementary in-repo guards now enforce the doc-truthing rules that were previously external-bot-only. DOC-16 (PR #476, tools/check-doc-truthing.sh): banner-PRESENCE invariant — fails if any over-claiming doc loses its CAPABILITY-MATRIX banner, if the matrix stops self-declaring primacy / loses its 'What AffineScript is NOT' section, or if STATE.a2ml drops its mirror keys; deliberately does NOT phrase-scan (a naive grep false-positives on the negating banners + future-roadmap text). DOC-17 (PR #475, tools/check-doc-overclaims.sh + tools/doc-overclaims.allow): the phrase-detection complement — a frozen-baseline RATCHET over README + docs/** (excluding CAPABILITY-MATRIX + TECH-DEBT, which quote the rule) that fails any NEW backend-breadth / 'production-ready' / stdlib-% occurrence beyond the 13-line baseline (all current entries legit: future-tense roadmap milestones + dated history snapshots + corrective banners); re-baseline via `--update` / `just doc-overclaims-bless`, diff = audit trail. Both wired into `just check` (guard recipe) + ci.yml build job, both toolchain-free bash (run without OCaml). #475 was originally a superset of #476 (built in parallel, same session); on discovering #476 had merged first, #475 was reworked to drop the duplicated banner check and keep only the unique ratchet, renamed check-doc-truth.sh→check-doc-overclaims.sh to avoid the name clash (DOC-DEDUP-clean). FOLLOW-UP (same day, post-#475-merge): the two near-identically-named guards were consolidated so neither lingers — the ratchet (incl. `--update` mode + tools/doc-overclaims.allow baseline) was folded INTO tools/check-doc-truthing.sh using #476's fail-accumulator/note() structure, and tools/check-doc-overclaims.sh was deleted. A SINGLE toolchain-free guard now enforces both presence invariants (DOC-04/05) and the over-claim ratchet (DOC-08/09) in one run; one CI step; the `guard` recipe runs it; re-baseline via `just doc-truth-bless`. DOC-17 folded into DOC-16 in the ledger. Gate-number policy unchanged (DOC-05): live `dune runtest --force` count never hard-coded. No compiler code touched. Refs #176 / #175." session-note-2026-05-31-partial-port-488 = "RES-TO-AFFINE PARTIAL-PORT MODE #488 SLICES 1-3 (successor to closed #57). New --partial flag, a DISTINCT model from --translate: renders module-top-level functions (let f = (params) => body) into AffineScript fn skeletons whose output DELIBERATELY does not type-check (un-annotated ReScript fns can't yield a compilable fn) but DOES parse — un-inferable types are `_` holes, un-translatable expr/pattern are () /* TODO */ / _ /* TODO */ islands. (1) Slice 1 (#494 / c157a0f): fn skeletons + switch->match (variant/tuple/literal patterns) + expression translation (literals / idents / calls / binary-ops with float-op +.->+ and identity-equality ===->== normalisation / ++ concat / member + module-qualified access / ternary). The binary operator is an anonymous tree-sitter token, sliced from source between the operands. (2) Slice 2 (#495 / 78906f9): pipe-first -> desugaring (a->f(b) -> f(a, b); chains are left-nested so x->f->g(2) -> g(f(x), 2) falls out of the recursion); if/else; blocks with let statements. (3) Slice 3 (#496 / 4d4d1d4): array literals ([a, b] -> [a, b]) + record literals ({x, y} -> Rec #{ x: x, y: y }; AffineScript records are NOMINAL so an anonymous record gets the placeholder type Rec for the human to rename; field punning {x} -> x: x). Walker-internal: translate_expr / translate_switch / translate_pipe / translate_if / translate_as_block / translate_block(_inner) / translate_block_let (mutually recursive) + translate_pattern + partial_function + collect_partial + Walker.translate_partial; emitter emit_partial; main --partial (precedence over --translate, walker-only). 32 res-to-affine walker tests. VERIFIED LOCALLY each slice (apt-bootstrapped toolchain): full dune build exit 0; dune runtest green; main.exe check on the generated skeletons reaches resolution/type-checking WITHOUT a parse error (the partial-port bar — type/resolution errors are expected). REMAINING #488: JS objects / interpolated template strings, labelled-arg refinement, combining --partial with --translate (declarations + functions in one pass), and module-qualified-reference RESOLUTION (a ReScript->AffineScript module-mapping POLICY decision, deliberately not built without owner scoping). #488 stays OPEN. Refs #488 / #57 (closed)." diff --git a/README.adoc b/README.adoc index 23ba43c5..7bd58811 100644 --- a/README.adoc +++ b/README.adoc @@ -61,6 +61,22 @@ Write software where the compiler helps enforce resource lifecycles, protocol st Honest status sync (2026-06-21): affine/QTT and borrow checking are wired into the standard CLI paths today (`check`, `compile`, `eval`) and gate user programs. Refinement/dependent-type surface was *removed* in v1 rather than left parse-only-and-unenforced (#558); effect-handler lowering on the compiled backends now *fails loud* rather than silently dropping arms (#555). See link:docs/CAPABILITY-MATRIX.adoc[docs/CAPABILITY-MATRIX.adoc] for authoritative per-feature status and link:docs/SOUNDNESS.adoc[docs/SOUNDNESS.adoc] for soundness-hole status (`.machine_readable/6a2/STATE.a2ml` mirrors the matrix; it does not lead). ==== +== Start here — by audience + +[cols="1,4"] +|=== +| You are a… | Start here + +| **New user / learning the language** +| link:docs/tutorial/lesson-01-hello.adoc[Tutorial (lessons 1–10)] · link:docs/guides/warmup/[runnable warm-ups] · link:wiki/language-reference/[language reference] + +| **Developer / compiler contributor** +| link:docs/NAVIGATION.adoc[Repository map] · link:wiki/compiler/architecture.md[compiler architecture] · link:docs/decisions/[ADRs] · link:docs/CAPABILITY-MATRIX.adoc[capability matrix] + +| **Maintainer / releaser** +| link:docs/governance/MAINTAINERS.adoc[Maintainers] · link:docs/governance/CONTRIBUTING.adoc[contributing] · link:.machine_readable/6a2/PLAYBOOK.a2ml[ops playbook] · link:docs/SOUNDNESS.adoc[soundness ledger] +|=== + == What AffineScript Is AffineScript is a practical programming language for building software where the hard problems are not just “does it parse?” or “does it type-check?”, but: diff --git a/docs/NAVIGATION.adoc b/docs/NAVIGATION.adoc index 69d99032..b8f96138 100644 --- a/docs/NAVIGATION.adoc +++ b/docs/NAVIGATION.adoc @@ -5,6 +5,12 @@ This guide helps you navigate the AffineScript repository structure. +== Start here — by audience + +* *New users* — link:tutorial/lesson-01-hello.adoc[tutorial (lessons 1–10)], link:guides/warmup/[runnable warm-ups], link:../wiki/language-reference/[language reference]. +* *Developers / contributors* — this guide, link:../wiki/compiler/architecture.md[compiler architecture], link:decisions/[ADRs], link:governance/CONTRIBUTING.adoc[contributing]. +* *Maintainers* — link:governance/MAINTAINERS.adoc[maintainers], link:standards/RELEASE.adoc[release process], link:../.machine_readable/6a2/PLAYBOOK.a2ml[ops playbook], link:SOUNDNESS.adoc[soundness ledger]. + == Quick Start Files (Root Level) [cols="1,3"] diff --git a/docs/tutorial/lesson-01-hello.adoc b/docs/tutorial/lesson-01-hello.adoc new file mode 100644 index 00000000..4ab09cb1 --- /dev/null +++ b/docs/tutorial/lesson-01-hello.adoc @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MPL-2.0 +// SPDX-FileCopyrightText: 2024-2026 hyperpolymath (Jonathan D.A. Jewell ) += Lesson 1: Hello, AffineScript + +The first stop in the tutorial series (lessons 1–10). For runnable, self-contained +snippets covering the same early ground, see the +link:../guides/warmup/[warm-up programs] (`*.affine` files you can `eval` directly). + +== Your first program + +[source,affinescript] +---- +fn main() -> Int { + println("Hello, AffineScript!"); + return 0; +} +---- + +A program is a set of declarations; `main` is the entry point. Functions use explicit +`return`, and statements end with `;`. + +== Running it + +AffineScript type-, effect-, and borrow-checks ahead of time, then compiles to +WebAssembly (it also has a tree-walking interpreter for quick runs): + +[source,sh] +---- +affinescript check hello.affine # static checks only (types, effects, borrows) +affinescript eval hello.affine # check, then run via the interpreter +affinescript compile hello.affine # check, then emit WebAssembly (-o out.wasm) +---- + +Install by building from source — `dune build bin/main.exe` (entry point +`_build/default/bin/main.exe`); prebuilt per-platform binaries are attached to tagged +link:https://github.com/hyperpolymath/affinescript/releases[releases]. + +== What you'll learn + +[cols="1,4"] +|=== +| Lesson | Topic + +| link:lesson-02-functions.adoc[2] | Functions and ownership (`own` / `ref` / `mut`) +| link:lesson-03-data.adoc[3] | Data: records, enums, tuples +| link:lesson-04-patterns.adoc[4] | Pattern matching +| link:lesson-05-types.adoc[5] | The type system +| link:lesson-06-errors.adoc[6] | Errors and `Result` +| link:lesson-07-effects.adoc[7] | Effects and handlers +| link:lesson-08-generics.adoc[8] | Generics +| link:lesson-09-modules.adoc[9] | Modules and imports +| link:lesson-10-building.adoc[10] | Building a complete program +|=== + +For the full language reference, see link:../../wiki/language-reference/[wiki/language-reference]; +for authoritative feature status, link:../CAPABILITY-MATRIX.adoc[docs/CAPABILITY-MATRIX.adoc]. + +Next: link:lesson-02-functions.adoc[Lesson 2 — Functions and Ownership].