Skip to content

feat: decouple intent/code from core (ontology-declared SourceRoles) - #82

Merged
mroops0111 merged 4 commits into
masterfrom
feat/decouple-source-roles
Aug 4, 2026
Merged

feat: decouple intent/code from core (ontology-declared SourceRoles)#82
mroops0111 merged 4 commits into
masterfrom
feat/decouple-source-roles

Conversation

@mroops0111

Copy link
Copy Markdown
Owner

Summary

Decouples the hard-coded intent / code source taxonomy from core so a third-party ontology can declare its own source roles and run the full extract, propose, HITL, model, view loop without touching @braidhq/core or @braidhq/schema. DDD becomes one ontology among several, declaring intent / code as data.

The guiding principle: the framework never branches on a role's identity, only on a capability the ontology declares for that role. The role name disappears from the framework; the capability stays.

What changed

schema

  • SourceRole is now an open branded string (matching the LoaderKind precedent) instead of a closed z.enum(['code','intent']).
  • BatchInputMode renamed intent | derive to role-agnostic direct | derived.
  • Skill-input provider source-intent generalized to source with a role filter parameter.
  • OntologyResponse carries sourceRoles; new OntologyListResponse.

core

  • SourceRoleDescriptor capability model on OntologyPlugin (id, label, required, unitBearing, pathSegment) replaces requiredSourceRoles. unitBearing is a single capability that drives both batch unit production and Reactor gating.
  • Workspace.sourcesWithRole(role) replaces intentSources() / codeSources(); domain stays pure, the application layer resolves the ontology.
  • BatchService.resolveMode, ReactorService.isUnitBearingSource, and the unit lister all read the declared capability, not a role literal.

server

  • intentScan becomes a generic unitScan filtered by the ontology's unit-bearing roles.
  • New host-level GET /ontologies catalog endpoint (pre-workspace flows like the wizard); GET /ontology now returns sourceRoles.

sdk / ontology-ddd

  • SDK re-exports SourceRole; defineOntologyPlugin takes sourceRoles and merges an extended ontology's roles.
  • DDD declares intent (unit-bearing) and code as data.

studio

  • Add-source dialog, create-workspace wizard, and the batch page render whatever roles the active ontology declares, fetched from the endpoints above, instead of hard-coded literals.

Not in this PR

  • The metadata.intentMissing / implementationMissing evidence flags encode a trust/corroboration model, not the source taxonomy, so they are left for design: trust / convergence model for domains with no privileged fact-SSoT #68 (trust / convergence for domains with no privileged fact source). They do not block this change: a non-software ontology's nodes carry sourceReferences and never set them.

Verification

  • pnpm typecheck green across all 15 packages.
  • Every package's test suite passes when run on its own; litmus grep "'intent'|'code'|source-intent" packages/*/src hits only packages/ontology-ddd.
  • Framework and shared @braidhq/test-utils fixtures are role-neutral (primary / secondary); tests that exercise the real DDD ontology keep intent / code as its declared vocabulary.
  • Also fixes a pre-existing build break in examples/redoc-extending-ddd (used a non-existent defineOntology export).

Refs #50

🤖 Generated with Claude Code

…ceRoles)

Open SourceRole to an ontology-declared set so a third-party ontology runs
the full loop without touching @braidhq/core or @braidhq/schema.

- schema: SourceRole becomes an open branded string; BatchInputMode direct|derived;
  skill-input `source` provider is role-parameterized; OntologyResponse carries sourceRoles
- core: SourceRoleDescriptor capability model (unitBearing drives batch + reactor);
  Workspace.sourcesWithRole replaces intent/codeSources
- server: unitScan replaces intentScan; GET /ontologies catalog endpoint
- studio: source-role UI driven by the active ontology, not hardcoded literals
- ontology-ddd: declares intent|code as data

Refs #50

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mroops0111 and others added 3 commits August 3, 2026 17:29
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The server dev entry (tsx src/server.ts) crashed on boot with
"WorkspaceId.openapi is not a function": startServer imports @braidhq/schema
before @hono/zod-openapi loads, and zod 4's extendZodWithOpenApi is not
retroactive, so branded types built first never gain .openapi().

Apply the extension inside @braidhq/schema itself, before any schema is
built, so schema types are OpenAPI-ready for every consumer regardless of
import order. Pre-existing break from the zod 4 migration, surfaced while
running the e2e; independent of the source-role work.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Renaming BatchInputMode intent|derive to direct|derived broke existing
persisted plans, workspace startup aborted with a ZodError on plan.mode.
Bump BATCH_PLAN_VERSION to 2 and migrate legacy v1 plans on load
(intent to direct, derive to derived), validating against the current
schema afterward.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mroops0111
mroops0111 merged commit bff151b into master Aug 4, 2026
6 checks passed
@mroops0111
mroops0111 deleted the feat/decouple-source-roles branch August 4, 2026 07:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant