feat: sync latest ARR implementation
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
# Probe Stream Semantics Before Designing Trace Capture
|
||||
|
||||
## Trigger
|
||||
|
||||
The user pointed to SuperAgent's
|
||||
`/messages/stream?include_trace=true` capability after the first task-log
|
||||
implementation reconstructed only ARR database facts. The URL alone did not
|
||||
establish whether it could replay an existing run or only create a new one.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `OPTIONS`, `HEAD` and `GET` returned `405 Allow: POST`.
|
||||
- A no-business-data probe showed the first SSE event was `run.started`, followed
|
||||
by task/step updates and a terminal run event/end marker.
|
||||
- Repeating the exact same message and idempotency key created a different
|
||||
`run_id`; the endpoint did not replay or deduplicate the prior run.
|
||||
|
||||
## Lesson
|
||||
|
||||
Do not infer read/replay semantics from an observability query parameter. Before
|
||||
wiring trace capture, verify the HTTP method, event order, connection lifetime
|
||||
and duplicate-submission behavior with an isolated harmless request. If trace is
|
||||
emitted only while creating the run, return the handle from the first start event
|
||||
and keep consuming that same connection; never POST again merely to recover
|
||||
diagnostics.
|
||||
|
||||
## Reusable Check
|
||||
|
||||
1. Probe non-mutating methods first and inspect `Allow`/Content-Type.
|
||||
2. Use a separate no-PII session for the smallest authorized POST probe.
|
||||
3. Record only schema/event names until the privacy boundary is known.
|
||||
4. Test identical idempotency keys explicitly; do not assume endpoint parity.
|
||||
5. Treat an uncertain post-send failure as ambiguous when the server cannot
|
||||
prove deduplication.
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# Reflection: Verify Runtime Target and Entrypoint Before E2E
|
||||
|
||||
## Trigger
|
||||
|
||||
Debugging initially followed the obsolete local MCP/ngrok path even after the user had moved services to a server environment. A subsequent SuperAgent export was also a manual chat-upload processor test rather than the accepted ARR Web upload flow.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
Before changing credentials or diagnosing transport, identify the exact MCP URL currently saved in SuperAgent and verify that the probe targets that runtime. Before calling a run “end to end,” require an ARR-created `job_id`, attempt identity, OSS provenance, submission grant, MCP receipt, and database evidence.
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
The local temporary gateway was authenticated successfully but was irrelevant to the server deployment. The manual Agent run processed XML and presented files without `fetch_oss_file` or `arr_submit_processing_result`, so it could never prove the database path.
|
||||
|
||||
## Root Cause
|
||||
|
||||
- Stale runtime assumption
|
||||
- Test-mode confusion
|
||||
- Acceptance gate applied too late
|
||||
|
||||
## Evidence
|
||||
|
||||
- User correction that the active MCP is server-side rather than the temporary local tunnel
|
||||
- `.project-docs/50-evidence/topics/2026-07-29-superagent-manual-xml-run-bypassed-mcp.md`
|
||||
- `deploy/README.md`
|
||||
|
||||
## Lesson
|
||||
|
||||
Use a two-part preflight for every external E2E:
|
||||
|
||||
1. Record the exact configured endpoint and confirm the probe reaches that endpoint.
|
||||
2. Classify the test entry as manual processor validation or ARR program-triggered ingestion before interpreting any Agent status.
|
||||
|
||||
Never synchronize credentials or restart a runtime until both checks identify it as the active target.
|
||||
|
||||
## Action
|
||||
|
||||
- Preserve the exported-run evidence and current blocker.
|
||||
- Require server Web upload plus authoritative MCP/database signals for the next acceptance attempt.
|
||||
|
||||
## Promotion
|
||||
|
||||
Promoted to current-state risks and the evidence index. No architecture decision changes.
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# Reflection: Backend Automation Must Reconcile The Open UI
|
||||
|
||||
## Trigger
|
||||
|
||||
The worker published monthly reports automatically, but the open page still required a person to click “刷新” before
|
||||
the new version appeared.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
An automated business workflow includes both durable backend completion and automatic reconciliation of the visible
|
||||
user interface. Once publication is committed, an open list should discover it without another user action.
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
The page loaded monthly versions only at boot or from a refresh-button handler. Backend automation was complete, but
|
||||
the UI held a stale snapshot indefinitely.
|
||||
|
||||
## Root Cause
|
||||
|
||||
- Backend completion and frontend observability were treated as separate acceptance concerns.
|
||||
- The asynchronous worker cannot return its result through the original upload HTTP response.
|
||||
- No polling, push channel or visibility-resume contract existed for the monthly list.
|
||||
|
||||
## Lesson
|
||||
|
||||
For asynchronous publication, acceptance must cover how an already-open client observes the committed result. Prefer a
|
||||
bounded, visibility-aware synchronization mechanism that avoids overlapping requests and preserves the last good state.
|
||||
|
||||
## Action
|
||||
|
||||
- Poll only while the monthly tab/document is visible and reload immediately when it becomes active.
|
||||
- Keep the last good rows on transient background errors and retry automatically.
|
||||
- Remove the manual refresh control from the primary workflow.
|
||||
- Verify both rendered state and actual repeated API requests.
|
||||
|
||||
## Promotion
|
||||
|
||||
Promoted to ADR-001, success criteria, business rules, architecture data flow and the Web static contract tests.
|
||||
@@ -0,0 +1,54 @@
|
||||
# Reflection: Coordinate Hot Static Assets With The Long-Lived Backend
|
||||
|
||||
## Trigger
|
||||
|
||||
The active port-8766 Python process predated the application-login routes, but it reads HTML/CSS/JavaScript from the
|
||||
workspace on every request. Editing logout/login frontend assets therefore created a temporary new-frontend / old-backend
|
||||
combination before any intentional process restart.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
A route-contract change should activate as one compatible release: the frontend should not advertise a control whose
|
||||
backend endpoint is absent, and a fail-closed backend should not be restarted until required credentials exist.
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
The long-lived process continued issuing anonymous CSRF sessions without `username` and returned 404 for `/login`,
|
||||
while newer static files were immediately visible from disk. Restarting it without credentials would have taken the
|
||||
whole portal offline.
|
||||
|
||||
## Root Cause
|
||||
|
||||
- Static assets and Python route code had different activation lifecycles.
|
||||
- The current workstation process is manually coordinated rather than deployed as one immutable image/restart.
|
||||
- Login correctly fails startup closed, so activation depends on an operator-owned secret choice.
|
||||
|
||||
## Evidence
|
||||
|
||||
- Files: `arr_web/app.py`, `arr_web/static/app.js`, `arr_web/static/h5.js`
|
||||
- Runtime: PID 37865 on port 8766
|
||||
- Evidence: `50-evidence/topics/2026-07-30-web-login-runtime-mismatch.md`
|
||||
- Verification: old `/api/session` shape lacks `username`; old `/login` returns 404; isolated new runtime passes login/logout.
|
||||
|
||||
## Lesson
|
||||
|
||||
Treat hot-read static files plus a long-lived backend as a rolling mixed-version deployment. Before editing, inspect the
|
||||
active route/session contract. Make new controls feature-detect the new response shape and stay hidden on the old one;
|
||||
then restart once only after every fail-closed runtime input is ready.
|
||||
|
||||
## Action
|
||||
|
||||
- Logout controls start hidden and are revealed only when `/api/session` returns an authenticated `username`.
|
||||
- Keep an old process running until every fail-closed secret exists; if it has already exited, restore only after the
|
||||
complete previous non-secret runtime composition is also recovered.
|
||||
- Store the Web password and OSS credentials in Keychain. The user-local launcher contains only allowlisted route
|
||||
parsing, paths and Keychain labels; it never commits or prints values.
|
||||
- A launchd-owned process cannot read this Desktop-hosted runtime under the current macOS privacy boundary. The active
|
||||
local workaround is a desktop-authorized detached Screen session; production should use an approved supervisor and
|
||||
non-Desktop deployment path.
|
||||
- Record the exact coordinated restart and acceptance sequence in current state, evidence, stale items and commitments.
|
||||
|
||||
## Promotion
|
||||
|
||||
Promoted to the frontend compatibility contract, current-state restart gate, login-runtime evidence and this reusable
|
||||
reflection. No broader ADR is required.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Reflection: Current projections must exclude fixtures
|
||||
|
||||
## Trigger
|
||||
|
||||
Real daily uploads and automatic monthly publication were enabled while the database acceptance fixture remained in
|
||||
`finance.current_daily_versions`, causing correct aggregation of non-business test data.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
The transition from schema acceptance to business-facing use should retire all fixture pins and verify that every
|
||||
current Finance source has operational provenance.
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
The fixture's immutable version and current pointer were both retained. Later features validated formulas, lineage,
|
||||
downloads and max-ARRIVAL consistency against a structurally valid but contaminated snapshot.
|
||||
|
||||
## Root Cause
|
||||
|
||||
- Weak gate
|
||||
- Unclear ownership
|
||||
|
||||
The handoff documented synthetic-data cleanup as a production gate, but no executable readiness check owned it.
|
||||
|
||||
## Evidence
|
||||
|
||||
- Current version 2: run `mvp-v1-fixture-20260727`, `synthetic.xml`, provider `local_fixture`.
|
||||
- [Channel BI contamination evidence](../../50-evidence/topics/2026-07-30-channel-bi-post-update-data-contamination.md)
|
||||
- `DATABASE_ARCHITECTURE_REASSESSMENT_V2.md` already required synthetic cleanup before production.
|
||||
|
||||
## Lesson
|
||||
|
||||
Structural reconciliation proves that downstream outputs match current facts; it does not prove those facts are
|
||||
operational. Before business-facing acceptance, assert provenance as well as counts, hashes and formulas.
|
||||
|
||||
## Action
|
||||
|
||||
- Add check/eval
|
||||
- Update gate
|
||||
|
||||
Future deployment/readiness work should fail when a current Finance version uses `local_fixture` or another explicitly
|
||||
non-operational source. Cleanup must preserve immutable history while removing the fixture from the current projection.
|
||||
|
||||
## Promotion
|
||||
|
||||
Promote this to a deployment/data-readiness gate and automated acceptance check when remediation is implemented.
|
||||
@@ -0,0 +1,45 @@
|
||||
# Reflection: Derive Report Watermarks From Business Facts
|
||||
|
||||
## Trigger
|
||||
|
||||
The user corrected the proposed monthly cutoff source: the Opera XML filename has no date, and the monthly “更新至”
|
||||
must come from the table's `ARRIVAL` field.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
Identify the authoritative business field before deriving a report period or label. Use the committed facts actually
|
||||
included in the report, not transport metadata, upload names, request time or a nearby technical date.
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
Earlier planning left the cutoff derivation policy open and existing code accepted a request cutoff, which allowed a
|
||||
7.30 filename even though the maximum included `ARRIVAL` was 7.27.
|
||||
|
||||
## Root Cause
|
||||
|
||||
- Source identity was conflated with business time.
|
||||
- An internal request field was trusted without reconciling it to the generated dataset.
|
||||
- The output label was validated structurally but not against the report's semantic maximum date.
|
||||
|
||||
## Evidence
|
||||
|
||||
- User correction on 2026-07-30.
|
||||
- The pre-fix manual workbook was named “更新至7.30” while included rows ended at `ARRIVAL=2026-07-27`.
|
||||
- The repaired live report stores `as_of_date=2026-07-27` and core validation enforces equality with max included
|
||||
`ARRIVAL`.
|
||||
|
||||
## Lesson
|
||||
|
||||
For derived period labels, trace the value to the authoritative business column and assert it again against the final
|
||||
dataset. Filenames and wall-clock timestamps are provenance/audit data, not business watermarks unless the domain
|
||||
explicitly says otherwise.
|
||||
|
||||
## Action
|
||||
|
||||
- Encode max-included-`ARRIVAL` in ADR-001 and durable business rules.
|
||||
- Derive worker scope through `daily_version_id` lookups rather than payload/filename dates.
|
||||
- Reject any non-empty monthly report whose stored `as_of_date` differs from its maximum included `ARRIVAL`.
|
||||
|
||||
## Promotion
|
||||
|
||||
Promoted to ADR-001, the data flow, business rules, migration column comment and monthly core/worker tests.
|
||||
@@ -0,0 +1,45 @@
|
||||
# Reflection: Distinguish a database snapshot from batch completeness
|
||||
|
||||
## Trigger
|
||||
|
||||
The first Channel BI diagnosis treated the three real versions visible at 15:44 as the complete intended input set and
|
||||
declared 307 the clean expected total. The user's 07-23 upload committed later at 16:12 and raised the real total to 416.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
A live-update diagnosis should timestamp its snapshot, enumerate expected source files/dates, check recent or in-flight
|
||||
runs, and distinguish “currently persisted” from “business batch complete” before declaring an expected total.
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
The diagnosis correctly found the one-row fixture but incorrectly promoted the then-current 307-row database subtotal
|
||||
to the final business expectation. The user's correction was required to reopen the missing-date audit.
|
||||
|
||||
## Root Cause
|
||||
|
||||
- Weak gate
|
||||
- Other: temporal incompleteness was mistaken for data correctness
|
||||
|
||||
## Evidence
|
||||
|
||||
- 15:44 snapshot: three real current versions totaling 307 plus one fixture.
|
||||
- 16:12:27: daily version 7 committed 109 retained rooms for 07-23.
|
||||
- Final real total: 416; live source total with fixture: 417.
|
||||
- [Channel BI contamination evidence](../../50-evidence/topics/2026-07-30-channel-bi-post-update-data-contamination.md)
|
||||
|
||||
## Lesson
|
||||
|
||||
PostgreSQL is authoritative for what is committed at a given instant, but it does not by itself prove that every
|
||||
expected source has arrived. Live batch diagnoses need both state reconciliation and completeness reconciliation.
|
||||
|
||||
## Action
|
||||
|
||||
- Update gate
|
||||
- Add check/eval
|
||||
|
||||
Before declaring a clean expected total after uploads, list expected dates, query recent runs, state the snapshot time,
|
||||
and wait for or explicitly exclude any missing/in-flight input.
|
||||
|
||||
## Promotion
|
||||
|
||||
Promote this to the data-diagnosis checklist and future automated batch-completeness checks.
|
||||
@@ -0,0 +1,45 @@
|
||||
# Keep Deterministic Results Machine-to-Machine
|
||||
|
||||
## Trigger
|
||||
|
||||
The fixed processor produced a complete valid 135-record result, but the model-mediated MCP call submitted only 20
|
||||
records. Prompt strengthening improved tool selection and fetch behavior but could not guarantee lossless serialization
|
||||
of a large structured payload.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
Once deterministic code has created a schema-valid result, the receiving system should validate and ingest that exact
|
||||
machine artifact without asking a model to reconstruct the payload as tool arguments.
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
The result crossed an unnecessary model serialization boundary. That boundary introduced truncation, rereads and
|
||||
retry ambiguity even though both the source fetch and deterministic business processing had already succeeded.
|
||||
|
||||
## Root Cause
|
||||
|
||||
- Unclear ownership of structured-result transport
|
||||
- A probabilistic orchestration boundary was placed between deterministic producer and deterministic consumer
|
||||
|
||||
## Evidence
|
||||
|
||||
- `.project-docs/50-evidence/topics/2026-07-30-superagent-fetch-oss-prompt-experiment.md`
|
||||
- `.project-docs/50-evidence/topics/2026-07-30-arr2-programmatic-pipeline.md`
|
||||
- `arr_web/programmatic.py`
|
||||
- `tests/test_arr_programmatic.py`
|
||||
|
||||
## Lesson
|
||||
|
||||
Use models to interpret ambiguous inputs or choose work when that is genuinely required. Do not use a model as the
|
||||
transport encoder for a complete, machine-generated business result. Preserve the original artifact, validate it at the
|
||||
system boundary, and make the database commit authoritative.
|
||||
|
||||
## Action
|
||||
|
||||
- Updated the architecture through ADR-004.
|
||||
- Added programmatic success/failure vertical slices and active-runtime deployment guards.
|
||||
|
||||
## Promotion
|
||||
|
||||
Promoted to ADR-004, the ARR2.0 architecture documents, deployment contracts and regression tests. No new skill is
|
||||
needed unless this pattern recurs in another project.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Reflection: Formatting is not business state
|
||||
|
||||
## Trigger
|
||||
|
||||
An early Booking parser interpretation treated a yellow source row as cancellation. The supplied real workbook showed
|
||||
that a fully yellow row can still be the authoritative active Tour Code row, and the user confirmed that only explicit
|
||||
source cancellation text should cancel it.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
The parser should derive replacement/cancellation from explicit business content and documented row order, not from
|
||||
presentation-only cell formatting.
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
A visual formatting heuristic could have removed a valid final Tour Code allocation.
|
||||
|
||||
## Root Cause
|
||||
|
||||
- Weak gate: a spreadsheet style was promoted to business meaning without an explicit contract or counterexample test.
|
||||
|
||||
## Evidence
|
||||
|
||||
- Files: `booking_ingestion/excel.py`, `tests/test_booking_excel_ingestion.py`
|
||||
- Command output: the supplied workbook retains its yellow final row; the regression test
|
||||
`test_yellow_formatting_alone_does_not_cancel_a_tour` passes.
|
||||
- Docs involved: `.project-docs/40-domain/business-rules.md`
|
||||
|
||||
## Lesson
|
||||
|
||||
Spreadsheet color, font, border and other presentation metadata must remain non-authoritative unless the user explicitly
|
||||
defines that formatting as a business field. When row state matters, prefer text/column contracts and add a real-style
|
||||
counterexample before accepting the rule.
|
||||
|
||||
## Action
|
||||
|
||||
- Add check/eval: retain a yellow-row regression fixture and keep cancellation text-based.
|
||||
- Update docs: promote the rule to durable Booking business rules.
|
||||
|
||||
## Promotion
|
||||
|
||||
Business rule plus parser regression test.
|
||||
Reference in New Issue
Block a user