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

标签:#dev

找到 4363 篇相关文章

AI 资讯

Detecting Tool + Schema Drift in a Remote MCP Server

An MCP server can ship a change that breaks every agent calling it, and nothing in your monitoring will notice. The endpoint still answers 200. The initialize handshake still completes. tools/list still returns a result. Every signal a conventional uptime check knows how to read stays green — and an agent that memorized last week's tool contract starts failing anyway, because the contract underneath it moved. This is drift: a server's tool inventory or a tool's input schema changing between two points in time, with no transport-level symptom at all. Drift is not a hypothetical. MCP servers are young, most are maintained by small teams, and a tool's inputSchema is just a JSON object in a deploy — there is no compiler stopping someone from renaming a required field, tightening an enum, or dropping a tool nobody remembered an agent still called. The only way to catch it is to have looked at the server before and remember what you saw. What Actually Counts as Drift Drift is anything about a server's advertised capability contract that differs from the last time you checked. Concretely: A tool disappears. It was in yesterday's tools/list , it is not in today's. Any agent that calls it now gets a JSON-RPC error mid-flight, not at startup — the failure shows up wherever the agent happens to reach for that tool. A tool appears. Informational on its own, but worth recording — it is also how you notice a server quietly forking its capability set per client or per deploy. A tool's contract changes shape. Same name, different inputSchema — a field renamed, a type narrowed, a new required parameter, a changed description that alters how an LLM decides to call it. The tool is still callable, which is what makes this the dangerous case: nothing errors immediately, calls just start failing validation or getting silently misinterpreted. The capability set changes. The server stops advertising resources or prompts , or starts. Anything built against the old capability list breaks the

2026-08-21 原文 →
AI 资讯

VRP Is Ready for External Validation — One Company Can Be the First to Pilot It

VRP Is Ready for External Validation — Who Will Be the First to Pilot It? My name is Vitalijus Riabovas. I am the independent architect and creator of VRP — Veil Routing Protocol . VRP is a continuity-first networking architecture built around a simple principle: A logical session should not have to die simply because the network underneath it changed. Wi-Fi → LTE/5G. IP mutation. NAT / CGNAT churn. Temporary blackout. Path failure. Recovery. Replay attempts. Stale authority. Duplicate execution. For a long time, VRP was primarily architecture, runtime engineering and internal validation. That stage has changed. The public validation boundary exists now. And I am inviting serious engineers and organisations to test it. DON'T TRUST MY CLAIMS. TEST THEM. I am not asking the networking industry to believe a presentation. I built the measurement boundary. The public VRP Validation Kit provides engineers with an environment for evaluating observable behaviour independently. You can: clone the repository; run the Docker scenarios; inspect generated evidence; verify manifests and hashes; attack the evidence; delete events; duplicate events; reorder events; attempt replay; introduce stale conditions; corrupt artifacts; run the verifier; reproduce PASS / REJECT / INCOMPLETE outcomes. If you believe something is wrong, try to produce a reproducible contradiction. Give me: environment → scenario → commands → evidence → result That is useful engineering. WHAT HAS BEEN BUILT? VRP has moved far beyond an architectural diagram. The project now includes multiple engineering layers. Continuity architecture Logical session identity is designed to survive changes in the underlying network path. The architecture is being developed around continuity rather than assuming that transport identity and logical session identity must always be the same thing. Runtime The protected runtime implements the private VRP mechanisms. That implementation is not public . State and transition handling T

2026-08-21 原文 →
AI 资讯

Your feature-usage scanner doesn't know Vue, Svelte, or Astro exist. Here's how we fixed that without touching its core.

If a static analyzer only walks .ts / .tsx / .js / .jsx , every other file type isn't scanned badly - it's not scanned at all. A .vue component, a .svelte widget, an .astro page: none of them exist to the tool. Not "low confidence." Not "partial support." Invisible, the same way an empty search result looks identical whether there's genuinely nothing to find or the search just never looked in the right place. That's exactly the gap Eventra's CLI had. It scans a codebase and tells you which tracked features are actually used - the whole pitch is "stop guessing which code is dead." Except if your team ships a Vue admin panel, a Svelte checkout widget, and an Astro marketing site around the same core app (which, if you've worked on more than one team, you've probably seen - nobody plans a multi-framework stack, it just accretes), the CLI would silently skip all three, report a clean scan, and never mention that it hadn't actually looked. The exact failure mode the product exists to prevent, happening inside the product itself. We'd already closed this gap once, for Vue. This month we closed it for Svelte and Astro too, and the interesting part isn't the frameworks - it's that adding two more meant touching exactly zero lines of the CLI's core analysis engine. The trick: don't teach the core anything The CLI's core is a TypeScript-compiler-API engine: it builds a real program, walks real ASTs, resolves real symbols across files, and figures out which .track("event_name") calls are statically reachable. It is, deliberately, framework-agnostic - it doesn't know what Vue is, and it shouldn't have to. So instead of teaching the core about .vue / .svelte / .astro , each framework gets a small, separate plugin whose only job is a translation: take the framework file, hand back one virtual TypeScript module. A Vue Checkout.vue becomes Checkout.vue.ts . A Svelte Cart.svelte becomes Cart.svelte.ts . The core never sees the original file - it sees TypeScript, because by the time

2026-08-21 原文 →
AI 资讯

Why 75% of Developers Prefer Claude Code Over Codex

Photo by Microsoft Copilot on Unsplash TL;DR: In a poll of 138 developers, three‑quarters say Claude Code outperforms Codex for everyday AI‑driven coding, pointing to higher accuracy, deeper context awareness, and a smoother workflow. The AI‑coding battlefield has been dominated by OpenAI’s Codex for years, powering tools like GitHub Copilot and shaping how developers write code. Yet a fresh wave of feedback suggests a shift: Anthropic’s Claude Code is rapidly becoming the preferred assistant for many programmers. A recent survey of 138 software engineers—spanning startups, enterprise teams, and freelance coders—revealed that 75% now rely on Claude Code as their go‑to AI partner. What drives this migration, and what does it mean for the future of AI‑augmented development? Survey Overview and Key Findings The questionnaire targeted developers who regularly use AI code generators, asking them to rank their primary tool and rate specific workflow attributes. Respondents represented a broad skill spectrum, from junior developers to senior architects, and worked across languages such as Python, JavaScript, Java, and Go. Adoption rate: 104 out of 138 participants (75%) listed Claude Code as their primary AI assistant, while only 34 (25%) still favored Codex. Primary criteria: Accuracy of generated snippets, ability to retain long‑form context, and ease of integration into existing IDEs topped the list. Secondary factors: Cost efficiency, response latency, and the perceived safety of the model (fewer hallucinations) also swayed decisions. The data paints a clear picture: developers are no longer satisfied with a one‑size‑fits‑all approach. They want an AI that can understand the nuance of a multi‑file project, stay on‑topic across extended sessions, and deliver code that compiles on the first try. Why Claude Code Wins Over Codex Higher Accuracy and Fewer Hallucinations Respondents repeatedly highlighted Claude Code’s ability to generate syntactically correct, production‑re

2026-08-21 原文 →
AI 资讯

176 Regeln, die kein Mensch geschrieben hat

Um 02:47 Uhr stoppte mein System ein Deployment. Kein Mensch war wach. Es war ein Dienstagmorgen, als mein Guard-System anschlug. Nicht wegen eines fehlgeschlagenen Tests. Nicht wegen eines Syntaxfehlers. Ein Agent hatte versucht, einen Commit zu pushen, der einen AWS-API-Schlüssel enthielt. Der Schlüssel steckte in einer Konfigurationsdatei, die eigentlich nie ins Repository sollte. Der Deployment-Prozess wurde blockiert. Um 02:47 Uhr. Kein Mensch hätte das um diese Zeit gesehen. Der Schlüssel wäre live gegangen. Das war kein Einzelfall. Es war der 47. Vorfall in 14 Monaten, den mein System automatisch abgefangen hatte, bevor er Schaden anrichten konnte. Und er hat mir klarer als je zuvor gezeigt, warum das Regelwerk wichtiger ist als das Modell selbst. Was ein Guard-System wirklich ist Die meisten, die über KI-Sicherheit sprechen, meinen Alignment, Halluzinationen oder Trainingsdaten. Das sind echte Probleme, aber sie liegen auf einer anderen Ebene. Ich rede von etwas Handwerklichem: einem System, das verhindert, dass ein KI-Agent im laufenden Betrieb Fehler macht, die Menschen Geld oder Daten kosten. Mein System läuft auf einem Prinzip, das ich GRIP nenne: Guards, Rules, Isolation, Protocol. Jeder Agent, der in meinem Stack läuft, durchläuft vor jeder kritischen Aktion eine Prüfkette. Nicht als Empfehlung. Als harter Block. Das bedeutet konkret: Der Agent darf nicht weiter, bis das Problem behoben ist. Kein Fallback, kein "try anyway", kein Override ohne explizite Freigabe. # Beispiel: Pre-Commit Guard gegen Secrets #!/bin/bash STAGED_FILES = $( git diff --cached --name-only ) for FILE in $STAGED_FILES ; do if grep -rE "(AKIA[0-9A-Z]{16}|sk-[a-zA-Z0-9]{32,}|ghp_[a-zA-Z0-9]{36})" " $FILE " 2>/dev/null ; then echo "GUARD BLOCK: Potential secret detected in $FILE " echo "Deployment halted. Remove secret before proceeding." exit 1 fi done Das ist kein ausgeklügeltes KI-Modell. Das ist ein Shell-Skript, das seit Monaten zuverlässig seinen Job macht. 176 Regeln und wie

2026-08-21 原文 →
AI 资讯

A CSS Hover-Reveal Pattern for Technical Specs

The problem on the Gate Seal page The Gate Seal product page for a maritime client needed to present detailed specifications without turning the layout into a wall of text or a table that looked like an export from Excel. The technical detail buyers cared about was present, but visually buried. The requirement was to surface those details in a compact way, keep the implementation CSS-only, and make sure it still worked with keyboard navigation. The hover-reveal pattern The pattern below uses a hover-reveal on key specification rows. On desktop, moving the cursor over a spec row reveals additional context. With a keyboard, focusing the same row does the same thing. No JavaScript is required for the basic interaction. Structurally, each spec item is a container with two layers of content: Always-visible summary (label and primary value) Hidden detail that appears on hover or focus Here is a simplified version of the markup: <div class="spec-list"> <button class="spec-item"> <div class="spec-main"> <span class="spec-label">Gate size</span> <span class="spec-value">Up to 6 m</span> </div> <div class="spec-detail"> Custom diameters available for retrofit situations. </div> </button> <button class="spec-item"> <div class="spec-main"> <span class="spec-label">Seal material</span> <span class="spec-value">EPDM / NBR</span> </div> <div class="spec-detail"> Oil-resistant compounds for lock gates in heavy traffic.</div> </button> </div> The choice of <button> here is deliberate: it is naturally focusable, works with keyboard navigation, and is announced as an interactive element by assistive technology. In a production implementation, the button semantics can be adapted depending on whether you need a true button or a different element with role="button" . The CSS-only interaction The interaction is controlled through :hover and :focus-visible , with a basic transition for a smoother reveal. .spec-list { display: grid; gap: 0.75rem; } .spec-item { width: 100%; text-align: left

2026-08-21 原文 →
AI 资讯

The Hard Part of Birth Chart Calculations Isn't the Zodiac. It's Time.

The most annoying bugs I’ve dealt with while building a birth-chart engine were not about zodiac signs. They were about time. And the deeper I got into it, the more I realized that “birth time” is a much less simple input than it looks on a form. A local datetime isn't enough Take this: 1990-05-15 09:30 It looks precise. But precise where? Without a timezone, it doesn’t identify an instant. So the calculation API I use takes both the local datetime and the IANA timezone: chart = engine . natal ( local_datetime = " 1990-05-15T09:30:00 " , timezone = " Europe/London " , latitude = 51.5074 , longitude =- 0.1278 , ) I prefer an IANA zone like Europe/London over something like UTC+1 . The former describes a real timezone with historical rules. The latter is just an offset. DST makes this more interesting During a daylight-saving fall-back transition, the same local clock time can occur twice. So a value like: 01:30 may correspond to two different UTC instants. That means the input looks exact to the user while still being ambiguous to the calculation engine. There’s a strong temptation to quietly choose one. I don’t like doing that. If the input is genuinely ambiguous, I’d rather make the ambiguity explicit. The same thing happens in the opposite direction during spring transitions. Some local clock times never existed. If the clock jumped directly from 01:59 to 03:00, then: 02:30 isn’t a valid local instant. Again, silently “fixing” it is convenient. But now the software has changed the user’s data. Then there’s the bigger problem: no birth time A lot of people simply don’t know what time they were born. This creates a product decision. You can say: unknown → 12:00 PM and suddenly everything works. You get: Ascendant houses house cusps Midheaven The object looks complete. But none of those values are based on a birth time the person actually supplied. That bothered me enough that I made unknown birth time a first-class state in the engine. chart = engine . natal ( local

2026-08-21 原文 →
AI 资讯

The Hidden Reasons Your iOS App Feels Slow

An iOS app can feel slow even when its interface looks well-designed and responsive. The problem may not always be the UI or the code running on the device. Often, the real issues are hidden in network requests, API responses, WebSocket connections, and background activity. For developers, finding these problems requires visibility into what is happening behind the screen. This is where Owlse , a network inspection and debugging tool for iOS and macOS developers, can help. 1. What Actually Makes an iOS App Feel Slow? Several hidden network issues can affect an app's performance: Slow API responses Too many network requests Large data payloads Connection delays Failed or repeated requests Background network activity A user may simply see a loading screen or delayed response, while several network operations are happening in the background. Understanding these operations is the first step toward finding the actual cause of the problem. 2. Why Traditional Debugging Can Make These Issues Hard to Find Network-related problems are not always easy to identify through standard debugging. Developers may need to switch between different tools to inspect requests, analyze timing, investigate WebSockets, and understand application issues. When an app generates hundreds of requests, finding one problematic request can also take considerable time. Without a clear view of network activity, developers often have to rely on assumptions. A dedicated network debugging workflow can make this process much easier. 3. Meet Owlse: Network Debugging for iOS & macOS Owlse is built to give iOS and macOS developers greater visibility into their application's network activity. Instead of treating network behavior as something happening in the background, Owlse helps developers inspect and understand it. With features including live request streaming, request inspection, timing analysis, WebSocket inspection, mocking, crash reporting, search, HAR export, and timeline debugging, Owlse brings impo

2026-08-21 原文 →
AI 资讯

Why Hitting Your Coverage Target Is Making Your Tests Worse

I had 87% coverage, and we still broke the billing flow on launch day. Not because of a gap in the percentage. Because 87% was covering the wrong things. The tests were written to pass a gate, not to catch a failure. That is a more common story than most teams admit. And the reason it keeps happening is not that engineers are careless. It is that the incentive structure you created made it the rational outcome. The series checkpoint The first three articles in this series built the investment case for testing and then dismantled the received wisdom about how to execute it. We've made the economic argument for automation. We've restructured when quality checks happen across the SDLC. We've replaced the pyramid model with something shaped by risk rather than by code hierarchy. Now, when someone asks: how do you know if it is working? The answer most teams give is their coverage percentage. This article is about why that answer is structurally broken, and why fixing it is a management decision before it is a tooling decision. What coverage percentage actually measures Coverage percentage tracks which lines of your code were executed during a test run. If a line ran, it counts as covered. That is the complete definition. It does not measure whether the test asserted anything meaningful about that line. It does not measure whether both branches of a conditional were exercised. It does not measure whether the specific inputs that cause failures were ever tried. A test that calls a payment function and checks assert response is not None covers the same lines as a test that validates the transaction ID, amount, currency, error code, and retry behaviour. The coverage tool treats them identically. The research on this is unambiguous. A 2017 study by Kochhar et al. examined the correlation between code coverage and actual bug rates across 100 large open-source Java projects. The finding: the coverage of existing test suites has an insignificant correlation with the number of b

2026-08-21 原文 →
AI 资讯

Your GitHub Actions cron fires less often than you declared: what we measured and how to design for it

We run an automated publishing pipeline entirely on GitHub Actions cron schedules — no server, no queue, just workflows that wake up, do one thing, and commit the result. It mostly works. But there is one behaviour of scheduled workflows that the docs mention in a single quiet sentence and that will silently halve your job frequency if you design around the cron expression instead of around reality: Scheduled workflows do not fire as often as you declare. What we measured We had a feedback-watcher workflow declared at four runs per hour: on : schedule : - cron : ' 7,22,37,52 * * * *' Measured over days, it actually fired one to two times per hour — not four, and not at the declared minutes. Roughly hourly on most days, at inconsistent offsets from the declared slots. We later redeclared it at two runs per hour ( 7,37 * * * * ) — measured result: still one to two runs per hour. The declared frequency changed by 2x; the delivered frequency barely moved. This is not an outage and not a misconfiguration. GitHub's own documentation says the schedule event can be delayed during periods of high load , and that high load times include the start of every hour — which is precisely where naive cron expressions cluster — and adds: "If the load is sufficiently high enough, some queued jobs may be dropped." What the docs understate is the magnitude: in our observation, on a private repo, "delayed" in practice meant "throttled to a fraction of the declared rate, indefinitely." What this breaks The failure mode is subtle because nothing goes red. Every run that happens succeeds. The runs that don't happen leave no trace — no log, no failure email, nothing. You only notice if something downstream depends on the frequency: We had promised a "reply within 15 minutes" SLA on incoming feedback, initially backed by the 4x/hour schedule. The schedule couldn't hold it, so for a while we ran a local 15-minute scheduler as the primary path and kept the workflow as fallback. When we later rel

2026-08-21 原文 →
AI 资讯

PCA Deletes Your Quietest Signals First

Classic Machine Learning Through the Eyes of an SRE — Part 7 Picture a client health metric that has been flat at 2 out of 10 for six months. Ask PCA to compress your client-health data and that metric will contribute almost nothing to the directions PCA decides to keep. Not because PCA is broken. Because PCA treats variance as importance, and a signal that barely moves contributes almost no variance. Reduce the data far enough and the independent information it carried is simply not there anymore. But a CSAT frozen at 2/10 is not noise. It is a crisis nobody is escalating. And after compression, it may no longer be available to anything downstream. That is the bet, and in ops data it is frequently wrong. The critical signals are often the quiet ones. There is a cheaper version of the same failure that catches most people first. PCA measures variance in whatever units your features happen to be in, so a metric ranging from 0 to 10,000 can dominate one ranging from 1 to 5 purely because it is bigger. Standardize before you compress, or your first principal component may just be an elaborate way of saying "ticket count." Same class of bug as unscaled features in K-Means and SVM, and it fails just as quietly. What PCA actually is Third answer-finding strategy in the unsupervised set, using the same shorthand as the last two articles. K-Means SEARCHES: iterate and hope. DBSCAN DEFINES: declare a rule and traverse. PCA SOLVES: an eigendecomposition or SVD gives a direct solution rather than an iterative local search. No convergence to babysit, no restarts, no local optima to escape. Two caveats on the word "direct," both worth knowing. Many libraries will use randomized SVD on large matrices, which is approximate and stochastic. And even with an exact solver, eigenvectors are only defined up to sign, so a component can come back inverted between runs or across implementations. The variance explained is identical either way, which is precisely why nobody notices. Hold ont

2026-08-21 原文 →
AI 资讯

Keep Every LangSmith Trace Without the 10 Retention Bill

LangSmith is excellent for debugging live AI systems. But keeping every trace in its extended-retention tier can turn observability into a surprisingly large line item. Today we merged a new archive workflow into langsmith-cli that changes that tradeoff: keep LangSmith for live debugging, continuously archive verified traces to organization-owned private S3, and query the retained Parquet directly with DuckDB. In other words, you can preserve your complete trace history without placing every trace on LangSmith's extended-retention tier. The cost-overrun risk LangSmith currently documents two trace-retention tiers: Tier Retention Published trace price Base 14 days 0.05¢ Extended 400 days 0.50¢ total The 0.45¢ extended-retention upgrade makes an extended trace cost 10× as much as a base trace. That difference becomes material at production volume: Monthly traces Base, 14 days Extended, 400 days Added retention cost 100,000 $50 $500 $450 1,000,000 $500 $5,000 $4,500 10,000,000 $5,000 $50,000 $45,000 These examples use the published per-trace rates before free allowances, plan terms, negotiated pricing, or taxes. Always check the official LangSmith usage and billing documentation before making budget decisions. There is another subtle risk: online evaluators and automation rules can upgrade matching traces when retention extension is enabled. A rule that matches one run upgrades the whole trace, and a thread-level rule can upgrade every trace in that thread. LangSmith currently enables retention extension by default for new online evaluators and automation rules, although you can opt out. At scale, an innocent-looking evaluator or rule can therefore create a much larger bill than expected. The new langsmith-cli archive workflow The new workflow separates live observability from long-term retention: LangSmith live traces (14 days) │ ├── D+2 primary export ───────┐ └── D+12 reconciliation ──────┤ deduplicate by run ID ▼ private S3 / Parquet │ ▼ runs ... --archive (DuckDB)

2026-08-21 原文 →
AI 资讯

The Principle of Least Privilege: Why File Permissions Like 600/644/755 Exist

Anyone who has worked with SSH private keys has run into an instruction to "set it to 600." Config files, by contrast, often get 644, and executable scripts get 755. What do these three-digit numbers actually mean, and why does the right number depend on what kind of file you're dealing with? This post starts from the mechanics of Unix-style (Mac/Linux) file permissions and works up to the design principle behind them: least privilege. Permissions as a 2D grid of who and what Unix-family operating systems express file access as a grid: three kinds of "who" crossed with three kinds of "what." "Who" breaks down into the file's owner, the group the owner belongs to, and everyone else ("other"). "What" breaks down into read, write, and execute. Each cell in that 3×3 grid is either granted or not, and that's exactly what a listing like -rw-r--r-- from ls -l is showing you. Strip the leading character and the remaining nine characters are three groups of three — owner, group, other — each rendered as r/w/x when granted or - when not. Why a single digit can represent read/write/execute Numeric notation like chmod 600 compresses that rwx combination into a single octal digit. Read is worth 4, write is worth 2, execute is worth 1 — powers of two — and you sum whichever bits are set. Note: powers of two are used here because each of read/write/execute is tracked as an independent bit (on or off), and any sum of a subset of {4, 2, 1} maps back to exactly one combination of bits. There's no ambiguity — for example, 6 can only mean read+write (4+2), never any other combination. Read and write, no execute ( rw- ): 4 + 2 = 6 Read only ( r-- ): 4 Read, write, and execute ( rwx ): 4 + 2 + 1 = 7 No access at all ( --- ): 0 A three-digit number like 600 lines up these single digits for owner, group, and other, left to right. 600 means "owner gets read+write, group and other get nothing." What the common numbers actually mean Reading the numbers mentioned at the top through this lens:

2026-08-21 原文 →
AI 资讯

iCloud Silently Evicted 69 Article Files and Killed 4 Days of Publishing: EDEADLK and a read_text_resilient Design

Every one of my publishing lanes went dark for four days, and every script involved exited with status 0. Nothing had crashed. The files themselves had quietly stopped existing on disk — macOS had uploaded them to iCloud and deleted the local copies to "optimize storage." Why This Matters What it means for automation to depend on its environment When you run 160+ launchd jobs around the clock, the execution environment itself becomes a failure source before your script logic does. Ports get exhausted, processes orphan and pile up, memory never frees — I wrote about that class of resource leak last time. This is a completely different kind of total failure that happened the very next day. The files had become fatal to read . Not a bug in my code. Not a filesystem bug. An unintended side effect of a mechanism macOS runs under the name "optimization." What optimize-storage actually does macOS's "Optimize Storage" (System Settings → General → Storage → Optimize Storage), on a machine with iCloud Drive enabled, uploads files under Desktop and Documents to iCloud and deletes the local copies when free disk space gets tight . In Finder they still look like normal icons, but there is no local data — they are in a "dataless" state. Click one and it downloads automatically. For a human user, that's an acceptable tradeoff. The problem is automation scripts. python3 's open() , pathlib.Path.read_text() , cat , jq , cp — all of them die instantly on a dataless file with Errno 11: EDEADLK: Resource deadlock avoided . The name "Resource deadlock" makes you suspect a deadlock, but this is a POSIX errno code that macOS repurposes to mean "waiting for a file download." No lock is contended. No thread is stuck. The mere fact that "the data isn't local" surfaces to the process as a fatal error code. You can also get EAGAIN (resource temporarily unavailable). That one shows up as a race right after a download starts. The actual damage: four days of zero posts On August 6, 2026, note's a

2026-08-21 原文 →
AI 资讯

The Active Flag Trap: unvalidated-but-logged-in in CakeDC/Users

If you ship email validation with CakeDC/Users , you eventually hit a question the plugin quietly hands back to you: what should happen when someone registers, never clicks the validation link, and then tries to log in? The honest answer is that CakeDC/Users doesn't decide for you. Out of the box you get a database column, a couple of behaviors, and a set of events — but the experience is yours to assemble. Get it wrong and you land in one of two bad places: a user silently logged in without ever validating, or a user who typed the right password and is told "username or password is incorrect." Neither is what you want. This post walks through why that happens in v16, and a clean way to wire the flow using the events the plugin already dispatches — no core hacks, no schema surgery. One flag, two meanings Everything starts with a single boolean column on the users table: active . When email validation is on, registration creates the account with active = 0 and only flips it to 1 when the user clicks the link in the validation email. You can trace it in BaseTokenBehavior::_updateActive() : // $user['validated'] is a transient flag set to false during register() $emailValidated = $user [ 'validated' ]; if ( ! $emailValidated && $validateEmail ) { $user [ 'active' ] = false ; // registered → inactive + token emailed $user -> updateToken ( $tokenExpiration ); } else { $user [ 'active' ] = true ; // clicked the link → active $user [ 'activation_date' ] = new DateTime (); } Notice there is no separate validated column in the database — $user['validated'] is a transient property used only during registration. The persisted truth is active , and it is doing two jobs at once: "Has this person confirmed their email?" — set by the validation flow. "Is this account enabled?" — the thing an admin toggles to ban or suspend someone. That conflation is the root of everything below. Hold onto it; we'll come back to it. How the finder decides who exists Login in CakeDC/Users runs thro

2026-08-21 原文 →
AI 资讯

Show DEV: Strata – Inspect your coding agent sessions

Today we're open sourcing Strata , the session infrastructure that powers Stele. https://github.com/Stele-Dev/strata Coding agents already leave surprisingly rich trails on your computer: prompts, responses, reasoning, tool calls, results, timing, token usage, cost, injected context, subagents, and more. The problem is that every agent stores this differently. Strata turns those trajectories into one normalized CLI and TypeScript API. You can use it to: search across past sessions inspect transcripts and granular tool use see token usage, cost, and active time replay complete agent trajectories tail running sessions in real time see which agents are currently running on your machine build your own agent infrastructure on top of the same normalized data It currently supports Claude Code, Codex, Cursor, DeepSeek Harness, Gemini CLI, GitHub Copilot CLI, Kimi, OpenCode, and Pi. But things get more interesting when agents use Strata themselves . Run strata --skill and an agent can learn the CLI. Now an agent can search previous sessions to find when and how something was built, inspect the trajectory behind a decision instead of rediscovering it, or watch another agent working in a different terminal in real time. Agent A can effectively observe Agent B. A message bus is also on the roadmap, opening the door for local agents to communicate directly through Strata. We built Strata because we needed this infrastructure inside Stele. It powers Stele today, so while this is the first public release, the core has already been battle tested against real agent workloads. Everything stays on your machine. Local-only. Read-only. No telemetry. MIT licensed. Your coding agents already leave a trail. Strata makes it readable. https://github.com/Stele-Dev/strata

2026-08-21 原文 →
AI 资讯

Why I Built a Zero-Knowledge, Client-Side Encrypted Burning Note App Over the Weekend

Hey everyone! 👋 Like many developers and sysadmins, I constantly find myself needing to share temporary credentials, API keys, or sensitive text with clients and coworkers. Dropping these straight into Slack, Discord, or standard email always feels like a massive security headache because those chat platforms store everything in plain text in their databases. I looked into popular "one-time secret" web utilities, but I noticed a major flaw: almost all of them handle the encryption and decryption on their servers. That means you have to blindly trust their backend configurations, logging policies, and database security. I wanted something truly zero-knowledge where the server owner physically couldn't read the notes even if they wanted to. So, I built ScorchNote : https://scorchnote.com 🛠️ How it Works (Under the Hood) To achieve absolute zero-knowledge, ScorchNote relies on strict client-side mechanics: Browser-Side Encryption: When you type a secret, the data is encrypted directly in your browser before it ever leaves your network interface. The URL Hash Advantage: The decryption key is generated and stored inside the URL's hash fragment (everything after the # ). Zero Server Footprint: Web browsers never send the hash fragment to the host server during HTTP requests. This means my database only receives a completely scrambled, encrypted payload. The server has no concept of what the key is. Millisecond Burn-on-Read: The moment the recipient visits the link, the encrypted payload is fetched and instantly purged from the server database. 🚀 Try It Out I kept the page entirely lightweight, minimalist, and completely free of bloated tracking scripts. It’s built to do exactly one job, safely and instantly. I would love to hear your thoughts on the architecture, the user experience, or what features you think I should cook up next! Check it out here: ScorchNote

2026-08-21 原文 →
AI 资讯

Buying a phone number is a distributed transaction

The API makes it look trivial. const number = await carrier . numbers . buy ({ phone_number : " +1... " }); await db . insert ( " rented_numbers " , { user_id , e164 : number . phone_number }); await stripe . subscriptions . create ({ customer , price }); Three lines, one number, done. Ship it. What you actually wrote is a distributed transaction across three systems. They share no transaction log, they have no two-phase commit, and none of them can roll back the others. The carrier will keep charging you for a number your database has never heard of. Stripe will stop charging for a number your database still thinks is paid up. Neither one is going to mention it. I run a virtual phone number product. Below are the failure modes that actually cost us money, roughly in order of how much. The orphan taxonomy Write down the states first, because the interesting ones are the states nobody designs for. Three systems, each holding an opinion about a single number: Your DB Carrier Stripe What is actually happening active owns it active The happy path. Rare in the tail. no row owns it nothing You pay monthly rent on a number nobody can see or use. active released active You bill a customer for a number you no longer own. pending_cancellation owns it canceled Customer stopped paying. You are still paying the carrier. active owns it canceled You provide service for free, indefinitely. cancelled owns it canceled Release failed at teardown. Silent monthly bleed. Every row under the first one is reachable from a plain network timeout at a bad moment. The first orphan class is the worst, because you cannot see it from inside your own product. No row, no user, no support ticket. The number sits in the carrier's inventory producing an invoice line every month until somebody actually reads the invoice. The second class is the one that generates a complaint. The rest leak money in one direction or the other, quietly. Reconcile, don't prevent The instinct is to armour the write path. S

2026-08-21 原文 →
AI 资讯

Clean code isn't what I thought it was

What working on real systems taught me about maintainable code. My second job was the first time I worked with an international team where everyone had ten or more years of experience. I had maybe two. It was also the first time I was part of proper code reviews, branching strategies, and pull request workflows. Everything felt new and slightly intimidating. One of my first tasks was adding spacing between two elements. It should have been a simple margin or padding change, but I added a <br> tag instead. The feedback on that PR was polite but clear, and it made me a little embarrassed. That moment, along with dozens of similar ones, made me want to get better. I started reading about clean code and caring deeply about how my code looked. Small functions, no repetition, everything abstracted and organized. For a while, that served me well. It helped me grow from a junior developer into someone who could write code that passed review without a wall of comments. But over time, as I worked on larger systems with real users and real constraints, I started noticing that the rules I had learned didn't always hold up. Sometimes the "clean" approach made things worse, and sometimes messy-looking code worked better than the elegant version I would have written. This post is about how my definition of clean code expanded. I still believe in the principles I learned early on. I'd just add a few things to them now. What I thought clean code meant When I first started paying attention to code quality, my idea of clean code was mostly about appearances. If the code looked organized and followed certain patterns, it was clean. If it didn't, it wasn't. I believed in small functions for everything. If a function was longer than fifteen or twenty lines, something was wrong. I would extract pieces into helpers even when they were only used once, just because the parent function felt "too long." I was strict about DRY. Any time I saw similar logic in two places, I would immediately pul

2026-08-21 原文 →