Safe agent-assisted change delivery / Field essay 50

Let a business operator request a site change without handing AI a deploy token.

A non-engineer can request a bounded change without becoming a proxy for unchecked code. Run generation without network or deployment credentials, enforce an exact file boundary, build and review a pinned artifact, and promote through a separate trusted deploy authority.

Published

SAFE AI-ASSISTED SITE CHANGES AND ARTIFACT PROMOTION
FIELD ESSAY 50 / SAFE AGENT-ASSISTED CHANGE DELIVERY

Let a business operator request a site change without handing AI a deploy token

A business operator should be able to request a small website change without receiving a deployment credential or becoming a proxy for unchecked code. Our first design put generated source and the deploy token in the same build environment. Independent review showed how a file could reach a broad credential before anyone approved the result. That changed the architecture: untrusted code builds in a sealed environment, while a separate pinned deploy tool receives only the resulting artifact.

Split generation from deployment authority

The model needs to produce a patch. It does not need the credential that can publish it. I moved build and test into a sandbox with no network, a fresh home directory and no deployment keys. The package cache is available offline, so dependency installation does not require opening the network boundary. Model inference goes through a separate gateway rather than placing a provider key inside the build environment.

A small deploy service holds the credential. It accepts a built artifact, validates the requested target and publishes only that artifact. Staging and production use separate authority. The person requesting the change can inspect staging and choose Promote or Undo; the build process cannot promote itself. The deploy credential is not exposed to the model, compiler, test process or package scripts.

This separation matters because a build is code execution. A malicious file can run during install, build or test, long before a person reviews a preview. If those processes share a user, home folder or environment variables with deployment, a review button later in the workflow cannot protect the credential earlier in the workflow.

Treat the plan as a file boundary

The operator describes a change in ordinary language. The system converts it to a narrow plan: which files may change, which checks run and which target is allowed. The agent can propose edits only inside that scope. If it adds a file outside the allowlist, the build stops and asks for a new decision rather than silently broadening its task.

A plan is useful only if the executor checks exact paths at each step. Symlinks can make a path that looks contained resolve outside the intended root. The runner must open files safely, reject traversal and ensure the final artifact includes only approved outputs. An independent reviewer found that a link could make the runner overwrite a file outside its sandbox even though the happy-path test passed. We fixed the path boundary and reran review before merging.

That review also taught me not to treat a model’s first verdict as a permanent property of the change. A later adversarial case changed the verdict. The right response was to reproduce the finding, add a concrete test and preserve both observations—not to average the reviews or prefer the earlier pass.

Bound each step and make runs recoverable

The first real run exposed another failure: a test command started one worker per CPU and exhausted the runner’s memory cap. The kernel killed the runner, but the job remained marked in progress until a timeout. We had isolated credentials, yet the workflow was still operationally unsafe because a dead process looked live and could hold resources indefinitely.

I added resource limits per build step, so one runaway test cannot take down the whole runner. Each step has a clear time, memory and CPU budget; failure returns the step name, exit status and useful output tail. The runner releases claims on restart, sweeps stale jobs and records a terminal result instead of leaving a ghost “running” state. These are not cosmetic reliability features. They determine whether an operator can understand what happened and safely retry.

Undo is a first-class operation too. Staging changes are tied to a commit so rollback can restore the prior version. Production promotion requires a separate human decision and uses the same pinned deploy route. A preview is not enough if the system cannot say exactly which artifact it built and which version it is serving.

Keep the human decision meaningful

The person should not need to approve every low-level command. The system can enforce the plan, build the artifact, run the site’s checks and show a preview. The operator decides whether the requested change is right for users and whether it should be promoted. If the system detects a sensitive path, expands the plan, loses run state or cannot establish which artifact is being deployed, it stops with a specific reason.

I use this checklist for an AI-assisted site change: generated code has no deployment credential; the build has no network; dependencies come from a controlled cache; the plan limits writable paths; symlinks cannot escape the workspace; staging and production authority differ; every step has resource limits; restarts yield a recoverable job state; and promotion and undo point to a pinned artifact.

That design lets a non-engineer ask for a change while keeping authority in the system that understands the deployment boundary. The question I ask before shipping is not “Did the model make the edit?” It is “Can this exact workflow prove what changed, what it could access and which version the operator is approving?” How does your deployment path keep generated code away from the credential that publishes it?

Make the artifact the handoff contract

I want each build step to produce a bounded set of files and a manifest that identifies them. The deploy service should accept those artifacts, verify the manifest and target, and reject paths or symlinks that resolve outside the approved root. It should not execute build scripts or install dependencies. The preview should show the content and the exact revision that produced it, while the production route should report the same revision after promotion.

The run state needs a durable owner and lease. If a worker disappears, another process can determine whether the step completed, release the stale claim and mark the run failed or recoverable. Avoid leaving an in-progress row until a broad timeout expires. Return the failed step, exit code and a bounded output tail so a non-engineer can decide whether to request a correction or ask for help.

Finally, test the boundaries with adversarial artifacts: a symlink outside the root, a path with traversal, an unexpected file, an install script that attempts network access, and a test process that exceeds its resource cap. Each should stop at the layer responsible for it. The person should be reviewing the desired website change, not guessing whether a hidden build process saw a credential. Which artifact does your deployment service trust, and how does it prove that is the one the operator reviewed?

Promote an artifact, not an agent workspace

A safe deployment pipeline turns generated changes into a reviewable artifact before deployment authority enters the path. The build output should be immutable and identified by a digest; the operator approves that digest, not a moving branch or mutable directory. The deployer then accepts only the approved artifact and the intended environment. That makes the boundary inspectable even if the source workspace changes afterward.

I also keep failure and recovery behavior explicit. A build can be retried without credentials; a deployment retry must first read the current release identity and determine whether the previous attempt took effect. If the answer is unknown, do not blindly repeat a side effect. The system should surface the run, artifact, target environment and last durable stage, then ask for the next authorized action. That lets a non-engineer request work without becoming responsible for interpreting shell output.

The human review is about the user-visible change and the promotion decision, not about granting the generator more privileges. A reviewer should see a preview, a bounded diff and the exact artifact identity. Rollback should name the previous known release and be available through a separate controlled path. The operational goal is not “AI can deploy a site”; it is “a small site change has a traceable request, constrained build, reviewed artifact, explicit promotion and recoverable release.”

How this was verified

I checked the pinned implementation and runtime-fix receipts in the source packet. I omit project names and unpinned test totals.

CONNECTED READINGForward and back
Keep reading

The answer deserves
another experiment.

Back to the journal