Skip to content

Commit 81caf8e

Browse files
docs: onboarding polish — tutorial lesson-01 + audience router + STATE.a2ml refresh (#649)
The three quick wind-down items from the close-out triage. The larger docs consolidation (unifying the two learning tracks, wiki-sync audit) stays tracked in **#647**. ## 1. `docs/tutorial/lesson-01-hello.adoc` (new) The `docs/tutorial/` track started at **lesson-02** — the intro lived only under `docs/guides/`, so a reader opening the tutorial began at lesson 2. Adds a concise, self-contained first lesson with a lessons 1–10 map and the `check`/`eval`/`compile` workflow. The hello-world is **verified against the built compiler**: `fn main() -> Int { println(…); return 0; }` passes `check`, prints under `eval`, and `compile`s to WASM. (Note: the *bare* top-level `println(…)` form shown in `docs/guides/lessons/01-hello-affinescript.adoc` is a **parse error** on the current compiler — folded into #647 rather than fixed here.) ## 2. README + NAVIGATION — "Start here — by audience" A top-level router so each audience has a clear entry point: - **New users** → tutorial → runnable warm-ups → language reference - **Developers** → repository map → `wiki/compiler/architecture` → ADRs → capability matrix - **Maintainers** → `MAINTAINERS` → contributing → ops playbook → soundness ledger (Also adds a `SOUNDNESS.adoc` back-link in `NAVIGATION.adoc`.) ## 3. `.machine_readable/6a2/STATE.a2ml` Adds a `2026-06-21` session note (release fix #641, the already-landed #602 ctor fix, filed gaps #642#644/#646/#647) and bumps `last-updated`. It was self-flagged stale; it still **mirrors** the authoritative docs, it does not lead. ## Verification All three doc guards pass locally: `check-doc-truthing`, `check-soundness-ledger`, `check-capability-anchors`. No over-claim phrases introduced; no compiler/code changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Lz7pRcec2Z3tVtaAhvB3M8 --- _Generated by [Claude Code](https://claude.ai/code/session_01Lz7pRcec2Z3tVtaAhvB3M8)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8b33cab commit 81caf8e

4 files changed

Lines changed: 82 additions & 1 deletion

File tree

.machine_readable/6a2/STATE.a2ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
[metadata]
55
project = "affinescript"
66
version = "0.1.1"
7-
last-updated = "2026-06-02"
7+
last-updated = "2026-06-21"
88
status = "active"
99
authoritative-status-doc = "docs/CAPABILITY-MATRIX.adoc"
1010
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.)"
11+
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)."
1112
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."
1213
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."
1314
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)."

README.adoc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,22 @@ Write software where the compiler helps enforce resource lifecycles, protocol st
6161
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).
6262
====
6363

64+
== Start here — by audience
65+
66+
[cols="1,4"]
67+
|===
68+
| You are a… | Start here
69+
70+
| **New user / learning the language**
71+
| link:docs/tutorial/lesson-01-hello.adoc[Tutorial (lessons 1–10)] · link:docs/guides/warmup/[runnable warm-ups] · link:wiki/language-reference/[language reference]
72+
73+
| **Developer / compiler contributor**
74+
| link:docs/NAVIGATION.adoc[Repository map] · link:wiki/compiler/architecture.md[compiler architecture] · link:docs/decisions/[ADRs] · link:docs/CAPABILITY-MATRIX.adoc[capability matrix]
75+
76+
| **Maintainer / releaser**
77+
| 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]
78+
|===
79+
6480
== What AffineScript Is
6581

6682
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:

docs/NAVIGATION.adoc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55

66
This guide helps you navigate the AffineScript repository structure.
77

8+
== Start here — by audience
9+
10+
* *New users* — link:tutorial/lesson-01-hello.adoc[tutorial (lessons 1–10)], link:guides/warmup/[runnable warm-ups], link:../wiki/language-reference/[language reference].
11+
* *Developers / contributors* — this guide, link:../wiki/compiler/architecture.md[compiler architecture], link:decisions/[ADRs], link:governance/CONTRIBUTING.adoc[contributing].
12+
* *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].
13+
814
== Quick Start Files (Root Level)
915

1016
[cols="1,3"]

docs/tutorial/lesson-01-hello.adoc

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// SPDX-License-Identifier: MPL-2.0
2+
// SPDX-FileCopyrightText: 2024-2026 hyperpolymath (Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>)
3+
= Lesson 1: Hello, AffineScript
4+
5+
The first stop in the tutorial series (lessons 1–10). For runnable, self-contained
6+
snippets covering the same early ground, see the
7+
link:../guides/warmup/[warm-up programs] (`*.affine` files you can `eval` directly).
8+
9+
== Your first program
10+
11+
[source,affinescript]
12+
----
13+
fn main() -> Int {
14+
println("Hello, AffineScript!");
15+
return 0;
16+
}
17+
----
18+
19+
A program is a set of declarations; `main` is the entry point. Functions use explicit
20+
`return`, and statements end with `;`.
21+
22+
== Running it
23+
24+
AffineScript type-, effect-, and borrow-checks ahead of time, then compiles to
25+
WebAssembly (it also has a tree-walking interpreter for quick runs):
26+
27+
[source,sh]
28+
----
29+
affinescript check hello.affine # static checks only (types, effects, borrows)
30+
affinescript eval hello.affine # check, then run via the interpreter
31+
affinescript compile hello.affine # check, then emit WebAssembly (-o out.wasm)
32+
----
33+
34+
Install by building from source — `dune build bin/main.exe` (entry point
35+
`_build/default/bin/main.exe`); prebuilt per-platform binaries are attached to tagged
36+
link:https://github.com/hyperpolymath/affinescript/releases[releases].
37+
38+
== What you'll learn
39+
40+
[cols="1,4"]
41+
|===
42+
| Lesson | Topic
43+
44+
| link:lesson-02-functions.adoc[2] | Functions and ownership (`own` / `ref` / `mut`)
45+
| link:lesson-03-data.adoc[3] | Data: records, enums, tuples
46+
| link:lesson-04-patterns.adoc[4] | Pattern matching
47+
| link:lesson-05-types.adoc[5] | The type system
48+
| link:lesson-06-errors.adoc[6] | Errors and `Result`
49+
| link:lesson-07-effects.adoc[7] | Effects and handlers
50+
| link:lesson-08-generics.adoc[8] | Generics
51+
| link:lesson-09-modules.adoc[9] | Modules and imports
52+
| link:lesson-10-building.adoc[10] | Building a complete program
53+
|===
54+
55+
For the full language reference, see link:../../wiki/language-reference/[wiki/language-reference];
56+
for authoritative feature status, link:../CAPABILITY-MATRIX.adoc[docs/CAPABILITY-MATRIX.adoc].
57+
58+
Next: link:lesson-02-functions.adoc[Lesson 2 — Functions and Ownership].

0 commit comments

Comments
 (0)