feat(atlas): Matter Frame agent on official AgentCore structure [Story-1178]

Story 1178Epic None63 files · +13688/−45

PR #40 · pramaan-io/pramaan-agents · merged 2026-06-11

Why this matters

Who signs when the AI cites a clause that does not exist?

A fabricated citation in a real filing is the catastrophe this PR closes.

No snapshot, no seal — a hallucinated clause walks straight into a filing.

The fix — Junior drafts, senior signs, file preserved.

How it flows

sequenceDiagram
  autonumber
  participant counsel as Counsel (senior partner)
  participant agent as Atlas agent (junior associate)
  participant model as Kimi K2.5 on Bedrock
  participant runtime as Runtime (file room)
  counsel->>agent: intake payload
  agent->>agent: build_intake_input
  agent->>model: BAML call (one retry)
  model->>agent: AtlasTurn: proposal + questions
  agent->>runtime: proposal
  runtime->>runtime: _wrap_proposal: freeze source_snapshot + requires_counsel_approval
  runtime-->>counsel: draft for review
  counsel->>runtime: Save (approve)

package-lock.json · +5499 — new methods

Methodin → outwhat it does
TypeBuilder(class)
__init__(tb)
AtlasTrigger() → "AtlasTriggerViewer"

What changed, file by file

Generated BAML type builder for the Atlas data classes (Trigger, Action, IntakeInput, Turn, etc.); regenerated by the new baml_src so the client matches the official AgentCore Atlas schema.

new classsignature
TypeBuilder(class)
__init__(tb)
AtlasTrigger() → "AtlasTriggerViewer"
AtlasAction() → "AtlasActionViewer"
AtlasExplainOutput() → "AtlasExplainOutputViewer"
AtlasHistoryMessage() → "AtlasHistoryMessageViewer"
AtlasIntakeInput() → "AtlasIntakeInputViewer"
AtlasOpenQuestion() → "AtlasOpenQuestionViewer"
AtlasParty() → "AtlasPartyViewer"
AtlasProposalCore() → "AtlasProposalCoreViewer"
AtlasRefined() → "AtlasRefinedViewer"
AtlasRefinedValue() → "AtlasRefinedValueViewer"
AtlasReframeOutput() → "AtlasReframeOutputViewer"
AtlasRelief() → "AtlasReliefViewer"
AtlasStalenessOutput() → "AtlasStalenessOutputViewer"
AtlasTurn() → "AtlasTurnViewer"
AtlasTriggerAst(class)
type() → baml_py.FieldType
values() → "AtlasTriggerValues"
AtlasTriggerViewer(class)
list_values() → typing.List[typing.Tuple[str, type_builder.EnumValueViewer]]
AtlasTriggerValues(class)
CounselRequest() → type_builder.EnumValueViewer
DocumentsAdded() → type_builder.EnumValueViewer
StageChanged() → type_builder.EnumValueViewer
ManualReframe() → type_builder.EnumValueViewer
AtlasActionAst(class)
props() → "AtlasTurnProperties"
AtlasActionViewer(class)
list_properties() → typing.List[typing.Tuple[str, type_builder.ClassPropertyViewer]]
AtlasActionProperties(class)
kind() → type_builder.ClassPropertyViewer
target_field() → type_builder.ClassPropertyViewer
AtlasExplainOutputAst(class)
AtlasExplainOutputViewer(class)
AtlasExplainOutputProperties(class)
explanation_md() → type_builder.ClassPropertyViewer
prompt_version() → type_builder.ClassPropertyViewer
schema_version() → type_builder.ClassPropertyViewer
AtlasHistoryMessageAst(class)
AtlasHistoryMessageViewer(class)
AtlasHistoryMessageProperties(class)
role() → type_builder.ClassPropertyViewer
text() → type_builder.ClassPropertyViewer
AtlasIntakeInputAst(class)
AtlasIntakeInputViewer(class)
AtlasIntakeInputProperties(class)
firm_id() → type_builder.ClassPropertyViewer
form_id() → type_builder.ClassPropertyViewer
matter_id() → type_builder.ClassPropertyViewer
template_name() → type_builder.ClassPropertyViewer
proceeding_types() → type_builder.ClassPropertyViewer
participant_labels() → type_builder.ClassPropertyViewer
filing_types() → type_builder.ClassPropertyViewer
title() → type_builder.ClassPropertyViewer
case_ref() → type_builder.ClassPropertyViewer
opened_on() → type_builder.ClassPropertyViewer
core_dispute_text() → type_builder.ClassPropertyViewer
outcome_sought_text() → type_builder.ClassPropertyViewer
value_at_stake_minor() → type_builder.ClassPropertyViewer
value_at_stake_currency() → type_builder.ClassPropertyViewer
value_at_stake_not_monetary() → type_builder.ClassPropertyViewer
parties() → type_builder.ClassPropertyViewer
AtlasOpenQuestionAst(class)
AtlasOpenQuestionViewer(class)
AtlasOpenQuestionProperties(class)
id() → type_builder.ClassPropertyViewer
field() → type_builder.ClassPropertyViewer
question_md() → type_builder.ClassPropertyViewer
actions() → type_builder.ClassPropertyViewer
AtlasPartyAst(class)
AtlasPartyViewer(class)
AtlasPartyProperties(class)
display_name() → type_builder.ClassPropertyViewer
side() → type_builder.ClassPropertyViewer
label() → type_builder.ClassPropertyViewer
AtlasProposalCoreAst(class)
AtlasProposalCoreViewer(class)
AtlasProposalCoreProperties(class)
description() → type_builder.ClassPropertyViewer
refined() → type_builder.ClassPropertyViewer
AtlasRefinedAst(class)
AtlasRefinedViewer(class)
AtlasRefinedProperties(class)
core_dispute() → type_builder.ClassPropertyViewer
relief_sought() → type_builder.ClassPropertyViewer
value_at_stake() → type_builder.ClassPropertyViewer
proceeding_type() → type_builder.ClassPropertyViewer
AtlasRefinedValueAst(class)
AtlasRefinedValueViewer(class)
AtlasRefinedValueProperties(class)
currency() → type_builder.ClassPropertyViewer
amount_minor() → type_builder.ClassPropertyViewer
basis() → type_builder.ClassPropertyViewer
AtlasReframeOutputAst(class)
AtlasReframeOutputViewer(class)
AtlasReframeOutputProperties(class)
proposed_frame_text() → type_builder.ClassPropertyViewer
changed_summary() → type_builder.ClassPropertyViewer
AtlasReliefAst(class)
AtlasReliefViewer(class)
AtlasReliefProperties(class)
principal() → type_builder.ClassPropertyViewer
interest() → type_builder.ClassPropertyViewer
costs() → type_builder.ClassPropertyViewer
ancillary() → type_builder.ClassPropertyViewer
AtlasStalenessOutputAst(class)
AtlasStalenessOutputViewer(class)
AtlasStalenessOutputProperties(class)
is_stale() → type_builder.ClassPropertyViewer
reason() → type_builder.ClassPropertyViewer
AtlasTurnAst(class)
AtlasTurnViewer(class)
AtlasTurnProperties(class)
verdict() → type_builder.ClassPropertyViewer
next_message_md() → type_builder.ClassPropertyViewer
is_terminal() → type_builder.ClassPropertyViewer
open_questions() → type_builder.ClassPropertyViewer
proposal() → type_builder.ClassPropertyViewer

BAML schema source defining Atlas data classes and the AtlasIntake, AtlasExplain, AtlasReframe, and AtlasStaleness BAML functions — the source of truth for the intake contract.

new classsignature
AtlasParty(class)
AtlasHistoryMessage(class)
AtlasRefinedValue(class)
AtlasRefined(class)
AtlasTurn(class)
AtlasExplainOutput(input, field)
AtlasReframeOutput(input)
AtlasStalenessOutput(input, current_frame_text)

BAML runtime plumbing for call, stream, and parse; the generated client surface required by the self-contained app/atlas/ deploy unit.

new classsignature
BamlCallOptions(class)
_ResolvedBamlOptions(tb, client_registry, collectors, env_vars, tags)
DoNotUseDirectlyCallManager(class)
__getstate__()
__setstate__(state)
__resolve() → _ResolvedBamlOptions
on_tick_wrapper()
merge_options(options) → "DoNotUseDirectlyCallManager"
call_function_async(function_name, args) → baml_py.baml_py.FunctionResult
call_function_sync(function_name, args) → baml_py.baml_py.FunctionResult
create_async_stream(function_name, args) → typing.Tuple[baml_py.baml_py.RuntimeContextManager, baml_py.baml_py.FunctionResultStream]
create_sync_stream(function_name, args) → typing.Tuple[baml_py.baml_py.RuntimeContextManager, baml_py.baml_py.SyncFunctionResultStream]
create_http_request_async(function_name, args, mode) → baml_py.baml_py.HTTPRequest
create_http_request_sync(function_name, args, mode) → baml_py.baml_py.HTTPRequest
parse_response(function_name, llm_response, mode) → typing.Any
disassemble(function) → None

Synchronous BAML client exposing AtlasIntake, AtlasExplain, AtlasReframe, and AtlasStaleness; lets the official AgentCore entrypoint invoke BAML functions synchronously.

new classsignature
BamlSyncClient(__options, __stream_client, __http_request, __http_stream_request, __llm_response_parser)
__getstate__()
__setstate__(state)
with_optionsdef with_options(self, tb: typing.Optional[type_builder.TypeBuilder] = None, client_registry: typing.Optional[baml_py.baml_py.ClientRegistry] = None, client: typing.Optional[str] = None, collector: typing.Optional[typing.Union[baml_py.baml_
stream()
request()
stream_request()
parse()
parse_stream()
AtlasExplain(input, field, selected_span, current_value, baml_options) → baml_py.baml_py.HTTPRequest
AtlasIntakedef AtlasIntake(self, input: types.AtlasIntakeInput,history: typing.List["types.AtlasHistoryMessage"],counsel_message: typing.Optional[str],is_final_turn: bool,target_field: typing.Optional[str] = None,selected_span: typing.Optional[str] =
AtlasReframe(input, current_frame_text, trigger, reason, baml_options) → baml_py.baml_py.HTTPRequest
AtlasStaleness(input, current_frame_text, trigger, reason, baml_options) → baml_py.baml_py.HTTPRequest
BamlStreamClient(__options)
BamlHttpRequestClient(__options)
BamlHttpStreamRequestClient(__options)
New fields: options : BamlCallOptions

Async mirror of the sync BAML client; needed for streaming AtlasTurn responses inside the AgentCore entrypoint.

new classsignature
BamlAsyncClient(__options, __stream_client, __http_request, __http_stream_request, __llm_response_parser)
with_optionsdef with_options(self, tb: typing.Optional[type_builder.TypeBuilder] = None, client_registry: typing.Optional[baml_py.baml_py.ClientRegistry] = None, client: typing.Optional[str] = None, collector: typing.Optional[typing.Union[baml_py.baml_
stream()
request()
stream_request()
parse()
parse_stream()
AtlasExplain(input, field, selected_span, current_value, baml_options) → baml_py.baml_py.HTTPRequest
AtlasIntakeasync def AtlasIntake(self, input: types.AtlasIntakeInput,history: typing.List["types.AtlasHistoryMessage"],counsel_message: typing.Optional[str],is_final_turn: bool,target_field: typing.Optional[str] = None,selected_span: typing.Optional[s
AtlasReframe(input, current_frame_text, trigger, reason, baml_options) → baml_py.baml_py.HTTPRequest
AtlasStaleness(input, current_frame_text, trigger, reason, baml_options) → baml_py.baml_py.HTTPRequest
BamlStreamClient(__options)
BamlHttpRequestClient(__options)
BamlHttpStreamRequestClient(__options)
New fields: options : BamlCallOptions

The Atlas agent core: intake construction, source snapshot, one-retry resilience, and the streaming turn / explain / reframe / staleness entry points that enforce assume-and-flag intake.

new methodsignature
_is_final_turn(history, config) → bool
build_intake_input(payload) → AtlasIntakeInput
source_snapshot(intake_input) → dict[str, Any]
provenance(config) → dict[str, Any]
_error_turn() → AtlasTurn
stream_atlas_turnasync def stream_atlas_turn( *, intake_input: AtlasIntakeInput, history: Sequence[AtlasHistoryMessage] | None = None, counsel_message: str | None = None, target_field: str | None = None, selected_span: str | None = None, config: AtlasConfig
run_atlas_turn(intake_input, history, counsel_message, config) → AtlasTurn
run_explain(intake_input, field, selected_span, current_value, config) → AtlasExplainOutput
run_staleness(intake_input, current_frame_text, trigger, reason, config) → AtlasStalenessOutput
run_reframe(intake_input, current_frame_text, trigger, reason, config) → AtlasReframeOutput
New fields: last_exc : Exception | Nonefinal : AtlasTurn | None

Runtime wrapper that seals every proposal with a frozen source_snapshot and sets requires_counsel_approval — the truth boundary that stops a proposal becoming a filing on its own.

new methodsignature
_dump(obj) → Any
_wrap_proposal(proposal, snapshot) → dict[str, Any] | None
_turn_event(turn, snapshot, stamp) → dict[str, Any]
handle_request(request) → Any

Generated Python types matching the BAML schema; the typed contract for every BAML function Atlas calls.

new classsignature
Check(class)
Checked(class)
get_checks(checks) → typing.List[Check]
all_succeeded(checks) → bool
AtlasTrigger(class)
AtlasAction(class)
AtlasExplainOutput(class)
AtlasHistoryMessage(class)
AtlasIntakeInput(class)
AtlasOpenQuestion(class)
AtlasParty(class)
AtlasProposalCore(class)
AtlasRefined(class)
AtlasRefinedValue(class)
AtlasReframeOutput(class)
AtlasRelief(class)
AtlasStalenessOutput(class)
AtlasTurn(class)
New fields: name : strexpression : strstatus : strvalue : CheckTexplanation_md : strtext : strfirm_id : strtitle : strcore_dispute_text : stroutcome_sought_text : strvalue_at_stake_not_monetary : boolid : strquestion_md : strdisplay_name : strdescription : strcore_dispute : strproceeding_type : strproposed_frame_text : strchanged_summary : stris_stale : boolreason : strnext_message_md : stris_terminal : bool

Stream-state Python types for BAML streaming; lets the agent consume partial AtlasTurn outputs as they arrive.

new classsignature
StreamState(class)
AtlasAction(class)
AtlasExplainOutput(class)
AtlasHistoryMessage(class)
AtlasIntakeInput(class)
AtlasOpenQuestion(class)
AtlasParty(class)
AtlasProposalCore(class)
AtlasRefined(class)
AtlasRefinedValue(class)
AtlasReframeOutput(class)
AtlasRelief(class)
AtlasStalenessOutput(class)
AtlasTurn(class)
New fields: value : StreamStateValueT

The @app.entrypoint `invoke` for the AgentCore Atlas agent — the single official entrypoint required by the new CodeZip deploy unit.

new methodsignature
invoke(payload, context)

Atlas agent manifest (name, role, baml_function); registers Atlas as the 'Matter Frame' agent inside the official AgentCore layout.

New fields: name : Atlasrole : Matter Framebaml_function : AtlasStaleness

BAML log and decorator configuration helpers; configures BAML logging for the regenerated client.

new methodsignature
_deprecated(message)
decorator(func) → typing.Callable[pT, rT]
new_func()
get_log_level()
set_log_level(level)
set_log_json_mode()
set_log_max_chunk_length()
set_log_max_message_length()

AtlasConfig loading model id, region, temperature, max_tokens, and prompt/schema versions — makes the Kimi K2.5 swap a one-line change via ATLAS_MODEL_ID.

new classsignature
_load_manifest() → dict[str, Any]
AtlasConfig(models, model_id, region, temperature, max_tokens)
load() → AtlasConfig
from_env() → AtlasConfig
New fields: prompt_version : strschema_version : str

LLM response parsers for the Atlas BAML functions; maps raw model output into typed stream_types.

new classsignature
LlmResponseParser(__options)
AtlasExplain(llm_response, baml_options) → stream_types.AtlasExplainOutput
AtlasIntake(llm_response, baml_options) → stream_types.AtlasTurn
AtlasReframe(llm_response, baml_options) → stream_types.AtlasReframeOutput
AtlasStaleness(llm_response, baml_options) → stream_types.AtlasStalenessOutput
LlmStreamParser(__options)

Builds the BAML ClientRegistry for the configured model; resolves which Bedrock client Atlas actually calls at runtime.

new classsignature
HasModelConfig(class)
build_client_registry(config, client_name) → ClientRegistry
New fields: model_id : strregion : strtemperature : floatmax_tokens : int

AgentIdentity dataclass (key, display_name) used for stable agent identity in logging and provenance.

new classsignature
AgentIdentity(key, display_name)

Generated BAML event watchers (BlockEvent, VarEvent, EventCollector); observability surface for the BAML client.

new classsignature
BlockEvent(class)
VarEvent(class)
__init__(variable_name, value, timestamp, function_name)
InternalEventBindings(class)
EventCollectorInternal(class)
__handlers__() → InternalEventBindings
New fields: function_name : str

BAML environment variable reset helper; clears BAML env state for test isolation.

new methodsignature
reset_baml_env_vars(env_vars)

BAML trace flush helper; lets the agent flush BAML traces cleanly at the end of a request.

new methodsignature
flush()

Inlines the baml_src content next to the regenerated client so the deploy unit is fully self-contained.

new methodsignature
get_baml_files()

CI pipeline update adding ruff and the new app/atlas offline unit-test steps to match the new self-contained layout.

New fields: run : |

Files changed (63)

File±
.github/workflows/ci.yml+20 −2
AGENTS.md+60 −41
agentcore/.cli/deployed-state.json+17
agentcore/.gitignore+15
agentcore/.llm-context/README.md+16
agentcore/.llm-context/agentcore.ts+438
agentcore/.llm-context/aws-targets.ts+45
agentcore/AGENTS.md+35
agentcore/agentcore.json+33
agentcore/aws-targets.json+7
agentcore/cdk/.gitignore+9
agentcore/cdk/.npmignore+6
agentcore/cdk/.prettierrc+8
agentcore/cdk/README.md+26
agentcore/cdk/bin/cdk.ts+176
agentcore/cdk/cdk.json+88
agentcore/cdk/jest.config.js+9
agentcore/cdk/lib/cdk-stack.ts+244
agentcore/cdk/package-lock.json ★+5499
agentcore/cdk/package.json+30
agentcore/cdk/test/cdk.test.ts+30
agentcore/cdk/tsconfig.json+28
app/AGENTS.md+150
app/atlas/.gitignore+3
app/atlas/AGENTS.md+59
app/atlas/README.md+1
app/atlas/agent.py+273
app/atlas/assets/atlas-intake.png+0
app/atlas/atlas.yaml+112
app/atlas/baml_client/__init__.py+60
app/atlas/baml_client/async_client.py+276
app/atlas/baml_client/config.py+102
app/atlas/baml_client/globals.py+35
app/atlas/baml_client/inlinedbaml.py+21
app/atlas/baml_client/parser.py+82
app/atlas/baml_client/runtime.py+361
app/atlas/baml_client/stream_types.py+116
app/atlas/baml_client/sync_client.py+284
app/atlas/baml_client/tracing.py+22
app/atlas/baml_client/type_builder.py ★+843
app/atlas/baml_client/type_map.py+61
app/atlas/baml_client/types.py+140
app/atlas/baml_client/watchers.py+44
app/atlas/baml_src/atlas.baml+459
app/atlas/baml_src/clients.baml+41
app/atlas/baml_src/generator.baml+6
app/atlas/client_registry.py+74
app/atlas/config.py+97
app/atlas/identity.py+50
app/atlas/main.py+116
app/atlas/pyproject.toml+28
app/atlas/runtime.py+157
app/atlas/tests/test_atlas_agent.py+89
app/atlas/tests/test_atlas_runtime.py+133
app/atlas/uv.lock ★+2225
baml_src/clients.baml+13
docs/notes/atlas-intake-ux-research.md+155
docs/walkthroughs/story-1178-walkthrough.html+112
pyproject.toml+1 −1
requirements-dev.in+4
requirements.in+9
src/baml_client/inlinedbaml.py+1 −1
src/pramaan_agents/AGENTS.md+34