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

标签:#EV

找到 3282 篇相关文章

AI 资讯

Parsing and Rebuilding EPUB Files in Python: Lessons Learned from Building an AI Translation Service

How we extract, translate, and reconstruct entire ebooks with Python while preserving every detail At LectuLibre, we built a service that translates entire books using large language models. Our users upload EPUB files, and our backend pipeline parses them, extracts the text, sends it to an LLM for translation, and then rebuilds the EPUB with the translated content—all while preserving the original formatting, images, and metadata. This sounded straightforward until we looked inside a real EPUB. EPUB is essentially a ZIP file containing a structured set of XHTML, CSS, and XML files. The content.opf file defines the reading order (spine), metadata, and manifest. The toc.ncx holds the table of contents. The actual text lives in XHTML documents, often split per chapter. To translate a book, we needed to: 1) reliably parse the EPUB, 2) locate all translatable text, 3) send it chunk by chunk to the LLM, and 4) rebuild the EPUB with the translated text while keeping every byte of the formatting intact. The Problem with Off-the-Shelf Libraries We initially reached for ebooklib , the most popular Python library for EPUB manipulation. It worked great for simple EPUBs—until we threw a few hundred real-world files at it. We quickly hit issues: Metadata loss : ebooklib didn’t fully preserve custom metadata or namespace-prefixed properties in the OPF. Namespace handling : When modifying XHTML, it could strip or mangle xmlns attributes, breaking rendering on some devices. TOC and spine sync : After rebuilding, the table of contents and spine often got out of sync unless we manually repaired them. Large files : Processing a 200‑chapter book consumed surprising memory because ebooklib loaded everything at once. We could have used a heavyweight tool like Calibre’s command-line interface, but that introduced external dependencies and wasn’t as programmatically flexible. Instead, we decided to stick with ebooklib for high-level book structure and augment it with lxml for precise XML c

2026-06-20 原文 →
AI 资讯

How AI Will Shape the Technology Industry in 2027

How AI Will Shape the Technology Industry in 2027 We're roughly 6 months out from 2027, and the signals are already converging: AI is not coming — it has arrived, and the next wave will be fundamentally different from everything that came before it. For developers and tech professionals, 2027 isn't a distant horizon. It's the next major inflection point to prepare for now. Here's what the research, analysts, and industry leaders are saying about what's ahead. From General-Purpose to Task-Specific: The Enterprise AI Shift One of the clearest signals comes from Gartner (April 2025): by 2027, organisations will use small, task-specific AI models three times more than general-purpose large language models. The era of "one model to rule them all" is already ending at the enterprise level. Companies are learning that a fine-tuned, domain-specific model trained on their proprietary data consistently outperforms a generic LLM on their specific workflows. Faster, cheaper, more accurate, and harder for competitors to replicate. For developers, this has real implications: Skills in fine-tuning, RAG (retrieval-augmented generation), and model evaluation become more valuable than prompt engineering alone The ability to build and maintain internal AI pipelines on private data will be a core engineering competency Generic API integrations to OpenAI or Anthropic get replaced — or layered under — proprietary model infrastructure The companies building and maintaining these specialised models will have durable competitive advantages. The ones that don't will be running on shared infrastructure that their competitors can access equally. The Macroeconomic Wake-Up Call: AI Hits GDP in 2027 Goldman Sachs projects that AI may start to meaningfully boost US GDP in 2027 — marking the first measurable macroeconomic signal of the current AI wave. Paired with estimates that ~25% of tasks in advanced economies could be automated by 2027 (10–20% in emerging markets), the scale of workforce restr

2026-06-20 原文 →
AI 资讯

Your Pink Slip Is an Algorithm — What the AI & Jobs Debate Means for Developers

AI isn't coming for your job. It already showed up, merged its first PR, and doesn't need a code review. The question developers keep dancing around — but rarely say out loud — is this: If GitHub Copilot, Cursor, and Claude can do what a junior dev does in a fraction of the time, what happens to junior devs? And more uncomfortably: what happens to mid-level devs in three years? The Uncomfortable Data Points This isn't speculation. It's already showing up in hiring data. Entry-level developer roles are contracting. Stanford's Digital Economy Lab (2025) found measurable decline in entry-level employment in AI-exposed roles — and software development is one of the most exposed. One senior dev + AI tools = the output of a small team. Brynjolfsson, Li & Raymond (NBER, 2023) showed generative AI productivity gains that compress what used to require multiple headcount into one. Goldman Sachs (2023) estimated significant white-collar labour market exposure — knowledge workers, not factory workers, are the primary target this time. This isn't the loom replacing weavers. It's the IDE replacing the person using the IDE. The Counter-Argument (And It's Not Weak) Here's where it gets interesting — because the doomsayer take isn't the whole story either. Every major technology wave destroyed jobs and created more than anyone predicted: The ATM didn't eliminate bank tellers — it lowered branch costs, banks opened more branches, teller roles increased for a decade The spreadsheet didn't kill accountants — it created an entire industry of financial analysts The internet didn't destroy publishing — it exploded the number of people who could publish The argument: AI raises developer productivity so dramatically that it expands the total addressable market for software. More products get built. More tools get created. More companies can afford to build what previously required a $500k engineering team. More demand for developers, not less. Where It Gets Complicated for Devs Specifically

2026-06-20 原文 →
AI 资讯

How to Access 50+ Chinese AI Models With One API — No Code Changes Required

If you've been following the AI market lately, you already know the headline numbers: DeepSeek V4 costs about 3% of what GPT-4o charges per token. GLM-4 runs benchmarks competitive with GPT-4 at roughly one-twentieth the price. Qwen delivers multilingual performance that rivals Claude for a rounding error in your cloud bill. The spreadsheets look incredible. The problem is actually using these models. Signing up for each provider means navigating Chinese-language dashboards, topping up separate wallets, managing six different API key formats, and dealing with SDKs that don't follow any consistent convention. Most developers give up after the second integration. That friction is why, despite the economics being objectively absurd in 2026, most teams still default to a single Western provider and eat the cost. AIWave exists to kill that friction. One API key. One endpoint. Fifty-plus models across eight Chinese labs, all speaking standard OpenAI-compatible format. Zero code changes to switch between DeepSeek, GLM, Qwen, MiniMax, and everything else. This post covers how the platform works under the hood, what the request lifecycle looks like, and how to integrate it in any language that can speak HTTP. The Fragmentation Problem, Quantified Before getting into the solution, here's what the Chinese LLM landscape actually looks like as of June 2026: Provider Flagship Model API Format Auth Method SDK Language DeepSeek V4-Pro Custom (DS format) Bearer token + signature Python, JS Zhipu GLM-4.5 OpenAI-compatible-ish JWT with expiry Python, Java Alibaba Qwen-3-Max DashScope (Alibaba) AK/SK + HMAC Python, Java, Go MiniMax MiniMax-Text-01 Custom REST API Key + Group ID Python Moonshot Kimi-K2 OpenAI-compatible API Key Python, JS Baidu ERNIE 4.5 Qianfan (Baidu) OAuth 2.0 Client Cred Python ByteDance Doubao-Pro Ark (Volcengine) IAM AK/SK + SigV4 Python, Go 01.AI Yi-Lightning OpenAI-compatible API Key Python Eight providers, seven different authentication schemes, four distinct A

2026-06-20 原文 →
AI 资讯

How to Access 50+ Chinese AI Models Through One API — No Code Changes Required

If you've been following the AI market lately, you already know the headline numbers: DeepSeek V4 costs about 3% of what GPT-4o charges per token. GLM-4 runs benchmarks competitive with GPT-4 at roughly one-twentieth the price. Qwen delivers multilingual performance that rivals Claude for a rounding error in your cloud bill. The spreadsheets look incredible. The problem is actually using these models. Signing up for each provider means navigating Chinese-language dashboards, topping up separate wallets, managing six different API key formats, and dealing with SDKs that don't follow any consistent convention. Most developers give up after the second integration. That friction is why, despite the economics being objectively absurd in 2026, most teams still default to a single Western provider and eat the cost. AIWave exists to kill that friction. One API key. One endpoint. Fifty-plus models across eight Chinese labs, all speaking standard OpenAI-compatible format. Zero code changes to switch between DeepSeek, GLM, Qwen, MiniMax, and everything else. This post covers how the platform works under the hood, what the request lifecycle looks like, and how to integrate it in any language that can speak HTTP. The Fragmentation Problem, Quantified Before getting into the solution, here's what the Chinese LLM landscape actually looks like as of June 2026: Provider Flagship Model API Format Auth Method SDK Language DeepSeek V4-Pro Custom (DS format) Bearer token + signature Python, JS Zhipu GLM-4.5 OpenAI-compatible-ish JWT with expiry Python, Java Alibaba Qwen-3-Max DashScope (Alibaba) AK/SK + HMAC Python, Java, Go MiniMax MiniMax-Text-01 Custom REST API Key + Group ID Python Moonshot Kimi-K2 OpenAI-compatible API Key Python, JS Baidu ERNIE 4.5 Qianfan (Baidu) OAuth 2.0 Client Cred Python ByteDance Doubao-Pro Ark (Volcengine) IAM AK/SK + SigV4 Python, Go 01.AI Yi-Lightning OpenAI-compatible API Key Python Eight providers, seven different authentication schemes, four distinct A

2026-06-20 原文 →
AI 资讯

Why I scrub AI prose with regex, not a second LLM

Written by Stephanie Dover, Software Engineer 10+ YOE, ex GitHub, Twitch, Microsoft. Creator of Klaussy. LinkedIn · GitHub · Klaussy Desktop · Klaussy Agents TL;DR klaussy-agents is a free, MIT-licensed CLI ( pip install klaussy-agents ) that makes the prose an AI coding agent writes, PR comments, review notes, commit messages, read like a person wrote them. It works in two layers: a humanization spec baked into the agent's skills so it writes clean prose up front, and a deterministic klaussy humanize pass that scrubs the output afterward. The scrubber is rule-based regex, not an LLM, and it never touches code. There's also a part I didn't expect going in: once the AI tells are gone, what's left can read curt and run long, so the spec also handles tone (don't be rude) and length (one sentence for a reply, one to five for a review comment). Repo: github.com/steph-dove/klaussy-agents. The problem You can spot AI-written text now. Everyone can. And the place it grates most is a code review comment or a commit message, where the prose sits next to your name in a thread your teammates read. The tells are consistent. The em-dash is the biggest one. Right behind it: filler openers like "It's worth noting that…" and "I wanted to point out that…", chatbot scaffolding like "Hope this helps!" and "Let me know if you have questions!", and stacked hedges like could potentially . An agent that leaves those in your PR reads like a bot, and people notice. The obvious fix is to tell the model not to do it. Add "don't sound like AI" to the prompt and move on. That helps, inconsistently, and it regresses silently the moment you change the model or the prompt drifts. Editing every comment by hand works too, but hand-editing every comment defeats the point of having an agent write them. I wanted something I could trust without rereading. Why "just tell the model" wasn't enough The honest answer to "why not just prompt for it" is: a prompt asks, it doesn't enforce. The model tries to com

2026-06-20 原文 →
AI 资讯

Event-Handling-Basics

Event Handling Basics in euv Project Code: https://github.com/euv-dev/euv euv is a Rust + WASM frontend UI framework that enables developers to build interactive web applications using the power of reactive signals and the html! macro. One of the most critical aspects of any UI framework is how it handles user interactions. In this article, we will take a deep dive into euv's event handling system — from inline closures to native event handlers, from input events to form changes, and from the comprehensive list of supported event names to utility functions that simplify common patterns. Table of Contents Inline Closure Events NativeEventHandler Input Events Form Change Events Supported Event Names Accessing Event Data Utility Functions for Event Handling Putting It All Together Inline Closure Events The most straightforward way to handle events in euv is through inline closures. You define the event handler directly within the html! macro using the move |event: Event| { ... } syntax. html! { button { onclick : move | event : Event | { } "Click me" } } This pattern is ideal for simple, self-contained event handlers that don't need to be reused across multiple components. The move keyword ensures that any captured variables (like signals) are moved into the closure, which is essential for the Rust ownership model. Inline closures work with any event type — not just onclick . You can use them for keyboard events, focus events, mouse events, and more. The closure receives an Event object that you can inspect to extract relevant data. NativeEventHandler For more complex scenarios where you need reusable event handlers or want to define handlers outside the html! macro, euv provides the NativeEventHandler type. This allows you to create named, parameterized event handler functions. pub fn counter_on_increment ( counter : Signal < i32 > ) -> NativeEventHandler { NativeEventHandler :: create ( "click" , move | _event : Event | { let current : i32 = counter .get (); counter

2026-06-20 原文 →
AI 资讯

Stop Wasting Tokens: I Built a File-Mapping Standard for AI-Assisted Development

Every time I started a new AI chat session, it read my entire codebase. 50 files. Thousands of tokens. On every single message. Whether I was asking about authentication, database schema, or a single UI component — the AI read everything. I'm 16 and building AI-powered products. Token costs add up fast. Context windows fill up. The AI loses track of older files. Responses slow down. So I built something to fix it. The Problem When you work with AI on large projects, you face a choice: Give the AI too much context → burns tokens, hits context limits, slower responses Give it too little → AI misses important files, makes wrong assumptions There's no middle ground — or at least there wasn't. Introducing FolioDux FolioDux is a lightweight, open-source file-mapping standard for AI-assisted development. The idea is simple: instead of giving your AI every file, you give it a compact index that tells it where everything is and what it does . The AI reads the index first, identifies the relevant files, and reads only those. One file. Two rules. Any AI. It works with Claude, ChatGPT, Gemini, Cursor, Copilot — any tool that accepts a system prompt. How It Works You add one file — FOLIODUX.md — to your project root. # FOLIODUX · TaskFlow · v1.0 · 2026-06-18 · 17 files STACK: React19+TypeScript+Vite · Express+SQLite · JWT --- ## TASKS auth/login/register → AuthView.tsx, authService.ts, server.ts create/edit task → TaskForm.tsx, taskService.ts, server.ts, types.ts list/filter tasks → TaskList.tsx, taskService.ts database → db.ts, server.ts --- ## INDEX App.tsx | fe | root: routing, auth state, layout wrapper AuthView.tsx | fe | login + register forms, error display taskService.ts | svc | CRUD tasks, local cache, optimistic updates server.ts | be | Express: all routes — auth, tasks, projects, user db.ts | be | SQLite setup, schema creation, migrations on boot types.ts | typ | Task, Project, User, Status(todo|in-progress|done) --- ## GROUPS Frontend: App.tsx · AuthView.tsx · TaskLi

2026-06-20 原文 →
AI 资讯

Humanizing Artificial Intelligence in DevOps Documentation: Making Runbooks Easier to Create and Use

The Runbook That Lied to Me at 3am The pager went off at 3:14am for a wedged OpenStack Neutron agent. I did what any tired engineer does: I opened the runbook. It told me to restart a service that had been renamed eighteen months earlier, pointed at a Grafana dashboard that 404'd, and assumed a network topology we'd migrated off of two quarters back. The runbook wasn't just unhelpful. It was actively lying to me, and I burned twenty minutes trusting it before I gave up and went to read the source. That's the real problem with documentation. It isn't that we don't write it. It's that the moment we finish writing it, it starts rotting, and the cost of keeping it fresh is high enough that nobody pays it until the document has already betrayed someone at 3am. A runbook your team doesn't trust is worse than no runbook, because no runbook at least forces you to think. This is where AI actually earns its keep in a platform org, and not in the way the marketing decks suggest. AI is not going to own your documentation. It's going to do the tedious first-draft labor — turning a resolved incident, a chunk of shell history, or a deploy diff into a structured skeleton — so a human engineer can spend their scarce attention on the part that matters: verifying the commands, marking what's unproven, and editing the robotic tone out so the team actually reads it. AI drafts. You verify and sign off. That distinction is the whole game. Why "Humanizing" AI Is the Job, Not a Slogan Let me be precise about what I mean by "humanizing AI," because the phrase gets abused. I don't mean making AI sound human to fool a reader. I mean keeping a human in the loop as the editor and owner of record, and doing the unglamorous work of turning a competent-but-soulless machine draft into something a colleague trusts. Two things break trust in AI-drafted docs, and both are fixable by a human pass: Unverified claims stated with confidence. An LLM will happily tell you to run systemctl restart neutron-l3-

2026-06-20 原文 →
AI 资讯

Migrating Ekehi from Vanilla JS to a TypeScript Stack

Ekehi platform has moved from hand-written HTML/CSS/JS pages to a typed, component-driven React 19 client and a module-based TypeScript Express/Node.js API. 0. Where we started and where we landed Before. A static client built from per-page folders ( landing/ , contributors/ , login/ , signup/ , admin/ ), each shipping its own index.html , a shared styles.css , and vanilla ES module scripts under client/shared/ . The server was an Express API written in plain JavaScript. After. Layer Before After Client Static HTML + CSS + vanilla JS React 19 + Vite 8 + TanStack Router + TypeScript 6 Styling One global styles.css Tailwind CSS 4 with @theme design tokens Data fetch scattered per page TanStack Query over a typed lib/api client Server Express in JavaScript Express + TypeScript, module-per-domain Repo Two loose folders pnpm workspace with shared git hooks Quality gate None ESLint 9, Prettier 3, Husky, commitlint, Vitest The migration ran in two phases on separate branches: **Phase 1 — client rewrite. **Phase 2 — server rewrite. 1. Why this framework? Choice: React 19 , rendered as a client-side SPA through Vite 8 , routed by TanStack Router . TanStack Router was chosen rather than React Router because it gives fully type-safe routes, first-class search-param typing, built-in code-splitting, and file-based route generation that pairs cleanly with Vite. 2. The folder and component structure The client uses a feature-sliced layout: code is grouped by domain, not by technical type. client/src/ ├── components/ │ ├── layout/ navbar.tsx, footer.tsx │ └── ui/ button, input, modal, select, dropdown, ... (design system) ├── config/ env.ts, env-schema.ts, endpoints.ts ├── features/ one folder per domain │ ├── auth/ auth.query.ts, auth.service.ts, auth.types.ts, components/, pages/ │ ├── opportunities/ pages/ │ ├── resources/ pages/ │ ├── submissions/ pages/ │ ├── admin/ pages/ │ └── site/ pages/ (landing, contributors) ├── lib/ │ ├── api/ request.ts, errors.ts, refresh.ts, types.t

2026-06-20 原文 →
AI 资讯

Building SyncCanvas: An AI-Powered Real-Time Collaborative Whiteboard

Modern collaboration needs more than documents and chat messages. Teams need a shared visual space where ideas can be created, organized, and refined together in real time. That's why I built SyncCanvas — an AI-powered collaborative whiteboard that combines real-time multiplayer collaboration, infinite canvas drawing, and AI-assisted brainstorming into one modern workspace. The Problem Most collaboration tools focus on only one aspect of teamwork. Some are great for drawing. Others are excellent for documentation. AI tools often live in separate windows, disconnected from the creative workflow. I wanted a platform where teams could brainstorm visually while AI actively helped generate and organize ideas directly on the canvas. Introducing SyncCanvas SyncCanvas is an infinite multiplayer whiteboard designed for students, developers, teams, and creators. Key features include: Real-time collaboration with live synchronization Infinite canvas with pan and zoom Drawing tools, shapes, text, and sticky notes AI-powered content generation using Gemini Private room sharing Guest mode access PNG export support WiFi Rooms for local collaboration Real-Time Collaboration Collaboration is at the heart of SyncCanvas. Using Yjs and WebSockets, multiple users can work on the same board simultaneously while seeing updates instantly. Users can: View live cursors Track online participants Join private rooms using secure room codes Collaborate anonymously through guest mode This creates a seamless experience similar to working together in the same room. Infinite Canvas Experience The whiteboard is designed to be limitless. Users can: Draw freehand sketches Create rectangles and circles Add text elements Organize ideas with sticky notes Move freely across an infinite workspace Export workspaces as images The canvas is powered by Fabric.js, providing smooth rendering and flexibility for future enhancements. AI-Powered Brainstorming One of the most exciting features is the integration of G

2026-06-20 原文 →
AI 资讯

I built a Chrome extension that catches every dark pattern trick on shopping sites. Here's exactly how.

A few months ago I was about to buy a flight. The page showed "Only 2 seats left at this price" in red letters. I hesitated, then refreshed the page out of curiosity. The counter said "Only 2 seats left" again. Same number. It had been resetting on every page load the whole time. That's when I started cataloguing every trick I'd seen on shopping sites and built a Chrome extension that flags them automatically, in real time, on any page. This isn't just my opinion — it's documented research In 2019, Princeton and University of Chicago researchers scraped 11,000 shopping sites and found dark patterns on more than 1,250 of them. The FTC has since fined several companies specifically for fake countdown timers and pre-checked subscription boxes. This isn't a grey area anymore — it's a known, studied, and increasingly regulated practice. The extension targets four categories that account for most of what's out there. The four patterns Fake urgency. Countdown timers that reset, "X people are viewing this" badges that never change, "only N left in stock" that's been static for a week. Trap checkboxes. A checkbox for "Yes, sign me up for the newsletter" that's pre-checked and styled to blend into the page so you don't notice it. Confirmshaming. The decline button reads "No thanks, I don't want to save money" instead of just "No thanks." Psychological pricing. Prices ending in .99 or .95 designed to register as a lower price bracket than they are. Why no AI this time My phishing detector used Claude because language and intent are genuinely ambiguous — you need a model that understands context. Dark patterns are different. They're structural. A countdown timer either resets on reload or it doesn't. A checkbox is either pre-checked or it isn't. That's a DOM query, not a judgment call. So this one runs entirely on regex and DOM inspection. No API calls, no latency, no cost per scan, works offline. Sometimes the boring solution is the correct one. Detecting the urgency pattern T

2026-06-20 原文 →
AI 资讯

Runbook Hygiene: Why Yours Are Lying to You

Your runbooks are out of date. I don't know your team, but I'd bet money on it. Most teams write runbooks once, in a panic after an outage, and then never touch them again until the next outage proves them wrong. How runbooks rot Steps reference deprecated tools. The grafana dashboard moved, the CLI command was renamed, the bastion host got retired. Nobody updated the runbook because nobody re-ran it during the calm months. The team that owned the system left. Three of the five engineers who wrote it are gone. The remaining two haven't actually run the runbook in 18 months because the outage type it covers stopped happening. Half-truths from the start. The original author skipped the obvious steps (because they were obvious to them) and the new on-call engineer can't reproduce the recovery. The result: at 2 AM during the actual incident, the runbook sends you down a dead end. Now you're improvising under stress. What working runbooks have in common I've seen exactly two patterns work: 1. Runbooks live with the code. Put them in the repo of the system they document. When the code changes, the runbook PR is part of the same review. Out-of-repo wikis die first because the cognitive distance is too great. 2. Runbooks are reviewed by people who weren't there. Have a junior engineer run through the runbook quarterly on a non-incident day. Every place they get stuck is a real bug in the document. Fix it then. The author will be too close to see the gaps. The three sections that matter A useful runbook has exactly three sections: Symptom : how do I know this is the right runbook? Concrete signals, with example screenshots if visual. First 5 minutes : what to do RIGHT NOW to stop the bleed. Not the root cause investigation, just the triage actions. Investigation : where to look, what queries to run, what to escalate. That's it. Anything else (architecture diagrams, history, philosophy) goes in a separate doc that the runbook links to. The cultural part The hardest part isn't

2026-06-20 原文 →
AI 资讯

My API Responded in 4 ms, but Navigation Still Felt Slow

I was debugging an internal project management application built with SvelteKit and a Rust API. Locally, navigation felt almost instant. On the VPS, opening the Tickets, Timeline, and OpenSpec docs pages felt noticeably slower. Clicking a ticket also took too long before the preview panel became useful. My first assumption was infrastructure: Maybe the VPS was underpowered. Maybe PostgreSQL queries were slow. Maybe the reverse proxy added latency. Maybe SvelteKit SSR was taking too long. The measurements pointed somewhere else. The Baseline I started with the feature list endpoint used by both Tickets and Timeline. For a project with 52 tickets: Metric Result API response time ~4 ms Response size 353,956 bytes Number of tickets 52 The API was not slow. But it was returning around 354 KB for a list of only 52 items. The SvelteKit route payload showed the same pattern: Route Data payload Tickets 349,857 bytes Timeline 354,731 bytes This explained why local testing was misleading. On localhost, transferring and parsing a few hundred kilobytes is easy to miss. Once the app runs behind a VPS, reverse proxy, TLS, and a real network connection, the payload becomes much more visible. What Was Inside the Payload? I broke down the feature response by field. The descriptions alone accounted for: 296,177 bytes That was more than 80% of the complete response. The list endpoint was returning something similar to this for every ticket: interface FeatureListItem { id : string ; title : string ; status : string ; priority : string ; storyPoints : number | null ; dueDate : string | null ; description : string | null ; checkoutCommand : string | null ; openSpecCommand : string | null ; } The problem was not that these fields were useless. They were useful on the ticket detail panel. They were not useful when rendering the initial list. Timeline was even more wasteful. It used ticket status, dates, dependencies, and assignees, but still downloaded every full Markdown description. The D

2026-06-20 原文 →
AI 资讯

No user verification leading to subscription bypass and pre-register

For security reasons, we consider "Target app", as the target we practiced on, and the real name won't be disclosed in this post. The target app, was a niche music streaming platform, available in web and mobile PWA, meaning the structure is same but access is easier for cross platform. The app worked in this way : You register using an account, 3rd party like google or via email After that you can use the app for free with a 3 day window (3 day trial) After the 3 day you gotta buy subscription to continue listening The flaw, existed in the first step, when you register using an email, no verification happens! You could enter any type of string@something.com , a random password and start your free trial. So what happens is that first I use string1@something.com , for 3 days. When the time runs out, I use string2@something.com for another 3 days. And since the app's trial and actual subscription don't have any difference, and the 3 day time window is the only limitation, the user with such knowledge from the app doesn't need to buy any subscriptions while such flaw exists! Mitigation : Apply email verification step after user input, so they have to use the received link to verify their address Blacklist "temporary email" service's address or IPs, so users won't generate any email to register after their trial has expired. This way, the registration process isn't too complex while keeps app from attackers avoiding a "For ever free" usage on the app.

2026-06-20 原文 →
AI 资讯

Pro File Uploads in Rails 8: Speed and Scalability with Direct Uploads

Imagine a user trying to upload a 100MB video or a high-resolution photo to your app. If you use the standard Rails file upload, that file travels from the user's browser to your Rails server, and then your server sends it to S3 or Google Cloud. This is a terrible way to do it. While that 100MB file is transferring, your Rails worker (Puma) is frozen. It can't handle other users. If three people upload large files at once, your whole app will stop responding. In 2026, the professional way to handle this is Direct Uploads . With Direct Uploads, the file goes directly from the user's browser to your cloud storage (S3, R2, etc.). Your Rails server only handles a tiny bit of metadata. It is faster for the user and much safer for your server. Here is how to set it up in Rails 8. STEP 1: Configure Your Storage First, make sure you aren't using the local disk for production. You need a cloud provider like AWS S3 or Cloudflare R2. In your config/storage.yml : amazon : service : S3 access_key_id : <%= ENV['AWS_ACCESS_KEY_ID'] %> secret_access_key : <%= ENV['AWS_SECRET_ACCESS_KEY'] %> region : us-east-1 bucket : my-app-uploads # Crucial for Direct Uploads! public : true Note: You must configure CORS in your S3/R2 dashboard to allow requests from your domain. If you don't do this, the browser will block the upload. STEP 2: The Rails Form Rails makes the backend part incredibly easy. You just add one attribute to your file field: direct_upload: true . <!-- app/views/users/_form.html.erb --> <%= form_with ( model: user ) do | f | %> <div class= "field" > <%= f . label :avatar %> <%= f . file_field :avatar , direct_upload: true %> </div> <%= f . submit "Save Profile" %> <% end %> When you add direct_upload: true , Rails automatically includes a JavaScript library that handles the "handshake" with S3. STEP 3: Adding a Progress Bar (The UX Win) Direct uploads can take a few seconds. If nothing happens on the screen, the user will think your app is broken. We can use the built-in Ac

2026-06-20 原文 →
AI 资讯

Why I stopped reading my own backlog.md (and what I read instead)

The morning my own file lied to me Wednesday, May 21, start of session, coffee next to the keyboard. I ask the agent where we stand on the DEV.to series. Clean answer, articulated, "Four articles on stand-by, ready to publish." I reread. Half a second of unease, because I think I saw two or three of them go through DEV.to last week, but I slept in between and I'm no longer sure. I type the question that changes everything, "Are you sure articles remain to publish?" The agent re-queries the DEV.to API in parallel, opens scripts/devto/state.json , crosses the two. The four articles have been published for two or three days. What I just read wasn't a hallucination. The agent did exactly what was expected of it, namely open articles/backlog.md , read the table, restitute what it said. I'm the one who had stopped updating that file. sync-backlog.ts hadn't run after the pushes of last week. The markdown said "stand-by" while production said "published" . The typist didn't lie. She read faithfully a file I had written myself and that I was treating as authority while nothing was maintaining it. A summary is a Cache without a refresher This is the most common failure mode of a solo project that lasts. Each day produces two flows. On one side the matter that moves, made of commits, deploys, rows in the database, statuses that transition. On the other side the writings we draft to keep our bearings, namely backlog.md , the root MEMORY.md , the Sunday-night session note, the README of the folder we refactored last week. These writings are produced quickly, in the gesture that closes a sprint, and they are maintained slowly, or not at all, because nothing in the pipeline triggers to close them. R6 of the Counterpart Toolkit says it for SQL columns, Live / Snapshot / Cache mandatory . Any column derivable from other data must declare its category in the commit that creates it. If it's a Cache, the refresher mechanism ( GENERATED ALWAYS AS , SQL trigger, materialized view with pl

2026-06-19 原文 →
AI 资讯

Ship an AI agent without a kill switch and you are the incident

A finance bot kept issuing refunds in a loop because nobody built a way to stop it. Clean code. Sound logic. No off switch. A small bug became a long night. Here is the opinion most teams do not want to hear. Building the agent is the easy 80 percent. That off switch is the 20 percent that decides whether you can ship it at all. We celebrate the wrong milestone. Picture the demo where the agent books the meeting, writes the email, updates the record. That part is genuinely fun to build and genuinely easy now. Harder is the boring question nobody claps for. What happens when it is wrong, fast, and confident. An AI agent is not a chatbot. It takes actions in the real world. It spends money, deletes rows, messages real people, moves files. Wrong answers in a chat are annoying. A wrong action at machine speed is an incident with your name on it. So before features, I build the stop. One real kill switch is not a single button. Think of it as a small set of bounds that live from the first version. A spend ceiling, so a retry loop cannot drain the account A blast radius limit, so one task can never touch more than it should A human gate on anything irreversible, so the agent proposes and a person commits A global stop that halts everything in one move, with no redeploy None of that is glamorous. All of it is what lets you sleep at night. Teams skip this for a reason that feels rational in the moment. Bounds feel like negative work. They never show up in the demo. Your agent runs fine without them right up until the one time it does not, and that one time is the only time anyone remembers. Here is the reframe that changed how I build. Treat the stop as the feature that makes an agent shippable. Bolt it on at the end and you have already shipped a liability that happens to pass the demo. Honest about the trade-off. Bounds slow you down. You will watch the agent pause for an approval it could technically have skipped, and it will feel like friction. That friction is the pric

2026-06-19 原文 →