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:
|
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:
|
|
|
|
|
print(json.dumps({"queue": "empty"}, indent=2))
|
|
|
|
|
return 0
|
|
|
|
|
issue, spec = result
|
|
|
|
|
print(
|
|
|
|
|
json.dumps(
|
|
|
|
|
{
|
|
|
|
|
"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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
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:
|
|
|
|
|
print(json.dumps({"ok": True, "queue": "empty"}, indent=2))
|
|
|
|
|
return 0
|
|
|
|
|
issue, spec = polled
|
|
|
|
|
issue_id = issue.issue_id
|
|
|
|
|
else:
|
|
|
|
|
if not args.task_file:
|
|
|
|
|
print(
|
|
|
|
|
"error: provide --task-file or --from-issue-core",
|
|
|
|
|
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-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,
|
|
|
|
|
"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,
|
|
|
|
|
"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",
|
|
|
|
|
help="Execute one task from a JSON file or next issue-core emission",
|
|
|
|
|
)
|
|
|
|
|
run_src = run.add_mutually_exclusive_group(required=True)
|
|
|
|
|
run_src.add_argument("--task-file", help="Local JSON task-spec (dev path)")
|
|
|
|
|
run_src.add_argument(
|
|
|
|
|
"--from-issue-core",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="Poll issue-core for one open harness-labeled task, claim, run, close",
|
|
|
|
|
)
|
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-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-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-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",
|
|
|
|
|
help="Peek/claim next open issue-core task labeled for the harness (no execute)",
|
|
|
|
|
)
|
|
|
|
|
poll.add_argument(
|
|
|
|
|
"--no-claim",
|
|
|
|
|
action="store_true",
|
|
|
|
|
help="List/map only; do not set in_progress",
|
|
|
|
|
)
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
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-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())
|