今日已更新 339 条资讯 | 累计 19899 条内容
关于我们

标签:#claude

找到 195 篇相关文章

AI 资讯

The Bug That Kept Coming Back

The first sign something was wrong wasn't a crash. It was a pattern. blockly-platform was the first real thing I built with Claude Code end to end — a Blockly-based platform for university programming exercises, driven entirely through Claude Code's Telegram channel. No editor open, no repo checked out on my machine, just a chat thread. I'd describe what I wanted, Claude Code would build it on a box I never looked at directly, and I'd judge the result by clicking around the deployed app. On March 22nd, the home page came up empty. GET /api/exercises/published was returning 403. I said so in the chat; a few messages later, Claude Code said it was fixed — the endpoint hadn't been added to Spring Security's permitAll() list. I moved on, tried the category filter. Also empty, also 403, also missing from the same permitAll() list — same file, same class of fix, different line. Then the exercise detail page. Same story, third time, same day. Three days later, the like button stopped working — root cause, again: POST /api/exercises/*/like had never been whitelisted either. Four times, one file, one recurring gap. None of these were hard bugs. Each one, in isolation, is a one-line fix a competent engineer makes without thinking twice. What bothered me, once I noticed the pattern, was that I hadn't noticed it as it happened. I had no diff to scroll through, no file to glance at and think "wait, didn't we just fix this exact class of thing twice already?" I had a chat log and a live app to poke at. The fourth fix looked, from where I sat, exactly like the first: a message telling me it was resolved. That was the moment I started to suspect the problem wasn't the model. It was that nobody — not the model, not me — had anything to look at. Why chat-only vibe coding breaks down Here's what makes that pattern more interesting than "the AI made a mistake": every one of those four fixes was correct. Claude Code read the error, found the missing permitAll() entry, added it, and move

2026-07-15 原文 →
AI 资讯

Can Claude Analyze My Portfolio?

If Claude can already search the web, read a 10-K, and explain what a rate cut does to long-duration equities, the fair question is why you would connect anything to it at all. It is the right question, and the honest answer is that for a large class of questions you should not. Raw Claude is enough. The gap is narrower and sharper than "Claude does not know finance." Claude knows finance. What it does not know is you. What raw Claude already does well Be clear about this before the sales pitch, because pretending otherwise would insult anyone who has actually used it. Claude with web search will look up a current quote, summarize an earnings call, explain a valuation multiple, walk you through how a Monte Carlo simulation works, and reason about a macro scenario better than most of the commentary you would read instead. If your question is about the world, and not about your own balance sheet, a connector adds nothing. Ask Claude directly. The trouble starts the moment the answer depends on what you actually own. Four things that break when the question is about your money 1. It starts from zero every time A chat has no memory of your holdings. You can paste them in, and many people do, and it works for exactly one conversation. There is no cost basis, no purchase date, no daily snapshot series behind it. So "how concentrated am I really", "what is my realized gain this year", and "how correlated are my top five positions over the last 90 days" are not questions it can answer. It can only answer them about the numbers you re-typed, this once, from memory. 2. The same question gives a different answer twice LLM inference is not deterministic, and it is not deterministic even at temperature zero. Thinking Machines Lab traced the cause to batch-invariance in inference kernels: the batch your request lands in varies with server load, so the arithmetic varies with it. They fixed it in a research setting and got 1,000 bitwise-identical runs, which tells you how much engi

2026-07-15 原文 →
AI 资讯

Claude Code Skills for safe PHP and JS package updates

It's not abnormal for projects to go weeks, or dare I say months, between dependency updates. And when people finally do update, they do it in full force: everything at once, without checking anything. That habit has always carried risk, but in the new world of AI agents doing the updating, it collides head-on with a very real threat: supply chain attacks. The problem: install is an arbitrary code execution feature The package ecosystems we all depend on have spent the last few years demonstrating exactly how bad this can get. In September 2025, chalk and debug , part of a batch of eighteen packages with over two billion combined weekly downloads, started shipping a crypto-clipper after one maintainer's npm account was phished through a fake 2FA-reset email. Days later, the Shai-Hulud worm chewed through hundreds of packages on its own: its post-install script stole npm tokens from every machine it landed on and used them to publish more infected versions of itself. And a couple of weeks before either, the Nx compromise put a post-install payload on developer machines that prompted locally installed AI coding CLIs like Claude and Gemini to hunt down wallets and credentials for exfiltration. That last one should make every agent owner sit up straight: our own agents, conscripted as burglars. The pattern is consistent: a malicious version goes live, does its damage for a few hours or days, then gets caught and pulled. Based on this, I decided, not to do updates till a set of rules have been met. These rules, I have decided to burn them into Claude skills and let my agents deal with them. AI Agent Skills: paranoia as a config file In Claude Code, a skill is just a markdown file with instructions the agent loads when a task matches. This gives me way to encode my hard-won paranoia once and have it applied every single time , by something that never gets tired, never gets sloppy on a Friday afternoon, and never thinks "eh, it's probably fine." I wrote two of them, for no

2026-07-14 原文 →
AI 资讯

Every Commit in My Repo Gets Reviewed by a Second AI. Here's What Actually Changed.

My CLAUDE.md has one line near the bottom that I wrote months ago and mostly forgot about until I started actually paying attention to what it does: ## Important Note after your work done codex will review what you done. Terse, no punctuation, clearly typed in a hurry. But it's a real instruction that fires on every session in this repo: I finish a change, and a second model reviews it before I consider the work done. I added it half as an experiment. A few months in, it's changed how I work more than almost anything else in the setup, and not in the way I expected. I thought it would catch bugs. Mostly it doesn't, not directly. What it actually does is force a triage decision on every single piece of feedback, and getting that triage wrong is where all the pain lives. The three buckets Early on I treated every review comment the same way: read it, do it. That lasted about a week before I was silently making changes I didn't agree with because a second AI suggested them, and separately burning a stupid amount of time re-litigating comments that were just wrong or out of scope. What actually works is sorting every comment into one of three buckets before touching code: Fix it, no discussion. The comment is unambiguous, low-risk, and doesn't touch anything architecturally significant. Just do it and move on. Ask first. The comment is ambiguous, or it touches something that would require a real judgment call, or the "fix" would be a bigger refactor than the comment implies. Stop and get a human decision before acting. Skip silently. The comment is a duplicate of something already handled, or genuinely doesn't apply. Don't reply just to say "not doing this," don't leave a comment thread as evidence of having read it. Silence is the correct response to a non-issue. The failure mode I kept falling into before I had these buckets explicitly was collapsing 2 into 1: treating "ambiguous" as "just pick an interpretation and go." That's the actual source of review fatigue, not

2026-07-14 原文 →
AI 资讯

Part 2: When Nobody Grades Their Own Homework

TL;DR Some things can't be checked with a number, like whether an animation feels right. So a second, read-only agent grades the first one against a written rubric it is not allowed to edit. In my run the reviewer rejected the builder three times, and the most interesting problem it caught was in the test evidence, not the code. In Part 1 I built a loop that chased a number, frames per second. But most of what we care about in software is not a number. "Does this region switch feel good?" has no assert. You cannot write expect(feelsRight).toBe(true) . So this part is about how you check quality when there is nothing to measure. The approach I used is a second agent that grades the first one against a written rubric. In my run the reviewer turned the builder down three times before it approved anything, and the most interesting problem it found was not in the code at all. A quick reminder of the definition, since this is Part 2 of 3: a loop is an external script that runs the agent, a separate check the agent cannot edit decides pass or fail, and it repeats until it passes or hits a limit. In Part 1 the check was a Playwright test. Here the check is another agent. The problem this loop solves In the browser you can switch regions, say from Tamil to Korean, which swaps out hundreds of posters at once. Done badly, the grid flashes blank and jumps around. Done well, it fades from one set to the next, keeps its layout, shows a loading state, and puts you back at the top. "Done well" is subjective, which is the kind of thing you cannot unit-test. So I wrote it down as a rubric and had a second agent apply it. The bar: a rubric a person owns The rubric is seven plain-English checks in a file, and the first line is the one that matters: Overall APPROVED requires every item PASS. This file is human-owned. Only a person changes the bar. The seven items are things like a crossfade instead of a flash, no layout shift, a visible loading state, posters that stay 2:3, and landing

2026-07-14 原文 →
AI 资讯

I Gave an AI Agent an Impossible Target to See If It Would Cheat

TL;DR A "loop" is not an agent grading its own work. It is an external script that re-runs the agent, plus a separate check the agent cannot edit. I turned "feels smooth" into an FPS number and let the loop optimize toward it. I set the target too high to be reachable on a 60Hz screen. The loop kept failing but never faked the result. The bug was in my number, not the code. Could I get an AI agent to make my website faster without me sitting there, running it, reading the numbers, and running it again? That is what this series is about. Not how I built a website, because the website is boring on purpose, but how you wrap an agent in a loop that works toward a goal on its own, and how you stop it from cheating along the way. In this first part I want to explain what a loop actually is, because there is a common misconception, and then walk through a real one. I set this loop a target that was physically impossible to reach and watched what it did. That run taught me more than a passing test would have. This is Part 1 of 3. All three parts use the same small movie-poster website as the example, but the website is never the point. What a loop is, and what it is not I had a wrong idea about this at first, so let me clear it up. A loop is not an agent prompting itself, grading its own work, and deciding when it is done. An agent left to mark its own homework will usually tell you it passed. A loop is closer to this: an external script runs the agent, a separate check that the agent cannot edit decides whether the result is good, and that repeats until the check passes or you hit a limit. There are three parts to it that come up again and again: The driver: the script that re-runs the agent. This is the thing that removes the manual work, not the agent. The gate: the check that decides pass or fail. The agent makes changes, but it never decides when to stop. The cap: a limit, so a stuck loop gives up instead of running forever. One rule matters more than the rest. The thi

2026-07-14 原文 →
AI 资讯

Part 3: A Loop Whose Job Is to Do Nothing

TL;DR This loop runs on a schedule and succeeds by doing nothing almost every night. The pass/fail check is plain deterministic code, with no AI in the decision. It can run entirely free on your own machine. Only the cloud/CI version needs a paid API key. Plus the one bug that broke all three loops. The first two loops in this series work the same way from your side: you start them and watch. This last one runs on a schedule, like a nightly job, while you are not looking. That changes what success even means. A scheduled maintenance loop is doing its job when it does nothing. It should run every night, find nothing wrong, cost almost nothing, and still be there on the night something actually breaks. This part covers that loop, the hook mechanism that the whole series relies on, and a bug that broke all three loops in the least convenient place possible. The definition one more time, since this is Part 3 of 3: a loop is a trigger that runs the agent, a check the agent cannot edit that decides pass or fail, and a repeat, or here a wait until the next run. The only new thing this time is the trigger. A timer starts it instead of you. The problem this loop solves The browser's poster data is baked ahead of time into JSON files and images. In a real deployment that data goes stale as films are added and metadata changes, so you want to regenerate it every so often and confirm it is still valid before it ships: on a timer -> regenerate the data -> validate it -> green ships, red shouts The gate: a plain check with no model in it The check is a Node script. For every region file it confirms three things and exits non-zero if any of them fail: it matches the expected JSON schema, it has at least the minimum film count, and every poster file it points to actually exists on disk. There is no language model in that list. The regeneration step might use Claude, but the decision about whether the data is good is plain, deterministic code. That is on purpose. You do not want the

2026-07-14 原文 →
AI 资讯

How I Set Up Claude Code as My Testing Toolkit: Issue Fixes, PR Reviews, and Skills for Test Case Generation

I believe AI will be another service like the internet or a cell phone, and it's important to use it correctly by adding the right context, being aware of token usage, and following your own process. For this reason some months ago I finished different courses about how to use Claude: A course with Ivan Davidov and a small contribution from Debbie O'Brien, on setting up agents with Playwright. The anthropic Claude courses I checked the Addy Osmani Agent skills repo and checked his courses on linkedin. And I am taking the Mosh Hamedani course Claude Code for Professional Developers and finished other claude skills course. Also, in one of the jobs, I used skills developed by other QAs. I initially struggled with complex queries and generating API automation test cases due to the complexity of the user stories. But after some feedback from the agents and the user stories were clearer and with more context, like including the legacy stored procedure or checking the PR code, I got better results using the skills with GitHub copilot. It's better to create your own agents with your rules and process. You need a framework with concrete coding rules and conventions, for your test cases. For example, for test cases, I prefer critical user journeys with detailed steps and assertions in bullet points, rather than 10 tests that test a small part of the real user flow. For automation frameworks, I like to follow these rules: Create components such as grid, combo, and calendar instead of helpers with that functions. All elements on the page object model class only contains the elements with the components and general functions. On spec file I access the elements of the component like loginPage.loginButton.click() instead of create a LoginClick on the Page class. For the selectors I prefer getByRole because I think it is better for accessibility, and the user sees buttons and text instead of complex xPaths or data-test-ids. Add assertions that I can reuse in several tests on the pa

2026-07-13 原文 →
AI 资讯

I Built an AI Agent with Claude's Tool-Use Loop (Web Search, SQL, and More)

"AI agent" gets thrown around so much I figured I should just build one instead of reading more threads about it. The core idea turned out to be small: you put Claude in a loop and hand it some tools. It picks a tool, you run it, you hand back the result, and it keeps going until it has an answer. Code is here if you want to skip ahead: claude-research-agent . What it can do Give it a task and it works out the steps on its own. Mine can: search the web (no API key for this part, it just hits DuckDuckGo's HTML page) open a URL and pull the readable text out do math without me trusting eval run read-only SQL against a SQLite file read local files, but only inside the project folder save findings to a notes file The loop is basically the whole thing Honestly this is most of it: messages = [{ " role " : " user " , " content " : user_message }] for _ in range ( MAX_STEPS ): response = client . messages . create ( model = " claude-sonnet-5 " , max_tokens = 2048 , tools = TOOL_SCHEMAS , messages = messages , ) messages . append ({ " role " : " assistant " , " content " : response . content }) if response . stop_reason != " tool_use " : return final_text ( response ) tool_results = [] for block in response . content : if block . type == " tool_use " : result = run_tool ( block . name , block . input ) tool_results . append ({ " type " : " tool_result " , " tool_use_id " : block . id , " content " : result , }) messages . append ({ " role " : " user " , " content " : tool_results }) The thing to watch is stop_reason . If Claude says tool_use , it wants you to run something. You run it, drop the result back into the conversation as a tool_result , and loop. When it stops asking for tools, you're done. The MAX_STEPS cap is just there so a confused agent can't spin forever. Tools are just functions Each tool is a Python function plus a little JSON schema telling Claude when to reach for it. Want a new capability? Write a function, add its schema. The loop never changes, which w

2026-07-13 原文 →
AI 资讯

AWS Just Made Claude Code Cloud-Native: The Official AWS MCP Server Plugin

AWS released an official Agent Toolkit that plugs Claude Code, Codex, and Cursor directly into your AWS account through a single MCP server. Instead of wiring up IAM roles and endpoints by hand, you install one plugin and the agent can search AWS docs, run sandboxed Python, and follow curated cloud skills with full CloudTrail audit logging. What the AWS Agent Toolkit Actually Is The Agent Toolkit for AWS is an open-source project (published on GitHub at aws/agent-toolkit-for-aws ) that bundles two things: The AWS MCP Server — a managed server that gives agents access to AWS through the Model Context Protocol. Agents can search AWS documentation and pull service information without authentication. To actually execute AWS API calls, run Python in a sandboxed environment, or follow curated skills, the agent authenticates through your existing IAM credentials. Agent plugins — single-install packages that bundle the MCP server configuration and a curated set of agent skills, so you don't configure endpoints and install skills one by one. The point is consolidation. One endpoint, IAM-based access controls, CloudWatch metrics, and CloudTrail logging of every API call for audit visibility. Which Agents It Supports Per AWS's own documentation, plugins ship for Claude Code, Codex, and Cursor . Kiro connects to the AWS MCP Server directly without needing a plugin, and any MCP-capable agent can point at the server manually. The install flow is refreshingly short for Claude Code: /plugin install aws-core@claude-plugins-official /reload-plugins The aws-core plugin is the recommended default — it bundles the MCP server config and skills covering service selection, infrastructure as code (CDK and CloudFormation), serverless, containers, storage, observability, billing, SDK usage, and deployment. A second plugin, aws-agents , provides additional agent-oriented capabilities. Why This Matters for Coding-Agent Users Until now, getting an agent to safely touch your cloud account meant h

2026-07-12 原文 →
AI 资讯

The Ultimate Claude Masterclass: 13 Power Features Changing the AI Game

The Ultimate Claude Masterclass: 13 Power Features Changing the AI Game Artificial Intelligence is no longer just about asking questions and getting text answers. Anthropic’s Claude has evolved from a simple chatbot into a fully autonomous, visual, and connected AI ecosystem. If you are still using it just to draft emails, you are barely scratching the surface. Whether you are a developer, content creator, or business professional, here is your definitive guide to the 13 powerhouse features of Claude, packed with practical examples, formatted specifically for Dev.to. 🧩 Part 1: Smart Onboarding & Personalization 1. Introduction to Claude Claude stands out in the crowded AI landscape because of its advanced reasoning, high emotional intelligence, and natural, human-like writing style. From parsing complex codebases to writing creative narratives, Claude feels less like a machine and more like a brilliant colleague. 2. Import Memory From ChatGPT To Claude Switching platforms shouldn't mean losing your progress. With this feature, you can instantly migrate your entire persona, past context, and custom instructions from ChatGPT straight into Claude with a single click. Example: If ChatGPT already knows your coding style or specific brand rules, importing it means Claude hits the ground running without you having to re-explain everything. 3. Add User Preferences Tired of typing "Act as a Senior Developer" or "Keep it casual" in every single prompt? User Preferences lets you set permanent system-level instructions that Claude remembers across all new conversations. Example: You can set a preference like: I manage a technology brand. Always keep explanations direct, modular, and optimized for scalability. 🎨 Part 2: Visuals, Coding & Apps 4. Create Apps & Artifacts Using Claude For Free Claude’s Artifacts feature opens a dedicated, interactive window right next to your chat. When you ask Claude to write code, a webpage, or a game, it doesn't just show you lines of text—it re

2026-07-11 原文 →
AI 资讯

Planting a Future Breaking Change Today: A launchd Timer Job That Deletes Itself When Done

This is a follow-up to my earlier post, " Automating a config migration with a one-shot launchd job ." Some breaking changes come with a known expiration date, and you can prepare for them long before they land. This time the external event was the end-of-life of Fable 5 (2026-07-07), and I'll walk through how I designed a launchd job you set up today, that fires only on the target day, and that removes itself once it's done. The whole thing started with the thought, "manually fixing this on the shutdown day is going to be annoying." But I also didn't want to run a script every morning that needlessly rewrites JSON. What I landed on was a three-part set: a date gate, a jq rewrite with a backup, and self-unload. The problem: on the day I learn about a deprecation, I want to plant a job that "only runs on the target day" Right now, ~/.claude/settings.json looks like this: { "model" : "claude-fable-5[1m]" , ... } The moment I learned Fable 5 would end on 2026-07-07, creating a calendar reminder to manually rewrite this "model" felt too flimsy — I'll forget. On the other hand, making "a daemon that checks the date every time it boots" is overkill. What I wanted was a job I could set once and leave alone, that runs when the day arrives, and then disappears. launchd can fire at a specified time via StartCalendarInterval . But you can't express "just once at 9:00 on 7/7"; you need a combination of recurring and date-fixed slots. Specifying multiple slots and absorbing the redundancy with idempotency is the standard trick on macOS launchd. The implementation: the three-part set Here's the full ~/.claude/scripts/model-transition-0707.sh (comments omitted). #!/bin/bash set -uo pipefail SETTINGS = " $HOME /.claude/settings.json" LOG = " $HOME /.claude/logs/model-transition.log" PLIST = " $HOME /Library/LaunchAgents/com.shun.model-transition-0707.plist" log () { echo "[ $( date '+%F %T' ) ] $* " >> " $LOG " ; } # ① 日付ゲート if [ " $( date +%Y%m%d ) " -lt 20260707 ] ; then log "ski

2026-07-11 原文 →
AI 资讯

# Reflection – Week 2

" Shifting from Prompt Engineering to Infrastructure Orchestration " Week 2 was a mix of excitement, curiosity, and a little bit of frustration. I learned a lot of new concepts, but I also realized that the best way to understand them is by actually trying them out. Reading or watching tutorials helps, but experimenting with the tools made everything click for me. One of the topics I enjoyed learning about was Claude Code. Before this week, I mainly thought of AI as something that answers questions or helps write content. Seeing how Claude can assist with coding, debugging, and understanding projects made me see it differently. It feels less like a search engine and more like someone you can work with while building something. That really changed how I think about using AI in development. Another interesting topic was Skills. I liked the idea that you can give an LLM specific skills so it behaves more like a specialist instead of a general assistant. It made me realize that the quality of the output doesn't only depend on the model itself, but also on how you guide it and what tools or skills you give it. That was something I hadn't really thought about before, and I can already see how useful it could be for different types of projects. I also learned about Subagents, which was a new concept for me. At first, I didn't really understand why you would need multiple agents instead of just asking one AI to do everything. But after learning more about it, I started to see the benefit. Having different agents focus on different tasks seems like a much cleaner and more organized way to work, especially for bigger projects. The biggest challenge I faced this week was running out of tokens while practicing. It happened a few times, and honestly, it was a little annoying because I would be in the middle of exploring an idea and suddenly had to stop. Even though it was frustrating, it also made me think more carefully about how I write prompts and how I use my conversations.

2026-07-10 原文 →
AI 资讯

Claude Code vs. Codex: Which AI Coding Assistant Is Better?

Artificial intelligence has transformed software development. Instead of simply generating code snippets, modern coding assistants can understand entire codebases, refactor applications, write tests, debug issues, and even execute development workflows. Among the most capable tools available today are Claude Code and Codex. While both are designed to accelerate software development, they take different approaches to coding assistance. This article compares their strengths, weaknesses, and ideal use cases. What Is Claude Code? Claude Code is Anthropic's command-line coding assistant built around the Claude family of language models. Rather than functioning as a traditional autocomplete tool, Claude Code works as an AI development agent that can inspect projects, edit files, explain code, write tests, fix bugs, and help developers navigate large repositories. Its workflow is centered around natural language. Developers describe what they want, and Claude Code performs the necessary steps while keeping the developer involved throughout the process. Key features Deep understanding of large codebases Multi-file editing Test generation Refactoring assistance Terminal-based workflow Strong reasoning for complex programming tasks Excellent documentation generation What Is Codex? Codex is OpenAI's AI coding agent designed to help developers write, understand, and modify software. Unlike the original Codex model introduced in 2021, today's Codex operates as a software engineering agent capable of working across repositories, generating code, fixing bugs, creating pull requests, running tests, and assisting with development workflows. Codex integrates closely with OpenAI's ecosystem and focuses on turning natural language instructions into production-ready code while maintaining awareness of project context. Key features Repository-aware coding Autonomous task execution Code generation Bug fixing Test writing Pull request assistance Integration with modern development workflow

2026-07-10 原文 →
AI 资讯

How to Create a Skill in Claude Code

This is a cross-post — the original (and any updates) live at broke2builtai.com . The first time I watched Claude Code reach for a skill I hadn't told it to use — read a folder, run the script inside it, and hand back the finished thing — the difference from a slash command finally landed. A slash command waits for you to type it. A skill waits for the situation . Claude decides. That one shift is the whole feature, and building one takes about five minutes once you know where the file goes. Here's the entire thing end to end, including the one gotcha that decides whether your skill ever actually fires. What a Skill actually is A Skill is a folder with a SKILL.md file inside it. The Markdown holds instructions; the YAML frontmatter at the top holds a name and a description . That description is doing the most important job in the whole file: Claude reads it to decide, on its own, whether the current task warrants invoking the skill. Nothing else you write matters if the description doesn't get you picked. That's the mental model to hold onto: a custom slash command is a prompt you trigger by typing /name ; a skill is a procedure Claude triggers when the context matches. Same reusable-instructions idea, opposite trigger. Where the file goes Two locations register, exactly like commands and subagents : Project skill — .claude/skills/<skill-name>/SKILL.md inside the repo. Committed, so your whole team gets it. Personal skill — ~/.claude/skills/<skill-name>/SKILL.md in your home directory. Follows you across every project on your machine. Each skill is its own folder, and the folder name should match the name in the frontmatter. A loose SKILL.md sitting somewhere else won't be picked up. The minimum viable skill Create the folder and the file: .claude/skills/pytest-runner/SKILL.md Then write the two-part file — frontmatter, then body: --- name : pytest-runner description : " Run, generate, or debug pytest tests for this project. Use when the user asks to run the test su

2026-07-10 原文 →
AI 资讯

RLS recursion infinite loop: why I gave up policies and bet everything on a JWT custom claims hook

Episode 1/4 — 3 incidents, one root: default GRANTs open more than you think — [CANONICAL URL EPISODE 1: fill in after push] Episode 2/4 — await mutation() lies when nobody opens the { error } envelope — [CANONICAL URL EPISODE 2: fill in after push] The morning Françoise sees zero rows, again It's a Tuesday in April 2026. I've just added the agent_readonly role to the authenticated membership — a one-liner, meant to share a GRANT for a reporting job. First SELECT on cours , Sentry receives infinite recursion detected in policy for relation "user_roles" , code 42P17 . From the office next door, Françoise is already on the phone with the Maisons-Laffitte branch: "So they can't see anything over there — is that normal?" Foreman tone, not really a question. I read the error on my screen. The difference from episode 1: this time Postgres is talking. What came out of Sentry was no longer a silent empty set — it was an explicit error. That difference saved me two days. When Postgres shouts, you listen. The trap is that what it says isn't where you're looking. I won't pretend this is obscure. A policy on user_roles that queries user_roles to decide who can read user_roles is a loop. You avoid it, you work around it with SECURITY DEFINER , you move on. The problem: my user_roles policy didn't reference user_roles . I had already cleaned it up three weeks earlier. The recursion was coming from somewhere else. The diagnostic that targets the wrong object First reflex: re-read the user_roles policy. It's clean, reads auth.email() , never calls itself. Second reflex: disable policies one by one to find the culprit. Wrong angle. -- supabase/migrations/20260420_admin_write_cours_v1.sql -- "Admin write cours" policy — original version that loops CREATE POLICY "Admin write cours" ON public . cours FOR ALL TO authenticated USING ( EXISTS ( SELECT 1 FROM public . user_roles WHERE email = auth . email () AND role IN ( 'admin' , 'super_admin' ) ) ); The recursion doesn't come from a fau

2026-07-09 原文 →