Plectis
This page

Paper module

Bounded Autonomy Campaign Packet

Bounded autonomy campaign packets propose guarded agent work without authorizing source-file changes or unsupervised repair.

Contains 25 sections · 1 diagram · 5 references

The write-up

Coverage gaps become proposals without action authority

This component lets an agent draft a plan to close its own coverage gaps while stamping every row as a proposal that carries no authority to act. bounded_autonomy_campaign_packet is a component that lets an agent draft a plan to close its own coverage gaps without giving that plan any authority to act. It reads synthetic public inputs, watches a read-only campaign builder, and emits a draft candidate packet where every row is stamped as a proposal, not a change.

The packet carries hashes and refs, never writes

The result record carries only refs, digests, line counts, and stdout and stderr hashes, never a write surface, a true source-file changes flag, or the builder's output bodies. The result record it writes carries refs, digests, line counts, and stdout and stderr hashes. It never carries a write surface, a source-file changes flag set to true, or the builder's output bodies.

The demonstration separates proposing from doing

What it demonstrates is narrow: an agent can propose work drawn from a real surface capable of doing it, observed in a mode where it did not. What it demonstrates is narrow and deliberate: an agent can propose work drawn from a real surface that could do that work, observed in a mode where it did not.

Purpose

The risk of sketching sliding into doing

An agent can usefully sketch a plan to fix its under-coverage, but the risk is that sketching quietly becomes doing as a proposal grows a write surface. An agent can usefully notice where it is under-covered and sketch a plan to fix it. The risk is that "sketch a plan" quietly becomes "do the work". A proposal grows a write surface, and a system meant to suggest starts editing its own source unsupervised.

Keeping proposing and acting apart

This component keeps proposing and acting apart, answering whether an agent can emit a draft campaign proposal from real coverage gaps without that proposal carrying any authority to act. This component keeps those two steps apart. It answers one question: can an agent emit a draft campaign proposal from real coverage gaps without that proposal carrying any authority to act on them?

Candidate count comes from a witnessed builder

The candidate count comes not from an invented list but from a check-only builder witness, and each candidate is stamped with no write surface, no source-file changes, and required review. The design choice that matters is where the candidate count comes from. The component does not invent a plausible list of work. It watches a real campaign builder run in a check-only mode and accepts its witness only when the builder reports candidate targets and leaves wrote_packet unset. Each drafted candidate is then stamped write_surface: none, source_mutation_authorized: false, and requires_human_review: true, so proposing can never be read as authorising.

How it works

Two entry points share the same checks

run and run_bounded_autonomy_bundle both route through run_crown_jewel_organ with the same evaluate and evaluate_negative_case evaluators, so the identical checks guard both command surfaces. run and run_bounded_autonomy_bundle both hand the fixture and the exported bundle to run_crown_jewel_organ, passing evaluate as the evaluator and evaluate_negative_case as the negative-case evaluator. The bundle entry point adds the bundle input mode. The same checks guard both command surfaces.

evaluate runs four ordered refusal checks

evaluate loads three inputs and runs four ordered checks, refusing a source-write policy, a failed witness, an empty list, or an authorising candidate, and passing only when no finding remains. evaluate loads three declared inputs: coverage_gaps.json, campaign_policy.json, and failed_campaign_digests.json. It then runs four checks in order and collects a finding for each failure. First, if write_source appears in the policy's allowed_actions, it records BOUNDED_AUTONOMY_SOURCE_WRITE_FORBIDDEN before any candidate is drafted. Second, it builds the candidate packet and refuses it if the builder witness did not pass or the packet is not marked drafted. Third, it refuses an empty candidate list. Fourth, it refuses any candidate that sets source_mutation_authorized to true or writes to the source surface. It also counts repeated entries in the failed digest ledger and records BOUNDED_AUTONOMY_REPEATED_FAILED_DIGEST if any digest appears more than once. A run passes only when the finding list is empty.

Turning the witnessed count into stamped rows

_candidate_packet_subprocess caps the witnessed count at the policy's max_candidate_count and turns it into draft rows, each tied to a coverage gap and stamped with no write surface and required human review. _candidate_packet_subprocess turns the witnessed target count into draft rows. It reads max_candidate_count from the policy (default 2), asks the witness for that many targets, and takes the smaller of the two counts. Each row ties to one coverage gap when one is available, carries the builder ref and the builder source digest, and sets write_surface: none, requires_human_review: true, and source_mutation_authorized: false.

Witnessing the builder in check-only mode

_campaign_builder_witness runs the real builder as a check-only subprocess when present, or falls back to the copied source-module manifest in the public clone, storing stdout and stderr hashes rather than bodies. The witness itself is _campaign_builder_witness. It looks for the builder named by BUILDER_REF at the repository root. When that file is present it runs it as a subprocess with --check --report --max-targets, with a 45 second timeout, and accepts the witness only when the process exits zero, returns kind standard_skill_pairing_campaign_summary, is not a no-op, reports at least one candidate target, emits a source_digest, and leaves wrote_packet unset. When the builder file is absent, which is the case in the public clone, it falls back to _public_source_module_builder_witness, which reads the copied source-module manifest and passes only when the target file's sha256 matches, its line count matches, and no required anchor is missing. Either way the witness stores stdout and stderr hashes, not bodies.

FunctionRole
run, run_bounded_autonomy_bundleRoute the fixture and exported bundle through run_crown_jewel_organ with the shared evaluators
evaluateLoad the three inputs, run the policy, witness, candidate, and digest checks, return findings
_candidate_packet_subprocessConvert the witnessed target count into stamped draft candidate rows
_campaign_builder_witnessWatch the real builder in check-only mode, or fall back to the source-module manifest
evaluate_negative_caseMutate a copy of the input and re-run evaluate to confirm the refusal fires

Module constants pin the boundary: EXPECTED_NEGATIVE_CASES maps mutations to codes, AUTHORITY_CEILING sets every autonomy flag false, and SPEC declares the required inputs, manifest ref, and anchors. The module constants pin the boundary. EXPECTED_NEGATIVE_CASES maps each named mutation to the error code it must produce. AUTHORITY_CEILING sets self_repair_authorized, unsupervised_source_mutation_authorized, source_write_packet_authorized, provider_calls_authorized, and release_authorized all to false. SPEC declares the required inputs, the source manifest ref, and the required anchors.

Diagram of the mechanism (8 steps).
Public synthetic inputscoverage_gaps, campaign_policy,failed_campaign_digestsPublic synthetic inputs coverage_gaps, campaign_policy, failed_campaign_digestspolicy allowswrite_source?policy allows write_source?Builder witnesscheck-only builder runor source-module manifestBuilder witness check-only builder run or source-module manifestreports candidatesand wrote_packet unset?reports candidates and wrote_packet unset?Draft candidate rowswrite_surface none,requires_human_review,source_mutation falseDraft candidate rows write_surface none, requires_human_review, source_mutation falsefailed digestrepeated?failed digest repeated?Refusesource-write, blocked witness,or repeated digestRefuse source-write, blocked witness, or repeated digestmetadata-only result recordrefs, digests, stdout/stderrhashesmetadata-only result record refs, digests, stdout/stderr hashes
Diagram source & refs
flowchart TD Inputs["Public synthetic inputs coverage_gaps, campaign_policy, failed_campaign_digests"] PolicyGate{"policy allows write_source?"} Witness["Builder witness check-only builder run or source-module manifest"] WitnessGate{"reports candidates and wrote_packet unset?"} Draft["Draft candidate rows write_surface none, requires_human_review, source_mutation false"] DigestGate{"failed digest repeated?"} Refuse["Refuse source-write, blocked witness, or repeated digest"] Record["metadata-only result record refs, digests, stdout/stderr hashes"] Inputs --> PolicyGate PolicyGate -- "yes" --> Refuse PolicyGate -- "no" --> Witness Witness --> WitnessGate WitnessGate -- "no" --> Refuse WitnessGate -- "yes" --> Draft Draft --> DigestGate DigestGate -- "yes" --> Refuse DigestGate -- "no" --> Record Refuse --> Record

Negative cases

Refusals checked by mutating the input

The refusals are checked by mutating the input rather than trusting a declared label, as evaluate_negative_case copies the inputs, edits one file, and re-runs evaluate. The refusals are checked by mutating the input, not by trusting a declared label. evaluate_negative_case copies the required inputs into a temporary directory, edits one file, and re-runs evaluate.

The source-write policy case

The source_write_campaign_packet case appends write_source to the policy's allowed_actions and must produce BOUNDED_AUTONOMY_SOURCE_WRITE_FORBIDDEN. The source_write_campaign_packet case appends write_source to the policy's allowed_actions. It must produce BOUNDED_AUTONOMY_SOURCE_WRITE_FORBIDDEN.

The repeated failed-digest case

The repeated_failed_campaign_digest case duplicates a digest in the failed-digest ledger and must produce BOUNDED_AUTONOMY_REPEATED_FAILED_DIGEST, since an already-failed plan cannot be re-proposed under a fresh wrapper. The repeated_failed_campaign_digest case rewrites the failed-digest ledger to hold the same digest twice. It must produce BOUNDED_AUTONOMY_REPEATED_FAILED_DIGEST. A plan that has already failed cannot be re-proposed under a fresh wrapper.

Unknown negative cases fail with one stable code

Any negative-case id outside the declared set is rejected as unsupported with the stable bounded-autonomy error code. A negative case with any other id returns BOUNDED_AUTONOMY_NEGATIVE_CASE_UNSUPPORTED.

Prior Art Grounding

Preflight gating of proposed actions

The component follows established preflight-gate patterns from NIST AI RMF, Open Policy Agent, and GitHub Actions, applying that shape to draft self-proposals over synthetic public coverage gaps. The component follows established patterns for gating proposed actions before they run. The NIST AI Risk Management Framework frames AI work as governing, mapping, measuring, and managing risk rather than assuming autonomy is authorized. Open Policy Agent is a policy-engine pattern for deciding whether an action may proceed. GitHub Actions workflow syntax is a common automation surface where jobs and permissions are declared before execution. This component keeps the preflight-gate shape and applies it to draft self-proposals over synthetic public coverage gaps.

Validation Result record Path

What a pass means and how to route drift

A pass means both fixture and bundle drafted a packet, both negative cases fired their codes, and the record stayed metadata-only, with digest drift routed through microcosm_exact_copy_refresh. A pass means the fixture and bundle both produced a draft packet, both named negative cases fired their expected error codes, and the result record stayed metadata-only. If the source-module manifest reports digest drift, route that through microcosm_exact_copy_refresh; this page is not the authority for copied source bodies. If the full projection check fails because another session holds the shared lattice outputs, treat that as unrelated contention and use the corpus check as the local gate.

Scope boundary

Scope limit

The strongest supported claim is that under public synthetic inputs the component emits a draft self-proposal from a read-only witness and refuses source-write or repeated-digest inputs, both checked by mutation. The strongest claim the evidence supports is this: under public synthetic inputs, the component emits a draft self-proposal derived from a read-only builder witness and refuses a source-write policy or a repeated failed digest, with both refusals checked by mutating the input. That is the proof boundary and the scope limit for this module.

What the module does not claim

Context & evidence

Source

Source Source module: src/microcosm_core/organs/bounded_autonomy_campaign_packet.py · Design note · Source registry