Summary
braid is meant to be a pure framework where the ontology is a plugin (DDD is just the default). But the intent / code worldview is still hard-coded into core, which blocks any non-software ontology (e.g. a story-world ontology, a research-notes ontology) from being a first-class citizen.
This issue tracks decoupling intent/code from core so braid is genuinely "braid anything".
Evidence (where the leak is)
The single root of the leak:
packages/schema/src/source.ts:5 — export const SourceRole = z.enum(['code', 'intent'])
A core schema type pins the source taxonomy to exactly these two values.
Two downstream dependents build on that binary:
packages/core/src/application/BatchService.ts — mode === 'intent' branch, buildIntentUnits(), and error strings like "has no intent or code sources to bootstrap from". Core knows about two privileged source kinds.
packages/core/src/infrastructure/validation/EvidenceValidator.ts — encodes the intent↔code drift semantics directly (implementationMissing = intent-only, intentMissing = code-only).
Everything else is already generic: LoaderKind is a branded string (loaders are open), deriveUnits lets an ontology bootstrap its own extraction units, and the whole ontology axis is a plugin. So this is roughly the last ~20% that bakes the software-engineering worldview into core.
Proposed direction
- Open up
SourceRole. Turn the fixed ['code','intent'] enum into an ontology-declared, open set of roles. The ontology plugin declares its own roles (DDD: code | intent; a story ontology: canon | play; etc.).
- Generalize the drift semantics. Replace
EvidenceValidator's hard-coded intent↔code drift with a generic notion of cross-role corroboration / conflict between sources of different declared roles. The intent↔code drift becomes one instantiation, not a built-in.
- Route bootstrap through
deriveUnits. BatchService's mode === 'intent' special-casing should fall out once roles are ontology-defined and unit derivation already has the deriveUnits escape hatch.
Forcing function
Don't do this speculatively. The real driver is an external consumer project building a second, non-software ontology (ontology-story, a serialized interactive bedtime-story world) as a genuine third-party plugin via @braidhq/sdk. Its sources are canon | play rather than code | intent.
Acceptance criteria: a third-party ontology can declare its own SourceRole set and run the full extract → propose → HITL → model → view loop without touching @braidhq/core or @braidhq/schema. When that passes, braid is proven to be a pure framework, and ontology-ddd is just one example among several.
Notes
- This also makes
ontology-ddd a cleaner reference: it would declare code | intent instead of relying on core knowing those names.
- Keep the HITL gate and evidence/provenance invariants — those are framework invariants and should stay. Only the software-specific source taxonomy is being lifted out.
🤖 Drafted via Claude Code while scoping the everstory project (a downstream consumer that will be the forcing function above).
Summary
braid is meant to be a pure framework where the ontology is a plugin (DDD is just the default). But the
intent/codeworldview is still hard-coded into core, which blocks any non-software ontology (e.g. a story-world ontology, a research-notes ontology) from being a first-class citizen.This issue tracks decoupling
intent/codefrom core so braid is genuinely "braid anything".Evidence (where the leak is)
The single root of the leak:
packages/schema/src/source.ts:5—export const SourceRole = z.enum(['code', 'intent'])A core schema type pins the source taxonomy to exactly these two values.
Two downstream dependents build on that binary:
packages/core/src/application/BatchService.ts—mode === 'intent'branch,buildIntentUnits(), and error strings like "has no intent or code sources to bootstrap from". Core knows about two privileged source kinds.packages/core/src/infrastructure/validation/EvidenceValidator.ts— encodes the intent↔code drift semantics directly (implementationMissing= intent-only,intentMissing= code-only).Everything else is already generic:
LoaderKindis a branded string (loaders are open),deriveUnitslets an ontology bootstrap its own extraction units, and the whole ontology axis is a plugin. So this is roughly the last ~20% that bakes the software-engineering worldview into core.Proposed direction
SourceRole. Turn the fixed['code','intent']enum into an ontology-declared, open set of roles. The ontology plugin declares its own roles (DDD:code | intent; a story ontology:canon | play; etc.).EvidenceValidator's hard-coded intent↔code drift with a generic notion of cross-role corroboration / conflict between sources of different declared roles. The intent↔code drift becomes one instantiation, not a built-in.deriveUnits.BatchService'smode === 'intent'special-casing should fall out once roles are ontology-defined and unit derivation already has thederiveUnitsescape hatch.Forcing function
Don't do this speculatively. The real driver is an external consumer project building a second, non-software ontology (
ontology-story, a serialized interactive bedtime-story world) as a genuine third-party plugin via@braidhq/sdk. Its sources arecanon | playrather thancode | intent.Acceptance criteria: a third-party ontology can declare its own
SourceRoleset and run the full extract → propose → HITL → model → view loop without touching@braidhq/coreor@braidhq/schema. When that passes, braid is proven to be a pure framework, andontology-dddis just one example among several.Notes
ontology-ddda cleaner reference: it would declarecode | intentinstead of relying on core knowing those names.🤖 Drafted via Claude Code while scoping the
everstoryproject (a downstream consumer that will be the forcing function above).