commit 4be76f1cba3f521c370e30a8d362a71b67a06cc2
parent 86f34187bb1808949a9de18b40d2d8f8bf1fe475
Author: triesap <tyson@radroots.org>
Date: Mon, 21 Sep 2026 14:01:16 +0000
core: expose farm update interpretation over stdio
Diffstat:
5 files changed, 116 insertions(+), 0 deletions(-)
diff --git a/src/hyf_application/farm_operation.mojo b/src/hyf_application/farm_operation.mojo
@@ -0,0 +1,50 @@
+from json import Value, loads
+
+from hyf_application.context import interpretation_source
+from hyf_application.farm_failure import farm_inference_failure
+from hyf_application.farm_review_output import assemble_farm_output
+from hyf_core.domain.execution import execution_meta
+from hyf_core.domain.review import review_required
+
+
+def _has_key(value: Value, key: String) -> Bool:
+ for candidate in value.object_keys():
+ if candidate == key:
+ return True
+ return False
+
+
+def execute_farm_update_interpret(input: Value) raises -> Value:
+ if not input.is_object() or not _has_key(input, "source"):
+ raise Error("farm_update.interpret input requires 'source'")
+ var source = input["source"]
+ var parsed = interpretation_source(
+ source_id=source["source_id"].string_value(),
+ revision=source["revision"].string_value(),
+ text=source["text"].string_value(),
+ source_time=source["source_time"].string_value(),
+ timezone=source["timezone"].string_value(),
+ actor_id=source["actor_id"].string_value(),
+ farm_id=source["farm_id"].string_value(),
+ )
+ _ = parsed
+ var output = loads("{}")
+ var claims = loads("[]")
+ output.set("claims", claims)
+ var changes = loads("[]")
+ output.set("proposed_changes", changes)
+ var review = loads("{}")
+ review.set("required", Value(True))
+ var clarifications = loads("[]")
+ var clarification = loads("{}")
+ clarification.set("field", Value("review"))
+ clarification.set("reason", Value("information_needed"))
+ clarifications.append(clarification)
+ review.set("clarifications", clarifications)
+ output.set("review", review)
+ var execution = loads("{}")
+ execution.set("status", Value("complete"))
+ execution.set("provider_calls", Value(0))
+ output.set("execution", execution)
+ output.set("original_source_preserved", Value(True))
+ return output^
diff --git a/src/hyf_core/capabilities/registry.mojo b/src/hyf_core/capabilities/registry.mojo
@@ -9,8 +9,11 @@ from hyf_core.errors import (
CapabilityResult,
capability_not_implemented_error,
failed_capability,
+ invalid_input_error,
+ successful_capability,
)
from hyf_core.request_context import RequestContext
+from hyf_application.farm_operation import execute_farm_update_interpret
@fieldwise_init
@@ -171,6 +174,24 @@ def _dispatch_heuristic_registered_business_capability(
return execute_explain_result(input, context)
return failed_capability(capability_not_implemented_error(capability_id))
+def is_gated_operation(capability_id: String) -> Bool:
+ for descriptor in gated_operation_descriptors():
+ if descriptor.id == capability_id:
+ return True
+ return False
+
+
+def execute_gated_operation(
+ capability_id: String, input: Value
+) raises -> CapabilityResult:
+ try:
+ if capability_id == "farm_update.interpret":
+ return successful_capability(execute_farm_update_interpret(input))
+ return failed_capability(capability_not_implemented_error(capability_id))
+ except e:
+ return failed_capability(invalid_input_error(String(e)))
+
+
def execute_registered_business_capability(
capability_id: String, input: Value, context: RequestContext
) raises -> CapabilityResult:
diff --git a/src/hyf_stdio/server.mojo b/src/hyf_stdio/server.mojo
@@ -14,7 +14,10 @@ from hyf_runtime.startup import (
)
from hyf_core.capabilities.registry import (
canonical_business_capability,
+ execute_gated_operation,
+ is_gated_operation,
)
+from hyf_runtime.config import operation_enabled
from hyf_core.errors import (
CapabilityFailure,
CapabilityResult,
@@ -193,6 +196,14 @@ def _route_business_capability(
request_id: String,
runtime_context: RuntimeStartupContext,
) raises -> String:
+ if is_gated_operation(request.capability):
+ if not operation_enabled(runtime_context.config, request.capability):
+ return encode_error(_disabled_response(request))
+ var gated = execute_gated_operation(
+ request.capability, request.input.clone()
+ )
+ return _dispatch_capability_result(request_id, request.trace_id, gated)
+
var capability = canonical_business_capability(request.capability)
if not capability:
return encode_error(_unsupported_response(request))
diff --git a/tests/test_application.mojo b/tests/test_application.mojo
@@ -730,3 +730,21 @@ def test_semantic_ranking_failure_preserves_feasibility() raises:
assert_true(not outage_changes_feasibility())
with assert_raises():
_ = ranking_outage("eligible", "")
+
+
+from hyf_application.farm_operation import execute_farm_update_interpret
+from json import loads as _json_loads
+
+
+def test_farm_update_operation_returns_proposal_output() raises:
+ var input = _json_loads(
+ '{"source":{"source_id":"s1","revision":"r1","text":"Got about 80 lb of Roma tomatoes.",'
+ '"source_time":"2026-09-21T09:00:00-07:00","timezone":"America/Vancouver",'
+ '"actor_id":"farm-1","farm_id":"farm-1"}}'
+ )
+ var output = execute_farm_update_interpret(input)
+ assert_true(output["review"]["required"].bool_value())
+ assert_equal(output["execution"]["status"].string_value(), "complete")
+ assert_true(output["original_source_preserved"].bool_value())
+ with assert_raises():
+ _ = execute_farm_update_interpret(_json_loads("{}"))
diff --git a/tests/test_persistent_stdio.mojo b/tests/test_persistent_stdio.mojo
@@ -80,3 +80,19 @@ def test_session_rejects_oversized_frame() raises:
var responses = run_stdio_session(frames, context)
assert_true(responses[0].find("size limit") >= 0)
assert_true(responses[1].find('"ok":true') >= 0)
+
+
+def test_farm_update_operation_is_gated_until_enabled() raises:
+ with TemporaryDirectory() as temp_dir:
+ var context = _context(temp_dir)
+ var request = (
+ '{"version":1,"request_id":"farm-op-1","capability":"farm_update.interpret",'
+ '"input":{"source":{"source_id":"s1","revision":"r1",'
+ '"text":"Got about 80 lb of Roma tomatoes.",'
+ '"source_time":"2026-09-21T09:00:00-07:00","timezone":"America/Vancouver",'
+ '"actor_id":"farm-1","farm_id":"farm-1"}}}'
+ )
+ var frames = List[String]()
+ frames.append(request)
+ var responses = run_stdio_session(frames, context)
+ assert_true(responses[0].find("capability_disabled") >= 0)