Skip to content

Commit d088490

Browse files
committed
design: both namespace positions accepted, and mcpp normalises to the file's own
W2 was a request; it is now a decision. An author may put the namespace on the version or on the key, because the two are interconvertible and neither is more natural than the other — one matches how deps spells a package, the other matches what the file already contains. Four rules keep it one fact: mcpp materialises the file's own form only, the install address is assembled from whichever half carried the namespace, stating it twice and differently is a hard error, and the key form needs quotes. The quoting is measured rather than asserted. TOML bare keys are [A-Za-z0-9_-] and mcpp's lexer matches; on the 2026.9.2.1 binary the unquoted key fails at the colon with a parser message that mentions nothing about namespaces, so the documented example carries the quotes. The previous rule making a colon in a key an error is withdrawn.
1 parent b9cb76e commit d088490

1 file changed

Lines changed: 38 additions & 22 deletions

File tree

.agents/docs/2026-09-03-xlings-workspace-as-the-one-table.md

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -118,28 +118,44 @@ environment and leaves its version open, which is exactly what `deps = ["cmake"]
118118
means today. No `*` and no `latest` is introduced: `""` is the form the file
119119
already has, and it maps onto an install target with no `@version`.
120120

121-
**W2. The namespace is undefined in this position today, and defining it is
122-
xlings' call.** No workspace key anywhere carries one: not in the authored
123-
example above, and not in 1635 version-database targets or 546 SubOS entries on
124-
the development host. The colon appears only on the version side, where a
125-
scope qualifies where a version came from — `"mcpp": {"active":
126-
"xim:2026.8.30.2", …}`, one target holding both scoped and unscoped versions.
127-
128-
But that is a statement about **resolution**, and the namespace is needed for
129-
**installation**, and nothing derives an install address from a workspace entry
130-
today, because nothing installs from `workspace` at all (§13.2). The moment
131-
mcpp does, the question becomes real and has two candidate answers:
132-
133-
| Form | Reads | Costs |
134-
|---|---|---|
135-
| `picolibc-riscv = "xim:1.8.12"` | key is the xvm target; the scope rides the version, as the version database already spells it | the address is assembled from two halves |
136-
| `"xim:picolibc-riscv" = "1.8.12"` | key is the install address, as `deps` spells it | the key is no longer the name the shim looks up, so resolution has to strip it |
137-
138-
The second is closer to `deps` and to how a person thinks about a package; the
139-
first is closer to what the file already contains. Either works if the rule is
140-
stated once — what must not happen is both being accepted, which would put one
141-
fact in two spellings. **This is the one item in section 3 that is a request
142-
rather than a finding.**
121+
**W2. Decided (2026-09-03): both positions are accepted, and mcpp normalises.**
122+
The namespace can ride the version or the key, the two are mechanically
123+
interconvertible, and an author should not have to remember which one this
124+
table wants:
125+
126+
```toml
127+
[xlings.workspace]
128+
picolibc-riscv = "xim:1.8.12" # scope on the version
129+
"xim:picolibc-riscv" = "1.8.12" # namespace on the key — quotes REQUIRED
130+
qemu-riscv = { linux = "xim:9.2.4-1" } # composes with W3
131+
```
132+
133+
Four rules make that one fact rather than two:
134+
135+
1. **mcpp writes one form.** Whatever was authored, the materialised
136+
`.xlings.json` carries the file's own convention: the key is the bare xvm
137+
target and the scope rides the version. So the file never holds two
138+
spellings, and everything downstream of it sees one.
139+
2. **The install address is assembled from the pair**, whichever half carried
140+
the namespace: `xim` + `picolibc-riscv` + `1.8.12`.
141+
3. **Stating the namespace twice and differently is a hard error** naming both
142+
halves — `"xim:foo" = "other:1.0"` is not a merge to resolve. So is naming
143+
one package under both spellings in the same table.
144+
4. **The key form needs quotes, and the documentation must show them.** TOML
145+
bare keys are `[A-Za-z0-9_-]`; mcpp's own lexer matches the specification
146+
(`is_bare_key_char`, `modules/libs/src/toml.cppm:150`). Measured on the
147+
2026.9.2.1 binary:
148+
149+
```
150+
xim:picolibc-riscv = "1.8.12" → error: mcpp.toml:6:4: error: expected …
151+
"xim:picolibc-riscv" = "1.8.12" → loads
152+
```
153+
154+
The unquoted form fails with a parser message that says nothing about
155+
namespaces, so the example in the documentation carries the quotes.
156+
157+
The earlier rule that a colon in a key is an error is withdrawn: the colon is
158+
now meaningful there.
143159

144160
**W3. The per-platform form is xlings' own, and its native keys are
145161
`linux`, `windows`, `macosx` and `default`** (`platform::OS_NAME` per

0 commit comments

Comments
 (0)