feat: accept Glas execution overrides

This commit is contained in:
tegwick 2026-08-21 00:21:53 +02:00
parent 0ebca80254
commit cf24d34b28
3 changed files with 52 additions and 5 deletions

View file

@ -41,6 +41,13 @@ rein-aharness profiles
# Run exactly one task (local JSON task-file path — dev)
rein-aharness run --task-file examples/task-hello-sandbox.json [--no-hub] [--no-metrics]
# Execution-profile overrides supplied by glas-harness
rein-aharness run --task-file examples/task-hello-sandbox.json \
--model claude-sonnet-4-6 \
--tool-profile green-commit-only \
--budget-tokens 60000 \
--no-hub --no-metrics
# Primary production intake: activity-core ops_run claim (ACT-ADR-005 / REIN-A-0002)
export ACTIVITY_CORE_URL=http://127.0.0.1:8010
export ACTIVITY_CORE_WORKER_TOKEN=…
@ -78,6 +85,10 @@ repo's instance manifest (default `green-commit-only`), loads a persona
bundle (`kaizen-agentic schedule prepare`), runs a bounded agentic
session (cwd-pinned, hard allow-list, never pushes), verifies a local
commit, writes `.kaizen/metrics`, and posts a State Hub progress event.
When invoked through `glas-harness`, the explicit versioned Glas profile may
override model, tool profile, and budget for that bounded run. Workforce and
activity consumers should reference the Glas profile rather than encode these
rein CLI details in an assignment.
Instance manifest contract: [docs/instance-manifest.md](docs/instance-manifest.md).
Example: [examples/schedule.harness.yml](examples/schedule.harness.yml).

View file

@ -235,6 +235,9 @@ def _cmd_run(args: argparse.Namespace) -> int:
write_metrics=not args.no_metrics,
emit_tool_events=args.stream_tool_events,
on_tool_event=_print_event if args.stream_tool_events else None,
model=args.model,
tool_profile_override=args.tool_profile,
budget_tokens_override=args.budget_tokens,
)
closed = False
@ -262,6 +265,7 @@ def _cmd_run(args: argparse.Namespace) -> int:
"tokens_spent": result.tokens_spent,
"execution_time_s": round(result.execution_time_s, 3),
"reason": result.reason,
"model": result.model,
"issue_id": issue_id,
"issue_closed": closed,
"issue_close_error": close_error,
@ -313,6 +317,22 @@ def main(argv: list[str] | None = None) -> int:
"-- HARNESS-WP-0002-T03)"
),
)
run.add_argument(
"--model",
default=None,
help="Explicit Claude Code model identifier supplied by the execution profile",
)
run.add_argument(
"--tool-profile",
default=None,
help="Override the instance tool profile for this explicitly governed run",
)
run.add_argument(
"--budget-tokens",
type=int,
default=None,
help="Override the instance token budget for this explicitly governed run",
)
scan = sub.add_parser(
"mail-scan", help="Deterministic company-mailbox scan (no LLM session)"

View file

@ -50,6 +50,7 @@ class RunResult:
persona_source: str
session_output: str
reason: str = ""
model: str | None = None
tool_profile: str = ""
budget_tokens: int | None = None
tokens_spent: int | None = None
@ -79,11 +80,18 @@ def run_task(
write_metrics: bool = True,
emit_tool_events: bool = False,
on_tool_event: Callable[[dict[str, Any]], None] | None = None,
model: str | None = None,
tool_profile_override: str | None = None,
budget_tokens_override: int | None = None,
) -> RunResult:
try:
profile_name, budget_tokens, lane, blueprint = resolve_run_policy(
spec.target_repo, spec.agent
)
if tool_profile_override:
profile_name = tool_profile_override
if budget_tokens_override is not None:
budget_tokens = budget_tokens_override
profile = get_profile(profile_name)
except UnknownToolProfileError as exc:
return RunResult(
@ -96,6 +104,7 @@ def run_task(
reason=f"refused: {exc}",
tool_profile="",
budget_tokens=None,
model=model,
)
except Exception as exc:
return RunResult(
@ -108,6 +117,7 @@ def run_task(
reason=f"manifest resolution failed: {exc}",
tool_profile="",
budget_tokens=None,
model=model,
)
collected_events: list[dict[str, Any]] = []
@ -127,11 +137,14 @@ def run_task(
if adapter is None:
from rein_aharness.adapter import AgenticClaudeCodeAdapter
adapter = AgenticClaudeCodeAdapter(
workdir=spec.target_repo,
tool_profile=profile,
on_tool_event=_on_event if (emit_tool_events or on_tool_event) else None,
)
adapter_kwargs = {
"workdir": spec.target_repo,
"tool_profile": profile,
"on_tool_event": _on_event if (emit_tool_events or on_tool_event) else None,
}
if model is not None:
adapter_kwargs["model"] = model
adapter = AgenticClaudeCodeAdapter(**adapter_kwargs)
head_before = _git(spec.target_repo, "rev-parse", "HEAD")
persona, persona_source = load_persona_bundle(blueprint, spec.target_repo)
@ -156,12 +169,14 @@ def run_task(
try:
response = adapter.execute_prompt(prompt, config)
session_output = response.content
resolved_model = response.model
session_ok = True
reason = ""
except Exception as exc: # adapter / budget failures must still be reported
session_output = ""
session_ok = False
reason = f"session failed: {exc}"
resolved_model = model
execution_time_s = time.monotonic() - started
head_after = _git(spec.target_repo, "rev-parse", "HEAD")
@ -180,6 +195,7 @@ def run_task(
persona_source=persona_source,
session_output=session_output,
reason=reason,
model=resolved_model,
tool_profile=profile.name,
budget_tokens=budget_tokens,
tokens_spent=tokens_spent,