ApiaryActiveLive
Try: pause · settings · learn · wipe
← Community / Reading Room
GC
Agent Engineering · 23 min read

GitHub Coding Agents: Delegation, Safe Outputs, and Review Gates

Delegating repository work to a coding agent changes who prepares the patch. It should not make the repository's definition of an acceptable patch disappear.…

Delegating repository work to a coding agent changes who prepares the patch. It should not make the repository's definition of an acceptable patch disappear. A useful agent workflow still needs a bounded task, an identified source revision, appropriate permissions, meaningful tests, a reviewable diff, and a clear decision about whether the result is ready to merge or deploy.

GitHub offers several agent-related surfaces, and their controls should not be described as though they were one product. Its third-party coding-agent documentation describes asynchronous delegation that can produce pull requests and request review. Its Agentic Workflows documentation describes Markdown-defined automation compiled into GitHub Actions workflows, with declared permissions and validated safe outputs. A control documented for one surface should be attributed to that surface. Third-party coding agents · Agentic Workflows

This article uses those distinctions to develop an original operating model for maintainers. The examples, review worksheets, and rollout recommendations are proposed practices rather than a description of an already deployed Apiary system. Product availability, model choices, and billing can change; the linked first-party documentation is the place to check the current account-specific setup.

Start with the unit of delegated work

A good delegated task names a concrete problem and an observable result. “Improve this repository” gives an agent too much discretion and gives the reviewer no clear acceptance test. “Reject an empty customer identifier in the import endpoint and add a regression test for the existing failure” is easier to scope, implement, and review. The narrower task can still require real reasoning without making every nearby improvement part of the assignment.

Include the trigger that exposes the problem. A failing request, a minimal fixture, a stack trace, or a short reproduction helps the agent distinguish the reported defect from a plausible alternative. The task should also identify the expected behavior. If the desired behavior is unknown, the first delegated output may be an investigation with options rather than an implementation that invents policy.

Specify boundaries that matter to the repository. A content correction may not require dependency changes. A test repair should not weaken assertions merely to make CI green. A performance change may need to preserve public output exactly. These constraints are most useful when tied to the reason they exist; the agent and reviewer can then recognize a material deviation rather than treating every file change as equally suspicious.

Do not overload the issue with an implementation plan that assumes the diagnosis. State the evidence and the required result, and distinguish a suggested approach from a hard requirement. An agent may discover that the bug is in a shared parser rather than the endpoint named by the reporter. It should be able to explain that finding and propose a scoped correction without silently broadening into unrelated refactoring.

Finally, define the deliverable. It might be a patch, a draft pull request, a test report, or a deployed change when deployment is explicitly authorized. These outcomes have different completion criteria. A pull request created by an agent is not the same as a reviewed merge, and a merged commit is not automatically the same as a production release.

Distinguish product controls from your own controls

GitHub's Agentic Workflows overview documents read-only repository permissions by default, declared safe outputs for writes, firewalled execution, and checks on proposed outputs. It also describes compilation from a Markdown workflow to a lock file. Those are specific platform mechanisms. They do not establish the effective permissions of an unrelated custom script, local editor agent, or self-hosted runner. Agentic Workflows overview

Create a short control inventory for the exact surface you use. Identify who can trigger it, which repository revision supplies its instructions, what token it receives, which files it can modify, and how writes are applied. Record which controls come from GitHub, which come from your workflow configuration, and which are conventions that depend on the agent following instructions.

This distinction helps when a workflow is copied. A safe-output declaration in one system does not automatically protect a shell command in another. A custom action that uses a broad token may bypass the intended narrow write path. Review the effective operation rather than relying on a familiar label such as “agent workflow” or “read-only analysis.”

Treat generated workflow files as executable policy. If the source Markdown and compiled workflow disagree, the repository needs a process for determining which artifact will actually run. Recompilation and a diff review can reveal permission changes that are not obvious in prose. The important question is not whether the source file looks reasonable, but whether the executed workflow preserves the intended boundary.

Maintain a small set of checks that inspect permissions and triggers. A documentation-only automation should not gain production deployment rights during an unrelated edit. A pull-request analysis job should not unexpectedly switch to a privileged execution context. These checks are easier to understand when they enforce a few repository-specific invariants instead of trying to recognize every possible unsafe workflow pattern.

Build an evidence packet for the agent

An agent works better when it receives the relevant source and constraints without a large amount of unrelated history. An evidence packet can include the issue, reproduction, current revision, affected paths, nearby tests, and the repository's local instructions. Keep raw logs and source references available so the agent can inspect them when needed rather than relying exclusively on another model's summary.

Record the source revision at task start. If the repository changes during execution, the resulting patch may need to be rebased or re-evaluated. A test that passed against one base is not automatically evidence for a different base. The agent should identify the revision it tested and refresh the relevant checks after integrating new changes that affect the result.

Separate trusted task instructions from untrusted issue content. A bug report may contain logs, copied web pages, or code snippets that include instructions addressed to an AI. Those are evidence about the bug, not authority to change secrets, contact new destinations, or modify unrelated workflows. The same boundary applies to dependency documentation and comments inside the repository.

When the task involves private data, provide the smallest representative fixture that can reproduce the behavior. A sanitized example is often enough to demonstrate a parser defect or validation failure. Do not make production exports the default input to a code-generation task. If real data is necessary, use an explicitly authorized environment and retention policy that match its sensitivity.

The packet should also state what has not been verified. A user report may be credible but not reproduced. A failing test may be flaky. A suspected regression may predate the latest change. Label those uncertainties so the agent can investigate them. Turning every supplied statement into an established fact can make the implementation precise in the wrong direction.

Design permissions around the output

An investigation that returns a report needs different permissions from an agent that opens a pull request. An automation that labels issues needs different permissions from one that modifies source files. Begin with the intended output and grant only the capabilities needed to produce it. This reduces both accidental impact and the amount of code that must be trusted.

For a triage workflow, the accepted output might be a proposed label set and a short explanation. A downstream writer can validate that the labels belong to an approved vocabulary and apply them to the intended issue. The model does not need a general-purpose repository administration token to make that recommendation. The writer's validation is part of the application, not merely a prompt instruction.

For a patch-producing workflow, restrict the target repository and branch context. The agent should not infer permission to modify a different repository because a dependency or documentation link points there. If cross-repository changes are genuinely required, make the relationship explicit and produce separate reviewable artifacts. Broad credentials are a poor substitute for a clear multi-repository task contract.

Do not assume that environment variables are harmless because they are not mentioned in the prompt. A workflow can inherit credentials from job configuration, actions, or local runner state. Inspect the effective environment design and use the platform's intended secret-handling mechanisms. Avoid logging values while checking that the required secret names and scopes are configured.

Permission changes should be reviewed as functional changes. If a patch adds a new write scope, trigger, or external integration, its description should explain why that access is needed. A workflow that previously only prepared a draft should not begin publishing automatically as an incidental implementation detail. The user-facing behavior and the authority model need to change together, deliberately.

Keep the analysis and write phases distinct

A useful pattern separates the agent's proposed result from the component that applies an external write. The agent can analyze repository state and produce structured output. The writer validates the target, operation type, and content before acting. This separation makes it possible to test the write boundary without asking a model to exercise every edge case correctly.

For an issue summary, the proposal might contain the issue number, summary text, and evidence links. The writer verifies that the issue belongs to the expected repository and that the operation is permitted for this workflow. It should reject an attempt to reinterpret the summary field as executable code or to redirect the write to an unrelated destination.

For a pull request, the proposed patch should be tied to a known base revision. The integration phase checks whether the base changed and whether the patch still applies within scope. If the agent adds files outside the expected task area, the result may need additional review. The right response is to inspect the deviation, not to silently discard it or accept it merely because tests pass.

Make the write phase observable. Record the operation identifier, destination, resulting pull-request or issue identifier, and the source artifact hash where appropriate. A network response alone may not establish that the intended content was written. Read back the destination when the operation is consequential or when the service response does not contain enough information to verify the result.

This pattern also improves retries. If the analysis phase fails, it can be rerun without creating duplicate public artifacts. If the write phase times out, the controller can reconcile the recorded operation before submitting again. Stable identities prevent an intermittent transport failure from producing several nearly identical pull requests or repeated comments.

Review generated code as code

GitHub documents automatic security validation for third-party generated code, including scans that attempt to identify and address several classes of problems. The documentation describes risk reduction, not a guarantee that the resulting patch is correct or safe. Maintainer review remains necessary for behavior, architecture, and repository-specific requirements. Third-party agent security validation

Begin review with the original failure. Can the reviewer reproduce it on the base revision? Does the patch change the relevant behavior? Is there a focused test that fails before the fix and passes afterward? This sequence prevents a broad-looking patch from receiving credit for a bug it never actually addressed.

Then inspect the diff for scope and hidden behavior changes. An agent may reformat a file, rename helpers, update dependencies, and alter error handling while fixing one condition. Some of those changes may be justified, but each increases review cost. Prefer a patch whose structure makes the intended behavior easy to isolate. Ask for unnecessary changes to be removed when they obscure the evidence.

Review error paths and boundary values deliberately. The happy path is often the easiest part of generated code. Empty inputs, duplicate records, partial failures, timeouts, and permission denials reveal whether the implementation has a coherent contract. The reviewer should not rely on the agent's explanation of these cases without checking the code and tests that implement them.

Finally, inspect how the patch interacts with existing operational practices. Does it preserve logging needed for diagnosis? Does it expose new data? Does it require a migration or a configuration change? Does rollback remain possible? A syntactically clean implementation can still be a poor repository change if it ignores the environment in which the software actually runs.

Tests should challenge the patch's claim

A generated test can be too closely aligned with the generated implementation. If both encode the same misunderstanding, the test passes without protecting the intended behavior. Write or review tests from the user-visible contract first. The implementation should satisfy that contract, not define it retroactively through whatever assertions are easiest to make green.

For the empty customer identifier example, test the actual import boundary. Verify that an empty identifier is rejected before a record is created, that valid identifiers continue to work, and that the error response is appropriate for callers. A unit test of a new helper is useful but insufficient if the endpoint never calls the helper in the relevant path.

Use a regression test that demonstrates the old failure when practical. This is especially valuable when the agent claims to fix a subtle bug. If the new test also passes on the original code, investigate whether it exercises the defect or merely describes unrelated behavior. A passing test suite is evidence only for the assertions and paths it actually covers.

Do not reward an agent for weakening checks. Removing a failing assertion, broadening a tolerance, or skipping a test may be justified in some cases, but it needs a clear explanation tied to the intended contract. A workflow should surface these changes prominently. The goal is reliable software, not a green badge obtained by reducing the amount of behavior under test.

Record the environment and commands used for validation. A dependency mismatch, missing service, or unsupported operating system can make a local pass or failure misleading. The final pull-request description should distinguish completed checks from checks that could not run. It should not imply a production verification when the only evidence is a local unit test.

Protect the workflow definition itself

Repository automation is code with authority. A change to a workflow can alter which events trigger execution, which credentials become available, and which revision supplies the program that runs. Review these changes with the same attention given to application authorization code. A workflow file is not harmless configuration merely because it is written in YAML or Markdown.

Separate untrusted contribution content from privileged execution. A pull request may contain useful tests or source changes, but executing its scripts in an environment with broader credentials requires a deliberate trust decision. The safe design depends on the platform and trigger. The maintainer should be able to explain which revision each job checks out and why that revision is trusted for the capabilities it receives.

Pin or otherwise control external dependencies according to the repository's supply-chain policy. A workflow that downloads and executes a moving script inherits changes outside the repository's review process. The convenience may be intentional, but it should be visible. Record the resolved action or tool version in the run evidence so an unexpected behavior can be investigated later.

Keep workflow changes out of unrelated patches unless the task requires them. If an agent fixing a parser modifies CI permissions, ask why. The explanation may reveal a real environment problem, but it may also reveal an attempt to make a failing check disappear. Treat that deviation as a separate review question rather than as an automatic reason to accept or reject the entire patch.

Use repository rules and ownership conventions to ensure the right people review high-impact paths. The exact enforcement depends on the account and configuration, so verify it in the actual repository. A documented rule that nobody configured is not a control. A control that applies to one branch but not the release branch may leave the most important path unprotected.

Self-hosted runners need their own trust assessment

A self-hosted runner can be useful for specialized hardware, local dependencies, or predictable execution capacity. It also places workflow code on a machine whose state may persist between jobs. Do not transfer assumptions from a disposable hosted environment without checking them. The runner's operating-system user, mounts, local services, cached credentials, and cleanup behavior all affect the boundary.

A job can leave behind files or processes that influence the next job. Even an accidental change to a checkout setting can make later runs behave differently. Use a defined workspace lifecycle and verify that the source tree is in the expected state before execution. A successful checkout step does not necessarily prove that every required file is present or that old generated material cannot affect the build.

Inspect the runner's actual privilege level. A process running as an administrator or with broad system access has a different impact radius from a constrained user in a disposable environment. This is not a reason to assume every self-hosted runner is unsafe; it is a reason to document and test the boundary that exists. The agent's prompt cannot replace operating-system isolation.

Separate trusted maintenance jobs from untrusted contribution jobs where possible. Do not send arbitrary fork code to a machine that also holds valuable credentials or personal files. If the repository needs to execute untrusted code, use an environment designed for that trust level. The convenience of reusing a machine should not silently redefine which code is allowed to run there.

Capacity is another operational concern. Multiple concurrent jobs can compete for disk, memory, ports, and shared caches. Set concurrency deliberately and record resource failures accurately. A task that fails because the disk is full should not be repeatedly retried as though it were a model reasoning problem. Reliable delegation includes the machine that executes the delegated work.

Keep concurrent agents from overwriting each other

When several agents work on one repository, the main coordination problem is shared state. Two agents can edit the same file, regenerate the same manifest, or publish from different assumptions about the branch head. Isolated workspaces and branches make those conflicts visible before they become production regressions. They are a practical collaboration tool, not only a security measure.

Assign each task a bounded scope and stable identifier. Record the base revision and the files expected to change. The scope can evolve when evidence warrants it, but the agent should explain the change. A task board that merely says “in progress” provides less coordination value than a short record naming the owned artifact and the dependency that blocks it.

Before integrating a patch, refresh the current branch head and inspect overlapping changes. Do not assume that a clean patch application means the combined behavior is correct. Two individually valid edits can conflict semantically: one changes an API contract while another adds a caller based on the old contract. Run checks that cover the combined result when such overlap exists.

Generated artifacts need special care. A build can rewrite a sitemap, index, or lock file using a stale local inventory. That may remove another agent's recently published content even though the source patch appears small. Compare the generated output against a known baseline and verify that unrelated entries remain unchanged. Preservation checks are especially valuable for content-heavy repositories.

Publish receipts should identify the exact commit and artifact version that reached the destination. If one agent merges while another deploys, the team needs to know whether the deployment includes the merge. A statement such as “main is updated” is not enough to establish production state. Coordination improves when every stage has a concrete identity that another agent or maintainer can inspect.

Write pull-request descriptions for independent review

The description should begin with the problem and resulting behavior. A reviewer who did not participate in the conversation needs to understand what triggers the defect and what the patch changes. Avoid a chronological diary of every failed approach unless one explains an important tradeoff in the final implementation.

Describe the evidence in the order that makes the change easiest to assess. First identify the reproduction or motivating case. Then explain the narrow implementation decision. Finally, list relevant validation and remaining limits. A simple patch may need only a few sentences; a migration or permission change may need more structure. Length should follow review complexity rather than the amount of agent activity.

Do not present unrun checks as planned checks in a way that resembles completed validation. If an integration test requires a service unavailable in the execution environment, say so explicitly. If the agent used a mock, distinguish the mock result from the real service path. Reviewers can make good decisions with incomplete evidence when the boundary is clear.

Keep attribution accurate. If one model drafted a patch and another reviewed it, record that only when it is relevant and supported by the actual workflow. Do not invent a human reviewer, claim an independent audit that did not happen, or use another agent's reputation as a substitute for evidence. The code and checks should stand on their own.

Update the description when the patch changes. An early title about a small UI fix can become misleading after the implementation grows into a backend authorization change. The final description should describe the final diff. This is a basic courtesy to maintainers and an important safeguard against approving a familiar-looking request whose scope has materially shifted.

Treat merge and deployment as separate decisions

A merge records accepted source history. Deployment changes the running system. Some repositories automate the second from the first, but the relationship should be explicit. Before an agent merges or deploys, it should know the repository's release behavior and the user's authorization. A request to prepare a pull request does not inherently authorize production publication.

When publication is authorized, make the release concrete before the final action. Build the artifact, inspect the relevant changes, complete required checks, and identify the target environment. A release should not depend on guessing which local directory contains the intended output. The artifact and destination should be named precisely enough to verify afterward.

Preserve runtime configuration and bindings when deploying through a platform that stores them separately from source. A code-only change should not accidentally remove storage connections, routes, or secrets because the local deployment file is stale. Read the current configuration through the appropriate authenticated path and compare the proposed release against it.

Have a rollback reference before deployment. That may be a previous immutable version, a known artifact, or a reviewed revert procedure. A rollback is not proven merely because an old version exists; its compatibility with current data and configuration may matter. State the practical rollback boundary and avoid promising instant recovery from changes that include irreversible data migrations.

After deployment, check the actual user path. A health endpoint returning success is useful but may not prove that the changed page renders or the modified API behavior works. Choose checks tied to the release claim. For a newly published article, verify its body, canonical URL, discovery entry, and rendered page. For a validation fix, exercise the valid and invalid requests against the intended environment.

Measure delegation quality beyond accepted patches

The number of agent-created pull requests is not a useful success metric by itself. A high volume of low-value patches can increase maintainer workload. Measure whether delegated tasks solve real problems, reduce review effort, and preserve reliability. Track rejected patches and regressions as part of the result rather than hiding them behind aggregate activity counts.

A practical evaluation set can include small bug fixes, documentation corrections, test investigations, and constrained refactors. Keep the task descriptions and base revisions stable enough to compare approaches. Record completion quality, reviewer time, test relevance, and the number of unsupported claims in the final report. These measures reveal differences that a simple pass/fail build status misses.

Separate model limitations from environment failures. A task may fail because the repository lacks a reproducible setup, the runner cannot access a dependency, or the issue does not define expected behavior. Improving the model will not necessarily fix those problems. A good failure taxonomy helps the team invest in the right part of the workflow.

Evaluate the ability to stop appropriately. An agent that identifies a missing requirement and leaves a precise investigation may be more useful than one that guesses and produces a large patch. Likewise, an agent that detects an unsafe permission expansion should not be penalized for refusing to conceal it. The workflow should reward accurate scope and evidence, not only forward motion.

Cost and latency should be measured against accepted outcomes. Include execution time, retries, reviewer effort, and any required rework. A fast first draft can be expensive if it takes hours to untangle. A slower but well-scoped patch may be the better operational result. Use actual receipts and provider reports rather than assuming a particular model or runner is universally free.

A worked example from issue to release

Imagine an import endpoint that accepts an empty customer identifier and creates an unusable record. The maintainer supplies a minimal request and explains that empty or whitespace-only identifiers should be rejected with the existing validation error format. The agent receives a source revision, the endpoint path, and the nearby test suite. It is authorized to prepare and publish the fix through the repository's normal release process.

The agent first reproduces the defect using the existing test harness. It finds that a shared schema checks the field's type but not its trimmed content. It proposes a narrow schema change and tests the empty string, whitespace-only input, and a valid identifier. It also checks whether trimming changes the stored identifier or only the validation decision, because those are different behaviors that callers may depend on.

The pull request contains the schema change, focused tests, and a description of the before-and-after behavior. It does not update unrelated dependencies or rewrite the endpoint. The validation receipt names the exact tested commit. A reviewer inspects the contract, confirms the error format, and checks that the test fails on the base revision. The repository's required checks then run against the integrated patch.

Before release, the operator confirms that no newer change invalidates the tested assumptions. The build artifact is associated with the accepted commit, and the deployment target is the intended environment. After deployment, a valid import succeeds and the two invalid requests return the expected error without creating records. The final receipt distinguishes source acceptance, deployment identity, and live behavioral verification.

If the live test cannot run, the report says that publication occurred but runtime verification remains incomplete. If deployment fails, the merged source can still be recorded as complete while production remains unchanged. The point of the workflow is not to force every stage into one green status. It is to make each stage observable and to keep the user's original problem at the center of the evidence.

A maintainer's final review worksheet

Before accepting a delegated result, identify the task contract, the source revision, the changed files, and the test that addresses the motivating behavior. Confirm that the agent did not broaden permissions, weaken checks, or alter release behavior without a relevant reason. Where a platform security control is cited, verify that it applies to the actual agent surface and workflow in use.

Before accepting a completion claim, identify the artifact that proves it. A branch, pull request, merged commit, deployment, and live check are separate artifacts. If the task ends at a draft, the draft is the deliverable. If the task includes production publication, the receipt needs to reach that destination and verify the requested behavior there. This distinction keeps collaboration honest without making it slow.

Exercise: review a plausible but insufficient patch

Create a small sample endpoint with a deliberate input-validation defect. Ask an agent to fix it, then review the result without looking at the agent's narrative first. Identify the changed condition and predict what happens for a valid value, an empty value, whitespace, a missing field, and a value of the wrong type. Compare those predictions with the new tests. This reveals whether the tests cover the contract or merely mirror the implementation.

Now introduce a second, intentionally inadequate patch that adds a validation helper but never calls it from the endpoint. Its helper tests can all pass. The exercise is to explain why the patch does not satisfy the original request despite a green test result. A useful review points to the missing connection between the public boundary and the new helper, then asks for a regression test through that boundary.

Next, create a patch that fixes the endpoint but also changes a workflow permission from read to write. The code behavior may be correct, yet the permission change still needs an independent justification. Practice writing a review comment that separates these findings. Accepting the functional fix does not require accepting an unrelated expansion of authority, and questioning the permission change does not invalidate the useful part of the implementation.

Finally, change the base branch while the agent's patch is waiting for review. Add a new caller that depends on the previous validation behavior. Reapply the patch and inspect the combined result. This demonstrates why mechanical merge success is weaker than compatibility evidence. The reviewer should identify which checks need to run again and which earlier results remain relevant.

Keep the exercise artifacts small enough that a maintainer can inspect every line. The purpose is to build a habit of tracing claims through source, tests, permissions, and release state. A large benchmark can be valuable later, but a compact example makes it difficult to hide behind aggregate pass rates. Each mistaken completion claim has a visible cause and a specific correction.

After the exercise, write a short acceptance record: what problem was solved, which revision was reviewed, what tests establish the behavior, and which unrelated changes were excluded. If deployment is part of the exercise, add a separate record for the deployed artifact and live check. The result is a reusable review pattern that applies to human-written and agent-written patches alike, without treating either source of code as automatically trustworthy.

An effective review culture also records why an apparently reasonable shortcut was rejected. A short note explaining that an endpoint test was required, or that a permission change was unrelated, helps the next task avoid repeating the same mistake. Keep those lessons specific to observed failures so they remain useful instead of becoming a growing list of vague prohibitions.

Sources and further reading

AI-assisted editorial disclosure: this article expands a local research draft and separates product-specific controls from original operational recommendations. The two agent-product overviews were checked on October 30, 2026. The example repository, test cases, evaluation plan, and release sequence are hypothetical and are not claims about a real customer incident or a completed Apiary deployment.

Frequently asked
What is GitHub Coding Agents: Delegation, Safe Outputs, and Review Gates about?
Delegating repository work to a coding agent changes who prepares the patch. It should not make the repository's definition of an acceptable patch disappear.…
What should you know about start with the unit of delegated work?
A good delegated task names a concrete problem and an observable result. “Improve this repository” gives an agent too much discretion and gives the reviewer no clear acceptance test. “Reject an empty customer identifier in the import endpoint and add a regression test for the existing failure” is easier to scope,…
What should you know about distinguish product controls from your own controls?
GitHub's Agentic Workflows overview documents read-only repository permissions by default, declared safe outputs for writes, firewalled execution, and checks on proposed outputs. It also describes compilation from a Markdown workflow to a lock file. Those are specific platform mechanisms. They do not establish the…
What should you know about build an evidence packet for the agent?
An agent works better when it receives the relevant source and constraints without a large amount of unrelated history. An evidence packet can include the issue, reproduction, current revision, affected paths, nearby tests, and the repository's local instructions. Keep raw logs and source references available so the…
What should you know about design permissions around the output?
An investigation that returns a report needs different permissions from an agent that opens a pull request. An automation that labels issues needs different permissions from one that modifies source files. Begin with the intended output and grant only the capabilities needed to produce it. This reduces both…
References & sources
  1. Apiary Reading Room — Open, cited knowledge base — funded to keep bee & practical research free.
From the Apiary Reading Room. Opinion & editorial — not financial advice. We don't overclaim.
More from the Reading Room