diff --git a/.machine_readable/6a2/PLAYBOOK.a2ml b/.machine_readable/6a2/PLAYBOOK.a2ml index 5003fd08..f6c65fe8 100644 --- a/.machine_readable/6a2/PLAYBOOK.a2ml +++ b/.machine_readable/6a2/PLAYBOOK.a2ml @@ -4,7 +4,7 @@ # PLAYBOOK.a2ml — Operational playbook [metadata] version = "0.1.0" -last-updated = "2026-04-11" +last-updated = "2026-05-26" [deployment] # method = "gitops" # gitops | manual | ci-triggered @@ -24,3 +24,38 @@ last-updated = "2026-04-11" [maintenance-operations] # Baseline audit: just maint-audit # Hard release gate: just maint-hard-pass + +[npm-publish] +# Runbook for publishing a @hyperpolymath/* package to npm (lineage from +# issue #104, first applied to @hyperpolymath/affine-vscode@0.1.0 +# on 2026-05-26). +# +# Prerequisites (one-time per estate, completed 2026-05-26): +# * npm org `hyperpolymath` exists on registry.npmjs.org (free public tier) +# * Repo secret NPM_TOKEN holds an automation token with read+write +# access to the @hyperpolymath/* scope +# +# Per-package workflow: +# 1. packages//package.json +# "name": "@hyperpolymath/" +# "version": "X.Y.Z" +# "license": "MPL-2.0" +# "publishConfig": { "access": "public" } +# "repository": { "type": "git", "url": "...", "directory": "packages/" } +# "files": [...] # explicit allowlist; never publish the whole tree +# 2. .github/workflows/-publish.yml +# on push tag '-v*' +# - verify GITHUB_REF_NAME (minus '-v') == package.json version +# - write ${HOME}/.npmrc from secrets.NPM_TOKEN, then npm publish --access public +# - rm -f ${HOME}/.npmrc (always) +# Mirror affine-vscode-publish.yml's shape. +# 3. Tag push (signed, at origin/main): +# git tag -s -vX.Y.Z origin/main -m " X.Y.Z — npm publish (Refs #N)" +# git push origin -vX.Y.Z +# 4. Verify: npm view @hyperpolymath/@X.Y.Z +# +# Tag naming: distinct prefix per package so they never collide with the +# OCaml compiler's `v*` Release-workflow tags. e.g. affine-vscode-v*. +# +# Token rotation: rotate NPM_TOKEN after any wire-up where the token +# value transited a session transcript. diff --git a/.machine_readable/6a2/STATE.a2ml b/.machine_readable/6a2/STATE.a2ml index 3e72c343..ea7a5ee9 100644 --- a/.machine_readable/6a2/STATE.a2ml +++ b/.machine_readable/6a2/STATE.a2ml @@ -8,6 +8,7 @@ last-updated = "2026-05-23" 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-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-26 = "MIGRATION-ASSISTANT PHASE 2C + REPO-TIDY STACK (T-1..T-7) + STDLIB BLOCKER CLOSURES. (1) PR #357 — feat(res-to-affine) Phase 2c on branch claude/epic-gauss-Mbi0E: tree-sitter walker extended from #322's single Side_effect_import detector to all six anti-patterns. New detectors in tools/res-to-affine/walker.ml — detect_raw_js (any extension_expression node), detect_untyped_exception (try_expression / call to value_identifier \"raise\" / member_expression starting with Js.Exn or ending with Promise.catch), detect_mutable_global (top-level let_declaration whose body is call to value_identifier \"ref\", OR top-level mutation_expression), detect_inline_callback_record (>=3 inline function values in a record literal or a call_expression's arguments list — handles direct function children + labeled_argument + record_field wrappers), detect_oversized_function (function node whose stop.row - start.row + 1 > 50). Module-toplevel predicate refactored to a single at_module_toplevel helper that walks the ancestor chain refusing on `function` or `let_binding` body. Findings deduped by (kind, line) so the AST walker doesn't emit more bullets than the line-based scanner. CLI flipped --engine=walker to the default in tools/res-to-affine/main.ml (scanner remains as fallback when grammar / tree-sitter CLI missing — pre-existing graceful-fallback path from #322 unchanged). Scanner.kind extended with Inline_callback_record + Oversized_function variants; scanner.ml gives them labels + guidance. New fixture test/fixtures/phase2c.res exercises the two walker-only kinds. test_walker.ml grew per-kind tests under three new suites (walker-side-effect-import / walker-phase2c-parity / walker-phase2c-new-kinds). README + walker.mli updated. (2) Phase 2c CI fix push (e7a3a44): initial Phase 2c commit had build+lint failing; defensive rewrite replaced the labeled-only `mk_finding ~kind:K ~line:L ~excerpt:E :: acc` emit pattern with explicit `let finding : Scanner.finding = { ... } in finding :: acc` matching Phase 2b's working style, plus replaced non-ASCII glyphs in comments (≥ → >=, … → ...) defensively. (3) DIAGNOSED: `main` itself is red. PR #359 (T-1, pure file-rename + delete + one-line CONTRIBUTING.md edit, zero OCaml touched) also fails on build+lint. That conclusively shows the build failure is inherited from main, not introduced by Phase 2c or any tidy work. Matches CLAUDE.md §\"CI signal reliability\" — auto-merge fires even when build is red; the historical pattern of #334/#335/#336/#344 landing red applies. Root cause on main is NOT diagnosed in this session (needs the actual `dune build` log; WebFetch on the actions UI returns React skeletons, not log content; container has no OCaml toolchain to repro locally). Filed implicit follow-up: someone with shell access should run `gh run view --log-failed ` against any of the recent failing runs to identify the underlying lib/ compile error. (4) REPO-TIDY STACK (T-1..T-7) — six small PRs landed off origin/main, each reviewable in isolation, none touching .ml/.mli, all inheriting the same baseline build/lint failure as PR #359 (proof above). T-1 PR #359 *MERGED* — AI.a2ml → 0-AI-MANIFEST.a2ml (Hypatia root_hygiene rule + sibling-repo convention), delete AI.djot (superseded), docs/TECH-DEBT-alt.adoc → docs/TECH-DEBT.adoc (restoring the canonical name every cross-link in the repo already points at; PR #356's -alt suffix during the #351 split is dead weight post-#355). T-2 PR #360 — delete 2,182 lines of submarine-game docs (DAMAGE-SYSTEM.md, CONTROLS-REFERENCE.md, GAME-BUNDLING-STRATEGY.md), zero cross-references. T-3 PR #365 — 13 loose root .md/.adoc moved into docs/ subtree (ABI-FFI-README → docs/reference/ABI-FFI.md, ALPHA-1-RELEASE-NOTES → docs/history/, BACKEND-{ANALYSIS,IMPLEMENTATION} → docs/architecture/, COMPILER-CAPABILITIES → docs/reference/, EXPLAINME/KNOWN-ISSUES/NAVIGATION/PROOF-NEEDS/ROADMAP → docs/, LICENSING-GUIDE/SECURITY-SETUP → docs/governance/, RSR_OUTLINE → docs/standards/RSR-OUTLINE.adoc), two new subdirs docs/architecture/ + docs/reference/, cross-refs fixed in CAPABILITY-MATRIX / BACKEND-IMPLEMENTATION / CONTRIBUTING / NAVIGATION / res-to-affine; root drops 17→5 community-health files. T-4 PR #366 — RSR_COMPLIANCE.adoc at root with four documented deviations (no guix.scm/flake.nix; STATE.scm substituted by .machine_readable/6a2/STATE.a2ml because .scm is reserved for Guix per language policy; 7 TS exemptions; 2 runtime exemptions — all cite CLAUDE.md as authoritative). T-5 PR #367 — wiki/README.md rewrite (drops ~20 dead links to non-existent .md files, updates stale ../ROADMAP.md → ../docs/ROADMAP.adoc path, annotates Features-at-a-Glance examples with current maturity, switches Ownership example from &File/&mut File sigil syntax to canonical ref File/mut File keyword types) + parse-only honesty banner on wiki/language-reference/dependent-types.md + partial honesty banner on wiki/language-reference/traits.md. T-6 — direct issue triage, no PR: closed #246 (ESC-02 JSON.t — stdlib/json.affine delivers Json ADT + encoders/decoders/get_field/stringify) and #247 (ESC-03 Dict.t — stdlib/dict.affine delivers empty/from_pairs/get/contains/size/insert/set/remove/keys/values), both with confirmation comments referencing the LANDED status in docs/TECH-DEBT.adoc STDLIB-02/03 rows. T-7 this PR — adds this session-note + the T-1..T-7 ledger entry below in docs/TECH-DEBT.adoc. (5) ALSO RESOLVED EARLIER IN SESSION (pre-T-6, as part of addressing the sustainabot tracker blockers the user asked about): #161 (Json) and #162 (Dict) closed with explicit owner-author-acknowledged closure comments dated 2026-05-24; this session was the explicit owner request to act on those. Migration-assistant tracker #57 stays open — Phase 2c lands #322's Phase 2b → 2c walker work but Phase 3 (partial translation of pure-structural forms — the phase the sustainabot tracker's exit criterion 3 specifically gates on) remains unstarted. (6) OPEN PRs AT SESSION END: #357 (Phase 2c, ready to merge — author/owner discretion on the baseline-red CI), #360/#365/#366/#367 (T-2/T-3/T-4/T-5, same baseline-red situation; pure-rename / pure-delete / pure-doc-add changes, no behavioural risk). (7) NOT DONE IN THIS SESSION: actual root-cause diagnosis of main's red build/lint; ~20 missing wiki pages (installation, hello-world, expressions, errors, package-manager, lsp, formatter, linter, stdlib subpages, design/*); guix.scm or flake.nix addition; full wiki content refresh beyond README + two banners; sync of wiki/ to the GitHub-wiki upstream repo (separate git repo, owner pushes manually). (8) CROSS-REPO: this session is AffineScript-only — the gitbot-fleet sustainabot tracker that prompted #161/#162/#57 lives in a different repo and was not touched here." typed-wasm-formalisation-2026-05-23 = "AS↔TYPED-WASM INTERFACE FORMALISED + WIDENING ROADMAP + TWO PROPOSED ADRs. (1) docs/specs/TYPED-WASM-INTERFACE.adoc + .a2ml — formal spec of the v1 interface (was previously scattered across ECOSYSTEM.adoc + code comments in lib/codegen.ml, tw_interface.ml, tw_verify.ml). Captures: enforced surface (L7 aliasing + L10 linearity + L13 module isolation negative-form); carrier binary layout (u32 entry_count + per-entry [u32 func_index | u8 param_count | u8[n] param_kind | u8 ret_kind], kind ∈ {0 Unrestricted, 1 Linear, 2 SharedBorrow, 3 ExclBorrow}, all LE, omit-when-empty, no version field in v1); producer machinery file-line pointers (lib/codegen.ml ~110-177 + ctx.ownership_annots ~2312/~2629); consumer machinery (tw_verify.ml 332 LOC, tw_interface.ml 276 LOC, primary entry verify_from_module); CLI surface (verify / verify-boundary / verify-bridge / interface — verify-boundary's pre-2026-04-19 silent-success bug fixed by f6089a2); test coverage (test_tw_isolation.ml 5 cases + E2E Boundary Verify 3 cases + ownership-roundtrip 3 cases; honest gap: no C5.1 cross-compat fixtures shipped); multi-producer responsibilities (AS = ref producer + spec of record until C5.1; ephapax = second producer same format; typed-wasm = spec + Rust verifier + cross-compat target); deliberate non-features NF-001..NF-005 with roadmap anchors; stability promise (v1 frozen; unilateral changes forbidden). (2) docs/specs/TYPED-WASM-ROADMAP.adoc + .a2ml — making typed-wasm a natural + optimal target. Five tranches with unblock graph: A (ergonomics, no ABI change: A1 --typed-wasm gating flag, A2 report-typed-wasm JSON, A3 extract ownership-section to dedicated module, A4 diagnostic span parity) → B (schema hygiene, additive single-byte ABI: B1 = ADR-020) → C (compiler-side foundations for L1–6/L14–16: C1 region inference / CORE-01 Phase 3, C2 session-type+capability tracking, C3 CONV-02/ADR-016 S2..S4 async recogniser, C4 capability-typed externs) → D (multi-producer ABI widening: D1 = ADR-021, D2 affinescript.regions, D3 affinescript.{capabilities,session,choreography}) → E (cross-compat closure: E1 INT-12/CONV-05 fixtures into typed-wasm C5.1, E2 Rust-verifier parity out-of-scope-here). Recommended sequencing: A1→A3→A2→E1→B1→A4→D1→C1..C4→D2/D3→E2. (3) ADR-020 (PROPOSED, META.a2ml): ownership-section schema versioning — v1 unversioned → v2 with 0xAF sentinel + u8 version + entry_count. v1 readers fail cleanly on v2 (bad entry-count parse); v2 readers dispatch on sentinel. Coordinated landing: verifier ships parse first, producers flip emit together. (4) ADR-021 (PROPOSED, META.a2ml): multi-producer ABI coordination model — four axes (spec authority OCaml→Rust on C5.1 closure; coordinated landing protocol; test parity protocol; conflict resolution via serialised queue owned by typed-wasm). ADR-020 is itself the first test of ADR-021's protocol. (5) Cross-links: ECOSYSTEM.adoc §contract paragraph now points at TYPED-WASM-INTERFACE.adoc as authoritative; CAPABILITY-MATRIX.adoc typed-wasm row links to INTERFACE + ROADMAP and notes L13 alongside L7/L10; TECH-DEBT.adoc Stage E section gets header pointer + DOC-13/14/15 ledger entries (interface, roadmap, ADRs); docs/README.adoc + NAVIGATION.adoc list both new specs. (6) Pure documentation work — no compiler code changed, no behaviour change. Both ADRs require owner ratification before they bind." stage-d-batch-2026-05-23 = "INT-01 ::-in-value-expr + BUG-005 deferred fixture + STDLIB-04 audit. (1) INT-01 follow-up: lib/parser.mly line ~835 — added `upper_ident COLONCOLON lower_ident` production emitting `ExprField(ExprVar Mod, lower_ident)`, the same AST shape `Mod.fn` already produces. Disambiguated from the line-above `Type::Variant` rule by lower_ident vs upper_ident. No resolver change required: Resolve.lower_qualified_value_paths handles both `.` and `::` syntaxes identically because the lowering pattern-matches on the ExprField shape, not the source separator. test/e2e/fixtures/cross_caller_qualified_colon{,_alias}.affine + 2 alcotest cases in qualified_value_tests pin both `use Mod; Mod::fn(x)` and `use Mod as M; M::fn(x)`. The remaining INT-01 'parser gap, not resolver' note in the ledger is now closed. (2) BUG-005 deferred regression test landed (test/test_e2e.ml, wasm_gc_loud_fail_tests): `fn main() -> Int { return totally_undefined_callee(42); }` is fed directly to Codegen_gc.generate_gc_module (no resolve step) and the emitted error must contain the unknown name — which UnboundFunction's format string includes verbatim. Closes the deferred-status entry on the [[closed-bug]] BUG-005 record. (3) docs/STDLIB-EXTERN-AUDIT.adoc — full triage of 135 extern fn + 24 extern type across 11 stdlib files into 4 classes (built-in / typed-boundary-bridge / adapter-Deno / adapter-Node); per-row status (done/partial/stub-only) and unblock condition for each module. STDLIB-04's ledger entry now points here. Implementation PRs close one row at a time; the audit doc is the canonical roadmap, not STATE.a2ml. (4) Not yet verified locally — no OCaml toolchain in this remote execution environment. CI is the verification surface; parser change is low-risk (single production, no Menhir conflict — `upper_ident COLONCOLON lower_ident` is unambiguous against the prior `upper_ident COLONCOLON upper_ident` rule by token class)." diff --git a/packages/affine-vscode/README.adoc b/packages/affine-vscode/README.adoc index 5108cc92..c7620c27 100644 --- a/packages/affine-vscode/README.adoc +++ b/packages/affine-vscode/README.adoc @@ -111,9 +111,11 @@ ABI lands. == Status -Phase 2 — bindings landed. The pilot affinescript port (issue #63) and -external-extension ports (issue #64: my-lang, rsr-certifier) consume -this adapter. npm publish wiring is in place (issue #104: -`affine-vscode-publish.yml` ships the package on `affine-vscode-v*` -tag pushes); the first publish + downstream un-vendoring is gated on -that issue. Phase 4 (rattlescript-face sweep) still to do. +Phase 2 — bindings landed; package published on npm as +`@hyperpolymath/affine-vscode@0.1.0` (2026-05-26, issue #104). The +pilot affinescript port (issue #63), `hyperpolymath/my-lang/vscode-extension/` +and `hyperpolymath/standards/rhodium-standard-repositories/satellites/rsr-certifier/extensions/vscode/` +(issue #64) all consume this adapter from the registry. The publish +workflow `affine-vscode-publish.yml` ships subsequent versions on +`affine-vscode-v*` tag pushes. Phase 4 (rattlescript-face sweep) still +to do.