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

标签:#acti

找到 59 篇相关文章

AI 资讯

# 🚀 C++ Abstraction Cheat Sheet: 10-Minute Interview Revision Guide

If you have an interview in the next few hours and need to quickly revise Abstraction in C++ , this guide is for you. No long theory. No unnecessary examples. Only the concepts interviewers expect you to know. 📌 What is Abstraction? Definition Abstraction is the process of exposing only the essential behavior of an object while hiding unnecessary implementation details. Remember WHAT ↓ Hide HOW The user knows what an object can do, but not how it performs the work. ❓ Why Do We Need Abstraction? Without abstraction: Every developer needs to understand internal implementation. Client code becomes tightly coupled. Maintenance becomes difficult. With abstraction: Developers interact with a simple interface. Internal implementation can change without affecting users. Systems become easier to extend and maintain. Benefits ✅ Reduces complexity ✅ Promotes loose coupling ✅ Improves maintainability ✅ Supports extensibility ✅ Enables cleaner architecture ⚙️ How Does C++ Achieve Abstraction? C++ primarily achieves abstraction using: Abstract Class + Pure Virtual Functions + Runtime Polymorphism 🏗️ What is an Abstract Class? An abstract class is a class that contains at least one pure virtual function . It represents a: ✅ Contract ✅ Blueprint ✅ Common capability Because it is incomplete , it cannot be instantiated . 🎯 What is a Pure Virtual Function? Syntax virtual ReturnType functionName () = 0 ; Meaning It tells the compiler: Every concrete derived class must implement this function. = 0 does NOT mean "return zero." It simply marks the function as pure virtual . 🧠 Mental Model Think of it like this: Job Description ↓ Employee The job description defines responsibilities. Each employee fulfills those responsibilities differently. Or: Blueprint ↓ House You don't live inside a blueprint. You build a house from it. Similarly, you don't create objects of an abstract class—you create objects of concrete derived classes. 🏭 Practical Software Example Imagine an e-commerce application

2026-07-15 原文 →
AI 资讯

Microsoft Patches a Record 570 Security Flaws

Microsoft Corp. today released software updates to plug at least 570 security holes in its Windows operating systems and other software, almost triple the number of vulnerabilities the software giant fixed in its record-smashing Patch Tuesday release last month. Microsoft attributed the burgeoning patch counts to vulnerability discoveries aided by artificial intelligence.

2026-07-15 原文 →
AI 资讯

Migrating from Auth0 Rules to Actions: a Practical Guide for Real-World Teams

Auth0’s direction is clear: new extensibility work should be built with Actions, not Rules. Auth0’s docs recommend migrating existing logic step by step, converting pieces of Rule code into Action code, testing in staging, and then rolling out one piece at a time. The platform also highlights that Actions give you modern JavaScript, inline documentation, richer type information, and access to public npm packages. I recently looked at the migration path with one question in mind: how do you move from “old but working” to “clean, testable, future-proof” without breaking login flows? This post is the practical version of that answer. Why Auth0 moved from Rules to Actions Rules were Auth0’s earlier customization layer for authentication flows. Actions are the next-generation extensibility platform, built to replace that model with a more structured developer experience. Auth0 positions Actions as a unified environment with version control, debugging, caching, Node 18 support, and access to millions of npm packages. The biggest shift is not just syntactic. Actions use a modern, promise-based programming model and are organized around triggers such as Post Login. That means you are no longer writing the same kind of callback-style Rule you may have used before; you are moving into a more explicit and modular workflow. The mental model change A Rule usually looks like this: it receives user , context , and callback it runs in a broader authentication pipeline it often mixes business logic with token customization, user metadata updates, and side effects An Action, by contrast, is built around a trigger such as onExecutePostLogin , and it receives an event object plus an api object. Auth0’s migration guide explicitly recommends converting Rule code into Action code in stages rather than copying everything at once. That one change matters because it forces you to separate concerns: what is read from the event what is changed through the API what should happen in this trigger

2026-07-12 原文 →
AI 资讯

Git: The Fellowship of the Commit – Best Practices for Solo Devs and Teams

The Quest Begins (The "Why") I still remember the first time I tried to track down a bug that only showed up after midnight. I opened my terminal, typed git log , and was greeted by a wall of commits that read like a toddler’s grocery list: * 7a9c3f1 (HEAD -> main ) fix stuff * 4b2e8a1 update * f1d9c6b wip * 9e3b7d2 more changes * … I spent three hours chasing a regression that turned out to be a one‑line typo in a file I hadn’t touched in weeks. The commit messages gave me zero clues, and the diff was a tangled mess of unrelated changes. I felt like I was wandering through a dungeon without a map, hoping the next room would hold the answer. That night I realized the real monster wasn’t the bug—it was the way I was committing code. My commits were large, vague, and scattered , making every subsequent step (review, revert, bisect) a gamble. If I wanted to keep my sanity (and maybe even enjoy coding again), I needed a better system. The Revelation (The Insight) The turning point came when I read about Conventional Commits —a lightweight convention that gives each commit a clear type ( feat , fix , docs , refactor , test , chore , etc.) and a short, descriptive message. It sounded simple, but the impact was massive: Atomicity – each commit does one thing. Clarity – the message tells you why the change exists, not just what changed. Automation – tools can generate changelogs, version bumps, and even release notes straight from the log. Adopting this felt like discovering a hidden shortcut in a Zelda dungeon—suddenly the whole map made sense, and I could sprint to the boss room with confidence. Wielding the Power (Code & Examples) Before – The Chaos Imagine we’re building a tiny API for user profiles. Here’s what a typical day of committing looked like (messages only, but the diffs were just as messy): $ git log --oneline -5 7a9c3f1 ( HEAD -> main ) fix stuff 4b2e8a1 update profile handler f1d9c6b wip 9e3b7d2 added auth middleware c5d4e3f refactor utils If I needed to ro

2026-07-12 原文 →
AI 资讯

littlebag Creator Seeks User Feedback to Validate 343-Byte UI Framework's Utility Despite Performance Limitations

Introduction: Unveiling littlebag Meet littlebag , a reactive UI framework that defies conventional expectations by packing essential features into a mere 343 bytes (minified and brotlified). This isn’t just a technical curiosity—it’s a proof of concept that challenges the notion that UI frameworks must be bloated to be functional. littlebag includes: Reactive state management via state and effect , enabling dynamic updates without manual DOM manipulation. An html element factory that inherently supports reactivity, reducing boilerplate code. Conditional rendering with keyed , allowing efficient updates to specific UI segments. Reactive lists using each , simplifying the handling of dynamic data collections. TypeScript declarations , ensuring type safety and developer productivity. The framework’s size is achieved through aggressive tree-shaking and code minimization , stripping away all non-essential logic. However, this comes at a cost: performance limitations due to the absence of optimizations like virtual DOM diffing or batch updates . Each reactive update triggers direct DOM manipulation, which can lead to layout thrashing —a mechanical process where frequent reflows and repaints cause frame rate drops, making the UI feel sluggish. Inspired by VanJS (1 kB) and its dependency on an additional 1.2 kB library (Van X), littlebag aims to eliminate such overhead. Yet, its current state is experimental. Without user feedback, it risks remaining a niche project, failing to address its performance bottlenecks or evolve into a viable alternative to larger frameworks. The creator’s plan to add Server-Side Rendering (SSR) hinges on community interest, but SSR itself introduces complexity—requiring a custom DOM implementation to avoid client-side hydration costs. If users engage, littlebag could become a lightweight SSR solution; if not, it may stagnate as a curiosity. The stakes are clear: littlebag’s utility depends on whether it can balance its minimalism with practical

2026-07-09 原文 →
AI 资讯

Row Lock — FOR UPDATE

FOR UPDATE: pessimistic row lock để chặn lost update, và cái giá deadlock khi không lock theo thứ tự SELECT ... FOR UPDATE là cách rõ ràng nhất để nói với Postgres "tao sẽ sửa row này, đừng cho ai khác đụng vào cho tới khi tao commit". Nó là một row-level lock thật sự — khác SELECT thường (chỉ chụp snapshot MVCC, không ngăn ai update song song). Lý do dev gặp nó trong việc thật là class bug lost update : hai transaction cùng đọc một row, cùng tính giá trị mới dựa trên giá trị đọc được, rồi cùng UPDATE — bản ghi cuối đè bản trước, một nửa thay đổi biến mất không log lỗi gì. FOR UPDATE ép hai bên xếp hàng tại bước đọc, một bên đợi bên kia commit rồi tự đọc lại bản mới. Đổi lại, nếu nhiều code path khoá nhiều row theo thứ tự khác nhau, Postgres sẽ bắn ERROR: deadlock detected và một bên transaction bay theo. Cơ chế hoạt động Khi một transaction chạy SELECT ... FOR UPDATE , Postgres không ghi row lock vào lock table chính (như cách nó làm với relation-level lock). Thay vào đó, nó ghi xid của transaction hiện tại vào xmax của chính tuple đó trên heap, kèm cờ infomask đánh dấu "đây là lock chứ chưa phải delete". Hệ quả: ôm row lock cho hàng triệu row gần như không tốn shared memory. Khi một transaction khác chạm cùng row (qua UPDATE , DELETE , hay một SELECT ... FOR UPDATE nữa), nó đọc xmax , thấy transaction kia còn sống, và đăng ký một heavyweight lock kiểu transactionid trong pg_locks để đợi xid đó kết thúc. Đó là cơ chế "đợi xid" lộ ra qua wait_event = 'transactionid' ở pg_stat_activity . Khi bên giữ COMMIT hoặc ROLLBACK , bên đợi được đánh thức, đọc lại tuple (visibility check theo isolation level), rồi mới chạy tiếp. -- Session A BEGIN ; SELECT id , balance FROM accounts WHERE id = 42 FOR UPDATE ; -- giữ row lock trên id=42, chưa commit -- Session B (terminal khác) BEGIN ; UPDATE accounts SET balance = balance - 100 WHERE id = 42 ; -- treo, đợi xid của Session A FOR UPDATE có bốn biến thể, mạnh dần ngược lại: FOR KEY SHARE (yếu nhất, chỉ chặn thay đổi key — đây là l

2026-07-07 原文 →
AI 资讯

Transaction State — Idle in Transaction

Idle in transaction: connection ngồi không nhưng vẫn giữ snapshot, VACUUM đứng hình và bảng phình idle in transaction là trạng thái mà pg_stat_activity.state đặt cho một connection đã BEGIN , đã chạy xong statement gần nhất, và đang ngồi đợi statement kế tiếp hoặc COMMIT / ROLLBACK . Trên giấy nó "rảnh"; trong thực tế nó vẫn cầm một snapshot, vẫn giữ backend_xmin , vẫn ôm mọi lock đã claim từ đầu transaction. Một connection trong state này chỉ vài chục giây không nguy hiểm; cùng connection đó ngồi vài giờ trên cluster có write traffic là kịch bản kinh điển khiến bảng update-nóng bloat, autovacuum đứng yên, replica conflict, và DBA on-call bị page lúc 3 giờ sáng. Đây không phải bug Postgres mà là application code path đã lỡ rời transaction mở rồi đi làm việc khác (đợi user input, gọi HTTP ra ngoài, ngủ trong queue worker) — Postgres chỉ trung thực phản chiếu lại. Cơ chế hoạt động Khi một connection gửi BEGIN , Postgres ghi nhận transaction nhưng chưa cấp xid (chỉ cấp khi câu lệnh ghi đầu tiên xuất hiện) và lập tức gán cho backend này một snapshot : tập hợp các xid mà transaction sẽ coi là visible. Snapshot này được phản chiếu ra cột backend_xmin trong pg_stat_activity . Ngay sau BEGIN , state của connection là idle in transaction . Mỗi câu lệnh sau đó đẩy connection sang active trong lúc chạy, rồi trả về idle in transaction ngay khi statement hoàn tất — và nó ở đó vô thời hạn , cho tới khi client gửi câu lệnh kế tiếp, gửi COMMIT / ROLLBACK , hoặc connection bị terminate. -- Session A BEGIN ; -- pg_stat_activity.state = 'idle in transaction' -- pg_stat_activity.backend_xmin = <xid horizon ngay tại thời điểm BEGIN> SELECT count ( * ) FROM orders ; -- trong lúc chạy: state = 'active' -- xong: state = 'idle in transaction', snapshot KHÔNG bị nhả -- (client đi gọi HTTP ngoài, hoặc đơn giản là quên gửi COMMIT) -- nhiều giờ trôi qua. state vẫn 'idle in transaction'. -- backend_xmin vẫn pin xmin horizon của cluster. Điểm cốt tử là backend_xmin : VACUUM (và autovacuum ) chỉ đ

2026-07-07 原文 →
AI 资讯

BEGIN/COMMIT — Transaction Lifecycle

Transaction lifecycle trong Postgres: BEGIN mở state machine, COMMIT đóng — quên đóng là dò mìn Một transaction trong Postgres không phải chỉ là cặp BEGIN ... COMMIT cú pháp; nó là một state machine sống cùng connection. BEGIN đẩy connection từ idle sang active , mỗi statement kết thúc đẩy nó về idle in transaction đợi statement kế tiếp, một statement lỗi đẩy sang idle in transaction (aborted) , và chỉ COMMIT / ROLLBACK mới trả connection về idle . Dev gặp lifecycle này trong việc thật không phải vì cú pháp khó mà vì một BEGIN quên COMMIT trong một code path lỗi: connection nằm trong pool ở idle in transaction vô thời hạn, giữ snapshot và lock, chặn autovacuum , kéo lock chain, làm bảng update-nóng bloat dần rồi cả service chậm chết. Cơ chế hoạt động Mặc định mỗi connection ở autocommit mode : mỗi statement là một transaction tự đóng. BEGIN (hoặc START TRANSACTION ) tắt autocommit cho tới khi gặp COMMIT / ROLLBACK . Trong khoảng đó connection có một xid (cấp khi cần ghi) và một snapshot, và lifecycle của nó đi qua các trạng thái mà Postgres phơi ra trong pg_stat_activity.state : idle — connection mở, không có transaction nào đang chạy. active — đang thực thi một statement (kể cả ngoài transaction block). idle in transaction — đang trong transaction block, vừa chạy xong một statement, đợi statement kế tiếp hoặc COMMIT / ROLLBACK . idle in transaction (aborted) — đang trong transaction, một statement đã ném lỗi, mọi statement tiếp theo trả ERROR: current transaction is aborted, commands ignored until end of transaction block cho tới khi ROLLBACK . fastpath function call / disabled — ít gặp, không phải mục tiêu của bài này. -- t0: state = 'idle' BEGIN ; -- t1: state = 'idle in transaction' (vừa thực thi xong BEGIN, đợi statement kế) INSERT INTO orders ( user_id , total ) VALUES ( 42 , 100 ); -- trong lúc chạy: state = 'active' -- sau khi statement xong: state = 'idle in transaction' lại INSERT INTO orders ( user_id , total ) VALUES ( NULL , 100 ); -- ERROR: null value

2026-07-07 原文 →
AI 资讯

Isolation Level — Read Committed

Read Committed: snapshot mỗi statement, và vì sao hai SELECT trong cùng transaction có thể trả khác nhau READ COMMITTED là isolation level mặc định của PostgreSQL, và là level mà phần lớn workload OLTP đang chạy mà không biết. Khác với mô hình "transaction lấy một snapshot rồi giữ nguyên" mà nhiều dev tưởng tượng từ MVCC, ở Read Committed mỗi statement lấy một snapshot mới tại thời điểm statement bắt đầu , không phải tại thời điểm BEGIN . Hậu quả thực tế: hai SELECT liên tiếp trong cùng một transaction có thể trả về dữ liệu khác nhau nếu giữa hai lần đó có transaction khác commit. Đây là non-repeatable read — đúng spec của Read Committed, không phải bug — và là nguồn của một class lỗi rất hay gặp: code đọc một giá trị, ra quyết định, rồi cập nhật dựa trên giá trị đã đọc, trong khi giá trị thực tế đã thay đổi. Cơ chế hoạt động Một transaction ở Read Committed không có transaction-level snapshot . Khi mỗi statement (mỗi SELECT , UPDATE , DELETE , INSERT ... SELECT ...) bắt đầu thực thi, backend lấy một snapshot mới gồm xmin , xmax và xip list — chính cái snapshot quyết định row version nào "visible" theo MVCC. Statement chỉ thấy: row có xmin đã commit trước thời điểm statement bắt đầu , và xmax chưa tồn tại hoặc thuộc một transaction chưa commit / đã abort. Ngay sau khi statement kết thúc, snapshot đó bị bỏ. Statement kế tiếp lấy snapshot mới — nếu trong khoảng giữa có transaction khác commit, statement này sẽ thấy dữ liệu mới đó. -- T1 BEGIN ; -- KHÔNG lấy snapshot ở đây SELECT balance FROM accounts WHERE id = 1 ; -- snapshot S1 -> trả 1000 -- ... T2 chạy: UPDATE accounts SET balance=500 WHERE id=1; COMMIT; SELECT balance FROM accounts WHERE id = 1 ; -- snapshot S2 -> trả 500 COMMIT ; Với UPDATE / DELETE / SELECT ... FOR UPDATE / FOR NO KEY UPDATE / FOR SHARE , Read Committed làm thêm một bước đặc biệt mà SELECT thường không làm: nếu target row bị một transaction khác đang lock (chưa commit), statement đợi transaction đó kết thúc. Khi unblock: nếu transaction kia ROL

2026-07-07 原文 →
AI 资讯

MCP Explained: How It's Different from Traditional APIs

Imagine you are planning a surprise birthday party. You need invitations, food, decorations, and a cake. You call different places to get these things. You tell each one exactly what you need. "I need 20 red balloons." "I need a chocolate cake for 10 people." This is how many computer programs talk to each other. They use something called an API (Application Programming Interface). An API is like a menu. You pick what you want. You get exactly that. It works well for simple tasks. But what if your party plans change? What if you decide on a theme mid-conversation? Traditional APIs can feel a bit rigid then. They don't always remember your past requests. They don't understand the bigger picture. Now, imagine talking to a super-smart party planner. You start by saying, "I'm planning a party." The planner asks, "For how many people?" You say, "About 20." Then you mention, "It's for a birthday." The planner instantly suggests a cake size. It recommends decorations based on your earlier answers. This smart planner remembers everything you said. It understands your overall goal. It uses something like MCP (Model Context Protocol). MCP is a new way for computers to talk. It's like having a real conversation. It's much smarter than a simple menu order. You will soon understand why this difference is a game-changer. Traditional APIs: The Fixed Menu Approach Let's start with what you might already know. Many apps you use every day rely on APIs. An API is like a waiter in a restaurant. You look at the menu. You tell the waiter your exact order. "I want a cheeseburger with fries." The waiter takes your order to the kitchen. The kitchen prepares only that specific meal. Then the waiter brings it back to you. This is how most apps work together. One app sends a very specific request. It asks for a certain piece of information or to perform a specific action. The other app performs that task. It sends back a very specific response. Think of ordering from an online store. You click

2026-07-07 原文 →
AI 资讯

Diffraction Grating: How Thousands of Slits Turn Light into a Spectrum

Tilt a CD or DVD under a desk lamp and a band of color sweeps across its surface. The disc is not painted; it is a spiral of microscopic pits, packed so tightly that they act on light the way a finely ruled scientific instrument does. Each wavelength of white light leaves the surface at its own angle, and your eye sees the result fanned out as a rainbow. That is a diffraction grating at work. The same principle that decorates a CD is the engine inside spectrometers that identify chemical elements, tune lasers, and read the composition of distant stars. This article explains how a grating spreads light, how to compute the angles, and where the analysis goes wrong. Why this calculation matters A prism also splits white light, but a grating does it with far more control and far more precision. Because the spreading depends on a countable number — the spacing between lines — a grating can be designed to send a chosen wavelength to a chosen angle. That predictability is what makes it the heart of the spectrometer. Spectroscopy underpins a remarkable range of work. Astronomers read a star's chemistry and velocity from the dark lines in its spectrum. Chemists identify unknown compounds by the wavelengths they absorb. Telecommunications engineers use gratings to combine and separate the many wavelengths sharing a single optical fiber. In every case the first task is the same: given the grating and the light, predict the angle at which each wavelength emerges. Get that wrong and a spectral line lands on the wrong detector pixel, and the measurement is meaningless. The core formula A diffraction grating is a surface ruled with a large number of equally spaced, parallel lines. When light passes through or reflects off it, each line acts as a source of secondary waves. Those waves interfere, and they reinforce each other only in specific directions — the directions where waves from neighboring lines arrive exactly in step. The condition for that reinforcement is the grating equ

2026-07-07 原文 →
AI 资讯

We Made Our AI-vs-Human PR Stats a Public Live Dashboard

A while back I wrote about 64% of our merged PRs being written by AI . A few people (reasonably) asked: "nice story, but can I verify any of that?" So we put it on a public, auto-updating dashboard: 👉 www.codens.ai/stats/en It shows, for our GitHub organization: What % of merged PRs are authored by AI agents (currently 65%) Median time from PR-open to merge (2 minutes) Who merged what — task-execution agents vs maintenance bots vs auto-fix vs humans Weekly AI-merge counts and a per-repository breakdown Every number is tallied straight from the GitHub API by a small collector script, and the page regenerates itself weekly. We can't inflate it — it's measured, and the down weeks show up too (that's kind of the point). Why bother making it public Two reasons. 1. "Trust me bro" doesn't scale. When you claim most of your code is AI-written, the only honest move is to expose the raw counts so anyone can sanity-check them. The dashboard is that receipt. 2. It's a live dogfooding test. The whole thing — the PRD, the implementation, the review, the auto-fix on production errors — runs on Codens , our own AI dev-automation suite. If our own numbers ever tanked, the dashboard would be the first place it'd show. Public accountability is a good forcing function. Funny footnote: the dashboard itself was code-reviewed by our own AI reviewer before it shipped, and it caught two real bugs — an OG-image percentage that had drifted out of sync with the live number, and a broken error-fallback that would have blanked the page on malformed data. The tool built to sell "AI reviews your PRs" reviewed the PR that announces it. We'll take it. If you want to see the same machinery on your repos, there's a 14-day free trial (no card): codens.ai . Japanese version of the dashboard is here .

2026-07-07 原文 →
AI 资讯

Securing Your Terraform Infrastructure with Checkov and GitHub Actions

Infrastructure as Code (IaC) has revolutionized how we provision and manage cloud resources. Tools like Terraform, Pulumi, and OpenTofu allow us to define infrastructure using code, making it versionable, repeatable, and scalable. However, with great power comes great responsibility. Misconfigurations in IaC can lead to massive security breaches, such as publicly exposed data storage or overly permissive access roles. This is where Static Application Security Testing (SAST) comes in. SAST tools analyze your source code to find security vulnerabilities before the code is deployed. In this article, we'll explore how to apply SAST to a Terraform project using Checkov , a popular open-source static analysis tool for IaC, and how to automate this process using GitHub Actions. (Note: We are intentionally avoiding tfsec for this demonstration to explore other powerful alternatives). Why Checkov? Checkov, created by Bridgecrew (now part of Prisma Cloud), is a static code analysis tool for IaC. It scans cloud infrastructure provisioned using Terraform, Terraform plan, Cloudformation, Kubernetes, Dockerfile, Serverless, or ARM Templates and detects security and compliance misconfigurations. It includes hundreds of built-in policies covering security and compliance best practices for AWS, Azure, and Google Cloud. The Demo Scenario: A Vulnerable S3 Bucket Let's start by creating a simple Terraform configuration for an AWS S3 bucket. We will intentionally introduce a security misconfiguration: making the bucket public without encryption. Create a file named main.tf : # main.tf provider "aws" { region = "us-east-1" } resource "aws_s3_bucket" "my_vulnerable_bucket" { bucket = "my-company-public-data-bucket-12345" } # Misconfiguration 1: Public Read Access resource "aws_s3_bucket_acl" "example" { bucket = aws_s3_bucket . my_vulnerable_bucket . id acl = "public-read" } If we were to deploy this, anyone on the internet could read the contents of this bucket. Let's see how Checkov can

2026-07-05 原文 →
AI 资讯

Copilot CLI drops the PAT requirement inside GitHub Actions

GitHub said this week that Copilot CLI, when it runs inside a GitHub Actions workflow, will accept the built-in GITHUB_TOKEN for authentication. Per the July 2 changelog, the previous path required creating and storing a personal access token. The operational read is small and precise: one fewer human-owned credential to mint, rotate and inherit. The exact scope of the change The changelog covers a narrow surface. It applies to Copilot CLI when invoked from a GitHub Actions workflow, and it swaps the required credential from a PAT to the workflow's ambient GITHUB_TOKEN . GitHub does not describe changes to how Copilot CLI authenticates outside Actions, and this post will not extrapolate to those contexts. If your Copilot CLI usage lives on a developer laptop or in another CI system, nothing in this announcement moves for you. Why the PAT was the wrong credential to leave in the loop A personal access token has almost none of the properties you would want from an automation credential. It does not expire on a job boundary. It carries a person's identity, not the workflow's. It sits in Actions secrets long enough to outlive the engineer who created it. And its scopes were chosen by that engineer, at that moment, often wider than the job actually needs. GITHUB_TOKEN is the opposite shape. Actions mints it at the start of a job, scopes it through the workflow's permissions: block, and revokes it when the job ends. If the token leaks, the window for abuse is the runtime of the job, not the years until somebody remembers to rotate it. When the person who wrote the workflow leaves, the pipeline does not silently break because a token expired with their account. For scripted Copilot CLI calls that had to be wrapped in a PAT, that is the whole win. The tool authenticates against the workflow instead of against a human. Wiring it up The workflow-side pattern is the same one every GITHUB_TOKEN -consuming step already follows: declare permissions: explicitly at the job level, k

2026-07-04 原文 →
AI 资讯

The Go Code Review Comments List: 10 Rules Every Reviewer Cites

Book: The Complete Guide to Go Programming Also by me: Hexagonal Architecture in Go — the companion book in the Thinking in Go series My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools Me: xgabriel.com | GitHub You open a pull request in a Go repo you just joined. Ten minutes later there are six comments on it. None of them are about your logic. They point at a capitalized error string, a receiver named this , a context stored on a struct. Each comment links the same page: the Go Code Review Comments wiki. That page is the closest thing Go has to an official style council. It grew out of the comments Go's own maintainers left on CLs for years, and most Go teams treat it as the default rulebook. The problem is that the wiki tells you what but rarely why , so the rules read like arbitrary taste. They aren't. Each one exists because the alternative bit somebody. Here are ten that reviewers cite the most, with the reason behind each. Everything below is idiomatic on Go 1.23+. 1. Error strings are lowercase and unpunctuated The rule: an error string should not be capitalized and should not end with punctuation. // wrong return fmt . Errorf ( "Failed to open config." ) // right return fmt . Errorf ( "failed to open config" ) The reason is wrapping. Go errors get concatenated. Your string is almost never the whole sentence a user reads; it's a fragment in a chain built with %w : return fmt . Errorf ( "load settings: %w" , err ) // -> "load settings: open config: permission denied" Capitalize your fragment and you get load settings: Open config: permission denied in the middle of a line. End it with a period and you get a period in the middle of a longer message. Lowercase, no trailing punctuation, and every fragment composes cleanly no matter where it lands in the chain. The exception is a string that begins with an exported name or acronym, which keeps its own case ( HTTP , TLS ). 2. Receiver types are consistent ac

2026-07-03 原文 →
AI 资讯

Go Naming: Why Getters Drop the Get Prefix (and Other Idioms)

Book: The Complete Guide to Go Programming Also by me: Hexagonal Architecture in Go — the companion book in the Thinking in Go series My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools Me: xgabriel.com | GitHub You write a Go struct with a private field and a method to read it. Muscle memory from Java, C#, or PHP takes over, and you type GetName() . The code compiles. Tests pass. Then a reviewer leaves a comment that just says "drop the Get" with no explanation, and you're left wondering whether that's a real rule or one person's taste. It's a real rule. It's written into the language's own style guide, the standard library follows it everywhere, and several linters will flag the code that breaks it. Go naming isn't a matter of opinion the way it is in some languages. A handful of conventions are baked into the tooling, and once you know them, half the reviewer nitpicks disappear. Getters drop the Get The convention comes straight from the Effective Go document. If you have an unexported field owner , the accessor is named Owner , not GetName or GetOwner . The mutator, if you need one, keeps the Set prefix. type File struct { owner string } func ( f * File ) Owner () string { return f . owner } func ( f * File ) SetOwner ( o string ) { f . owner = o } The reasoning is about how the call reads. person.Name() says the same thing as GetName() with less noise, and the parentheses already tell you it's a method call. Get adds a word that carries no information in a language where field access and method calls look different anyway. The Set prefix stays because there's no other clean way to signal mutation. Name() reads, SetName(x) writes. The asymmetry is deliberate. This shows up all over the standard library. bytes.Buffer has Len() , not GetLen() . sync.Once has no getters to get wrong, but http.Request exposes fields and methods that never carry a Get . time.Time has Hour() , Minute() , Second() . The pattern is

2026-07-03 原文 →
AI 资讯

glasp v0.3.0 & v0.4.0 — PKCE Support, Timeouts, and Retries

Last time I wrote about using glasp, a Go-based, npm-free CLI for Google Apps Script (GAS), in GitHub Actions. Previous post: Lean, Fast, Simple — npm-free GAS Deployment on GitHub Actions with glasp This time, a quick rundown of what landed in v0.3.0 and v0.4.0 . v0.3.0: PKCE support glasp login now supports PKCE (RFC 7636) as an opt-in. glasp login --pkce # or GLASP_USE_PKCE = 1 glasp login Each login generates a code_verifier and sends an S256 code_challenge to Google. It's a defense against authorization code interception, and it coexists fine with the existing client_secret flow. It only applies to the interactive login — --auth / GLASP_AUTH for CI is untouched. Off by default. Worth turning on if you're in a stricter security environment. v0.4.0: Timeouts and retries The focus here is basically "can this run unattended in CI/CD without falling over." Timeouts Script API requests previously had no timeout — a stuck request could hang the job indefinitely. v0.4.0 adds a 180s default. glasp push --timeout 60 # set to 60s glasp push --no-timeout # disable Also configurable via GLASP_TIMEOUT / GLASP_NO_TIMEOUT env vars or timeoutSeconds in .glasp/config.json . Priority: --no-timeout > flag/env > config > default. If the config file is broken, it warns instead of silently falling back. Retries Transient failures (5xx, 429) now get retried automatically. glasp push --max-retries 5 glasp push --no-retries 3 retries by default (up to 4 attempts total) Only applies to idempotent commands: push , pull , clone , list-deployments Commands with side effects ( create-script , run-function , etc.) are never retried Exponential backoff with jitter, respecting Retry-After It's implemented as a single http.RoundTripper wrapper, so the Google SDK itself isn't touched — same pattern as the timeout implementation. retryTransport → oauth2.Transport → http.DefaultTransport Some refactoring, too Internal packages got reorganized ( #107 ), and the hand-rolled retry transport was swappe

2026-07-02 原文 →