feat: sync latest ARR implementation
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# ADR-001: Automatic Monthly Trigger And TOTAL PRICE Formula
|
||||
|
||||
- Status: Accepted
|
||||
- Status: Implemented
|
||||
- Date: 2026-07-29
|
||||
- Source: User correction in the current session
|
||||
|
||||
@@ -11,21 +11,26 @@ Earlier discussion incorrectly treated monthly-report generation as a separate u
|
||||
## Decision
|
||||
|
||||
1. The user's workflow begins and ends with uploading the XML.
|
||||
2. The Agent processes the XML and returns structured data for validation and database persistence.
|
||||
3. Only after that structured result is successfully committed does the business system automatically trigger the monthly-report processing program.
|
||||
4. `report_year`, `report_month`, `as_of_date`, or equivalent values may remain as internal execution and audit fields, but the backend must derive them. They are not user inputs in the primary workflow.
|
||||
2. ARR's frozen processor produces structured data for independent validation and database persistence; the production path has no Agent/MCP dependency.
|
||||
3. Only after that structured result is successfully committed does the business system emit `arr.daily_version_committed`; a dedicated worker process consumes it and runs the monthly-report program.
|
||||
4. `report_year`, `report_month`, `as_of_date`, or equivalent values may remain as internal execution and audit fields, but the backend must derive them. The worker uses committed retained `ARRIVAL` facts to select the affected month, and the greatest `ARRIVAL` actually included in the snapshot is the report's `as_of_date`/“更新至”. The XML filename and wall clock are never authorities for this value.
|
||||
5. The report keeps the `TOTAL PRICE` dimension/field. Each XLSX data-row cell must contain a formula with the business meaning:
|
||||
|
||||
`TOTAL PRICE = REAL PRICE × NIGHTS × NO_OF_ROOMS`
|
||||
|
||||
With the current 19-column layout, this is equivalent to `=R2*C2*G2` for row 2 and must fill relatively for later rows.
|
||||
6. The monthly page automatically discovers newly published versions. A user must not need a separate refresh action
|
||||
after the worker finishes.
|
||||
|
||||
## Consequences
|
||||
|
||||
- A manual month/as-of form or endpoint is not the primary product flow and must not be presented as a required user step.
|
||||
- The monthly processor may still accept internally supplied month/cutoff arguments from its orchestrator.
|
||||
- Existing manual-trigger UI/API code and static-cell workbook generation are implementation gaps, not the accepted requirement.
|
||||
- The exact internal event/outbox/worker mechanism and cutoff derivation policy remain implementation details to design and verify; they must not be delegated to the user.
|
||||
- The monthly processor may still accept internally supplied month/cutoff arguments through a controlled recovery CLI/API, but the primary page exposes none of them.
|
||||
- The dedicated worker leases outbox rows, retries transient publication failures, dead-letters exhausted events, and acknowledges success only after both registered artifacts are active/downloadable.
|
||||
- Durable `reporting` metadata records the snapshot identity, Finance daily-version lineage, channel manifest and local artifact identities without duplicating monthly business rows.
|
||||
- The implemented workbook writes and reopens one exact row-relative `TOTAL PRICE` formula per data row.
|
||||
- The portal uses a visibility-aware, non-overlapping list poll while the monthly tab is open and reloads immediately
|
||||
when the tab becomes active again. A transient background error keeps the last good list and retries automatically.
|
||||
|
||||
## Supersedes
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# ADR-002: Controlled Agent Delegates Validation To System Boundaries
|
||||
|
||||
- Status: Accepted
|
||||
- Date: 2026-07-29
|
||||
- Source: User clarification in the current session
|
||||
|
||||
## Context
|
||||
|
||||
The ARR data-processing Agent is a dedicated Agent that accepts only business-system messages from a fixed,
|
||||
controlled entrypoint. Earlier Main Prompt revisions repeated contract, attachment, identity, hash and source
|
||||
checks already enforced by ARR code. A manual SuperAgent chat test also encouraged chat-input rejection logic,
|
||||
even though that entrypoint is outside the production contract.
|
||||
|
||||
The implementation already has three authoritative boundaries:
|
||||
|
||||
1. `ProcessingRequest` and `OssProcessingMessageBuilder` validate and construct the fixed PROGRAM_INPUT.
|
||||
2. `arr-opera-daily-ingest` owns deterministic business processing and output validation.
|
||||
3. ARR MCP validates the grant and payload, independently replays the source XML, and commits in a database
|
||||
transaction.
|
||||
|
||||
## Decision
|
||||
|
||||
1. Main Prompt trusts PROGRAM_INPUT supplied by the controlled ARR entrypoint and does not repeat field,
|
||||
attachment, source, identity, hash or Schema validation.
|
||||
2. The Agent performs only fixed orchestration: one OSS fetch, one Skill run, one result read, at most one MCP
|
||||
submission, and one final output.
|
||||
3. Processing failure does not call MCP. MCP `committed` or `already_committed` remains the only successful
|
||||
submission outcome recognized by the Agent.
|
||||
4. Manual chat-upload behavior is not a production acceptance criterion. End-to-end testing starts at ARR Web
|
||||
or the equivalent controlled business-system entrypoint.
|
||||
5. If the Agent is ever exposed to untrusted/general inputs, validation must be added at the API/gateway boundary
|
||||
and this decision revisited; prompt prose must not be treated as the security boundary.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The Main Prompt is shorter and avoids redundant LLM work and token/latency overhead.
|
||||
- Business and security validation remains deterministic in code rather than probabilistic in the Agent.
|
||||
- The fixed entrypoint and its access controls become an explicit operational prerequisite.
|
||||
- Direct SuperAgent chat tests may be useful for isolated Skill experiments but cannot prove or invalidate the
|
||||
production ingestion flow.
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# ADR-003: Public-read source URL for fetch_oss_file
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Date
|
||||
|
||||
2026-07-30
|
||||
|
||||
## Context
|
||||
|
||||
Controlled SuperAgent traces showed that `fetch_oss_file` accepts `object_uri` and `filename`. An `oss://`
|
||||
request failed with `public_endpoint_missing`, while earlier HTTPS attempts reached file-type handling. The user
|
||||
confirmed that the installed Tool reads a publicly accessible OSS address without a Provider and that the OSS
|
||||
deployment is `public-read`.
|
||||
|
||||
The previous ARR adapter explicitly wrote every object with object ACL `private`. That overrides a public-read
|
||||
bucket and would make a generated public URL unusable. At the same time, making every processing output public
|
||||
would unnecessarily widen exposure.
|
||||
|
||||
## Decision
|
||||
|
||||
1. ARR requires the integration bucket to report bucket ACL `public-read`; anonymous writes remain forbidden.
|
||||
2. Only `committed/source_xml/source.xml` is written with object ACL `public-read`. Staged objects, generated
|
||||
reports, result JSON and exchange objects remain explicitly `private`.
|
||||
3. `arr-opera-daily-program-input-3` includes a required `oss.url` generated by ARR as
|
||||
`https://{bucket}.oss-{region}.aliyuncs.com/{encoded-object-key}`. It contains no query signature or secret.
|
||||
4. The Main Prompt passes `oss.url` unchanged as `fetch_oss_file.object_uri` and the canonical attachment name
|
||||
as `filename`, exactly once. It must not construct `oss://`, sign or substitute another URL.
|
||||
5. XML extension/MIME acceptance remains a separate platform Tool configuration requirement.
|
||||
|
||||
## Rationale
|
||||
|
||||
ARR owns the bucket, endpoint and immutable object key, so it can generate one deterministic address without
|
||||
asking the Agent to infer storage semantics. Object-level ACL selection satisfies anonymous source download
|
||||
while keeping intermediate and output artifacts private.
|
||||
|
||||
## Consequences
|
||||
|
||||
- `fetch_oss_file` needs no OSS Provider, AccessKey or signed URL for this flow.
|
||||
- A committed source XML is anonymously readable to anyone who has its URL; the URL is not a secret or an
|
||||
authorization mechanism. Retention, access logging and public-source privacy review remain deployment duties.
|
||||
- Readiness now rejects a private bucket for this integration.
|
||||
- Deploying code and Prompt changes does not by itself allow XML; the platform must permit `.xml` and
|
||||
`application/xml` if it still returns `extension_not_allowed`.
|
||||
|
||||
## Supersedes
|
||||
|
||||
- The private-object/credential-backed Provider assumption in earlier implementation notes and the historical
|
||||
`oss://` Prompt experiment.
|
||||
|
||||
## Related
|
||||
|
||||
- `arr_processing/source_message.py`
|
||||
- `arr_storage/aliyun_oss_v2.py`
|
||||
- `prompts/arr_opera_daily_program_input.schema.json`
|
||||
- `prompts/arr_opera_daily_main_agent_prompt.md`
|
||||
- `.project-docs/50-evidence/topics/2026-07-30-superagent-fetch-oss-prompt-experiment.md`
|
||||
@@ -0,0 +1,52 @@
|
||||
# ADR-004: ARR owns deterministic processing and terminal ingestion
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Date
|
||||
|
||||
2026-07-30
|
||||
|
||||
## Context
|
||||
|
||||
The remote Agent successfully fetched the exact XML and ran the deterministic processor, but model-mediated MCP
|
||||
arguments reduced a valid 135-record result to 20 records. Prompt changes could guide tool use but could not guarantee
|
||||
lossless transport of a large structured payload. The user authorized a separate ARR2.0 workspace whose production XML
|
||||
path has no Agent involvement.
|
||||
|
||||
## Decision
|
||||
|
||||
ARR2.0 runs the frozen `process_daily.py` itself after upload. It stores source and output artifacts as private immutable
|
||||
objects, validates a canonical `DeliveryEnvelope` with the existing independent validator, and commits through
|
||||
`PostgresIngestionRepository` in one transaction. The upload request waits for a terminal success or failure result.
|
||||
|
||||
The active runtime does not call SuperAgent, expose MCP, issue submission/read grants, use prompts or require a public
|
||||
source URL. Existing 009/010 database tables remain for historical compatibility but are not used by this path.
|
||||
|
||||
## Rationale
|
||||
|
||||
This keeps deterministic business logic, source/artifact identity checks, independent validation, version activation,
|
||||
idempotent delivery replay and atomic Finance writes while removing the unreliable model-serialization boundary.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Upload latency now includes processing, validation and database commit.
|
||||
- Controlled processor failures are persisted through the normal failed-delivery contract; infrastructure failures use
|
||||
explicit run/attempt terminal transitions and an outbox event.
|
||||
- Fresh user uploads create fresh jobs and follow existing business-date versioning; replay of the same delivery remains
|
||||
idempotent.
|
||||
- All ARR-managed object ACLs are private even when the bucket itself is public-read.
|
||||
- The original `/Users/chillishark/ARR项目0727` workspace remains unchanged as the ARR1 rollback baseline.
|
||||
|
||||
## Supersedes
|
||||
|
||||
- ADR-002 for the ARR2.0 production XML path only.
|
||||
- ADR-003 for the ARR2.0 production XML path only.
|
||||
|
||||
## Related
|
||||
|
||||
- `arr_web/programmatic.py`
|
||||
- `arr_processing/local.py`
|
||||
- `arr_web/processing_runtime.py`
|
||||
- `tests/test_arr_programmatic.py`
|
||||
@@ -4,21 +4,15 @@
|
||||
|
||||
| ID | Decision | Status | Date | Applies To | Detail |
|
||||
|---|---|---|---|---|---|
|
||||
| ADR-001 | 月报在 Agent 结构化结果成功入库后由业务系统自动触发;`TOTAL PRICE` 为 Excel 公式字段 | Accepted | 2026-07-29 | 上传链路、月报触发、XLSX 输出 | [ADR-001](ADR-001-automatic-monthly-trigger-and-total-price-formula.md) |
|
||||
| ADR-004 | ARR2.0 owns deterministic processing, artifact validation and terminal ingestion; no Agent/MCP in production XML flow | Accepted | 2026-07-30 | Upload, processing runtime, OSS ACL, validation, deployment | [ADR-004](ADR-004-arr-owned-programmatic-processing.md) |
|
||||
| ADR-001 | 月报由独立 worker 自动触发;“更新至”取最新纳入的 `ARRIVAL`;发布后页面自动新增;`TOTAL PRICE` 为公式字段 | Implemented | 2026-07-29 | 月报触发、持久化、页面同步、XLSX 输出 | [ADR-001](ADR-001-automatic-monthly-trigger-and-total-price-formula.md) |
|
||||
|
||||
## Superseded Decisions
|
||||
## Superseded For ARR2.0
|
||||
|
||||
| ID | Decision | Superseded By | Date |
|
||||
|---|---|---|---|
|
||||
| Conversation draft | 用户点击月报按钮并提交或选择年月/截止范围;金额写静态值 | ADR-001 | 2026-07-29 |
|
||||
| ADR-003 | Public-read source URL passed to `fetch_oss_file` | ADR-004 | 2026-07-30 |
|
||||
| ADR-002 | Controlled Agent orchestrates Skill and MCP submission | ADR-004 | 2026-07-30 |
|
||||
| Conversation draft | Manual monthly parameters and static total values | ADR-001 | 2026-07-29 |
|
||||
|
||||
## Decision Criteria
|
||||
|
||||
Create or update an ADR when a choice affects:
|
||||
|
||||
- project positioning
|
||||
- architecture boundaries
|
||||
- public behavior
|
||||
- data model
|
||||
- long-term maintenance
|
||||
- user-facing workflow
|
||||
ADR-002/003 remain factual history for the separate ARR1 rollback workspace; they are not ARR2.0 runtime decisions.
|
||||
|
||||
Reference in New Issue
Block a user