|
3 | 3 |
|
4 | 4 | = RSR Language Policy |
5 | 5 | :author: Jonathan D.A. Jewell (hyperpolymath) |
6 | | -:revnumber: 1.2.0 |
| 6 | +:revnumber: 1.2.1 |
7 | 7 | :revdate: 2026-05-16 |
8 | 8 | :toc: left |
9 | 9 | :icons: font |
10 | 10 | :source-repo: https://github.com/hyperpolymath/cccp |
11 | 11 |
|
12 | 12 | [NOTE] |
13 | 13 | ==== |
14 | | -*Version Status*: v1.2.0 — codifies the Interface & Architecture Law |
15 | | -(ABI=Idris2, API+FFI=Zig; strict typed boundaries; no gatekeeperless gateways) |
16 | | -as a normative section, 2026-05-16. v1.1.0 amended the allowed/banned lists |
17 | | -2026-04-10. See §Amendments at the bottom for rationale and the full change list. |
| 14 | +*Version Status*: v1.2.1 — adds the Naming Convention (separator semantics, |
| 15 | +RFC 8552-grounded, with scoped override for foreign/inverted conventions). |
| 16 | +v1.2.0 codified the Interface & Architecture Law (ABI=Idris2, API+FFI=Zig; |
| 17 | +strict typed boundaries; no gatekeeperless gateways). v1.1.0 amended the |
| 18 | +allowed/banned lists 2026-04-10. See §Amendments for the full change list. |
18 | 19 | ==== |
19 | 20 |
|
20 | 21 | == Terminology: "Rust" means "Rust/SPARK" |
@@ -288,12 +289,102 @@ Every gateway / API edge MUST front a policy gate (authentication + entitlement |
288 | 289 | nicety. (This is a *runtime access-control* rule and is distinct from the |
289 | 290 | social "graduated trust without gatekeeping" contribution model.) |
290 | 291 |
|
| 292 | +== Naming Convention: separator semantics (NORMATIVE) |
| 293 | + |
| 294 | +Estate-wide, the name separator carries meaning so a reader or agent can tell |
| 295 | +*code from data* at a glance: |
| 296 | + |
| 297 | +* **`-` (hyphen) → a program or application** (repo, service, app, library, |
| 298 | + CLI). e.g. `v-graphql`, `v-api-interfaces/`. |
| 299 | +* **`_` (underscore) → structured data/content that a program acts upon** |
| 300 | + (config, metadata, attribute payloads). e.g. `machine_readable/`, |
| 301 | + `bot_directives/`. |
| 302 | + |
| 303 | +[NOTE] |
| 304 | +==== |
| 305 | +*Precedent.* This deliberately mirrors DNS underscore-prefixed labels |
| 306 | +(`_dmarc`, `_acme-challenge`, `_domainkey`, `_spf` TXT records), where a |
| 307 | +leading underscore marks structured metadata a protocol consumes, kept |
| 308 | +distinct from real host names (which never use underscores). Formalised in |
| 309 | +**RFC 8552 ("DNS Attrleaf")**. The estate convention is the same idea applied |
| 310 | +to repo/directory names; it is a deliberate, standards-grounded rule, not a |
| 311 | +stylistic preference. |
| 312 | +==== |
| 313 | + |
| 314 | +=== Resolution when a language/OS/protocol mandates a separator |
| 315 | + |
| 316 | +This convention is *layered* and must not be enforced flatly: |
| 317 | + |
| 318 | +. **Technical mandate wins at its own layer.** Where a language, OS, package |
| 319 | + manager, or protocol *requires* a particular separator, or *assigns it a |
| 320 | + different or inverted meaning* (imagine a language whose ecosystem uses `_` |
| 321 | + for programs and `-` for data — the exact opposite of this convention), |
| 322 | + that requirement is authoritative within that language/ecosystem and is |
| 323 | + **NOT drift**. Tools and agents MUST NOT "auto-correct" a language-mandated |
| 324 | + or foreign-convention separator. A genuinely required component (e.g. a |
| 325 | + mandatory networking component that must be written in such a language) |
| 326 | + keeps its native naming internally. |
| 327 | +. **Scoped convention override (the general solution for foreign/inverted |
| 328 | + conventions).** The boundary of a foreign subtree MUST carry a |
| 329 | + machine-readable convention-scope marker in its `.machine_readable/` |
| 330 | + declaring the in-scope separator semantics (e.g. `convention: foreign` / |
| 331 | + `program-separator: _`). Inside a declared scope, estate separator |
| 332 | + *inference is suspended*: tools classify by the subtree's declared rules |
| 333 | + and explicit kind metadata only, never by the estate separator. Tools MUST |
| 334 | + detect the marker and never infer across a declared convention boundary in |
| 335 | + either direction. Absence of a marker = estate convention applies. The |
| 336 | + marker sits at the same place as the typed boundary required by the |
| 337 | + Interface & Architecture Law — the foreign subtree is itself such a |
| 338 | + boundary. |
| 339 | +. **The estate convention governs the discretionary layer** — repo names, |
| 340 | + directory names, project/app names — where the namer has free choice. |
| 341 | +. **Collision is a documented cross-layer mapping, not a contradiction.** A |
| 342 | + program repo is `v-graphql` (discretionary layer); its in-language Rust |
| 343 | + crate is legitimately `v_graphql` (Rust mandate). The repo SHOULD record the |
| 344 | + mapping (e.g. in `.machine_readable/`) so the language form is not read as a |
| 345 | + violation. |
| 346 | +. **Machine-readable backstop.** When the separator is constrained and cannot |
| 347 | + carry the program-vs-data signal, the kind (`program` | `data`) MUST be |
| 348 | + declared in the repo's `.machine_readable/` metadata. Classification never |
| 349 | + depends solely on the separator; tooling reads the declaration. |
| 350 | + |
| 351 | +=== Application |
| 352 | + |
| 353 | +The sanctioned `developer-ecosystem/v-ecosystem/v-api-interfaces/` (hyphen, |
| 354 | +holds V *programs*) is correct. The parallel |
| 355 | +`developer-ecosystem/v-ecosystem/v_api_interfaces/` (underscore, also holds |
| 356 | +programs) is a **misnamed duplicate** introduced by tooling that did not know |
| 357 | +this convention — it is to be collapsed into the hyphen form, not treated as a |
| 358 | +valid parallel structure. Underscore is reserved for genuine data/content dirs. |
| 359 | + |
291 | 360 | == Machine-Readable Policy |
292 | 361 |
|
293 | 362 | See link:../spec.scm/language-policy.scm[spec.scm/language-policy.scm] for tooling integration. |
| 363 | +The separator convention above MUST be mirrored there so agents/tools enforce |
| 364 | +it from the machine-readable policy, not prose alone. |
294 | 365 |
|
295 | 366 | == Amendments |
296 | 367 |
|
| 368 | +=== v1.2.1 — 2026-05-16 (Jonathan D.A. Jewell) |
| 369 | + |
| 370 | +Added the *Naming Convention: separator semantics* normative section: |
| 371 | +`-` = program/application, `_` = structured data acted upon, grounded in |
| 372 | +RFC 8552 ("DNS Attrleaf") underscore-label precedent. Includes the layered |
| 373 | +resolution for language/OS/protocol-mandated separators and the |
| 374 | +**scoped convention override** (machine-readable convention-boundary marker |
| 375 | +that suspends estate separator-inference inside foreign or inverted-convention |
| 376 | +subtrees, in either direction). Convention MUST be mirrored into the |
| 377 | +machine-readable policy. |
| 378 | + |
| 379 | +=== v1.2.0 — 2026-05-16 (Jonathan D.A. Jewell) |
| 380 | + |
| 381 | +Codified the *Interface & Architecture Law* as a normative section: ABI=Idris2, |
| 382 | +API+FFI=Zig (Rust/SPARK is app-logic only and never the abi/api/ffi layer or a |
| 383 | +migration target; "→ Rust" migration docs are themselves drift); V-lang only |
| 384 | +when it is Coq; strict typed boundaries (Idris2 correctness contract + Zig |
| 385 | +transaction interface; exemplars `snifs`/`typed-wasm`); no gatekeeperless |
| 386 | +gateways. |
| 387 | + |
297 | 388 | === v1.1.0 — 2026-04-10 (Jonathan D.A. Jewell) |
298 | 389 |
|
299 | 390 | The v1.0.0 freeze was lifted to reflect architectural decisions made in the |
|
0 commit comments