Merge pull request '[AUTO-ARCH-1] Spec clarifications: layer boundary DI exception, ULID scope, TUI/ACMS gap-fill' (#11092) from auto-arch/spec-pr-10451-test-coverage into master
CI / push-validation (push) Successful in 40s
CI / build (push) Successful in 55s
CI / lint (push) Successful in 1m14s
CI / e2e_tests (push) Successful in 1m8s
CI / helm (push) Successful in 1m22s
CI / quality (push) Successful in 1m25s
CI / typecheck (push) Successful in 1m36s
CI / security (push) Successful in 1m36s
CI / unit_tests (push) Successful in 6m8s
CI / docker (push) Successful in 1m39s
CI / integration_tests (push) Successful in 10m8s
CI / coverage (push) Successful in 11m0s
CI / status-check (push) Successful in 10s
CI / benchmark-regression (push) Has been cancelled
CI / benchmark-publish (push) Has been cancelled
CI / push-validation (push) Successful in 40s
CI / build (push) Successful in 55s
CI / lint (push) Successful in 1m14s
CI / e2e_tests (push) Successful in 1m8s
CI / helm (push) Successful in 1m22s
CI / quality (push) Successful in 1m25s
CI / typecheck (push) Successful in 1m36s
CI / security (push) Successful in 1m36s
CI / unit_tests (push) Successful in 6m8s
CI / docker (push) Successful in 1m39s
CI / integration_tests (push) Successful in 10m8s
CI / coverage (push) Successful in 11m0s
CI / status-check (push) Successful in 10s
CI / benchmark-regression (push) Has been cancelled
CI / benchmark-publish (push) Has been cancelled
This commit was merged in pull request #11092.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,204 @@
|
||||
@spec @clarification @layer_boundary @di_exception @ulid_scope @acms_pipeline @tui_components
|
||||
Feature: Spec clarifications — layer boundary DI exception, ULID scope, TUI/ACMS gap-fill
|
||||
|
||||
As a CleverAgents developer
|
||||
I want BDD coverage for the AUTO-ARCH-1 spec clarifications introduced in PR #10451
|
||||
So that the following architectural rules can be tested programmatically:
|
||||
- Application layer container.py is the sole permitted location for application-to-infrastructure concrete type references
|
||||
- Domain entity IDs must be ULIDs; ephemeral internal IDs need not be
|
||||
- ACMS pipeline per-stage protocol contracts include storage tier definitions and budget enforcement
|
||||
- TUI has 8+ component public interfaces with verifiable checks
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Layer boundary DI exception — container.py as sole permitted location
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@di_exception @layer_boundary
|
||||
Scenario: Import analysis confirms container.py references infrastructure types
|
||||
Given the source directory is at "src/cleveragents"
|
||||
And I examine file "application/container.py"
|
||||
Then container.py should import from cleveragents.infrastructure (application-to-infrastructure concrete type references)
|
||||
|
||||
@di_exception @layer_boundary
|
||||
Scenario: Non-container application files must not import infrastructure types directly
|
||||
Given the source directory is at "src/cleveragents"
|
||||
And I examine all files in "application/services/" for imports
|
||||
Then no file outside container.py should import from cleveragents.infrastructure with a concrete class
|
||||
And application modules may only depend on domain model interfaces
|
||||
|
||||
@di_exception @layer_boundary
|
||||
Scenario: container.py is the designated DI exception per spec clarification
|
||||
Given the source directory is at "src/cleveragents"
|
||||
When I check that cleveragents/application/container.py imports infrastructure types
|
||||
Then "container.py" should be listed as the sole permitted location for application-to-infrastructure concrete references
|
||||
And ADR-003 (Dependency Injection Framework) section on layer boundaries should cite this exception
|
||||
|
||||
@di_exception @layer_boundary
|
||||
Scenario: container.py imports from domain models and infrastructure simultaneously
|
||||
Given the file "src/cleveragents/application/container.py" is readable
|
||||
Then container.py should import domain types such as AIProviderInterface, AnalyzerRegistry, InMemoryGraphBackend, InMemoryTextBackend
|
||||
And container.py should import infrastructure types such as UnitOfWork, CheckpointRepository, SessionRepository, LLMTraceRepository
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ULID scope — domain entity IDs must be ULIDs; ephemeral internal IDs don't have to be
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@ulid_scope @spec_clarification_10451
|
||||
Scenario: Domain entity Plan uses ULID for plan_id field
|
||||
When I verify the domain model for "Plan" at cleveragents.domain.models.core.plan
|
||||
Then the plan model should have a plan_id field typed as a ULID string (26 chars, Crockford alphabet)
|
||||
|
||||
@ulid_scope @spec_clarification_10451
|
||||
Scenario: Decision entity uses ULID for decision_id
|
||||
When I verify the domain model for "Decision" at cleveragents.domain.models.core.decision
|
||||
Then the decision model should have a parent_plan_id field typed as a nullable ULID
|
||||
And the decision model should have a plan_id field typed as a ULID string
|
||||
|
||||
@ulid_scope @spec_clarification_10451
|
||||
Scenario: Actor entity uses a namespaced identifier (not raw ULID)
|
||||
When I verify the domain model for "Actor" at cleveragents.domain.models.core.actor
|
||||
Then the actor model should use an actor_id field as its persistent identity format
|
||||
|
||||
@ulid_scope @spec_clarification_10451
|
||||
Scenario: Child plans identified solely by ULID (no namespaced name) — spec clarification
|
||||
When I verify subplan identity rules in the specification
|
||||
Then child plans should use ULID identifiers only, not namespaced names
|
||||
And all operations on child plans reference them by plan ID (ULID)
|
||||
|
||||
@ulid_scope @spec_clarification_10451
|
||||
Scenario: Ephemeral internal IDs are exempt from ULID requirement
|
||||
When I verify the ephemeral context fragment model
|
||||
Then ContextFragment should have a fragment_id field typed as any str (not mandated to be ULID)
|
||||
And the specification should clarify that domain entity identifiers must be ULIDs
|
||||
And ephemeral internal identifiers need not conform to ULID format
|
||||
|
||||
@ulid_scope @spec_clarification_10451
|
||||
Scenario: Resource identifier uses ULID consistently
|
||||
When I verify the domain model for "Resource" at cleveragents.domain.models.core
|
||||
Then all resource identifiers should be ULIDs (resource_ulid field)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ACMS pipeline per-stage protocol contracts with storage tier and budget enforcement
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@acms_protocol @per_stage_contract
|
||||
Scenario: Phase 1 components define Pipeline Protocol interfaces
|
||||
Given the ACMS pipeline specification at docs/specification.md section "Context Assembly Pipeline"
|
||||
And I identify the Phase 1 — Strategy Orchestration components
|
||||
Then Phase 1 should have exactly three components: StrategySelector, BudgetAllocator, StrategyExecutor
|
||||
And each component must be defined as a @runtime_checkable Protocol
|
||||
|
||||
@acms_protocol @per_stage_contract
|
||||
Scenario: Phase 2 (Fragment Fusion) protocol interfaces are specified
|
||||
Given the ACMS pipeline specification at docs/specification.md section "Context Assembly Pipeline"
|
||||
And I identify the Phase 2 — Fragment Fusion components
|
||||
Then Phase 2 should have exactly four components:
|
||||
| Component | Protocol |
|
||||
| FragmentDeduplicator | FragmentDeduplicatorProtocol |
|
||||
| DetailDepthResolver | DetailDepthResolverProtocol |
|
||||
| FragmentScorer | FragmentScorerProtocol |
|
||||
| BudgetPacker | BudgetPackerProtocol |
|
||||
|
||||
@acms_protocol @per_stage_contract
|
||||
Scenario: Phase 3 (Context Finalization) protocol interfaces are specified
|
||||
Given the ACMS pipeline specification at docs/specification.md section "Context Assembly Pipeline"
|
||||
And I identify the Phase 3 — Context Finalization components
|
||||
Then Phase 3 should have exactly two components: PreambleGenerator and SkeletonCompressor
|
||||
And each must be defined as a @runtime_checkable Protocol
|
||||
|
||||
@acms_protocol @per_stage_contract
|
||||
Scenario: BudgetPacker enforces token budget limit (storage tier definition)
|
||||
Given the ACMS pipeline modules are available
|
||||
When I assemble with strategy "tiered" and budget 200 tokens from hot + warm tier fragments
|
||||
Then the payload total tokens should not exceed the specified budget of 200
|
||||
And BudgetPackerProtocol should guarantee total_tokens <= budget.max_tokens
|
||||
|
||||
@acms_protocol @per_stage_contract
|
||||
Scenario: StrategyExecutor handles strategy failures gracefully with circuit breaking
|
||||
Given a pipeline with a custom coordinator that has a per-strategy cost cap
|
||||
When I coordinate with a budget of 100 tokens using the capped coordinator
|
||||
Then the coordination result should list strategies used without raising unhandled exceptions
|
||||
|
||||
@acms_protocol @per_stage_contract
|
||||
Scenario: Fragment deduplication retains highest relevance score for duplicates
|
||||
Given fusion fragments with duplicates by URI and content
|
||||
When I fuse with a budget of 500 tokens
|
||||
Then the coordination fragment count should be less than or equal to total distinct resources
|
||||
And each unique resource_uri should appear at most once in the output
|
||||
|
||||
@acms_protocol @per_stage_contract
|
||||
Scenario: SkeletonCompressor integrates with parent plan context hierarchy
|
||||
Given the ACMS pipeline specification describes skeleton compression for child plans
|
||||
When a child plan's ContextRequest is assembled via ACMSPipeline
|
||||
Then the payload should include skeleton_fragments derived from parent context
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# TUI component public interfaces — 8+ components with verifiable checks
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@tui_component @public_interface
|
||||
Scenario: TUI widgets module exports exactly the documented component classes
|
||||
Given the source directory is at "src/cleveragents"
|
||||
When I enumerate widgets exported from "tui/widgets/__init__.py"
|
||||
Then the following widget public interfaces should be present:
|
||||
| Component |
|
||||
| ActorSelectionOverlay |
|
||||
| HelpPanelOverlay |
|
||||
| PermissionQuestionWidget |
|
||||
| PersonaBar |
|
||||
| PromptInput |
|
||||
| ReferencePickerOverlay |
|
||||
| SlashCommandOverlay |
|
||||
| ThoughtBlockWidget |
|
||||
|
||||
@tui_component @public_interface
|
||||
Scenario: All TUI widget classes are Textual-compatible with _StaticBase base
|
||||
Given the source directory is at "src/cleveragents"
|
||||
When I check each TUI widget file for its base class
|
||||
Then every widget in tui/widgets/ should derive from a Static base (Textual or Fallback)
|
||||
And this provides graceful degradation when Textual is not installed
|
||||
|
||||
@tui_component @public_interface
|
||||
Scenario: PromptInput exposes mode-aware behavior (normal, command, shell, multi-line)
|
||||
When I verify the PromptInput class interface at cleveragents.tui.widgets.prompt
|
||||
Then PromptInput should support InputMode enum values for mode-dependent symbol rendering
|
||||
And PromptInput should emit a PromptSubmitted event on submission
|
||||
|
||||
@tui_component @public_interface
|
||||
Scenario: PersonaBar provides content update API
|
||||
Given the TUI persona bar module is importable
|
||||
When I check PersonaBar's public methods
|
||||
Then PersonaBar should have a set_content method for updating display text
|
||||
|
||||
@tui_component @public_interface
|
||||
Scenario: ReferencePickerOverlay exposes suggestion population API
|
||||
Given the TUI reference picker module is importable
|
||||
When I check ReferencePickerOverlay's public methods
|
||||
Then ReferencePickerOverlay should have a set_suggestions method accepting query and suggestion list
|
||||
|
||||
@tui_component @public_interface
|
||||
Scenario: HelpPanelOverlay provides context-sensitive help rendering
|
||||
Given the source directory is at "src/cleveragents"
|
||||
Then HelpPanelOverlay should derive from a base Static widget class with _load_static_base
|
||||
|
||||
@tui_component @public_interface
|
||||
Scenario: Throbber widget defined and documented in specification (8th+ component beyond widgets/)
|
||||
Given the TUI app module imports widgets
|
||||
When I verify throbber.py exists in tui/widgets/
|
||||
Then ThrobberWidget should be a valid widget class with update visibility and animation methods
|
||||
|
||||
@tui_component @public_interface
|
||||
Scenario: TUI total public interface component count meets 8+ requirement
|
||||
When I count all classes exported from cleveragents.tui.widgets
|
||||
Then the total component count should be at least 8
|
||||
And the following minimum set must all be present:
|
||||
| Component |
|
||||
| ActorSelectionOverlay |
|
||||
| HelpPanelOverlay |
|
||||
| PermissionQuestionWidget |
|
||||
| PersonaBar |
|
||||
| PromptInput |
|
||||
| ReferencePickerOverlay |
|
||||
| SlashCommandOverlay |
|
||||
| ThoughtBlockWidget |
|
||||
| ThrobberWidget |
|
||||
Reference in New Issue
Block a user