v0.18.0 Phase 1 Final Review
Status: complete on 2026-08-26. This review covers source-declared named builtin types and the primitive func syntax migration. It applies the repository boundary rule that each responsibility may depend on another responsibility's published contract but not on its implementation details.
Reviewed Boundaries
| Owner | Published contract | Forbidden knowledge checked |
|---|---|---|
| syntax | PrimitiveTypeDeclaration and an ordinary FunctionDeclaration with a primitive modifier | semantic builtin IDs, standard paths, runtime roles |
| discovery | exact BuiltinTypeInput and PrimitiveRoleInput declaration tokens | semantic arena IDs, namespace construction, source presentation |
| declaration lowering | ExportedEntity::BuiltinType, standard ownership, frozen source namespaces, frontend projections | filesystem paths, later checking state, editor queries |
| declarations | canonical builtin module ownership and structural slice attachment authority | source tokens, locator spellings, discovery traversal |
| checking | exported name targets and canonical TypeStore identities | standard paths, builtin spelling tables, discovery locators |
| analysis | semantic entities, source projections, and declaration documentation | parsing builtin names, reconstructing module authority |
Findings And Remediation
1. Builtin names had two semantic resolution paths
Body name resolution still contained a spelling switch that manufactured NameTarget::Builtin after ordinary namespace lookup. Header binding had a similar historical direct builtin path. This would have allowed the new declarations and the old implicit mapping to disagree.
Resolution: removed NameTarget::Builtin and every semantic spelling decoder. Header and body uses now resolve ExportedEntity::BuiltinType from the frozen source namespace. Construction calls such as error.new(...) consume that same exported entity.
2. Named builtin ownership had two authorities
The toolchain selected both named type declarations and Scalar, Str, and Error attachment modules. Instance authorization therefore required two independently maintained descriptions of the same ownership boundary.
Resolution: removed the three named attachment variants and renamed the remaining contract to StructuralAttachment. A named builtin's declaration module is its inherent-surface authority. Only StructuralAttachment::Slice remains because [T] has no named source declaration.
3. Invalid primitive types crossed an internal-error boundary
An unselected primitive type could reach reservation without a semantic entity and become InconsistentSurface, even though user source can author that syntax.
Resolution: surface validation now emits source diagnostic E0235 before reservation. The reservation error remains only as an invariant guard after this authored rule.
4. The fallback contract was mislabeled and repeated work
PreparedNamespaces::prelude contained both universal builtins and the package-external prelude. It also searched the toolchain builtin list again for every projected origin.
Resolution: renamed the stored layer to fallback and carry each already validated declaration token through fallback construction. The former monolithic application step is split into resolution, installation, and fallback composition; each substep consumes the preceding value rather than inspecting or reconstructing its work. Namespace freezing performs no second role lookup.
5. Editor capability selection omitted the new entity
Source projection and presentation supported SemanticEntity::BuiltinType, but the central interactive-entity capability filter did not. Header references therefore had semantic bindings that hover could not select.
Resolution: added the entity to the shared interactive capability and added an analysis test covering presentation plus navigation from an application i32 use to std/num/index.nct.
6. Presentation retained a second builtin spelling table
Type rendering used a local exhaustive switch while declaration rendering used the model's canonical spelling.
Resolution: all semantic presentation now calls BuiltinType::spelling(). The syntax crate's contextual spelling classifier remains separate: it is a grammar vocabulary contract, not a semantic identity or standard-library authority.
7. Obsolete syntax and fixtures remained
The unused NodeKind::BuiltinType, legacy primitive name(...) fixture strings, and a test that mixed old and new primitive forms survived the initial migration.
Resolution: removed the node kind and migrated active fixtures and tests. Historical release records and archived design documents remain unchanged as versioned records.
8. Universal and prelude fallback composition could repeat one entity
The complete workspace test exposed a single-file toolchain shape whose prelude module also owned the primitive type declarations. The same builtin then entered the recipient fallback once as a universal builtin and once through the prelude. The collision appeared only when the semantic module namespace was frozen.
Resolution: fallback composition now gives universal builtin names precedence before adding visible prelude entries. The normalization remains in declaration lowering, which owns fallback composition; neither the immutable namespace representation nor later checking and analysis layers contain a duplicate-tolerating exception. Discovery fixtures now carry exact declaration locators through this path, and the language-server token fixture recognizes the resulting exact void binding.
Authority And Flow Audit
The completed flow is:
standard source declaration
-> discovery-selected SyntaxToken
-> BuiltinTypeInput
-> ReservedEntity / ExportedEntity::BuiltinType
-> frozen module and source fallback namespaces
-> FrontendDeclaration + SemanticEntity projection
-> checking and analysis consumers
No later layer searches a package path or declaration spelling to recover builtin authority. SourceIndex receives declaration and reference projections for diagnostics and editor features; it is not an input to type binding, name resolution, instance authorization, or checking. The semantic path uses FrontendBindings, DeclarationGraph, StandardLibrary, and TypeStore.
Final Result
The review found no remaining compatibility parser, named attachment duplication, semantic spelling decoder, repeated declaration-role search, duplicate fallback entry, checking-to-analysis reverse dependency, or contract that requires a consumer to inspect another responsibility's internal state. Named builtin representation remains compiler-owned by design, while its source name, documentation, navigation identity, and inherent extension boundary now have one selected declaration authority.