/**
* std/verification — deterministic verification facts and helper shapes.
*
* Import: import "std/verification"
*
* This module is the Harn-owned home for reusable verification intelligence
* primitives. It intentionally starts with fact capture, not policy: callers
* can bind diagnostics and background check results to file snapshots without
* duplicating hostlib plumbing or inventing product-specific hash logic.
*/
import { command_run, command_wait } from "std/command"
import { shell_quote } from "std/runtime"
import { regex_first_capture, truncate_text } from "std/text"
type VerificationFileHashSnapshotEntry = {
path: string,
known: bool,
readable: bool,
hash: string?,
hash_source: "indexed" | "disk" | "missing",
size: int?,
mtime_ms: int?,
indexed_hash: string?,
indexed_mtime_ms: int?,
last_edit_seq: int,
}
type VerificationFileHashSnapshot = {
seq: int,
captured_at_ms: int,
algorithm: string,
snapshot: dict,
missing: list<string>,
files: list<VerificationFileHashSnapshotEntry>,
}
type VerificationCheckObservation = {
durationMs?: int,
warm: bool,
at?: string,
exit?: int,
failureSignature?: string,
snapshot?: dict,
}
type VerificationRecordedCheck = {
result: dict,
observation: VerificationCheckObservation,
row: dict?,
snapshot: VerificationFileHashSnapshot?,
}
type VerificationStartedCheck = {
row_id: string,
started: dict,
observation_options: dict,
snapshot: VerificationFileHashSnapshot?,
}
type VerificationToolchainFact = {
id: string,
name: string,
available: bool,
version?: string,
raw_version: string,
cache_identity: dict,
probe: dict,
}
type VerificationWarmStateFact = {
id: string,
name: string,
configured: bool,
available: bool,
ready: bool,
warm: bool,
timing_kind: string,
mode: string,
expected_warm_delta_ms?: int,
warm_ms?: int,
cold_ms?: int,
cache_identity: dict,
probe: dict,
}
type VerificationAffectedTarget = dict
type VerificationAffectedAdapterFact = {
id: string,
parser_id: string,
status: string,
ok: bool,
target_count: int,
exit?: int,
error?: string,
}
type VerificationAffectedTargetsFact = {
changed_paths: list<string>,
targets: list<VerificationAffectedTarget>,
adapters: list<VerificationAffectedAdapterFact>,
fallback: dict,
}
type VerificationProfileMatch = {row: dict, specificity: int, index: int}
type VerificationLadderPlanEntry = dict
type VerificationLadderPlan = {
schema: string,
query: dict,
matches: list<VerificationProfileMatch>,
selected: list<VerificationLadderPlanEntry>,
skipped: list<dict>,
fallback: bool,
reason: string,
}
type VerificationDiagnosticDelta = dict
fn __verification_opts(options) {
return options ?? {}
}
fn __verification_result_ok(result) -> bool {
if result?.ok != nil {
return result.ok ? true : false
}
if result?.success != nil {
return result.success ? true : false
}
let exit = to_int(result?.exit_code)
let status = result?.status ?? "completed"
return status == "completed" && exit == 0 && !(result?.timed_out ?? false)
}
fn __verification_duration_ms(result, opts) {
if opts?.duration_ms != nil {
return to_int(opts.duration_ms)
}
if result?.duration_ms != nil {
return to_int(result.duration_ms)
}
if result?.execution_duration_ms != nil {
return to_int(result.execution_duration_ms)
}
return nil
}
fn __verification_exit(result, opts) {
if opts?.exit != nil {
return to_int(opts.exit)
}
if result?.exit_code != nil {
return to_int(result.exit_code)
}
if result?.status == "timed_out" || result?.timed_out == true {
return 124
}
if result?.ok != nil || result?.success != nil {
return __verification_result_ok(result) ? 0 : 1
}
return nil
}
fn __verification_warm(opts) -> bool {
if opts?.warm != nil {
return opts.warm ? true : false
}
if opts?.cold != nil {
return !(opts.cold ? true : false)
}
return true
}
fn __verification_snapshot_map(value) {
if value == nil {
return nil
}
if type_of(value) == "dict" && value?.snapshot != nil {
return value.snapshot
}
return value
}
fn __verification_capture_snapshot(opts) {
var snapshot_fact = nil
var snapshot = __verification_snapshot_map(opts?.snapshot)
if opts?.snapshot_paths != nil {
snapshot_fact = verification_file_hash_snapshot(opts.snapshot_paths)
snapshot = snapshot_fact.snapshot
}
return {fact: snapshot_fact, snapshot: snapshot}
}
fn __verification_result_text(result, source: string) -> string {
if source == "stderr" {
return result?.stderr ?? ""
}
if source == "stdout" {
return result?.stdout ?? ""
}
if source == "combined" {
return result?.combined ?? ((result?.stdout ?? "") + (result?.stderr ?? ""))
}
return ""
}
fn __verification_failure_signature(result, opts) {
if opts?.failure_signature != nil {
let explicit = to_string(opts.failure_signature)
return trim(explicit) == "" ? nil : explicit
}
if __verification_result_ok(result) {
return nil
}
let source = opts?.failure_signature_from ?? "combined"
if source == "none" {
return nil
}
let max_chars = to_int(opts?.max_failure_signature_chars) ?? 4000
let text = trim(__verification_result_text(result, source))
if text != "" {
return truncate_text(text, max_chars)
}
let status = result?.status ?? "failed"
let exit = __verification_exit(result, opts)
return "check " + to_string(status) + " exit=" + to_string(exit)
}
fn __verification_row_id(row, index: int) -> string {
let id = trim(to_string(row?.id ?? row?.name ?? ""))
if id != "" {
return id
}
return "toolchain/" + to_string(index)
}
fn __verification_toolchain_name(row, id: string) -> string {
let name = trim(to_string(row?.name ?? ""))
return name == "" ? id : name
}
fn __verification_toolchain_probe(row) {
let probe = row?.versionProbe ?? row?.probe
if probe == nil {
return nil
}
if type_of(probe) == "dict" && probe?.spec != nil {
return probe.spec
}
return probe
}
fn __verification_toolchain_probe_options(row, opts) {
let probe = row?.versionProbe ?? row?.probe ?? {}
return (opts?.command_options ?? {}) + (probe?.command_options ?? row?.command_options ?? {})
}
fn __verification_toolchain_version_pattern(row, opts) -> string {
let probe = row?.versionProbe ?? row?.probe ?? {}
return to_string(
probe?.versionPattern
?? probe?.version_pattern
?? row?.versionPattern
?? row?.version_pattern
?? opts?.version_pattern
?? "([0-9]+(\\.[0-9A-Za-z_+\\-]+)+)",
)
}
fn __verification_toolchain_raw_version(result) -> string {
let stdout = trim(result?.stdout ?? "")
if stdout != "" {
return stdout
}
return trim(result?.stderr ?? "")
}
fn __verification_toolchain_cache_identity(row, opts) -> dict {
return (opts?.cache_identity ?? {}) + (row?.cacheIdentity ?? row?.cache_identity ?? {})
}
fn __verification_warm_state_mode(row) {
let mode = row?.warmMode ?? row?.warm_mode ?? row?.warmState ?? row?.warm_state
if mode == nil {
return nil
}
if type_of(mode) == "dict" {
return mode
}
return {warm: mode ? true : false}
}
fn __verification_warm_state_id(row, index: int) -> string {
let mode = __verification_warm_state_mode(row) ?? {}
let id = trim(to_string(mode?.id ?? row?.row_id ?? row?.id ?? row?.name ?? ""))
if id != "" {
return id
}
return "warm-state/" + to_string(index)
}
fn __verification_warm_state_name(row, id: string) -> string {
let mode = __verification_warm_state_mode(row) ?? {}
let name = trim(to_string(mode?.name ?? row?.name ?? ""))
return name == "" ? id : name
}
fn __verification_warm_state_probe(row) {
let mode = __verification_warm_state_mode(row) ?? {}
let probe = mode?.readyProbe ?? mode?.ready_probe ?? mode?.readinessProbe ?? mode?.readiness_probe
?? mode?.probe
?? row?.readyProbe
?? row?.ready_probe
?? row?.readinessProbe
?? row?.readiness_probe
?? row?.probe
if probe == nil {
return nil
}
if type_of(probe) == "dict" && probe?.spec != nil {
return probe.spec
}
return probe
}
fn __verification_warm_state_probe_options(row, opts) {
let mode = __verification_warm_state_mode(row) ?? {}
let probe = mode?.readyProbe ?? mode?.ready_probe ?? mode?.readinessProbe ?? mode?.readiness_probe
?? mode?.probe
?? row?.readyProbe
?? row?.ready_probe
?? row?.readinessProbe
?? row?.readiness_probe
?? row?.probe
?? {}
return (opts?.command_options ?? {})
+ (probe?.command_options ?? mode?.command_options ?? row?.command_options ?? {})
}
fn __verification_warm_state_cache_identity(row, opts) -> dict {
let mode = __verification_warm_state_mode(row) ?? {}
return (opts?.cache_identity ?? {})
+ (row?.cacheIdentity ?? row?.cache_identity ?? {})
+ (mode?.cacheIdentity ?? mode?.cache_identity ?? {})
}
fn __verification_warm_state_expected_delta_ms(row, mode) {
return to_int(
mode?.expectedWarmDeltaMs
?? mode?.expected_warm_delta_ms
?? row?.expectedWarmDeltaMs
?? row?.expected_warm_delta_ms,
)
}
fn __verification_warm_state_timings(row, mode) {
let timings = row?.timings ?? mode?.timings ?? {}
let warm_ms = to_int(mode?.warmMs ?? mode?.warm_ms ?? timings?.warmMs?.p95 ?? timings?.warm_ms?.p95)
let cold_ms = to_int(mode?.coldMs ?? mode?.cold_ms ?? timings?.coldMs?.p95 ?? timings?.cold_ms?.p95)
return {warm_ms: warm_ms, cold_ms: cold_ms}
}
fn __verification_warm_state_mode_name(mode) -> string {
let raw = mode?.mode ?? mode?.kind ?? mode?.type ?? "probe"
let value = lowercase(trim(to_string(raw)))
return value == "" ? "probe" : value
}
fn __verification_warm_state_probe_receipt(result) -> dict {
return {
status: result?.status ?? "not_configured",
exit: result == nil ? nil : __verification_exit(result, {}),
durationMs: result?.duration_ms,
stdout: result?.stdout ?? "",
stderr: result?.stderr ?? "",
}
}
fn __verification_string_list(value) -> list<string> {
if value == nil {
return []
}
let raw = type_of(value) == "list" ? value : [value]
var out: list<string> = []
for item in raw {
let text = trim(to_string(item ?? ""))
if text != "" && !contains(out, text) {
out = out + [text]
}
}
return out
}
fn __verification_delta_config_dict(value) -> dict {
return type_of(value) == "dict" ? value : {}
}
fn __verification_delta_known_options(value) -> dict {
if type_of(value) != "dict" {
return {}
}
var out = {}
for key in [
"lowercase",
"strip_ansi",
"strip_locations",
"strip_temp_paths",
"collapse_whitespace",
"include_path",
"include_code",
"include_severity",
"max_chars",
"replacements",
"ignore_patterns",
"strip_patterns",
"stripPatterns",
] {
if value.keys().contains(key) {
out = out + {[key]: value[key]}
}
}
return out
}
fn __verification_delta_normalization(options) -> dict {
let opts = __verification_opts(options)
let row = __verification_delta_config_dict(opts?.row ?? opts?.profile_row)
let check = __verification_delta_config_dict(row?.check)
let direct = __verification_delta_config_dict(
opts?.diagnosticDelta
?? opts?.diagnostic_delta
?? opts?.signatureNormalization
?? opts?.signature_normalization,
)
+ __verification_delta_known_options(opts)
return {
lowercase: true,
strip_ansi: true,
strip_locations: true,
strip_temp_paths: true,
collapse_whitespace: true,
include_path: false,
include_code: true,
include_severity: false,
max_chars: 4000,
replacements: [],
ignore_patterns: [],
strip_patterns: [],
}
+ __verification_delta_config_dict(row?.signatureNormalization)
+ __verification_delta_config_dict(row?.signature_normalization)
+ __verification_delta_config_dict(row?.diagnosticDelta)
+ __verification_delta_config_dict(row?.diagnostic_delta)
+ __verification_delta_config_dict(check?.signatureNormalization)
+ __verification_delta_config_dict(check?.signature_normalization)
+ __verification_delta_config_dict(check?.diagnosticDelta)
+ __verification_delta_config_dict(check?.diagnostic_delta)
+ direct
}
fn __verification_delta_raw_text(value) -> string {
if value == nil {
return ""
}
if type_of(value) != "dict" {
return trim(to_string(value))
}
let raw = value?.failureSignature
?? value?.failure_signature
?? value?.signature
?? value?.message
?? value?.text
?? value?.error
?? value?.stderr
?? value?.stdout
?? value?.combined
?? value?.result
?? ""
return trim(to_string(raw ?? ""))
}
fn __verification_delta_status(value) -> string {
let direct = lowercase(trim(to_string(value?.status ?? "")))
if direct != "" {
return direct
}
return lowercase(trim(to_string(value?.classification?.status ?? value?.diagnostic?.status ?? "")))
}
fn __verification_delta_feeds_gates(value) -> bool {
if value == nil {
return true
}
if value?.feedsGates != nil {
return value.feedsGates ? true : false
}
if value?.feeds_gates != nil {
return value.feeds_gates ? true : false
}
if value?.classification?.feedsGates != nil {
return value.classification.feedsGates ? true : false
}
if value?.classification?.feeds_gates != nil {
return value.classification.feeds_gates ? true : false
}
if value?.diagnostic?.feedsGates != nil {
return value.diagnostic.feedsGates ? true : false
}
if value?.diagnostic?.feeds_gates != nil {
return value.diagnostic.feeds_gates ? true : false
}
let status = __verification_delta_status(value)
return !["advisory", "bound_stale", "stale", "unbound"].contains(status)
}
fn __verification_delta_explicit_success(value) -> bool {
if value == nil {
return false
}
if value?.ok != nil {
return value.ok ? true : false
}
if value?.success != nil {
return value.success ? true : false
}
let exit = to_int(value?.exit ?? value?.exit_code)
if exit != nil {
return exit == 0
}
let status = __verification_delta_status(value)
return ["pass", "passed", "success", "succeeded"].contains(status)
}
fn __verification_delta_explicit_failure(value) -> bool {
if value == nil {
return false
}
if value?.ok != nil {
return !(value.ok ? true : false)
}
if value?.success != nil {
return !(value.success ? true : false)
}
let exit = to_int(value?.exit ?? value?.exit_code)
if exit != nil {
return exit != 0
}
let status = __verification_delta_status(value)
return ["error", "fail", "failed", "failure", "timed_out", "timeout"].contains(status)
}
fn __verification_delta_has_collection(value) -> bool {
return type_of(value?.diagnostics) == "list" || type_of(value?.errors) == "list"
}
fn __verification_delta_synthetic_failure(value) -> dict {
let status = __verification_delta_status(value)
let exit = to_int(value?.exit ?? value?.exit_code)
let status_text = status == "" ? "failed" : status
let exit_text = exit == nil ? "" : " exit=" + to_string(exit)
return {message: "check " + status_text + exit_text, code: status_text}
}
fn __verification_delta_raw_entries(value) -> list {
if value == nil {
return []
}
let kind = type_of(value)
if kind == "list" {
return value
}
if kind == "string" {
return [value]
}
if kind != "dict" {
return [value]
}
if type_of(value?.diagnostics) == "list" {
return value.diagnostics
}
if type_of(value?.errors) == "list" {
return value.errors
}
if type_of(value?.diagnostic) == "dict" {
return [value.diagnostic]
}
if __verification_delta_raw_text(value) != "" {
return [value]
}
if __verification_delta_explicit_failure(value) {
return [__verification_delta_synthetic_failure(value)]
}
return []
}
fn __verification_delta_location(value) -> string {
if type_of(value) != "dict" {
return ""
}
var path = trim(to_string(value?.path ?? value?.file ?? value?.filename ?? value?.uri ?? ""))
let line = to_int(value?.line ?? value?.line_number)
if path != "" && line != nil {
path = path + ":" + to_string(line)
let column = to_int(value?.column ?? value?.col)
if column != nil {
path = path + ":" + to_string(column)
}
}
return path
}
fn __verification_delta_replacement_pattern(entry) -> string {
if type_of(entry) == "dict" {
return trim(to_string(entry?.pattern ?? entry?.regex ?? ""))
}
return trim(to_string(entry ?? ""))
}
fn __verification_delta_replacement_text(entry) -> string {
if type_of(entry) == "dict" {
return to_string(entry?.replacement ?? entry?.with ?? " ")
}
return " "
}
fn __verification_delta_normalize_text(text: string, cfg: dict) -> string {
var out = to_string(text ?? "")
if cfg?.strip_ansi != false {
out = regex_replace_all("\\u{1b}\\[[0-9;]*m", "", out)
}
for replacement in cfg?.replacements ?? [] {
let pattern = __verification_delta_replacement_pattern(replacement)
if pattern != "" {
out = regex_replace_all(pattern, __verification_delta_replacement_text(replacement), out)
}
}
for pattern in __verification_string_list(cfg?.strip_patterns ?? cfg?.stripPatterns) {
out = regex_replace_all(pattern, " ", out)
}
if cfg?.lowercase != false {
out = lowercase(out)
}
if cfg?.strip_locations != false {
out = regex_replace_all("[^\\s:]+:[0-9]+(?::[0-9]+)?", " ", out)
out = regex_replace_all("\\b(?:line|col|column)\\s+[0-9]+\\b", " ", out)
}
if cfg?.strip_temp_paths != false {
out = regex_replace_all("/tmp/[^\\s:]*", " ", out)
out = regex_replace_all("/var/folders/[^\\s:]*", " ", out)
}
if cfg?.collapse_whitespace != false {
out = trim(regex_replace_all("\\s+", " ", out))
}
let max_chars = to_int(cfg?.max_chars) ?? 4000
if max_chars > 0 {
out = truncate_text(out, max_chars)
}
return out
}
fn __verification_delta_signature(value, cfg: dict) -> string {
var parts: list<string> = []
if type_of(value) == "dict" {
if cfg?.include_path == true {
let location = __verification_delta_location(value)
if location != "" {
parts = parts.push(location)
}
}
if cfg?.include_severity == true {
let severity = trim(to_string(value?.severity ?? value?.level ?? ""))
if severity != "" {
parts = parts.push(severity)
}
}
if cfg?.include_code != false {
let code = trim(to_string(value?.code ?? value?.rule ?? value?.kind ?? ""))
if code != "" {
parts = parts.push(code)
}
}
}
let text = __verification_delta_raw_text(value)
if text != "" {
parts = parts.push(text)
}
return __verification_delta_normalize_text(join(parts, " "), cfg)
}
fn __verification_delta_ignored(signature: string, cfg: dict) -> bool {
for pattern in __verification_string_list(cfg?.ignore_patterns ?? cfg?.ignorePatterns) {
if regex_match(pattern, signature) != nil {
return true
}
}
return false
}
fn __verification_delta_direct_count(value) {
return to_int(
value?.error_count ?? value?.diagnostic_count ?? value?.diagnostics_count
?? value?.failure_count,
)
}
fn __verification_delta_info(value, cfg: dict) -> dict {
let entries = __verification_delta_raw_entries(value)
var normalized: list<string> = []
for entry in entries {
let signature = __verification_delta_signature(entry, cfg)
if signature != "" && !__verification_delta_ignored(signature, cfg) {
normalized = normalized.push(signature)
}
}
var signatures: list<string> = []
for signature in normalized {
if !signatures.contains(signature) {
signatures = signatures.push(signature)
}
}
let direct_count = __verification_delta_direct_count(value)
let count = direct_count ?? len(normalized)
let has_collection = __verification_delta_has_collection(value)
let failed = len(normalized) > 0 || (!has_collection && __verification_delta_explicit_failure(value))
return {
count: count,
explicit_success: __verification_delta_explicit_success(value),
failed: failed,
feedsGates: __verification_delta_feeds_gates(value),
feeds_gates: __verification_delta_feeds_gates(value),
has_collection: has_collection,
signatures: signatures.sort(),
}
}
fn __verification_delta_set_minus(left: list<string>, right: list<string>) -> list<string> {
var out: list<string> = []
for item in left {
if !right.contains(item) && !out.contains(item) {
out = out.push(item)
}
}
return out.sort()
}
fn __verification_delta_set_intersection(left: list<string>, right: list<string>) -> list<string> {
var out: list<string> = []
for item in left {
if right.contains(item) && !out.contains(item) {
out = out.push(item)
}
}
return out.sort()
}
fn __verification_delta_gate_signatures(info: dict) -> list<string> {
return info.feedsGates ? info.signatures : []
}
fn __verification_delta_snapshot(info: dict) -> dict {
return {
count: info.count,
feedsGates: info.feedsGates,
feeds_gates: info.feeds_gates,
signatures: info.signatures,
}
}
fn __verification_delta_result(
status: string,
progress_credit: bool,
previous_info: dict,
current_info: dict,
removed: list<string>,
added: list<string>,
persisted: list<string>,
normalization: dict,
reason: string,
) -> VerificationDiagnosticDelta {
var out = {
schema: "harn.verification.diagnostic_delta.v1",
status: status,
progress_credit: progress_credit,
feedsGates: current_info.feedsGates,
feeds_gates: current_info.feeds_gates,
advisory: !current_info.feedsGates,
reason: reason,
previous: __verification_delta_snapshot(previous_info),
current: __verification_delta_snapshot(current_info),
removed: removed,
added: added,
persisted: persisted,
same_signature_set: len(removed) == 0 && len(added) == 0,
normalization: normalization,
}
if previous_info.feedsGates && current_info.feedsGates {
out = out + {count_delta: current_info.count - previous_info.count}
}
return out
}
fn __verification_clean_path(value) -> string {
var path = regex_replace_all("\\\\", "/", trim(to_string(value ?? "")))
while starts_with(path, "./") {
path = substring(path, 2)
}
return path
}
fn __verification_path_under(root_value, path_value) -> bool {
let root = __verification_clean_path(root_value)
let path = __verification_clean_path(path_value)
if path == "" {
return false
}
if root == "" || root == "." {
return true
}
return path == root || starts_with(path, root + "/")
}
fn __verification_shell_join(values) -> string {
var quoted = []
for value in values ?? [] {
quoted = quoted + [shell_quote(to_string(value))]
}
return join(quoted, " ")
}
fn __verification_render_adapter_value(value, ctx) {
if type_of(value) == "string" {
return render_string(value, ctx)
}
if type_of(value) == "list" {
var out = []
for item in value {
out = out + [__verification_render_adapter_value(item, ctx)]
}
return out
}
if type_of(value) == "dict" {
var out = {}
for key in value.keys() {
out = out + {[key]: __verification_render_adapter_value(value[key], ctx)}
}
return out
}
return value
}
fn __verification_adapter_spec(row, changed_paths, opts) {
let spec = row?.spec ?? row?.command
if spec == nil {
return nil
}
let ctx = (opts?.template_context ?? {})
+ (row?.template_context ?? {})
+ {
changed_paths: changed_paths,
changed_paths_json: json_stringify(changed_paths),
changed_paths_space: __verification_shell_join(changed_paths),
root: opts?.root ?? opts?.workspace_root ?? "",
}
return __verification_render_adapter_value(spec, ctx)
}
fn __verification_adapter_command_options(row, opts) {
return (opts?.command_options ?? {}) + (row?.command_options ?? {})
}
fn __verification_adapter_id(row, index: int) -> string {
let id = trim(to_string(row?.id ?? row?.name ?? ""))
return id == "" ? "adapter/" + to_string(index) : id
}
fn __verification_parser_id(row) -> string {
let parser = trim(to_string(row?.parser_id ?? row?.parser ?? "harn.targets_json.v1"))
return parser == "" ? "harn.targets_json.v1" : parser
}
fn __verification_target_from_value(value, adapter_id: string, default_kind: string, files) {
let base = if type_of(value) == "dict" {
value
} else {
{id: to_string(value), label: to_string(value)}
}
let id = trim(to_string(base?.id ?? base?.name ?? base?.label ?? ""))
if id == "" {
return nil
}
var out = base + {id: id, adapter_id: adapter_id, source: base?.source ?? "adapter"}
if out?.label == nil {
out = out + {label: id}
}
if out?.kind == nil {
out = out + {kind: default_kind}
}
if out?.files == nil {
out = out + {files: __verification_string_list(files)}
}
return out
}
fn __verification_push_target(targets, target) {
if target == nil {
return targets
}
let key = trim(to_string(target?.id ?? ""))
if key == "" {
return targets
}
for existing in targets {
if existing?.id == key {
return targets
}
}
return targets + [target]
}
fn __verification_json_target_values(data) {
if type_of(data) == "list" {
return data
}
if type_of(data) == "dict" {
let targets = data?.targets ?? data?.affectedTargets ?? data?.affected_targets
if type_of(targets) == "list" {
return targets
}
}
return []
}
fn __verification_parse_json_targets(adapter_id: string, data, changed_paths) {
var targets = []
for item in __verification_json_target_values(data) {
targets = __verification_push_target(
targets,
__verification_target_from_value(item, adapter_id, "target", item?.files ?? changed_paths),
)
}
return targets
}
fn __verification_parse_line_targets(adapter_id: string, text: string, changed_paths) {
var targets = []
for line in text.split("\n") {
let id = trim(line)
if id != "" {
targets = __verification_push_target(
targets,
__verification_target_from_value(id, adapter_id, "target", changed_paths),
)
}
}
return targets
}
fn __verification_cargo_package_files(package, changed_paths) -> list<string> {
let manifest = __verification_clean_path(package?.manifest_path ?? "")
let root = dirname(manifest)
var files: list<string> = []
for path in changed_paths {
if __verification_path_under(root, path) {
files = files + [path]
}
}
return files
}
fn __verification_cargo_target_names(package) -> list<string> {
var names: list<string> = []
for target in package?.targets ?? [] {
let name = trim(to_string(target?.name ?? target))
if name != "" && !contains(names, name) {
names = names + [name]
}
}
return names
}
fn __verification_parse_cargo_metadata(adapter_id: string, data, changed_paths) {
var targets = []
for package in data?.packages ?? [] {
let files = __verification_cargo_package_files(package, changed_paths)
if len(files) == 0 {
continue
}
let name = trim(to_string(package?.name ?? ""))
if name == "" {
continue
}
targets = __verification_push_target(
targets,
{
id: "cargo:" + name,
label: name,
kind: "cargo-package",
adapter_id: adapter_id,
source: "adapter",
files: files,
manifest_path: package?.manifest_path,
target_names: __verification_cargo_target_names(package),
},
)
}
return targets
}
fn __verification_project_targets(project) -> list<string> {
let raw = project?.targets ?? project?.tasks ?? []
if type_of(raw) == "dict" {
return raw.keys().sort()
}
var names: list<string> = []
for item in raw {
let name = trim(to_string(item?.name ?? item))
if name != "" && !contains(names, name) {
names = names + [name]
}
}
return names.sort()
}
fn __verification_project_rows(data) {
let raw = data?.projects ?? data?.workspaces ?? data
var rows = []
if type_of(raw) == "dict" {
for name in raw.keys().sort() {
rows = rows + [(raw[name] ?? {}) + {name: name}]
}
return rows
}
if type_of(raw) == "list" {
return raw
}
return []
}
fn __verification_parse_js_workspace_graph(adapter_id: string, data, changed_paths) {
var targets = []
for project in __verification_project_rows(data) {
let root = project?.root ?? project?.sourceRoot ?? project?.source_root ?? ""
var files: list<string> = []
for path in changed_paths {
if __verification_path_under(root, path) {
files = files + [path]
}
}
if len(files) == 0 {
continue
}
let name = trim(to_string(project?.name ?? project?.id ?? root))
if name == "" {
continue
}
targets = __verification_push_target(
targets,
{
id: "js:" + name,
label: name,
kind: "js-project",
adapter_id: adapter_id,
source: "adapter",
files: files,
root: root,
target_names: __verification_project_targets(project),
},
)
}
return targets
}
fn __verification_parse_adapter_targets(
row,
adapter_id: string,
parser_id: string,
result,
changed_paths,
) {
if parser_id == "harn.targets_lines.v1" || parser_id == "lines.v1" {
return __verification_parse_line_targets(adapter_id, result?.stdout ?? "", changed_paths)
}
let data = json_parse(result?.stdout ?? "null")
if parser_id == "harn.targets_json.v1" || parser_id == "json.targets.v1" {
return __verification_parse_json_targets(adapter_id, data, changed_paths)
}
if parser_id == "cargo.metadata.v1" {
return __verification_parse_cargo_metadata(adapter_id, data, changed_paths)
}
if parser_id == "js.workspace_graph.v1" || parser_id == "nx.project_graph.v1" {
return __verification_parse_js_workspace_graph(adapter_id, data, changed_paths)
}
throw "verification_affected_targets: unsupported parser_id `" + parser_id + "`"
}
fn __verification_code_index_fallback(changed_paths, opts) {
if opts?.fallback == false {
return {enabled: false, available: false, targets: []}
}
var targets = []
var errors = []
for path in changed_paths {
targets = __verification_push_target(
targets,
{
id: "file:" + path,
label: path,
kind: "file",
source: "code_index",
files: [path],
reason: "changed_file",
},
)
let file_id = try {
hostlib_code_index_path_to_id({path: path})
} catch (e) {
errors = errors + [to_string(e)]
nil
}
if file_id == nil || file_id == 0 {
continue
}
let importers = try {
hostlib_code_index_deps_get({file_id: file_id, direction: "importers"})
} catch (e) {
errors = errors + [to_string(e)]
[]
}
for importer_id in importers {
let importer_path = try {
hostlib_code_index_id_to_path({file_id: importer_id})
} catch (_e) {
nil
}
if importer_path != nil {
targets = __verification_push_target(
targets,
{
id: "file:" + importer_path,
label: importer_path,
kind: "file",
source: "code_index",
files: [importer_path],
reason: "reverse_dependency",
changed_path: path,
},
)
}
}
}
return {enabled: true, available: len(errors) == 0, targets: targets, errors: errors}
}
fn __verification_profile_row_id(row, index: int) -> string {
let id = trim(to_string(row?.id ?? row?.name ?? ""))
if id != "" {
return id
}
return "profile/" + to_string(index)
}
fn __verification_check(row) -> dict {
if type_of(row?.check) == "dict" {
return row.check
}
return {}
}
fn __verification_rung_text(value) -> string {
return uppercase(trim(to_string(value ?? "")))
}
fn __verification_rung_rank(value) {
let rung = __verification_rung_text(value)
let direct = to_int(rung)
if direct != nil && direct >= 0 && direct <= 5 {
return direct
}
if len(rung) == 2 && starts_with(rung, "R") {
let parsed = to_int(substring(rung, 1))
if parsed != nil && parsed >= 0 && parsed <= 5 {
return parsed
}
}
return nil
}
fn __verification_rung_bound(value, fallback: int) -> int {
let rank = __verification_rung_rank(value)
return rank ?? fallback
}
fn __verification_resource_class(row, check) -> string {
let raw = check?.resourceClass ?? check?.resource_class ?? row?.resourceClass ?? row?.resource_class
?? "moderate"
let value = lowercase(trim(to_string(raw)))
return value == "" ? "moderate" : value
}
fn __verification_resource_rank(value) -> int {
let resource = lowercase(trim(to_string(value ?? "")))
if resource == "cheap" {
return 0
}
if resource == "moderate" {
return 1
}
if resource == "heavy" {
return 2
}
if resource == "remote_ok" || resource == "remote-ok" || resource == "remote" {
return 3
}
return 4
}
fn __verification_lower_string_list(value) -> list<string> {
var out: list<string> = []
for item in __verification_string_list(value) {
let text = lowercase(item)
if !contains(out, text) {
out = out + [text]
}
}
return out
}
fn __verification_resource_allowed(resource: string, opts) -> bool {
let allowed = __verification_lower_string_list(opts?.resource_classes ?? opts?.allowed_resource_classes)
if len(allowed) == 0 {
return true
}
return contains(allowed, lowercase(resource))
}
fn __verification_warm_state_fact_for(row_id: string, opts) {
let facts = opts?.warm_state_facts ?? opts?.warm_states ?? []
if type_of(facts) == "dict" {
return facts[row_id]
}
for fact in facts {
let id = trim(to_string(fact?.row_id ?? fact?.id ?? ""))
if id == row_id {
return fact
}
}
return nil
}
fn __verification_row_timing_kind(row_id: string, row, opts, warm_state) -> string {
let explicit = lowercase(trim(to_string(opts?.timing_kind ?? "")))
if explicit != "" && explicit != "auto" {
return explicit
}
if warm_state != nil {
return warm_state?.warm ?? false ? "warm" : "cold"
}
let mode = __verification_warm_state_mode(row)
if mode?.warm != nil {
return mode.warm ? "warm" : "cold"
}
if mode?.ready != nil {
return mode.ready ? "warm" : "cold"
}
return "warm"
}
fn __verification_row_p95_ms(row, opts, timing_kind: string) -> int {
let kind = lowercase(trim(to_string(timing_kind)))
let timings = row?.timings ?? {}
let raw = if kind == "cold" {
timings?.coldMs?.p95
} else if kind == "any" {
timings?.warmMs?.p95 ?? timings?.coldMs?.p95
} else {
timings?.warmMs?.p95 ?? timings?.coldMs?.p95
}
return to_int(raw) ?? to_int(opts?.unknown_p95_ms) ?? 999999
}
fn __verification_row_command(row, check) {
return check?.command ?? check?.spec ?? row?.command ?? row?.spec
}
fn __verification_command_present(command) -> bool {
if command == nil {
return false
}
if type_of(command) == "string" {
return trim(command) != ""
}
return true
}
fn __verification_skip(row_id: string, reason: string, profile_match) -> dict {
return {
row_id: row_id,
reason: reason,
specificity: profile_match?.specificity ?? 0,
index: profile_match?.index ?? 0,
}
}
fn __verification_ladder_candidate(profile_match, opts) {
let row = profile_match?.row ?? {}
let row_id = __verification_profile_row_id(row, to_int(profile_match?.index) ?? 0)
let check = __verification_check(row)
let rung_rank = __verification_rung_rank(check?.rung ?? row?.rung)
if rung_rank == nil {
return {entry: nil, skip: __verification_skip(row_id, "missing_or_invalid_rung", profile_match)}
}
let rung = "R" + to_string(rung_rank)
let min_rank = __verification_rung_bound(opts?.min_rung, 0)
let max_rank = __verification_rung_bound(opts?.max_rung, 5)
if rung_rank < min_rank {
return {entry: nil, skip: __verification_skip(row_id, "below_min_rung", profile_match)}
}
if rung_rank > max_rank {
return {entry: nil, skip: __verification_skip(row_id, "above_max_rung", profile_match)}
}
let resource = __verification_resource_class(row, check)
if !__verification_resource_allowed(resource, opts) {
return {entry: nil, skip: __verification_skip(row_id, "resource_class_filtered", profile_match)}
}
if opts?.allow_stale_prone == false
&& (check?.staleProne ?? check?.stale_prone ?? row?.staleProne ?? row?.stale_prone ?? false) {
return {entry: nil, skip: __verification_skip(row_id, "stale_prone_filtered", profile_match)}
}
let command = __verification_row_command(row, check)
if !__verification_command_present(command) {
return {entry: nil, skip: __verification_skip(row_id, "missing_command", profile_match)}
}
let warm_state = __verification_warm_state_fact_for(row_id, opts)
let timing_kind = __verification_row_timing_kind(row_id, row, opts, warm_state)
let p95_ms = __verification_row_p95_ms(row, opts, timing_kind)
let specificity = to_int(profile_match?.specificity) ?? 0
let index = to_int(profile_match?.index) ?? 0
let sort_key = [rung_rank, __verification_resource_rank(resource), p95_ms, 0 - specificity, index]
return {
entry: {
row_id: row_id,
row: row,
rung: rung,
rung_rank: rung_rank,
command: command,
runnable: true,
granularity: check?.granularity ?? row?.granularity,
trust: check?.trust ?? check?.trust_level ?? row?.trust ?? row?.trust_level,
resource_class: resource,
p95_ms: p95_ms,
timing_kind: timing_kind,
warm_state: warm_state,
specificity: specificity,
index: index,
sort_key: sort_key,
background: check?.background ?? row?.background ?? false,
},
skip: nil,
}
}
/**
* Capture current on-disk hashes for `paths` under one code-index sequence
* binding. Unknown-but-readable workspace files are included with
* `known = false`; unreadable or out-of-workspace paths return a null hash
* and appear in `missing`. The `snapshot` field is the direct path->hash map
* consumed by `verification_diagnostic_classify`.
*
* @effects: [host, fs]
* @errors: [backend, invalid_argument]
* @api_stability: experimental
* @example: verification_file_hash_snapshot(["src/main.zig", "build.zig"])
*/
pub fn verification_file_hash_snapshot(paths: list<string>) -> VerificationFileHashSnapshot {
return hostlib_code_index_file_hash_snapshot({paths: paths})
}
/**
* Resolve build/test targets affected by changed files using data-declared
* adapters. Each adapter row supplies a command `spec` (or `command`) and a
* `parser_id`; Harn ships parser ids for generic JSON/line targets, Cargo
* metadata, and JS workspace graphs, while arbitrary stacks can add rows
* without changing Rust code.
*
* Supported parser ids:
* - `harn.targets_json.v1`: stdout JSON is `[{id, ...}]` or `{targets:[...]}`
* - `harn.targets_lines.v1`: one target id per stdout line
* - `cargo.metadata.v1`: Cargo metadata JSON; changed files map to packages
* - `js.workspace_graph.v1`: `{projects:{name:{root, targets}}}` or list rows
*
* If adapters produce no targets, the helper falls back to the existing
* code-index file graph: the changed file plus reverse importers become
* conservative file targets. Pass `{fallback:false}` to disable that.
*
* @effects: [process, host]
* @errors: [invalid_argument]
* @api_stability: experimental
*/
pub fn verification_affected_targets(changed_paths: list<string>, adapters = nil, options = nil) -> VerificationAffectedTargetsFact {
let opts = __verification_opts(options)
let paths = __verification_string_list(changed_paths)
let rows = adapters ?? opts?.adapters ?? []
var targets = []
var adapter_facts: list<VerificationAffectedAdapterFact> = []
var index = 0
for row in rows {
let adapter_id = __verification_adapter_id(row, index)
let parser_id = __verification_parser_id(row)
let spec = __verification_adapter_spec(row, paths, opts)
if spec == nil {
adapter_facts = adapter_facts
+ [{id: adapter_id, parser_id: parser_id, status: "not_configured", ok: false, target_count: 0}]
index = index + 1
continue
}
let result = command_run(spec, __verification_adapter_command_options(row, opts))
let parsed = try {
__verification_parse_adapter_targets(row, adapter_id, parser_id, result, paths)
} catch (e) {
if opts?.fail_on_adapter_error ?? false {
throw e
}
adapter_facts = adapter_facts
+ [
{
id: adapter_id,
parser_id: parser_id,
status: result?.status ?? "failed",
ok: false,
exit: __verification_exit(result, {}),
target_count: 0,
error: to_string(e),
},
]
[]
}
for target in parsed {
targets = __verification_push_target(targets, target)
}
if len(parsed) > 0 || len(adapter_facts) == index {
adapter_facts = adapter_facts
+ [
{
id: adapter_id,
parser_id: parser_id,
status: result?.status ?? "completed",
ok: __verification_result_ok(result),
exit: __verification_exit(result, {}),
target_count: len(parsed),
},
]
}
index = index + 1
}
let fallback = if len(targets) == 0 || opts?.include_fallback == true {
__verification_code_index_fallback(paths, opts)
} else {
{enabled: false, available: false, targets: []}
}
for target in fallback.targets ?? [] {
targets = __verification_push_target(targets, target)
}
return {changed_paths: paths, targets: targets, adapters: adapter_facts, fallback: fallback}
}
/**
* Build a data-driven verification ladder plan from profile rows.
*
* The selector engine lives in the Harn VM builtin
* `verification_profile_matches`; this helper only ranks matching rows by
* declared rung, resource class, observed p95 timing, selector specificity,
* and row order. It never hardcodes languages, toolchains, or commands.
*
* Options:
* - `dir`: profile-store directory to read from.
* - `min_rung` / `max_rung`: inclusive bounds, default `R0`..`R5`.
* - `resource_classes`: optional allow-list such as `["cheap", "moderate"]`.
* - `timing_kind`: `warm` (default), `cold`, or `any`.
* - `unknown_p95_ms`: timing fallback for unseen rows, default `999999`.
* - `allow_stale_prone`: set false to skip stale-prone checks.
* - `limit`: optional maximum selected checks.
*
* @effects: [state]
* @errors: []
* @api_stability: experimental
*/
pub fn verification_ladder_plan(query: dict, options = nil) -> VerificationLadderPlan {
let opts = __verification_opts(options)
let matches = verification_profile_matches(query, opts?.dir)
var selected = []
var skipped = []
for profile_match in matches {
let candidate = __verification_ladder_candidate(profile_match, opts)
if candidate.entry != nil {
selected = selected + [candidate.entry]
} else if candidate.skip != nil {
skipped = skipped + [candidate.skip]
}
}
selected = selected.sort_by({ entry -> entry.sort_key })
let limit = to_int(opts?.limit)
if limit != nil && limit >= 0 && len(selected) > limit {
selected = selected.slice(0, limit)
}
let reason = if len(matches) == 0 {
"no_profile_rows"
} else if len(selected) == 0 {
"no_matching_runnable_rows"
} else {
"profile_rows_selected"
}
return {
schema: "harn.verification.ladder_plan.v1",
query: query,
matches: matches,
selected: selected,
skipped: skipped,
fallback: len(selected) == 0,
reason: reason,
}
}
/**
* Compare previous and current verification diagnostics as normalized sets and
* return deterministic progress credit. This is the data-only primitive behind
* diagnostic-delta repair policy: advisory/stale/unbound diagnostics never feed
* gates; advisory previous diagnostics never become the baseline; a clean
* current result clears a gate-bearing failure; removed or changed stuck
* signatures advance; the same normalized set does not.
*
* Inputs may be `nil`, a string signature, a single diagnostic dict, a check
* result dict, or `{diagnostics:[...]}` / `{errors:[...]}`. Row-level
* normalization is read from `diagnosticDelta`, `diagnostic_delta`,
* `signatureNormalization`, or `signature_normalization` on the row and its
* check, then overridden by direct options.
*
* @effects: []
* @errors: []
* @api_stability: experimental
*/
pub fn verification_diagnostic_delta(previous, current, options = nil) -> VerificationDiagnosticDelta {
let normalization = __verification_delta_normalization(options)
let previous_info = __verification_delta_info(previous, normalization)
let current_info = __verification_delta_info(current, normalization)
let previous_gate_signatures = __verification_delta_gate_signatures(previous_info)
let current_gate_signatures = __verification_delta_gate_signatures(current_info)
let removed = __verification_delta_set_minus(previous_gate_signatures, current_gate_signatures)
let added = __verification_delta_set_minus(current_gate_signatures, previous_gate_signatures)
let persisted = __verification_delta_set_intersection(previous_gate_signatures, current_gate_signatures)
if !current_info.feedsGates {
return __verification_delta_result(
"advisory",
false,
previous_info,
current_info,
removed,
added,
persisted,
normalization,
"current_diagnostic_does_not_feed_gates",
)
}
let current_clear = current_info.explicit_success || (current_info.has_collection && current_info.count == 0)
if current_clear {
return __verification_delta_result(
"cleared",
len(previous_gate_signatures) > 0,
previous_info,
current_info,
removed,
added,
persisted,
normalization,
"current_result_is_passing",
)
}
if !current_info.failed || len(current_gate_signatures) == 0 {
return __verification_delta_result(
"initialized",
false,
previous_info,
current_info,
removed,
added,
persisted,
normalization,
"current_has_no_gate_bearing_failure_signature",
)
}
if !previous_info.feedsGates || !previous_info.failed || len(previous_gate_signatures) == 0 {
return __verification_delta_result(
"initialized",
false,
previous_info,
current_info,
removed,
added,
persisted,
normalization,
"no_prior_gate_bearing_failure",
)
}
if len(removed) == 0 && len(added) == 0 {
if current_info.count < previous_info.count {
return __verification_delta_result(
"advanced",
true,
previous_info,
current_info,
removed,
added,
persisted,
normalization,
"diagnostic_count_decreased",
)
}
if current_info.count > previous_info.count {
return __verification_delta_result(
"regressed",
false,
previous_info,
current_info,
removed,
added,
persisted,
normalization,
"diagnostic_count_increased",
)
}
return __verification_delta_result(
"unchanged",
false,
previous_info,
current_info,
removed,
added,
persisted,
normalization,
"same_diagnostic_signature_set",
)
}
if len(removed) > 0 {
return __verification_delta_result(
"advanced",
true,
previous_info,
current_info,
removed,
added,
persisted,
normalization,
"diagnostic_signature_set_changed",
)
}
if len(added) > 0 {
return __verification_delta_result(
"regressed",
false,
previous_info,
current_info,
removed,
added,
persisted,
normalization,
"new_diagnostics_added_without_clearing_prior_signatures",
)
}
return __verification_delta_result(
"unchanged",
false,
previous_info,
current_info,
removed,
added,
persisted,
normalization,
"same_diagnostic_signature_set",
)
}
/**
* Convert a normalized command/check result into the canonical profile-store
* observation shape: `{durationMs, warm, exit, failureSignature?, snapshot?}`.
* This keeps timing capture DRY while leaving scheduler policy to the caller.
*
* Options:
* - `warm` / `cold`: classify the run for warm/cold timing distributions.
* - `snapshot`: either a direct file->hash map or a
* `VerificationFileHashSnapshot`.
* - `failure_signature`: explicit signature to persist on failing runs.
* - `failure_signature_from`: `combined` (default), `stderr`, `stdout`, or
* `none`.
* - `max_failure_signature_chars`: defaults to 4000.
*
* @effects: []
* @errors: []
* @api_stability: experimental
*/
pub fn verification_observation_from_command_result(result: dict, options = nil) -> VerificationCheckObservation {
let opts = __verification_opts(options)
var observation = {warm: __verification_warm(opts)}
let duration_ms = __verification_duration_ms(result, opts)
if duration_ms != nil {
observation = observation + {durationMs: duration_ms}
}
let exit_code = __verification_exit(result, opts)
if exit_code != nil {
observation = observation + {exit: exit_code}
}
let snapshot = __verification_snapshot_map(opts?.snapshot)
if snapshot != nil {
observation = observation + {snapshot: snapshot}
}
let failure_signature = __verification_failure_signature(result, opts)
if failure_signature != nil {
observation = observation + {failureSignature: failure_signature}
}
if opts?.at != nil {
observation = observation + {at: to_string(opts.at)}
}
return observation
}
/**
* Record one command/check result into a verification profile row and return
* the persisted row plus the observation that was applied. Unknown row ids
* return `row = nil`, matching `verification_profile_record_run`.
*
* @effects: [state]
* @errors: [invalid_argument]
* @api_stability: experimental
*/
pub fn verification_record_check_result(row_id: string, result: dict, options = nil) -> VerificationRecordedCheck {
let opts = __verification_opts(options)
let observation = verification_observation_from_command_result(result, opts)
let row = verification_profile_record_run(row_id, observation, opts?.dir)
return {result: result, observation: observation, row: row, snapshot: nil}
}
/**
* Run a command as one verification check, capture optional launch-time file
* hashes, and record exactly one profile observation for the completed result.
*
* Options:
* - `command_options`: options passed to `command_run`.
* - `snapshot_paths`: file paths hashed before the command launches.
* - `snapshot`: explicit file->hash map when the caller already captured one.
* - `record`: set `false` to run and build the observation without updating
* the profile store.
* - any `verification_observation_from_command_result` option.
*
* @effects: [process, host, fs, state]
* @errors: [backend, invalid_argument]
* @api_stability: experimental
*/
pub fn verification_run_check(row_id: string, spec, options = nil) -> VerificationRecordedCheck {
let opts = __verification_opts(options)
if opts?.command_options?.background == true {
throw "verification_run_check: background command_options are not supported; use verification_start_check"
}
let captured = __verification_capture_snapshot(opts)
let result = command_run(spec, opts?.command_options)
let observation = verification_observation_from_command_result(result, opts + {snapshot: captured.snapshot})
var row = nil
if opts?.record != false {
row = verification_profile_record_run(row_id, observation, opts?.dir)
}
return {result: result, observation: observation, row: row, snapshot: captured.fact}
}
/**
* Start a verification check in the background after capturing optional
* launch-time file hashes. The returned receipt is safe to persist and pass to
* `verification_finish_check`; no profile row is updated until finish records
* the completed result.
*
* @effects: [process, host, fs]
* @errors: [backend, invalid_argument]
* @api_stability: experimental
*/
pub fn verification_start_check(row_id: string, spec, options = nil) -> VerificationStartedCheck {
let opts = __verification_opts(options)
let captured = __verification_capture_snapshot(opts)
let command_options = (opts?.command_options ?? {}) + {background: true}
let started = command_run(spec, command_options)
return {
row_id: row_id,
started: started,
observation_options: opts + {snapshot: captured.snapshot},
snapshot: captured.fact,
}
}
/**
* Wait for a check started by `verification_start_check`, record its completed
* command result into the profile row, and return the same recorded-check
* receipt shape as `verification_run_check`.
*
* Options:
* - `wait_options`: options passed to `command_wait`.
* - `record`: set `false` to wait and build the observation without updating
* the profile store.
* - `row_id`: override the row id stored in the started-check receipt.
* - any observation option can override the started-check observation options.
*
* @effects: [process, state]
* @errors: [backend, invalid_argument]
* @api_stability: experimental
*/
pub fn verification_finish_check(started_check: dict, options = nil) -> VerificationRecordedCheck {
let opts = __verification_opts(options)
let row_id = opts?.row_id ?? started_check?.row_id
if row_id == nil || trim(to_string(row_id)) == "" {
throw "verification_finish_check: row_id must be supplied in the receipt or options"
}
let result = command_wait(started_check.started, opts?.wait_options ?? {timeout_ms: 60000})
let observation_options = (started_check?.observation_options ?? {}) + opts
let observation = verification_observation_from_command_result(result, observation_options)
var row = nil
if opts?.record != false && started_check?.observation_options?.record != false {
row = verification_profile_record_run(to_string(row_id), observation, observation_options?.dir)
}
return {result: result, observation: observation, row: row, snapshot: started_check?.snapshot}
}
/**
* Execute config-declared toolchain probes and return deterministic identity
* facts. Rows are data, not code: Harn does not hardcode Go, Zig, Cargo, or
* any other toolchain. A row may declare:
*
* - `id` / `name`
* - `versionProbe`: a `command_run` spec or `{spec, versionPattern,
* command_options}`
* - `cacheIdentity`: any cache/build-server/env identity fields the scheduler
* wants to bind to the profile row
*
* Failed or missing probes produce `available = false` facts instead of
* throwing, so a verification scheduler can reason about unavailable tools.
*
* @effects: [process]
* @errors: []
* @api_stability: experimental
*/
pub fn verification_toolchain_facts(rows: list<dict>, options = nil) -> list<VerificationToolchainFact> {
let opts = __verification_opts(options)
var facts = []
var index = 0
for row in rows {
let id = __verification_row_id(row, index)
let name = __verification_toolchain_name(row, id)
let spec = __verification_toolchain_probe(row)
var result = nil
if spec != nil {
result = command_run(spec, __verification_toolchain_probe_options(row, opts))
}
let ok = result != nil && __verification_result_ok(result)
let raw_version = result == nil ? "" : __verification_toolchain_raw_version(result)
let version = ok ? regex_first_capture(__verification_toolchain_version_pattern(row, opts), raw_version) : nil
let exit_code = result == nil ? nil : __verification_exit(result, {})
let probe = {
status: result?.status ?? "not_configured",
exit: exit_code,
durationMs: result?.duration_ms,
stdout: result?.stdout ?? "",
stderr: result?.stderr ?? "",
}
facts = facts
+ [
{
id: id,
name: name,
available: ok,
version: version,
raw_version: raw_version,
cache_identity: __verification_toolchain_cache_identity(row, opts),
probe: probe,
},
]
index = index + 1
}
return facts
}
/**
* Execute config-declared warm-state probes and return deterministic readiness
* facts for verification scheduling. Rows are data, not code: a row may
* declare `warmMode` / `warm_state` with a `readyProbe`, cache identity,
* expected warm-vs-cold delta, and optional timing hints. The helper does not
* hardcode language names or build-system daemons.
*
* A ready probe that exits successfully marks the row warm; a failing or
* missing probe marks it cold. Pass the returned list to
* `verification_ladder_plan(..., {timing_kind:"auto", warm_state_facts:facts})`
* so each selected check uses its own warm or cold p95 timing.
*
* @effects: [process]
* @errors: []
* @api_stability: experimental
*/
pub fn verification_warm_state_facts(rows: list<dict>, options = nil) -> list<VerificationWarmStateFact> {
let opts = __verification_opts(options)
var facts = []
var index = 0
for row in rows {
let mode = __verification_warm_state_mode(row)
let id = __verification_warm_state_id(row, index)
let name = __verification_warm_state_name(row, id)
let spec = __verification_warm_state_probe(row)
var result = nil
if spec != nil {
result = command_run(spec, __verification_warm_state_probe_options(row, opts))
}
let probe_ready = result != nil && __verification_result_ok(result)
let configured = mode != nil || spec != nil
let ready = if mode?.ready != nil {
mode.ready ? true : false
} else if mode?.warm != nil {
mode.warm ? true : false
} else {
probe_ready
}
let timings = __verification_warm_state_timings(row, mode ?? {})
facts = facts
+ [
{
id: id,
name: name,
configured: configured,
available: probe_ready,
ready: ready,
warm: ready,
timing_kind: ready ? "warm" : "cold",
mode: __verification_warm_state_mode_name(mode ?? {}),
expected_warm_delta_ms: __verification_warm_state_expected_delta_ms(row, mode ?? {}),
warm_ms: timings.warm_ms,
cold_ms: timings.cold_ms,
cache_identity: __verification_warm_state_cache_identity(row, opts),
probe: __verification_warm_state_probe_receipt(result),
},
]
index = index + 1
}
return facts
}