Release 1.0.0-beta.13 diagnostic catalog and schema policy

This commit is contained in:
sanjin 2026-05-22 21:10:37 +02:00
parent dd5302507d
commit acbe58f70e
18 changed files with 1121 additions and 67 deletions

View File

@ -0,0 +1,66 @@
# 1.0.0-beta.13 Diagnostic Catalog And Schema Policy
Status: release scope for `1.0.0-beta.13`.
`1.0.0-beta.13` is a docs/tooling-only policy slice for the existing
diagnostic surface. It keeps the `1.0.0-beta` source language, typed core,
runtime, standard library, compiler CLI, diagnostic output shape, ABI/layout,
and compiler-known runtime names unchanged.
## Scope
- Add `docs/language/DIAGNOSTICS.md` as the beta policy for
`slovo.diagnostic` version `1`.
- Document the S-expression and JSON relationship.
- Document required and optional fields, severity/source/range/related-span
semantics, JSON-line discipline, source-less diagnostics, and
artifact-manifest diagnostic metadata.
- Define diagnostic compatibility and migration classes.
- Inventory the current diagnostic codes covered by
`compiler/tests/diagnostics_contract.rs` and the matching `.diag` snapshots.
- Update README, language roadmap, language spec, release notes, migration
policy, and post-beta roadmap to introduce beta13 and link the diagnostics
policy.
## Acceptance
- `docs/language/DIAGNOSTICS.md` names schema `slovo.diagnostic` and version
`1`.
- The document is clear that S-expression diagnostics and JSON diagnostics are
encodings of the same data model.
- JSON diagnostics are documented as one object per line on stderr, without an
array wrapper or pretty-printing requirement.
- Source-less diagnostics are documented without inventing fake source spans.
- Artifact manifests are documented as carrying diagnostic schema version,
diagnostic encoding, and diagnostic stream metadata, not a second diagnostic
schema.
- Human prose is documented as beta-flexible, while machine fields, codes,
schema/version markers, ranges, JSON-line discipline, and golden fixture
shape are compatibility-sensitive.
- The code catalog is concise and derived from the current golden diagnostics
contract.
## Explicit Non-Scope
- no source-language syntax change
- no typed-core, lowering, runtime, stdlib, or ABI/layout change
- no diagnostic-output shape change
- no LSP server, watch mode, SARIF, daemon protocol, or debug adapter
- no stable Markdown schema
- no stable `1.0.0` diagnostics freeze
- no source-map, DWARF, or LLVM debug metadata contract
- no compiler-emitted diagnostic catalog artifact
- no release publication, tag, push, or version publication work
## Expected Controller Verification
- Review the policy for consistency with `compiler/src/diag.rs`,
`compiler/src/main.rs`, `compiler/tests/diagnostics_contract.rs`, and the
current `.diag` snapshots.
- Confirm the catalog count matches the current contract: 358 snapshots and
114 unique diagnostic codes.
- Run lightweight docs checks:
- `git diff --check -- README.md docs/POST_BETA_ROADMAP.md docs/language/DIAGNOSTICS.md docs/language/MIGRATION_POLICY.md docs/language/SPEC-v1.md docs/language/ROADMAP.md docs/language/RELEASE_NOTES.md .llm/BETA_13_DIAGNOSTIC_CATALOG_AND_SCHEMA_POLICY.md`
- run an `rg` check for stale beta12-only current-stage phrasing across the
same touched docs
- Do not commit, tag, push, or run release publication from this worker scope.

View File

@ -0,0 +1,64 @@
# 1.0.0-beta.13 Release Review
Status: ready for publication after controller release gate.
## Verdict
No blockers after controller catalog-count reconciliation.
## Findings
No blocking findings remain.
Controller reconciliation note: the initial review used `rg -o -h ...` for the
catalog count. On the local ripgrep version, `-h` prints help instead of
meaning "no filename", so that command mixed help text with diagnostic codes.
Using `--no-filename` gives the correct inventory: 358 `.diag` snapshots and
114 unique `(code ...)` values. The Current Golden Catalog table matches that
114-code snapshot set.
## Scope Checked
- Public docs in scope: `README.md`, `docs/POST_BETA_ROADMAP.md`,
`docs/language/DIAGNOSTICS.md`, `docs/language/MIGRATION_POLICY.md`,
`docs/language/SPEC-v1.md`, `docs/language/ROADMAP.md`,
`docs/language/RELEASE_NOTES.md`, `docs/compiler/ROADMAP.md`,
`docs/compiler/RELEASE_NOTES.md`, `docs/language/STDLIB_API.md`, and
`.llm/BETA_13_DIAGNOSTIC_CATALOG_AND_SCHEMA_POLICY.md`.
- Compiler/tooling in scope: `compiler/src/diag.rs`, `compiler/src/main.rs`,
`compiler/tests/diagnostics_schema_beta13.rs`,
`compiler/tests/diagnostics_contract.rs`, `scripts/release-gate.sh`,
`compiler/Cargo.toml`, and `compiler/Cargo.lock`.
- The compiler diff keeps diagnostic output shape limited to centralizing
`slovo.diagnostic` schema name/version constants and reusing the version in
artifact manifest diagnostics metadata.
- `docs/language/DIAGNOSTICS.md` describes the current S-expression and JSON
diagnostic shape, newline-delimited JSON stderr behavior, source-less JSON
`file:null` and `span:null`, artifact-manifest diagnostic metadata,
compatibility/migration classes, and explicit deferrals.
- Release-facing stage wording consistently points at `1.0.0-beta.13` as the
current stage and post-beta13 work as the next scope. Focused private-path
and stale current-stage beta12 checks found no matches.
## Verification Commands And Results
- `cargo fmt --check`: passed.
- `cargo test --test diagnostics_schema_beta13`: passed, 3 tests.
- `cargo test --test diagnostics_contract current_negative_cases_match_machine_diagnostic_snapshots`:
passed, 1 test.
- `git diff --check`: passed.
- `rg -o 'snapshot: "\\.\\./tests/[^"]+\\.diag"' compiler/tests/diagnostics_contract.rs | wc -l`:
`358`.
- `rg --files tests | rg '\\.diag$' | wc -l`: `358`.
- `rg --no-filename -o '\\(code [A-Za-z][A-Za-z0-9]*\\)' tests/*.diag | sed -E 's/^\\(code ([^)]+)\\)$/\\1/' | sort -u | wc -l`:
`114`.
- Comparing the unique snapshot code set with the Current Golden Catalog code
set produced no differences, confirming the catalog table itself matches the
114-code snapshot set.
- Focused `rg` check for private/local paths and stale current-stage beta12
release wording in the scoped public docs produced no matches.
- `./scripts/release-gate.sh`: passed after the beta13 release commit,
including docs/API freshness, the focused beta13 diagnostics schema test,
`cargo fmt --check`, full `cargo test`, ignored promotion gates, 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.12`.
Current release: `1.0.0-beta.13`.
## Repository Layout
@ -24,7 +24,7 @@ scripts/ local release and document tooling
## Beta Scope
`1.0.0-beta.12` keeps the `1.0.0-beta` language baseline, includes the
`1.0.0-beta.13` 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
@ -35,8 +35,9 @@ 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, plus the `1.0.0-beta.12` concrete vector query and prefix parity
slice. The language baseline supports practical local
command-line, file, and loopback-network programs with:
slice, and the `1.0.0-beta.13` diagnostic catalog and schema policy slice.
The language baseline supports practical local command-line, file, and
loopback-network programs with:
- modules, explicit imports, packages, and local workspaces
- `new`, `check`, `fmt`, `test`, `doc`, `symbols`, `build`, `run`, and
@ -65,23 +66,30 @@ types, non-export filtering, and module-local alias normalization.
The `1.0.0-beta.12` vector parity slice adds source-authored helper coverage
only: `std.vec_i64` gains `count_of`, `starts_with`, `without_prefix`,
`ends_with`, and `without_suffix`, while `std.vec_f64` gains `count_of`.
The `1.0.0-beta.13` diagnostics slice documents the beta
`slovo.diagnostic` version `1` policy in
[`docs/language/DIAGNOSTICS.md`](docs/language/DIAGNOSTICS.md): the
S-expression/JSON relationship, required and optional fields, JSON-line
discipline, source-less diagnostics, manifest diagnostic metadata,
compatibility and migration classes, and the current golden diagnostic code
catalog.
Still deferred before stable: executable generics, maps/sets, broad package
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,
mutable vectors, slice/view APIs, iterators, new compiler-known runtime names,
stable ABI and layout, performance claims, and runtime changes for generic
collections.
protocols, stable `1.0.0` diagnostics freeze, re-exports/globs/hierarchical
modules, mutable vectors, slice/view APIs, iterators, new compiler-known
runtime names, stable ABI and layout, performance claims, and runtime changes
for generic collections.
The next likely language slice after `1.0.0-beta.12` 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, mutable vectors, slice/view APIs,
new runtime names, or performance claims until the contract and gates are
explicit.
The next likely language slice after `1.0.0-beta.13` should continue from the
developer-experience, package, and reserved generic/collection lanes without
claiming executable generics, maps, sets, traits, inference, monomorphization,
iterators, ABI stability, runtime changes, LSP/watch protocols, SARIF/daemon
protocols, registry semantics, stable Markdown schema, a stable `1.0.0`
diagnostics freeze, standard-library/API compatibility freeze, mutable
vectors, slice/view APIs, new runtime names, or performance claims until the
contract and gates are explicit.
## Build And Test
@ -307,10 +315,28 @@ maps/sets, iterators, mutable vectors, slice/view APIs, new runtime helper
names, stable stdlib API freeze, and broader collection abstractions remain
deferred.
## 1.0.0-beta.13 Diagnostic Catalog And Schema Policy
The `1.0.0-beta.13` release is a docs/tooling policy update for the existing
diagnostic surface. It adds
[`docs/language/DIAGNOSTICS.md`](docs/language/DIAGNOSTICS.md) as the beta
policy for `slovo.diagnostic` version `1`.
The policy documents the S-expression and JSON encodings, required and optional
machine fields, severity/source/range/related-span semantics, JSON-line
discipline, source-less diagnostics, artifact-manifest diagnostic metadata,
compatibility and migration classes, and the current code catalog covered by
the golden diagnostics contract.
This release does not change the source language, runtime, stdlib API,
diagnostic output shape, compiler CLI, LSP/watch behavior, SARIF/daemon
protocols, stable Markdown schema, or stable `1.0.0` diagnostics freeze.
## Documentation
- [Language Manifest](docs/language/MANIFEST.md)
- [Language Specification](docs/language/SPEC-v1.md)
- [Diagnostics Policy](docs/language/DIAGNOSTICS.md)
- [Local Package And Workspace Guide](docs/language/PACKAGES.md)
- [Standard Library API Catalog](docs/language/STDLIB_API.md)
- [Compiler Manifest](docs/compiler/GLAGOL_COMPILER_MANIFEST.md)

2
compiler/Cargo.lock generated
View File

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

View File

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

View File

@ -1,5 +1,8 @@
use crate::token::Span;
pub const DIAGNOSTIC_SCHEMA_NAME: &str = "slovo.diagnostic";
pub const DIAGNOSTIC_SCHEMA_VERSION: u32 = 1;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Severity {
Error,
@ -184,8 +187,8 @@ impl Diagnostic {
) -> String {
let source = source_for(&self.file).unwrap_or("");
let mut parts = vec![
" (schema slovo.diagnostic)".to_string(),
" (version 1)".to_string(),
format!(" (schema {})", DIAGNOSTIC_SCHEMA_NAME),
format!(" (version {})", DIAGNOSTIC_SCHEMA_VERSION),
format!(" (severity {})", self.severity.as_str()),
format!(" (code {})", self.code),
format!(" (message {})", render_string(&self.message)),
@ -310,8 +313,8 @@ fn render_json_diagnostic<'a>(
related: impl Iterator<Item = JsonRelated<'a>>,
) -> String {
let mut fields = vec![
"\"schema\":\"slovo.diagnostic\"".to_string(),
"\"version\":1".to_string(),
format!("\"schema\":{}", render_json_string(DIAGNOSTIC_SCHEMA_NAME)),
format!("\"version\":{}", DIAGNOSTIC_SCHEMA_VERSION),
format!("\"severity\":{}", render_json_string(severity)),
format!("\"code\":{}", render_json_string(code)),
format!("\"message\":{}", render_json_string(message)),

View File

@ -1977,7 +1977,10 @@ fn render_manifest(
" (success {})\n",
if success { "true" } else { "false" }
));
out.push_str(" (diagnostics-schema-version 1)\n");
out.push_str(&format!(
" (diagnostics-schema-version {})\n",
diag::DIAGNOSTIC_SCHEMA_VERSION
));
out.push_str(&format!(
" (diagnostics-encoding {})\n",
match diagnostics {

View File

@ -0,0 +1,486 @@
use std::{
ffi::OsStr,
fs,
path::{Path, PathBuf},
process::{Command, Output},
sync::atomic::{AtomicUsize, Ordering},
};
static NEXT_FIXTURE_ID: AtomicUsize = AtomicUsize::new(0);
#[test]
fn sexpr_diagnostics_keep_v1_schema_across_source_pipelines() {
let cases = [
SourceDiagnosticCase {
name: "parse",
args: &["check"],
source: "(module main",
code: "UnclosedList",
},
SourceDiagnosticCase {
name: "check",
args: &["check"],
source: r#"
(module main)
(fn id ((value i32)) -> i32
value)
(fn main () -> i32
(id true))
"#,
code: "TypeMismatch",
},
SourceDiagnosticCase {
name: "fmt",
args: &["fmt"],
source: r#"
(module main) ; comments stay outside formatter input
(fn main () -> i32
0)
"#,
code: "UnsupportedFormatterComment",
},
SourceDiagnosticCase {
name: "test",
args: &["test"],
source: r#"
(module main)
(test "false case"
false)
"#,
code: "TestFailed",
},
];
for case in cases {
let fixture = write_fixture(case.name, case.source);
let mut args = case.args.iter().map(OsStr::new).collect::<Vec<_>>();
args.push(fixture.as_os_str());
let output = run_glagol(args);
assert_exit_code(case.name, &output, 1);
assert_stdout_empty(case.name, &output);
assert_sexpr_diagnostic_schema(case.name, &output, case.code, 1);
}
let project = write_project(
"sexpr-project",
"(module main)\n\n(import missing (value))\n",
);
let output = run_glagol(["check".as_ref(), project.as_os_str()]);
assert_exit_code("project", &output, 1);
assert_stdout_empty("project", &output);
assert_sexpr_diagnostic_schema("project", &output, "MissingImport", 1);
}
#[test]
fn json_diagnostics_keep_v1_schema_across_policy_boundaries() {
let cases = [
SourceDiagnosticCase {
name: "json-parse",
args: &["--json-diagnostics", "check"],
source: "(module main",
code: "UnclosedList",
},
SourceDiagnosticCase {
name: "json-check",
args: &["--json-diagnostics", "check"],
source: r#"
(module main)
(fn id ((value i32)) -> i32
value)
(fn main () -> i32
(id true))
"#,
code: "TypeMismatch",
},
SourceDiagnosticCase {
name: "json-fmt",
args: &["--json-diagnostics", "fmt"],
source: r#"
(module main) ; comments stay outside formatter input
(fn main () -> i32
0)
"#,
code: "UnsupportedFormatterComment",
},
SourceDiagnosticCase {
name: "json-test",
args: &["--json-diagnostics", "test"],
source: r#"
(module main)
(test "false case"
false)
"#,
code: "TestFailed",
},
];
for case in cases {
let fixture = write_fixture(case.name, case.source);
let mut args = case.args.iter().map(OsStr::new).collect::<Vec<_>>();
args.push(fixture.as_os_str());
let output = run_glagol(args);
assert_exit_code(case.name, &output, 1);
assert_stdout_empty(case.name, &output);
assert_json_diagnostic_schema(case.name, &output, case.code, JsonSource::Source);
}
let project = write_project(
"json-project",
"(module main)\n\n(import missing (value))\n",
);
let output = run_glagol([
"--json-diagnostics".as_ref(),
"check".as_ref(),
project.as_os_str(),
]);
assert_exit_code("json project", &output, 1);
assert_stdout_empty("json project", &output);
assert_json_diagnostic_schema("json project", &output, "MissingImport", JsonSource::Source);
let usage_manifest = temp_path("json-usage", "manifest.slo");
let usage = run_glagol([
"--json-diagnostics".as_ref(),
"--manifest".as_ref(),
usage_manifest.as_os_str(),
]);
assert_exit_code("json usage", &usage, 2);
assert_stdout_empty("json usage", &usage);
assert_json_diagnostic_schema("json usage", &usage, "UsageError", JsonSource::SourceLess);
assert_manifest_schema_fields(&read_manifest(&usage_manifest), "json");
let toolchain_fixture = write_fixture(
"json-toolchain",
"(module main)\n\n(fn main () -> i32\n 0)\n",
);
let toolchain_manifest = temp_path("json-toolchain", "manifest.slo");
let output_path = temp_path("json-toolchain", "bin");
let missing_clang = temp_path("json-toolchain", "not-a-clang");
let toolchain = Command::new(compiler_path())
.arg("--json-diagnostics")
.arg("build")
.arg(&toolchain_fixture)
.arg("-o")
.arg(&output_path)
.arg("--manifest")
.arg(&toolchain_manifest)
.env("GLAGOL_CLANG", &missing_clang)
.env_remove("GLAGOL_RUNTIME_C")
.env_remove("SLOVO_RUNTIME_C")
.output()
.unwrap_or_else(|err| panic!("run glagol build: {}", err));
assert_exit_code("json toolchain", &toolchain, 3);
assert_stdout_empty("json toolchain", &toolchain);
assert_json_diagnostic_schema(
"json toolchain",
&toolchain,
"ToolchainUnavailable",
JsonSource::SourceLess,
);
assert_manifest_schema_fields(&read_manifest(&toolchain_manifest), "json");
}
#[test]
fn project_failure_manifests_record_schema_encoding_and_count_deterministically() {
let project = write_project(
"manifest-project",
"(module main)\n\n(import missing (value))\n",
);
let first_sexpr = run_project_failure_manifest(&project, "sexpr", false);
let second_sexpr = run_project_failure_manifest(&project, "sexpr-repeat", false);
assert_manifest_schema_fields(&first_sexpr, "sexpr");
assert_project_diagnostics_count(&first_sexpr, 1);
assert_eq!(
project_block(&first_sexpr),
project_block(&second_sexpr),
"S-expression failure manifest project block drifted"
);
let first_json = run_project_failure_manifest(&project, "json", true);
let second_json = run_project_failure_manifest(&project, "json-repeat", true);
assert_manifest_schema_fields(&first_json, "json");
assert_project_diagnostics_count(&first_json, 1);
assert_eq!(
project_block(&first_json),
project_block(&second_json),
"JSON failure manifest project block drifted"
);
}
struct SourceDiagnosticCase {
name: &'static str,
args: &'static [&'static str],
source: &'static str,
code: &'static str,
}
#[derive(Copy, Clone)]
enum JsonSource {
Source,
SourceLess,
}
fn run_project_failure_manifest(project: &Path, name: &str, json: bool) -> String {
let manifest = temp_path(name, "manifest.slo");
let output = if json {
run_glagol([
"--json-diagnostics".as_ref(),
"check".as_ref(),
"--manifest".as_ref(),
manifest.as_os_str(),
project.as_os_str(),
])
} else {
run_glagol([
"check".as_ref(),
"--manifest".as_ref(),
manifest.as_os_str(),
project.as_os_str(),
])
};
assert_exit_code(name, &output, 1);
assert_stdout_empty(name, &output);
read_manifest(&manifest)
}
fn assert_sexpr_diagnostic_schema(
context: &str,
output: &Output,
expected_code: &str,
expected_count: usize,
) {
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
!stderr.trim().is_empty(),
"{} did not emit diagnostics",
context
);
assert!(
!stderr
.lines()
.all(|line| line.starts_with('{') && line.ends_with('}')),
"{} unexpectedly emitted JSON diagnostics:\n{}",
context,
stderr
);
assert_eq!(
stderr.matches("(diagnostic\n").count(),
expected_count,
"{} diagnostic block count drifted:\n{}",
context,
stderr
);
assert_eq!(
stderr.matches(" (schema slovo.diagnostic)\n").count(),
expected_count,
"{} diagnostic schema name drifted:\n{}",
context,
stderr
);
assert_eq!(
stderr.matches(" (version 1)\n").count(),
expected_count,
"{} diagnostic schema version drifted:\n{}",
context,
stderr
);
assert!(
stderr.contains(" (severity error)\n")
&& stderr.contains(&format!(" (code {})\n", expected_code))
&& stderr.contains(" (file ")
&& stderr.contains(" (span\n"),
"{} S-expression diagnostic missed required structural fields:\n{}",
context,
stderr
);
}
fn assert_json_diagnostic_schema(
context: &str,
output: &Output,
expected_code: &str,
source: JsonSource,
) {
let stderr = String::from_utf8_lossy(&output.stderr);
let lines = stderr
.lines()
.filter(|line| !line.trim().is_empty())
.collect::<Vec<_>>();
assert!(!lines.is_empty(), "{} did not emit diagnostics", context);
for line in &lines {
assert!(
line.starts_with('{') && line.ends_with('}'),
"{} emitted non-JSON diagnostic text:\n{}",
context,
stderr
);
assert!(
line.contains(r#""schema":"slovo.diagnostic""#)
&& line.contains(r#""version":1"#)
&& line.contains(r#""severity":"error""#)
&& line.contains(r#""message":"#)
&& line.contains(r#""file":"#)
&& line.contains(r#""span":"#),
"{} JSON diagnostic missed required schema fields:\n{}",
context,
line
);
}
assert!(
lines
.iter()
.any(|line| line.contains(&format!(r#""code":"{}""#, expected_code))),
"{} JSON diagnostics did not include code `{}`:\n{}",
context,
expected_code,
stderr
);
match source {
JsonSource::Source => assert!(
lines
.iter()
.any(|line| line.contains(r#""span":{"byte_start":"#)),
"{} JSON diagnostics should include a concrete source span:\n{}",
context,
stderr
),
JsonSource::SourceLess => assert!(
lines
.iter()
.any(|line| line.contains(r#""file":null"#) && line.contains(r#""span":null"#)),
"{} JSON diagnostics should be source-less:\n{}",
context,
stderr
),
}
}
fn assert_manifest_schema_fields(manifest: &str, encoding: &str) {
assert!(
manifest.contains(" (schema slovo.artifact-manifest)\n")
&& manifest.contains(" (version 1)\n")
&& manifest.contains(" (diagnostics-schema-version 1)\n")
&& manifest.contains(&format!(" (diagnostics-encoding {})\n", encoding))
&& manifest.contains("slovo.diagnostic"),
"manifest diagnostic schema fields drifted:\n{}",
manifest
);
}
fn assert_project_diagnostics_count(manifest: &str, expected: usize) {
assert!(
manifest.contains(&format!(" (diagnostics_count {})\n", expected)),
"manifest diagnostics count drifted:\n{}",
manifest
);
}
fn project_block(manifest: &str) -> &str {
let start = manifest
.find(" (project\n")
.expect("manifest did not contain project block");
manifest[start..]
.strip_suffix("\n)\n")
.expect("manifest did not end with artifact-manifest close")
}
fn run_glagol<I, S>(args: I) -> Output
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
Command::new(compiler_path())
.args(args)
.output()
.unwrap_or_else(|err| panic!("run glagol: {}", err))
}
fn compiler_path() -> &'static str {
env!("CARGO_BIN_EXE_glagol")
}
fn write_fixture(name: &str, source: &str) -> PathBuf {
let path = temp_path(name, "slo");
fs::write(&path, source).unwrap_or_else(|err| panic!("write `{}`: {}", path.display(), err));
path
}
fn write_project(name: &str, main_source: &str) -> PathBuf {
let root = temp_dir(name);
let source_root = root.join("src");
fs::create_dir_all(&source_root)
.unwrap_or_else(|err| panic!("create `{}`: {}", source_root.display(), err));
fs::write(
root.join("slovo.toml"),
"[project]\nname = \"beta13\"\nsource_root = \"src\"\nentry = \"main\"\n",
)
.unwrap_or_else(|err| panic!("write project manifest: {}", err));
fs::write(source_root.join("main.slo"), main_source)
.unwrap_or_else(|err| panic!("write main source: {}", err));
root
}
fn read_manifest(path: &Path) -> String {
fs::read_to_string(path).unwrap_or_else(|err| panic!("read `{}`: {}", path.display(), err))
}
fn temp_path(name: &str, extension: &str) -> PathBuf {
let mut path = std::env::temp_dir();
let id = NEXT_FIXTURE_ID.fetch_add(1, Ordering::Relaxed);
path.push(format!(
"glagol-beta13-{}-{}-{}.{}",
std::process::id(),
id,
name,
extension,
));
path
}
fn temp_dir(name: &str) -> PathBuf {
let mut path = std::env::temp_dir();
let id = NEXT_FIXTURE_ID.fetch_add(1, Ordering::Relaxed);
path.push(format!(
"glagol-beta13-{}-{}-{}",
std::process::id(),
id,
name,
));
path
}
fn assert_exit_code(context: &str, output: &Output, expected: i32) {
assert_eq!(
output.status.code(),
Some(expected),
"{} exit code mismatch\nstdout:\n{}\nstderr:\n{}",
context,
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
}
fn assert_stdout_empty(context: &str, output: &Output) {
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.is_empty(), "{} wrote stdout:\n{}", context, stdout);
}

View File

@ -348,6 +348,37 @@ Why twelfth: concrete vectors are already broad enough that parity gaps create
surprising differences, and source-authored helpers can close those gaps
without committing to generic collection design.
### 13. Diagnostic Catalog And Schema Policy
Goal: document the existing diagnostic machine contract before larger tooling
or editor-facing slices depend on it.
Work:
- add [`docs/language/DIAGNOSTICS.md`](language/DIAGNOSTICS.md) as the beta
`slovo.diagnostic` version `1` policy
- document the S-expression and JSON encodings, required and optional fields,
severity/source/range/related-span semantics, JSON-line discipline,
source-less diagnostics, and artifact-manifest diagnostic metadata
- classify diagnostic changes as clarifying, additive, or migration-level,
with human prose remaining beta-flexible unless machine fields, schema
markers, codes, or golden fixture shape change intentionally
- inventory the current diagnostic codes covered by
`compiler/tests/diagnostics_contract.rs` and the matching `.diag` snapshots
- keep LSP/watch, SARIF, daemon protocols, stable Markdown schema, stable
`1.0.0` diagnostics freeze, and runtime/source-language changes out of scope
Released in `1.0.0-beta.13`:
[`docs/language/DIAGNOSTICS.md`](language/DIAGNOSTICS.md) now defines the beta
diagnostic schema policy and catalogs the current golden diagnostic codes. The
release is documentation/tooling policy only; it does not change Glagol
diagnostic output, the source language, runtime, stdlib/API surface, or
ABI/layout behavior.
Why thirteenth: diagnostics already have a machine schema and broad golden
coverage, but the compatibility policy and current code inventory need one
central reference before future tooling or migration work builds on them.
## Stable `1.0.0` Gate
Slovo should not become stable until all of these are true:

View File

@ -10,11 +10,45 @@ integration/readiness release, not the first real beta.
## Unreleased
Next scoped Glagol work is expected to continue after the `1.0.0-beta.12`
concrete vector query and prefix parity update.
Next scoped Glagol work is expected to continue after the `1.0.0-beta.13`
diagnostic catalog and schema policy hardening update.
No unreleased compiler scope is committed here yet.
## 1.0.0-beta.13
Release label: `1.0.0-beta.13`
Release date: 2026-05-22
Release state: diagnostic catalog and schema policy hardening update
### Summary
The beta.13 compiler-side contract is tooling/docs-only diagnostics policy
hardening. It keeps emitted diagnostic machine shapes stable while making the
schema name/version a single compiler constant source and gating the current
policy with focused structural tests.
- Bump the `glagol` compiler package version to `1.0.0-beta.13`.
- Centralize the `slovo.diagnostic` schema name and version used by
S-expression rendering and newline-delimited JSON diagnostics, and use the
same schema version in artifact manifest diagnostics metadata.
- Add focused `diagnostics_schema_beta13` coverage for parse, check,
formatter, test-runner, project, source-less usage, toolchain, and manifest
diagnostic policy across S-expression and `--json-diagnostics` outputs.
- Require artifact manifests to keep recording diagnostics schema version,
diagnostics encoding, and project diagnostic counts deterministically.
- Run the focused beta.13 diagnostics schema test in `scripts/release-gate.sh`
before the full compiler test suite.
### Explicit Deferrals
This release does not implement LSP, watch mode, SARIF, daemon protocols,
stable human diagnostic text, a stable Markdown schema, generic collections,
generic vectors, maps, sets, runtime changes, ABI changes, source-language
expansion, standard-library/API expansion, or performance claims.
## 1.0.0-beta.12
Release label: `1.0.0-beta.12`

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.12`, released on 2026-05-22 as a concrete vector
query and prefix parity update. It keeps the `1.0.0-beta`
Current stage: `1.0.0-beta.13`, released on 2026-05-22 as a diagnostic
catalog and schema policy hardening 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,
@ -51,15 +51,19 @@ normalization. The beta.12 stdlib/helper parity slice adds source-authored
coverage for `std.vec_i64.count_of`, `std.vec_i64.starts_with`,
`std.vec_i64.without_prefix`, `std.vec_i64.ends_with`,
`std.vec_i64.without_suffix`, and `std.vec_f64.count_of` without changing
source-language runtime behavior.
source-language runtime behavior. The beta.13 tooling/docs-only diagnostics
slice centralizes the `slovo.diagnostic` schema name/version constants and
adds structural gates for S-expression diagnostics, `--json-diagnostics`, and
artifact-manifest diagnostics metadata without changing emitted machine
diagnostic shape.
Next stage target: post-`1.0.0-beta.12` 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, mutable vectors, slice/view APIs, new runtime names,
iterators, performance claims, ABI/layout stability, and a stable stdlib/API
Next stage target: post-`1.0.0-beta.13` developer-experience, package, and
collection/generic planning. Generic vectors, generic collections, maps, sets,
generic stdlib dispatch, runtime collection changes, collection unification,
stable human diagnostic text, stable Markdown schema, LSP/watch protocols,
SARIF/daemon protocols, re-exports/globs/hierarchical modules, registry
semantics, mutable vectors, slice/view APIs, new runtime names, iterators,
performance claims, ABI/layout stability, and a stable stdlib/API
compatibility freeze remain unimplemented until a later scoped contract
promotes them explicitly.

View File

@ -0,0 +1,253 @@
# Slovo Diagnostics
This document defines the `1.0.0-beta.13` beta policy for Slovo machine
diagnostics. It documents the existing `slovo.diagnostic` version `1` schema,
the relationship between the S-expression and JSON encodings, the current
golden diagnostic code catalog, and the migration rules for changing machine
diagnostic fields or codes.
This is a diagnostics policy and catalog slice only. It does not add source
language syntax, runtime behavior, stdlib APIs, ABI/layout guarantees, LSP,
watch mode, SARIF, daemon protocols, stable Markdown output, or a stable
`1.0.0` diagnostics freeze.
## Schema Identity
The machine diagnostic schema name is `slovo.diagnostic`.
The current schema version is `1`.
The S-expression form uses a root `(diagnostic ...)` object:
```text
(diagnostic
(schema slovo.diagnostic)
(version 1)
...)
```
The JSON form uses a single JSON object:
```json
{"schema":"slovo.diagnostic","version":1}
```
The schema name and version belong to the machine contract. Changing either one
requires an explicit migration note, release-note entry, and matching Glagol
snapshot or JSON fixture updates.
## Encodings
S-expression diagnostics and JSON diagnostics are two encodings of the same
diagnostic data model. They must not diverge semantically.
The default human diagnostics path may print human-readable prose and then the
S-expression machine form for source diagnostics. Human prose, spacing,
excerpts, hints, and surrounding text remain beta-flexible unless a later
release freezes them explicitly. Tools should consume the machine form, not the
human rendering.
`--json-diagnostics` emits JSON diagnostics on stderr. Each diagnostic is one
complete JSON object on one line. There is no JSON array wrapper, no pretty
printing, and no required trailing summary object for source failures. Consumers
should parse stderr as newline-delimited JSON objects and should treat each
line as an independent diagnostic record.
JSON and S-expression escaping must preserve the same string values. JSON uses
standard JSON string escaping. S-expression strings use the Glagol diagnostic
string escaping convention already used in golden `.diag` fixtures.
## Fields
Every source-attached compiler diagnostic must include these machine fields:
| Field | S-expression | JSON | Meaning |
| --- | --- | --- | --- |
| Schema | `(schema slovo.diagnostic)` | `"schema":"slovo.diagnostic"` | Diagnostic schema name. |
| Version | `(version 1)` | `"version":1` | Diagnostic schema version. |
| Severity | `(severity error)` | `"severity":"error"` | Diagnostic severity. |
| Code | `(code TypeMismatch)` | `"code":"TypeMismatch"` | Stable PascalCase diagnostic code for the condition. |
| Message | `(message "...")` | `"message":"..."` | Concise beta-flexible human message for the machine record. |
| Source file | `(file "...")` | `"file":"..."` | Source identity used by the invocation or project loader. |
| Span | `(span ...)` | `"span":{...}` | Primary source span and line/column range. |
Optional fields may appear when the compiler has precise data:
| Field | S-expression | JSON | Meaning |
| --- | --- | --- | --- |
| Expected | `(expected "...")` | `"expected":"..."` | Expected type, arity, value, or form. |
| Found | `(found "...")` | `"found":"..."` | Found type, arity, value, or form. |
| Hint | `(hint "...")` | `"hint":"..."` | Safe repair or orientation hint. |
| Related spans | repeated `(related ...)` | `"related":[...]` | Secondary source locations tied to the primary diagnostic. |
Optional fields are additive when they do not replace an existing machine field
or change an existing diagnostic code. Removing an optional field from an
existing golden fixture is a migration-level change unless the release note
states that the previous field was incorrect.
## Severity
Current source diagnostics use severity `error`.
JSON source-less or invocation-level messages may use `error` for failures and
`note` for informational tool output such as a machine-readable test-run
summary. A `note` is not by itself a source failure; consumers should still use
the process exit code and artifact manifest success field to determine command
success.
Adding a new severity value is an additive schema change only when old
consumers can safely ignore or display it. Reclassifying an existing failing
diagnostic from `error` to another severity is migration-level.
## Source And Range Semantics
`file` is the source identity reported by the compiler path, project loader, or
workspace loader. It is not a promise of absolute path normalization, URI
formatting, registry identity, or editor document identity.
Primary and related byte spans are zero-based and half-open: `start` is the
first byte included, and `end` is the first byte after the highlighted source.
Line and column ranges are one-based and derived from the original source text.
Columns are byte columns within the original UTF-8 source line; a tab counts as
one input byte. The end column is the first byte column after the highlighted
range on the end line.
Diagnostic locations are derived from source input, not formatter output,
lowered IR, generated C, LLVM IR, native object code, or runtime stack traces.
## Related Spans
Related spans identify secondary source locations such as an original
declaration, previous duplicate, or conflicting arm. A related span never
replaces the primary span.
In S-expression diagnostics, each related location is a repeated
`(related (span ...))` form. In JSON diagnostics, related locations are objects
inside the `related` array. Each related object has its own `file` and `span`;
it may also carry a `message` string.
Related messages are beta-flexible prose. The existence of a related span for a
current golden fixture is part of the machine shape for that fixture and should
change only intentionally.
## Source-Less Diagnostics
Some diagnostics describe tool invocation or usage failures rather than a
source range. Examples include invalid CLI arguments, missing inputs, and
source-loading failures before a source span is available.
JSON source-less diagnostics use:
```json
{"file":null,"span":null}
```
Source-less diagnostics must not invent dummy paths, byte offsets, or
line/column ranges. Text-mode source-less diagnostics may remain human-only in
current Glagol output; consumers that need machine-readable source-less
diagnostics should request `--json-diagnostics`.
If a future release adds S-expression source-less diagnostics, absence of a
source must be explicit and documented under `slovo.diagnostic` version `1` or
a later migrated version. It must not be encoded as fake source coordinates.
## Artifact Manifest Metadata
`slovo.artifact-manifest` records the diagnostic metadata for a tool
invocation. The relevant fields are:
- `(diagnostics-schema-version 1)`: the diagnostic schema version used by the
invocation.
- `(diagnostics-encoding sexpr)` or `(diagnostics-encoding json)`: the encoding
selected for diagnostics.
- `(primary-output (kind diagnostics) ...)`: the primary output kind when the
command failed by emitting diagnostics.
- `(diagnostic_artifacts ...)`: the diagnostic stream artifact metadata for
project/package/workspace modes.
- `(diagnostics_count N)`: the project-level count when available.
The manifest points to or records diagnostic streams. It does not define a
separate diagnostic schema, embed a parsed diagnostic catalog, freeze Markdown
documentation structure, or replace the newline discipline of JSON diagnostic
stderr.
## Compatibility And Migration
Diagnostic changes are classified as follows.
Clarifying changes:
- Rewording human-readable stderr prose.
- Rewording `message` or `hint` text without changing the diagnostic code,
source span, field set, severity, or expected/found semantics.
- Improving documentation around an existing code or fixture.
Additive changes:
- Adding a new diagnostic code for a newly covered boundary.
- Adding a new golden fixture for a newly rejected form.
- Adding an optional field when the old fields, code, severity, source span,
and JSON-line discipline remain valid.
- Adding related spans for a new fixture.
Migration changes:
- Renaming, removing, splitting, or merging an existing diagnostic code covered
by golden fixtures.
- Changing required field names, schema name, schema version, span shape, range
indexing, JSON null policy, or JSON-line discipline.
- Removing an existing optional field or related span from a golden fixture
without documenting the correction.
- Changing a source-attached diagnostic into a source-less diagnostic, or the
reverse, for an existing golden fixture.
- Reclassifying an existing failing diagnostic away from severity `error`.
- Changing artifact manifest diagnostic metadata fields or their meaning.
Every migration-level diagnostic change must update this document or the next
release policy, `docs/language/MIGRATION_POLICY.md` if needed,
`docs/language/RELEASE_NOTES.md`, and the matching Glagol golden snapshots or
tests.
## Current Golden Catalog
The current golden diagnostics contract is the snapshot inventory in
`compiler/tests/diagnostics_contract.rs`. As of `1.0.0-beta.13`, that contract
references 358 `.diag` snapshots under `tests/`, and those snapshots contain
114 unique diagnostic codes.
This catalog inventories those codes. It is policy-focused: messages and
fixture-specific prose remain in the snapshots.
| Area | Current codes |
| --- | --- |
| General calls, typing, signatures, and source shape | `ArityMismatch`, `ReturnTypeMismatch`, `SingleFileMainSignature`, `TypeMismatch`, `UnclosedList`, `UnknownFunction`, `UnknownTopLevelForm`, `UnsupportedBackendFeature`, `UnsupportedUnitSignatureType` |
| Control flow and tests | `EmptyWhileBody`, `IfBranchTypeMismatch`, `IfConditionNotBool`, `MalformedIfForm`, `MalformedTestForm`, `MalformedWhileForm`, `NestedWhileUnsupported`, `TestExpressionNotBool`, `WhileBodyFormNotUnit`, `WhileConditionNotBool` |
| Literals and strings | `I64LiteralOutOfRange`, `IntegerOutOfRange`, `InvalidI64Literal`, `UnsupportedFloatLiteral`, `UnsupportedStringConcatenation`, `UnsupportedStringEscape`, `UnsupportedStringLiteral` |
| Locals, assignment, and name conflicts | `CannotAssignImmutableLocal`, `CannotAssignParameter`, `DuplicateFunction`, `DuplicateLocal`, `DuplicateTestName`, `InvalidSetTarget`, `InvalidTestName`, `LocalDeclarationInWhileBodyUnsupported`, `LocalDeclarationNotAllowed`, `LocalRedeclaresParameter`, `LocalShadowsCallable`, `ParameterShadowsCallable`, `UnknownVariable`, `UnsupportedLocalType` |
| Type aliases, generics, maps, and sets | `DuplicateTypeAlias`, `MalformedTypeAlias`, `SelfTypeAlias`, `TypeAliasCycle`, `TypeAliasNameConflict`, `UnknownTypeAliasTarget`, `UnsupportedGenericFunction`, `UnsupportedGenericStandardLibraryCall`, `UnsupportedGenericTypeAlias`, `UnsupportedGenericTypeParameter`, `UnsupportedMapType`, `UnsupportedSetType`, `UnsupportedTypeAliasTarget` |
| Structs and fields | `DuplicateStruct`, `DuplicateStructConstructorField`, `DuplicateStructField`, `EmptyStructUnsupported`, `FieldAccessOnNonStruct`, `MissingStructField`, `RecursiveStructFieldUnsupported`, `StructConstructorFieldOrderMismatch`, `UnknownStructField`, `UnknownStructType`, `UnsupportedStructFieldType` |
| Arrays and vectors | `ArrayIndexNotI32`, `ArrayIndexOutOfBounds`, `EmptyArrayUnsupported`, `IndexOnNonArray`, `MutableArrayLocalUnsupported`, `UnsupportedArrayElementType`, `UnsupportedArrayEquality`, `UnsupportedArrayPrint`, `UnsupportedVectorElementType`, `UnsupportedVectorEquality`, `ZeroLengthArrayUnsupported` |
| Options, results, and match | `DuplicateMatchArm`, `MalformedMatchPattern`, `MalformedOptionConstructor`, `MalformedResultConstructor`, `MalformedUnwrapForm`, `MatchArmTypeMismatch`, `MatchBindingCollision`, `MatchSubjectTypeMismatch`, `NonExhaustiveMatch`, `OptionObservationTypeMismatch`, `OptionUnwrapTypeMismatch`, `ResultObservationTypeMismatch`, `ResultUnwrapTypeMismatch`, `UnsupportedMatchContainer`, `UnsupportedMatchMutation`, `UnsupportedMatchPayloadType`, `UnsupportedOptionPayloadType`, `UnsupportedOptionResultEquality`, `UnsupportedOptionResultPrint`, `UnsupportedResultPayloadType` |
| Enums | `DuplicateEnum`, `DuplicateEnumVariant`, `EmptyEnumUnsupported`, `EnumSubjectMismatch`, `InvalidEnumMatchArm`, `MixedEnumPayloadTypesUnsupported`, `RecursiveEnumPayloadStructUnsupported`, `UnknownEnumConstructor`, `UnknownVariantConstructor`, `UnsupportedEnumContainer`, `UnsupportedEnumEquality`, `UnsupportedEnumOrdering`, `UnsupportedEnumPayloadType`, `UnsupportedEnumPrint`, `VariantConstructorArity` |
| Unsafe operations | `MalformedUnsafeForm`, `UnsafeRequired`, `UnsupportedUnsafeOperation` |
| Standard-library reservation boundaries | `UnsupportedStandardLibraryCall` |
Future releases may add codes or split broad codes when the release scope
requires more precise tooling behavior. Such changes must be documented using
the compatibility classes above.
## Explicit Deferrals
`1.0.0-beta.13` does not define:
- a stable `1.0.0` diagnostics freeze
- LSP diagnostics, watch mode, SARIF, daemon protocols, or debug adapters
- a stable Markdown documentation schema
- stable source-map, DWARF, LLVM debug metadata, or runtime stack trace schema
- warning, lint, or suggestion taxonomies beyond the current `error` and
source-less `note` uses
- localized diagnostic text
- machine-readable remediation edits
- a separate diagnostic catalog artifact emitted by the compiler
- stable package registry, URI, or workspace identity semantics for `file`

View File

@ -46,10 +46,18 @@ Slovo must not silently repurpose an old supported form with new meaning.
## Diagnostic And Tooling Changes
Diagnostic code or machine-shape changes require a documented schema migration
and matching Glagol snapshot updates. Formatter changes require before/after
fixture coverage so agents can see whether the change is additive,
clarifying, or migration-level.
[`docs/language/DIAGNOSTICS.md`](DIAGNOSTICS.md) is the beta policy for
`slovo.diagnostic` version `1`. Human-readable diagnostic prose remains
beta-flexible, but machine fields, schema/version markers, diagnostic codes,
source/span/range semantics, JSON-line discipline, related-span shape, and
artifact-manifest diagnostic metadata are compatibility-sensitive.
Diagnostic code or machine-shape changes require the compatibility class
defined in [`docs/language/DIAGNOSTICS.md`](DIAGNOSTICS.md), a documented
schema or catalog migration when the change is migration-level, and matching
Glagol snapshot updates. Formatter changes require before/after fixture
coverage so agents can see whether the change is additive, clarifying, or
migration-level.
Native executable output, package layout, stable ABI/layout promises, stable
standard-runtime printing APIs, and raw-memory/FFI contracts remain outside the

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.12`, published on 2026-05-22. It keeps the
The current release is `1.0.0-beta.13`, 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
@ -22,12 +22,44 @@ collection alias unification and generic reservation slice from
`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`, plus the concrete vector query and prefix parity slice from
`1.0.0-beta.12`.
`1.0.0-beta.12`, and the diagnostic catalog and schema policy slice from
`1.0.0-beta.13`.
## Unreleased
No unreleased language scope is committed here yet.
## 1.0.0-beta.13
Release label: `1.0.0-beta.13`
Release name: Diagnostic Catalog And Schema Policy
Release date: 2026-05-22
Status: released beta documentation/tooling policy update on the
`1.0.0-beta` language baseline.
`1.0.0-beta.13` documents the existing diagnostic machine contract without
changing the source language, runtime, standard library, CLI, or diagnostic
output shape:
- Adds [`docs/language/DIAGNOSTICS.md`](DIAGNOSTICS.md) as the beta
`slovo.diagnostic` version `1` policy.
- Documents the S-expression and JSON relationship, required and optional
fields, severity/source/range/related-span semantics, JSON-line discipline,
source-less diagnostics, and artifact-manifest diagnostic metadata.
- Defines compatibility and migration classes for diagnostic machine fields
and codes. Human-readable prose remains beta-flexible unless a release
intentionally changes machine fields, schema/version markers, codes, or
golden fixture shape.
- Inventories the 114 current diagnostic codes covered by the 358-snapshot
golden diagnostics contract in `compiler/tests/diagnostics_contract.rs`.
This release does not add LSP/watch behavior, SARIF, daemon protocols, stable
Markdown schema, stable `1.0.0` diagnostics freeze, source-language/runtime
changes, stdlib/API changes, or ABI/layout promises.
## 1.0.0-beta.12
Release label: `1.0.0-beta.12`

View File

@ -10,10 +10,10 @@ 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.12`, released on 2026-05-22 as a post-beta concrete
vector query and prefix parity 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`
Current stage: `1.0.0-beta.13`, released on 2026-05-22 as a post-beta
diagnostic catalog and schema policy 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
release, the `1.0.0-beta.5` package/workspace discipline release, and a narrow
@ -31,23 +31,25 @@ exported struct fields, exported enum variants/payload types, non-export
filtering, and module-local alias normalization, plus source-authored concrete
vector helper parity: `std.vec_i64` gains `count_of`, `starts_with`,
`without_prefix`, `ends_with`, and `without_suffix`, and `std.vec_f64` gains
`count_of`. 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
`count_of`, plus [`docs/language/DIAGNOSTICS.md`](DIAGNOSTICS.md) as the beta
`slovo.diagnostic` version `1` policy and current golden diagnostic code
catalog. 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, stable Markdown schema, stable
stdlib/API compatibility freeze, LSP/watch, SARIF/daemon protocols,
diagnostics schema policy, re-exports/globs/hierarchical modules, mutable
vectors, slice/view APIs, new runtime names, performance claims, and package
registry semantics remain deferred.
stable `1.0.0` diagnostics freeze, re-exports/globs/hierarchical modules,
mutable vectors, slice/view APIs, new runtime names, performance claims, and
package registry semantics remain deferred.
Next stage target: continue after `1.0.0-beta.12` 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, mutable
vectors, slice/view APIs, new runtime names, performance claims, maps/sets, or
iterators until the exact scope is frozen from the manifest and roadmap.
Next stage target: continue after `1.0.0-beta.13` from developer-experience,
package, and reserved generic/map/set planning without claiming executable
generics, an LSP/watch protocol, SARIF/daemon protocol, stable Markdown
schema, registry semantics, stable `1.0.0` diagnostics freeze, or stable
standard-library/API compatibility freeze, mutable vectors, slice/view APIs,
new runtime names, performance claims, maps/sets, or iterators 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
@ -3015,8 +3017,9 @@ exp-20 f64 numeric primitive alpha decisions:
## Phase 8: Improve v1 Tooling Contracts
- [x] Define `slovo.diagnostic` version `1` as the stable v1 machine
diagnostic schema.
- [x] Define `slovo.diagnostic` version `1` as the current v1 machine
diagnostic schema, with beta policy and catalog details in
[`docs/language/DIAGNOSTICS.md`](DIAGNOSTICS.md).
- [x] Define the v1 direction for preserving source spans through LLVM IR
emission while deferring stable debug metadata and source-map files.
- [x] Define `slovo.artifact-manifest` version `1` for compiler outputs and

View File

@ -4,7 +4,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, `1.0.0-beta.10` developer-experience API discovery update,
`1.0.0-beta.11` local package API documentation update, and `1.0.0-beta.12`
concrete vector query and prefix parity update. The language contract integrates
concrete vector query and prefix parity update, and `1.0.0-beta.13`
diagnostic catalog and schema policy 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
@ -148,6 +149,14 @@ Current v1 release surface and explicit experimental targets:
executable generics, maps/sets, iterators, mutable vectors, slice/view APIs,
new runtime names, ABI/layout stability, performance claims, or a stable
stdlib API freeze
- `1.0.0-beta.13` diagnostic catalog and schema policy target:
[`docs/language/DIAGNOSTICS.md`](DIAGNOSTICS.md) documents the existing
`slovo.diagnostic` version `1` beta policy, S-expression/JSON relationship,
required and optional fields, JSON-line discipline, source-less diagnostics,
artifact-manifest diagnostic metadata, compatibility/migration classes, and
current golden diagnostic code catalog; this is docs/tooling policy only, not
a source-language/runtime change, LSP/watch contract, SARIF/daemon protocol,
stable Markdown schema, or stable `1.0.0` diagnostics freeze
- `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
@ -1345,6 +1354,31 @@ dispatch, maps, sets, iterators, mutable vectors, slice/view APIs, new runtime
names, stable ABI/layout promises, performance claims, or a stable stdlib API
freeze.
### 4.4.10 Post-Beta Diagnostic Catalog And Schema Policy
Status: released in `1.0.0-beta.13` as a docs/tooling policy update for the
existing diagnostic surface.
`1.0.0-beta.13` adds
[`docs/language/DIAGNOSTICS.md`](DIAGNOSTICS.md) as the central beta policy for
`slovo.diagnostic` version `1`. The document records the S-expression and JSON
encodings, source-attached and source-less diagnostic field rules,
severity/source/range/related-span semantics, JSON-line discipline,
artifact-manifest diagnostic metadata, diagnostic compatibility classes, and
the current golden diagnostic code catalog.
The source language, typed core, runtime, standard library, compiler-known
runtime names, ABI/layout behavior, CLI behavior, and diagnostic output shape
are unchanged by this target. Human-readable diagnostic prose remains
beta-flexible; schema names, versions, machine fields, diagnostic codes, source
span/range semantics, JSON-line discipline, and golden fixture shape change
only intentionally through the documented migration policy.
This target explicitly does not add LSP/watch behavior, SARIF output, daemon
protocols, stable Markdown schema, stable `1.0.0` diagnostics freeze,
source-map/debug-metadata contracts, localized diagnostic text, automated
machine fix-its, or a compiler-emitted diagnostic catalog artifact.
## 4.5 v2.0.0-beta.1 Experimental Integration Readiness
Status: current experimental Slovo-side release contract, released 2026-05-17.
@ -5479,10 +5513,14 @@ requirement.
Slovo v1 keeps the v0 rule that diagnostics have both human-readable and
machine-readable forms generated from one compiler diagnostic object. Human
rendering may choose layout and surrounding prose, but the machine form is a
stable tool API.
rendering may choose layout and surrounding prose. The machine form is the
tooling contract, with beta compatibility and migration rules defined by the
diagnostics policy rather than by human text.
The v1 machine diagnostic schema is `slovo.diagnostic` version `1`.
The v1 machine diagnostic schema is `slovo.diagnostic` version `1`. As of
`1.0.0-beta.13`, the detailed beta schema policy, JSON-line discipline,
source-less diagnostic policy, compatibility classes, and current code catalog
live in [`docs/language/DIAGNOSTICS.md`](DIAGNOSTICS.md).
Every machine diagnostic emitted for a v1 compiler boundary must include:
@ -5544,8 +5582,10 @@ Diagnostic locations are derived from original source text, not from formatter
output.
The schema version belongs in every machine diagnostic and every golden
diagnostic fixture. Future machine-shape changes require a documented schema
migration and updated Glagol snapshots.
diagnostic fixture. Human-readable diagnostic prose remains beta-flexible, but
future machine-shape or code changes require the compatibility class defined in
[`docs/language/DIAGNOSTICS.md`](DIAGNOSTICS.md) and updated Glagol snapshots
when the current golden contract changes.
### 9.2 Artifact Manifest Schema

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.12`; future releases may mark new helpers this way before they graduate.
- `experimental`: not used for exported `lib/std` helpers in `1.0.0-beta.13`; 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.

View File

@ -63,6 +63,7 @@ fi
cd "${compiler_dir}"
cargo fmt --check
cargo test --test diagnostics_schema_beta13
# Full cargo test includes unignored integration gates such as dx_v1_7,
# beta_v2_0_0_beta_1, and beta_1_0_0.
cargo test