Skip to content

feat(harness): run one bounded correlated Prime text turn #7

Description

@rynfar

Outcome

Consume one fresh native PrimeSessionLease, submit exactly one bounded correlated text prompt, project a privacy-safe internal text/reasoning stream, support deterministic interruption, settle exactly once, and authoritatively close the owned native worker.

This is the host-private prompt/event normalization slice after #5 / PR #6. It does not register a public Prime Harness yet.

Coordination and dependency:

Implementation must wait for a reviewed Prime artifact that exposes the post-attach negotiation proof from Prime zeronsh#17 and for Pylon's correlated consumer gate to be reviewed against the same contract.

Owned area

  • focused extensions under crates/harness/src/prime/session/**;
  • focused fake SDK/daemon coverage under crates/harness/tests/**;
  • docs/prime-agent-integration.md contract and validation receipts.

Do not claim registry, proto, engine, document, RPC, settings, model, or UI files here.

Capability gate

Require:

  • frozen public-root SDK features bounded_daemon_ingress_v1 and proposed negotiated_daemon_session_capabilities_v1;
  • feat(harness): establish bounded native Prime SDK session host #5's existing daemon/session gates;
  • post-attach connection.supportsNegotiatedCapability("correlated_prompt_lifecycle_v1") === true for the current attachment generation;
  • public correlated submit/lifecycle/cancel methods.

A server offer, method presence, package/protocol/schema version, attach success alone, constructor arity, or ignored arguments are not proof. Stock Prime and older fork artifacts must return a typed local unsupported result and perform normal cleanup before prompt submission. There is no ordinary-prompt or ACP fallback in this slice.

Do not require or imply model_catalog, rlm_quiescence_barrier, queue mutation/modes, owned_prompt_cancellation, extension UI, MCP, or any other optional offer.

Prompt and attribution contract

  • Subscribe before submission.
  • Use only submitCorrelatedPrompt(text, { correlationId, queueIfBusy: false, signal }).
  • Generate one host-private random correlation token. Never log, serialize, persist, hash into, or export it.
  • Allow exactly one active and total prompt per fresh no-tools lease.
  • On uncertain submission, query getPromptLifecycles() once within a bound. Continue only from the exact retained record; never resubmit.
  • Require kind === "model_prompt", monotonic revisions, legal phase transitions, and non-regressing delivery evidence.
  • Accept turn events only when outer attribution is scope:"prompt" with the current correlation and the inner prompt correlation agrees. Session-scoped background metadata cannot settle the turn. Wrong/missing/stale attribution is a protocol failure.

Normalized projection

Only bounded normalized values may cross Node -> Rust:

  • assistant text deltas;
  • reasoning deltas, if implemented consistently;
  • finite terminal input/output token counts;
  • one fixed terminal outcome/error code.

Never forward raw snapshots/events/errors, native session/correlation/message/tool/child IDs, session files/paths, socket/package paths, credentials, provider diagnostics, costs, queues, tools, or extension UI data.

Native tool events or tool calls are an unsupported-state failure because the session is created with noTools: true. Unknown future event types may be ignored locally but never settle the turn.

Settlement and interruption

  • Correlated lifecycle is the ownership barrier. agent_end, message_end, turn_end, activity/idle, host EOF, or silence alone cannot complete the prompt.
  • Buffer/validate agent_end final message and usage, but emit exactly one terminal internal event only from the exact correlated terminal plus required final-response checks.
  • cancelled or completed with stopReason:"aborted" -> Interrupted.
  • lifecycle failed, native error, stopReason:"error", tool-use final state, malformed usage, or missing required final response -> fixed Errored outcome.
  • Other valid completed state -> Completed.
  • Cleanup uncertainty overrides Completed/Interrupted with cleanup-uncertain.
  • Pre-delivery interrupt uses cancelPromptLifecycle.
  • Delivered too_late may call session-scoped connection.abort() only because this slice owns one prompt, has tools disabled, and permits no other work. It must still await the exact terminal lifecycle or destructively close the lease.
  • expired/unknown cancellation evidence is Errored unless terminal ownership had already linearized.
  • Close, caller cancellation, Drop, host crash, and overflow retain all feat(harness): establish bounded native Prime SDK session host #5 cleanup ownership rules.

Bounds

Retain #5's 512 MiB V8 heap, 64 MiB daemon ingress, 16 KiB control frames, 8 pending requests, 32 normalized events, 256-byte native IDs, finite stage deadlines, and authoritative cleanup horizon.

Add and freeze before implementation:

  • non-empty prompt: at most 8 KiB UTF-8;
  • cumulative projected output: at most 16 MiB UTF-8;
  • one prompt per lease;
  • explicit admission, turn, interrupt, and terminal-grace deadlines;
  • UTF-8-safe output splitting that keeps every private frame within 16 KiB;
  • bounded lifecycle records and queue/coalescing behavior.

Overflow, backlog saturation, malformed data, partial/final mismatch, or host OOM is terminal failure plus authoritative cleanup. Never silently truncate and report success.

Deterministic acceptance tests

  1. Negotiation truth table: token/accessor/offer/attach proof combinations, stock behavior, stale generation, and unrelated optional offers.
  2. Event-before-response, response-before-event, terminal-before-response, duplicates, and uncertain submit reconciliation with an exact one-submit assertion.
  3. Wrong/session/unknown/stale attribution; conflicting duplicate revision; illegal transition/kind/delivery regression; post-terminal events.
  4. Text/reasoning UTF-8 boundaries, final-message fallback/consistency, unknown events, no-tools violation, per-frame/cumulative/backlog overflow, and FIFO ordering.
  5. Early agent_end during compaction/continuation cannot complete; full completed/cancelled/failed/aborted/error/toolUse/missing-final/usage matrix.
  6. Interrupt before ownership, owned/queued, delivered too_late, completion race, expired/unknown, abort failure/timeout, repeated interrupt, and Drop/close during every phase.
  7. Exactly one terminal only after authoritative cleanup proof; cleanup-uncertain never becomes success/interrupted.
  8. Privacy canaries for every forbidden identity/path/raw payload/error/credential in events, errors, logs, and Debug output.
  9. Preserve feat(harness): establish bounded native Prime SDK session host #5 process/reaper/descriptor/poison/OOM cleanup coverage.
  10. Env-gated no-model negotiation smoke against the exact new artifact; live credentialed prompts remain opt-in/ignored.

Non-goals

HarnessId::PrimeAgent, public AgentEvent, durable resume tokens, saved-session attach/reconnect, model/thinking selection, steering/follow-up, images, tools/subagents, approvals, resources/queues, compaction UI, refinement/goals/automation, background PrimeAgentTextGeneration, and ACP fallback.

Later merge order

  1. Prime Bound Rust development cache growth zeronsh/comet#17 proof API and reproducible artifact.
  2. Pylon consumes the same post-attach proof and passes compatibility review.
  3. This issue in an isolated Comet worktree.
  4. Opaque host-local resume-token mapping with a cumulative saved-snapshot budget.
  5. Hidden normalized Prime Harness, then registry/settings/model/UI exposure for a text-only preview.

Do not emit AgentEvent::SessionStarted.session_id in this issue. That field is durable Comet resume state; a native Prime ID is forbidden and an unmapped random value is not a resume contract.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions