Skip to content

Chat coding adapter guardrails: session sentinel, provider notices, token and progress budgets - #79

Merged
wilke merged 1 commit into
chian:mainfrom
wilke:fix/chat-coding-guardrails
Oct 9, 2026
Merged

wilke merged 1 commit into
chian:mainfrom
wilke:fix/chat-coding-guardrails

Conversation

@wilke

@wilke wilke commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

What happened (2026-10-09, fourth live refiner build on Argo)

  • The Code Implementer ran 257 steps. It issued 230 container commands studying OpenChia's own sources under /ctx/openchia (admission.py, emitter.py, constructor signatures), and made no edit despite six nudges.

  • One turn sent ~7.8M input tokens. Each step resends the conversation (up to 240k characters), and chat completions on Argo get no prompt cache.

  • That exhausted the user's monthly Argo quota. Argo then replied with an ordinary assistant message:

    ⚠️ IMPORTANT USAGE NOTICE FROM ARGO 🚫 ACCESS REVOKED — Your Argo usage limit has been exceeded. Reason: Monthly limit exceeded.

    The adapter treated it as the coder's final summary.

  • The next turn of the same invocation failed: Previous coding agent is live or unverifiable; its workspace cannot be resumed. The adapter's process_identity() reported the host's own PID, which is always alive (iterative_episode_refiner/coding.py:197-200).

Changes (agent/transports/refinement_chat.py)

Guardrail Behaviour
Session sentinel process_identity() now reports a small per-session process (python -I -S -c "import sys; sys.stdin.read()"). It exits on close(), or when the host dies and its stdin pipe closes, so the refiner can resume the invocation's workspace.
Provider notices A reply containing a gateway refusal ("access revoked", usage/monthly/quota limit exceeded, "notice from Argo") fails the turn as Provider refused service: … with an api_error event, instead of becoming a result.
Input-token budget 1.5M input tokens per turn by default (OPENCHIA_CODING_MAX_INPUT_TOKENS). It counts provider-reported prompt_tokens, or ~4 characters per token when the provider reports none.
Step and progress budgets The default is now 60 steps per turn (was 300). The model is nudged after 20 steps without an edit, and the turn ends after 40 (finish=no_progress), asking for the blocker to be recorded.

Budget and no-progress endings are not errors: edits made so far stand for host admission, and the Episode's controller decides what comes next. Only provider refusals and non-transient provider errors fail the turn.

Tests

tests/agent/test_refinement_chat_coding.py: 18 pass, 4 new:

  • the sentinel is not the host and becomes dead after close();
  • an Argo notice fails the turn;
  • a no-progress ending;
  • a token-budget ending.

test_coding_container_shell.py: 6 pass.

Not in this PR

  • The shared launch transport can receive the same notice as content. For a structured call it would fail JSON parsing, but less clearly.
  • Making the coding loop cheaper (caching, context packs, cheaper model slots, the deterministic emitter for mechanical transcription) is being investigated separately.

🤖 Generated with Claude Code

…oken and progress budgets

Fourth live refiner build on Argo (2026-10-09): the coder ran 257 steps
(230 container commands studying OpenChia's sources, no edit despite six
nudges), sending ~7.8M input tokens in one turn — chat completions on Argo
carry no prompt cache — and exhausted the user's monthly Argo quota. Argo then
answered with "ACCESS REVOKED … Monthly limit exceeded" as an ordinary
assistant message, which ended the turn as if it were the coder's summary. The
next turn of the same invocation failed: "Previous coding agent is live or
unverifiable", because process_identity() reported the host's own PID.

- process_identity() reports a per-session sentinel process (python -I -S
  reading stdin) that exits on close() or when the host dies; the refiner's
  liveness check can now resume the invocation's workspace.
- A reply containing a gateway refusal (access revoked, usage/monthly/quota
  limit, "notice from Argo") fails the turn as "Provider refused service: …"
  instead of becoming a result.
- Per-turn input-token budget, 1.5M by default (OPENCHIA_CODING_MAX_INPUT_TOKENS),
  counted from provider-reported prompt_tokens or ~4 chars/token.
- Default step budget 60 (was 300); nudge after 20 steps without an edit, end
  the turn (no error, finish=no_progress) after 40.
Budget and no-progress endings are not errors: edits stand for admission and
the Episode's controller decides what follows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wilke
wilke merged commit a7931b6 into chian:main Oct 9, 2026
33 of 52 checks passed
wilke added a commit that referenced this pull request Oct 9, 2026
With the Argo monthly quota exhausted (2026-10-09), every refiner call through
the shared pinned transport "succeeded" in about one second with Argo's
"IMPORTANT USAGE NOTICE FROM ARGO … ACCESS REVOKED … Monthly limit exceeded"
text as the reply, and that text became refiner input. #79 detected such
notices only in the chat coding adapter.

- agent/provider_notices.py: provider_notice() recognizes a refusal when a
  short reply (<= 4000 chars) carries at least two distinct markers (notice
  from Argo, access revoked, usage/monthly limit exceeded, quota exceeded,
  contact your Directorate Operations Officer); one marker alone, as in a
  genuine answer discussing quotas, is not enough.
- episode_launch_transport._invoke raises ProviderRefusedService for such a
  reply, so the pinned call fails visibly (Designer, Materialization
  Implementer, Builder, Target Workflow calls). It is not a dropped
  connection, so the supervisor does not replace it.
- The chat coding adapter uses the same detector.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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