Background
PR #552 (TML-2584 S1.A substrate) narrowed Namespace.kind to required at the TypeScript type level across the framework, SQL, and Mongo IR classes. However, the Mongo contract-ts builder (packages/2-mongo-family/2-authoring/contract-ts/src/contract-builder.ts ~L1515) still constructs plain object literals for namespaces:
storageBody = { namespaces: { [UNBOUND_NAMESPACE_ID]: { id, collections } } }
No kind property is present, no class instance is constructed. As a result:
- Making
kind required in createMongoNamespaceEnvelopeSchema (and the equivalent SQL path) would surface kind enumerably on those literals, changing the storage-hash input and breaking pnpm fixtures:check.
- On-disk unbound Mongo contracts carry no
kind key today.
- The same plain-literal bypass affects the SQLite path (sqlite fixtures likewise omit
kind on the namespace literal).
This condition is captured in drive/retro/findings.md (2026-05-20 entry, "plain-literal namespace path bypass").
Required work
- Lift the Mongo authoring builder to construct
new MongoStorage(...) / new MongoNamespacePayload(...) instances so that kind is set non-enumerably (matching the class-hierarchy convention) and the storage hash input is unchanged.
- Apply the equivalent lift to the SQLite authoring builder.
- Once both builders use class instances, tighten the family validators to require
kind: 'string' (removing the ?) in createMongoNamespaceEnvelopeSchema and its SQL counterpart.
- Verify
pnpm fixtures:check passes with zero drift after the change.
Relationship to other follow-ups
This is a sibling cleanup to TML-2634 (slot renames) and TML-2636 (emitter cleanups). It should be sequenced after the builder migration work is scoped.
References
Background
PR #552 (TML-2584 S1.A substrate) narrowed
Namespace.kindto required at the TypeScript type level across the framework, SQL, and Mongo IR classes. However, the Mongo contract-ts builder (packages/2-mongo-family/2-authoring/contract-ts/src/contract-builder.ts~L1515) still constructs plain object literals for namespaces:No
kindproperty is present, no class instance is constructed. As a result:kindrequired increateMongoNamespaceEnvelopeSchema(and the equivalent SQL path) would surfacekindenumerably on those literals, changing the storage-hash input and breakingpnpm fixtures:check.kindkey today.kindon the namespace literal).This condition is captured in
drive/retro/findings.md(2026-05-20 entry, "plain-literal namespace path bypass").Required work
new MongoStorage(...)/new MongoNamespacePayload(...)instances so thatkindis set non-enumerably (matching the class-hierarchy convention) and the storage hash input is unchanged.kind: 'string'(removing the?) increateMongoNamespaceEnvelopeSchemaand its SQL counterpart.pnpm fixtures:checkpasses with zero drift after the change.Relationship to other follow-ups
This is a sibling cleanup to TML-2634 (slot renames) and TML-2636 (emitter cleanups). It should be sequenced after the builder migration work is scoped.
References