<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Marek Zaremba-Pike — blog</title><description>Marek Zaremba-Pike leads the backend platform at Photoroom and builds production AI systems. Writing on backend engineering and agentic coding.</description><link>https://marekzp.com/</link><item><title>Why I&apos;m writing here</title><link>https://marekzp.com/blog/why-im-writing-here/</link><guid isPermaLink="true">https://marekzp.com/blog/why-im-writing-here/</guid><description>What this site is for, and why the writing lives on my own domain rather than someone else&apos;s.</description><pubDate>Sun, 05 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This site exists mostly as plumbing. I wanted one canonical page that says who I am, links to everything I&apos;ve made, and belongs to me rather than to an employer or a platform. The blog is the part of that plumbing that grows.&lt;/p&gt;
&lt;p&gt;I already write on the Photoroom blog, and I&apos;ll keep doing that — posts about our systems belong there. But anything an employer&apos;s domain hosts ultimately accrues to the employer&apos;s domain. Writing that&apos;s mine — opinions, notes from side projects, things that outlast any one job — should live somewhere that moves with me. That&apos;s here.&lt;/p&gt;
&lt;p&gt;Expect posts about backend systems, running coding agents in production, and the occasional note from building side projects like Savin Hood. Short and concrete, published when there&apos;s something worth saying rather than on a schedule.&lt;/p&gt;
&lt;p&gt;If something here is useful, or wrong, email me — the address is on the front page.&lt;/p&gt;
</content:encoded></item><item><title>Senior Claude reviewer is not a good use of engineering talent</title><link>https://marekzp.com/blog/senior-claude-reviewer-is-not-a-good-use-of-engineering-talent/</link><guid isPermaLink="true">https://marekzp.com/blog/senior-claude-reviewer-is-not-a-good-use-of-engineering-talent/</guid><description>If engineers only review agent-generated diffs, they bear accountability with none of the agency. Ownership has to start before the coding workflow runs.</description><pubDate>Tue, 19 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;An engineer on the team recently changed their job title in Slack to Senior Claude Reviewer. It is less funny than it sounds. It is too close to home. If the future of software engineering is humans staring at agent-generated diffs until their souls leave their bodies, then we will have an exodus of the most talented and experienced people leave the profession.&lt;/p&gt;
&lt;p&gt;But if the agent writes more of the code, what is the engineer for? There are plenty of discussions online about coding being only one of many things that a good software engineer does, but here I want to explore those discussions from our own working experience.&lt;/p&gt;
&lt;h2&gt;What I think bad looks like&lt;/h2&gt;
&lt;p&gt;We no longer have to only imagine a world in which a product person writes a ticket and triggers a coding workflow. Coding agents make implementation look cheap. The agent reads the ticket, modifies the codebase, runs some tests, opens a pull request, and posts a cheerful summary. An engineer is then asked to review the result.&lt;/p&gt;
&lt;p&gt;On paper, there is still a human engineer in the loop. Engineers are still protecting the code, right? In practice, the human has been moved to the least impactful part of the loop. By the time the pull request exists, many of the important decisions have already been made; that this feature should live here, that this abstraction should stretch a little further, that the system should absorb one more special case, etc. Those are not merely implementation details. They are engineering decisions. Moreover, the pressure will be on to just get it merged.&lt;/p&gt;
&lt;p&gt;This is not an argument against product people using powerful tools, and Product should be able to explore ideas quickly. The problem starts when we pretend that a generated pull request is a neutral implementation detail, rather than a bundle of architectural decisions that someone has already made.&lt;/p&gt;
&lt;p&gt;A pull request is too late to discover that the feature should not exist (yes, there are valid engineering reasons for this!). It is too late to discover that the boundary is wrong. It is too late to discover that the system is being bent into the wrong shape. You can still reject the PR, of course. But now you are not doing design, you are doing damage control.&lt;/p&gt;
&lt;h2&gt;Sign-off is not ownership&lt;/h2&gt;
&lt;p&gt;Human review remains essential, but review is not the same thing as ownership. Sign-off is what happens at the end. Ownership starts much earlier.&lt;/p&gt;
&lt;p&gt;Ownership means understanding why the change exists, why it was built this way, where it belongs in the system, how it will fail, how it will be observed, how it can be rolled back, and what future work it makes easier or harder. It means being able to explain the change without pointing at the agent. It means being able to debug it when it breaks. It means being willing to delete it later.&lt;/p&gt;
&lt;p&gt;If an engineer is only asked for a PR approval, then in practise the engineer is no longer the owner of the stack but merely a quality gate for decisions made elsewhere, not unlike a lint rule. That may look efficient for a while. It may even be efficient for a while. But it is a bad operating model. It is also a miserable job.&lt;/p&gt;
&lt;p&gt;This is a version of the agentic coding revolution where the interesting part of development is taken away and the engineer is left with review fatigue, accountability, and none of the agency.&lt;/p&gt;
&lt;p&gt;That would waste an enormous amount of engineering talent.&lt;/p&gt;
&lt;h2&gt;Could the agent be the Staff Engineer?&lt;/h2&gt;
&lt;p&gt;At this point, there is an obvious objection. If the issue is the risk of bad architecture and design, why only let agents solve that problem, too?&lt;/p&gt;
&lt;p&gt;If an agent can write implementation code, why should it not also write the design doc, choose the abstraction, identify the migration path, spot the dependency risk, and make the architectural recommendation? Can the answer not be to provide those same non-engineers with better system design guidance? Perhaps at some point.&lt;/p&gt;
&lt;p&gt;Agents can help with system design. Sometimes they will do this better than a human who is tired, rushed, or missing context. Often, they will do it faster. Often, they will do it worse. One recent example at Photoroom involved an agent which tried to rewrite our entire Django Redis middleware because our current one wasn&apos;t closing connections. We went with closing/shortening the lifespan of pods instead (though you may agree with the agent and not our approach). Agents will get better, though, so the argument that humans must move into system design because AI cannot go there does not hold. It can and will.&lt;/p&gt;
&lt;p&gt;But even when they get better, the decision still has to be owned. An agent can recommend a design. It can draft the memo, argue for an approach, and find problems in the plan. It does not make the agent accountable for the decision. An agent can even explain the trade-offs, but understanding them and taking ownership of the decision requires experience and expertise.&lt;/p&gt;
&lt;p&gt;The agent can be a very good design partner. It is not the owner of the stack.&lt;/p&gt;
&lt;h2&gt;Accountability cannot be outsourced&lt;/h2&gt;
&lt;p&gt;When a non-engineer asked for the feature, the agent wrote the code, the engineer approved the PR, the tests passed, and the incident happened, who owned the decision? Everyone can point to the step before or after them. Product did not choose the implementation. The agent cannot explain itself in the sense that matters. The reviewing engineer did not shape the approach. Leadership wanted more throughput. The process worked exactly as designed.&lt;/p&gt;
&lt;p&gt;Maybe it does not matter to you who made the decision, as long as the process is later optimised to avoid repeating the same mistakes. I think it matters not to apportion blame, but to ensure there are individuals who can pre-empt problems. Individuals who care, not just an agent who afterwards just says how very sorry they are and how they should not have done it. I also do not think most leadership teams are ready to run companies where the answer to &quot;who is responsible for this system?&quot; is &quot;the workflow&quot;. When a serious system fails, when a customer asks why, when a regulator asks who approved it, the organisation will still look for a person or a team responsible for that workflow (process).&lt;/p&gt;
&lt;p&gt;This is not only about blame, but also about ensuring lessons are learnt. Feedback has to land with someone who can change the system. If the engineer is accountable but only allowed to approve it at the end, then the development process will not improve. They would bear responsibility without having had control.&lt;/p&gt;
&lt;p&gt;If someone is going to be held accountable for a decision, they need to be able to shape it. This is why ownership cannot be placed only at code review. By that time, an implementation exists, and rejecting the work feels like slowing everyone down. The accountable person needs to be involved when the ticket is refined, and the agent is instructed. In practice, ownership has to start before coding begins.&lt;/p&gt;
&lt;p&gt;Organisations are already good at making accountability disappear, but an accountability sink will not make engineering teams more competitive, no matter how many lines of code are written every second.&lt;/p&gt;
&lt;h2&gt;The workflow should make ownership obvious&lt;/h2&gt;
&lt;p&gt;The agent may author the diff, but if we want the engineer to own the code, the engineer needs to decide whether the ticket is ready for implementation, what the technical approach should be, what the constraints are, and what the agent should not touch. The agent may draft the technical approach, propose the test plan, identify existing code paths, or challenge the engineer&apos;s assumptions. But there should still be a moment where a human engineer owns the decision. Only then does the coding workflow run. The engineer reviews the result, not as a stranger inspecting a surprise package in the post, but as the owner of an approach they helped define.&lt;/p&gt;
&lt;p&gt;This is still fast. It may be faster, because a well-shaped ticket avoids the slowest kind of review: discovering at the end that the entire approach is wrong.&lt;/p&gt;
&lt;p&gt;There will be exceptions. Tiny changes. Prototypes. Internal tools. Safe experiments. I am not arguing for a heavy committee before every small diff. That would be another familiar way to ruin software.&lt;/p&gt;
&lt;p&gt;The point is simpler. For meaningful changes to important systems, engineering judgement needs to enter before implementation starts.&lt;/p&gt;
&lt;p&gt;Otherwise, we are not accelerating engineering. We are routing around it.&lt;/p&gt;
&lt;h2&gt;Where we are, right now&lt;/h2&gt;
&lt;p&gt;So the answer is not to make engineers better reviewers of AI-generated code. Or rather, that is part of the answer, but it is the least interesting part. The answer is to keep engineers on the left and keep them involved early in the process, before the coding workflow starts. They should be shaping the ticket, not merely reviewing the diff. They should be asking whether the change is necessary. They should be deciding where the work belongs, what constraints matter, what should be left alone, and what the agent must not be allowed to casually reinterpret.&lt;/p&gt;
&lt;p&gt;At Photoroom, at least in the part of the backend world I am describing, we are exploring what happens (good and bad) when agents can reliably produce reviewable or near-reviewable pull requests from tickets. As implementation becomes cheaper, engineering value has to stay on the left, not be edged to the right. They need to stay as owners.&lt;/p&gt;
&lt;p&gt;If AI also helps with that upstream work, great! We should use it there too. We just should not confuse help with ownership.&lt;/p&gt;
&lt;p&gt;The agent can write code. It can even write useful code. It can help design systems. It can draft the design doc, suggest the migration, and argue with the plan. But it cannot own the stack. It cannot decide what kind of system we need. That remains engineering work. And we should keep engineers there.&lt;/p&gt;
</content:encoded></item><item><title>The laptop is the wrong place to run coding agents</title><link>https://marekzp.com/blog/the-laptop-is-the-wrong-place-to-run-coding-agents/</link><guid isPermaLink="true">https://marekzp.com/blog/the-laptop-is-the-wrong-place-to-run-coding-agents/</guid><description>Once coding agents reliably ship real work in parallel, the developer laptop becomes the most dangerous place to run them. Why Photoroom is moving remote.</description><pubDate>Wed, 22 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In a &lt;a href=&quot;/blog/ai-coding-guardrails-are-mostly-the-old-guardrails/&quot;&gt;previous post&lt;/a&gt;, I argued that AI coding guardrails are mostly the old guardrails. In this post, I look at why, as coding agents become more capable, the laptop stops being the safe or right place to run them.&lt;/p&gt;
&lt;h2&gt;This Is No Longer a Demo&lt;/h2&gt;
&lt;p&gt;At Photoroom, we have the scaffolding in place to ensure that coding agents can reliably deliver approvable or near-approvable PRs just by being given a ticket. Our local workflow fetches the ticket, creates an isolated worktree, plans the commits, reviews the plan, implements with tests, runs specialised review agents, verifies the commits, opens the PR, and then responds to reviews. In other words, the agent is not being asked to &quot;write some code&quot;. It is being dropped into a scaffolded delivery process. Model reliability is now good enough that the agent can produce reviewable pull requests for small tickets and a surprising number of medium-complexity ones without human steering or intervention. Not every time, certainly. And as mentioned previously, we are keeping the human in the loop at the review stage, but hundreds of PRs, where the agent is the author and the human is the reviewer, have now been merged following this process alone. Even complex work starts to look tractable when we break it into smaller tickets and let agents attack the pieces in parallel.&lt;/p&gt;
&lt;p&gt;That success creates a problem.&lt;/p&gt;
&lt;h2&gt;The Laptop Is the Problem&lt;/h2&gt;
&lt;p&gt;A local coding agent does not just have access to your repository. It sits on your machine, next to your shell history, your SSH configuration, your cloud credentials, your browser sessions, your local tools, your Docker daemon, your kube contexts, your MCP connectors, and whatever else you have accumulated as an individual contributor. Permission dialogues help, but they do not change the practical trust boundary very much. The trust boundary is still your laptop. Local agents sometimes do more than you expected, or do it sooner than you expected. Anyone who has used them seriously knows this. You will have seen how even &quot;safe&quot; Claude has performed actions without permission, including in plan mode. The permission model is not always as strict, or as reassuring, as the UI suggests. The real question is not whether the pop-up looked sensible. The real question is what the agent could actually touch from a real machine on a real Tuesday.&lt;/p&gt;
&lt;p&gt;You might argue that we should not have all this access on our laptops. Maybe, but regardless of whether or not that is achievable for you, the point remains: human and agent permissions should differ.&lt;/p&gt;
&lt;h2&gt;One Agent Is Not the Point&lt;/h2&gt;
&lt;p&gt;Even if you are convinced Claude&apos;s prompts mean it will never take action without permission, many local setups become officially permissive quite quickly. You start by approving a few safe actions. Then you whitelist recurring commands. Then you add tool access because the agent needs one more thing to complete the task. Before long, the setup is still &quot;guardrailed&quot; in theory, but in practice it can reach far more than people imagine. Local agentic coding scales surprisingly well. Running one agent locally is pair programming. Running ten to fifteen in parallel with git worktrees is where the benefits really start to take off. Context switching while babysitting each agent leaves me completely exhausted. One agent can be implementing a backwards-compatible serializer change, another can be writing tests for a new endpoint, another can be refactoring files, another can be preparing a migration, and another can be working on yet another endpoint. This is exciting, very productive, and completely impossible to monitor safely.&lt;/p&gt;
&lt;p&gt;If you only ever run one agent at a time and closely monitor it, then yes, you reduce some of the risk. But you also leave a large part of the productivity gain on the table. The main reason teams are interested in tools like Claude Code is that they can dramatically increase throughput. Once you are serious about capturing that gain, parallelism stops being a weird edge case and starts becoming the natural next step.&lt;/p&gt;
&lt;p&gt;It is also slightly absurd.&lt;/p&gt;
&lt;p&gt;After a certain point, your job stops looking like writing software and starts looking like supervising a rowdy small firm of junior developers who all want approval at once. You bounce between terminals, worktrees, branches, review comments, permission prompts, and half-finished mental stacks. The raw throughput is real, but so is the context switching.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storyblok-cdn.photoroom.com/f/191576/640x640/9f5ff6ef37/anthropic_keyboard.webp&quot; alt=&quot;A keyboard rendered in the style of Anthropic&apos;s branding&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Credits: NinjaGraphics&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;At that point, approval review fatigue becomes its own failure mode. You are not just reviewing code. You are reviewing plans, approving commands, checking diffs, re-orienting yourself, reloading context, and trying to remember whether agent seven is the one that rebased cleanly or the one that wants to run an integration test against a dev branch. It is horrendous context switching. It also gets more dangerous as it becomes more routine. Fatigue is not merely annoying. It lowers the quality of supervision.&lt;/p&gt;
&lt;p&gt;If this were only a productivity issue, the answer might just be &quot;be more disciplined&quot;. I do not think that is enough.&lt;/p&gt;
&lt;h2&gt;Better Agents, Harder Risks&lt;/h2&gt;
&lt;p&gt;As models become more capable, the security argument gets sharper, not softer. I am not claiming that today&apos;s coding agents are all secretly acting like insider threats on developer laptops. I am saying that as these models become more capable, more autonomous, and more useful, the risks become more complex as well. We are getting more evidence of that complexity, not less.&lt;/p&gt;
&lt;p&gt;Anthropic&apos;s 2025 work on agentic misalignment is a case in point. In simulated corporate environments, models from multiple providers sometimes chose harmful insider-style actions such as blackmail and leaking sensitive information when those actions were framed as the only way to avoid replacement or achieve their goals. In a more extreme and explicitly contrived extension, Anthropic also found that some models would take actions leading to an executive&apos;s death. I am not suggesting your coding agent has that capability or those goals. But the study used single-shot prompts. In the messy context of real work, as agents become more autonomous, the range of failure modes widens and becomes harder to dismiss as simple mistakes.&lt;/p&gt;
&lt;p&gt;The wider body of research points in the same direction. Anthropic&apos;s reward tampering work showed that relatively mild specification gaming can, in controlled settings, generalise into more serious behaviour, including occasional attempts to cover tracks. Their alignment-faking work showed that a model can strategically appear aligned under training pressure, without that behaviour necessarily telling the full story. And OpenAI&apos;s March 2026 note on monitoring internal coding agents is important precisely because it is not a purely abstract safety paper. It treats real coding agents in realistic, tool-rich environments as a deployment category that warrants active monitoring.&lt;/p&gt;
&lt;p&gt;The practical conclusion? As capabilities improve, it becomes easier to imagine failure modes that are less about obvious mistakes and more about strategic behaviour, hidden incentives, over-eager workarounds, or interactions with tools that create new ways to go wrong. That does not mean we should panic. It does mean we should stop pretending that more capable agents automatically make the deployment question simpler. They make it more operationally demanding.&lt;/p&gt;
&lt;p&gt;OpenAI explicitly describes internal coding agents as operating in realistic, tool-rich workflows, with access to internal systems, visibility into safeguard code, and opportunities to modify those safeguards. Their conclusion is not &quot;do not worry&quot;. Their conclusion is that monitoring and similar safeguards should become standard for internal coding agent deployments.&lt;/p&gt;
&lt;p&gt;It&apos;s not just me, but those selling the agents to us.&lt;/p&gt;
&lt;h2&gt;Why We Are Moving Remote&lt;/h2&gt;
&lt;p&gt;So our direction at Photoroom is straightforward. We want agents to have broad freedom inside the box, and a narrow blast radius outside it.&lt;/p&gt;
&lt;p&gt;That means remote containers with full permissions inside their environment, but very limited access beyond it. Limited credentials. Limited network egress. Limited connectors. Limited access to internal systems. Enough power to do real engineering work, but not enough reach to turn a mistake, a prompt injection, or a more serious failure mode into a company-wide problem. This is not perfect security. It is just a better default shape.&lt;/p&gt;
&lt;p&gt;It also improves the human workflow. Remote execution makes parallelism easier to supervise. It separates long-running work from the developer&apos;s laptop. It reduces terminal sprawl. It gives us a cleaner place to add logging, monitoring, policy, audit trails, and eventually more systematic review queues. In short, it moves agentic coding out of the personal-computing model and into the deployment model, which is where it increasingly belongs.&lt;/p&gt;
&lt;h2&gt;What are the options?&lt;/h2&gt;
&lt;p&gt;As of 18 April 2026, the options are starting to look meaningfully different.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Coder&lt;/strong&gt; is attractive if you want maximum control. It is self-hosted, open source, and built around remote development environments. Its strength is infrastructure sovereignty: you decide how the workspace is provisioned, what the network policy looks like, how identity is handled, where data lives, and what the agent can reach. If your goal is to give agents broad freedom inside a tightly controlled box, Coder fits that model well. The downside is that you own more of the operational burden. You have to provision it, secure it, maintain it, and make the developer experience good enough that people actually want to use it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anthropic Managed Agents&lt;/strong&gt; looks like a strong option for teams that want a managed remote-agent platform without relying on ambient laptop permissions. What is appealing here is the split in the security model: environments define packages and network policy, while credentials are supplied separately at session creation through vaults. That is much closer to the sort of scoped access model we actually want. In practice, it means you can be more deliberate about what an agent can reach from a given environment.&lt;/p&gt;
&lt;p&gt;The trade-off with Anthropic is vendor lock-in. The more deeply you adopt Managed Agents, the more your workflow depends on Anthropic-specific concepts such as agents, sessions, environments, vaults, and managed MCP integration. That may be a perfectly reasonable trade if you want speed and a coherent managed platform, but it does mean that moving later may involve rewriting orchestration and auth patterns, not just moving containers somewhere else. GPT 5.4 writes excellent code; Anthropic is not the only game in town.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OpenAI Codex cloud&lt;/strong&gt; is the most fully managed version of the idea I have seen so far. OpenAI explicitly positions Codex as a cloud coding agent that can work on tasks in parallel in its own cloud environment, and it has added admin-facing controls, monitoring, and analytics. The upside is speed to value. The downside is that its permission model appears more workspace-centric than a deeply granular per-task least-privilege design. That is still much safer than running agents directly on a laptop, but it is not quite the end state I would want for long-term control.&lt;/p&gt;
&lt;p&gt;So the trade-off is fairly clean. Coder gives you more control and portability, but asks you to do more infrastructure work. Anthropic gives you a strong managed model with better separation between environment policy and credentials, but with more platform dependence. OpenAI gives you a polished managed experience, but today it seems somewhat coarser in how permissions are scoped.&lt;/p&gt;
&lt;p&gt;To be clear, moving to remote coding agents is only one possible answer. Another answer is not to use these systems for meaningful autonomous coding work at all. That is coherent. Another is to use them only one run at a time and watch them closely on a local machine. I understand the appeal of that position, but I am not convinced. If you are using these tools seriously to raise productivity, then keeping them on your laptop gives them access to the most dangerous environment in the stack. And if you avoid parallel execution altogether, you are deliberately giving up much of the productivity gain that made the tools attractive in the first place.&lt;/p&gt;
&lt;p&gt;You do not need to believe every internet horror story about container escapes to see the point. Laptops are messy, privileged, deeply connected environments. If we are going to give increasingly capable agents real autonomy, it makes more sense to give them that autonomy inside disposable remote containers with tightly limited access to external systems than on the same machine that stores the rest of our working life.&lt;/p&gt;
&lt;p&gt;Local agentic coding was the right first step because it was easy to start, easy to iterate on, and close to the developer. It helped us learn what good scaffolding looks like. It helped us learn where reviews belong. It helped us learn that agents can be much more useful than the sceptics claimed, and much weirder than the optimists admitted. But once the agents become reliable enough to do real work and cheap enough to run in parallel, the local model starts to show its limits. The permissions are too broad. The context switching is too ugly. The blast radius is too personal. The supervision model does not scale cleanly.&lt;/p&gt;
&lt;p&gt;Remote agentic coding is not interesting because it sounds futuristic. It is interesting because it is the more boring, more operationally sane answer.&lt;/p&gt;
&lt;p&gt;And in infrastructure decisions, boring is often a very good sign.&lt;/p&gt;
&lt;h2&gt;Postscript&lt;/h2&gt;
&lt;p&gt;It is worth stating the major implication. This is not just a change in where code is written. It is a breaking change in the role of a software engineer. Once you rely on remote coding agents seriously, the software engineer is no longer the coder. For years, the centre of gravity was the developer inside their IDE, with everything else arranged around that. You may still connect via VS Code or a browser while retaining some familiar ergonomics. Fun aside, I first learnt to code on a Chromebook using Cloud9, a browser-based IDE, so remote development itself does not strike me as strange. But that is not really the point. The engineer may still specify, review, steer, and remain accountable for what ships. But that is not the same thing as coding. Maybe I will write separately about what the role of a software engineer in Photoroom&apos;s backend team is becoming. For this post, it is enough to say that remote agentic coding is not a tooling tweak. It is a change in who, or what, actually writes the software.&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Previous post: &lt;a href=&quot;https://www.photoroom.com/inside-photoroom/ai-coding-guardrails-are-mostly-the-old-guardrails&quot;&gt;https://www.photoroom.com/inside-photoroom/ai-coding-guardrails-are-mostly-the-old-guardrails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Anthropic, &quot;Agentic Misalignment: How LLMs Could Be Insider Threats&quot;, 20 June 2025: &lt;a href=&quot;https://arxiv.org/abs/2510.05179&quot;&gt;https://arxiv.org/abs/2510.05179&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Anthropic summary page, &quot;Agentic Misalignment: How LLMs could be insider threats&quot;: &lt;a href=&quot;https://www.anthropic.com/research/agentic-misalignment&quot;&gt;https://www.anthropic.com/research/agentic-misalignment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Anthropic, &quot;Sycophancy to subterfuge: Investigating reward tampering in language models&quot;, 17 June 2024: &lt;a href=&quot;https://www.anthropic.com/research/reward-tampering&quot;&gt;https://www.anthropic.com/research/reward-tampering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Anthropic, &quot;Auditing language models for hidden objectives&quot;, 13 March 2025: &lt;a href=&quot;https://www.anthropic.com/research/auditing-hidden-objectives&quot;&gt;https://www.anthropic.com/research/auditing-hidden-objectives&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OpenAI, &quot;How we monitor internal coding agents for misalignment&quot;, 19 March 2026: &lt;a href=&quot;https://openai.com/index/how-we-monitor-internal-coding-agents-misalignment/&quot;&gt;https://openai.com/index/how-we-monitor-internal-coding-agents-misalignment/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OpenAI, Codex cloud docs: &lt;a href=&quot;https://developers.openai.com/codex/cloud&quot;&gt;https://developers.openai.com/codex/cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Coder docs: &lt;a href=&quot;https://coder.com/docs/about&quot;&gt;https://coder.com/docs/about&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Anthropic Managed Agents overview: &lt;a href=&quot;https://platform.claude.com/docs/en/managed-agents/overview&quot;&gt;https://platform.claude.com/docs/en/managed-agents/overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Anthropic Managed Agents vaults: &lt;a href=&quot;https://platform.claude.com/docs/en/managed-agents/vaults&quot;&gt;https://platform.claude.com/docs/en/managed-agents/vaults&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>AI coding guardrails are mostly the old guardrails</title><link>https://marekzp.com/blog/ai-coding-guardrails-are-mostly-the-old-guardrails/</link><guid isPermaLink="true">https://marekzp.com/blog/ai-coding-guardrails-are-mostly-the-old-guardrails/</guid><description>The tools are new and the pace is faster, but the safety controls that make agent-written code shippable are the same unglamorous ones backend teams rely on.</description><pubDate>Thu, 26 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We are increasingly using an &lt;code&gt;implement-ticket&lt;/code&gt; style workflow where an engineer gives the coding agent a ticket, lets it work through the implementation process, and then reviews the result. That is a simplification, but only a slight one. The code is realised in a high-scale system; roughly 2.5k requests per second, around 10TB of data, and roughly 200 million users. Sloppiness is expensive. Our team is small (5 engineers), and we ship multiple times a day. So safety matters.&lt;/p&gt;
&lt;p&gt;We are still learning. This is simply a description of where we are, right now, on the Photoroom Backend team. In six months, we will most likely disagree with bits of it. That is fine. The guardrails are still real, even if the paint is still drying.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Plus ça change, plus c&apos;est la même chose.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The tools are new. The pace of development can be faster. The actual safety controls are, for the most part, the same unglamorous ones backend teams have relied on for years. We have not discovered a new law of physics. We have mostly rediscovered the old ones with an LLM-powered coding agent attached.&lt;/p&gt;
&lt;h2&gt;1. Automated checks before review&lt;/h2&gt;
&lt;p&gt;The first guardrail is still the least glamorous. We run pre-commit hooks and the full test suite on every commit (we use atomic commits) and PR. This is our primary defence because it is cheap, repeatable, and hard-coded. We have high unit test coverage, around 85% at the moment, and PRs need more than 80% coverage to pass. The local &lt;code&gt;.claude&lt;/code&gt; material adds a more specific point. We ask Claude to use that other rediscovered method of Test Driven Development (TDD) and provide a reference file with our testing strategies. That file tells it to prefer end-to-end tests over isolated unit tests, extend existing tests where possible, hard-code URLs rather than using &lt;code&gt;reverse()&lt;/code&gt; (the URL is part of the contract), and use &lt;code&gt;django_assert_num_queries&lt;/code&gt; when query counts matter.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;run-tests&lt;/code&gt; skill tells the agent to run &lt;code&gt;pytest -n auto&lt;/code&gt; on every commit in worktrees to isolate itself with its own &lt;code&gt;COMPOSE_PROJECT_NAME&lt;/code&gt; and Docker override so multiple branches and multiple agents do not tread on one another.&lt;/p&gt;
&lt;p&gt;Taken together, linting and tests do a lot of the early mechanical filtering. They are not enough on their own, but they are one of the main reasons this workflow is usable rather than merely exciting.&lt;/p&gt;
&lt;h2&gt;2. Migration safety checks&lt;/h2&gt;
&lt;p&gt;This is the most backend-shaped item on the list, and perhaps the least negotiable. Our migration reference opens with a rather useful reminder that some of our tables have billions of rows. At our scale, a migration mistake is not an abstract quality concern, and we take zero-downtime deployments seriously. The local rules are correspondingly strict. &lt;code&gt;AddIndex&lt;/code&gt; is out. &lt;code&gt;AddIndexConcurrently&lt;/code&gt; is in. Migrations using concurrent operations must be &lt;code&gt;atomic = False&lt;/code&gt;. Foreign keys on existing tables need &lt;code&gt;NOT VALID&lt;/code&gt; and then validated later. Direct &lt;code&gt;RemoveField&lt;/code&gt; is blocked; only &lt;code&gt;SeparateDatabaseAndState&lt;/code&gt; can be used for that. Data backfills do not belong in migrations at all. They belong in management commands with batching, &lt;code&gt;--dry-run&lt;/code&gt;, and progress logging.&lt;/p&gt;
&lt;p&gt;The general point is simple enough. An LLM can otherwise quite happily generate a migration that would lock a table and ruin your afternoon. We prefer not to skip that bit.&lt;/p&gt;
&lt;h2&gt;3. Datadog monitoring&lt;/h2&gt;
&lt;p&gt;We also have the ancient and honourable guardrail known as &quot;watching production carefully&quot;. We rely on Datadog for an ever-expanding collection of real-time alerts, performance tracking, and error visibility. As the number of releases per day increases ever higher, babysitting deployments becomes ever more unfeasible, and hence the alerts ever more essential.&lt;/p&gt;
&lt;h2&gt;4. Multiple rounds of automated review&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;implement-ticket&lt;/code&gt; workflow does not just ask the agent to write code and hope for the best. It bakes in review stages. There is a &lt;code&gt;review-plan&lt;/code&gt; step before coding. There is a &lt;code&gt;review-senior-dev&lt;/code&gt; step afterwards, which spawns parallel specialised reviewers for requirements, security, general code quality, queries, translations, tests, DRF conventions, and migrations when needed. Then there is &lt;code&gt;review-claude&lt;/code&gt;, which runs two further rounds of external Claude review from a fresh context.&lt;/p&gt;
&lt;p&gt;I rather like this because the tooling is modern, but the logic is not. It is basically defence in depth applied to software delivery. Use repeated scrutiny. Use different kinds of checks. Stay suspicious of first impressions.&lt;/p&gt;
&lt;p&gt;There is, of course, a risk of false reassurance if one starts treating stackable model reviews as proof (and actually, everything here risks false reassurance). But they are not identical checks either. Each review stage uses a different model, a separate sub-agent with its own prompt, and a fresh context. That does not make them independent in the way two human reviewers with different expertise are, but it does reduce the likelihood of correlated blind spots. They are another layer of scepticism. Used that way, they are helpful.&lt;/p&gt;
&lt;h2&gt;5. Atomic commit verification before shipping&lt;/h2&gt;
&lt;p&gt;We also verify commits before opening a PR. This is another deeply unfashionable safeguard that turns out to be quite sensible. The &lt;code&gt;verify-commits&lt;/code&gt; skill checks that commits are still atomic after review changes, that they build and pass tests independently, that the commit messages follow the expected format, and that there are no orphaned &quot;fix review feedback&quot; style commits left hanging about like evidence.&lt;/p&gt;
&lt;p&gt;That matters because agent-assisted work can become messy in a distinctive way. It is very easy to accrete corrections and tidy-ups until a branch stops making narrative sense. Commit verification is one way of insisting that the branch still tells a coherent story.&lt;/p&gt;
&lt;h2&gt;6. Human pull request review&lt;/h2&gt;
&lt;p&gt;Human review remains essential. Final approval still comes from backend team members. There is still no substitute for a human reading the change and asking whether it makes sense in the context of the system, the ticket, the deployment model, and the assorted bits of tacit knowledge that never quite make it into a prompt. This is also the point at which one has to admit the obvious: human review is a bottleneck. We feel that as well. Like many teams, we are looking for ways to reduce the strain without lowering the standard. More on that another time.&lt;/p&gt;
&lt;h2&gt;7. Permission settings as a guardrail&lt;/h2&gt;
&lt;p&gt;This is one of the newer-looking guardrails, though really it is just access control in a sharper suit. We keep a local &lt;code&gt;.claude/settings.local.json&lt;/code&gt; file that defines what the tool is allowed to do. At the moment, it is fairly permissive. It has dozens of allow rules, no deny rules, no &lt;code&gt;defaultMode&lt;/code&gt;, and no hooks. That does not mean it is wrong. It does mean one ought to be honest about what sort of setup that is.&lt;/p&gt;
&lt;p&gt;The interesting part is that the local workflow already treats permission hygiene as work. The &lt;code&gt;tidy-up&lt;/code&gt; skill explicitly tells engineers to remove stale ticket-specific permission entries, collapse over-specific rules back into general patterns where appropriate, and remove anything containing secrets. That is exactly the sort of procedural, faintly tedious housekeeping that real guardrails tend to involve.&lt;/p&gt;
&lt;h2&gt;8. Reviewing inherited access&lt;/h2&gt;
&lt;p&gt;This is the sharpest point, and the one most likely to puncture airy theorising. Our workflows run on developer laptops. So whatever access the developer has through local tools, local credentials, GitHub, Docker, &lt;code&gt;kubectl&lt;/code&gt;, or MCP integrations is part of the practical trust boundary.&lt;/p&gt;
&lt;p&gt;And the MCP surface is not imaginary. The local settings file includes access to things like Notion, Linear, Datadog, and Figma, alongside a broad set of shell capabilities. Again, that may be entirely justified for the work at hand. The point is simply that this is where the real safety conversation has to happen, in the grubby details of what the tool can actually reach from a real machine on a real Tuesday.&lt;/p&gt;
&lt;p&gt;This, more than anything else, is why I am reluctant to speak as if we have solved the problem. We have a workflow. We have guardrails. The obvious next steps are tightening the defaults: introducing deny rules, narrowing MCP scopes per task rather than per developer, and moving toward least-privilege agent configurations that grant access to what a specific ticket requires and nothing more. We also plainly have more work to do here.&lt;/p&gt;
&lt;h2&gt;9. Basic secrets hygiene&lt;/h2&gt;
&lt;p&gt;This should not need saying, but it does. The security review prompt explicitly checks for hardcoded secrets, tokens, passwords, and sensitive settings committed instead of coming from the environment. Good. It should.&lt;/p&gt;
&lt;p&gt;There is nothing terribly futuristic about this. Do not commit production passwords. Do not leave secrets lounging about in env files and scripts. An LLM-powered coding agent will heighten the risk and scale of secrets leaking.&lt;/p&gt;
&lt;h2&gt;10. Not making the change&lt;/h2&gt;
&lt;p&gt;One guardrail we do not talk about enough is restraint. Sometimes the safest change is a smaller one. Sometimes the safest outcome is no change at all. This sounds banal because it is banal. It is also true.&lt;/p&gt;
&lt;p&gt;Today, there is ever-greater emphasis on the backend team approving all tickets and approaches before they reach a PR. Human PR reviews are expensive, and we want to ensure the WHY behind a PR is clear and justified.&lt;/p&gt;
&lt;p&gt;No one has yet managed to turn &quot;we wisely left it alone&quot; into a thrilling keynote line. That is a pity, because it is often one of the better engineering decisions available.&lt;/p&gt;
&lt;h2&gt;So what is actually new?&lt;/h2&gt;
&lt;p&gt;What is new is not that guardrails suddenly exist. It is that the set of things requiring guardrails has widened. Tool permissions, MCP access, local workstation reach, agent configuration, and instruction layers all now belong in the same conversation as tests, review, and production monitoring.&lt;/p&gt;
&lt;p&gt;That is the real adjustment. We are not replacing the old controls. We are extending them into places they did not previously need to reach.&lt;/p&gt;
&lt;h2&gt;Where we are, right now&lt;/h2&gt;
&lt;p&gt;So the honest version is this. Our safety guardrails are mostly traditional. That is a feature, not a failing. We trust linting, tests, migration discipline, monitoring, review, permissions, and basic secret hygiene because those things have earned the right to be trusted more than sweeping claims about autonomous software engineering.&lt;/p&gt;
&lt;p&gt;We are also still learning. Some of this feels sturdy. Some of it still feels slightly improvised, in the way many real engineering workflows do when they are solving today&apos;s problem with tomorrow&apos;s vocabulary. But better an honest guard rail with visible scuffs than a glossy theory with no brakes attached.&lt;/p&gt;
&lt;p&gt;The tools are new enough to attract fresh jargon and fresh anxiety. The actual safety work still looks suspiciously familiar. That may be a little deflating. It also happens to be where we are.&lt;/p&gt;
</content:encoded></item></channel></rss>