Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion prompts/playbooks/implementation-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,25 @@ Create an approved implementation context document containing the selected
plan, decision and plan IDs, authority and approval basis, intended outcome,
rejected alternatives and reasons, must-do and must-not-do constraints, migration choice,
responsibility boundary, affected paths, unresolved questions, and revision.
When the workflow has a registered contract artifact, never retype, summarize,
or reconstruct that artifact or its digest. Compose the approved context from
the supervisor-owned values and the exact artifact file bytes:

```bash
contract_path="$(multiagent workflow value "$MULTIAGENT_WORKFLOW_ID" contract_artifact)"
contract_hash="$(multiagent workflow value "$MULTIAGENT_WORKFLOW_ID" contract_artifact_sha256)"
{
printf 'contract-artifact-sha256=%s\n' "$contract_hash"
cat "$contract_path"
cat APPROVED_CONTEXT_BODY_PATH
} >CONTEXT_PATH
```

Write the selected plan and other implementation context to
`APPROVED_CONTEXT_BODY_PATH` first. Do not edit the registered artifact file,
copy its contents through model-generated text, or calculate a replacement
digest. The exact composition above is required even when the artifact is
already visible in conversation history.
Commit the selected alternative with `multiagent decision commit`, then record the
passed authority review and approved context with:

Expand Down Expand Up @@ -114,7 +133,9 @@ implementation context; a decision ID alone is insufficient.
Production runbook operations are not workspace implementation. For a signed
prod-mcp request, do not create a worker or assignment. Spawn the `ops` role
after independent review of the exact request and have that role invoke
`multiagent ops execute`. This special case remains subject to the active
`multiagent ops execute --request-file PATH --reviewer REVIEWER_NAME`. The
reviewer argument is mandatory and must name the finalized reviewer that
inspected that unchanged request file. This special case remains subject to the active
workflow, decision, plan, runbook, bounds, and post-execution review.

Do not silently change the approved plan. A newly discovered choice or factual
Expand Down Expand Up @@ -200,3 +221,14 @@ if a shell command overrides `MULTIAGENT_LIFECYCLE_ENFORCEMENT`.
`MULTIAGENT_VERIFIER_MAX_ITERATIONS` is an escalation threshold, not an
acceptance condition. At the threshold, reconsider the route, surface a
blocker, or ask the user. Never accept merely because the threshold was reached.
# Workflow TODO command contract

Use the CLI's exact TODO vocabulary; do not guess aliases such as `implementation` or `task`:

```bash
multiagent workflow add-todo "$MULTIAGENT_WORKFLOW_ID" TODO_ID \
--kind direct|decision \
--summary "SUMMARY"
```

Operational execution with an already stated caller goal is `--kind direct`. A TODO does not bypass contract registration, implementation-context binding, or authority review.
17 changes: 16 additions & 1 deletion prompts/playbooks/orchestration-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ When a goal needs access to an external or production service, inspect the avail

For a production operation, spawn exactly one `--role ops` agent with the immutable original goal, the selected Markdown runbook, and the prod-mcp contract. The `.md` runbook is authoritative; the ops agent owns construction of the JSON execution envelope but receives no KMS, bearer-token, AWS, Grafana, or Kubernetes credentials.

Before execution, require the ops agent to certify the request with `multiagent ops bind-runbook`, then spawn a separate read-only agent named with the `ops-reviewer` prefix against that exact request file. Finalize it so the supervisor seals its output. A failed `review-bind` is a rejection and cannot be replaced by manual review. The ops agent may then call `multiagent ops execute --request-file PATH --reviewer NAME` against the same unchanged file; execution fails unless the first verdict is accepted and the sealed evidence contains hashes of the exact request, goal, runbook metadata, and runbook content. After execution, spawn a different read-only reviewer to inspect the persisted request and receipt. Never let the orchestrator, ops agent, or pre-execution reviewer self-approve or perform the post-execution review.
Before execution, require the ops agent to certify the request with `multiagent ops bind-runbook`, then spawn a separate read-only agent named with the `ops-reviewer` prefix against that exact request file. Finalize it so the supervisor seals its output. A failed `review-bind` is a rejection and cannot be replaced by manual review. The execution instruction must preserve both the exact reviewed request path and finalized reviewer name, and must give the ops agent the complete command `multiagent ops execute --request-file PATH --reviewer REVIEWER_NAME`; never omit `--reviewer` or replace it with workflow-ledger editing. Execution fails unless the first verdict is accepted and the sealed evidence contains hashes of the exact request, goal, runbook metadata, and runbook content. After execution, spawn a different read-only reviewer to inspect the persisted request and receipt. Never let the orchestrator, ops agent, or pre-execution reviewer self-approve or perform the post-execution review.

## Progress And Status

Expand Down Expand Up @@ -246,3 +246,18 @@ and use its progress/status procedure.
- For worker, subagent, verifier, status, or checkpoint mechanics, load `prompts/playbooks/agent-spawning.md`.
- For pre-implementation contract extraction, load `prompts/roles/contract-scout.md`.
- For post-diff scope and blast-radius audits, load `prompts/roles/scope-guard.md`.
# Canonical operations instruction binding

For production operations, the supervisor coordinates roles but does not author the provider procedure:

- Discover and select the applicable Markdown file under `runbooks/`. The selected `.md` content is the authoritative procedure.
- For an operational goal, mechanically compose the contract scout instruction from the exact bytes of `prompts/roles/contract-scout.md`, the immutable original goal, the available Markdown runbook paths, and the prod-mcp operation contract. Do not paraphrase the scout role or tell the scout to require a provider-native MCP tool.
- The absence of provider-native Slack, GitHub, Grafana, AWS, Kubernetes, or similar tools in the agent harness is expected. It is not a blocker when the selected runbook and prod-mcp expose the required operation. Only a missing runbook, missing prod-mcp operation, or unavailable prod-mcp service is an execution blocker.
- Discard any implementation context drafted before contract registration. After registration, mechanically create a fresh context from the exact registered contract artifact bytes and digest; never repair or reuse a speculative pre-contract context.
- Treat bounded execution mechanics such as pagination, cursor traversal, chunking, identifier resolution, and related-record traversal as orchestrator-owned when they are necessary to fulfill the caller's explicit result. Do not ask the caller to choose a knowingly incomplete result.
- Mechanically compose the preparation agent's first instruction from the exact bytes of `prompts/roles/ops-agent.md`, the immutable original goal, the exact selected Markdown runbook, and the prod-mcp request contract. Do not paraphrase or replace the canonical role or runbook.
- Do not add provider-specific steps, operation parsing, hand-written request JSON, pagination policy, time-window calculations, or action sequencing to the supervisor prompt. The ops role constructs bounded requests from the goal, runbook, and prod-mcp contract.
- Any date, time, numeric bound, digest, identifier, or other value not literal in the goal or inspected source must be computed and verified with a bounded read-only command. Calendar arithmetic and epoch conversion must never be performed mentally. Preserve the command and relevant output as evidence or leave the value unknown.
- Mechanically compose each review instruction from the exact bytes of `prompts/roles/ops-reviewer.md`, the immutable original goal, the exact selected runbook, and the exact request-file path. Do not invent a reviewer checklist or output format. The canonical reviewer role owns `multiagent ops review-bind`, its four unchanged binding lines, and the first-line verdict format.
- Keep at most one active `--role ops` process. A preparation process may finalize at the review boundary. After the reviewer is finalized, a fresh `--role ops` execution process may receive only the exact canonical ops role, immutable bound artifacts, and the exact `multiagent ops execute --request-file PATH --reviewer NAME` command for the sealed request.
- The execution process must not reconstruct or broaden the reviewed request. Any follow-up operation requires a new request and a new canonical reviewer cycle.
14 changes: 14 additions & 0 deletions prompts/roles/contract-scout.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,3 +263,17 @@ Return only:

Keep the report short enough for the orchestrator to paste into worker and
verifier first instructions.
# Machine-readable contract output

- Emit every `contract-artifact: version=1` and `contract-rule:` record as plain ASCII text beginning in column one.
- Do not wrap those records in Markdown bold, backticks, code fences, headings, bullets, block quotes, or any other prefix or suffix. Human-readable explanation must be outside the machine-readable records.
- Treat any value that is not literal in the original goal or an inspected source as derived evidence. Compute and verify derived values with a bounded, read-only command and cite the command and relevant output in the contract evidence; otherwise record the value under `unknowns`.
- Never perform calendar arithmetic or calendar-to-epoch conversion mentally. Use a bounded date/time command and preserve its output as evidence.

# Production operations boundary

- For operational access to an external provider or deployed service, inspect the applicable Markdown runbook and the prod-mcp operation contract. Provider-native MCP tools are neither required nor expected in the agent harness.
- Never report missing Slack, GitHub, Grafana, AWS, Kubernetes, or other provider-native tools as a blocker when the runbook routes that capability through prod-mcp.
- The contract scout remains read-only and does not call prod-mcp. Record the selected runbook, required prod-mcp operation, bounded parameters, expected receipt evidence, and any actual missing runbook or operation as the contract. The `--role ops` agent performs execution after review.
- Distinguish per-request bounds from the caller's overall requested scope. Do not reinterpret a per-request limit as permission to return a knowingly incomplete result.
- Pagination, cursor traversal, chunking, identifier resolution, and traversal of related records needed for the explicit output are bounded execution mechanics, not unresolved user choices. Leave them to the orchestrator and ops role unless the runbook or caller explicitly makes them outcome-level decisions.
7 changes: 7 additions & 0 deletions prompts/roles/decision-authority-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,10 @@ Return only:
Do not use agent agreement or majority preference as authority. A passing
review means the orchestrator may proceed under the recorded authority; it is
not approval of a user-owned choice.
# Execution mechanics are not user-owned decisions

- When the caller has already specified the intended outcome and safety boundary, ordinary bounded execution mechanics remain orchestrator-owned. This includes pagination, cursor traversal, chunking, provider identifier resolution, bounded retries, and following related records or replies needed to produce the requested result.
- A per-request provider or runbook limit is not an instruction to truncate the caller's requested scope. Select a completeness-preserving bounded strategy that obeys each request limit and stop condition.
- Do not ask the caller to choose between a knowingly incomplete result and the complete result they already requested. Do not escalate implementation details merely because they affect latency, token use, or the number of bounded read calls.
- Escalate only when materially different user-visible outcomes remain after applying the original goal, runbook, and explicit safety constraints, or when a configured cost/risk threshold would be exceeded.
- Evidence needed to choose an execution path may be gathered by the ops role after the implementation gate. Do not create a circular requirement that demands production execution before authority review can pass.
2 changes: 1 addition & 1 deletion prompts/roles/ops-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ You are the operations agent. Execute the original goal by following the supplie
- Certify the request against the exact Markdown bytes by running `multiagent ops bind-runbook --request-file "$REQUEST_FILE" --runbook-document runbooks/SELECTED.md`. Never calculate or write `runbookContentSha256` yourself. Any change after this command creates a different request and requires binding again.
- Keep production evidence in your role-owned trace directory, never in the repository or another role's private home.
- Before execution, print the exact request and request path, then exit so an independent `ops-reviewer` can inspect the same literal request. Do not execute an unreviewed request.
- When invoked for execution with accepted reviewer evidence, call `multiagent ops execute` against the exact unchanged request path inspected by that reviewer. Do not recreate, copy, reformat, or otherwise mutate the reviewed file. Wait for its persisted receipt before continuing the runbook.
- When invoked for execution with accepted reviewer evidence, call `multiagent ops execute --request-file PATH --reviewer REVIEWER_NAME` against the exact unchanged request path inspected by that finalized reviewer. The `--reviewer` argument is mandatory. Do not infer approval from or edit the workflow ledger, and do not recreate, copy, reformat, or otherwise mutate the reviewed file. Wait for its persisted receipt before continuing the runbook.
- Treat changed request content as a new request that requires a new independent review.
- You have authority to request any operation allowed by prod-mcp. You do not possess AWS, KMS, bearer-token, Grafana, or Kubernetes credentials.
- The authority supervisor owns KMS signing and prod-mcp transport authentication. Missing credential environment variables in this role are intentional; use the local `multiagent ops` commands and report only an actual broker rejection.
Expand Down
40 changes: 33 additions & 7 deletions src/prod_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,11 +299,7 @@ fn verify_reviewer(
if !actual_output.eq_ignore_ascii_case(expected_output) {
return Err("ops reviewer evidence failed its supervisor seal".into());
}
let accepted = evidence
.lines()
.map(str::trim)
.find(|line| !line.is_empty())
.is_some_and(|line| line.eq_ignore_ascii_case("verdict: accepted"));
let accepted = reviewer_accepted(&evidence);
if !accepted {
return Err("ops reviewer did not accept the operation".into());
}
Expand Down Expand Up @@ -345,6 +341,25 @@ fn verify_reviewer(
})
}

fn reviewer_accepted(evidence: &str) -> bool {
evidence
.lines()
.map(str::trim)
.find(|line| !line.is_empty())
.is_some_and(|line| {
let mut value = line;
for wrapper in ["`", "**", "__"] {
if value.starts_with(wrapper)
&& value.ends_with(wrapper)
&& value.len() >= wrapper.len() * 2
{
value = &value[wrapper.len()..value.len() - wrapper.len()];
}
}
value.eq_ignore_ascii_case("verdict: accepted")
})
}

fn required_object<'a>(
object: &'a serde_json::Map<String, Value>,
key: &str,
Expand Down Expand Up @@ -809,8 +824,8 @@ fn base64_decode(value: &str) -> Result<Vec<u8>, String> {
mod tests {
use super::{
base64_decode, base64url_encode, build_request, canonical, curl_command, ecdsa_der_to_raw,
parse_mcp_body, private_temp_path, runbook_content_digest, write_mcp_headers,
TrustedApproval,
parse_mcp_body, private_temp_path, reviewer_accepted, runbook_content_digest,
write_mcp_headers, TrustedApproval,
};
use chrono::{TimeZone, Utc};
use serde_json::json;
Expand Down Expand Up @@ -847,6 +862,17 @@ mod tests {
"sha256:a0bd8567ec5da5c4c78ef8370994af0b34e5c83c1ebdd28359d297096f8efa75"
);
}

#[test]
fn reviewer_acceptance_allows_only_cosmetic_markdown_wrapping() {
assert!(reviewer_accepted("Verdict: ACCEPTED\n"));
assert!(reviewer_accepted(
"**Verdict: ACCEPTED**\n\nReview analysis"
));
assert!(reviewer_accepted("`verdict: accepted`"));
assert!(!reviewer_accepted("Review result: verdict: accepted"));
assert!(!reviewer_accepted("**Verdict: REJECTED**"));
}
#[test]
fn operation_and_target_come_from_runbook_request_data() {
let now = Utc.with_ymd_and_hms(2026, 8, 22, 12, 0, 0).unwrap();
Expand Down
12 changes: 10 additions & 2 deletions src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3342,8 +3342,13 @@ fn normalize_report_line(line: &str) -> &str {
value = rest.trim_start();
}
}
if value.starts_with('`') && value.ends_with('`') && value.len() >= 2 {
value = &value[1..value.len() - 1];
for wrapper in ["`", "**", "__"] {
if value.starts_with(wrapper)
&& value.ends_with(wrapper)
&& value.len() >= wrapper.len() * 2
{
value = &value[wrapper.len()..value.len() - wrapper.len()];
}
}
value
}
Expand Down Expand Up @@ -3949,6 +3954,9 @@ review-record: type=decision-authority verdict=pass diff=-\n";
assert!(accepted_report(
"3. `review-record: type=scope verdict=pass diff=abc`"
));
assert!(accepted_report(
"**review-record: type=decision-authority verdict=pass diff=-**"
));
}

#[test]
Expand Down
11 changes: 9 additions & 2 deletions src/workflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1242,8 +1242,13 @@ fn review_marker_matches(line: &str, marker: &str) -> bool {
value = rest.trim_start();
}
}
if value.starts_with('`') && value.ends_with('`') && value.len() >= 2 {
value = &value[1..value.len() - 1];
for wrapper in ["`", "**", "__"] {
if value.starts_with(wrapper)
&& value.ends_with(wrapper)
&& value.len() >= wrapper.len() * 2
{
value = &value[wrapper.len()..value.len() - wrapper.len()];
}
}
value == marker
}
Expand Down Expand Up @@ -1636,6 +1641,8 @@ mod tests {
assert!(review_marker_matches(marker, marker));
assert!(review_marker_matches(&format!("3. `{marker}`"), marker));
assert!(review_marker_matches(&format!("- `{marker}`"), marker));
assert!(review_marker_matches(&format!("**{marker}**"), marker));
assert!(review_marker_matches(&format!("- __{marker}__"), marker));
assert!(!review_marker_matches(
&format!("evidence includes {marker}"),
marker
Expand Down
Loading