chore: adopt learning-first charter and UTC run versions
This commit is contained in:
@@ -4,10 +4,30 @@
|
||||
|
||||
**Claro** is a small, readable scripting language for beginners. It is designed to make programming approachable without requiring punctuation-heavy syntax, while still providing a path toward functions, types, objects, files, packages, and networking.
|
||||
|
||||
Current release: **v1.18.26**
|
||||
Current release: **v2026.10.20.155641**
|
||||
|
||||
## Versioning
|
||||
|
||||
Development/release runs use their current UTC date and time: `vYYYY.MM.DD.HHMMSS`.
|
||||
Stamp once at the beginning of each run, then build:
|
||||
|
||||
```bash
|
||||
python3 tools/stamp_version.py
|
||||
make
|
||||
```
|
||||
|
||||
Ordinary rebuilds retain the run version. The stamp updates current runtime,
|
||||
IDE metadata, generated project/lockfile versions, validators, and current docs;
|
||||
historical release records remain unchanged. Existing lockfiles from a previous
|
||||
run can be refreshed with `claro package lock`.
|
||||
|
||||
## Quick start
|
||||
|
||||
Claro's learning-first development charter and current priorities are in
|
||||
[`docs/LEARNING_FIRST.md`](docs/LEARNING_FIRST.md). It supersedes older
|
||||
feature-expansion priorities for current development; historical roadmaps remain
|
||||
available as project history.
|
||||
|
||||
Build Claro with a C99 compiler and `make`:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Classroom Readiness Checklist
|
||||
|
||||
Claro v1.18.26 is suitable for beginner classroom-style testing of the stable console-language foundation. Advanced platform features should still be introduced carefully and only after the basics are comfortable.
|
||||
Claro v2026.10.20.155641 is suitable for beginner classroom-style testing of the stable console-language foundation. Advanced platform features should still be introduced carefully and only after the basics are comfortable.
|
||||
|
||||
## Ready to test
|
||||
|
||||
@@ -25,7 +25,7 @@ Claro v1.18.26 is suitable for beginner classroom-style testing of the stable co
|
||||
## Recommended testing session
|
||||
|
||||
1. Build Claro or use the included executable.
|
||||
2. Run `claro --version` and confirm `Claro v1.18.26`.
|
||||
2. Run `claro --version` and confirm `Claro v2026.10.20.155641`.
|
||||
3. Run `claro test`.
|
||||
4. Run `claro validate`.
|
||||
5. Run `lessons/01_hello.claro`.
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
# Claro Command Line
|
||||
|
||||
Claro v1.18.26 supports these main commands:
|
||||
Claro v2026.10.20.155641 supports these main commands:
|
||||
|
||||
```bash
|
||||
claro file.claro
|
||||
@@ -58,7 +58,7 @@ claro package doctor
|
||||
claro package lock
|
||||
```
|
||||
|
||||
The v1.18.26 package command is a safer local project-file helper. It creates `claro.project`, `claro.lock`, and local folders under `packages/`. Package names may appear only once in `claro.project`; `claro package doctor` reports duplicate entries so the lockfile stays unambiguous. It also requires the project manifest to have exactly one non-empty `name:` field. It is not yet an online package registry.
|
||||
The v2026.10.20.155641 package command is a safer local project-file helper. It creates `claro.project`, `claro.lock`, and local folders under `packages/`. Package names may appear only once in `claro.project`; `claro package doctor` reports duplicate entries so the lockfile stays unambiguous. It also requires the project manifest to have exactly one non-empty `name:` field. It is not yet an online package registry.
|
||||
|
||||
## IDE metadata
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Claro Complete Platform Roadmap
|
||||
|
||||
Current release: **Claro v1.18.26**
|
||||
Current release: **Claro v2026.10.20.155641**
|
||||
|
||||
This roadmap tracks the larger goal: Claro as a complete beginner-friendly programming platform, not only a toy scripting interpreter.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Claro v1.18.26 Current Status
|
||||
# Claro v2026.10.20.155641 Current Status
|
||||
|
||||
This file is the beginner-safe status map for the current package. It separates what is ready to use from what is historical, experimental, or still planned.
|
||||
|
||||
@@ -11,7 +11,7 @@ This file is the beginner-safe status map for the current package. It separates
|
||||
|
||||
## Security and correctness review progress
|
||||
|
||||
The v1.18.26 review identified missing-argument reads in standard-library built-ins. The current runtime now validates required argument counts centrally before any builtin indexes `args[]`. Covered calls include `math.abs`, `math.clamp`, `random.seed`, `random.int`, text helpers, CSV helpers, path helpers, and collection helpers. Missing arguments produce a beginner-facing `needs N arguments` runtime error.
|
||||
The v2026.10.20.155641 review identified missing-argument reads in standard-library built-ins. The current runtime now validates required argument counts centrally before any builtin indexes `args[]`. Covered calls include `math.abs`, `math.clamp`, `random.seed`, `random.int`, text helpers, CSV helpers, path helpers, and collection helpers. Missing arguments produce a beginner-facing `needs N arguments` runtime error.
|
||||
|
||||
Focused regression coverage: `tests/38_builtin_arity.claro`, `tests/39_random_inverted_range.claro`, and `tests/40_call_depth_guard.claro`.
|
||||
|
||||
@@ -197,7 +197,7 @@ Ready now:
|
||||
- `claro package doctor` compares the complete manifest `checksum:` value, so a valid checksum followed by extra text is rejected
|
||||
- `claro package doctor` requires the complete supported `manifest-version: 1` value in `claro.project`, so a prefix such as `manifest-version: 10` is rejected
|
||||
- `claro package doctor` requires the complete supported `version: 1` value in each local package manifest, so a prefix such as `version: 10` is rejected
|
||||
- `claro package doctor` requires exactly one current `version: v1.18.26` line in `claro.lock`, so stale, missing, blank, or duplicate lockfile release versions are rejected
|
||||
- `claro package doctor` requires exactly one current `version: v2026.10.20.155641` line in `claro.lock`, so stale, missing, blank, or duplicate lockfile release versions are rejected
|
||||
- `claro package doctor` requires the complete supported `source: local` value in each local package manifest, so a prefix such as `source: local-extra` is rejected
|
||||
- package project entries must be unique; `claro package doctor`, `list`, `add`, `init`, and `lock` reject duplicate names instead of generating ambiguous package or lockfile data
|
||||
- lockfile package entries must also be unique; `claro package doctor` reports duplicate lock entries instead of accepting ambiguous package/checksum data
|
||||
@@ -301,7 +301,7 @@ Files named `RC*_NOTES.md`, `RC*_VALIDATION.md`, older `V1_*_VALIDATION.md`, and
|
||||
|
||||
## Which docs should a new learner trust first?
|
||||
|
||||
For the current v1.18.26 package, read docs in this order:
|
||||
For the current v2026.10.20.155641 package, read docs in this order:
|
||||
|
||||
1. `QUICK_START.md`, `FIRST_HOUR.md`, and `lessons/README.md` for first programs.
|
||||
2. `README.md` and this file for the current feature map.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Claro Final Release Checklist
|
||||
|
||||
Before publishing `Claro v1.18.26` as the current stable release:
|
||||
Before publishing `Claro v2026.10.20.155641` as the current stable release:
|
||||
|
||||
- Build from a clean unzip on Windows.
|
||||
- Build from a clean unzip on Linux or macOS.
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Claro Graphics Status
|
||||
|
||||
Current release: **Claro v1.18.26**
|
||||
Current release: **Claro v2026.10.20.155641**
|
||||
|
||||
Graphics support is intentionally separated from the stable beginner console workflow.
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# Claro Learning-First Development Charter
|
||||
|
||||
Claro is a learning tool first and a general-purpose programming language second. Prioritize an easy first experience, especially for learners with learning disabilities, without assuming one design suits every learner or claiming accessibility validation without learner testing.
|
||||
|
||||
## Active priorities
|
||||
|
||||
- Keep syntax, rules, and behavior simple, predictable, and consistent.
|
||||
- Favor the small core: `SAY`/`ASK`, variables, basic arithmetic, decisions, loops, lists, simple functions, and text-file save/load.
|
||||
- Teach one recommended syntax per concept. Keep supported compatibility forms working, but outside the initial learning path.
|
||||
- Teach one concept at a time with short explanations, runnable examples, small exercises, visible results, and concrete expected output.
|
||||
- Make errors identify the line, explain the problem without blame, and show a repair.
|
||||
- Fix broken examples, inconsistent core behavior, and simple-core crashes before considering features.
|
||||
- Do not pursue advanced type systems, concurrency, package registries, web frameworks, complex object models, or graphics systems absent an explicit request.
|
||||
- Claro runs trusted scripts; it is not a sandbox.
|
||||
|
||||
Older roadmap documents preserve project history and describe prior ambitions. This charter guides current work without removing supported features or erasing that history.
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Claro Performance and Optimization Notes
|
||||
|
||||
Current release: **Claro v1.18.26**
|
||||
Current release: **Claro v2026.10.20.155641**
|
||||
|
||||
Performance work should come after language behavior is stable and measured. Do not optimize blindly.
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# Claro Roadmap
|
||||
|
||||
> **Current direction:** Follow [`LEARNING_FIRST.md`](LEARNING_FIRST.md) for
|
||||
> active priorities. The broader milestones below are historical planning
|
||||
> context, not a mandate to expand the language or a statement that features
|
||||
> have been removed.
|
||||
|
||||
Current release: **Claro v1.18.26**
|
||||
|
||||
Claro is now in the stable v1 development line. Older RC milestones are kept as historical notes in files such as `RC0_NOTES.md`, `RC3_NOTES.md`, and `RC9_VALIDATION.md`; they are not the current roadmap.
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
SDL 1.2 support is **not included in the current stable executable**.
|
||||
|
||||
The `examples/experimental_sdl/` files are design experiments / future examples only. In Claro v1.18.26, running them with the included `claro.exe` will fail with:
|
||||
The `examples/experimental_sdl/` files are design experiments / future examples only. In Claro v2026.10.20.155641, running them with the included `claro.exe` will fail with:
|
||||
|
||||
```text
|
||||
Unknown command: SDL
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Claro Language Specification
|
||||
|
||||
Current package: **Claro v1.18.26**
|
||||
Current package: **Claro v2026.10.20.155641**
|
||||
Status: **Living v1 specification**
|
||||
|
||||
This document defines the intended behavior of the Claro language. It is written to reduce breaking changes and keep the v1 line teachable and predictable.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Claro v1.18.26 - Packages and Projects
|
||||
# Claro v2026.10.20.155641 - Packages and Projects
|
||||
|
||||
Claro v1.18.26 makes projects and packages safer and more useful while keeping the beginner syntax simple.
|
||||
Claro v2026.10.20.155641 makes projects and packages safer and more useful while keeping the beginner syntax simple.
|
||||
|
||||
## Create a project
|
||||
|
||||
@@ -28,7 +28,7 @@ README.md
|
||||
manifest-version: 1
|
||||
name: MyProject
|
||||
main: main.claro
|
||||
version: v1.18.26
|
||||
version: v2026.10.20.155641
|
||||
packages:
|
||||
package: text
|
||||
package: net_tools
|
||||
@@ -77,10 +77,10 @@ If `package doctor` reports `BAD lock checksum: math-tools`, check the `math-too
|
||||
BAD lock version: expected exactly one lock-version: 1 line
|
||||
```
|
||||
|
||||
The lockfile must also contain exactly one current release line, `version: v1.18.26`. A missing, stale, blank, or duplicate release line fails with:
|
||||
The lockfile must also contain exactly one current release line, `version: v2026.10.20.155641`. A missing, stale, blank, or duplicate release line fails with:
|
||||
|
||||
```text
|
||||
BAD lock release version: expected exactly one version: v1.18.26 line
|
||||
BAD lock release version: expected exactly one version: v2026.10.20.155641 line
|
||||
```
|
||||
|
||||
The doctor leaves your files unchanged. After reviewing your project and package manifests, run `claro package lock` to regenerate the lockfile, then run `claro package doctor` again. Spaces around values and capitalization of the lock-format field name are accepted, as with other lockfile fields. Valid generated lockfiles continue to work unchanged; this check does not add registry downloads or verify package content hashes.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Claro Web Server Plan
|
||||
|
||||
Current release: **Claro v1.18.26**
|
||||
Current release: **Claro v2026.10.20.155641**
|
||||
|
||||
Claro currently has beginner HTTP client commands and offline `claro://` test URLs. A web server API is not complete yet.
|
||||
|
||||
|
||||
+9
-9
File diff suppressed because one or more lines are too long
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Stamp a development/release run once, using its current UTC date and time.
|
||||
|
||||
Run before building: python3 tools/stamp_version.py && make
|
||||
Ordinary rebuilds and validation retain the stamp for reproducibility.
|
||||
Historical release notes and changelog entries are deliberately not rewritten.
|
||||
"""
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
CURRENT_DOCS = (
|
||||
"CURRENT_STATUS.md", "CLASSROOM_READINESS.md", "CLI.md", "SPEC.md",
|
||||
"FINAL_RELEASE_CHECKLIST.md", "WEB_SERVER_PLAN.md", "GRAPHICS.md",
|
||||
"PERFORMANCE.md", "COMPLETE_PLATFORM_ROADMAP.md", "SDL12.md",
|
||||
"V1_16_PACKAGES_PROJECTS.md",
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
source = ROOT / "src/claro.c"
|
||||
match = re.search(r'#define CLARO_VERSION "Claro ([^"\n]+)"', source.read_text())
|
||||
if not match:
|
||||
raise SystemExit("Cannot find CLARO_VERSION; no files changed")
|
||||
previous = match.group(1)
|
||||
version = datetime.now(timezone.utc).strftime("v%Y.%m.%d.%H%M%S")
|
||||
paths = [source, ROOT / "README.md"]
|
||||
paths += sorted((ROOT / "tools").glob("*.py"))
|
||||
paths += [ROOT / "docs" / name for name in CURRENT_DOCS]
|
||||
updates = []
|
||||
for path in paths:
|
||||
if path == Path(__file__).resolve() or not path.exists():
|
||||
continue
|
||||
old = path.read_text(encoding="utf-8")
|
||||
new = old.replace(previous, version)
|
||||
if new != old:
|
||||
updates.append((path, new))
|
||||
for path, content in updates:
|
||||
path.write_text(content, encoding="utf-8")
|
||||
print(f"Claro {version} (UTC); updated {len(updates)} current source/docs/validator files")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -6,7 +6,7 @@ from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
EXE = ROOT / ("claro.exe" if os.name == "nt" else "claro")
|
||||
EXPECTED_VERSION = "Claro v1.18.26"
|
||||
EXPECTED_VERSION = "Claro v2026.10.20.155641"
|
||||
|
||||
|
||||
def fail(message):
|
||||
@@ -57,11 +57,11 @@ def main():
|
||||
fail(out)
|
||||
starter = work / "StarterApp"
|
||||
starter_project = read(starter / "claro.project")
|
||||
for phrase in ["manifest-version: 1", "name: StarterApp", "main: main.claro", "version: v1.18.26", "packages:"]:
|
||||
for phrase in ["manifest-version: 1", "name: StarterApp", "main: main.claro", "version: v2026.10.20.155641", "packages:"]:
|
||||
if phrase not in starter_project:
|
||||
fail(f"claro new project file missing {phrase!r}:\n{starter_project}")
|
||||
starter_lock = read(starter / "claro.lock")
|
||||
for phrase in ["lock-version: 1", "version: v1.18.26"]:
|
||||
for phrase in ["lock-version: 1", "version: v2026.10.20.155641"]:
|
||||
if phrase not in starter_lock:
|
||||
fail(f"claro new lockfile missing {phrase!r}:\n{starter_lock}")
|
||||
|
||||
@@ -71,7 +71,7 @@ def main():
|
||||
if rc != 0:
|
||||
fail(out)
|
||||
project = read(work / "claro.project")
|
||||
for phrase in ["manifest-version: 1", "name: ClaroProject", "main: main.claro", "version: v1.18.26", "packages:"]:
|
||||
for phrase in ["manifest-version: 1", "name: ClaroProject", "main: main.claro", "version: v2026.10.20.155641", "packages:"]:
|
||||
if phrase not in project:
|
||||
fail(f"claro.project missing {phrase!r}:\n{project}")
|
||||
|
||||
@@ -100,7 +100,7 @@ def main():
|
||||
fail(f"Package checksum should be a stable non-placeholder value, got {checksum!r}")
|
||||
|
||||
lock = read(work / "claro.lock")
|
||||
for phrase in ["lock-version: 1", "version: v1.18.26", "package: math-tools", "checksum:"]:
|
||||
for phrase in ["lock-version: 1", "version: v2026.10.20.155641", "package: math-tools", "checksum:"]:
|
||||
if phrase not in lock:
|
||||
fail(f"claro.lock missing {phrase!r}:\n{lock}")
|
||||
|
||||
@@ -127,12 +127,12 @@ def main():
|
||||
fail(f"Lock format-version diagnostic was unclear:\n{out}")
|
||||
if read(work / "claro.lock") != invalid_lock:
|
||||
fail("package doctor must not rewrite an invalid lock format version")
|
||||
invalid_release_lock = lock.replace("version: v1.18.26", "version: v1.18.25", 1)
|
||||
invalid_release_lock = lock.replace("version: v2026.10.20.155641", "version: v1.18.25", 1)
|
||||
(work / "claro.lock").write_text(invalid_release_lock, encoding="utf-8")
|
||||
rc, out = run([str(EXE), "package", "doctor"], work)
|
||||
if rc == 0:
|
||||
fail("package doctor must reject a lockfile for a different Claro release")
|
||||
if "BAD lock release version: expected exactly one version: v1.18.26 line" not in out:
|
||||
if "BAD lock release version: expected exactly one version: v2026.10.20.155641 line" not in out:
|
||||
fail(f"Lock release-version diagnostic was unclear:\n{out}")
|
||||
if read(work / "claro.lock") != invalid_release_lock:
|
||||
fail("package doctor must not rewrite an invalid lock release version")
|
||||
@@ -343,7 +343,7 @@ def main():
|
||||
fail("Long package name should not create a package folder")
|
||||
|
||||
(work / "claro.project").write_text(
|
||||
"manifest-version: 1\nname: ClaroProject\nmain: main.claro\nversion: v1.18.26\npackages:\npackage: ../bad\n",
|
||||
"manifest-version: 1\nname: ClaroProject\nmain: main.claro\nversion: v2026.10.20.155641\npackages:\npackage: ../bad\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
rc, out = run([str(EXE), "package", "doctor"], work)
|
||||
@@ -382,7 +382,7 @@ def main():
|
||||
fail("package add should not create a package folder while unsafe names remain in claro.project")
|
||||
|
||||
(work / "claro.project").write_text(
|
||||
"manifest-version: 1\nname: ClaroProject\nmain: main.claro\nversion: v1.18.26\npackages:\npackage: math-tools\npackage: ../bad\n",
|
||||
"manifest-version: 1\nname: ClaroProject\nmain: main.claro\nversion: v2026.10.20.155641\npackages:\npackage: math-tools\npackage: ../bad\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
rc, out = run([str(EXE), "package", "remove", "math-tools"], work)
|
||||
|
||||
@@ -43,4 +43,4 @@ with tempfile.TemporaryDirectory() as td:
|
||||
run([str(local), "package", "remove", "text"], cwd=proj)
|
||||
run([str(local), "run"], cwd=proj)
|
||||
|
||||
print("Validation passed. Claro v1.18.26 networking reliability is ready for use.")
|
||||
print("Validation passed. Claro v2026.10.20.155641 networking reliability is ready for use.")
|
||||
|
||||
@@ -38,7 +38,7 @@ def build():
|
||||
def main():
|
||||
build()
|
||||
out = run([str(EXE), "--version"])
|
||||
if "Claro v1.18.26" not in out:
|
||||
if "Claro v2026.10.20.155641" not in out:
|
||||
raise SystemExit("Wrong version string")
|
||||
run([str(EXE), "test"])
|
||||
run([str(EXE), "validate"])
|
||||
@@ -55,7 +55,7 @@ def main():
|
||||
run([sys.executable, "tools/validate_write_file_expression_cleanup.py"])
|
||||
run([sys.executable, "tools/validate_version_convention.py"])
|
||||
run([str(EXE), "examples/networking.claro"])
|
||||
print("v1.18.26 validation complete")
|
||||
print("v2026.10.20.155641 validation complete")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import re
|
||||
from datetime import datetime
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
EXE = ROOT / "claro.exe"
|
||||
EXPECTED = "Claro v1.18.26"
|
||||
EXPECTED = "Claro v2026.10.20.155641"
|
||||
|
||||
|
||||
def fail(message):
|
||||
@@ -20,18 +22,21 @@ def main():
|
||||
if not EXE.exists():
|
||||
fail(f"Missing executable: {EXE}")
|
||||
out = run([str(EXE), "--version"]).stdout.strip()
|
||||
if not re.fullmatch(r"Claro v\d{4}\.\d{2}\.\d{2}\.\d{6}", out):
|
||||
fail(f"Expected UTC run timestamp Claro vYYYY.MM.DD.HHMMSS, got {out!r}")
|
||||
datetime.strptime(out.removeprefix("Claro v"), "%Y.%m.%d.%H%M%S")
|
||||
if out != EXPECTED:
|
||||
fail(f"Expected version {EXPECTED!r}, got {out!r}")
|
||||
ide = run([str(EXE), "ide"])
|
||||
if ide.returncode != 0:
|
||||
fail(ide.stdout)
|
||||
metadata = json.loads(ide.stdout)
|
||||
if metadata.get("version") != "v1.18.26":
|
||||
fail(f"Expected IDE metadata version 'v1.18.26', got {metadata.get('version')!r}")
|
||||
if metadata.get("version") != "v2026.10.20.155641":
|
||||
fail(f"Expected IDE metadata version 'v2026.10.20.155641', got {metadata.get('version')!r}")
|
||||
validator = ROOT / "tools" / "validate_v1_17.py"
|
||||
text = validator.read_text(encoding="utf-8")
|
||||
if "Claro v1.18.26" not in text:
|
||||
fail("tools/validate_v1_17.py must validate Claro v1.18.26")
|
||||
if "Claro v2026.10.20.155641" not in text:
|
||||
fail("tools/validate_v1_17.py must validate Claro v2026.10.20.155641")
|
||||
print("Version convention validation OK")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user