Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,14 @@ make doctest # → tests/STD<MOD>DOCTST.m for every module with Pattern-
make frontmatter # re-syncs YAML frontmatter on docs/modules/std*.md
```

The Phase 0 `repo.meta.json` (`dist/repo.meta.json`) is hand-edited —
not regenerated — and is covered by `make check-manifest` (see below).
The root `repo.meta.json` is hand-edited — not regenerated — and is
covered by `make check-manifest` (see below). It lives at the repo ROOT
(the standardized "one meta artifact, one location"); `m arch check`
reads it root-first and validates its shape.

## Verify

These commands match `dist/repo.meta.json`'s `verification_commands`
These commands match `repo.meta.json`'s `verification_commands`
and are what an agent should run to confirm a change in this repo:

```bash
Expand All @@ -189,10 +191,10 @@ make check-manifest # drift gate: dist/ matches src/ AND repo.meta.json is co
`dist/skill/`, or `tests/STD*DOCTST.m`.** They are regenerated from
`src/STD*.m` doc-comments by `make manifest`, `make skill`, and
`make doctest`. CI's drift gates will reject any direct edit.
- **`dist/repo.meta.json` is the one file under `dist/` that is
hand-edited.** Bump `verified_on` to today's date whenever you
touch it; `make check-manifest` asserts that `dist/` (including
`repo.meta.json`) is committed and clean.
- **The root `repo.meta.json` is the hand-edited meta artifact** (the
rest of `dist/` is generated). Bump `verified_on` to today's date
whenever you touch it; `make check-manifest` asserts it is committed
and clean.
- **Do not introduce GT.M support.** AGPL-3.0 YottaDB and IRIS only —
GT.M is deliberately out of scope.
- **Do not duplicate utilities into m-cli.** m-stdlib has architectural
Expand All @@ -209,8 +211,9 @@ elsewhere — m-stdlib's top-level layout:

| Path | Contents |
|---|---|
| `repo.meta.json` (root) | Hand-edited repo meta (id/layer/language/verification_commands); `m arch check` reads it root-first |
| `docs/` | Tracking (changelog, module tracker, discoveries, parallel tracks), per-module API reference (`modules/`), plans, guides, testing writeups |
| `dist/` | Phase 0 `repo.meta.json` + `stdlib-manifest.json` / `errors.json` / `skill/` (drift gates) |
| `dist/` | Generated drift-gated artifacts — `stdlib-manifest.json` / `errors.json` / `skill/` |
| `examples/` | Demo M source (e.g. `stdargs-demo.m`) |
| `templates/` | Project scaffolds (e.g. `m-vista-test-suite/`) |
| `scripts/` | Shell helpers |
Expand Down
18 changes: 9 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -155,16 +155,16 @@ manifest-check: manifest
|| { echo "ERROR: dist/errors.json out of date — run 'make manifest' and commit."; exit 1; }
@echo "manifest: clean"

# `check-manifest` is the Phase 0 tier-1 drift gate. It composes the
# existing manifest-check (generated payloads) with an assertion that
# the hand-edited dist/repo.meta.json is tracked and clean. The org
# catalog generator fetches dist/repo.meta.json by raw URL — a missing
# or stale file would break Phase 0's smoke test in .github.
# `check-manifest` is the tier-1 drift gate. It composes the existing
# manifest-check (generated payloads) with an assertion that the hand-edited
# repo.meta.json is tracked and clean. The meta lives at the repo ROOT (the
# standardized "one meta artifact, one location"); `m arch check` reads it
# root-first and validates its shape (id/layer/language/verification_commands).
check-manifest: manifest-check
@git ls-files --error-unmatch dist/repo.meta.json >/dev/null 2>&1 \
|| { echo "ERROR: dist/repo.meta.json is not tracked — 'git add dist/repo.meta.json' and commit."; exit 1; }
@git diff --exit-code -- dist/repo.meta.json \
|| { echo "ERROR: dist/repo.meta.json has uncommitted changes — review and commit."; exit 1; }
@git ls-files --error-unmatch repo.meta.json >/dev/null 2>&1 \
|| { echo "ERROR: repo.meta.json is not tracked — 'git add repo.meta.json' and commit."; exit 1; }
@git diff --exit-code -- repo.meta.json \
|| { echo "ERROR: repo.meta.json has uncommitted changes — review and commit."; exit 1; }
@echo "check-manifest: clean"

# `make frontmatter` re-syncs YAML frontmatter on every docs/modules/std*.md
Expand Down
7 changes: 7 additions & 0 deletions dist/errors.json
Original file line number Diff line number Diff line change
Expand Up @@ -319,5 +319,12 @@
"loadJson"
],
"module": "STDSEED"
},
"U-STDSEED-NO-FILER": {
"labels": [
"load",
"loadJson"
],
"module": "STDSEED"
}
}
2 changes: 1 addition & 1 deletion dist/skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module + label, the canonical-idiom library, and the full U-STD* error
surface, all rendered for AI / agent context loading.

**Catalogue:** 33 modules, 290 public labels,
43 error codes.
44 error codes.

## When to use this skill

Expand Down
3 changes: 2 additions & 1 deletion dist/skill/error-codes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# m-stdlib — error codes

m-stdlib v0.5.0; 43 error codes across 14 modules.
m-stdlib v0.5.0; 44 error codes across 14 modules.

Inverted index over the manifest's `@raises` arrays. Every
`,U-STDxxx-NAME,` code an m-stdlib label sets via `set $ecode=`
Expand Down Expand Up @@ -91,4 +91,5 @@ that needs to disambiguate sources, this is the lookup table.
- **`U-STDSEED-INVALID-MANIFEST`** — raised by: `loadJson`
- **`U-STDSEED-MISSING-FIELD`** — raised by: `load`, `validate`
- **`U-STDSEED-MISSING-FILE`** — raised by: `load`, `validate`, `loadJson`
- **`U-STDSEED-NO-FILER`** — raised by: `load`, `loadJson`

6 changes: 3 additions & 3 deletions dist/skill/manifest-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -385,12 +385,12 @@ _raises: `U-STDREGEX-BAD-PATTERN`, `U-STDREGEX-NO-MATCH`, `U-STDREGEX-UNSUPPORTE
declarative test data loader (v0.1.3).

- `do clear^STDSEED(path)` — Drop bookkeeping for `path`. Idempotent.
- `do load^STDSEED(path, filer)` — Load manifest at `path` via `filer` (default FILE^DIE).
- `do loadJson^STDSEED(jsonText, filer)` — Load JSON-array manifest via `filer`.
- `do load^STDSEED(path, filer)` — Load manifest at `path` via the required `filer`.
- `do loadJson^STDSEED(jsonText, filer)` — Load JSON-array manifest via the required `filer`.
- `$$loaded^STDSEED(path)` — Predicate — 1 iff `path` is currently loaded.
- `$$validate^STDSEED(path)` — Parse-only check — return 1 on success; raise on syntax error.

_raises: `U-STDSEED-FILE-NOT-FOUND`, `U-STDSEED-FILER-ERROR`, `U-STDSEED-INVALID-JSON`, `U-STDSEED-INVALID-MANIFEST`, `U-STDSEED-MISSING-FIELD`, `U-STDSEED-MISSING-FILE`_
_raises: `U-STDSEED-FILE-NOT-FOUND`, `U-STDSEED-FILER-ERROR`, `U-STDSEED-INVALID-JSON`, `U-STDSEED-INVALID-MANIFEST`, `U-STDSEED-MISSING-FIELD`, `U-STDSEED-MISSING-FILE`, `U-STDSEED-NO-FILER`_

## `STDSEMVER`

Expand Down
47 changes: 33 additions & 14 deletions dist/stdlib-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8920,8 +8920,9 @@
},
"STDSEED": {
"synopsis": "m-stdlib — declarative test data loader (v0.1.3).",
"description": "Public API:\n load^STDSEED(path,filer) ; load TSV manifest via `filer`\n (default: fileViaDie -> FILE^DIE)\n $$loaded^STDSEED(path) ; 1 iff path is currently tracked\n clear^STDSEED(path) ; drop bookkeeping for path\n $$validate^STDSEED(path) ; 1 if manifest parses; raises on syntax\n loadJson^STDSEED(jsonText,filer) ; load JSON-array manifest via `filer`\n (each element: {\"file\":..,\"fields\":{..}})\n\nManifest format (TSV, one row per record):\n <file>\\t<field>=<value>\\t<field>=<value>...\nLines beginning with '#' are comments. Whitespace-only lines skip.\n\nFiler hook: the optional `filer` argument is a \"tag^routine\"\nreference invoked once per row as\n do @filer@(file,.fda,.iens)\nwith fda(file,\"+1,\",field)=value and `iens` an output IEN. The\ndefault — when filer is empty — calls FILE^DIE; that path\nassumes FileMan is loaded in the runtime environment.\n\nState per loaded path lives under ^STDLIB($job,\"stdseed\",path,...).\nclear() drops it. STDSEED does NOT open its own transaction;\ncallers wanting rollback semantics wrap in STDFIX (v0.1.1+).\n\nErrors set $ECODE to one of:\n ,U-STDSEED-FILE-NOT-FOUND,\n ,U-STDSEED-MISSING-FILE,\n ,U-STDSEED-MISSING-FIELD,\n ,U-STDSEED-FILER-ERROR,\n ,U-STDSEED-INVALID-JSON,\n ,U-STDSEED-INVALID-MANIFEST,",
"description": "Public API:\n load^STDSEED(path,filer) ; load TSV manifest via `filer`\n $$loaded^STDSEED(path) ; 1 iff path is currently tracked\n clear^STDSEED(path) ; drop bookkeeping for path\n $$validate^STDSEED(path) ; 1 if manifest parses; raises on syntax\n loadJson^STDSEED(jsonText,filer) ; load JSON-array manifest via `filer`\n (each element: {\"file\":..,\"fields\":{..}})\n\nManifest format (TSV, one row per record):\n <file>\\t<field>=<value>\\t<field>=<value>...\nLines beginning with '#' are comments. Whitespace-only lines skip.\n\nFiler hook: the `filer` argument is REQUIRED — a \"tag^routine\"\nreference invoked once per row as\n do @filer@(file,.fda,.iens)\nwith fda(file,\"+1,\",field)=value and `iens` an output IEN. STDSEED is\nengine-neutral (m layer, the m/v waterline) and ships no FileMan\ndefault; a missing filer raises U-STDSEED-NO-FILER. A VistA caller\ninjects a FileMan-backed filer from the v layer (v-stdlib).\n\nState per loaded path lives under ^STDLIB($job,\"stdseed\",path,...).\nclear() drops it. STDSEED does NOT open its own transaction;\ncallers wanting rollback semantics wrap in STDFIX (v0.1.1+).\n\nErrors set $ECODE to one of:\n ,U-STDSEED-NO-FILER,\n ,U-STDSEED-FILE-NOT-FOUND,\n ,U-STDSEED-MISSING-FILE,\n ,U-STDSEED-MISSING-FIELD,\n ,U-STDSEED-FILER-ERROR,\n ,U-STDSEED-INVALID-JSON,\n ,U-STDSEED-INVALID-MANIFEST,",
"errors": [
"U-STDSEED-NO-FILER",
"U-STDSEED-FILE-NOT-FOUND",
"U-STDSEED-MISSING-FILE",
"U-STDSEED-MISSING-FIELD",
Expand All @@ -8933,7 +8934,7 @@
"load": {
"form": "procedure",
"signature": "do load^STDSEED(path, filer)",
"synopsis": "Load manifest at `path` via `filer` (default FILE^DIE).",
"synopsis": "Load manifest at `path` via the required `filer`.",
"params": [
{
"name": "path",
Expand All @@ -8943,11 +8944,15 @@
{
"name": "filer",
"type": "string",
"doc": "M call-site \"label^routine\" (default fileViaDie^STDSEED)"
"doc": "REQUIRED M call-site \"label^routine\" filer"
}
],
"returns": null,
"raises": [
{
"code": "U-STDSEED-NO-FILER",
"doc": "filer argument was empty"
},
{
"code": "U-STDSEED-FILE-NOT-FOUND",
"doc": "could not open `path`"
Expand All @@ -8965,9 +8970,11 @@
"doc": "filer raised; propagated as a STDSEED code"
}
],
"raised_in_body": [],
"raised_in_body": [
"U-STDSEED-NO-FILER"
],
"examples": [
"do load^STDSEED(\"/etc/seed.tsv\")"
"do load^STDSEED(\"/etc/seed.tsv\",\"myFiler^MYAPP\")"
],
"since": "v0.1.3",
"stable": "stable",
Expand All @@ -8977,10 +8984,10 @@
"do clear^STDSEED"
],
"deprecated": "",
"description": "Each parsed row is dispatched once.",
"description": "Each parsed row is dispatched once. `filer` is required —\nSTDSEED is engine-neutral and ships no FileMan default.",
"source": {
"file": "src/STDSEED.m",
"line": 39
"line": 40
}
},
"loaded": {
Expand Down Expand Up @@ -9013,7 +9020,7 @@
"description": "",
"source": {
"file": "src/STDSEED.m",
"line": 57
"line": 60
}
},
"clear": {
Expand Down Expand Up @@ -9043,7 +9050,7 @@
"description": "Best-effort — does not delete already-filed records (caller's\nresponsibility, typically via STDFIX rollback).",
"source": {
"file": "src/STDSEED.m",
"line": 66
"line": 69
}
},
"validate": {
Expand Down Expand Up @@ -9088,13 +9095,13 @@
"description": "Never invokes the filer. Use as a pre-flight before load().",
"source": {
"file": "src/STDSEED.m",
"line": 77
"line": 80
}
},
"loadJson": {
"form": "procedure",
"signature": "do loadJson^STDSEED(jsonText, filer)",
"synopsis": "Load JSON-array manifest via `filer`.",
"synopsis": "Load JSON-array manifest via the required `filer`.",
"params": [
{
"name": "jsonText",
Expand All @@ -9104,11 +9111,15 @@
{
"name": "filer",
"type": "string",
"doc": "M call-site \"label^routine\" (default fileViaDie^STDSEED)"
"doc": "REQUIRED M call-site \"label^routine\" filer"
}
],
"returns": null,
"raises": [
{
"code": "U-STDSEED-NO-FILER",
"doc": "filer argument was empty"
},
{
"code": "U-STDSEED-INVALID-JSON",
"doc": "jsonText does not parse as JSON"
Expand All @@ -9127,11 +9138,12 @@
}
],
"raised_in_body": [
"U-STDSEED-NO-FILER",
"U-STDSEED-INVALID-JSON",
"U-STDSEED-INVALID-MANIFEST"
],
"examples": [
"do loadJson^STDSEED(\"[{\"\"file\"\":\"\"PATIENT\"\",\"\"fields\"\":{\"\".01\"\":\"\"Smith\"\"}}]\")"
"do loadJson^STDSEED(\"[{\"\"file\"\":\"\"PATIENT\"\",\"\"fields\"\":{\"\".01\"\":\"\"Smith\"\"}}]\",\"myFiler^MYAPP\")"
],
"since": "v0.2.0",
"stable": "stable",
Expand All @@ -9143,7 +9155,7 @@
"description": "",
"source": {
"file": "src/STDSEED.m",
"line": 91
"line": 94
}
}
},
Expand Down Expand Up @@ -11631,6 +11643,13 @@
"groups"
]
},
"U-STDSEED-NO-FILER": {
"module": "STDSEED",
"labels": [
"load",
"loadJson"
]
},
"U-STDSEED-FILE-NOT-FOUND": {
"module": "STDSEED",
"labels": [
Expand Down
2 changes: 2 additions & 0 deletions docs/memory/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ One line per memory file. Content lives in the files, not here.

- [iris-native-backends](iris-native-backends.md) — PR #1: the 3 optional modules' IRIS dispatch arm uses the **inlined `$zversion["IRIS"` probe** (not a public engine helper — that part of the PR was dropped as superseded); dual-engine local-test runbook (**YDB needs `--chset m`**, rebuild `/tmp/m` for the flag); `m-test-iris` embedded-Python is non-functional so STDCOMPRESS-IRIS is unverifiable locally; how the stale PR was landed without merge/rebase/force-push (forward-commit-to-master-tree).
- [dual-engine-validation-2026-06-14](dual-engine-validation-2026-06-14.md) — 2026-06-14 full sweep: YDB 49/49 (2585 assertions, 0 fail), IRIS 45/49 (crypto cluster hangs/aborts — B2 IRIS-backends PR unmerged on this branch). Durable IRIS-runner gotchas: no per-suite timeout; killing a hung iris docker-exec corrupts staging → false 0/0 until `docker restart`; stdout reports `ok:true` even on a failed run (trust shell exit / stderr). Coverage gate is aggregate, not per-module.
- [stdseed-g2-engine-neutral](stdseed-g2-engine-neutral.md) — STDSEED made strictly engine-neutral for **G2** (Option B, 2026-06-14): FileMan default filer `fileViaDie` removed, `filer` now required (`U-STDSEED-NO-FILER`); G2 stays a pure deny-list (no exception pragma). Owed: re-home `fileViaDie^VSLSEED` in v-stdlib. Verified 37/37 both engines.
- [meta-at-root](meta-at-root.md) — m-stdlib's repo meta moved `dist/repo.meta.json` → **root `repo.meta.json`** (Phase B item 1, 2026-06-15); `make check-manifest` checks root; the stale "catalog generator" comment removed (no such generator exists). Rides the `stdseed-engine-neutral-g2` branch.
- [waterline-g1-gate](waterline-g1-gate.md) — the m/v waterline **G1 gate** (`m arch check` in m-cli) — dependency-direction (v→m only); how `layer` is declared (dist/ meta vs root `repo.meta.json` for m-cli's gitignored dist/), check-manifest doesn't schema-validate the meta, and the v-cli registry-regen `go mod tidy` dep. Built s12 (loose end C).
- [t0b2-msl-kids-base](t0b2-msl-kids-base.md) — VSL T0b.2 (MSL KIDS-install-as-green): **YDB leg GREEN — 15/15 test-in-place** after the m-ydb gbldir (`e5dcf85`) + v-pkg streamed-install (`aa1991f`) fixes. **IRIS leg (s9):** `raises^STDASSERT` **now ported to IRIS** (try/catch `irisRaises` branch; YDB byte-identical) → STDFMT/STDARGS clean + STDASSERTTST 40/40 both engines + STDUUID P2 gone; remaining IRIS crashes are **non-raises**. **(s10):** file I/O made dual-engine — STDFS portable facade (`$$openRead/Write/Append`+`readLn`) + STDOS.env IRIS arm + 5 consumers migrated; **STDFSTST 50/50 both engines, YDB full 2098/0**. **But the consumer SUITES still don't go green on IRIS** — separate non-file blockers (STDJSON **byte-mode** parser, STDCSV **`@cb@` indirection**, **wide-char** descriptions). file-I/O ≠ green suites; see §s10. Full 15/15 needs byte-mode + callback-idiom + wide-char work (out of file-I/O scope). ≤8-char-name decision keeps STDASSERT/STDSEMVER as a rename follow-up.
- [vsl-doc-gaps-v0.2](vsl-doc-gaps-v0.2.md) — how the VistA Standard Library architecture doc's §12 VDL gaps resolved at v0.2; the vdocs `XU:XU:UG` over-collapse defect that blocks gold-promotion of the Kernel feature guides.
Expand Down
23 changes: 23 additions & 0 deletions docs/memory/meta-at-root.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
name: meta-at-root
description: m-stdlib's repo meta moved from dist/repo.meta.json to root repo.meta.json (Phase B item 1)
metadata:
type: project
---

The hand-edited repo meta moved **`dist/repo.meta.json` → root `repo.meta.json`**
(Phase B item 1, 2026-06-15) — the standardized "one meta artifact, one
location", now that `m arch check` reads the meta **root-first** and validates
its shape (id/layer/language/verification_commands; `Gate:"META"`).

- `make check-manifest` now asserts the **root** `repo.meta.json` is tracked +
clean (Makefile updated); the rest of `dist/` stays generated/drift-gated.
- The "org catalog generator fetches `dist/repo.meta.json` by raw URL" note in
the old Makefile comment was **stale** — no catalog generator exists in the
`.github` repo (only `go-ci.yml` + `arch-waterline.yml`); the future scheduled
**meta-gate** reads root metas. Comment removed.
- Landed on the `stdseed-engine-neutral-g2` branch (same m-stdlib Phase B PR as
the STDSEED G2 fix — keeps the branch fully waterline-clean). `verified_on`
stays today. Verified: `m arch check` 0 violations; `make check-manifest` clean.

Supersedes the "dist/ meta" half of [[waterline-g1-gate]]. See [[stdseed-g2-engine-neutral]].
Loading
Loading