2026-07-17 23:49:03 +02:00
|
|
|
"""CLI: validate instance manifests and execute exactly one task."""
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
|
import json
|
|
|
|
|
import sys
|
2026-07-17 23:49:03 +02:00
|
|
|
from pathlib import Path
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
|
Rename package, CLI, and deploy artifacts to rein-aharness (HARNESS-WP-0002-T02)
agent_harness -> rein_aharness (package + all imports), CLI command
agent-harness -> rein-aharness, Docker image tag, k8s namespace/labels/
names, Makefile targets, deploy script env var/paths. In-repo identity
strings (hub event source, metrics harness field, default assignee,
argparse prog name, commit author identity) updated to match.
Historical documents left untouched on purpose: docs/adr/ADR-001-agent-harness-architecture.md,
docs/architecture.md (dated v0.1 snapshot), workplans/HARNESS-WP-0001
(completed under the old name), and the SSH host alias
"forgejo-agent-harness" (external ~/.ssh/config entry, not owned here).
Verified: 47/47 tests pass, CLI runs correctly from a fresh venv,
`make image` builds and the resulting container runs correctly.
deploy/README.md gained an explicit rename cutover checklist for what
this session cannot safely do unattended -- moving the host-side
secrets dir and checkout on railiance01, and not deleting the old k8s
namespace until the new one is confirmed working. The actual live
cutover (running that checklist against the real Railiance deployment)
is not attempted here -- real production surgery on binky-control's
live automation, needs the operator present.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 14:22:18 +02:00
|
|
|
from rein_aharness.manifest import (
|
2026-07-17 23:49:03 +02:00
|
|
|
ManifestError,
|
|
|
|
|
load_manifest_for_repo,
|
|
|
|
|
manifest_path,
|
|
|
|
|
validate_manifest,
|
|
|
|
|
)
|
Rename package, CLI, and deploy artifacts to rein-aharness (HARNESS-WP-0002-T02)
agent_harness -> rein_aharness (package + all imports), CLI command
agent-harness -> rein-aharness, Docker image tag, k8s namespace/labels/
names, Makefile targets, deploy script env var/paths. In-repo identity
strings (hub event source, metrics harness field, default assignee,
argparse prog name, commit author identity) updated to match.
Historical documents left untouched on purpose: docs/adr/ADR-001-agent-harness-architecture.md,
docs/architecture.md (dated v0.1 snapshot), workplans/HARNESS-WP-0001
(completed under the old name), and the SSH host alias
"forgejo-agent-harness" (external ~/.ssh/config entry, not owned here).
Verified: 47/47 tests pass, CLI runs correctly from a fresh venv,
`make image` builds and the resulting container runs correctly.
deploy/README.md gained an explicit rename cutover checklist for what
this session cannot safely do unattended -- moving the host-side
secrets dir and checkout on railiance01, and not deleting the old k8s
namespace until the new one is confirmed working. The actual live
cutover (running that checklist against the real Railiance deployment)
is not attempted here -- real production surgery on binky-control's
live automation, needs the operator present.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 14:22:18 +02:00
|
|
|
from rein_aharness.profiles import list_profiles
|
|
|
|
|
from rein_aharness.runner import run_task
|
|
|
|
|
from rein_aharness.taskspec import TaskSpec, TaskSpecError
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
|
|
|
|
|
|
2026-07-17 23:49:03 +02:00
|
|
|
def _cmd_validate(args: argparse.Namespace) -> int:
|
|
|
|
|
target = Path(args.target).expanduser().resolve()
|
|
|
|
|
path = manifest_path(target)
|
|
|
|
|
if not path.is_file():
|
|
|
|
|
print(f"error: no instance manifest at {path}", file=sys.stderr)
|
|
|
|
|
return 2
|
|
|
|
|
try:
|
|
|
|
|
manifest = load_manifest_for_repo(target)
|
|
|
|
|
except ManifestError as exc:
|
|
|
|
|
print(f"error: {exc}", file=sys.stderr)
|
|
|
|
|
return 2
|
|
|
|
|
|
|
|
|
|
errors = validate_manifest(
|
|
|
|
|
manifest, require_harness_fields=bool(args.strict)
|
|
|
|
|
)
|
|
|
|
|
if errors:
|
|
|
|
|
print(f"invalid: {path}", file=sys.stderr)
|
|
|
|
|
for err in errors:
|
|
|
|
|
print(f" - {err}", file=sys.stderr)
|
|
|
|
|
return 1
|
|
|
|
|
|
|
|
|
|
enabled = manifest.enabled_agents()
|
|
|
|
|
print(f"ok: {path}")
|
|
|
|
|
print(f" version: {manifest.version}")
|
|
|
|
|
if manifest.timezone:
|
|
|
|
|
print(f" timezone: {manifest.timezone}")
|
|
|
|
|
if manifest.harness is not None:
|
|
|
|
|
print(f" harness major: {manifest.harness}")
|
|
|
|
|
print(f" agents: {len(manifest.agents)} ({len(enabled)} enabled)")
|
|
|
|
|
for agent in manifest.agents:
|
|
|
|
|
flags = []
|
|
|
|
|
if not agent.enabled:
|
|
|
|
|
flags.append("disabled")
|
|
|
|
|
if agent.tool_profile:
|
|
|
|
|
flags.append(f"profile={agent.tool_profile}")
|
|
|
|
|
if agent.lane:
|
|
|
|
|
flags.append(f"lane={agent.lane}")
|
|
|
|
|
if agent.budget is not None:
|
|
|
|
|
flags.append(f"budget={agent.budget}")
|
|
|
|
|
suffix = f" [{', '.join(flags)}]" if flags else ""
|
|
|
|
|
print(f" - {agent.name}: {agent.cadence}{suffix}")
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _cmd_profiles(_args: argparse.Namespace) -> int:
|
|
|
|
|
for profile in list_profiles():
|
|
|
|
|
print(f"{profile.name}\tlane={profile.lane}\t{profile.description}")
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
2026-07-18 11:30:40 +02:00
|
|
|
def _cmd_poll(args: argparse.Namespace) -> int:
|
2026-08-03 20:04:25 +02:00
|
|
|
source = getattr(args, "source", "issue-core") or "issue-core"
|
|
|
|
|
if source in {"ops-run", "ops_run", "ops"}:
|
|
|
|
|
from rein_aharness.claim_loop import process_one, poll_peek
|
|
|
|
|
from rein_aharness.ops_run_client import OpsRunError
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
if args.no_claim:
|
|
|
|
|
rows = poll_peek()
|
|
|
|
|
print(
|
|
|
|
|
json.dumps(
|
|
|
|
|
{"source": "ops-run", "queue": "empty" if not rows else "open", "items": rows},
|
|
|
|
|
indent=2,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
return 0
|
|
|
|
|
result = process_one(
|
|
|
|
|
dry_run=bool(getattr(args, "dry_run", False)),
|
|
|
|
|
report_to_hub=False if getattr(args, "no_hub", False) else True,
|
|
|
|
|
)
|
|
|
|
|
except OpsRunError as exc:
|
|
|
|
|
print(f"ops-run error: {exc}", file=sys.stderr)
|
|
|
|
|
return 2
|
|
|
|
|
print(
|
|
|
|
|
json.dumps(
|
|
|
|
|
{
|
|
|
|
|
"source": "ops-run",
|
|
|
|
|
"claimed": result.claimed,
|
|
|
|
|
"empty": result.empty,
|
|
|
|
|
"run_id": result.run_id,
|
|
|
|
|
"approach": result.approach,
|
|
|
|
|
"ok": result.ok,
|
|
|
|
|
"ops_state": result.ops_state,
|
|
|
|
|
"reason": result.reason,
|
|
|
|
|
"detail": result.detail,
|
|
|
|
|
},
|
|
|
|
|
indent=2,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
if result.empty:
|
|
|
|
|
return 0
|
|
|
|
|
return 0 if result.ok else 1
|
|
|
|
|
|
Rename package, CLI, and deploy artifacts to rein-aharness (HARNESS-WP-0002-T02)
agent_harness -> rein_aharness (package + all imports), CLI command
agent-harness -> rein-aharness, Docker image tag, k8s namespace/labels/
names, Makefile targets, deploy script env var/paths. In-repo identity
strings (hub event source, metrics harness field, default assignee,
argparse prog name, commit author identity) updated to match.
Historical documents left untouched on purpose: docs/adr/ADR-001-agent-harness-architecture.md,
docs/architecture.md (dated v0.1 snapshot), workplans/HARNESS-WP-0001
(completed under the old name), and the SSH host alias
"forgejo-agent-harness" (external ~/.ssh/config entry, not owned here).
Verified: 47/47 tests pass, CLI runs correctly from a fresh venv,
`make image` builds and the resulting container runs correctly.
deploy/README.md gained an explicit rename cutover checklist for what
this session cannot safely do unattended -- moving the host-side
secrets dir and checkout on railiance01, and not deleting the old k8s
namespace until the new one is confirmed working. The actual live
cutover (running that checklist against the real Railiance deployment)
is not attempted here -- real production surgery on binky-control's
live automation, needs the operator present.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 14:22:18 +02:00
|
|
|
from rein_aharness.intake import IntakeError, IssueCoreClient, poll_next
|
2026-07-18 11:30:40 +02:00
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
client = IssueCoreClient()
|
|
|
|
|
result = poll_next(client, claim=not args.no_claim)
|
|
|
|
|
except IntakeError as exc:
|
|
|
|
|
print(f"intake error: {exc}", file=sys.stderr)
|
|
|
|
|
return 2
|
|
|
|
|
if result is None:
|
2026-08-03 20:04:25 +02:00
|
|
|
print(json.dumps({"source": "issue-core", "queue": "empty"}, indent=2))
|
2026-07-18 11:30:40 +02:00
|
|
|
return 0
|
|
|
|
|
issue, spec = result
|
|
|
|
|
print(
|
|
|
|
|
json.dumps(
|
|
|
|
|
{
|
2026-08-03 20:04:25 +02:00
|
|
|
"source": "issue-core",
|
2026-07-18 11:30:40 +02:00
|
|
|
"issue_id": issue.issue_id,
|
|
|
|
|
"state": issue.state,
|
|
|
|
|
"title": issue.title,
|
|
|
|
|
"agent": spec.agent,
|
|
|
|
|
"target_repo": str(spec.target_repo),
|
|
|
|
|
"completion_event_type": spec.completion_event_type,
|
|
|
|
|
"labels": spec.labels,
|
|
|
|
|
"claimed": not args.no_claim,
|
|
|
|
|
},
|
|
|
|
|
indent=2,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
2026-08-03 20:04:25 +02:00
|
|
|
def _cmd_claim_loop(args: argparse.Namespace) -> int:
|
|
|
|
|
import logging
|
|
|
|
|
|
|
|
|
|
from rein_aharness.claim_loop import run_claim_loop
|
|
|
|
|
|
|
|
|
|
logging.basicConfig(
|
|
|
|
|
level=logging.DEBUG if args.verbose else logging.INFO,
|
|
|
|
|
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
|
|
|
|
|
)
|
|
|
|
|
return run_claim_loop(
|
|
|
|
|
once=bool(args.once),
|
|
|
|
|
interval_seconds=args.interval,
|
|
|
|
|
report_to_hub=not args.no_hub,
|
|
|
|
|
commit=not args.no_commit,
|
|
|
|
|
dry_run=bool(args.dry_run),
|
|
|
|
|
max_iterations=args.max_iterations,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2026-07-18 11:30:40 +02:00
|
|
|
def _cmd_run(args: argparse.Namespace) -> int:
|
Rename package, CLI, and deploy artifacts to rein-aharness (HARNESS-WP-0002-T02)
agent_harness -> rein_aharness (package + all imports), CLI command
agent-harness -> rein-aharness, Docker image tag, k8s namespace/labels/
names, Makefile targets, deploy script env var/paths. In-repo identity
strings (hub event source, metrics harness field, default assignee,
argparse prog name, commit author identity) updated to match.
Historical documents left untouched on purpose: docs/adr/ADR-001-agent-harness-architecture.md,
docs/architecture.md (dated v0.1 snapshot), workplans/HARNESS-WP-0001
(completed under the old name), and the SSH host alias
"forgejo-agent-harness" (external ~/.ssh/config entry, not owned here).
Verified: 47/47 tests pass, CLI runs correctly from a fresh venv,
`make image` builds and the resulting container runs correctly.
deploy/README.md gained an explicit rename cutover checklist for what
this session cannot safely do unattended -- moving the host-side
secrets dir and checkout on railiance01, and not deleting the old k8s
namespace until the new one is confirmed working. The actual live
cutover (running that checklist against the real Railiance deployment)
is not attempted here -- real production surgery on binky-control's
live automation, needs the operator present.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 14:22:18 +02:00
|
|
|
from rein_aharness.intake import IntakeError, IssueCoreClient, poll_next
|
2026-07-18 11:30:40 +02:00
|
|
|
|
|
|
|
|
issue_id: str | None = None
|
|
|
|
|
client: IssueCoreClient | None = None
|
|
|
|
|
|
2026-08-03 20:04:25 +02:00
|
|
|
if getattr(args, "from_ops_run", False):
|
|
|
|
|
from rein_aharness.claim_loop import process_one
|
|
|
|
|
from rein_aharness.ops_run_client import OpsRunError
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
result = process_one(
|
|
|
|
|
report_to_hub=not args.no_hub,
|
|
|
|
|
commit=not getattr(args, "no_commit", False),
|
|
|
|
|
)
|
|
|
|
|
except OpsRunError as exc:
|
|
|
|
|
print(f"ops-run error: {exc}", file=sys.stderr)
|
|
|
|
|
return 2
|
|
|
|
|
print(
|
|
|
|
|
json.dumps(
|
|
|
|
|
{
|
|
|
|
|
"source": "ops-run",
|
|
|
|
|
"ok": bool(result.ok) if result.claimed else True,
|
|
|
|
|
"empty": result.empty,
|
|
|
|
|
"run_id": result.run_id,
|
|
|
|
|
"approach": result.approach,
|
|
|
|
|
"ops_state": result.ops_state,
|
|
|
|
|
"reason": result.reason,
|
|
|
|
|
"detail": result.detail,
|
|
|
|
|
},
|
|
|
|
|
indent=2,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
if result.empty:
|
|
|
|
|
return 0
|
|
|
|
|
return 0 if result.ok else 1
|
|
|
|
|
|
2026-07-18 11:30:40 +02:00
|
|
|
if args.from_issue_core:
|
|
|
|
|
try:
|
|
|
|
|
client = IssueCoreClient()
|
|
|
|
|
polled = poll_next(client, claim=True)
|
|
|
|
|
except IntakeError as exc:
|
|
|
|
|
print(f"intake error: {exc}", file=sys.stderr)
|
|
|
|
|
return 2
|
|
|
|
|
if polled is None:
|
2026-08-03 20:04:25 +02:00
|
|
|
print(json.dumps({"ok": True, "source": "issue-core", "queue": "empty"}, indent=2))
|
2026-07-18 11:30:40 +02:00
|
|
|
return 0
|
|
|
|
|
issue, spec = polled
|
|
|
|
|
issue_id = issue.issue_id
|
|
|
|
|
else:
|
|
|
|
|
if not args.task_file:
|
|
|
|
|
print(
|
2026-08-03 20:04:25 +02:00
|
|
|
"error: provide --task-file, --from-ops-run, or --from-issue-core",
|
2026-07-18 11:30:40 +02:00
|
|
|
file=sys.stderr,
|
|
|
|
|
)
|
|
|
|
|
return 2
|
|
|
|
|
try:
|
|
|
|
|
spec = TaskSpec.from_file(args.task_file)
|
|
|
|
|
except (TaskSpecError, OSError, json.JSONDecodeError) as exc:
|
|
|
|
|
print(f"invalid task spec: {exc}", file=sys.stderr)
|
|
|
|
|
return 2
|
|
|
|
|
|
2026-07-26 14:49:36 +02:00
|
|
|
def _print_event(event: dict) -> None:
|
|
|
|
|
# Tagged + single-line so a consumer reading stdout line-by-line
|
|
|
|
|
# (e.g. glas-harness's ReinAharness) can tell an event line apart
|
|
|
|
|
# from the pretty-printed final result block below.
|
|
|
|
|
print(json.dumps({"stream_event": event}), flush=True)
|
|
|
|
|
|
2026-07-18 11:30:40 +02:00
|
|
|
result = run_task(
|
|
|
|
|
spec,
|
|
|
|
|
report_to_hub=not args.no_hub,
|
|
|
|
|
write_metrics=not args.no_metrics,
|
2026-07-26 14:49:36 +02:00
|
|
|
emit_tool_events=args.stream_tool_events,
|
|
|
|
|
on_tool_event=_print_event if args.stream_tool_events else None,
|
2026-08-21 00:21:53 +02:00
|
|
|
model=args.model,
|
|
|
|
|
tool_profile_override=args.tool_profile,
|
|
|
|
|
budget_tokens_override=args.budget_tokens,
|
2026-07-18 11:30:40 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
closed = False
|
|
|
|
|
close_error = ""
|
|
|
|
|
if client is not None and issue_id:
|
|
|
|
|
try:
|
|
|
|
|
if result.ok:
|
|
|
|
|
client.close(issue_id)
|
|
|
|
|
closed = True
|
|
|
|
|
else:
|
|
|
|
|
client.reopen(issue_id)
|
|
|
|
|
except IntakeError as exc:
|
|
|
|
|
close_error = str(exc)
|
|
|
|
|
|
|
|
|
|
print(
|
|
|
|
|
json.dumps(
|
|
|
|
|
{
|
|
|
|
|
"ok": result.ok,
|
2026-08-03 20:04:25 +02:00
|
|
|
"source": "issue-core" if issue_id else "task-file",
|
2026-07-18 11:30:40 +02:00
|
|
|
"committed": result.committed,
|
|
|
|
|
"head_after": result.head_after,
|
|
|
|
|
"persona_source": result.persona_source,
|
|
|
|
|
"tool_profile": result.tool_profile,
|
|
|
|
|
"budget_tokens": result.budget_tokens,
|
|
|
|
|
"tokens_spent": result.tokens_spent,
|
|
|
|
|
"execution_time_s": round(result.execution_time_s, 3),
|
|
|
|
|
"reason": result.reason,
|
2026-08-21 00:21:53 +02:00
|
|
|
"model": result.model,
|
2026-07-18 11:30:40 +02:00
|
|
|
"issue_id": issue_id,
|
|
|
|
|
"issue_closed": closed,
|
|
|
|
|
"issue_close_error": close_error,
|
|
|
|
|
},
|
|
|
|
|
indent=2,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
return 0 if result.ok else 1
|
|
|
|
|
|
|
|
|
|
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
def main(argv: list[str] | None = None) -> int:
|
Rename package, CLI, and deploy artifacts to rein-aharness (HARNESS-WP-0002-T02)
agent_harness -> rein_aharness (package + all imports), CLI command
agent-harness -> rein-aharness, Docker image tag, k8s namespace/labels/
names, Makefile targets, deploy script env var/paths. In-repo identity
strings (hub event source, metrics harness field, default assignee,
argparse prog name, commit author identity) updated to match.
Historical documents left untouched on purpose: docs/adr/ADR-001-agent-harness-architecture.md,
docs/architecture.md (dated v0.1 snapshot), workplans/HARNESS-WP-0001
(completed under the old name), and the SSH host alias
"forgejo-agent-harness" (external ~/.ssh/config entry, not owned here).
Verified: 47/47 tests pass, CLI runs correctly from a fresh venv,
`make image` builds and the resulting container runs correctly.
deploy/README.md gained an explicit rename cutover checklist for what
this session cannot safely do unattended -- moving the host-side
secrets dir and checkout on railiance01, and not deleting the old k8s
namespace until the new one is confirmed working. The actual live
cutover (running that checklist against the real Railiance deployment)
is not attempted here -- real production surgery on binky-control's
live automation, needs the operator present.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 14:22:18 +02:00
|
|
|
parser = argparse.ArgumentParser(prog="rein-aharness")
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
sub = parser.add_subparsers(dest="command", required=True)
|
2026-07-17 23:49:03 +02:00
|
|
|
|
2026-07-18 11:30:40 +02:00
|
|
|
run = sub.add_parser(
|
|
|
|
|
"run",
|
2026-08-03 20:04:25 +02:00
|
|
|
help="Execute one task: ops_run (primary), issue-core (legacy), or task file",
|
2026-07-18 11:30:40 +02:00
|
|
|
)
|
|
|
|
|
run_src = run.add_mutually_exclusive_group(required=True)
|
|
|
|
|
run_src.add_argument("--task-file", help="Local JSON task-spec (dev path)")
|
2026-08-03 20:04:25 +02:00
|
|
|
run_src.add_argument(
|
|
|
|
|
"--from-ops-run",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Claim one activity-core ops_run, select approach, execute, complete/fail",
|
|
|
|
|
)
|
2026-07-18 11:30:40 +02:00
|
|
|
run_src.add_argument(
|
|
|
|
|
"--from-issue-core",
|
|
|
|
|
action="store_true",
|
2026-08-03 20:04:25 +02:00
|
|
|
help="Legacy: poll issue-core for one open harness-labeled task, claim, run, close",
|
2026-07-18 11:30:40 +02:00
|
|
|
)
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
run.add_argument("--no-hub", action="store_true", help="Skip hub reporting")
|
2026-08-03 20:04:25 +02:00
|
|
|
run.add_argument(
|
|
|
|
|
"--no-commit",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="With --from-ops-run: approaches that support it skip git commit",
|
|
|
|
|
)
|
2026-07-17 23:49:03 +02:00
|
|
|
run.add_argument(
|
|
|
|
|
"--no-metrics",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Skip writing .kaizen/metrics in the target repo",
|
|
|
|
|
)
|
2026-07-26 14:49:36 +02:00
|
|
|
run.add_argument(
|
|
|
|
|
"--stream-tool-events",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help=(
|
|
|
|
|
"Run claude with --output-format stream-json --include-hook-events "
|
|
|
|
|
"and print each tool_use/tool_result/hook event as its own JSON "
|
|
|
|
|
"line while running (real-time audit, not external tool dispatch "
|
|
|
|
|
"-- HARNESS-WP-0002-T03)"
|
|
|
|
|
),
|
|
|
|
|
)
|
2026-08-21 00:21:53 +02:00
|
|
|
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",
|
|
|
|
|
)
|
2026-07-17 23:49:03 +02:00
|
|
|
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
scan = sub.add_parser(
|
|
|
|
|
"mail-scan", help="Deterministic company-mailbox scan (no LLM session)"
|
|
|
|
|
)
|
|
|
|
|
scan.add_argument("--target-repo", required=True)
|
|
|
|
|
scan.add_argument("--config", default="integrations/mailbox-binky-company.yml")
|
|
|
|
|
scan.add_argument("--out", default="mailmeta/reports")
|
|
|
|
|
scan.add_argument("--no-hub", action="store_true", help="Skip hub reporting")
|
2026-07-17 23:49:03 +02:00
|
|
|
|
2026-07-22 00:05:23 +02:00
|
|
|
triage = sub.add_parser(
|
|
|
|
|
"mail-triage",
|
|
|
|
|
help="Triage newest mail CSV via llm-connect (JSON + deterministic apply; no Claude)",
|
|
|
|
|
)
|
|
|
|
|
triage.add_argument("--target-repo", required=True)
|
|
|
|
|
triage.add_argument("--reports-dir", default="mailmeta/reports")
|
|
|
|
|
triage.add_argument("--mail-log", default="mailmeta/mail-log.md")
|
|
|
|
|
triage.add_argument(
|
|
|
|
|
"--max-rows",
|
|
|
|
|
type=int,
|
|
|
|
|
default=None,
|
|
|
|
|
help="Max CSV rows to send to the model (default env MAIL_TRIAGE_MAX_ROWS or 40)",
|
|
|
|
|
)
|
|
|
|
|
triage.add_argument("--no-hub", action="store_true", help="Skip hub reporting")
|
|
|
|
|
triage.add_argument(
|
|
|
|
|
"--no-commit",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Apply log updates but do not git commit",
|
|
|
|
|
)
|
|
|
|
|
|
2026-07-22 00:18:52 +02:00
|
|
|
brief = sub.add_parser(
|
|
|
|
|
"brief-daily",
|
|
|
|
|
help="Write daily brief via llm-connect (JSON + markdown apply; no Claude)",
|
|
|
|
|
)
|
|
|
|
|
brief.add_argument("--target-repo", required=True)
|
|
|
|
|
brief.add_argument(
|
|
|
|
|
"--date",
|
|
|
|
|
default=None,
|
|
|
|
|
help="Brief date YYYY-MM-DD (default: today Europe/Berlin)",
|
|
|
|
|
)
|
|
|
|
|
brief.add_argument(
|
|
|
|
|
"--force",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Overwrite if today's brief already exists",
|
|
|
|
|
)
|
|
|
|
|
brief.add_argument("--no-hub", action="store_true", help="Skip hub reporting")
|
|
|
|
|
brief.add_argument(
|
|
|
|
|
"--no-commit",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Write brief file but do not git commit",
|
|
|
|
|
)
|
|
|
|
|
|
2026-08-08 21:26:29 +02:00
|
|
|
weekly = sub.add_parser(
|
|
|
|
|
"brief-weekly",
|
|
|
|
|
help="Write weekly founder-review prep via llm-connect (no coding agent)",
|
|
|
|
|
)
|
|
|
|
|
weekly.add_argument("--target-repo", required=True)
|
|
|
|
|
weekly.add_argument(
|
|
|
|
|
"--date",
|
|
|
|
|
default=None,
|
|
|
|
|
help="Review date YYYY-MM-DD (default: today Europe/Berlin)",
|
|
|
|
|
)
|
|
|
|
|
weekly.add_argument(
|
|
|
|
|
"--force",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Overwrite if today's weekly review already exists",
|
|
|
|
|
)
|
|
|
|
|
weekly.add_argument("--no-hub", action="store_true", help="Skip hub reporting")
|
|
|
|
|
weekly.add_argument(
|
|
|
|
|
"--no-commit",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Write review file but do not git commit",
|
|
|
|
|
)
|
|
|
|
|
|
2026-08-03 17:53:06 +02:00
|
|
|
fi_brief = sub.add_parser(
|
|
|
|
|
"fi-research-brief",
|
|
|
|
|
help=(
|
|
|
|
|
"Freedom Intelligence research brief via llm-connect "
|
|
|
|
|
"(activity-core consumer; posts fi_daily_brief)"
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
fi_brief.add_argument(
|
|
|
|
|
"--target-repo",
|
|
|
|
|
required=True,
|
|
|
|
|
help="freedom-intelligence checkout path",
|
|
|
|
|
)
|
|
|
|
|
fi_brief.add_argument(
|
|
|
|
|
"--date",
|
|
|
|
|
default=None,
|
|
|
|
|
help="Brief date YYYY-MM-DD (default: today Europe/Berlin)",
|
|
|
|
|
)
|
|
|
|
|
fi_brief.add_argument(
|
|
|
|
|
"--force",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Overwrite if today's brief already exists",
|
|
|
|
|
)
|
|
|
|
|
fi_brief.add_argument("--no-hub", action="store_true", help="Skip hub reporting")
|
|
|
|
|
fi_brief.add_argument(
|
|
|
|
|
"--no-commit",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Write brief file but do not git commit",
|
|
|
|
|
)
|
|
|
|
|
|
2026-07-17 23:49:03 +02:00
|
|
|
validate = sub.add_parser(
|
|
|
|
|
"validate",
|
|
|
|
|
help="Validate instance manifest (.kaizen/schedule.yml + harness fields)",
|
|
|
|
|
)
|
|
|
|
|
validate.add_argument(
|
|
|
|
|
"--target",
|
|
|
|
|
default=".",
|
|
|
|
|
help="Consuming repo root (default: cwd)",
|
|
|
|
|
)
|
|
|
|
|
validate.add_argument(
|
|
|
|
|
"--strict",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Require lane, tool_profile, and harness pin on every enabled agent",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
sub.add_parser("profiles", help="List named tool profiles")
|
|
|
|
|
|
2026-07-18 10:48:44 +02:00
|
|
|
smoke = sub.add_parser(
|
|
|
|
|
"smoke",
|
|
|
|
|
help="Deterministic Railiance smoke: commit SMOKE.md, optional push, hub event",
|
|
|
|
|
)
|
|
|
|
|
smoke.add_argument(
|
|
|
|
|
"--target-repo",
|
|
|
|
|
help="Existing git checkout (default: clone executor-sandbox under --work-dir)",
|
|
|
|
|
)
|
|
|
|
|
smoke.add_argument(
|
|
|
|
|
"--work-dir",
|
|
|
|
|
default="~/work/executor-sandbox",
|
|
|
|
|
help="Clone destination when --target-repo is omitted",
|
|
|
|
|
)
|
|
|
|
|
smoke.add_argument(
|
|
|
|
|
"--remote",
|
|
|
|
|
default="ssh://git@forgejo-agent-harness/coulomb/executor-sandbox.git",
|
|
|
|
|
help="Git remote for sandbox clone",
|
|
|
|
|
)
|
|
|
|
|
smoke.add_argument("--no-hub", action="store_true", help="Skip hub reporting")
|
|
|
|
|
smoke.add_argument("--no-push", action="store_true", help="Skip git push after commit")
|
|
|
|
|
|
2026-07-18 11:30:40 +02:00
|
|
|
poll = sub.add_parser(
|
|
|
|
|
"poll",
|
2026-08-03 20:04:25 +02:00
|
|
|
help="Peek/claim next task (default source=ops-run; issue-core is legacy)",
|
|
|
|
|
)
|
|
|
|
|
poll.add_argument(
|
|
|
|
|
"--source",
|
|
|
|
|
choices=["ops-run", "issue-core"],
|
|
|
|
|
default="ops-run",
|
|
|
|
|
help="ops-run = activity-core claim queue (primary); issue-core = legacy tickets",
|
2026-07-18 11:30:40 +02:00
|
|
|
)
|
|
|
|
|
poll.add_argument(
|
|
|
|
|
"--no-claim",
|
|
|
|
|
action="store_true",
|
2026-08-03 20:04:25 +02:00
|
|
|
help="List/map only; do not claim",
|
2026-07-18 11:30:40 +02:00
|
|
|
)
|
2026-08-03 20:04:25 +02:00
|
|
|
poll.add_argument(
|
|
|
|
|
"--dry-run",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="With ops-run: claim then fail+reopen without executing",
|
|
|
|
|
)
|
|
|
|
|
poll.add_argument("--no-hub", action="store_true", help="Skip hub on execute")
|
|
|
|
|
|
|
|
|
|
claim_loop = sub.add_parser(
|
|
|
|
|
"claim-loop",
|
|
|
|
|
help="Continuously claim ops_runs, select approach, execute, complete/fail",
|
|
|
|
|
)
|
|
|
|
|
claim_loop.add_argument(
|
|
|
|
|
"--once",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Process at most one claim cycle then exit",
|
|
|
|
|
)
|
|
|
|
|
claim_loop.add_argument(
|
|
|
|
|
"--interval",
|
|
|
|
|
type=float,
|
|
|
|
|
default=None,
|
|
|
|
|
help="Seconds between empty-queue polls (default env AGENT_HARNESS_CLAIM_INTERVAL or 30)",
|
|
|
|
|
)
|
|
|
|
|
claim_loop.add_argument(
|
|
|
|
|
"--max-iterations",
|
|
|
|
|
type=int,
|
|
|
|
|
default=None,
|
|
|
|
|
help="Stop after N cycles (tests / bounded runs)",
|
|
|
|
|
)
|
|
|
|
|
claim_loop.add_argument("--dry-run", action="store_true")
|
|
|
|
|
claim_loop.add_argument("--no-hub", action="store_true")
|
|
|
|
|
claim_loop.add_argument("--no-commit", action="store_true")
|
|
|
|
|
claim_loop.add_argument("-v", "--verbose", action="store_true")
|
2026-07-18 11:30:40 +02:00
|
|
|
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
args = parser.parse_args(argv)
|
|
|
|
|
|
2026-07-17 23:49:03 +02:00
|
|
|
if args.command == "validate":
|
|
|
|
|
return _cmd_validate(args)
|
|
|
|
|
|
|
|
|
|
if args.command == "profiles":
|
|
|
|
|
return _cmd_profiles(args)
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
|
2026-07-18 11:30:40 +02:00
|
|
|
if args.command == "poll":
|
|
|
|
|
return _cmd_poll(args)
|
|
|
|
|
|
2026-08-03 20:04:25 +02:00
|
|
|
if args.command == "claim-loop":
|
|
|
|
|
return _cmd_claim_loop(args)
|
|
|
|
|
|
2026-07-18 11:30:40 +02:00
|
|
|
if args.command == "run":
|
|
|
|
|
return _cmd_run(args)
|
|
|
|
|
|
2026-07-18 10:48:44 +02:00
|
|
|
if args.command == "smoke":
|
Rename package, CLI, and deploy artifacts to rein-aharness (HARNESS-WP-0002-T02)
agent_harness -> rein_aharness (package + all imports), CLI command
agent-harness -> rein-aharness, Docker image tag, k8s namespace/labels/
names, Makefile targets, deploy script env var/paths. In-repo identity
strings (hub event source, metrics harness field, default assignee,
argparse prog name, commit author identity) updated to match.
Historical documents left untouched on purpose: docs/adr/ADR-001-agent-harness-architecture.md,
docs/architecture.md (dated v0.1 snapshot), workplans/HARNESS-WP-0001
(completed under the old name), and the SSH host alias
"forgejo-agent-harness" (external ~/.ssh/config entry, not owned here).
Verified: 47/47 tests pass, CLI runs correctly from a fresh venv,
`make image` builds and the resulting container runs correctly.
deploy/README.md gained an explicit rename cutover checklist for what
this session cannot safely do unattended -- moving the host-side
secrets dir and checkout on railiance01, and not deleting the old k8s
namespace until the new one is confirmed working. The actual live
cutover (running that checklist against the real Railiance deployment)
is not attempted here -- real production surgery on binky-control's
live automation, needs the operator present.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 14:22:18 +02:00
|
|
|
from rein_aharness.smoke import ensure_sandbox_clone, run_smoke
|
2026-07-18 10:48:44 +02:00
|
|
|
|
|
|
|
|
if args.target_repo:
|
|
|
|
|
repo = Path(args.target_repo).expanduser().resolve()
|
|
|
|
|
else:
|
|
|
|
|
try:
|
|
|
|
|
repo = ensure_sandbox_clone(
|
|
|
|
|
Path(args.work_dir).expanduser(),
|
|
|
|
|
remote=args.remote,
|
|
|
|
|
)
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
print(f"smoke clone failed: {exc}", file=sys.stderr)
|
|
|
|
|
return 2
|
|
|
|
|
try:
|
|
|
|
|
smoke_result = run_smoke(
|
|
|
|
|
repo,
|
|
|
|
|
report_to_hub=not args.no_hub,
|
|
|
|
|
push=not args.no_push,
|
|
|
|
|
)
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
print(f"smoke failed: {exc}", file=sys.stderr)
|
|
|
|
|
return 1
|
|
|
|
|
print(
|
|
|
|
|
json.dumps(
|
|
|
|
|
{
|
|
|
|
|
"ok": smoke_result.run.ok and (
|
|
|
|
|
smoke_result.pushed or args.no_push
|
|
|
|
|
),
|
|
|
|
|
"committed": smoke_result.run.committed,
|
|
|
|
|
"pushed": smoke_result.pushed,
|
|
|
|
|
"head_after": smoke_result.run.head_after,
|
|
|
|
|
"tool_profile": smoke_result.run.tool_profile,
|
|
|
|
|
"reason": smoke_result.run.reason,
|
|
|
|
|
"push_reason": smoke_result.push_reason,
|
|
|
|
|
"target_repo": str(repo),
|
|
|
|
|
},
|
|
|
|
|
indent=2,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
ok = smoke_result.run.ok and (smoke_result.pushed or args.no_push)
|
|
|
|
|
return 0 if ok else 1
|
|
|
|
|
|
2026-07-22 00:05:23 +02:00
|
|
|
if args.command == "mail-triage":
|
Rename package, CLI, and deploy artifacts to rein-aharness (HARNESS-WP-0002-T02)
agent_harness -> rein_aharness (package + all imports), CLI command
agent-harness -> rein-aharness, Docker image tag, k8s namespace/labels/
names, Makefile targets, deploy script env var/paths. In-repo identity
strings (hub event source, metrics harness field, default assignee,
argparse prog name, commit author identity) updated to match.
Historical documents left untouched on purpose: docs/adr/ADR-001-agent-harness-architecture.md,
docs/architecture.md (dated v0.1 snapshot), workplans/HARNESS-WP-0001
(completed under the old name), and the SSH host alias
"forgejo-agent-harness" (external ~/.ssh/config entry, not owned here).
Verified: 47/47 tests pass, CLI runs correctly from a fresh venv,
`make image` builds and the resulting container runs correctly.
deploy/README.md gained an explicit rename cutover checklist for what
this session cannot safely do unattended -- moving the host-side
secrets dir and checkout on railiance01, and not deleting the old k8s
namespace until the new one is confirmed working. The actual live
cutover (running that checklist against the real Railiance deployment)
is not attempted here -- real production surgery on binky-control's
live automation, needs the operator present.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 14:22:18 +02:00
|
|
|
from rein_aharness.mail_triage import run_mail_triage
|
2026-07-22 00:05:23 +02:00
|
|
|
|
|
|
|
|
triage_result = run_mail_triage(
|
|
|
|
|
target_repo=Path(args.target_repo).expanduser(),
|
|
|
|
|
reports_dir=args.reports_dir,
|
|
|
|
|
mail_log_rel=args.mail_log,
|
|
|
|
|
max_rows=args.max_rows,
|
|
|
|
|
report_to_hub=not args.no_hub,
|
|
|
|
|
commit=not args.no_commit,
|
|
|
|
|
)
|
|
|
|
|
print(
|
|
|
|
|
json.dumps(
|
|
|
|
|
{
|
|
|
|
|
"ok": triage_result.ok,
|
|
|
|
|
"report": triage_result.report,
|
|
|
|
|
"entries_applied": triage_result.entries_applied,
|
|
|
|
|
"committed": triage_result.committed,
|
|
|
|
|
"head_after": triage_result.head_after,
|
|
|
|
|
"reason": triage_result.reason,
|
|
|
|
|
"model_meta": triage_result.model_meta,
|
|
|
|
|
},
|
|
|
|
|
indent=2,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
return 0 if triage_result.ok else 1
|
|
|
|
|
|
2026-07-22 00:18:52 +02:00
|
|
|
if args.command == "brief-daily":
|
|
|
|
|
from datetime import date as date_cls
|
|
|
|
|
|
Rename package, CLI, and deploy artifacts to rein-aharness (HARNESS-WP-0002-T02)
agent_harness -> rein_aharness (package + all imports), CLI command
agent-harness -> rein-aharness, Docker image tag, k8s namespace/labels/
names, Makefile targets, deploy script env var/paths. In-repo identity
strings (hub event source, metrics harness field, default assignee,
argparse prog name, commit author identity) updated to match.
Historical documents left untouched on purpose: docs/adr/ADR-001-agent-harness-architecture.md,
docs/architecture.md (dated v0.1 snapshot), workplans/HARNESS-WP-0001
(completed under the old name), and the SSH host alias
"forgejo-agent-harness" (external ~/.ssh/config entry, not owned here).
Verified: 47/47 tests pass, CLI runs correctly from a fresh venv,
`make image` builds and the resulting container runs correctly.
deploy/README.md gained an explicit rename cutover checklist for what
this session cannot safely do unattended -- moving the host-side
secrets dir and checkout on railiance01, and not deleting the old k8s
namespace until the new one is confirmed working. The actual live
cutover (running that checklist against the real Railiance deployment)
is not attempted here -- real production surgery on binky-control's
live automation, needs the operator present.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 14:22:18 +02:00
|
|
|
from rein_aharness.brief_daily import run_brief_daily
|
2026-07-22 00:18:52 +02:00
|
|
|
|
|
|
|
|
day = None
|
|
|
|
|
if args.date:
|
|
|
|
|
day = date_cls.fromisoformat(args.date)
|
|
|
|
|
brief_result = run_brief_daily(
|
|
|
|
|
target_repo=Path(args.target_repo).expanduser(),
|
|
|
|
|
day=day,
|
|
|
|
|
force=bool(args.force),
|
|
|
|
|
report_to_hub=not args.no_hub,
|
|
|
|
|
commit=not args.no_commit,
|
|
|
|
|
)
|
|
|
|
|
print(
|
|
|
|
|
json.dumps(
|
|
|
|
|
{
|
|
|
|
|
"ok": brief_result.ok,
|
|
|
|
|
"date": brief_result.date,
|
|
|
|
|
"path": brief_result.path,
|
|
|
|
|
"wrote": brief_result.wrote,
|
|
|
|
|
"committed": brief_result.committed,
|
|
|
|
|
"skipped_existing": brief_result.skipped_existing,
|
|
|
|
|
"head_after": brief_result.head_after,
|
|
|
|
|
"reason": brief_result.reason,
|
|
|
|
|
"model_meta": brief_result.model_meta,
|
|
|
|
|
},
|
|
|
|
|
indent=2,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
return 0 if brief_result.ok else 1
|
|
|
|
|
|
2026-08-08 21:26:29 +02:00
|
|
|
if args.command == "brief-weekly":
|
|
|
|
|
from datetime import date as date_cls
|
|
|
|
|
|
|
|
|
|
from rein_aharness.brief_weekly import run_brief_weekly
|
|
|
|
|
|
|
|
|
|
day = date_cls.fromisoformat(args.date) if args.date else None
|
|
|
|
|
result = run_brief_weekly(
|
|
|
|
|
target_repo=Path(args.target_repo).expanduser(),
|
|
|
|
|
day=day,
|
|
|
|
|
force=bool(args.force),
|
|
|
|
|
report_to_hub=not args.no_hub,
|
|
|
|
|
commit=not args.no_commit,
|
|
|
|
|
)
|
|
|
|
|
print(
|
|
|
|
|
json.dumps(
|
|
|
|
|
{
|
|
|
|
|
"ok": result.ok,
|
|
|
|
|
"date": result.date,
|
|
|
|
|
"path": result.path,
|
|
|
|
|
"wrote": result.wrote,
|
|
|
|
|
"committed": result.committed,
|
|
|
|
|
"skipped_existing": result.skipped_existing,
|
|
|
|
|
"milestone_moved": result.milestone_moved,
|
|
|
|
|
"risk005_state": result.risk005_state,
|
|
|
|
|
"head_after": result.head_after,
|
|
|
|
|
"reason": result.reason,
|
|
|
|
|
"model_meta": result.model_meta,
|
|
|
|
|
},
|
|
|
|
|
indent=2,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
return 0 if result.ok else 1
|
|
|
|
|
|
2026-08-03 17:53:06 +02:00
|
|
|
if args.command == "fi-research-brief":
|
|
|
|
|
from datetime import date as date_cls
|
|
|
|
|
|
|
|
|
|
from rein_aharness.fi_research_brief import run_fi_research_brief
|
|
|
|
|
|
|
|
|
|
day = None
|
|
|
|
|
if args.date:
|
|
|
|
|
day = date_cls.fromisoformat(args.date)
|
|
|
|
|
fi_result = run_fi_research_brief(
|
|
|
|
|
target_repo=Path(args.target_repo).expanduser(),
|
|
|
|
|
day=day,
|
|
|
|
|
force=bool(args.force),
|
|
|
|
|
report_to_hub=not args.no_hub,
|
|
|
|
|
commit=not args.no_commit,
|
|
|
|
|
)
|
|
|
|
|
print(
|
|
|
|
|
json.dumps(
|
|
|
|
|
{
|
|
|
|
|
"ok": fi_result.ok,
|
|
|
|
|
"date": fi_result.date,
|
|
|
|
|
"path": fi_result.path,
|
|
|
|
|
"wrote": fi_result.wrote,
|
|
|
|
|
"committed": fi_result.committed,
|
|
|
|
|
"skipped_existing": fi_result.skipped_existing,
|
|
|
|
|
"collection_candidates": fi_result.collection_candidates,
|
|
|
|
|
"head_after": fi_result.head_after,
|
|
|
|
|
"reason": fi_result.reason,
|
|
|
|
|
"model_meta": fi_result.model_meta,
|
|
|
|
|
},
|
|
|
|
|
indent=2,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
return 0 if fi_result.ok else 1
|
|
|
|
|
|
2026-07-17 23:49:03 +02:00
|
|
|
if args.command == "mail-scan":
|
Rename package, CLI, and deploy artifacts to rein-aharness (HARNESS-WP-0002-T02)
agent_harness -> rein_aharness (package + all imports), CLI command
agent-harness -> rein-aharness, Docker image tag, k8s namespace/labels/
names, Makefile targets, deploy script env var/paths. In-repo identity
strings (hub event source, metrics harness field, default assignee,
argparse prog name, commit author identity) updated to match.
Historical documents left untouched on purpose: docs/adr/ADR-001-agent-harness-architecture.md,
docs/architecture.md (dated v0.1 snapshot), workplans/HARNESS-WP-0001
(completed under the old name), and the SSH host alias
"forgejo-agent-harness" (external ~/.ssh/config entry, not owned here).
Verified: 47/47 tests pass, CLI runs correctly from a fresh venv,
`make image` builds and the resulting container runs correctly.
deploy/README.md gained an explicit rename cutover checklist for what
this session cannot safely do unattended -- moving the host-side
secrets dir and checkout on railiance01, and not deleting the old k8s
namespace until the new one is confirmed working. The actual live
cutover (running that checklist against the real Railiance deployment)
is not attempted here -- real production surgery on binky-control's
live automation, needs the operator present.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 14:22:18 +02:00
|
|
|
from rein_aharness.mailscan import run_mail_scan
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
|
|
|
|
|
result = run_mail_scan(
|
|
|
|
|
target_repo=Path(args.target_repo).expanduser(),
|
|
|
|
|
config=args.config,
|
|
|
|
|
out_dir=args.out,
|
|
|
|
|
report_to_hub=not args.no_hub,
|
|
|
|
|
)
|
|
|
|
|
print(
|
|
|
|
|
json.dumps(
|
|
|
|
|
{
|
|
|
|
|
"ok": result.ok,
|
|
|
|
|
"report": result.report_path,
|
|
|
|
|
"new_messages": result.new_messages,
|
|
|
|
|
"auth_lane": result.auth_lane,
|
|
|
|
|
"reason": result.reason,
|
|
|
|
|
},
|
|
|
|
|
indent=2,
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
return 0 if result.ok else 1
|
|
|
|
|
|
2026-07-18 11:30:40 +02:00
|
|
|
print(f"unknown command: {args.command}", file=sys.stderr)
|
|
|
|
|
return 2
|
Harness foundation: INTENT, ADR-001, architecture, prototype adoption
- INTENT.md: three-layer model (blueprint/instance/harness), single
shared runtime, never-become boundaries
- ADR-001 (accepted): DEC-2026-002 resolution — one harness repo for
all projects; instances are declarative state in consuming repos
- docs/architecture.md: components, contracts (manifest, tool
profiles, completion events, credential lanes), deployment shape
- agent_harness/: executor-worker prototype adopted and renamed
(6/6 tests green); HARNESS-WP-0001 initial workplan (7 tasks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 23:35:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
raise SystemExit(main())
|