Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .machine_readable/6a2/STATE.a2ml
Original file line number Diff line number Diff line change
Expand Up @@ -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)."
Expand Down
16 changes: 16 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 6 additions & 0 deletions docs/NAVIGATION.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
58 changes: 58 additions & 0 deletions docs/tutorial/lesson-01-hello.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// SPDX-License-Identifier: MPL-2.0
// SPDX-FileCopyrightText: 2024-2026 hyperpolymath (Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>)
= 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].
Loading