AI Agents - Implementation Checklist¶
Package: mineproductivity.agents
Governing specification: docs/architecture/11_AI_Agents_Design_Specification.md
Architecture Decision Record: docs/adr/ADR-0011-AI-Agents.md
Status: Implemented and released (software v1.10.0, 2026-07-12).
All items below are satisfied: the complete design spec §6 module list is implemented, the unit suite passes with ≥95% coverage (99% including branches), the five examples/agents/ scripts and both benchmark/reports/agents/ reports exist and are mypy --strict/ruff-clean, and the §35 acceptance proofs each run as dedicated tests. TaskExecutor.resume() is an added public method resolving the spec's Approved/Rejected approval transitions, disclosed in the module docstring. No architectural changes were made relative to the locked v1.3.0 design.
Binding, locked implementation contract for agents - the sixth package built on top of the Foundation Layer, sitting directly above the now-locked optimization, and the enterprise operational-intelligence (orchestration) layer for the entire platform. Nothing described here may be implemented before this checklist and its governing specification exist in reviewed form, and nothing may be implemented that is not represented by an item on this list. Complete in order; every box must be checked or explicitly deferred with a linked issue and Chief Software Architect sign-off before merge.
Pre-Implementation Gate¶
- Design specification (
11_AI_Agents_Design_Specification.md) read in full by the implementer, including every cross-reference to specs 01–10. - ADR-0011 read in full; the rationale for
agentsexisting as a separate package aboveoptimization(and for the interface-only treatment ofAgent,Tool, andAgentMemory) is understood, not merely accepted. -
core,events,ontology,registry,plugins,connectors,kpis,analytics,decision,digital_twin,simulation,optimizationavailable and importable, exactly as released; no lower package file is modified as a side effect of this work. - Confirmed:
agentswill not importvisualizationunder any circumstance - it does not exist yet (design spec §5, §37). - Confirmed: no lower package (
corethroughoptimization) will be modified to import or otherwise referenceagents(design spec §5). - Confirmed: no concrete LLM provider SDK (OpenAI, Anthropic, Gemini, Llama, or any local-model runtime) is added as a dependency of this package - reasoning backends are out of scope (design spec §4's non-responsibilities, §35's no-provider-coupling proof).
Package Structure¶
-
src/mineproductivity/agents/created matching design spec §6 exactly:abstractions.py,metadata.py,capability.py,policy.py,task.py,state.py,memory.py,conversation.py,approval.py,tool.py,communication.py,goal.py,workflow.py,executor.py,result.py,audit.py,discovery.py,persistence.py,_registry.py,exceptions.py,__init__.py,README.md. -
agents/README.mdwritten following thecore/README.mdtemplate. - Confirmed
memory.py(AgentMemory) andtool.py(Tool) each contain zero concrete, non-test subclasses (mechanical grep/AST check - design spec §14, §17, §35's interface-purity proof). - Confirmed no module under
src/mineproductivity/agents/performs direct KPI, statistical, decision, twin-state, simulation-projection, or solved-plan computation of its own - every such value arrives via the corresponding lower package's public API (design spec §3.2, §35's no-fact-recomputation proof). - Confirmed no module under
src/mineproductivity/agents/imports, or contains a string reference to,openai,anthropic,google.generativeai, or any other LLM provider SDK (design spec §35's no-provider-coupling proof).
Public API¶
-
agents/__init__.pyexports exactly the symbol list in design spec §7, alphabetized__all__. -
test_public_api.pymirrorstests/unit/core/test_public_api.pyand every existing package's own copy of it. -
TestNoForbiddenDependenciesAST-walks everyagentssubmodule for a forbidden import (visualization) - mirrors every existing package's own copy of this test (design spec §5). - A second, reverse-direction test asserts no file under
src/mineproductivity/{core,ontology,events,registry,plugins,connectors,kpis,analytics,decision,digital_twin,simulation,optimization}/importsmineproductivity.agents(design spec §5) - theoptimization-package precedent for this test extended one layer up.
Agent Abstractions (§8)¶
-
Agent(§8) -meta: ClassVar[AgentMetadata]; one shared abstract method_act(task, *, context) -> AgentResult, mirroringdecision.DecisionModel's shared-_decideposture, notsimulation's/optimization's no-shared-method posture. -
AgentContext(§8) -kpi_results,analytics_results,decision_results,twin_snapshot,simulation_results,optimization_results, each defaulting to an empty sequence orNone; caller-assembles pattern only, no session-assembles variant. - Confirmed
Agentsubclasses (of every category) are stateless - no instance attribute is mutated by any_actimplementation; all statefulness lives inTask(§11, §29, §32).
Agent Capabilities and Permissions (§9)¶
-
Permission(§9) - frozencore.BaseValueObject;capability: str,scope: Mapping[str, str](default empty). -
AgentCapabilitySet(§9) - frozencore.BaseValueObject;agent_code: str,permissions: tuple[Permission, ...]. - Confirmed an
AgentCapabilitySetis always an explicit, authored, and governed artifact - never inferred from anAgentsubclass's own code at runtime.
Policy Engine (§10)¶
-
PolicyStatusenum (§10) - exactlyProposed/Active/Superseded/Retired. -
AgentPolicy(§10) - frozencore.BaseValueObject;code,version(default"1.0.0"),status,rule,requires_approval(defaultFalse),denies(defaultFalse). -
PolicyEngine.evaluate(task, *, capabilities, policies) -> Result[None](§10) implemented; confirmed to return exactly one of three outcomes - proceed, route toAWAITING_APPROVAL, or raise/returnPermissionDeniedError- never a fourth. - Confirmed
PolicyEnginenever parses or evaluatesAgentPolicy.ruleas executable code -ruleis a solver-independent string interpreted only by a concrete evaluation strategy. - Confirmed an
ActiveAgentPolicyis never edited in place anywhere in the codebase - a changed policy is published as a new version, with the prior version transitioned toSuperseded(§10, §26, §34's recorded anti-pattern). -
PolicyConflictErrorraised for a materially-different re-registration under an existing,Activepolicy code without a version bump (§10, §26). - Confirmed
AgentPolicyis documented as a deliberate non-reuse ofdecision.Policy- the shapes look similar but the concerns (authorization guardrail vs. business-recommendation threshold) are distinct (§10, §34's recorded anti-pattern against conflating them).
Task Model and Agent Lifecycle (§11)¶
-
TaskStatusenum (§11) - exactlyScheduled/Running/AwaitingApproval/Paused/Completed/Failed. -
Task(§11) - subclassescore.BaseEntity[str]directly;goal_code,agent_code,state: TaskState,status: TaskStatus;with_state()non-overridden, produces a new instance viadataclasses.replace, never mutatesself. -
TaskState(§11) - frozencore.BaseValueObject; openattributes: Mapping[str, Any]carries model-specific/delegation-chain data;validate()rejects emptyattributes. - Identity/equality proven:
Task.__eq__/__hash__inherited unchanged fromBaseEntity(identity-based onid, ignoringstate/status); no override anywhere in the package. - Lifecycle transitions proven to match design spec §11's state diagram exactly;
CompletedandFailedproven terminal (no transition out of either).
Task Execution and Failure Recovery (§12)¶
-
TaskExecutor(§12) - evaluatesPolicyEngine, dispatches to the registeredAgent's_act, gates on approval, retries on recoverable failure, persists resulting state via aremove-then-addpair againstTaskRepository, appends toAgentAuditTrail. -
TaskExecutor's dispatch, approval-gate, and persistence sequence tested against design spec §12's sequence diagram exactly, including the approval-required, denied, and cleared branches. - Confirmed
retry_policy(defaulting toconnectors.RetryPolicy's own defaults, spec 04 §10) governs only retrying the sameAgent's_actcall after a transient failure - never silently reassigns aTaskto a different agent. - Confirmed a
Taskwhose retries are exhausted transitions toFailed, never retries indefinitely.
Workflow Engine and Goal Decomposition (§13)¶
-
Goal(§13) - frozencore.BaseValueObject;description,success_criteria(default empty mapping). -
WorkflowEngine(§13) -decompose(goal, *, context) -> Sequence[Task];run(goal, *, context) -> Sequence[AgentResult]; composesTaskExecutorper individualTaskrather than duplicating its dispatch/persistence/audit logic. - A scripted hypothesis-exploration task is proven to compose
simulation.ExperimentRunner.run_trialsdirectly (§13), without this package reimplementing simulation logic. - A scripted candidate-plan-search task is proven to compose
optimization.OptimizationExecutor/optimization.PlanComparatordirectly (§13), without this package reimplementing optimization logic.
Memory Model (§14)¶
-
AgentMemory(§14) -remember(task_id, key, value, *, context) -> Noneandrecall(task_id, key, *, context) -> Any | Noneabstract; zero concrete subclasses shipped. - Confirmed a
recall()miss returnsNoneand is never treated as an error anywhere in the package's own code. - Confirmed
AgentMemoryis documented as a deliberate non-reuse ofkpis.ResultCache/digital_twin.TwinStateCache/simulation.SimulationStateCache- memory is semantically meaningful to an agent's reasoning, never a silently-evictable performance optimization.
Conversation Context (§15)¶
-
ConversationTurn(§15) - frozencore.BaseValueObject;speaker(open string),content,occurred_at. -
ConversationContext(§15) - frozencore.BaseValueObject;task_id,turns: tuple[ConversationTurn, ...](default empty); a new turn produces a new instance, never mutatesturnsin place.
Human Approval Workflows (§16)¶
-
ApprovalStatusenum (§16) - exactlyPending/Approved/Rejected. -
ApprovalRequest(§16) - frozencore.BaseValueObject;task_id,requested_action,status(defaultPending),approver(defaultNone),resolved_at(defaultNone). - Confirmed an
ApprovalRequestresolving toApprovedtransitions itsTaskfromAwaitingApprovalback toRunning; a resolution toRejectedtransitions it directly toFailed, carrying the rejection as anAgentResultwarning. - Confirmed
TaskExecutornever resolves anApprovalRequestitself - resolution is exclusively a caller (human-supervisor-facing) action.
Tool Invocation (§17)¶
-
ToolMetadata(§17) -code,description,version(default"1.0.0"). -
Tool(§17) -meta: ClassVar[ToolMetadata];invoke(*, arguments, context) -> Mapping[str, Any]abstract; zero concrete subclasses shipped. -
ToolInvocation(§17) - frozencore.BaseValueObject;tool_code,arguments,result,invoked_at. - Confirmed this package never invokes a
Toolon anAgent's behalf - a concreteAgentimplementation looks up and invokes a neededToolitself and carries the resultingToolInvocationon its ownAgentResult.
Inter-Agent Communication and Delegation (§18)¶
-
AgentMessage(§18) - frozencore.BaseValueObject;from_agent_code,to_agent_code,task_id,content(open mapping),sent_at; published viaevents.EventBusdirectly, no new message bus defined. -
DelegationRequest(§18) - frozencore.BaseValueObject;task_id,from_agent_code,to_agent_code,reason. - Confirmed delegation is expressed as an ordinary
AgentMessagewhosecontentcarries aDelegationRequest- no separate delegation-transport mechanism exists. - Confirmed the delegation chain (which agent handed a task to which) is carried in
Task.state.attributesas an open-mapping entry - no new typed field added toTaskfor this purpose.
Multi-Agent Collaboration (§19)¶
- A scripted integration test reproduces design spec §19's worked example shape (a
ShiftSupervisor-category task coordinating aFleet-category and aMaintenance-category task viaWorkflowEngine.decompose/run), each producing its own auditedAgentResult. - Confirmed no concrete category behavior (which evidence a
FleetAgentweighs, etc.) is hard-coded intoWorkflowEngineorTaskExecutor- category-specific reasoning lives exclusively in the registeredAgentsubclass.
Agent Outputs (§20)¶
-
AgentResult(§20) - frozencore.BaseValueObject;task_id(default""),computed_at,warnings(default empty tuple),output(open mapping, default empty),explanation: Explanation | None(reusesdecision.Explanationdirectly - no second justification type),tool_invocations: tuple[ToolInvocation, ...](default empty). - Confirmed
TaskStateis not anAgentResultsubclass (it represents the task's condition itself, not the outcome of an orchestration call about it).
Explainability and Audit Trails (§21)¶
-
AgentAuditEntry(§21) - frozencore.BaseValueObject;recorded_at,result: AgentResult,agent_code,scope. -
AgentAuditTrail.record()/query(*, scope=None)(§21) implemented;record()proven to serialize concurrent appends internally;query()proven never to block on a concurrentrecord(). - Confirmed every
AgentResult'sexplanationand everyToolInvocationit carries are preserved verbatim in the recordedAgentAuditEntry- never summarized.
Agent Registry and Tool Registry (§22)¶
-
agents._registry.REGISTRY/register(§22) -Registry[str, type[Agent]], raisingAgentValidationErrorfor an empty code andAgentVersionConflictErrorfor a materially-different re-registration under an existing code. -
agents._registry.TOOLS/register_tool(§22) -Registry[str, type[Tool]], identical error semantics, specialized forTool. -
EntryPointSpec(group="mineproductivity.agents", target_registry="agents")andEntryPointSpec(group="mineproductivity.agents.tools", target_registry="agents.tools")discovery wired viaregistry.EntryPointDiscovery(§31). - Confirmed
REGISTRYandTOOLSare never merged into one - anAgenttype and aTooltype remain orthogonal registrable concepts throughout the codebase.
Agent Discovery (§23)¶
-
by_category()/by_scope()(§23) - plaincore.PredicateSpecificationfactories; composed withTaskRepository.list(); confirmed to return an empty sequence (never raise) for a filter matching nothing. - Confirmed the three-way distinction (
REGISTRY/TOOLS= which types are known;TaskRepository= which task instances currently exist;discovery.py= query facade over the instance store) is never conflated anywhere in the codebase.
Serialization and Persistence (§24, §25)¶
- Every
TaskState/Permission/AgentCapabilitySet/AgentPolicy/ConversationTurn/ConversationContext/ApprovalRequest/ToolMetadata/ToolInvocation/AgentMessage/DelegationRequest/Goal/AgentResult/AgentAuditEntryandTaskitself confirmed to serialize viacore.serialization(DataclassSerializer/to_dict) with no bespoke per-type serializer. -
TaskRepositoryimplemented astype TaskRepository = BaseRepository[Task, str]- a type alias, not a new ABC or subclass. - Reference implementation uses
core.InMemoryRepository[Task, str]()directly, with zero new persistence code. - Test suite for
TaskRepositorybehavior written against thecore.BaseRepository[Task, str]contract alone, never againstInMemoryRepository-specific internals (§35's repository-substitutability proof).
Versioning (§26)¶
-
AgentMetadata.version/ToolMetadata.version(a registered type's own SemVer) andAgentPolicy.version(a governed guardrail artifact's own SemVer) confirmed to vary independently - no code path derives one from another. -
AgentVersionConflictErrorraised at registration time for a materially-different re-registration under an existingAgentMetadata/ToolMetadatacode;PolicyConflictErrorraised at publication time for the equivalentAgentPolicycase - both never deferred.
Caching (§27)¶
- Confirmed no dedicated cache module exists anywhere in the package (§27's documented, deliberate non-need; §34's recorded anti-pattern against introducing one "for consistency").
- Confirmed
AgentContextassembly happens once, at construction, never re-fetched per-retry or per-delegation (§36). - Confirmed
AgentMemory(§14) is never treated as a substitute for a cache - its absence-of-caching rationale is documented distinctly from its own semantics.
Validation (§28)¶
-
AgentMetadata.validate()/ToolMetadata.validate()- non-emptycode, category matches the closedAgentCategorynamespace where applicable. -
Task.validate()- non-emptygoal_codeandagent_code. -
TaskState.validate()- non-emptyattributes. -
AgentPolicy.validate()- non-emptycodeandrule. -
PolicyEngine.evaluate()'s three-outcome contract mechanically proven to never return a fourth outcome.
Metadata (§29)¶
-
AgentCategoryenum (§29) - exactlyProduction/Dispatch/Fleet/Maintenance/DrillAndBlast/ShiftSupervisor/Esg/Safety/ExecutiveAdvisor/Planning; a closed enum, adding a member is a governance-reviewed change. -
AgentMetadata(§29) -code,category,description,version(default"1.0.0");validate()rejects an emptycode. - Confirmed
AgentMetadata.codenames an agent type and is never confused with aTask.idanywhere in the codebase.
Error Handling (§30)¶
- Full exception hierarchy (design spec §6
exceptions.py):AgentValidationError,TaskNotFoundError,AgentExecutionError,AgentVersionConflictError,PolicyConflictError,PermissionDeniedError- each subclassing the matchingcoreorregistryexception (AgentVersionConflictError/PolicyConflictErrorsubclassregistry.RegistrationError; the rest subclass acoreexception). - Confirmed no
Agent._actimplementation raises for a legitimately incomplete or ambiguous task - returns anAgentResultcarrying a warning instead (§30's "qualify, don't coerce" central rule). - Confirmed
PermissionDeniedErroris the one case in this package where a policy outcome is a hard-stop exception rather than a warning - never a silently-persistedAgentResult.
Extension Points & Plugin Integration (§31)¶
- Entry-point groups
mineproductivity.agentsandmineproductivity.agents.toolsdocumented and wired exactly per §31. - A scripted integration test exercises a fixture "sitepack" plugin (registered via entry points, mirroring
examples/registry/01_register_and_discover.py's pattern) that subclassesAgent, proving the platform-side dispatch and registration path works end to end. - A second fixture plugin subclasses
Tooland is proven discoverable viaTOOLSindependently of theAgentfixture.
Thread Safety & Concurrency (§32)¶
-
Agentinstances (of every category) confirmed stateless and safe to share/read across threads with no locking. -
Taskinstances confirmed immutable and safe to share/read across threads with no locking. -
TaskRepository's per-id write serialization contract documented and tested against any production-grade implementation candidate; confirmed the barecore.InMemoryRepositoryreference implementation provides no locking of its own - any concurrent-write test against it must add external synchronization itself. -
AgentAuditTrail.record()proven to serialize concurrent appends internally; no lost entry under concurrent load. -
agents.REGISTRY/agents.TOOLSeach confirmed read-only and thread-safe after startup discovery, inheritingRegistry's own contract. - Independent
Tasks (differentids) proven to execute fully in parallel without contention.
Security (§33)¶
- Confirmed every
Agent._act-proposed action is evaluated byPolicyEngine/TaskExecutorbefore any effect - never executed directly against aToolor downstream system. - Confirmed a concrete
Toolimplementation validates its ownargumentsindependently - never assumes anAgent'sAgentCapabilitySetalready constrains argument-level safety. - Confirmed
AgentMemoryis scoped pertask_idin every reference usage - no global-sharing code path exists. - Confirmed no new cryptographic, network, or credential-handling surface is introduced by this package.
Tests¶
-
tests/unit/agents/mirrorssrc/mineproductivity/agents/1:1. - Coverage ≥95%.
- Unit tests per concrete agent category - at least one flagship agent per
AgentCategory, each against a scripted task with a known expectedAgentResult(§35). - Identity/equality tests, policy-gate tests, approval-lifecycle tests, failure-recovery tests, delegation tests,
simulation.ExperimentRunner/optimization.OptimizationExecutorcomposition tests, interface-only ABC contract tests, registry/discovery isolation tests, and concurrency stress tests as enumerated in design spec §35. - The six package acceptance proofs in design spec §35 (no-fact-recomputation, immutability, interface-purity, no-architectural-drift, no-provider-coupling, policy-enforcement) each independently verified and recorded in the PR description.
Documentation¶
-
agents/README.mdcomplete. - Every registered
Agent/Tooltype's docstring restates itsAgentMetadata.description/ToolMetadata.descriptionfor source-level readability.
Examples¶
-
examples/agents/01_single_agent_task.py- a singleAgentcategory executing oneTaskend-to-end viaTaskExecutor. -
examples/agents/02_policy_gated_approval.py- a scriptedAgentPolicyrequiring approval, driving aTaskthroughAwaitingApprovaltoCompletedvia a resolvedApprovalRequest. -
examples/agents/03_multi_agent_workflow.py- the design spec §19 worked example (ShiftSupervisor/Fleet/Maintenancecoordination viaWorkflowEngine), end-to-end. -
examples/agents/04_hypothesis_and_plan_search.py- a task composingsimulation.ExperimentRunnerand a task composingoptimization.OptimizationExecutor, each viaWorkflowEngine(§13). -
examples/agents/05_plugin_agent_and_tool.py- a third-party-styleAgentandToolsubclass registered via entry points, mirroringexamples/registry/01_register_and_discover.py's pattern. - All examples pass
mypy --strict+ruff.
Benchmarks¶
-
TaskRepository.get()/list()latency at representative task-population scale, recorded inbenchmark/reports/agents/. - A
WorkflowEngine-decomposed multi-task workflow's parallel-execution throughput at representative sub-task counts, recorded.
Certification¶
- Design spec §35's six package acceptance proofs pass and are recorded in the PR description (duplicated here from Tests for merge-gate visibility).
Type Hints, Mypy, Ruff, Coverage¶
- 100% type-hinted;
mypy --strictclean. -
ruff checkandruff format --checkclean. - Coverage report attached; ≥95%.
Release¶
-
CHANGELOG.mdupdated. - Root README dependency diagram cross-checked - confirm no forbidden import (
visualization) was introduced, and confirm no lower package gained a newagentsimport. - Version bump proposed and reviewed.
- Design spec §35's acceptance proofs re-verified as final merge gate.
Derived from 11_AI_Agents_Design_Specification.md. Keep in sync with the governing specification and with ADR-0011-AI-Agents.md.