Skip to content

feat(core): contracts, domain, ports, blocs, and DI skeleton (M1) - #32

Merged
Dimoshka merged 2 commits into
mainfrom
feat/m1-core-skeleton
Oct 20, 2026
Merged

Dimoshka merged 2 commits into
mainfrom
feat/m1-core-skeleton

Conversation

@Dimoshka

Copy link
Copy Markdown
Contributor

Summary

Implements the full interface skeleton from the specification — no business logic yet; every method that performs effects is a documented stub for M2.

  • packages/contracts: Risk, ToolSpec (interim hand-written form pending schemantic spike T2), sealed AgentEvent hierarchy with hand-written JSON round-trip and UnknownEvent fallback, protocol error codes, ExtensionManifest.
  • alteri_one_core domain (pure Dart): transition() state machine, PolicyGate.decide() with the fixed check order (capability → taint → profile rules), effectiveRisk, RunCapabilities.narrow(), Budget, Invocation, typed IDs, Message/Turn/ToolCall, CancelToken, memory and context types, TriggerEvent chain depth.
  • alteri_one_core ports: LlmPort, JournalPort, MemoryPort, ToolPort as abstract interface class.
  • Application layer: the six state components from domain.md §8.10 (RunBloc, ApprovalsBloc, ExtensionsBloc, SchedulerBloc with droppable(), TriggersCubit, ChannelsCubit), StatePublisher stub, applyBlocDefaults().
  • DI: configureCore(environment) for dev/prod/test; injectable-generated config committed; PolicyGate registered fail-closed.

Also carries two chore fixes that predate this branch: repository URLs normalized to dip-develop/alteri-one (closes Q4) and build_runner pinned to >=2.16.1 <2.17.0 (2.17.0 retracted on pub.dev; 2.17.1 needs build 5 while injectable_generator 3.x needs build ^4).

Specification

  • Spec sections: docs/spec/domain.md §8.1–8.10, docs/spec/contracts.md §10.1–10.5, docs/spec/dart-language.md §7
  • New/changed decisions: none accepted; findings recorded as T21, Q5, Q6 in docs/spec/open-questions.md
  • docs/spec/open-questions.md updated; docs/plan/M1.md created and checked off

Tests

  • Full transition matrix (17×12), including every invalid transition throwing InvalidTransition
  • All PolicyGate.decide branches (fail-closed defaults, taint rules, ask→deny without a channel)
  • RunCapabilities.narrow / effectiveRisk boundaries; Budget.standard() pinned to the spec values
  • AgentEvent JSON round-trips; unknown event types degrade to UnknownEvent
  • RunBloc lifecycle under bloc_test (closes T14); component and DI suites
  • melos run ci green locally (format, analyze --fatal-infos, arch, 144+ tests)

Notable implementation findings (review focus)

  1. T21 — bloc 9 event ordering: each on<E>() is a separate subscription; per-handler sequential() never orders events across types. The composition root sets Bloc.transformer = sequential() once (applyBlocDefaults()), and RunBloc/ApprovalsBloc/ExtensionsBloc use a single handler with an exhaustive switch over their sealed event types. Section 8.10 rule 4 should be rewritten accordingly.
  2. Q5: the 3.13.5 analyzer cannot attach /// docs to primary-constructor parameters, so public_member_api_docs is omitted from the shared lint set (dartdoc stays mandatory by convention per packages/AGENTS.md).
  3. Q6: compiler-verified new constructor forms differ from dart-language.md §7.3 (space instead of dot for named new, type-less named factories, no named new factories).

Checklist

  • Commits signed off (git commit -s, DCO) and follow Conventional Commits
  • Generated files regenerated via melos run gen, not edited by hand
  • No new dependency outside docs/spec/architecture.md (get_it is injectable's runtime container)
  • Tests for new behavior, including negative ones (invalid transitions, denied policy branches)

- Replace github.com/alteri-one/alteri-one with github.com/dip-develop/alteri-one
  across pubspecs, READMEs, and community files (closes open question Q4).
- Pin build_runner to >=2.16.1 <2.17.0: 2.17.0 is retracted on pub.dev and
  2.17.1 needs build 5 while injectable_generator 3.x needs build ^4.

Signed-off-by: Dmytro Prylutskyi <dmytro.prylutskyi@outlook.com>
Implements the interface skeleton per docs/spec/domain.md (sections 8-9),
docs/spec/contracts.md (section 10), and docs/spec/dart-language.md (section 7):

packages/contracts:
- Risk, ToolSpec (interim hand-written form pending spike T2)
- sealed AgentEvent hierarchy with JSON round-trip and UnknownEvent fallback
- ApiErrorCode constants, ApiError, ExtensionManifest/ExtensionProvides

alteri_one_core:
- domain: transition() state machine, PolicyGate.decide (capability -> taint ->
  profile rules), effectiveRisk, RunCapabilities.narrow, Budget, Invocation,
  typed IDs, Message/Turn/ToolCall/ToolResultBlock, CancelToken, memory,
  ContextFragment, TriggerEvent with chain depth
- ports: LlmPort, JournalPort, MemoryPort, ToolPort (abstract interface class)
- application: RunBloc, ApprovalsBloc, ExtensionsBloc, SchedulerBloc (droppable),
  TriggersCubit, ChannelsCubit, StatePublisher stub, applyBlocDefaults
- DI: configureCore(environment) with dev/prod/test; fail-closed PolicyGate

Tests: full transition matrix incl. invalid transitions, all PolicyGate
branches, capabilities boundaries, event JSON round-trip, RunBloc lifecycle
under bloc_test (closes T14), component and DI suites. melos run ci green.

Findings recorded in docs/spec/open-questions.md and docs/plan/M1.md:
- T21: bloc 9 runs each on<E>() as a separate subscription; cross-type ordering
  requires the static Bloc.transformer plus a single handler per bloc.
- Q5: public_member_api_docs cannot see primary-constructor parameter docs.
- Q6: verified new-constructor syntax differs from dart-language.md section 7.3.

Signed-off-by: Dmytro Prylutskyi <dmytro.prylutskyi@outlook.com>
@Dimoshka
Dimoshka merged commit fd64d00 into main Oct 20, 2026
1 check failed
@Dimoshka
Dimoshka deleted the feat/m1-core-skeleton branch October 20, 2026 12:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant