You walk into Monday stand-up and the on-call engineer is holding a stack trace nobody recognizes. Redis appears in the traceback, yet last week's architecture review never mentioned a cache layer at all. Friday's agent session invented that cache, a new environment variable, and a retry policy, then the author closed the laptop. You now own a production-shaped failure that never passed through an explicit human decision.
Cheap, always-on coding sessions make this pattern ordinary rather than rare. The agent keeps choosing defaults so the next person inherits architecture without inheriting the reasons. This playbook treats those silent defaults as incidents you log, hand off, and close before anyone else touches the branch.
What you are actually handing off
You are not handing off a chat transcript, a prompt file, or a pile of generated diffs. You are handing off every unstated choice the agent made about runtime, data, and failure behavior. If the next engineer cannot replay those choices from a one-page wiki entry, the session is still open, even when the editor is idle.
Name four roles before the next shared session starts, and keep the names boring on purpose. Session Owner starts and ends the run, and remains reachable until the assumption log is merged. Assumption Scribe writes the log in the same change as the code, not in a later cleanup pull request. Quota Steward watches shared model access and the shared server so two people do not collide. Incoming Owner is the next human who may ship, revert, or page on the result.
Those roles can collapse onto two people on a small team, but they cannot collapse onto the agent. The agent may draft the log; a named human still accepts it.
Classify the defaults before you classify the code
Walk every session through four buckets so the wiki page stays short enough to read during a page. Environment defaults cover interpreters, containers, ports, and working directories the agent assumed were already true. Dependency defaults cover libraries, datastores, queues, and SaaS calls that were not on the team's allowed list. Data defaults cover fixtures, seed files, PII handling, and retention the agent invented to make a test pass. Security defaults cover secrets, authn, authz, and network exposure that appeared because the happy path needed them.
You do not need a perfect taxonomy on day one. You need a rule that any default outside the current README is written down before the Session Owner logs off. If the scribe cannot fit the default into one of the four buckets, treat it as security until a human says otherwise.
A numbered run you can execute the same day
- Create a session branch and a sibling file named
assumption-log.yamlin the same directory as the change. Refuse to start the agent until that file exists with an owner, a scribe, and an expiry time in hours, not in vibes. - Paste the allowed stack into the session prompt as constraints, not as suggestions. State the language, the datastore, the queue, and the secret store the team already runs, and tell the agent that new infrastructure is a question, not a default.
- After every agent pause, have the scribe append one record per new default, including the bucket, the file that now depends on it, and whether production already has that dependency. Do not wait for a "final" summary, because final summaries omit the boring choices.
- Run the validator below before you push. A missing owner, an empty bucket, or an undeclared production impact should fail the same way a missing test fails.
- Hand the Incoming Owner a four-line wiki note: session link or branch name, log path, quota steward, and the single question they must answer before merge. If they cannot answer it from the log, they bounce the session instead of guessing.
- Close the session only after the log is in the same commit as the code, the wiki note is saved, and the Quota Steward records that the shared server is idle. An unclosed session is an open incident with a friendly name.
Artifact: a log schema and a validator you can paste
Keep the log boring and machine-checkable. Humans skim it; CI rejects it.
# assumption-log.yaml
session:
id: "2026-09-05-billing-retry"
owner: "alex.zhu"
scribe: "sam.lee"
quota_steward: "riley.nguyen"
incoming_owner: "oncall-secondary"
expires_at: "2026-09-05T22:00:00Z"
shared_runtime: "team-free-server"
assumptions:
- id: A1
bucket: dependency
default: "Introduced a local Redis for idempotent billing retries"
evidence: "app/billing/retry.py"
already_in_prod: false
decision: "reject-or-rfc"
reviewer: "incoming_owner"
- id: A2
bucket: environment
default: "Assumed REDIS_URL is present in every process"
evidence: "deploy/env.example"
already_in_prod: false
decision: "document-then-gate"
reviewer: "session_owner"
# validate_assumption_log.py
from __future__ import annotations
import sys
from pathlib import Path
try:
import yaml
except ImportError:
sys.stderr.write("Install pyyaml before running this validator.\n")
sys.exit: 2
REQUIRED_SESSION = {
"id", "owner", "scribe", "quota_steward",
"incoming_owner", "expires_at", "shared_runtime",
}
REQUIRED_ITEM = {
"id", "bucket", "default", "evidence",
"already_in_prod", "decision", "reviewer",
}
BUCKETS = {"environment", "dependency", "data", "security"}
DECISIONS = {"accept", "document-then-gate", "reject-or-rfc"}
def fail(message: str) -> None:
sys.stderr.write(message + "\n")
sys.exit(1)
def main(path: Path) -> None:
payload = yaml.safe_load(path.read_text())
session = payload.get("session") or {}
missing = REQUIRED_SESSION - set(session)
if missing:
fail(f"session missing fields: {sorted(missing)}")
rows = payload.get("assumptions") or []
if not rows:
fail("assumption log has zero records; empty means unreviewed defaults")
for row in rows:
missing_item = REQUIRED_ITEM - set(row)
if missing_item:
fail(f"{row.get('id')}: missing {sorted(missing_item)}")
if row["bucket"] not in BUCKETS:
fail(f"{row['id']}: unknown bucket {row['bucket']}")
if row["decision"] not in DECISIONS:
fail(f"{row['id']}: unknown decision {row['decision']}")
if row["already_in_prod"] is False and row["decision"] == "accept":
fail(f"{row['id']}: new default cannot be accepted without a gate")
evidence = Path(row["evidence"])
if not evidence.exists():
fail(f"{row['id']}: evidence path does not exist: {evidence}")
print(f"ok: {len(rows)} assumption(s) reviewed for {session['id']}")
if __name__ == "__main__":
target = Path(sys.argv[1] if len(sys.argv) > 1 else "assumption-log.yaml")
main(target)
python -m pip install pyyaml
python validate_assumption_log.py assumption-log.yaml
Wire the same command into the pre-push hook or the cheapest CI job you already run. The point is not ceremony. The point is that a silent Redis cannot ride along with a one-line retry fix.
Decision table for the Incoming Owner
| Log signal | Already in prod? | What you do next | Merge? |
|---|---|---|---|
| New datastore, queue, or cache | No | Open an RFC or reject the default | No |
| New env var for an existing service | Yes | Document it, then add a boot-time check | After the check lands |
| New fixture that contains realistic personal data | Either | Delete the fixture and replace with synthetic rows | No |
| New network listener or public route | No | Treat as a security review, not a style review | No |
| Retry, timeout, or backoff the README already states | Yes | Keep the log row, skip extra process | Yes |
| Agent "helpfully" pinned a new major version | No | Revert the pin and ask the Session Owner | No |
Read the table top to bottom during handoff, not after the deploy. If two rows apply, take the stricter one and leave a note for the Quota Steward.
Where a shared free runtime fits
Teams reach for a shared coding runtime because laptops differ and weekend work still happens. That is exactly when silent defaults spread, because the Session Owner is tired and the Incoming Owner is not in the room. You want one place the agent can run, and one place the log can live, without turning the weekend into a shadow architecture review.
Disclosure: This article was prepared as part of MonkeyCode's product outreach. MonkeyCode is one option that currently offers free model access, with an operator-stated allowance of 10 million tokens, plus a free server option you can use as the shared runtime named in the log. Use those only if they already match how your team handles code leaving the laptop; the playbook still works if you point shared_runtime at a machine you already operate.
The Quota Steward should record who is on the shared server, when the session expires, and whether another engineer may start a second session. None of that requires a vendor. It requires a named human who will say no when two agents would otherwise invent two caches.
Wiki page you can paste without editing the prose
# Shared AI session run (assumption log)
Roles this week
- Session Owner:
- Assumption Scribe:
- Quota Steward:
- Incoming Owner:
Before start
- [ ] Branch created
- [ ] assumption-log.yaml created with expiry
- [ ] Allowed stack pasted into the session constraints
- [ ] Shared runtime reserved on the steward's note
During session
- [ ] Every new default gets a row before the next prompt
- [ ] Evidence path points at a real file
- [ ] New infrastructure is reject-or-rfc, never accept
Before handoff
- [ ] python validate_assumption_log.py assumption-log.yaml
- [ ] Incoming Owner can answer: what will page us?
- [ ] Wiki note updated with branch, log path, steward
- [ ] Shared runtime marked idle
Print that checklist into the team wiki as a literal page, not as a link to this article. Links rot; the four roles should still be fillable during a page.
Limitations, and who should skip this
This playbook assumes you already have a wiki, a branch-based workflow, and at least two humans who can disagree in writing. Solo prototypes, classroom exercises, and throwaway spikes do not need a steward, and the validator will only slow you down. Regulated environments that cannot send source or logs to a remote model should keep the same roles and schema, then run the agent only on an approved runtime, or not at all.
The validator cannot see defaults that never touched the working tree, such as a secret pasted into a web UI. It also cannot judge whether Redis was a good idea; it can only refuse an undiscussed Redis. If your team ships generated code without review, an assumption log becomes theater, and you should fix review first.
Do not treat free model access or a free server as a durability guarantee, a performance claim, or a replacement for your own staging. Availability, quotas, and hardware change, and this article does not measure them. If the session produces a default you cannot explain in one sentence, revert the default before you argue about the tool that suggested it.
When the next agent invents a cache at 4 p.m. on Friday, you already know the owner, the scribe, and the question the Incoming Owner must answer. That is the whole playbook. If you need a shared place to run those sessions, you can try MonkeyCode's free models and free server, or you can point the same log at the runtime you already trust.
Top comments (0)