feat(runtime): consume governed Activity Core closes
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a06ba0-10aa-7ea0-b20a-4f3fac39efe9
This commit is contained in:
parent
0e6d795aa4
commit
d00ffcb402
22 changed files with 1218 additions and 148 deletions
|
|
@ -34,11 +34,12 @@
|
|||
|---|---|---|---|
|
||||
| Instance manifest | `manifest.py` | extends `.kaizen/schedule.yml`; `validate` CLI | unchanged contract; tenant onboarding |
|
||||
| Tool profiles | `profiles.py` | `green-commit-only`, `blue-mail-triage` registry | additional named profiles as needed |
|
||||
| Task intake | `intake.py` + `taskspec.py` | issue-core GET/PATCH poll+claim; JSON task-file for local dev | NATS when activity-core migrates |
|
||||
| Task intake | `ops_run_client.py` + `taskspec.py` | Activity Core claim/lease/close; JSON task-file for local dev; issue-core compatibility | event-driven wakeup if needed |
|
||||
| Persona | `persona.py` | `kaizen-agentic schedule prepare` (ADR-005) | unchanged, plus phase-memory profile hook |
|
||||
| Session | `adapter.py` | `AgenticClaudeCodeAdapter` (cwd-pinned, profile allow-list) | + hosted adapters |
|
||||
| Orchestration | `runner.py` | profile/budget → transaction → session → grant acceptance → metrics → hub | activity-core intake |
|
||||
| Orchestration | `runner.py` + `claim_loop.py` | profile → transaction → session → grant acceptance → metrics → durable close | readiness and recovery drills |
|
||||
| Metrics | `metrics.py` | compatibility `.kaizen/metrics`; durable external ledger for granted runs | kaizen-owned projection |
|
||||
| Close evidence | `close_outbox.py` | enqueue-before-close; exact replay; conflict quarantine | operational retention policy |
|
||||
| Mail lane | `mailscan.py` | deterministic credentialed pre-step outside the session | pattern generalizes to other credentialed pre-steps |
|
||||
| Hub reporting | `hub.py` | REST progress event + task close + token event | unchanged |
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Close-evidence outbox
|
||||
|
||||
Status: **durable core implemented, not connected to the live claim loop**.
|
||||
Status: **active for profiled Activity Core terminal closes**.
|
||||
|
||||
The outbox preserves one bounded Activity Core completion or failure intent
|
||||
after repository work. Replaying an outbox entry calls only the queue close
|
||||
|
|
@ -21,9 +21,10 @@ outside target checkouts. Outbox directories are mode `0700`; lock and JSON
|
|||
files are mode `0600`.
|
||||
|
||||
An entry is keyed by the digest of the bounded Activity Core `run_id` and
|
||||
repository `transaction_id`. Re-enqueuing the identical intent returns its
|
||||
existing pending or delivered state. Reusing that identity for a different
|
||||
action, result, error, or reopen decision is a conflict and is refused.
|
||||
repository `transaction_id` and retains the original worker identity.
|
||||
Re-enqueuing the identical intent returns its existing pending or delivered
|
||||
state. Reusing that identity for a different worker, action, result, error, or
|
||||
reopen decision is a conflict and is refused.
|
||||
|
||||
The v1 close intent contains:
|
||||
|
||||
|
|
@ -41,7 +42,8 @@ Enqueue and retry-state updates use a same-directory temporary file, file
|
|||
`fsync`, atomic replace, and directory `fsync` under a process-safe `flock`.
|
||||
The retry attempt is durable before the delivery callback begins.
|
||||
|
||||
Normal callback return marks the entry delivered and atomically moves it from
|
||||
Normal callback return, including Activity Core `close_disposition=applied` or
|
||||
`reconciled`, marks the entry delivered and atomically moves it from
|
||||
`pending/` to `delivered/`. An ordinary exception retains it in `pending/` with
|
||||
only the exception class and a generic failure marker; exception text is not
|
||||
persisted. Process interrupts propagate; the already-recorded attempt remains
|
||||
|
|
@ -49,21 +51,29 @@ pending. Invalid, oversized, or directory/state-mismatched records are moved
|
|||
intact to `quarantine/` with a bounded reason sidecar and are never delivered
|
||||
automatically.
|
||||
|
||||
A network timeout may occur after Activity Core accepted a close. Retrying the
|
||||
same close intent can therefore repeat the queue mutation request, but cannot
|
||||
repeat repository workload. Activity Core remains authoritative for terminal
|
||||
row state and must provide idempotent or reconcilable close semantics.
|
||||
Activity Core refusal codes `not_found`, `wrong_owner`, `expired_lease`,
|
||||
`state_conflict`, `evidence_conflict`, and `terminal_conflict` are conclusive,
|
||||
not transient. Such entries move to quarantine rather than retrying forever.
|
||||
An unclassified HTTP failure or transport outage remains pending.
|
||||
|
||||
## Activation gates
|
||||
A network timeout may occur after Activity Core accepted a close. The worker
|
||||
replays pending close-only work before it claims another row. Retrying the same
|
||||
intent can repeat the queue request, but cannot repeat repository workload;
|
||||
Activity Core reconciles the exact normalized terminal repeat.
|
||||
|
||||
The live claim loop still returns an in-memory failure when close delivery
|
||||
fails. Connecting it to this outbox requires:
|
||||
## Operator controls
|
||||
|
||||
1. the lease-bound repository transaction and accepted-result envelope;
|
||||
2. enqueue-before-close using the same run and transaction identities;
|
||||
3. Activity Core review of repeat close behavior for already-terminal rows;
|
||||
4. startup/periodic replay that never calls workload code; and
|
||||
5. operator status, quarantine inspection, and replay controls.
|
||||
```bash
|
||||
rein-aharness close-outbox status
|
||||
rein-aharness close-outbox replay
|
||||
rein-aharness close-outbox replay --limit 10
|
||||
```
|
||||
|
||||
Until those gates are implemented and reviewed, no production close behavior
|
||||
changes.
|
||||
`status` and `replay` return non-zero while pending or quarantined material
|
||||
exists, making them suitable for readiness/recovery checks. Quarantine content
|
||||
and its bounded reason sidecar remain under the private state path for explicit
|
||||
operator inspection; it is never silently deleted or treated as delivered.
|
||||
|
||||
Profile-absent compatibility closes are not yet outboxed. Granted rows without
|
||||
an authoritative `harness_profile_ref` are refused before execution so they
|
||||
cannot cross that weaker path.
|
||||
|
|
|
|||
|
|
@ -42,10 +42,10 @@ must never fall back to either.
|
|||
|
||||
An unmatched route fails terminally. Most matched executor failures set
|
||||
`reopen=true`; an unexpected exception also reopens. Activity Core applies its
|
||||
attempt limit. The harness now records a repository transaction identity, but
|
||||
Activity Core does not yet carry an accepted repository grant or reconcile a
|
||||
response-lost terminal close, so a retry after ambiguous completion remains a
|
||||
T03 gate.
|
||||
attempt limit. Grant-bearing work now requires an authoritative profile and
|
||||
therefore cannot enter this registry. Profiled terminal closes use durable
|
||||
response-loss reconciliation; legacy close delivery remains a T04 migration
|
||||
constraint rather than a grant-bearing path.
|
||||
|
||||
## Scheduled definitions
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ Does **not** require issue-core or Forgejo for FI / Binky-style ops.
|
|||
|
||||
```text
|
||||
activity-core emit_tasks
|
||||
→ INSERT ops_run (open, optional harness_profile_ref) + activity_task_spawn
|
||||
→ INSERT ops_run (open, optional profile + repository_grant) + task_spawn
|
||||
│
|
||||
▼
|
||||
rein-aharness claim-loop
|
||||
|
|
@ -17,15 +17,18 @@ rein-aharness claim-loop
|
|||
harness_profile_ref present? ─ yes → Glas ExecutionRequest → gateway
|
||||
│ no
|
||||
└─→ select_approach(labels, definition, hint) → legacy executor
|
||||
POST complete | fail(+reopen)
|
||||
validate granted repository result + persist external metrics
|
||||
enqueue exact terminal close → POST complete | fail
|
||||
replay pending close evidence before another claim
|
||||
```
|
||||
|
||||
`harness_profile_ref` is authoritative under ACT-ADR-006. A profiled row never
|
||||
consults `approach_hint`, `select_approach`, or a legacy executor, including
|
||||
after profile resolution refusal. The claim worker sends the complete
|
||||
`GatewayResult` to Activity Core; Activity Core persists its allowlisted
|
||||
`ExecutionEvidence` and drops direct tool output/error. Profile-absent rows keep
|
||||
the legacy coexistence path until the migration flag is enabled upstream.
|
||||
after profile resolution refusal. The claim worker sends bounded
|
||||
`ExecutionEvidence`; direct tool output/error and unknown provider fields are
|
||||
not persisted in its close outbox. A separately typed grant activates commit,
|
||||
path, clean-state, metadata, and remote-ref acceptance plus external metrics.
|
||||
Profile-absent rows keep the legacy coexistence path, but cannot carry a grant.
|
||||
|
||||
## Environment
|
||||
|
||||
|
|
@ -87,6 +90,10 @@ rein-aharness poll --source=ops-run
|
|||
rein-aharness claim-loop
|
||||
rein-aharness claim-loop --once --verbose
|
||||
|
||||
# Required close evidence and recovery
|
||||
rein-aharness close-outbox status
|
||||
rein-aharness close-outbox replay
|
||||
|
||||
# Dry-run: claim then fail+reopen without domain work
|
||||
rein-aharness poll --source=ops-run --dry-run
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Repository grant contract
|
||||
|
||||
Status: **v1 enabled for local `TaskSpec` files; queued/profiled carriage is
|
||||
not yet available**.
|
||||
Status: **v1 enabled for local `TaskSpec` files and profiled Activity Core
|
||||
rows**.
|
||||
|
||||
`repository_grant` is the explicit authority envelope for a bounded local Git
|
||||
mutation. It is separate from task prose, labels, organizational attribution,
|
||||
|
|
@ -53,16 +53,18 @@ Granted runs require durable external metrics and refuse `--no-metrics`. Their
|
|||
metrics are written outside the checkout only after acceptance, so a successful
|
||||
run remains clean. See [external-metrics.md](external-metrics.md).
|
||||
|
||||
Activity Core and issue-core adapters do not populate `repository_grant`.
|
||||
Queued/profiled runs therefore cannot claim repository acceptance under this
|
||||
contract. Existing grant-absent direct and compatibility runs retain their
|
||||
legacy `HEAD`-changed behavior during migration.
|
||||
Activity Core revision `b63131e` added strict definition admission and separate
|
||||
queue carriage. The claim client parses that exact v1 field, refuses malformed
|
||||
authority, and requires `harness_profile_ref` whenever a queued grant is
|
||||
present. Profiled success applies the same repository acceptance policy and
|
||||
external metrics contract as a local granted run.
|
||||
|
||||
Queued/profiled execution may use this contract only after:
|
||||
|
||||
1. an authoritative Activity Core/profile field carries the reviewed grant;
|
||||
2. required close evidence durably records the grant, transaction, and accepted
|
||||
result identities.
|
||||
Before sending a profiled terminal result, the worker durably records the exact
|
||||
run, transaction, worker, action, and bounded result. Response-lost closes are
|
||||
replayed without repeating workload code and Activity Core distinguishes exact
|
||||
reconciliation from terminal, evidence, owner, state, and lease conflicts.
|
||||
Grant-absent compatibility runs retain their legacy result behavior during
|
||||
migration.
|
||||
|
||||
Task descriptions, labels, `execution_refs`, consuming-repo defaults, and
|
||||
profile absence must never synthesize a grant.
|
||||
|
|
|
|||
|
|
@ -32,10 +32,10 @@ rein-aharness claim-loop
|
|||
|
||||
`TaskExecutorWorkflow` in activity-core stays a stub; execution lives here.
|
||||
|
||||
Activity Core does not yet emit the versioned `repository_grant` required by
|
||||
the lease-bound transaction path. The harness must not infer one from labels,
|
||||
task prose, `execution_refs`, or target-repo lookup. See
|
||||
**`docs/repository-grant.md`** for the parsed-but-not-enabled v1 contract.
|
||||
Activity Core revision `b63131e` emits a separately typed versioned
|
||||
`repository_grant`. The harness parses it strictly, requires an authoritative
|
||||
profile for queued grants, and never infers authority from labels, task prose,
|
||||
`execution_refs`, or target-repo lookup. See **`docs/repository-grant.md`**.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue