Release 1.0.0-beta.11 local package api documentation

This commit is contained in:
sanjin 2026-05-22 20:24:42 +02:00
parent f8f0862ee3
commit 87f90ba264
14 changed files with 1147 additions and 52 deletions

View File

@ -0,0 +1,57 @@
# 1.0.0-beta.11 Local Package API Documentation
Status: release scope for `1.0.0-beta.11`.
`1.0.0-beta.11` extends the beta.10 API discovery lane. The release keeps the
`1.0.0-beta` source-language and runtime baseline unchanged while making local
package and module documentation show the public API surface users need to
review.
## Scope
- Extend `glagol doc <file|project|workspace> -o <dir>` so generated Markdown
includes deterministic exported/public API sections for local source files,
projects, packages, and workspaces.
- Render exact exported function signatures with parameter names, parameter
types, and return types.
- Render exported struct field names and field types.
- Render exported enum variant names and payload types for payloadless and
current single-payload variants.
- Keep non-exported functions, structs, enums, tests, and `(type ...)` aliases
out of the public API sections.
- Normalize module-local concrete aliases before rendering public types, so
private names such as `VecI32`, `OptionString`, or `ResultU64` do not leak
into local package/module public docs.
- Update README, language docs, compiler docs, and the post-beta roadmap to
describe the beta11 documentation contract clearly.
## Public Contract
The generated local documentation is a beta API discovery aid. It exposes what
the current local module/package export lists make public, with concrete public
types after alias normalization.
The public API sections are deterministic and suitable for human review, but
they are not a stable machine-readable Markdown schema. Headings, anchors, file
names, and surrounding prose remain beta-scoped unless a later release freezes
them explicitly.
## Explicit Non-Scope
- no stable Markdown schema
- no stable stdlib/API compatibility freeze
- no LSP server or watch mode
- no SARIF or daemon protocol
- no diagnostics schema policy
- no executable generics
- no maps or sets
- no re-exports, glob imports, or hierarchical modules
- no package registry semantics
- no new compiler-known runtime names
- no runtime helper or ABI/layout changes
## Checks
Focused checks for this slice:
- `git diff --check -- README.md docs/POST_BETA_ROADMAP.md docs/language/ROADMAP.md docs/language/RELEASE_NOTES.md docs/language/SPEC-v1.md docs/compiler/ROADMAP.md docs/compiler/RELEASE_NOTES.md .llm/BETA_11_LOCAL_PACKAGE_API_DOCUMENTATION.md`

View File

@ -0,0 +1,73 @@
# 1.0.0-beta.11 Release Review
Status: ready for publication after the controller release gate.
## Verdict
No blocking issues remain after controller follow-up. The original workspace
package API leak was reproduced, fixed, and covered by a regression test before
publication.
## Resolved Finding
- Workspace package API docs originally included compiler-loaded standard
library modules when a workspace package imported `std.option`.
- Controller fix: workspace package API rendering now filters package modules
to the package source root before collecting public API sections, matching
the existing project-mode local-root behavior. Ordinary module summaries can
still show loaded standard-library modules, but package API sections no
longer present those modules as package-owned API.
- Regression added:
`doc_workspace_package_api_excludes_loaded_std_modules`.
## Scope Checked
- `compiler/src/docgen.rs` adds per-module public API sections and package API
sections, renders exported function signatures, struct fields, enum variants,
and normalizes module-local aliases before public rendering.
- `compiler/tests/doc_api_beta11.rs` covers file, project, workspace scaffold,
workspace packages importing `std.*`, alias normalization, non-exported
function omission, and byte-identical repeat generation for a file input.
- README, compiler/language roadmaps, release notes, SPEC-v1, `STDLIB_API.md`,
and the beta11 `.llm` contract include the main deferrals: no stable Markdown
schema, no stable stdlib/API compatibility freeze, no LSP/watch, no
SARIF/daemon protocol, no diagnostics schema policy, no executable generics,
no maps/sets, no re-exports/globs/hierarchical modules, and no registry
semantics.
- Version bumps in `compiler/Cargo.toml` and `compiler/Cargo.lock` move
`glagol` from `1.0.0-beta.10` to `1.0.0-beta.11`.
## Test Coverage Notes
- Workspace packages that import `std.*` are now covered by a focused
regression that verifies package API excludes loaded standard-library
modules and helpers.
- Determinism is asserted byte-for-byte only for file docs. Project and
workspace determinism are indirectly exercised by sorted rendering but not
protected by repeat-generation tests.
- Non-export filtering is asserted for functions and aliases. There is no
explicit negative test for non-exported structs, non-exported enums, or tests
appearing in public API sections.
- Alias normalization is covered for file/module docs, but not for project or
workspace package API fixtures.
## Verification
- `cargo fmt --check`: passed.
- `cargo check`: passed.
- `cargo test --test doc_api_beta11`: passed, 6 tests.
- `cargo test --test dx_v1_7`: passed, 13 tests.
- `cargo test --test symbols_beta10`: passed, 4 tests.
- `cargo test --test promotion_gate`: passed, 1 unignored test.
- `git diff --check`: passed.
- Stale beta10 current-release/version scan over README, docs, `.llm`, and
compiler package metadata: no matches.
- Private/local publication text scan over README, docs, scripts, compiler
source/tests, lib, examples, benchmarks, tests, and `.llm`: no matches.
- `node scripts/render-stdlib-api-doc.js`: passed and refreshed the catalog
release wording to `1.0.0-beta.11`.
- Manual workspace std-import doc generation after the fix: package API no
longer includes loaded standard-library modules.
- `./scripts/release-gate.sh`: passed docs, generated stdlib API catalog
consistency, private-publication text checks, formatter checks, the full cargo
test suite, ignored promotion checks, binary smoke, and LLVM smoke.

View File

@ -6,7 +6,7 @@ This repository is the canonical public monorepo for the language design,
standard library source, compiler, runtime, examples, benchmarks, and technical
documents.
Current release: `1.0.0-beta.10`.
Current release: `1.0.0-beta.11`.
## Repository Layout
@ -24,16 +24,17 @@ scripts/ local release and document tooling
## Beta Scope
`1.0.0-beta.10` keeps the `1.0.0-beta` language baseline, includes the
`1.0.0-beta.11` keeps the `1.0.0-beta` language baseline, includes the
`1.0.0-beta.1` tooling/install hardening slice, the `1.0.0-beta.2`
runtime/resource foundation bundle, the `1.0.0-beta.3` standard-library
stabilization bundle, the `1.0.0-beta.4` language-usability diagnostics
bundle, the `1.0.0-beta.5` local package/workspace discipline bundle, and the
`1.0.0-beta.6` loopback networking foundation, plus the `1.0.0-beta.7`
serialization/data-interchange foundation and the `1.0.0-beta.8` concrete type
alias foundation, and the `1.0.0-beta.9` collection alias unification and
generic reservation slice, plus the `1.0.0-beta.10` developer-experience API
discovery slice. The language baseline supports practical local
alias foundation, the `1.0.0-beta.9` collection alias unification and
generic reservation slice, the `1.0.0-beta.10` developer-experience API
discovery slice, and the `1.0.0-beta.11` local package API documentation
slice. The language baseline supports practical local
command-line, file, and loopback-network programs with:
- modules, explicit imports, packages, and local workspaces
@ -56,17 +57,24 @@ types, and omits non-exported helpers and `(type ...)` aliases.
`glagol symbols <file.slo|project|workspace>` emits deterministic
editor-facing S-expression metadata for modules, imports, exports, aliases,
structs, enums, functions, tests, source spans, and workspace package names.
`glagol doc <file|project|workspace> -o <dir>` now includes deterministic public
API sections for local package and module documentation: exact exported
function signatures, exported struct fields, exported enum variants and payload
types, non-export filtering, and module-local alias normalization.
Still deferred before stable: executable generics, maps/sets, broad package
registry semantics, DNS/TLS/async networking, LSP/watch/debug-adapter
guarantees, stable ABI and layout, runtime changes for generic collections,
and a stable standard-library compatibility freeze.
registry semantics, stable Markdown schema, stable stdlib/API compatibility
freeze, DNS/TLS/async networking, LSP/watch guarantees, SARIF and daemon
protocols, diagnostics schema policy, re-exports/globs/hierarchical modules,
stable ABI and layout, and runtime changes for generic collections.
The next likely language slice after `1.0.0-beta.10` should continue from the
developer-experience and reserved generic/collection diagnostics without
claiming executable generics, maps, sets, traits, inference,
monomorphization, iterators, ABI stability, runtime changes, or a
standard-library API freeze until the contract and gates are explicit.
The next likely language slice after `1.0.0-beta.11` should continue from the
developer-experience, diagnostics, and reserved generic/collection lanes
without claiming executable generics, maps, sets, traits, inference,
monomorphization, iterators, ABI stability, runtime changes, LSP/watch
protocols, registry semantics, stable Markdown schema, or a
standard-library/API compatibility freeze until the contract and gates are
explicit.
## Build And Test
@ -261,6 +269,24 @@ add executable generics, maps, sets, new runtime helpers, new compiler-known
runtime names, ABI/layout guarantees, an LSP server, watch mode, or a stable
standard-library API freeze.
## 1.0.0-beta.11 Local Package API Documentation
The `1.0.0-beta.11` release extends the beta.10 API discovery lane to local
package and module documentation. `glagol doc <file|project|workspace> -o <dir>`
includes deterministic exported/public API sections for local modules and
workspace packages.
Those sections list exact exported function signatures, exported struct fields,
and exported enum variants with payload types. They omit non-exported
functions, structs, enums, tests, and aliases from the public API surface, and
they normalize module-local concrete aliases before rendering public types.
This remains beta API discovery. It does not freeze the Markdown schema, create
a stable stdlib/API compatibility freeze, add LSP/watch behavior, define
SARIF or daemon protocols, set diagnostics schema policy, implement executable
generics, maps, or sets, add re-exports, globs, or hierarchical modules, or
define package registry semantics.
## Documentation
- [Language Manifest](docs/language/MANIFEST.md)

2
compiler/Cargo.lock generated
View File

@ -4,4 +4,4 @@ version = 3
[[package]]
name = "glagol"
version = "1.0.0-beta.10"
version = "1.0.0-beta.11"

View File

@ -1,6 +1,6 @@
[package]
name = "glagol"
version = "1.0.0-beta.10"
version = "1.0.0-beta.11"
edition = "2021"
description = "Glagol, the first compiler for the Slovo language"
license = "MIT OR Apache-2.0"

View File

@ -1,4 +1,8 @@
use std::{fs, path::Path};
use std::{
collections::{BTreeMap, BTreeSet},
fs,
path::Path,
};
use crate::{
ast::Program,
@ -6,6 +10,7 @@ use crate::{
lexer, lower,
project::{self, ProjectArtifact, SourceFile, ToolFailure, WorkspaceArtifact},
sexpr::{Atom, SExpr, SExprKind},
types::Type,
};
pub fn generate(input: &str, output_dir: &str) -> Result<(), ToolFailure> {
@ -56,16 +61,23 @@ fn render_project(
artifact: &ProjectArtifact,
sources: &[SourceFile],
) -> Result<String, ToolFailure> {
let modules = sources
.iter()
.map(document_source)
.collect::<Result<Vec<_>, _>>()?;
let mut out = String::new();
out.push_str("# Project ");
out.push_str(&artifact.project_name);
out.push_str("\n\n");
if let Some(workspace) = &artifact.workspace {
render_workspace(&mut out, workspace);
render_workspace_package_public_api(&mut out, workspace, &modules);
} else {
render_project_package_public_api(&mut out, artifact, &modules);
}
for source in sources {
let module = document_source(source)?;
render_module(&mut out, &module);
for module in &modules {
render_module(&mut out, module);
}
Ok(out)
}
@ -120,27 +132,58 @@ fn document_source(source: &SourceFile) -> Result<DocModule, ToolFailure> {
sources: vec![source.clone()],
artifact: None,
})?;
let program = lower::lower_program(&source.path, &forms).ok();
let lowerable_forms = forms
.iter()
.filter(|form| !matches!(list_head(form), Some("import")))
.cloned()
.collect::<Vec<_>>();
let program = lower::lower_program(&source.path, &lowerable_forms).ok();
Ok(module_from_forms(&source.path, &forms, program.as_ref()))
}
struct DocModule {
path: String,
title: String,
imports: Vec<String>,
exports: Vec<String>,
structs: Vec<String>,
functions: Vec<String>,
tests: Vec<String>,
public_api: PublicApi,
}
#[derive(Default)]
struct PublicApi {
functions: Vec<DocFunction>,
structs: Vec<DocStruct>,
enums: Vec<DocEnum>,
}
struct DocFunction {
name: String,
signature: String,
}
struct DocStruct {
name: String,
fields: Vec<String>,
}
struct DocEnum {
name: String,
variants: Vec<String>,
}
fn module_from_forms(file: &str, forms: &[SExpr], program: Option<&Program>) -> DocModule {
let mut module = DocModule {
path: file.to_string(),
title: file.to_string(),
imports: Vec::new(),
exports: Vec::new(),
structs: Vec::new(),
functions: Vec::new(),
tests: Vec::new(),
public_api: PublicApi::default(),
};
for form in forms {
@ -205,6 +248,7 @@ fn module_from_forms(file: &str, forms: &[SExpr], program: Option<&Program>) ->
})
.collect();
module.tests = program.tests.iter().map(|test| test.name.clone()).collect();
module.public_api = public_api_from_program(program, &module.exports);
}
module.imports.sort();
@ -221,11 +265,120 @@ fn render_module(out: &mut String, module: &DocModule) {
out.push_str("\n\n");
render_list(out, "Imports", &module.imports);
render_list(out, "Exports", &module.exports);
render_public_api_section(out, "###", &module.public_api);
render_list(out, "Structs", &module.structs);
render_list(out, "Functions", &module.functions);
render_list(out, "Tests", &module.tests);
}
fn render_project_package_public_api(
out: &mut String,
artifact: &ProjectArtifact,
modules: &[DocModule],
) {
let local_root = Path::new(&artifact.project_root).join(&artifact.source_root);
let local_modules = modules
.iter()
.filter(|module| Path::new(&module.path).starts_with(&local_root))
.collect::<Vec<_>>();
render_package_public_api(out, &artifact.project_name, &local_modules);
}
fn render_workspace_package_public_api(
out: &mut String,
workspace: &WorkspaceArtifact,
modules: &[DocModule],
) {
let by_path = modules
.iter()
.map(|module| (module.path.as_str(), module))
.collect::<BTreeMap<_, _>>();
for package in &workspace.packages {
let local_root = Path::new(&package.root).join(&package.source_root);
let package_modules = package
.modules
.iter()
.filter(|module| Path::new(&module.path).starts_with(&local_root))
.filter_map(|module| by_path.get(module.path.as_str()).copied())
.collect::<Vec<_>>();
render_package_public_api(
out,
&format!("{} {}", package.name, package.version),
&package_modules,
);
}
}
fn render_package_public_api(out: &mut String, package_name: &str, modules: &[&DocModule]) {
out.push_str("## Package API ");
out.push_str(package_name);
out.push_str("\n\n");
let public_modules = modules
.iter()
.copied()
.filter(|module| !module.public_api.is_empty())
.collect::<Vec<_>>();
if public_modules.is_empty() {
out.push_str("None.\n\n");
return;
}
for module in public_modules {
out.push_str("### Module ");
out.push_str(&module.title);
out.push_str("\n\n");
render_public_api_body(out, "####", &module.public_api);
}
}
fn render_public_api_section(out: &mut String, heading: &str, public_api: &PublicApi) {
out.push_str(heading);
out.push_str(" Public API\n\n");
render_public_api_body(out, "####", public_api);
}
fn render_public_api_body(out: &mut String, heading: &str, public_api: &PublicApi) {
if public_api.is_empty() {
out.push_str("None.\n\n");
return;
}
if !public_api.functions.is_empty() {
out.push_str(heading);
out.push_str(" Functions\n");
for function in &public_api.functions {
render_code_bullet(out, &function.signature);
}
out.push('\n');
}
if !public_api.structs.is_empty() {
out.push_str(heading);
out.push_str(" Structs\n");
for struct_decl in &public_api.structs {
render_code_bullet(out, &format!("struct {}", struct_decl.name));
for field in &struct_decl.fields {
render_indented_code_bullet(out, field);
}
}
out.push('\n');
}
if !public_api.enums.is_empty() {
out.push_str(heading);
out.push_str(" Enums\n");
for enum_decl in &public_api.enums {
render_code_bullet(out, &format!("enum {}", enum_decl.name));
for variant in &enum_decl.variants {
render_indented_code_bullet(out, variant);
}
}
out.push('\n');
}
}
fn render_list(out: &mut String, title: &str, values: &[String]) {
out.push_str("### ");
out.push_str(title);
@ -242,6 +395,182 @@ fn render_list(out: &mut String, title: &str, values: &[String]) {
out.push('\n');
}
fn list_head(expr: &SExpr) -> Option<&str> {
list(expr).and_then(|items| items.first()).and_then(ident)
}
fn render_code_bullet(out: &mut String, value: &str) {
out.push_str("- `");
out.push_str(&value.replace('`', "\\`"));
out.push_str("`\n");
}
fn render_indented_code_bullet(out: &mut String, value: &str) {
out.push_str(" - `");
out.push_str(&value.replace('`', "\\`"));
out.push_str("`\n");
}
impl PublicApi {
fn is_empty(&self) -> bool {
self.functions.is_empty() && self.structs.is_empty() && self.enums.is_empty()
}
}
fn public_api_from_program(program: &Program, exports: &[String]) -> PublicApi {
let export_names = exports.iter().cloned().collect::<BTreeSet<_>>();
let aliases = alias_targets(program);
let mut functions = program
.functions
.iter()
.filter(|function| export_names.contains(&function.name))
.map(|function| DocFunction {
name: function.name.clone(),
signature: function_signature(
&function.name,
function
.params
.iter()
.map(|param| (param.name.as_str(), &param.ty)),
&function.return_type,
&aliases,
),
})
.collect::<Vec<_>>();
functions.sort_by(|left, right| left.name.cmp(&right.name));
let mut structs = program
.structs
.iter()
.filter(|struct_decl| export_names.contains(&struct_decl.name))
.map(|struct_decl| DocStruct {
name: struct_decl.name.clone(),
fields: struct_decl
.fields
.iter()
.map(|field| {
format!(
"{}: {}",
field.name,
display_public_type(&field.ty, &aliases)
)
})
.collect(),
})
.collect::<Vec<_>>();
structs.sort_by(|left, right| left.name.cmp(&right.name));
let mut enums = program
.enums
.iter()
.filter(|enum_decl| export_names.contains(&enum_decl.name))
.map(|enum_decl| DocEnum {
name: enum_decl.name.clone(),
variants: enum_decl
.variants
.iter()
.map(|variant| match &variant.payload_ty {
Some(payload_ty) => {
format!(
"{}({})",
variant.name,
display_public_type(payload_ty, &aliases)
)
}
None => variant.name.clone(),
})
.collect(),
})
.collect::<Vec<_>>();
enums.sort_by(|left, right| left.name.cmp(&right.name));
PublicApi {
functions,
structs,
enums,
}
}
fn function_signature<'a>(
name: &str,
params: impl Iterator<Item = (&'a str, &'a Type)>,
return_type: &Type,
aliases: &BTreeMap<String, Type>,
) -> String {
let params = params
.map(|(name, ty)| format!("{}: {}", name, display_public_type(ty, aliases)))
.collect::<Vec<_>>()
.join(", ");
format!(
"fn {}({}) -> {}",
name,
params,
display_public_type(return_type, aliases)
)
}
fn alias_targets(program: &Program) -> BTreeMap<String, Type> {
let raw = program
.type_aliases
.iter()
.map(|alias| (alias.name.clone(), alias.target.clone()))
.collect::<BTreeMap<_, _>>();
raw.keys()
.map(|name| {
let mut visiting = BTreeSet::new();
(
name.clone(),
resolve_alias_type(&Type::Named(name.clone()), &raw, &mut visiting),
)
})
.collect()
}
fn display_public_type(ty: &Type, aliases: &BTreeMap<String, Type>) -> String {
let mut visiting = BTreeSet::new();
resolve_alias_type(ty, aliases, &mut visiting).to_string()
}
fn resolve_alias_type(
ty: &Type,
aliases: &BTreeMap<String, Type>,
visiting: &mut BTreeSet<String>,
) -> Type {
match ty {
Type::Named(name) => {
let Some(target) = aliases.get(name) else {
return ty.clone();
};
if !visiting.insert(name.clone()) {
return ty.clone();
}
let resolved = resolve_alias_type(target, aliases, visiting);
visiting.remove(name);
resolved
}
Type::Ptr(inner) => Type::Ptr(Box::new(resolve_alias_type(inner, aliases, visiting))),
Type::Array(inner, len) => {
Type::Array(Box::new(resolve_alias_type(inner, aliases, visiting)), *len)
}
Type::Vec(inner) => Type::Vec(Box::new(resolve_alias_type(inner, aliases, visiting))),
Type::Slice(inner) => Type::Slice(Box::new(resolve_alias_type(inner, aliases, visiting))),
Type::Option(inner) => Type::Option(Box::new(resolve_alias_type(inner, aliases, visiting))),
Type::Result(ok, err) => Type::Result(
Box::new(resolve_alias_type(ok, aliases, visiting)),
Box::new(resolve_alias_type(err, aliases, visiting)),
),
Type::I32
| Type::I64
| Type::U32
| Type::U64
| Type::F64
| Type::Bool
| Type::Unit
| Type::String => ty.clone(),
}
}
fn list(expr: &SExpr) -> Option<&[SExpr]> {
match &expr.kind {
SExprKind::List(items) => Some(items),

View File

@ -0,0 +1,420 @@
use std::{
ffi::OsStr,
fs,
path::{Path, PathBuf},
process::{Command, Output},
sync::atomic::{AtomicUsize, Ordering},
};
static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
#[test]
fn doc_file_renders_public_api_with_signatures_and_shapes() {
let source = r#"(module api (export Point Status make))
(struct Point
(x i32)
(label string))
(enum Status Ready (Blocked i32))
(fn helper ((value i32)) -> i32
value)
(fn make ((x i32) (label string)) -> Point
(Point (x x) (label label)))
(test "make is documented"
true)
"#;
let file = write_file("file-api", source);
let docs = unique_path("file-api-docs");
let output = run_glagol([
OsStr::new("doc"),
file.as_os_str(),
OsStr::new("-o"),
docs.as_os_str(),
]);
assert_success("doc file", &output);
let index = read_index(&docs);
assert!(index.contains("## Module api"));
assert!(index.contains("### Imports\n\nNone.\n\n"));
assert!(index.contains("- `Point`"));
assert!(index.contains("- `make(x i32, label string) -> Point`"));
assert!(index.contains("- `make is documented`"));
let api = public_api_for_module(&index, "api");
assert!(api.contains("- `fn make(x: i32, label: string) -> Point`"));
assert!(api.contains("- `struct Point`"));
assert!(api.contains(" - `x: i32`"));
assert!(api.contains(" - `label: string`"));
assert!(api.contains("- `enum Status`"));
assert!(api.contains(" - `Ready`"));
assert!(api.contains(" - `Blocked(i32)`"));
assert!(
!api.contains("helper"),
"non-exported helper leaked into public API:\n{}",
api
);
}
#[test]
fn doc_project_renders_package_and_module_public_api() {
let project = write_project(
"project-api",
&[(
"math",
r#"(module math (export add Pair))
(struct Pair
(left i32)
(right i32))
(fn add ((left i32) (right i32)) -> i32
(+ left right))
(fn private_double ((value i32)) -> i32
(+ value value))
"#,
)],
"(module main)\n\n(import math (add Pair))\n\n(fn main () -> i32\n (add 1 2))\n",
);
let docs = unique_path("project-api-docs");
let output = run_glagol([
OsStr::new("doc"),
project.as_os_str(),
OsStr::new("-o"),
docs.as_os_str(),
]);
assert_success("doc project", &output);
let index = read_index(&docs);
assert!(index.contains("# Project project-api"));
assert!(index.contains("## Package API project-api"));
assert!(index.contains("## Module math"));
assert!(index.contains("## Module main"));
assert!(index.contains("- `math`"));
assert!(index.contains("- `add`"));
let package_api = package_api(&index, "project-api");
assert!(package_api.contains("### Module math"));
assert!(package_api.contains("- `fn add(left: i32, right: i32) -> i32`"));
assert!(package_api.contains("- `struct Pair`"));
assert!(
!package_api.contains("private_double"),
"non-exported function leaked into package API:\n{}",
package_api
);
let math_api = public_api_for_module(&index, "math");
assert!(math_api.contains("- `fn add(left: i32, right: i32) -> i32`"));
}
#[test]
fn doc_workspace_renders_each_package_api_deterministically() {
let workspace = unique_path("workspace-api");
let scaffold = run_glagol([
OsStr::new("new"),
workspace.as_os_str(),
OsStr::new("--template"),
OsStr::new("workspace"),
]);
assert_success("workspace scaffold", &scaffold);
let docs = unique_path("workspace-api-docs");
let output = run_glagol([
OsStr::new("doc"),
workspace.as_os_str(),
OsStr::new("-o"),
docs.as_os_str(),
]);
assert_success("doc workspace", &output);
let index = read_index(&docs);
assert!(index.contains("## Workspace"));
assert!(index.contains("- `packages/app`"));
assert!(index.contains("- `packages/libutil`"));
assert!(index.contains("## Package API app 0.1.0"));
assert!(index.contains("## Package API libutil 0.1.0"));
let app_api = package_api(&index, "app 0.1.0");
assert!(app_api.contains("None."));
let lib_api = package_api(&index, "libutil 0.1.0");
assert!(lib_api.contains("### Module libutil"));
assert!(lib_api.contains("- `fn answer() -> i32`"));
assert!(lib_api.contains("- `fn label() -> string`"));
}
#[test]
fn doc_workspace_package_api_excludes_loaded_std_modules() {
let workspace = write_workspace_with_std_import("workspace-std-api");
let docs = unique_path("workspace-std-api-docs");
let output = run_glagol([
OsStr::new("doc"),
workspace.as_os_str(),
OsStr::new("-o"),
docs.as_os_str(),
]);
assert_success("doc workspace std import", &output);
let index = read_index(&docs);
assert!(
index.contains("## Module option"),
"module summaries should still include loaded std module docs:\n{}",
index
);
let app_api = package_api(&index, "app 0.1.0");
assert!(app_api.contains("### Module main"));
assert!(app_api.contains("- `fn local_some(value: i32) -> (option i32)`"));
assert!(
!app_api.contains("Module std.option") && !app_api.contains("Module option"),
"loaded std module leaked into package API:\n{}",
app_api
);
assert!(
!app_api.contains("some_i32"),
"loaded std helper leaked into package API:\n{}",
app_api
);
}
#[test]
fn public_api_normalizes_local_aliases_and_omits_alias_exports() {
let source = r#"(module aliases (export Count Score Status measure))
(type Count i32)
(type MaybeCount (option Count))
(struct Score
(value Count)
(maybe MaybeCount))
(enum Status Ready (Blocked Count) (Maybe MaybeCount))
(fn hidden ((value Count)) -> Count
value)
(fn measure ((value Count) (maybe MaybeCount)) -> Count
value)
"#;
let file = write_file("alias-api", source);
let docs = unique_path("alias-api-docs");
let output = run_glagol([
OsStr::new("doc"),
file.as_os_str(),
OsStr::new("-o"),
docs.as_os_str(),
]);
assert_success("doc aliases", &output);
let index = read_index(&docs);
assert!(
index.contains("- `Count`"),
"exports summary should retain the alias name"
);
assert!(
index.contains("- `hidden(value Count) -> Count`"),
"function summary should retain non-public declarations"
);
let api = public_api_for_module(&index, "aliases");
assert!(api.contains("- `fn measure(value: i32, maybe: (option i32)) -> i32`"));
assert!(api.contains(" - `value: i32`"));
assert!(api.contains(" - `maybe: (option i32)`"));
assert!(api.contains(" - `Blocked(i32)`"));
assert!(api.contains(" - `Maybe((option i32))`"));
assert!(
!api.contains("Count"),
"alias names leaked into public API:\n{}",
api
);
assert!(
!api.contains("hidden"),
"non-exported function leaked into public API:\n{}",
api
);
}
#[test]
fn repeated_doc_generation_is_byte_identical() {
let source = r#"(module stable (export value))
(fn value () -> i32
42)
"#;
let file = write_file("stable-api", source);
let docs = unique_path("stable-api-docs");
let first = run_glagol([
OsStr::new("doc"),
file.as_os_str(),
OsStr::new("-o"),
docs.as_os_str(),
]);
assert_success("first doc", &first);
let first_bytes = fs::read(docs.join("index.md")).expect("read first docs");
let second = run_glagol([
OsStr::new("doc"),
file.as_os_str(),
OsStr::new("-o"),
docs.as_os_str(),
]);
assert_success("second doc", &second);
let second_bytes = fs::read(docs.join("index.md")).expect("read second docs");
assert_eq!(first_bytes, second_bytes);
}
fn write_project(name: &str, modules: &[(&str, &str)], main: &str) -> PathBuf {
let project = unique_path(name);
fs::create_dir_all(project.join("src")).expect("create project src");
fs::write(
project.join("slovo.toml"),
format!(
"[project]\nname = \"{}\"\nsource_root = \"src\"\nentry = \"main\"\n",
name
),
)
.expect("write manifest");
for (module, source) in modules {
fs::write(project.join("src").join(format!("{}.slo", module)), source)
.expect("write module");
}
fs::write(project.join("src/main.slo"), main).expect("write main");
project
}
fn write_workspace_with_std_import(name: &str) -> PathBuf {
let workspace = unique_path(name);
let package = workspace.join("packages/app");
fs::create_dir_all(package.join("src")).expect("create workspace package src");
fs::write(
workspace.join("slovo.toml"),
"[workspace]\nmembers = [\"packages/app\"]\ndefault_package = \"app\"\n",
)
.expect("write workspace manifest");
fs::write(
package.join("slovo.toml"),
"[package]\nname = \"app\"\nversion = \"0.1.0\"\nsource_root = \"src\"\nentry = \"main\"\n",
)
.expect("write package manifest");
fs::write(
package.join("src/main.slo"),
r#"(module main (export local_some))
(import std.option (some_i32))
(fn local_some ((value i32)) -> (option i32)
(some_i32 value))
"#,
)
.expect("write package main");
workspace
}
fn write_file(name: &str, source: &str) -> PathBuf {
let path = unique_path(name).with_extension("slo");
fs::write(&path, source).expect("write fixture");
path
}
fn read_index(docs: &Path) -> String {
fs::read_to_string(docs.join("index.md")).expect("read generated docs")
}
fn package_api<'a>(docs: &'a str, package: &str) -> &'a str {
let heading = format!("## Package API {}", package);
let start = docs
.find(&heading)
.unwrap_or_else(|| panic!("missing package API heading `{}`\n{}", heading, docs));
let rest = &docs[start..];
let end = rest
.find("\n## Package API ")
.or_else(|| rest.find("\n## Module "))
.unwrap_or(rest.len());
&rest[..end]
}
fn public_api_for_module<'a>(docs: &'a str, module: &str) -> &'a str {
let heading = format!("## Module {}", module);
let module_start = if docs.starts_with(&heading) {
0
} else {
let marker = format!("\n{}", heading);
docs.find(&marker)
.map(|index| index + 1)
.unwrap_or_else(|| panic!("missing module heading `{}`\n{}", heading, docs))
};
let module_docs = &docs[module_start..];
let module_end = module_docs
.find("\n## Module ")
.unwrap_or(module_docs.len());
let module_docs = &module_docs[..module_end];
let public_start = module_docs.find("### Public API").unwrap_or_else(|| {
panic!(
"missing public API for module `{}`\n{}",
module, module_docs
)
});
let public_docs = &module_docs[public_start..];
let public_end = public_docs
.find("\n### Structs")
.unwrap_or(public_docs.len());
&public_docs[..public_end]
}
fn unique_path(name: &str) -> PathBuf {
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
let nanos = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("system clock before UNIX_EPOCH")
.as_nanos();
std::env::temp_dir().join(format!(
"glagol-doc-api-beta11-{}-{}-{}-{}",
std::process::id(),
nanos,
id,
name
))
}
fn run_glagol<I, S>(args: I) -> Output
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
Command::new(env!("CARGO_BIN_EXE_glagol"))
.args(args)
.output()
.expect("run glagol")
}
fn assert_success(context: &str, output: &Output) {
assert!(
output.status.success(),
"{} failed\nstdout:\n{}\nstderr:\n{}",
context,
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
assert!(
output.stdout.is_empty(),
"{} wrote stdout:\n{}",
context,
String::from_utf8_lossy(&output.stdout)
);
assert!(
output.stderr.is_empty(),
"{} wrote stderr:\n{}",
context,
String::from_utf8_lossy(&output.stderr)
);
}

View File

@ -270,7 +270,6 @@ Work:
- language-server diagnostics and document symbols
- editor-facing symbol metadata for files, projects, and workspaces
- project watch mode
- generated API documentation for local packages
- clearer benchmark harness output
- machine-readable diagnostics stability policy
@ -281,12 +280,45 @@ public types. `glagol symbols <file.slo|project|workspace>` now emits
deterministic `slovo.symbols` metadata for editor integrations without
starting an LSP server. This is beta API discovery only; it does not add
executable generics, maps, sets, runtime changes, or a stable standard-library
API freeze. LSP, watch mode, local-package API docs, benchmark-output work,
and a machine-readable diagnostics stability policy remain deferred.
API freeze. LSP, watch mode, benchmark-output work, stable Markdown schema,
stable stdlib/API compatibility freeze, SARIF/daemon protocols, and a
machine-readable diagnostics stability policy remain deferred.
Why tenth: editor support matters, but it should follow a stable enough syntax,
project model, and diagnostic model.
### 11. Local Package API Documentation
Goal: extend beta API discovery from `lib/std` and symbol metadata to the
local packages and modules users document with `glagol doc`.
Work:
- make `glagol doc <file|project|workspace> -o <dir>` include deterministic
exported/public API sections for local packages and modules
- list exact exported function signatures
- list exported struct fields
- list exported enum variants and payload types
- keep non-exported functions, structs, enums, tests, and aliases out of the
public API sections
- normalize module-local concrete aliases in public docs so local alias names
do not leak across module/package boundaries
- keep Markdown layout and generated file names beta-scoped rather than stable
Released in `1.0.0-beta.11`: local file, project, package, and workspace docs
generated by `glagol doc <file|project|workspace> -o <dir>` include
deterministic public API sections with exact exported function signatures,
exported struct fields, exported enum variants/payload types, non-export
filtering, and module-local alias normalization. This extends beta10 API
discovery only; it does not freeze the Markdown schema, create a stable
stdlib/API compatibility freeze, add LSP/watch, define SARIF/daemon protocols,
set a diagnostics schema policy, implement executable generics/maps/sets, add
re-exports/globs/hierarchical modules, or define registry semantics.
Why eleventh: local packages are useful only if their public surface can be
reviewed without reading every source file, but the documentation format
should remain flexible until the package and editor stories are stronger.
## Stable `1.0.0` Gate
Slovo should not become stable until all of these are true:

View File

@ -10,11 +10,42 @@ integration/readiness release, not the first real beta.
## Unreleased
Next scoped Glagol work is expected to continue after the `1.0.0-beta.10`
developer-experience API discovery and symbol-metadata update.
Next scoped Glagol work is expected to continue after the `1.0.0-beta.11`
local package API documentation update.
No unreleased compiler scope is committed here yet.
## 1.0.0-beta.11
Release label: `1.0.0-beta.11`
Release date: 2026-05-22
Release state: local package API documentation update
### Summary
The beta.11 docs/tooling contract extends beta.10 API discovery so generated
local documentation exposes the public API of local files, projects, packages,
and workspaces without changing source-language execution semantics.
- `glagol doc <file|project|workspace> -o <dir>` includes deterministic
exported/public API sections for local modules and workspace packages.
- Public API sections render exact exported function signatures, exported
struct fields, and exported enum variants with payload types.
- Module-local concrete aliases are normalized in public docs before rendering.
- Non-exported functions, structs, enums, tests, and `(type ...)` aliases stay
out of the public API sections.
### Explicit Deferrals
This release does not define a stable Markdown schema, stable stdlib/API
compatibility freeze, an LSP server, watch mode, SARIF, daemon protocols,
diagnostics schema policy, executable generics, generic vectors, maps, sets,
iterators, re-exports, globs, hierarchical modules, package registry
semantics, runtime collection changes, new standard-library runtime APIs, or
stable ABI/layout promises.
## 1.0.0-beta.10
Release label: `1.0.0-beta.10`

View File

@ -22,8 +22,8 @@ general-purpose beta release.
A Glagol feature is done only when it has parser/lowerer support, checker behavior, diagnostics for invalid forms, backend behavior or explicit unsupported diagnostics, and tests.
Current stage: `1.0.0-beta.10`, released on 2026-05-22 as a
developer-experience API discovery and symbol-metadata update. It keeps the `1.0.0-beta`
Current stage: `1.0.0-beta.11`, released on 2026-05-22 as a local package API
documentation update. It keeps the `1.0.0-beta`
language/compiler support baseline and includes the
`1.0.0-beta.1` tooling hardening release, the `1.0.0-beta.2` runtime/resource
foundation release, the `1.0.0-beta.3` standard-library stabilization release,
@ -42,11 +42,19 @@ helper signatures after alias normalization, and adds
`glagol symbols <file.slo|project|workspace>` for deterministic
editor-facing source metadata over modules, imports, exports, aliases,
structs, enums, functions, tests, spans/ranges, and workspace package labels.
It adds no source-language runtime behavior.
The beta.11 documentation slice extends
`glagol doc <file|project|workspace> -o <dir>` with deterministic
exported/public API sections for local packages and modules, including exact
exported function signatures, exported struct fields, exported enum
variants/payload types, non-export filtering, and module-local alias
normalization. It adds no source-language runtime behavior.
Next stage target: post-`1.0.0-beta.10` developer-experience and
collection/generic planning. Generic vectors, maps, sets, generic stdlib
dispatch, runtime collection changes, and collection unification remain
Next stage target: post-`1.0.0-beta.11` developer-experience,
diagnostics-schema, package, and collection/generic planning. Generic vectors,
maps, sets, generic stdlib dispatch, runtime collection changes, collection
unification, stable Markdown schema, LSP/watch protocols, SARIF/daemon
protocols, re-exports/globs/hierarchical modules, diagnostics schema policy,
registry semantics, and a stable stdlib/API compatibility freeze remain
unimplemented until a later scoped contract promotes them explicitly.
The final experimental precursor scope is `exp-125`. Its unsigned direct-value

View File

@ -8,7 +8,7 @@ Historical `exp-*` releases listed here are experimental maturity milestones.
The pushed tag `v2.0.0-beta.1` is historical. It is now documented as an
experimental integration/readiness release, not as a beta maturity claim.
The current release is `1.0.0-beta.10`, published on 2026-05-22. It keeps the
The current release is `1.0.0-beta.11`, published on 2026-05-22. It keeps the
`1.0.0-beta` language surface, includes the first post-beta tooling/install
hardening bundle from `1.0.0-beta.1`, and adds the first runtime/resource
foundation bundle from `1.0.0-beta.2` plus the first standard-library
@ -19,13 +19,45 @@ loopback networking foundation bundle from `1.0.0-beta.6`, and the first
serialization/data-interchange foundation bundle from `1.0.0-beta.7`, and the
first concrete type alias foundation from `1.0.0-beta.8`, plus the first
collection alias unification and generic reservation slice from
`1.0.0-beta.9`, and the first developer-experience API discovery slice from
`1.0.0-beta.10`.
`1.0.0-beta.9`, the first developer-experience API discovery slice from
`1.0.0-beta.10`, and the local package API documentation extension from
`1.0.0-beta.11`.
## Unreleased
No unreleased language scope is committed here yet.
## 1.0.0-beta.11
Release label: `1.0.0-beta.11`
Release name: Local Package API Documentation
Release date: 2026-05-22
Status: released beta documentation/API-discovery update on the
`1.0.0-beta` language baseline.
`1.0.0-beta.11` extends the beta.10 API discovery lane from the generated
standard-library catalog and `glagol symbols` metadata into local package and
module documentation:
- `glagol doc <file|project|workspace> -o <dir>` includes deterministic
exported/public API sections for local source files, projects, packages, and
workspaces.
- Public API sections list exact exported function signatures, exported struct
fields, and exported enum variants with payload types.
- Module-local concrete aliases are normalized before public rendering, so
local names do not leak into package/module API docs.
- Non-exported functions, structs, enums, tests, and `(type ...)` aliases
remain omitted from the public API surface.
This release does not define a stable Markdown schema, stable stdlib/API
compatibility freeze, LSP server, watch mode, SARIF, daemon protocols,
diagnostics schema policy, executable generics, maps, sets, re-exports, globs,
hierarchical modules, package registry semantics, runtime changes, new
compiler-known runtime names, or stable ABI/layout promises.
## 1.0.0-beta.10
Release label: `1.0.0-beta.10`

View File

@ -10,8 +10,8 @@ Long-horizon planning lives in
release train from the historical `v2.0.0-beta.1` tag toward and beyond the
first real general-purpose beta Slovo contract.
Current stage: `1.0.0-beta.10`, released on 2026-05-22 as the first post-beta
developer-experience API discovery update. It keeps the `1.0.0-beta` language contract and
Current stage: `1.0.0-beta.11`, released on 2026-05-22 as a post-beta local
package API documentation update. It keeps the `1.0.0-beta` language contract and
includes the `1.0.0-beta.1` tooling hardening release, the `1.0.0-beta.2`
runtime/resource foundation release, the `1.0.0-beta.3` standard-library
stabilization release, the `1.0.0-beta.4` language-usability diagnostics
@ -24,18 +24,24 @@ inside the current concrete vector, option, and result facades, plus a
generated standard-library API catalog that lists exact exported helper
signatures with module-local aliases normalized to concrete public types, plus
`glagol symbols` deterministic source metadata for files, projects, and
workspaces. JSON
parsing, recursive JSON values, executable generics, generic aliases,
workspaces, plus `glagol doc <file|project|workspace> -o <dir>` public API
sections for local packages/modules with exact exported function signatures,
exported struct fields, exported enum variants/payload types, non-export
filtering, and module-local alias normalization. JSON parsing, recursive JSON
values, executable generics, generic aliases,
parameterized aliases, cross-module alias visibility, maps/sets, traits,
inference, monomorphization, iterators, runtime changes for generic
collections, DNS, TLS, UDP, async IO, non-loopback binding, HTTP frameworks,
rich host-error ADTs, stable ABI/layout, and a stable standard-library API
freeze remain deferred.
rich host-error ADTs, stable ABI/layout, stable Markdown schema, stable
stdlib/API compatibility freeze, LSP/watch, SARIF/daemon protocols,
diagnostics schema policy, re-exports/globs/hierarchical modules, and package
registry semantics remain deferred.
Next stage target: continue from developer-experience and reserved
generic/map/set diagnostics without claiming executable generics, an LSP/watch
protocol, or stable standard-library APIs until the exact scope is frozen from
the manifest and roadmap.
Next stage target: continue from developer-experience, diagnostics, package,
and reserved generic/map/set planning without claiming executable generics, an
LSP/watch protocol, stable Markdown schema, registry semantics, or
stable standard-library/API compatibility freeze until the exact scope is
frozen from the manifest and roadmap.
The final experimental precursor scope is `exp-125`, defined in
`.llm/EXP_125_UNSIGNED_U32_U64_NUMERIC_AND_STDLIB_BREADTH_ALPHA.md`. Its

View File

@ -2,8 +2,8 @@
Status: living beta contract for `1.0.0-beta`, with the post-beta
`1.0.0-beta.1` tooling/install update, `1.0.0-beta.2` runtime/resource
foundation update, and `1.0.0-beta.10` developer-experience API discovery
update. The language contract integrates
foundation update, `1.0.0-beta.10` developer-experience API discovery update,
and `1.0.0-beta.11` local package API documentation update. The language contract integrates
promoted language slices through `exp-125` and the historical publication
baseline through `exp-123`. `1.0.0-beta` is the first real general-purpose
beta release. `exp-125` completed the unsigned numeric and stdlib breadth
@ -129,6 +129,16 @@ Current v1 release surface and explicit experimental targets:
for files, projects, and workspaces; this is beta API discovery only, not
executable generics, maps, sets, runtime changes, LSP/watch, or a stable
`1.0.0` standard-library freeze
- `1.0.0-beta.11` local package API documentation target:
`glagol doc <file|project|workspace> -o <dir>` includes deterministic
exported/public API sections for local packages and modules with exact
exported function signatures, exported struct fields, exported enum
variants/payload types, non-export filtering, and module-local alias
normalization; this remains beta API discovery only, not a stable Markdown
schema, stable stdlib/API
compatibility freeze, LSP/watch contract, SARIF/daemon protocol, diagnostics
schema policy, executable generics, maps/sets, re-exports, globs,
hierarchical modules, or registry semantics
- `exp-1` owned runtime strings: compiler-known `std.string.concat` accepts two
`string` values and returns an immutable runtime-owned `string`; existing
string equality, length, printing, locals, parameters, returns, and calls work
@ -953,6 +963,14 @@ structs, functions, and tests. It is a documentation generator, not a semantic
reflection API, and it does not expose stable typed-core, debug metadata,
source-map, ABI, layout, runtime reflection, or compiler-internal contracts.
As of `1.0.0-beta.11`, `glagol doc <file|project|workspace> -o <dir>` also
includes deterministic exported/public API sections for local packages and
modules. These sections render exact exported function signatures, exported
struct fields, and exported enum variants with payload types. They omit
non-exported functions, structs, enums, tests, and aliases from the public API
surface and normalize module-local concrete aliases before rendering public
types.
`glagol symbols <file.slo|project|workspace>` emits deterministic
machine-readable S-expression metadata using the `slovo.symbols` schema. It
reports module paths, package labels when available, imports, exports,
@ -1075,6 +1093,25 @@ solving, package publishing, archive formats, optional/dev/target
dependencies, feature flags, package build scripts, or stable package
ABI/layout promises.
`1.0.0-beta.11` extends the generated local-package documentation surface, but
not the package model itself. `glagol doc <file|project|workspace> -o <dir>`
includes deterministic exported/public API sections for local modules and
workspace packages:
- exported functions are rendered with exact parameter and return types
- exported structs are rendered with exported field names and field types
- exported enums are rendered with exported variant names and payload types
- non-exported functions, structs, enums, tests, and `(type ...)` aliases are
excluded from the public API sections
- module-local concrete aliases are normalized to their concrete public target
types before rendering
The generated Markdown remains a beta documentation format. This does not
define a stable Markdown schema, stable stdlib/API compatibility freeze,
LSP/watch behavior, SARIF or daemon protocols, diagnostics schema policy,
executable generics, maps/sets, re-exports, glob imports, hierarchical modules,
registry semantics, runtime behavior, or stable ABI/layout.
### 4.4.4 Post-Beta Networking Foundation
Status: released in `1.0.0-beta.6`.
@ -1232,6 +1269,44 @@ generic aliases, parameterized aliases, maps, sets, traits, inference,
monomorphization, iterators, new runtime helpers, stable ABI/layout promises,
or a stable standard-library API freeze.
### 4.4.8 Post-Beta Local Package API Documentation
Status: released in `1.0.0-beta.11` as a documentation/API-discovery update on
top of the beta.10 discovery lane.
`1.0.0-beta.11` extends `glagol doc <file|project|workspace> -o <dir>` so the
generated Markdown includes deterministic exported/public API sections for
local source files, projects, packages, and workspaces. The public API surface
is derived from explicit module exports and local package boundaries.
The public API sections include:
- exact exported function signatures, including parameter names, parameter
types, and return types
- exported struct field names and field types
- exported enum variant names and payload types, including payloadless variants
and current single-payload variants
- deterministic ordering that follows the existing module/package
documentation ordering
Non-exported functions, structs, enums, tests, and `(type ...)` aliases are
not part of the public API sections. A declaration can still appear in other
source-structure summaries when those summaries already exist, but it must not
be presented as exported/public API unless the module export list exposes it.
Module-local concrete aliases are normalized before public rendering. Public
docs show concrete target types such as `(vec i32)`, `(option string)`, and
`(result u64 i32)` rather than private alias names introduced by the
documented module. This mirrors beta.10 `lib/std` catalog behavior for local
packages and modules.
This is not a stable documentation schema. It does not freeze Markdown
headings, anchors, file names, machine parsing contracts, stable stdlib/API
compatibility freeze, LSP/watch behavior, SARIF or daemon protocols,
diagnostics schema policy, executable generics, maps/sets, re-exports, glob
imports, hierarchical modules, registry semantics, runtime behavior, package
ABI, or layout.
## 4.5 v2.0.0-beta.1 Experimental Integration Readiness
Status: current experimental Slovo-side release contract, released 2026-05-17.
@ -5678,12 +5753,18 @@ manifest source root and uses deterministic v1.3 module ordering. Plain
`glagol fmt <file.slo>` continues to write formatted source to stdout.
Documentation generation records modules, imports/exports, structs, functions,
and tests as deterministic Markdown. It is generated documentation, not
runtime reflection, typed-core reflection, debug metadata, DWARF, source maps,
or ABI/layout information.
tests, and beta.11 exported/public API sections as deterministic Markdown.
Public API sections include exact exported function signatures, exported
struct fields, exported enum variants/payload types, non-export filtering, and
module-local alias normalization. It is generated documentation, not runtime
reflection, typed-core reflection, debug metadata, DWARF, source maps,
ABI/layout information, or a stable Markdown schema.
LSP, watch mode, daemon protocols, SARIF, debug adapters, stable debug
metadata, DWARF emission, and standalone source-map files remain deferred.
LSP, watch mode, daemon protocols, SARIF, debug adapters, diagnostics schema
policy, stable debug metadata, DWARF emission, standalone source-map files,
stable stdlib/API compatibility freeze, executable generics, maps/sets,
re-exports, globs, hierarchical modules, and registry semantics remain
deferred.
## 10. Slice 6: Unsafe, Memory, And FFI

View File

@ -6,7 +6,7 @@ Do not edit this file by hand.
## Stability Tiers
- `beta-supported`: exported from `lib/std` and covered by source-search, promotion, or facade gates in the current beta line.
- `experimental`: not used for exported `lib/std` helpers in `1.0.0-beta.10`; future releases may mark new helpers this way before they graduate.
- `experimental`: not used for exported `lib/std` helpers in `1.0.0-beta.11`; future releases may mark new helpers this way before they graduate.
- `internal`: helper names that are not exported from their module; they are intentionally omitted from this catalog.
The catalog is a beta API discovery aid, not a stable `1.0.0` standard-library freeze.