AI-Native Series Β· Agent Engineering Β· Loop Engineering in Practice
The AI Review Loop Report: Eleven Silent Days, One Chat Card, and a 24% Ceiling
What broke, what we built, the six decisions and why, what the reviewer caught in its own repairs, and the next moves, each with the observation that would prove it wrong.
1-minute takeaway β what you'll walk away with
What this is. A report on an AI review loop: the AI that reads every pull request in a manufacturing quality-management codebase, and the new path that carries its verdict to the team's chat app and back. It covers the problem (the reviewer was out of budget for eleven days and nobody heard), the solution (one chat card per decision, with a different card when the reviewer itself is broken), the six design decisions and why, the lessons, and the next moves.
Why it matters. For an engineer: "never silent" is necessary and not sufficient. A failure that is posted where nobody looks behaves exactly like silence. For a founder: the team set a goal that 90β95% of changes would merge without a human, and the measured ceiling in this codebase is 24%, because most changes touch things a human must sign. Knowing that before a quarter of chasing it is worth more than the loop. For a student: a worked example of measuring a target before building toward it.
What you can do after reading. Run the two measurements on your own repository today (how many of your reviewer's verdicts actually ran, and what share of merged changes your auto-merge rules could ever allow). Copy the 30-minute contract below to route your reviewer's verdicts into the channel your team already reads, with a distinct alarm for "the reviewer did not run".
What this AI review loop report covers, and who it is for
This report continues a line of work in one repository. AI PR Review That Cannot Lie built the reviewer: every claim cites a file and a line, and "unmeasured" is a posted state instead of silence. The ANDON series turned that into five rules, and its fourth episode, the auto-merge envelope, ended with an honest sentence: the door that lets a bot merge had never opened. In parallel, the Visionboard series built the instrument I run my projects on, and its last episode, the scoreboard, closed with three bets for the next quarter, each with a dated falsifier. The second bet was a sensor that cannot be silent.
This report is what happened when those designs met a real week. On 2026-09-23 my co-founder, who owns the quality domain, and I agreed on three things for the AI review loop: the reviewer judges two dimensions (does the change do what the requirements say, and does it follow the engineering rules); it escalates to a human only when it is unsure, which we guessed would be 5 to 10% of pull requests; and every notification goes to the team chat instead of e-mail. The same day I measured the guess. It was 100%.
The report has three parts. Report: the problem, the solution, and the six decisions with the reasoning behind each. Reflect: what the build taught, including what the reviewer caught when it reviewed its own repairs, and one lesson about delegation that cost me an afternoon of trust. Project: the next moves, small and big, short and long, each tied to a Visionboard bet or an ANDON door and each with the observation that would prove it wrong.
Readers: engineers who run an AI reviewer or are about to; founders deciding what "auto-merge" is allowed to touch; students who want one complete loop, from failure to measurement to design to what is still unproven. The codebase is private; every mechanism is reproduced here in enough detail to rebuild it.
One picture: the pass, the sous-chef, and a bell in the chef's pocket
One picture will carry the report, and it continues the kitchen from the first report, on the cooking ladder's "running a restaurant" rung. Every plate leaves through the pass. A sous-chef tastes it and clips a note to the ticket. The head chef reads the note, tastes one spoonful, and either sends the plate or sends it back. Cold starters the sous-chef is sure about can go straight out.
For eleven days the sous-chef was off shift. The kitchen's rule said "never pretend you tasted it", so on every plate the sous-chef's stand-in clipped a note: not tasted. The rule was obeyed perfectly. The notes sat at the pass. The chef was in the dining room, phone in hand, and never walked past the pass. Every plate waited for the chef, which is safe, and the kitchen's promise that most plates would flow without him quietly became zero plates. Nobody lied. Nobody heard.
The fix is a bell in the chef's pocket that rings in two different tones.
| In the kitchen | In the AI review loop |
|---|---|
| The sous-chef's note on the ticket | The AI's review summary posted on the pull request: questions for a human, findings with file:line, a suggested verdict, and whether the change qualifies for auto-merge. |
| "Not tasted" notes piling up at the pass | 45 of 47 summaries saying "unmeasured": the reviewer's budget cap was hit, so it never ran. Posted, honest, and acted on by no one. |
| An orange ring: "I'm unsure about this plate" | A chat card titled needs your decision: the AI's open questions, every unmet auto-merge condition, and a button to the pull request. |
| A grey ring: "I'm not in the kitchen" | A different card: the reviewer did not run, with the cause in plain words and the fix. A system fault, never disguised as a question about the plate. |
| The chef walks to the pass to decide | The button opens the pull request on GitHub. Approval happens there, where it is recorded, never by a reply in chat. |
| A light in the dining room: "plate served" | A merged card, fired by a separate workflow when the pull request closes as merged. The loop closes where it started. |
Where the picture breaks: a real sous-chef who is off shift is missed at once, because the kitchen slows. A reviewer that is "off shift" costs nothing visible, because the human path still works. That is the whole problem, and the reason the grey ring had to exist.
Part I Β· Report β the problem, measured before it was fixed
Later that same day, US time (the meeting ran at 22:04 in China), I pulled every pull request the reviewer had labelled, and read the reason printed in each summary. Not the label: the label for "the AI is unsure" and the label for "the AI never ran" were the same label.
| Reading (2026-09-23, 47 labelled pull requests) | Count |
|---|---|
| Auto-merged | 0 |
| Escalated because the AI was unsure or found a problem (the reviewer actually ran) | 2 |
| Escalated because the reviewer never ran ("unmeasured") | 45 |
| Of all 47, reasons printed (one pull request can have several): reviewer did not run Β· change outside the auto-merge paths Β· a machine gate red | 45 Β· 33 Β· 6 |
Share of pull requests that reached a human: 47 of 47. Scope: one repository, the reviewer's labels from its first labelled pull request to 2026-09-23. [MEASURED]
Read again a day later, with four more pull requests: 51 labelled, 0 auto-merged, 4 escalated by a reviewer that ran, 47 where it never ran. The shape did not change, only the count.
Five whys, each answered from the repository or its logs:
- Why did every pull request reach a human? Because 45 of 47 summaries said the reviewer had not run.
- Why had it not run? Every call since about 2026-09-12 returned the same error: the organization's monthly spend limit was reached, and access would return on 2026-10-01.
- Why was the limit reached? The reviewer shared one API key, and one $100 monthly limit, with everything else I run on that machine, including a batch job that translates articles into four languages. The billing console shows spend per key, not per job, so I cannot say which job spent most of it; I can say the reviewer was the one that starved.
- Why did nobody notice for eleven days? The review job is set to not block merges when it fails, so the workflow showed green. The "unmeasured" summary was posted on each pull request, exactly as the never-silent rule requires, and acted on by no one in eleven days, because nobody opens a summary on a pull request they are about to review by hand anyway.
- Root cause: the reviewer's own failure had no path to a human ear. "Never silent" was satisfied on the page and violated in the world.
The repository's lessons file already had an entry from two weeks earlier saying almost exactly this, unmeasured needs someone watching it, with a next step that never landed. A lesson recorded as prose is a lesson the prose can stop being true about. It is the thesis of ANDON episode 3, rules as data rather than prose, and I apparently needed to learn it a second time.
Part I Β· Report β the solution: an AI review loop that reports to the channel people live in
The team had already decided that the chat app (Feishu) is the only inbox. So the loop has four hops: GitHub runs the reviewer, a script turns its summary into a chat card, a button on the card returns the human to GitHub, and the merge event sends one more card back.
The card kinds, and what decides each:
| Card | Fires when | What the human does |
|---|---|---|
| π¨ Needs your decision | The reviewer ran and the change did not qualify for auto-merge: outside the allowed paths, a gate red, a finding, or a question only a human can answer. | Read the questions (on measured reviews so far, 2.3 per pull request on average, n=7), press the button, decide on GitHub. |
| βͺ Reviewer did not run | The summary says "unmeasured" (budget, invalid key), or there is no summary and the review step did not report success. | Fix the system. The card names the cause and the fix; it says in bold that the pull request is not the problem. |
| β Auto-merging | All five auto-merge conditions from the envelope episode hold. | Nothing. Can be switched off with one setting. |
| β Merged | The pull request closes as merged. | Nothing. The loop is closed. |
| (no card) | There was nothing to review, or a newer push cancelled the run. | Nothing, and that silence is a declared decision, with one known gap named below. |
The first end-to-end run, 2026-09-24: once the organization limit was raised, the reviewer ran on a real pull request, raised three warnings and two questions for a human, and the team chat received an orange card with its questions; after the fixes, the merge produced a blue card. Every hop was seen working on a live pull request, not only in a test.
Part I Β· Report β six design decisions, and the reasoning behind each
| # | Decision | Rejected alternative | Why |
|---|---|---|---|
| 1 | A broken reviewer gets its own card. Grey, titled "did not run", with the cause and the fix. | One "needs a human" card for everything that is not auto-merged. | The two states need different people and different actions. Mixing them is how 45 system faults looked like 45 review questions. If the loop had shipped with one card type, it would have pinged on 100% of pull requests on day one and been muted by day two. |
| 2 | The card type is decided by the summary's text, in code. | Ask the model which card to send. | The router must not depend on the thing it is routing. A reviewer that is out of budget cannot be asked whether it is out of budget. |
| 3 | Approval stays on GitHub. The card's button takes the human there. | Approve by replying in chat, through a chat-platform app with a callback server. | This is a quality-evidence system: in an audit, "who approved this change, and when" must be answerable from one record. A chat reply is a second record that can disagree with the first. It also needs an app, a server and a credential to maintain. |
| 4 | When unsure of the reviewer's state, ring. Only an explicit "success" with no summary stays quiet. | Stay quiet unless the step explicitly failed. | A missing or garbled status is exactly what a broken setup produces. The default must be the loud one. The one exception, a run cancelled by a newer push, is quiet because the newer run will report. Its cost is named below. |
| 5 | Replace the 5β10% target with two numbers the repository computes. | Keep "escalate only 5β10%" and widen what auto-merge may touch until it is reached. | Measured: 24% of recent merged changes could ever qualify, for reasons that are correct (Part I, the ceiling). Chasing 90% means trading the evidence chain for speed. The replacement numbers are the Tier-1 auto-merge rate and the human's burden per review. |
| 6 | The reviewer gets its own budget. Done on 2026-09-24: a new key in a separate workspace, so its spending is visible on its own line; the organization limit was also raised from $100 to $200. | Keep one key for everything; raise the limit when it runs out. | A shared budget means the least important job can starve the most important one. The honest caveat: the organization's limit still sits above every workspace, so isolation is partial (the lessons section says what I got wrong about this). |
A seventh decision is a refusal: the loop does not decide anything. It carries decisions. The reviewer suggests, the rules file decides what may auto-merge, and a human decides everything else. That is the design of the Visionboard applied to a team: agents propose and report, and the human stays above the loop. In the small-team episode, the human-only field became a role with separation of duties. Here the role is "code owner", and the card is how the role gets asked.
Part I Β· Report β the 24% ceiling: what auto-merge can actually reach
A loop that routes decisions faster does not tell you how many decisions a human must make. So the second measurement asked a different question: of the last 60 merged pull requests, how many touched only files the auto-merge rules allow, such as docs, plans, tests and golden test cases? That is the ceiling. No reviewer, however good, can auto-merge a change the rules exclude. One of the 60 had exactly 100 files, the most GitHub returns per pull request, so its list may be cut short; it is counted as unmeasured, which leaves 59.
Path-eligible for auto-merge: 14 of the 59 measurable pull requests among the last 60 merged (24%). Adding frontend styles, components and views: 15. Adding the tooling folder: 20. Scope: one repository, measured 2026-09-24; a ceiling, not a forecast, because eligible changes still need green gates and a clean review. [MEASURED]
The biggest blocker was a surprise, and it is ours. Nineteen of them touched AGENTS.md, the handbook the coding agents read before they work. The repository has a rule that every feature change must update that handbook, so humans and agents never read stale instructions. And the auto-merge rules correctly forbid a bot from merging changes to the handbook, because changing it changes every agent's behaviour. Put the two rules together and every feature change needs a human, by design. The robots must update their handbook, and the robots may not approve updates to their handbook. Both rules are right. The target was wrong.
Widening the frontend would have added one pull request, because real frontend changes usually touch protected files too. Widening the tooling folder as well (the what-ifs are cumulative) adds five more, and that folder is where the gates and the reviewer themselves live: letting a bot merge a change to the grader is letting the cook grade their own plate. So the proposal for the next team decision is to keep the rules as they are, replace the target, and run a two-week pilot. It has one more gate that has nothing to do with software: GitHub refuses branch protection on this repository, answering "Upgrade to GitHub Pro", so the bot can approve but cannot merge. Until that changes, the auto-merge rate is zero by construction, which is the same door the envelope episode found closed.
Correction, 2026-09-25. This report first said the door needed a $4 monthly plan. The owner already had that plan. Every other private repository on the same account accepted branch protection; this one is a private fork of an older repository, and a fork inherits these features from its upstream network, not from its owner. The error message named a fix that had already been applied. The real fix is detaching the fork. It is the same lesson as the rest of this report, one level down: I had read the state from the message instead of measuring it, and the measurement took a handful of API calls.
Part II Β· Reflect β what the reviewer caught when it reviewed its own repairs
The fixes to the loop were themselves pull requests, so the reviewer, freshly revived, spent its first afternoon grading the code that revived it. It ran ten times on four of my pull requests. It asked for more work five times and approved five, and every round, approvals included, listed something real. Here are the catches in order, because the order is the lesson.
| # | What it caught | Kind of mistake |
|---|---|---|
| 0 | My own script sent a false "needs your decision" card for a pull request that had nothing to review. I caught this one myself, from the chat, on the reviewer's first live day. | An empty result treated as a finding. |
| 1 | My fix skipped the card when the summary lacked a marker string. If the template were ever renamed, every card would vanish silently. | Keyed on an incidental detail instead of the real condition (empty). |
| 2 | My new test checked the last card sent, not that a new card was sent. A broken branch could pass by reading the previous test's card. | A test that could not fail. Fixed and mutation-tested. |
| 3 | A test-only flag had been added to the production command line, and "no summary" had two causes (nothing to review, or the reviewer crashed) that took the same silent branch. | Test scaffolding in the product; two states, one code path. |
| 4 | The whole crash alarm depended on one line in a workflow file outside the diff, which no test read. | A guarantee living outside its test. Now a check reads the file and fails if the line goes. |
| 5 | The grep output I pasted as evidence was missing one line. | I had trimmed evidence. The reviewer noticed the output did not match the file. |
| 6 | My ceiling measurement read GitHub's per-pull-request file list, which stops at 100 files, so a huge change could look eligible. And my new "questions per review" metric had no test that could fail. | A number that could only err in the flattering direction. |
My favourite catch was not the reviewer's, and I found it only because a new test failed. When the reviewer script crashes, the alarm card explains why in words I wrote: "the script itself failed; this is not a budget or 401 problem". The card's explainer searches the text for "401" to recognise an invalid key. It found my disclaimer and told the reader to rotate the key. The alarm had diagnosed itself from the sentence that said what it wasn't. The fix was to reword the disclaimer; the lesson was that I had written a keyword detector and then fed it keywords.
Catch 6 has a second half I am less proud of. The reviewer posted it as "hold" on the proposal's last update, the chat received an orange card, and I merged anyway, because the tests were green and I did not open the card. The loop worked end to end; the human at the end of it did not read. The fix was a follow-up pull request, the ceiling moved from 23% to 24% once the truncated change was set aside, and the repository's implementation log now carries the rule I broke: before merging, read both the test result and the reviewer's latest verdict, and write down why when you overrule a hold.
Catch 5 is the one I would have missed and a colleague might not have mentioned. The pull request said "here is the grep output, the line exists". The grep output had been shortened by me, and the reviewer, reading the diff context, counted one more match than I showed. It then marked the claim "unverified" instead of arguing with it. That is the first report's rule, no claim without evidence, enforced on its own author.
Part II Β· Reflect β lessons learned
- Never silent is necessary, not sufficient. A state must reach an ear. The reviewer obeyed the rule for 45 pull requests and helped no one. The test for any alarm is not "was it posted" but "who read it within a day". This is the Visionboard's second bet, "a sensor that cannot be silent", with a stronger clause: a sensor also cannot be unheard.
- Measure the denominator before you argue about the ratio. We spent part of a meeting designing for 5β10% escalation. The real number was 100%, and 45 of those were not escalations at all but a broken sensor. Put the "did not measure" cases in their own bucket before computing any rate; when the bucket is everything, the rate is "unmeasured", not 0% or 100%.
- A shared budget lets the least important job starve the most important one. The reviewer shared a budget with a batch translation job and every other project on the machine, and it was the one that starved; the console could not say which job spent the month, because the whole spend sat on one old key they all used. Give the critical path its own budget, and track spend per job, not per key.
- The gate you write for others will grade you. Ten review rounds on my own repairs, five requests for more work, and the one I ignored was right. The day the reviewer came back, the author it reviewed most was the one who built it. That is the best evidence so far that it is worth roughly $0.25 a review (an estimate: the key's cost column read $1.96 after about eight reviews).
- Deliver results, not navigation. The agent that did this build for me sent me through a billing console four times: "Settings, then Limits", "Rate limits", "switch workspace, then Billing". The last destination does not exist. The vendor's own help centre says "The default Workspace is not editable and cannot be removed." [5] I was the executor of a plan the planner had not checked. The rule it wrote for itself afterwards: verify the destination before asking a human to go there, hand over one link and one action, and if a step cannot be verified and is not essential, drop it and deliver the result without the human. The people lesson is the same shape: when you delegate upward, the person above you should receive a plated dish, not a recipe and a map to the pantry.
Patterns, anti-patterns, and the mechanism
- Pattern: two tones for two faults. "The judge is unsure" and "the judge is absent" go to different cards, colours and people.
- Pattern: the router is dumb on purpose. Deterministic classification from text the system wrote, never from the model's opinion of itself.
- Pattern: loud by default. Silence is an explicit, listed decision per case; anything unlisted rings.
- Anti-pattern: the green failure. A job allowed to fail without blocking shows green while doing nothing. Allowing it not to block merges is right; letting that also make it invisible is the bug.
- Anti-pattern: a target without a ceiling. A ratio goal set before measuring what the rules allow.
- Mechanism: jidoka. Toyota describes it as the ability, when an abnormality occurs, for "the machine or equipment can detect the abnormality and stop automatically, or the operator can stop the line by pulling the stop cord themselves" [1]. In the kitchen, the cord is the sous-chef's note and the board is the bell: pulling the cord only helps if it rings where the chef is standing. The chat card is that bell.
- First principle, one sentence: a check is only as real as the shortest path from its failure to a person who can act on it.
Part III Β· Project β the next moves, small and big, short and long
Each move is tied to a Visionboard bet or an ANDON door, and each carries the observation that would prove it wrong, dated, in the style of the scoreboard episode. The Visionboard's falsifier date for its second bet, the silent sensor, is 2026-10-07; the first two moves report against it.
| Short term (this month) | Long term (this quarter) | |
|---|---|---|
| Small | S1 Β· Weekly readings into the team meeting. Every Monday the repository prints the escalation rate, the auto-merge ceiling and the human's burden per review. Wrong if: by 2026-10-07 a grey card has fired and no one on the team can say what it meant; then the card's words are the problem. S2 Β· Close the named gap. Today any cancelled review is silent, including one cancelled by a timeout or by hand, where no newer run will report. Wrong if: a cancelled-and-never-rerun review is found in the log; that is the day the exception becomes too wide. | S3 Β· The reviewer's calibration. For every pull request the reviewer approved, count reverts and bugs traced back to it; for every one it held, count how many a human merged unchanged. This is the calibration question asked of our own judge. Wrong if: by 2026-12-31, or after 50 reviewed pull requests if that comes first, its "merge" and "hold" verdicts predict reverts no better than chance; then the reviewer is a formatter, and should be priced like one. |
| Big | B1 Β· Open the door, once. Detach the fork from its upstream network, apply branch protection, and run the two-week pilot with the rules unchanged. Success is at least three real auto-merges, zero reverts, and at most three human questions per reviewed pull request. Wrong if: by 2026-10-31, or two weeks after the door opens if that comes later, fewer than three changes have qualified; then the ceiling is lower than measured and the team should say plainly that this repository is human-reviewed, and stop pretending otherwise. | B2 Β· The review loop becomes a Visionboard sensor. The escalation rate and the auto-merge rate feed the board's engineering track as a gauge, and "reviewer did not run for 24 hours" becomes a named tripwire, not only a card. This is the scoreboard's second future made concrete, and the first step toward its third future, the double loop, which asks whether a signed decision predicts movement (see the scoreboard episode). Wrong if: by 2026-12-01 the board shows the gauge and the team's decisions about the review loop were made without looking at it. |
What I am deliberately not doing: approving from chat, widening the auto-merge rules before the pilot, or building a second reviewer to review the first. Each is interesting. None closes a loop that is open today.
Build it in 30 minutes: the review-loop contract
The contract, not the code. Thirty minutes is the budget this contract sets for a reader copying it into a repository that already has an AI reviewer posting a summary; it is not a time I measured.
| Element | Specification |
|---|---|
| Inputs | The reviewer's summary file (possibly empty), the review step's outcome (success, failure, cancelled, skipped, or missing), the pull request number, a chat webhook URL. |
| Output | Zero or one chat card: title, colour, body, one button linking to the pull request. Plus one line in the CI job's summary saying what was sent or why nothing was. |
| Classifier | Empty summary and outcome in {success, cancelled}: nothing. Empty summary otherwise: grey, "reviewer did not run", synthesised cause. Summary contains the "unmeasured" section: grey, cause translated into its fix. Summary says auto-merge qualified: green. Otherwise: orange, with the questions for a human and every unmet condition. |
| Invariant | A grey card and an orange card are never the same card. Approval never happens in chat. |
| Wiring | The notify step runs with if: always(), which GitHub documents as: "Causes the step to always execute, and returns true, even when canceled." [2] Pass the outcome quoted, so an empty value stays an argument. A separate workflow on pull_request: closed with merged == true sends the merged card. |
| Missing webhook | Exit 0 in CI and write "chat not notified, here is how to get a webhook" into the job summary. Never fail the pull request over a notification. |
| Tests that must be able to fail | Empty summary sends nothing; crash sends exactly one grey card; missing outcome rings; a cancelled run is quiet; a wrong signature is refused; a test reads the workflow file and fails if if: always() is removed. Mutate each branch once and watch its test go red. |
| Two measurements | The escalation split (auto / escalated / did not run) from labels plus summary text; the auto-merge ceiling (share of recent merged changes whose every file is allowed). |
| Deliberately missing | Approving from chat, de-duplicating repeated alarms, per-person routing, and any use of the model to classify. |
Same story, five exits
| Reader | The decision this report informs | One action this week |
|---|---|---|
| Student | Whether a "safe" rule (never lie, say unmeasured) is enough without a delivery path. | Find one alarm in your life (a low-battery light, a smoke detector) and ask who hears it and how fast. |
| Engineer | Whether your AI reviewer's "failed to run" state reaches anyone. | Count your reviewer's runs in the last 30 days that did not produce a real verdict. |
| Founder | What share of changes can ever skip a human in your codebase. | Compute the ceiling on your last 60 merged changes before setting any automation target. |
| Executive | Whether AI review budgets are isolated from batch workloads. | Ask which job spent last month's AI budget, by key, and whether the reviewer has its own limit. |
| Investor | Whether a team's "90% automated" claim has a measured ceiling behind it. | Ask for the denominator and the share of runs that did not measure. |
Reality mission
Pick one automated check your team trusts. Break its input on purpose tonight, a bad key or an empty file, and see where the failure shows up tomorrow morning, and who notices first. If the answer is "on a page nobody opens" or "nobody", you have the problem this report is about, and the grey card is a 30-minute fix.
Read next
Part of the AI-Native Series Β· Agent Engineering. Numbers are scoped where they appear and come from one private repository's own measurement commands on 2026-09-23 and 2026-09-24; the per-review cost is my estimate from the billing console's per-key cost column, not a metered average. The kitchen is a model, not a measurement.
References
- Toyota Motor Corporation. Toyota Production System. global.toyota β the jidoka passage quoted above, checked word for word against the page on 2026-09-24.
- GitHub Docs. Expressions: status check functions, always. docs.github.com β the quoted definition, checked against the page source on 2026-09-24.
- GitHub Docs. Control the concurrency of workflows and jobs. docs.github.com β
cancel-in-progress, the reason a superseded review is cancelled and why that case is quiet. - GitHub Docs. About protected branches. docs.github.com β branch protection rules; on this repository, a private fork, the API answered "Upgrade to GitHub Pro" even though the owner's account was already Pro.
- Anthropic Help Center. Creating and managing Workspaces in the Claude Console. support.claude.com β the quoted note on the default workspace, checked against the page on 2026-09-24.
- Anthropic. Workspaces (Claude Platform documentation). platform.claude.com β described, not quoted: every organization has a default workspace; spend limits are set per additional workspace, under the organization's own limit.
- Feishu Open Platform. Custom bot usage guide. open.feishu.cn β the webhook the cards are posted to; described, not quoted.