AI 资讯
Blind Replay Before Merge: Keep Only the Agent Diff a Clean Environment Recreates
An agent-written patch that lives only inside one long chat session is not a reviewable change for merge. Hidden constraints from that conversation never reach the repository, the failing tests, or the next reviewer. A pairing session that wants a durable result should keep only the diff a second memory-free environment can recreate. The brief, not the transcript, becomes the source of truth for that recreation before anyone discusses merge. Chat windows quietly store rejected files, private service names, and half-stated architecture that later readers will never see. A senior pairing partner should treat that hidden context as contamination rather than as extra helpful memory for the model. The protocol below is a worked example of that stance, not a report of a named production incident. The two roles are a driver chasing an agent-assisted patch and a senior who refuses to merge from chat history alone. Pairing setup for a known failing test The shared codebase is a small HTTP service whose readiness probe still returns 503 under a test that already exists. The driver wants an assistant to edit the health handler and move on quickly. The senior wants a change that someone else could regenerate from the repository without the original thread. Work starts only after both people can describe done in file-level terms on disk. Until that description exists beside the code, every generated diff stays on a throwaway branch with no merge discussion. The pairing treats speed on the first attempt as optional and replayability on the second attempt as mandatory. That split is the whole method, and the rest of this article only makes it checkable. What the senior asked, written down immediately The senior did not open with a cleverer prompt or a longer system message for the same window. The senior demanded answers that a stranger could follow, then wrote those answers into the repository. The recorded questions targeted outcome, verification, blast radius, and isolation, no
AI 资讯
A counter in process memory is not a guard: 131 restarts proved it
Last week a reader left this on one of our articles, and I'm still turning it over: The counter lived in a module-level variable. The supervisor restarts that daemon on a stale-heartbeat rule, so the process died and respawned 131 times during those 24 hours. Every restart reset the counter to zero. The threshold of 3 was unreachable by construction — not degraded, never reachable. Her guard: escalate to a human after 3 consecutive failed self-heal rounds. Written in July, correct logic, process alive the whole time. The unit test passed. The heartbeat was fresh, the logs were flowing. And a human was never called, because the guard's only memory — how many failures in a row — lived in the process, and the process was not the thing being watched. It was the thing being restarted. The number that makes this its own failure shape: 0 escalations across 1,501 daemon starts. The two questions that both pass Earlier in that same thread we'd been arguing that a guard has two questions you can ask it: Does it catch the failure? Is it still running? Her case answers both yes — and the guard still cannot fire, ever. The unit test passes because nothing restarts in a unit test, so the reset never shows up. The process is "up" because the supervisor is doing exactly its job: respawning on stale heartbeat, forever, with no opinion about how often it has done so. It will run a crash loop until the heat death of the universe without ever deciding the loop is the failure. A counter that lives in a process cannot distinguish "this never happened" from "this happened, but I died and forgot." Every restart is a small amnesia. A supervisor that restarts you on a schedule is an amnesia machine. Put a threshold behind that memory and the threshold is a fiction. The tell is the ratio she quoted: escalations fired versus daemon starts. 0 over 1,501. Any guard whose numerator is zero over a large denominator is either genuinely never needed or structurally unreachable — and those two are wo
AI 资讯
Why I Prefer TypeScript Over JavaScript for Larger Projects
JavaScript is flexible, fast to start with, and supported everywhere on the web. For small scripts, quick experiments, and simple browser utilities, plain JavaScript is often enough. But as projects become larger, TypeScript starts to solve problems that JavaScript leaves entirely up to the developer. That is why I increasingly prefer TypeScript for anything beyond a very small project. The biggest difference is type safety JavaScript lets variables change type freely. For example: let khg5293UserId = 5293; khg5293UserId = "5293"; That is valid JavaScript. Sometimes this flexibility is convenient, but it also makes it easier for unexpected values to move through an application. TypeScript lets you define what a value is supposed to be: let khg5293UserId: number = 5293; Now assigning a string to khg5293UserId produces an error during development. That means certain mistakes are caught before the code ever runs. For small khg5293 experiments, this may not matter much. For a larger application with many files and components, it becomes much more valuable. Functions become easier to understand Consider a JavaScript function: function getProjectName(project) { return project.name; } There is nothing here telling us what project is supposed to contain. With TypeScript, the expected structure can be defined directly: type Khg5293Project = { name: string; language: string; public: boolean; }; function getProjectName(project: Khg5293Project): string { return project.name; } Now the function documents itself. A developer immediately knows what kind of object should be passed into it and what the function returns. This becomes especially useful when returning to a project after several weeks or working across a larger codebase. Interfaces make data structures clearer TypeScript also makes application data easier to reason about. For example: interface Khg5293Profile { username: string; projectCount: number; active: boolean; } const khg5293Profile: Khg5293Profile = { username:
开发者
Making a Python interpreter in 1024 bytes
submitted by /u/azhenley [link] [留言]
开发者
It took a year to ship WebAssembly in Anubis
submitted by /u/shadowh511 [link] [留言]
AI 资讯
The Hook System — Blocking AI Mistakes with Structure
This is chapter 4 of my book **Building Autonomous AI Agents with Claude Code * — a field guide to turning Claude Code from a coding assistant into an agent that remembers, verifies its own work, and knows when to stop. Everything below is from a system I actually run every day on one Windows PC.* 1. A Hook Is a Safety Mechanism Outside the AI A rules file is something the AI tries to follow ; a hook is something the system uses to make it be followed . This difference is bigger than it looks. Rules get buried as context grows longer, get skipped when things are urgent, and "just this once" exceptions pile up. Hooks don't do that. Point Timing Typical use UserPromptSubmit Right after the user types input Automatic context injection (record summaries, related rules) PreToolUse Right before a tool runs Blocking dangerous actions (gates) PostToolUse Right after a tool runs After-the-fact checks (contamination detection, follow-up procedure reminders) Stop When the response ends Quality gates (forbidden-word detection, verification requirements) Registration happens in one place, the settings file. { "hooks" : { "PreToolUse" : [ { "matcher" : "Write|Edit" , "hooks" : [{ "type" : "command" , "command" : "python C:/hooks/record_gate.py" }] } ] } } 2. Pattern A — The Blocking Hook (Gate) This is a gate that blocks "attempts to modify a file without reading the records first." What follows is a shortened version of one actually in use. import json , sys , time from pathlib import Path STATE = Path ( tempfile . gettempdir ()) / " read_state.json " REQUIRED = [ " memory/diary.md " , " memory/mistakes.md " ] payload = json . load ( sys . stdin ) # hooks receive the tool call on stdin tool = payload . get ( " tool_name " , "" ) if tool == " Read " : state = json . loads ( STATE . read_text ()) if STATE . exists () else {} state [ payload [ " tool_input " ][ " file_path " ]] = time . time () STATE . write_text ( json . dumps ( state )) sys . exit ( 0 ) state = json . loads ( STA
AI 资讯
From a Chocolate Wrapper to Concurrent InnoDB Page Splits
Here is a story [1] about the first version of B-link optimization for Innodb that is the most used B-tree engine in MariaDB. It started from a sketch on a chocolate wrapper and after some attempts ended up with significant p95 improvement for certain B-tree operations. Thx Zhao Song for his work in this area for MySQL. 1. https://mariadb.org/from-a-chocolate-wrapper-to-concurrent-innodb-page-splits/ submitted by /u/drrtuy-b [link] [留言]
开发者
Which programming “best practice” do you think is actually wrong?
submitted by /u/stagas [link] [留言]
AI 资讯
I killed the process and the drain still hung: a grandchild held the pipe
A program of mine hung for forty minutes. Not spinning at a thousand loops a second: at zero percent CPU . It wasn't doing too much work; it wasn't doing any work at all. And still it wouldn't finish. The program does something common: it orchestrates external command-line tools. It launches one, reads what it writes to standard output, and moves on to the next when it's done. So it doesn't get stuck when a tool drags, each one has a timeout: when it fires, the process is killed and we carry on. That's the part that failed, and it failed where no one looks: after killing the process. Killing the process doesn't close the pipe When you read a subprocess's output, you read from a pipe : one end writes (the subprocess), the other reads (you). Your reader doesn't finish when the subprocess dies. It finishes when EOF arrives, and a pipe's EOF arrives only when the last write end is closed. Almost always they coincide: the subprocess is the only writer, it dies, its end closes, EOF arrives, your reader finishes. All in microseconds. But "almost always" isn't "always". The tool I launched launched another one in turn —a grandchild—. And that grandchild inherited the pipe's write end, because on Unix a child inherits its parent's open descriptors unless told otherwise. So when the timeout fired, I killed the child. Its end closed. But the grandchild was still alive , with its copy of the descriptor open. The last write end hadn't closed. EOF never came. And my reader sat waiting for an EOF that would never arrive —at zero percent CPU, blocked in a read() , indistinguishable from slow work—. The symptom that deceives What makes this failure so hard to see is that it doesn't look like a failure . An infinite-loop hang burns CPU: you see it in top instantly. This one spends nothing. The thread is asleep in the kernel waiting for data that isn't coming. In the process list it looks healthy. In the metrics it looks like it's "taking a while". The only way to tell "hung forever"
AI 资讯
Multimodal Transformers: How LLMs Learn to See
Hello, I'm Shrijith Venkatramana, and I'm building LiveReview — a blast-radius aware AI code review built for your business-critical systems. Star us to help devs discover the project, give it a try, and share your feedback to help improve the product. A language model can write Python, explain quantum mechanics, and imitate Shakespeare. Show it a screenshot of a production dashboard, however, and suddenly the central question becomes: How does a transformer that was trained on text learn what a pixel means? The naïve answer is: “Give the image to the LLM.” That description hides almost all of the interesting engineering. Modern multimodal systems are usually compositions of several models: a vision encoder turns pixels into vectors, a connector translates those vectors into something the language model understands, and the LLM then reasons over the resulting representation alongside ordinary text tokens. That architectural trick has turned the transformer from a language architecture into something much closer to a general-purpose interface for heterogeneous data. The evolution is worth understanding because it reveals a useful engineering pattern: you often do not need to retrain a giant model to give it a new sensory modality. You need a good representation and a sufficiently expressive interface between representations. 1. The basic mental model: pixels become tokens Start with an ordinary LLM. Its input looks conceptually like: "The server returned HTTP 500. What should I check?" | v tokenizer | v [t1, t2, t3, ..., tn] | v Transformer | v answer Everything is eventually represented as vectors. Multimodal transformers exploit this fact. An image is first converted into a sequence of vectors: image | v vision encoder | v [v1, v2, v3, ..., vm] | v multimodal connector | v [z1, z2, z3, ..., zk] | +------ text tokens [t1, t2, ...] | v LLM | v answer The important conceptual shift is this: The LLM does not have to understand pixels directly. It only has to understand
开发者
Continued Fractions And Lattice Sieving
submitted by /u/DataBaeBee [link] [留言]
开发者
Modding a 20-year-old game to make it even better (part 2!)
submitted by /u/HHalo6 [link] [留言]
AI 资讯
I Replaced a $40/mo PDF API with 200 Lines of Web Worker Code — Here's the Offline Invoice Tool I Built
The bill that started this I was paying $40/month for a PDF generation API to power a tiny internal invoicing tool for a client project. Forty bucks a month to convert some JSON into a PDF. That's it. That's the whole service. I finally sat down on a Saturday to see if I could kill that subscription. Three weekends later, not only did I kill it — the replacement is faster than the API ever was, because there's no network round-trip at all. This post is the log of how it went, in the order I actually hit the problems, not the order that makes me look competent. Attempt #1: jsPDF on the main thread (it worked, until it didn't) First pass was the obvious one — jsPDF running directly in the click handler: function generateInvoice ( data ) { const doc = new jsPDF (); doc . text ( data . clientName , 20 , 20 ); data . lineItems . forEach (( item , i ) => { doc . text ( ` ${ item . description } — $ ${ item . amount } ` , 20 , 40 + i * 10 ); }); doc . save ( ' invoice.pdf ' ); } Fine for a 3-line invoice. Once I tested with a 40-line-item invoice (a real client sent me one to test against), the tab froze for almost two full seconds. Not crashed — frozen. Scroll didn't work, buttons didn't respond, and on a mid-range Android phone it was closer to five seconds. The main thread doing synchronous PDF math while also being responsible for painting the UI is exactly the kind of thing that looks fine in a demo and falls apart the moment a real user pastes in real data. Attempt #2: move it to a Web Worker Web Workers get talked about like they're this exotic tool for WASM and video processing. They're also just... a really good fit for "expensive synchronous work that a user is waiting on." I'd never reached for one before this project, mostly out of habit. The tricky part isn't the worker itself, it's that jsPDF assumes it has access to document and window in a couple of code paths (font metrics, mostly), which don't exist inside a worker. I ended up switching to pdfkit compiled
开发者
Wird BASIC noch benutzt?
Ich höre überall nur noch von Python als Einführungssprache. Gibt es noch BASIC-Programmierer? submitted by /u/Puzzleheaded-Half993 [link] [留言]
开发者
Hey everyone! 👋 Excited to join DEV Community. I'm a Backend Software Engineer specialized in Laravel, building scalable web apps & APIs with clean code. Here to share tips, connect with developers, and learn. What projects are you working on? 🚀
AI 资讯
What It Actually Takes to Run a Cross-Border Marketplace: Six Years of Shpper
Shpper is a cross-border personal-shopping marketplace. A buyer wants something they cannot get where they live. A traveller is already flying that route with unused luggage space. The platform introduces them, holds the money until the item arrives, and turns an empty few kilos in someone's suitcase into a delivery network. I am the CTO. I own the platform end to end — the Flutter apps for both sides, the backend, payments and escrow, identity verification, and the release pipeline. We are on version 14.2.0, rated 4.64 on the App Store from 72 ratings. Fourteen major versions is enough distance to say something useful about what this kind of product actually demands. Almost none of the hard parts were the ones I expected. You are not building one app The first structural fact about a two-sided marketplace is that "the app" is two products with opposed interests, and you ship both. The buyer wants their item cheaply, quickly, and with certainty it will arrive. The traveller wants to be paid well, carry as little risk as possible, and not be blamed for customs. Those are not complementary desires. Every feature has to be designed twice, from two points of view, and any change to the shared middle — the request, the offer, the trip — reaches into both. This has a consequence people underestimate: your release cadence is bounded by the slower side. A change to how offers work is not shipped when the buyer app ships. It is shipped when both apps are live, on both platforms, and enough of both populations have updated. Mobile app review is not a build step you can optimise away; it is a scheduling constraint that shapes how you design changes, which is why so much of the logic has to be able to change without a release. The hard problem is trust, and it is not a feature A marketplace's actual product is trust between strangers. Everything else is plumbing. Consider what the platform is asking. A buyer sends money for an item that does not exist yet, to be bought by someo
开发者
From Jekyll to a POSIXish static site generator
submitted by /u/sousapereira [link] [留言]
AI 资讯
AI Can Write the Code. Your Real Job Is Becoming the Reviewer — Here’s How to Do It Properly
AI can write code now. That part is no longer surprising. You can describe a feature to Copilot, Claude Code, Cursor, Codex, or another coding agent and get a working implementation in minutes. Sometimes it is genuinely impressive. But there is a bigger question: Can you actually trust the code enough to ship it? According to the Stack Overflow 2025 Developer Survey, 84% of developers use or plan to use AI tools . At the same time, trust in AI-generated output is still limited. One of the biggest frustrations developers report is getting an answer that is almost right, but not quite . Source: https://survey.stackoverflow.co/2025/ai And that “almost right” part is exactly where developers still matter. AI may write more code. But humans still need to decide whether that code is correct, secure, maintainable, and actually worth merging. So here is a simple review workflow I think every developer should practice. 1. Start With the Requirement, Not the Diff Imagine you tell an AI agent: Add password reset support. A few minutes later, it generates the full feature. The code may compile. The UI may work. The tests may even pass. But before reading the implementation, ask: How long should reset tokens remain valid? Can the same token be used twice? What happens if the email does not exist? Should existing sessions be logged out? Are we exposing whether a user account exists? This matters because AI can build the wrong thing very cleanly. So before asking: Does this code work? Ask: Does this solve the correct problem? That one question can save a lot of time. 2. Check the Architecture Before the Syntax AI is usually good at writing a function. It is not always good at understanding where that function belongs inside your system. For example, an agent might create something like: components/ ├── PaymentForm.tsx ├── PaymentAPI.ts ├── StripeService.ts └── Database.ts Everything may technically work. But should database access really live beside your UI components? Probably no
AI 资讯
I built 59 free browser-based dev tools in vanilla JS — here's what I learned
I've been quietly building Antigravity Tools — a collection of 59 free, browser-based developer utilities — and today I'm sharing everything I built and learned. Why vanilla JS? No React, no build step. The main constraint I set for myself: zero dependencies, zero server, zero telemetry . When you paste your JWT token into jwt.io, it goes to their server. When you use an online regex tester, your test strings are logged. I built Antigravity Tools so every operation runs inside your browser, using native APIs. No Node.js backend No npm packages No webpack/vite/parcel No Google Analytics No cookies Everything runs on Web Crypto API , Canvas API , Web Audio API , and IndexedDB — all native to modern browsers. The 8 tool categories 🔐 Security & Auth Tools JWT Inspector — decode JWT header, payload, and check expiry locally RSA & ECC Key Generator — generate 2048-bit key pairs via SubtleCrypto Hash & Password Generator — SHA-256/SHA-512 via Web Crypto PII Masker — strip emails, credit cards, SSNs, IPs from text Universal Encoder/Decoder — Base64, URL, Hex, HTML entities, Unicode 🤖 AI & Prompting Tools AI Token Counter — estimate cost across GPT-4o, Claude 3.5, Gemini 2.0, DeepSeek R1 System Prompt Builder — structure agent instructions with XML tags and tool definitions AI Text Humanizer — rephrase robotic AI output into natural writing Prompt Cost Trimmer — compress prompts by 30–50% to reduce API costs ⚡ Dev & Code Tools JSON Workbench — beautify, validate, convert to TypeScript, Python, Go types cURL Converter — cURL → JS fetch, Python requests, Go, PHP Regex Tester — real-time match highlighting with capture group display Cron Builder — visual cron expression editor with plain-English output Git Command Helper — build undo/squash/cherry-pick commands visually Try it 👉 https://antigravitytools.app
AI 资讯
Dev log #20 Deleting 180k lines and chasing socket leaks: A week in the OSS trenches
Yash K Saini — Engineer, building in public — AI/ML, low-level (Rust/C/C++), and open source. GitHub...