harn-stdlib 0.10.121

Embedded Harn standard library source catalog
Documentation
// std/agent/completion_evidence — typed, bounded terminal evidence contracts.
import { CompletionRequirementEvidenceRecord } from "std/agent/completion_requirements"
import { CompletionVerificationState } from "std/agent/judge_internals"
import { AgentTranscriptToolLifecycleStatus } from "std/agent/transcript"

const COMPLETION_EVIDENCE_FIELD_CHAR_LIMIT = 4500

const COMPLETION_FINAL_OUTPUT_EVIDENCE_INDEX = -1

pub const COMPLETION_VERIFICATION_EVIDENCE_INDEX = -2

pub type CompletionEvidenceRole = "observation" | "mutation" | "verification" | "other"

pub type CompletionToolSemantics = {
  name: string,
  kind: string,
  side_effect_level: string,
  read_only: bool,
  evidence_role: CompletionEvidenceRole,
}

pub type CompletionEvidenceAction = {
  ordinal: int,
  evidence_index: int,
  tool_call_id: string,
  name: string,
  semantics: CompletionToolSemantics,
  lifecycle_status: AgentTranscriptToolLifecycleStatus,
  arguments: string,
  observation: string,
  result_facts: string,
  has_error_result: bool,
}

pub type CompletionEvidenceIssue = {
  code: string,
  record_index: int,
  message: string,
  details: string,
}

pub type CompletionEvidencePacket = {
  schema: "harn.completion_judge_evidence.v2",
  raw_message_count: int,
  raw_transcript_digest: string,
  relevant_action_count: int,
  omitted_read_only_call_count: int,
  omitted_older_action_count: int,
  lifecycle_issue_count: int,
  lifecycle_issues: list<CompletionEvidenceIssue>,
  actions: list<CompletionEvidenceAction>,
  fallback_observations: list<CompletionEvidenceAction>,
  requirement_evidence: list<CompletionRequirementEvidenceRecord>,
}

pub type CompletionEvidenceSelection = {
  name: string,
  evidence_role: CompletionEvidenceRole,
  evidence_index: int,
}

pub type CompletionEvidenceProjectionStats = {
  schema: "harn.completion_judge_evidence_projection.v1",
  raw_message_count: int,
  relevant_call_count: int,
  included_action_count: int,
  included_fallback_observation_count: int,
  omitted_read_only_call_count: int,
  omitted_older_action_count: int,
  lifecycle_issue_count: int,
  serialized_chars: int,
  raw_transcript_digest: string,
  selected_actions: list<CompletionEvidenceSelection>,
}

pub type CompletionEvidenceProjection = {
  packet: CompletionEvidencePacket,
  serialized: string,
  stats: CompletionEvidenceProjectionStats,
}

pub type CompletionEvidenceSnapshot = {
  schema: "harn.completion_evidence_snapshot.v1",
  evidence_id: string,
  session_id: string,
  task: string,
  stop_reason: string,
  // These three fields are display projections of the candidate turn. The
  // unprojected emission below is the authority for completion declarations.
  text: string,
  visible_text: string,
  last_text: string,
  raw_text: string,
  transcript: string,
  judge_evidence: string,
  judge_evidence_packet: CompletionEvidencePacket,
  judge_evidence_projection: CompletionEvidenceProjectionStats,
  all_tools_used: string,
  successful_tools_used: string,
  iteration: int,
  knowledge_state: string,
  // Deferred effects survive turns. Completion policy alone decides whether
  // later evidence supersedes them, so expose their count instead of hiding a veto.
  pending_tool_batch_effect_count: int,
  // Absent until a deterministic gate actually ran and reported.
  verification?: CompletionVerificationState?,
}

fn completion_evidence_clip(value: string) -> string {
  if len(value) <= COMPLETION_EVIDENCE_FIELD_CHAR_LIMIT {
    return value
  }
  const tail_chars = COMPLETION_EVIDENCE_FIELD_CHAR_LIMIT / 3
  const head_chars = COMPLETION_EVIDENCE_FIELD_CHAR_LIMIT - tail_chars
  const omitted = len(value) - COMPLETION_EVIDENCE_FIELD_CHAR_LIMIT
  return substring(value, 0, head_chars)
    + "\n…["
    + to_string(omitted)
    + " chars elided — middle of evidence]…\n"
    + substring(value, len(value) - tail_chars, len(value))
}

fn completion_requirement_evidence_without(
  records: list<CompletionRequirementEvidenceRecord>,
  evidence_index: int,
) -> list<CompletionRequirementEvidenceRecord> {
  return records.filter({ record -> record.evidence_index != evidence_index }).to_list()
}

/**
 * Project final-output and deterministic readings onto one requirement-evidence model.
 *
 * @effects: []
 * @errors: []
 * @api_stability: internal
 */
pub fn completion_requirement_evidence_packet(
  packet: CompletionEvidencePacket,
  final_text: string,
  verification: CompletionVerificationState? = nil,
) -> CompletionEvidencePacket {
  let records = packet.requirement_evidence
  records = completion_requirement_evidence_without(records, COMPLETION_FINAL_OUTPUT_EVIDENCE_INDEX)
  records = completion_requirement_evidence_without(records, COMPLETION_VERIFICATION_EVIDENCE_INDEX)
  const answer = trim(final_text)
  if answer != "" {
    records = records
      + [
        {
          evidence_index: COMPLETION_FINAL_OUTPUT_EVIDENCE_INDEX,
          role: "assistant_output",
          supports_completion: true,
          summary: completion_evidence_clip(answer),
          representative_artifact_ids: [],
          measurement: "present",
        },
      ]
  }
  if verification != nil {
    records = records
      + [
        {
          evidence_index: COMPLETION_VERIFICATION_EVIDENCE_INDEX,
          role: "deterministic_verification",
          supports_completion: verification.observed == "passed",
          summary: "Deterministic verification observed `" + verification.observed + "`.",
          representative_artifact_ids: [],
          measurement: verification.observed,
        },
      ]
  }
  return packet + {requirement_evidence: records}
}

/**
 * Bind one terminal decision to its complete typed evidence snapshot.
 *
 * @effects: []
 * @errors: []
 * @api_stability: internal
 */
pub fn completion_evidence_id(
  task: string,
  stop_reason: string,
  text: string,
  packet: CompletionEvidencePacket,
  pending_tool_batch_effect_count: int,
  verification: CompletionVerificationState? = nil,
) -> string {
  return "sha256:"
    + sha256(
      json_stringify(
        {
          task: task,
          trigger: stop_reason,
          candidate_text: text,
          actions: packet.actions,
          fallback_observations: packet.fallback_observations,
          requirement_evidence: packet.requirement_evidence,
          lifecycle_issues: packet.lifecycle_issues,
          pending_tool_batch_effect_count: pending_tool_batch_effect_count,
          verification: verification,
        },
      ),
    )
}