import {
CompletionRequirement,
CompletionRequirementContract,
CompletionRequirementEvidenceRole,
} from "std/agent/options_types"
pub type CompletionRequirementAssessment = {
requirement_id: string,
met: bool,
evidence_refs: list<int>,
}
pub type CompletionRequirementRowStatus = "met" | "unmet" | "missing" | "unsupported"
pub type CompletionRequirementStatus = {
requirement_id: string,
name: string,
met: bool,
evidence_refs: list<int>,
status: CompletionRequirementRowStatus,
}
pub type CompletionRequirementReport = {
schema: "harn.completion_requirement_report.v1",
complete: bool,
required_count: int,
reported_count: int,
pending_count: int,
pending_names: list<string>,
rows: list<CompletionRequirementStatus>,
}
/** One typed, bounded fact a requirement assessment may cite. */
pub type CompletionRequirementEvidenceRecord = {
evidence_index: int,
role: CompletionRequirementEvidenceRole,
supports_completion: bool,
summary: string,
representative_artifact_ids: list<string>,
artifact_count?: int,
artifact_set_digest?: string,
measurement?: string,
}
pub type CompletionRequirementEvidencePacket = {
requirement_evidence?: list<CompletionRequirementEvidenceRecord>,
}
fn completion_requirement_evidence_role(value: unknown) -> CompletionRequirementEvidenceRole? {
if value == "assistant_output" {
return "assistant_output"
}
if value == "deterministic_verification" {
return "deterministic_verification"
}
if value == "mutation_summary" {
return "mutation_summary"
}
return nil
}
fn completion_requirement_evidence_roles(raw: unknown) -> list<CompletionRequirementEvidenceRole> {
if raw == nil {
let all_roles: list<CompletionRequirementEvidenceRole> = []
all_roles = all_roles + ["assistant_output"]
return all_roles + ["deterministic_verification"]
}
let roles: list<CompletionRequirementEvidenceRole> = []
if type_of(raw) != "list" {
return roles
}
for value in raw {
const role = completion_requirement_evidence_role(value)
if role != nil && !roles.contains(role) {
roles = roles + [role]
}
}
return roles
}
/**
* Validate and normalize the optional requirement ledger. One owner for the
* acceptance-ledger policy: every surface that accepts a raw contract routes
* here, so a malformed ledger fails closed with one vocabulary instead of
* silently shrinking the set of requirements the completion gate enforces.
*
* `label` names the option the raw value arrived under, so a caller-facing
* message points at the field the author wrote.
*
* @effects: []
* @errors: [validation]
* @api_stability: internal
*/
pub fn __completion_requirement_contract_checked(
label: string,
value: any,
) -> CompletionRequirementContract? {
if value == nil {
return nil
}
if type_of(value) != "dict" {
throw "agent_loop: `" + label + ".requirement_contract` must be a dict or nil; got "
+ type_of(value)
}
const raw_requirements = value?.requirements
if type_of(raw_requirements) != "list" || len(raw_requirements) == 0 {
throw "agent_loop: `" + label
+ ".requirement_contract.requirements` must be a non-empty list"
}
let requirements: list<CompletionRequirement> = []
let seen: dict = {}
for raw in raw_requirements {
if type_of(raw) != "dict" {
throw "agent_loop: every `" + label
+ ".requirement_contract.requirements` item must be a dict"
}
const requirement_id = trim(to_string(raw?.requirement_id ?? ""))
const name = trim(to_string(raw?.name ?? ""))
if requirement_id == "" || name == "" {
throw "agent_loop: every completion requirement needs non-empty `requirement_id` and `name`"
}
if seen[requirement_id] ?? false {
throw "agent_loop: duplicate completion `requirement_id` `" + requirement_id + "`"
}
seen = seen + {[requirement_id]: true}
const raw_roles = raw?.evidence_roles
if raw_roles != nil {
if type_of(raw_roles) != "list" || len(raw_roles) == 0 {
throw "agent_loop: completion requirement `evidence_roles` must be a non-empty list"
}
let seen_roles: dict = {}
for value_role in raw_roles {
if completion_requirement_evidence_role(value_role) == nil {
throw "agent_loop: unsupported completion requirement evidence role `"
+ to_string(value_role)
+ "`"
}
if seen_roles[value_role] ?? false {
throw "agent_loop: duplicate completion requirement evidence role `"
+ to_string(value_role)
+ "`"
}
seen_roles = seen_roles + {[value_role]: true}
}
}
const roles = completion_requirement_evidence_roles(raw_roles)
requirements = requirements
+ [{requirement_id: requirement_id, name: name, evidence_roles: roles}]
}
return {requirements: requirements}
}
/**
* Return the optional requirement ledger, normalized to its public shape.
* A malformed ledger throws rather than dropping requirements, so the
* completion gate can never be weakened by a contract it could not read.
*
* @effects: []
* @errors: [validation]
* @api_stability: experimental
* @example: completion_requirement_contract({requirements: [{requirement_id: "build", name: "Build the artifact."}]})
*/
pub fn completion_requirement_contract(value: unknown) -> CompletionRequirementContract? {
return __completion_requirement_contract_checked("completion_judge", value)
}
/**
* JSON-schema projection accepted by the existing structured judge call.
*
* @effects: []
* @errors: []
* @api_stability: experimental
* @example: completion_requirement_assessments_schema(contract)
*/
pub fn completion_requirement_assessments_schema(
contract: CompletionRequirementContract?,
) -> dict? {
if contract == nil || len(contract.requirements) == 0 {
return nil
}
return {
type: "array",
description:
"One assessment per required item. Cite only requirement_evidence indices whose role is allowed by that item.",
items: {
type: "object",
properties: {
requirement_id: {type: "string"},
met: {type: "boolean"},
evidence_refs: {type: "array", items: {type: "integer"}},
},
required: ["requirement_id", "met", "evidence_refs"],
additionalProperties: false,
},
}
}
/**
* Stable requirement text added to the one completion judge's input.
*
* @effects: []
* @errors: []
* @api_stability: experimental
* @example: completion_requirement_contract_prompt(contract)
*/
pub fn completion_requirement_contract_prompt(contract: CompletionRequirementContract?) -> string {
if contract == nil || len(contract.requirements) == 0 {
return ""
}
return "\n\nAtomic completion requirements:\n"
+ json_stringify(contract.requirements)
+ "\nReturn one requirement_report row for every requirement_id. Mark met only when requirement_evidence semantically supports that item, and cite indices with an allowed evidence role."
}
fn completion_requirement_strict_refs(raw: unknown) -> list<int> {
let refs: list<int> = []
if type_of(raw) != "list" {
return refs
}
for value in raw {
if type_of(value) == "int" && !refs.contains(value) {
refs = refs + [value]
}
}
return refs
}
fn completion_requirement_refs_well_formed(raw: unknown) -> bool {
if type_of(raw) != "list" {
return false
}
for value in raw {
if type_of(value) != "int" {
return false
}
}
return true
}
fn completion_requirement_evidence_matches(
packet: CompletionRequirementEvidencePacket,
evidence_index: int,
) -> list<CompletionRequirementEvidenceRecord> {
let matches: list<CompletionRequirementEvidenceRecord> = []
for record in packet.requirement_evidence ?? [] {
if type_of(record?.evidence_index) == "int" && record.evidence_index == evidence_index {
matches = matches + [record]
}
}
return matches
}
fn completion_requirement_refs_supported(
refs: list<int>,
requirement: CompletionRequirement,
packet: CompletionRequirementEvidencePacket,
) -> bool {
if len(refs) == 0 {
return false
}
const allowed_roles = completion_requirement_evidence_roles(requirement.evidence_roles)
if len(allowed_roles) == 0 {
return false
}
for evidence_index in refs {
const matches = completion_requirement_evidence_matches(packet, evidence_index)
if len(matches) != 1 {
return false
}
const record = matches[0]
const role = completion_requirement_evidence_role(record?.role)
if role == nil || !allowed_roles.contains(role) || record?.supports_completion != true
|| type_of(record?.summary) != "string"
|| trim(record.summary) == ""
|| type_of(record?.representative_artifact_ids) != "list" {
return false
}
if role == "deterministic_verification" && record?.measurement != "passed" {
return false
}
if role == "mutation_summary"
&& (type_of(record?.artifact_count) != "int" || record.artifact_count < 1
|| type_of(record?.artifact_set_digest) != "string"
|| trim(record.artifact_set_digest) == "") {
return false
}
}
return true
}
fn completion_requirement_matches(raw_rows: unknown, requirement_id: string) -> list {
let matches = []
if type_of(raw_rows) != "list" {
return matches
}
for row in raw_rows {
if trim(to_string(row?.requirement_id ?? "")) == requirement_id {
matches = matches + [row]
}
}
return matches
}
/**
* Join model assessments to the authoritative ledger and evidence packet.
* A scalar `done` cannot collapse a missing, duplicate, unmet, or uncited row.
*
* @effects: []
* @errors: []
* @api_stability: experimental
* @example: completion_requirement_report(contract, assessments, evidence_packet)
*/
pub fn completion_requirement_report(
contract: CompletionRequirementContract?,
raw_rows: unknown,
evidence_packet: CompletionRequirementEvidencePacket,
) -> CompletionRequirementReport? {
if contract == nil || len(contract.requirements) == 0 {
return nil
}
let rows: list<CompletionRequirementStatus> = []
let pending_names: list<string> = []
let authoritative_ids: list<string> = []
for requirement in contract.requirements {
authoritative_ids = authoritative_ids + [requirement.requirement_id]
}
for requirement in contract.requirements {
const matches = completion_requirement_matches(raw_rows, requirement.requirement_id)
let refs: list<int> = []
let status: CompletionRequirementRowStatus = "missing"
if len(matches) == 1 {
const raw = matches[0]
refs = completion_requirement_strict_refs(raw?.evidence_refs)
if type_of(raw?.met) != "bool" || raw.met != true {
status = "unmet"
} else if !completion_requirement_refs_well_formed(raw?.evidence_refs)
|| !completion_requirement_refs_supported(refs, requirement, evidence_packet) {
status = "unsupported"
} else {
status = "met"
}
} else if len(matches) > 1 {
status = "unsupported"
}
const met = status == "met"
if !met {
pending_names = pending_names + [requirement.name]
}
rows = rows
+ [
{
requirement_id: requirement.requirement_id,
name: requirement.name,
met: met,
evidence_refs: refs,
status: status,
},
]
}
if type_of(raw_rows) == "list" {
for raw in raw_rows {
const reported_id = trim(to_string(raw?.requirement_id ?? ""))
if reported_id == "" || !authoritative_ids.contains(reported_id) {
pending_names = pending_names
+ [
reported_id == "" ? "Invalid requirement row" : "Unknown requirement `" + reported_id
+ "`",
]
}
}
}
return {
schema: "harn.completion_requirement_report.v1",
complete: len(pending_names) == 0,
required_count: len(contract.requirements),
reported_count: type_of(raw_rows) == "list" ? len(raw_rows) : 0,
pending_count: len(pending_names),
pending_names: pending_names,
rows: rows,
}
}
/**
* Plain, bounded feedback for an incomplete atomic-requirement report.
*
* @effects: []
* @errors: []
* @api_stability: experimental
* @example: completion_requirement_pending_feedback(report)
*/
pub fn completion_requirement_pending_feedback(report: CompletionRequirementReport) -> string {
return "Completion rejected: " + to_string(report.pending_count)
+ " pending or invalid assessment(s) across "
+ to_string(report.required_count)
+ " required acceptance item(s): "
+ join(report.pending_names, "; ")
}