Project Builtin Call Constructor v1

September 10, 2026 ยท View on GitHub

Status: implemented bounded profile; HOSTED GREEN under the v0.4.0 release baseline. Historical local, authoring-time, ignored, or separately provisioned observations below retain their narrower scope; public promotion and broader product completion remain separately gated.

Audience: compiler contributors, agent builders, and reviewers.

Typed candidate expressions can select an existing compiler-owned byte or string operation without inventing a source function or import:

{
  "kind": "builtin_call",
  "target": "core.bytes.len",
  "arguments": [{ "kind": "place", "name": "input" }]
}

The object is closed to these three fields. target is a stable operation identity, never a source spelling. Arguments use the ordinary recursive typed expression grammar, retain request order, and consume its existing node, depth, and input budgets. There are no type arguments or implicit conversions. The existing call constructor retains its local/imported function lookup.

Compiler ownership and source replay

src/byte_ops.rs and src/string_ops.rs own the closed operation inventories, source spellings, arities, and semantic signatures. This constructor projects those inventories; it introduces no new language semantics, evaluator, or backend operation.

Stable identitySource operationArgumentsResult
core.bytes.lenbyte_lenborrowed byte sliceusize
core.bytes.getbyte_getborrowed byte slice, usize indexOption<u8>
core.bytes.rangebyte_rangeborrowed byte slice, usize start, usize endbyte slice
core.bytes.copybytes_copyborrowed byte sliceowned Bytes
core.bytes.as-slicebytes_as_sliceborrowed Bytes placebyte slice
core.array-u8.as-slicearray_as_sliceborrowed fixed byte-array placebyte slice
core.str.as-bytesstr_as_bytesborrowed strbyte slice
core.string.as-strstring_as_strunprojected owning string placeborrowed str
core.string.lenstring_lenborrowed String readi64
core.string.concatstring_concattwo consumed Stringsowned string
core.string.is_emptystring_is_emptyborrowed String readbool
core.string.starts_withstring_starts_withtwo borrowed String readsbool
core.string.containsstring_containstwo borrowed String readsbool
core.string.len_charsstring_len_charsborrowed String readi64
core.string.from_charstring_from_charcopied charowned string

String operations retain their ordinary source contract. len counts UTF-8 bytes; len_chars counts Unicode scalar values. Borrowed reads leave their named owners available, while concatenation consumes both arguments using the existing ownership machinery. Compiler-generated staging and String place reads retain their ordinary cloning/allocation behavior; borrow metadata is not a claim of allocation-free execution. from_char accepts an existing checked character place or an ordinary character-valued expression. The separate scalar literal constructor can construct that checked character; this operation does not coerce an integer/string into a character. String and byte operations remain distinct: there is no implicit String-to-str, byte-slice or Bytes conversion.

An authored Project identity that collides with the selected compiler identity fails closed. Reserved spelling collisions and active lexical bindings must not redirect a requested operation. Constructor lowering emits the ordinary source call, then the complete candidate is canonically rendered, reparsed, and independently admitted through the existing Project path. Wrong argument types, unsupported profiles, escaping views, live-loan conflicts, cleanup, capacity, and contract restrictions remain compiler obligations. A structurally valid request is not evidence that a candidate can be admitted.

Before source materialization, the disposable edited AST inventory is also checked against builtin selectors in the retained intention history and new request. This catches a colliding declaration introduced by the same request or a later candidate edit, rather than relying only on the prior revision's identity inventory. Both checks use the complete source inventory, including protocol and implementation IDs omitted by runtime graph lookup. The prior inventory is parsed lazily once per expression constructor; it is not a new persistent index. Invalid selectors, arity, scope, or namespace collisions use the existing SPX-G225 constructor diagnostic. Semantic rebase conflicts retain the existing SPX-G235 diagnostic; source admission keeps its own type, provenance, and ownership diagnostics. The history check is conservative: overwriting an earlier expression does not release its builtin selector for reuse as an authored declaration identity.

View operations retain their existing source-place constraints. Bind an owned value before borrowing it; do not treat a nested temporary as an authenticated owner. A slice produced by a range operation retains its original provenance. See Portable Indexed Byte Data, Shared Loan Plan, and Projected Owned Byte Field Borrow. The constructor does not widen those language profiles.

The separate Field Place Constructor can supply a direct authenticated record field to core.bytes.as-slice without the value-staging temporary used by project. Its root-type and field-identity checks do not waive the source borrow profile or live-loan checks.

bytes_copy allocates an owned value and participates in capacity and cleanup analysis. An empty declared effect list grants no ambient authority and does not mean allocation-free execution, unrestricted contract admission, or guaranteed success.

Semantic rebase binds compiler-owned operation descriptors separately from ordinary source function dependencies. It rechecks identity and spelling availability in the destination revision and retains nested ordinary-call dependencies. Source function signature, effect, and contract guards remain in force; a matching source identity is not compiler provenance.

Discovery

Recursive constructor schemas derive fourteen closed alternatives from the two compiler operation inventories. Each alternative fixes the target and exact argument count while recursively referring to the complete expression grammar.

Target-specific change catalogues and full typed-hole contexts can expose builtin_calls separately from their existing ordinary accessible_calls. Rows describe the constructor kind, target, source name, arity, ordered parameters, return type identity, effects, evidence owner, and the requirement for full candidate validation. These are available operation descriptors, not a result-type-filtered list of proven valid replacements.

The eight borrowed byte/view descriptors retain their existing contents and order; the seven string descriptors follow them. String parameter types and ownership come from the owner's resolved signatures, with type_family: null and evidence_owner: compiler_string_operations. Byte descriptors keep evidence_owner: compiler_byte_operations. Closed response schemas distinguish the two inventories. Namespace filtering can remove unavailable descriptors; absence does not authorize a fallback to an authored function with a similar name.

Each parameter carries its index, name, ownership mode, and either a concrete type_id or a type_family. The array parameter describes the fixed byte-array family; the operation owner's internal ArrayU8(0) sentinel must not be presented as requiring a zero-length array. Actual array length and aggregate capacity remain checked from the source argument.

The compact hole navigation interface continues to expose constructor choices and a link to the full context. No new transport authority or publication route is added. Candidate exploration and failed fills leave canonical source unchanged; committing source still requires the existing separate authority.

Limits and evidence

This operation does not add arbitrary intrinsics, external calls or raw source fragments. Separate literal constructors can supply string or byte-array values, and the existing field-place extension authenticates both the root's type and selected field. Record value projection still stages an authenticated typed value; it cannot be silently substituted for a borrow of the original owned field.

Library and transport regression cases are implemented. The v0.4.0 release regression corpus is HOSTED GREEN. The graph-operational programme and completion matrix remain partial.

The string extension has separate candidate regressions and protocol regressions. String fixtures retained outside the selected entry/test closure establish no active Project or Wasm String execution support. Existing target profiles, generated-client response limits, and the serialized Rust client size gate are unchanged; their executable validation remains required.