Files
wyndham-ARR/.project-docs/50-evidence/topics/2026-07-30-superagent-fetch-oss-prompt-experiment.md
2026-07-31 15:11:42 +08:00

206 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SuperAgent fetch_oss_file Prompt Experiment
## Scope
Use the first fresh controlled ARR trace together with historical successful
SuperAgent fetches to separate Agent orchestration behavior, address shape and
platform file-type policy.
## Evidence
- The controlled ARR job reached the intended SuperAgent Agent with its
generated `PROGRAM_INPUT` and invoked `fetch_oss_file` four times.
- The trace shows that the runtime Tool accepted `object_uri` and optional
`filename` arguments. The first OSS shorthand request returned
`public_endpoint_missing`; later HTTPS variants for the XML returned
`extension_not_allowed`. These are Provider results, not Tool Schema
validation failures.
- The Agent also read the Skill and used shell inspection before fetch success,
despite the prior concise Prompt's stop rule. The four calls were four Agent
tool decisions inside one remote run, not four ARR submissions or transport
retries.
- Historical exported conversations contain successful `fetch_oss_file` calls
for `.xlsx` attachments. They returned a local file under the runtime uploads
directory in about 220 seconds. Those inputs included a direct OSS HTTPS URL,
but the exports do not expose the raw Tool Call arguments and do not prove
that `.xml` is allowed in the ARR Agent's Provider configuration.
- No public upstream source or official documentation containing the two
Provider error codes was found; this appears to be a platform-specific Tool.
## Historical Prompt Change (superseded)
The first corrective Main Prompt made fetch the only permitted tool action before a
local source file exists and specifies exactly one call:
```text
object_uri = "oss://" + attachment.oss.bucket + "/" + attachment.oss.object_key
filename = attachment.name
```
It forbids parallel Skill/reference reads, filesystem/environment inspection,
URI substitution, argument repair, shell/curl/SDK fallback and every second
fetch. Any Provider failure, ambiguous result or missing unique local path must
produce one failed Profile object and end the run.
The Prompt is 1,757 characters, remains below the existing 1,800-character
regression limit, and all 12 `tests.test_arr_opera_daily_ingest` tests pass.
## Interpretation at that stage
This was a bounded diagnostic Prompt experiment. It removed retries and
side-path noise but still used the wrong `oss://` address form.
After this Prompt is published, one fresh controlled ARR job has decisive
outcomes:
1. One successful fetch returning one local XML path: continue to verify the
Skill and MCP stages.
2. One `public_endpoint_missing`: confirm whether the Tool expects a public
HTTPS address before assuming it needs a credential-backed Provider.
3. One `extension_not_allowed`: add `.xml`/`application/xml` to the Provider's
allowed source types; do not keep tuning the Prompt.
4. More than one fetch or any pre-fetch shell/Skill read: the published Prompt
was not selected or the model did not obey it; verify Profile version and
runtime trace before any Provider change.
## Published Prompt Follow-up Run
Controlled job `arrjob-737acd9d35d04d7f9bcbbc60e7674236` reached remote run
`53510877-e30a-4f44-9a6c-26980cdc9461` with the intended PROGRAM_INPUT. The
available trace snapshot shows:
- exactly one model-selected tool action: `fetch_oss_file` with `object_uri`
and `filename=source.xml`;
- no `read_file`, shell, Skill processor, `present_files`, or
`arr_submit_processing_result` action before or after that fetch in the
captured events;
- one Provider result with `success=false`,
`error=public_endpoint_missing`, and message
`Public OSS endpoint is not configured`;
- no HTTPS substitution and therefore no new `extension_not_allowed` result.
This validates the Prompt's single-call/no-bypass behavior for the captured
portion and makes the Agent-specific Provider endpoint the first actionable
blocker. The supplied snapshot was refreshed about 20 seconds after the Tool
result and still ended with `status=running`; it contains no `message.final` or
terminal run event, so it does not yet prove final failure-object emission or
ARR terminalization. A later trace snapshot is required for that separate
check.
## Public-read URL correction
The user subsequently confirmed two authoritative deployment facts:
- `fetch_oss_file` reads a publicly accessible OSS URL and does not need a Provider;
- the ARR OSS deployment is `public-read`.
The local implementation therefore replaces the historical `oss://` experiment:
- PROGRAM_INPUT is now `arr-opera-daily-program-input-3` with required `oss.url`;
- ARR generates `https://{bucket}.oss-{region}.aliyuncs.com/{encoded-object-key}` with no query signature;
- the 1,682-character Prompt copies `oss.url` to `object_uri` and `source.xml` to `filename` exactly once;
- only committed source XML has public-read object ACL; staged objects and processing outputs remain private;
- OSS readiness requires the approved public-read bucket.
Forty-four targeted tests and the complete 276-test suite pass with two expected skips. No fresh platform run
has exercised this contract yet. The next controlled trace should no longer return `public_endpoint_missing`.
If it returns the previously observed `extension_not_allowed`, `.xml`/`application/xml` must be enabled in the
platform Tool; more Prompt retries or URI substitutions would not solve that policy failure.
## Mixed-version local run
The next attempted local job, `arrjob-1fd0f5e182eb4056af53be7300174981`, did not exercise this correction.
Its complete available snapshot ended about seven seconds after `run.started`, still in middleware processing,
with no `object_uri`, Tool call, Tool result, Skill load, MCP submission or terminal event. The serialized input
was PROGRAM_INPUT v2 because the local 8765 process had started before the v3 files were modified. After the
validated listener was restarted, all local readiness flags returned true. Acceptance therefore moves to one
new job generated by the restarted process; the mixed-version job must not be used as v3 evidence.
## First true v3 controlled run
Job `arrjob-3c2cd75568554b0ab6d17817d446fed1` provided decisive evidence:
- middleware input contained `arr-opera-daily-program-input-3` and no v2 contract;
- the model selected exactly one `fetch_oss_file` call with a redacted URL and `filename=source.xml`;
- the Tool returned `success=false`, `error=extension_not_allowed` and no artifact;
- the Agent made no second fetch, shell/SDK bypass, Skill call or MCP submission;
- SuperAgent emitted `run.completed` with remote status `success`, meaning the orchestration run ended, not that business ingestion succeeded;
- direct submissions, deliveries, Finance versions and outbox events remained zero.
Because an extension check can precede network download, ARR separately issued an anonymous HEAD without
logging the object URL or reading its body. OSS returned HTTP 200, `Content-Type: application/xml` and
`Content-Length: 629434`, exactly matching the registered source. ARR URL generation, object ACL and public
reachability are therefore verified; the platform XML allowlist is the sole current fetch blocker.
The failure path also exposed two independent defects. The Agent returned only `job_id`, `source_file_id`, a
minimal `processor_result` and `files=[]`, which does not satisfy the Profile output object's required fields
or object-shaped `files`. ARR still reported `status=running` 145 seconds after `run.completed`, because no MCP
submission arrived and remote finalization is not yet projected into a terminal ARR failure. Neither defect
should be addressed by URI retries or renaming the XML.
## Frozen RUNNING diagnosis
A later read-only inspection distinguished a stale ARR state from an active Agent run:
- the page continued polling every four seconds and its `refreshed_at` changed, but two trace samples stayed at 73 events;
- the last persisted Agent event was `AGENT_TRACE_STREAM_ENDED` at 11:42:26 +08, three seconds after remote `run.completed`;
- a read-only remote run lookup reported `success`, while the authoritative ARR run and attempt remained `running` with no finish time;
- the trace JSONL was fully drained and no longer changing; direct submissions, artifact deliveries, Finance versions and outbox events were all zero;
- the Agent-side business result was a safe failure code, `extension_not_allowed`, not an in-progress computation.
The production upload path constructs `ProcessingRunner` but calls only `start()`. No production component invokes
`poll()` or otherwise reconciles a terminal remote run that never calls MCP. Even if polling were wired, the runner's
`delivery_missing` transition is not recognized by `PostgresProcessingState`. The available stale-expiry helper is
also not scheduled and applies to existing submission rows, whereas this run created none. Consequently this task
will remain `running` until separately authorized repair logic or a guarded one-off repair is applied. Diagnosis did
not change state, retry the stream, submit another XML or restart a service.
## Main-flow impact assessment
The stale `running` state is not currently a report-generation gate:
- every upload creates a new independent job id, and the upload control is gated by runtime readiness rather than another job's status;
- Finance facts are written only inside an accepted MCP submission transaction, not by polling or task-log state;
- current monthly and analytics readers consume committed Finance facts and do not wait for all processing jobs to become terminal;
- at this historical ARR1 snapshot, automatic post-commit monthly dispatch was still absent, so no worker was blocked by this stale job. ARR2 later implemented a separate worker under ADR-001.
Terminal reconciliation would still improve operational correctness: accurate failure state, bounded retry semantics,
idempotent failure notification and earlier revocation of an unused writeback grant. It does not make a failed XML run
produce Finance facts or a report. At that snapshot, the immediate business-flow priorities were platform XML
allowlisting, a successful MCP commit and the accepted automatic report-trigger implementation; the later run below
supersedes the allowlist diagnosis while leaving the reconciler as separate control-plane hardening.
## First successful fetch/process and rejected direct submission
Job `arrjob-ae1a40b69c46402fb80e55c980b84886` proves that the platform XML allowlist was changed successfully and moves
the failure boundary beyond OSS ingestion:
- PROGRAM_INPUT v3 caused exactly one `fetch_oss_file` call. The Tool returned `/mnt/user-data/uploads/source.xml`,
`application/xml`, 629434 bytes and SHA-256
`b0019ba8ecdaad878bbde463b0c3129994bf582da16d9caf56d6b96da9a2db2a`, exactly matching ARR registration.
- The Agent loaded the intended Skill and references and invoked `process_daily.py` once. Its successful result reported
135 source rows, 16 excluded rows, 119 output rows and channel counts 26/25/54/14.
- The generated `structured-result.json` passed the Agent's own key check with 135 records, zero errors and a compact
size of 124493 characters.
- Instead of passing that object through once, the Agent repeatedly reopened, printed, compacted and range-read the
file. The captured sequence includes extra shell inspections, a temporary serialization, a full-file read and a
later `start_line=1200,end_line=2500` read.
- The supplied trace snapshot was not a terminal log: it was copied at 12:41:02 +08 with `status=running`, after the
trace connection had failed at 12:40:15 +08. A later read-only ARR trace projection shows the actual terminal state
at 12:41:40 +08.
- Exactly one MCP submission then reached ARR, proving active Tool discovery, network reachability and grant acceptance.
ARR recorded only 20 submitted records, rejected the request as `RESULT_CONTRACT_INVALID`, wrote no Finance version,
terminalized the job as failed and queued one downstream failure event.
The submitted payload therefore was not the complete 135-record object produced by the deterministic Skill. This is
not an OSS, XML allowlist, Skill or MCP reachability problem, and another URI or fetch retry cannot change it. The
current contract makes the model reproduce roughly 124 KB of JSON inside one tool-call argument after receiving that
file through bounded model/tool context. Prompt wording can discourage the observed rereads, but cannot make exact
large-payload transport reliable.
The durable options are either (1) let an installed platform-side submission adapter consume a sandbox file without
serializing it through model output, or (2) make the MCP call a compact attempt-bound completion signal and let ARR use
the deterministic source replay it already performs as the canonical structured payload. A remote MCP server cannot
resolve an Agent-local `/mnt/...` path by itself, so merely replacing `payload` with `payload_path` in the current
remote schema would not work.