Skip to content

Commit 18e3c44

Browse files
olwangclaude
andcommitted
docs: refresh language spec to v0.7 and discover spec path in tests
Fold the recent surface additions (`?` on Option, default params, constants, tuples, list slice patterns, #lower_name, generated-namespace isolation) into the spec, bump the version to v0.7, and replace the historical changelog blocks with a current "Implemented surface" status index plus the existing future-directions section. Tests no longer hard-code the spec version: a common helper discovers docs/RSScript_v*_Spec.md (and the package-manager design doc) by name shape, and the dynamic-dispatch assertion is version-agnostic. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent b338ad7 commit 18e3c44

6 files changed

Lines changed: 442 additions & 198 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ The product core is the review protocol: `.rssi` semantic contracts, structured
208208

209209
Before AI, writing code was expensive and reviewing was manageable. That ratio has flipped: generating is cheap, reviewing is the bottleneck. RSScript is designed for the new ratio: AI writes, the compiler checks semantic boundaries, humans focus on the *risk*. What mutates, what gets retained, who owns a resource, where you cross into native or unsafe, what changed in a public API — all of it lives in the signature and in machine-readable diagnostics.
210210

211-
This discipline is binding, not aspirational: the language specification opens with a [Constitution](docs/RSScript_v0.6_Spec.md#constitution) of nine articles that govern every design decision — most importantly that constraint is the product, that review-critical behavior must be explicit in the signature, and that a feature is admitted only if it phrases as a reviewer question and needs no implicit rule to be ergonomic. Restraint is anchored to a measurable property (review cost), which is what keeps it from eroding as the language grows.
211+
This discipline is binding, not aspirational: the language specification opens with a [Constitution](docs/RSScript_v0.7_Spec.md#constitution) of nine articles that govern every design decision — most importantly that constraint is the product, that review-critical behavior must be explicit in the signature, and that a feature is admitted only if it phrases as a reviewer question and needs no implicit rule to be ergonomic. Restraint is anchored to a measurable property (review cost), which is what keeps it from eroding as the language grows.
212212

213213
---
214214

crates/rsscript/tests/checker_package/lock_metadata.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,8 +511,7 @@ risk = "unknown"
511511

512512
#[test]
513513
fn package_manager_spec_uses_implemented_provider_resolution_manifest_shape() {
514-
let root = common::workspace_root();
515-
let spec = fs::read_to_string(root.join("docs/RSScript_Package_Manager_Design_v0.6.md"))
514+
let spec = fs::read_to_string(common::package_manager_spec_path())
516515
.expect("package manager spec should be readable");
517516

518517
for stale in ["[provider]", "mode = \"platform_provided\""] {

crates/rsscript/tests/checker_package/misc.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,17 @@ fn docs_do_not_reintroduce_legacy_gc_runtime_surface() {
99
let legacy_runtime_path = ["rsscript_runtime::", "G", "c"].concat();
1010
let legacy_review_category = ["safe", "_to_", "skip"].concat();
1111

12-
for relative_path in [
13-
"README.md",
14-
"docs/RSScript_v0.6_Spec.md",
15-
"docs/RSScript_Package_Manager_Design_v0.6.md",
12+
for doc_path in [
13+
root.join("README.md"),
14+
common::language_spec_path(),
15+
common::package_manager_spec_path(),
1616
] {
17-
let source = fs::read_to_string(root.join(relative_path))
17+
let relative_path = doc_path
18+
.strip_prefix(&root)
19+
.unwrap_or(&doc_path)
20+
.display()
21+
.to_string();
22+
let source = fs::read_to_string(&doc_path)
1823
.unwrap_or_else(|error| panic!("{relative_path} should read: {error}"));
1924

2025
assert!(
@@ -34,8 +39,7 @@ fn docs_do_not_reintroduce_legacy_gc_runtime_surface() {
3439

3540
#[test]
3641
fn package_manager_spec_uses_current_http_and_env_facade_shapes() {
37-
let root = common::workspace_root();
38-
let spec = fs::read_to_string(root.join("docs/RSScript_Package_Manager_Design_v0.6.md"))
42+
let spec = fs::read_to_string(common::package_manager_spec_path())
3943
.expect("package manager spec should be readable");
4044

4145
for stale in [
@@ -67,8 +71,7 @@ fn package_manager_spec_uses_current_http_and_env_facade_shapes() {
6771

6872
#[test]
6973
fn rss_spec_keeps_protocol_dynamic_dispatch_deferred() {
70-
let root = common::workspace_root();
71-
let spec = fs::read_to_string(root.join("docs/RSScript_v0.6_Spec.md"))
74+
let spec = fs::read_to_string(common::language_spec_path())
7275
.unwrap_or_else(|error| panic!("RSScript spec should read: {error}"));
7376

7477
for forbidden in [
@@ -80,10 +83,10 @@ fn rss_spec_keeps_protocol_dynamic_dispatch_deferred() {
8083
] {
8184
assert!(
8285
!spec.contains(forbidden),
83-
"v0.6 protocol dynamic dispatch must remain deferred, found `{forbidden}`"
86+
"protocol dynamic dispatch must remain deferred, found `{forbidden}`"
8487
);
8588
}
86-
assert!(spec.contains("Dynamic dispatch (deferred, not admitted in v0.6)"));
89+
assert!(spec.contains("Dynamic dispatch (deferred, not admitted in v"));
8790
assert!(spec.contains("The only implemented and specified protocol call form is"));
8891
assert!(spec.contains("explicit `Protocol.method(...)` dispatch"));
8992
}

crates/rsscript/tests/common/mod.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,40 @@ pub fn workspace_root() -> PathBuf {
3131
crate_root().join("../..")
3232
}
3333

34+
/// Locate the language spec under `docs/` by its stable, version-independent
35+
/// name shape `RSScript_v<version>_Spec.md`, so tests never hard-code the spec
36+
/// version. Panics if zero or more than one match is found.
37+
pub fn language_spec_path() -> PathBuf {
38+
find_versioned_doc("RSScript_v", "_Spec.md")
39+
}
40+
41+
/// Locate the package-manager design doc by its version-independent name shape
42+
/// `RSScript_Package_Manager_Design_v<version>.md`.
43+
pub fn package_manager_spec_path() -> PathBuf {
44+
find_versioned_doc("RSScript_Package_Manager_Design_v", ".md")
45+
}
46+
47+
/// Find exactly one file in `docs/` whose name starts with `prefix` and ends
48+
/// with `suffix` (the span between them is the version and is not constrained).
49+
fn find_versioned_doc(prefix: &str, suffix: &str) -> PathBuf {
50+
let docs = workspace_root().join("docs");
51+
let mut matches: Vec<PathBuf> = fs::read_dir(&docs)
52+
.unwrap_or_else(|error| panic!("docs/ should be readable: {error}"))
53+
.filter_map(|entry| entry.ok().map(|entry| entry.path()))
54+
.filter(|path| {
55+
path.file_name()
56+
.and_then(|name| name.to_str())
57+
.is_some_and(|name| name.starts_with(prefix) && name.ends_with(suffix))
58+
})
59+
.collect();
60+
matches.sort();
61+
match matches.as_slice() {
62+
[path] => path.clone(),
63+
[] => panic!("no docs/ file matched `{prefix}*{suffix}`"),
64+
many => panic!("expected exactly one docs/ file matching `{prefix}*{suffix}`, found {many:?}"),
65+
}
66+
}
67+
3468
pub fn runtime_path() -> String {
3569
workspace_root()
3670
.join("crates/runtime")

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LLMs); everything else lives here.
88

99
| Doc | What it governs |
1010
|-----|-----------------|
11-
| [RSScript_v0.6_Spec.md](RSScript_v0.6_Spec.md) | The language. Opens with a binding **Constitution** (Articles I–IX) that overrides every chapter. |
11+
| [RSScript_v0.7_Spec.md](RSScript_v0.7_Spec.md) | The language. Opens with a binding **Constitution** (Articles I–IX) that overrides every chapter. |
1212
| [RSScript_Package_Manager_Design_v0.6.md](RSScript_Package_Manager_Design_v0.6.md) | The package manager (`rss pkg`): `.rssi` contracts, `rsspkg.toml`/`.lock`, semantic dependency review. |
1313
| [Review_Evidence_IR_Spec_v0.2.md](Review_Evidence_IR_Spec_v0.2.md) | REIR — the review-evidence IR consumed by `--reir` tooling and CI gates. |
1414
| [ARCHITECTURE.md](ARCHITECTURE.md) | Module boundaries of the checker/lowering implementation. |

0 commit comments

Comments
 (0)