Skip to content

Redact and clamp park fault text; pin the planner wire schema - #2059

Merged
ppXD merged 1 commit into
mainfrom
fix/redact-park-fault-and-pin-wire-schema
Sep 30, 2026
Merged

ppXD merged 1 commit into
mainfrom
fix/redact-park-fault-and-pin-wire-schema

Conversation

@ppXD

@ppXD ppXD commented Sep 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • Redact scope secrets from, and clamp to 512 characters, the fault text a model-plane park writes down. LlmApiException.Message ends with the provider's whole error body, verbatim and unbounded, and the park put it on the durable marker, in the failure text and in the log. One InfraPark.FaultText now feeds all three, for the generic park and for the supervisor's own park (whose log line now carries the fault text too). Redaction runs before the clamp, and the clamp never cuts a surrogate pair, which Npgsql's strict UTF-8 encoder refuses to write.
  • Pin what the combinator-free planner schema left implicit: the prompt still quotes the full contract schema (now the only place the model reads the per-kind acceptance requirements), the re-ask request sends the wire schema too, the flat-acceptance check walks every field a branch declares rather than only the ones it requires, and the portability guard also requires every array to declare its items. The two validation-schema tests are renamed for what they check.
  • Correct the docs that said the tool schema is JsonSchema/ResponseSchema (the provider receives WireJsonSchema ?? JsonSchema; validation uses JsonSchema), and treat a default(JsonElement) wire schema as unset instead of failing at serialization.

The wire schema itself does not change. Refs #2052.

Test plan

  • Unit: JsonSchemaCombinatorsTests 38, StructuredResponseContractTests 54, TypedModelSchemaBranchTests 38, InfraParkTests 13, AgentSupervisorNodeInfraParkTests 1 (new; the real supervisor node over a faulting turn service)
  • Integration: InfraParkRideTests 22 (skip message quotes the clamped text the production park stored); SupervisorInfraParkFlowTests 4, LlmCompleteInfraParkFlowTests 4 and InfraParkRideFlowTests 6 against local Postgres
  • Mutations, each restored from a copy afterwards:
    • drop the redaction: the three secret tests go red
    • clamp before redact: the straddling-secret and supervisor tests go red
    • drop the clamp: the clamp, surrogate, supervisor and ride tests go red
    • drop the surrogate guard: the surrogate test goes red
    • supervisor marker takes the raw message, or its log omits the fault: the supervisor test goes red
    • pass the wire schema to WithSchemaInstruction (Anthropic and OpenAI): the planner capture and re-ask tests go red
    • re-ask sends the contract schema on the wire: the re-ask test goes red for both providers
    • optional property declared only inside a branch: the flat-acceptance check goes red, and the previous required-only check stays green
    • array without items in PlannerSchema.WireSchema or ArbiterDecisionSchema: the guard goes red, naming the schema and the JSON path
    • ProviderSchema back to a bare ??: the undefined-wire-schema test goes red for both providers
  • The real-model workflow is not dispatched, because the wire schema is unchanged

A model-plane park stored LlmApiException.Message on its marker, in the
node's failure text and in the park log. That message ends with the
provider's whole error body, verbatim and unbounded, so a gateway that
echoed a credential or answered with a page wrote it to the durable run
row and the log. InfraPark.FaultText now redacts scope secrets, then
clamps to 512 characters (never inside a surrogate pair, which Npgsql
refuses to write), and the generic park and the supervisor's own park
use that one text for the marker, the failure and the log line.

The planner's provider schema stopped being its validation schema in
the previous change, but tests and docs still said otherwise:

- the prompt still quoting the full contract schema, and the re-ask
  request still sending the wire schema, are now asserted
- the validation-schema tests are named for what they check, and the
  flat-acceptance test walks every field a branch declares, not only
  the ones it requires
- the portability guard also requires every array to declare its items,
  the second candidate for the empty HTTP 500
- the structured client docs say the provider receives
  WireJsonSchema ?? JsonSchema and that validation uses JsonSchema
- an Undefined WireJsonSchema counts as unset instead of failing at
  serialization
@ppXD
ppXD merged commit 1a9055a into main Sep 30, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant