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

标签:#dev

找到 4348 篇相关文章

AI 资讯

A LaunchAgent gets `Operation not permitted` for `~/Documents` while Terminal works

The same zsh script could list ~/Documents when I ran it in Terminal. Started as a LaunchAgent, it failed with: ls: /Users/administrator/Documents: Operation not permitted The LaunchAgent had the same user ID, the same $HOME , and the same script. That combination makes this look like a Unix permission problem. In this test it was not. The useful discriminator was the launch context: access succeeded from Terminal, failed from launchd , and still succeeded for a path outside the protected folder. I reproduced this on macOS 15.6.1 (Darwin 24.6.0) with a LaunchAgent in gui/501 . The probe was removed after the test. Why chmod is the wrong first check The obvious suspects were file ownership, a wrong home directory, or a job running as another user. The probe printed those facts before touching the files: #!/bin/zsh print -- "user= $( id -un ) uid= $( id -u ) " print -- "home= $HOME pwd= $PWD " /bin/ls " $HOME /Documents" 2>&1 | /usr/bin/head -5 /bin/cat " $HOME /Documents/vinh/working/CLAUDE.md" 2>&1 | /usr/bin/head -1 # Negative control: outside Documents /bin/ls " $HOME /.pf004" 2>&1 | /usr/bin/head -5 The two runs produced this difference: Check Terminal LaunchAgent in gui/501 User / uid administrator / 501 administrator / 501 $HOME /Users/administrator /Users/administrator ls ~/Documents Listed entries Operation not permitted cat inside ~/Documents Read the file Operation not permitted ls ~/.pf004 Listed entries Listed entries The working directory differed, but the script used absolute paths under $HOME , so PWD=/ did not explain the denial. The negative control mattered more: the LaunchAgent could read another directory owned by the same user. Changing ownership or mode bits would not explain why only the launch context changed the result. The owning layer is the privacy context On this machine, the access decision was attached to how the process was launched, not just to uid 501. Terminal had a privacy context that allowed access to the user's Documents folder.

2026-08-26 原文 →
AI 资讯

Cheapest Hosted App Log Search for Small Businesses: A Practical Comparison

Short answer: compare a hosted app log search service, self-hosted Loki, and Elastic Cloud by the operational boundary each one creates. Low effort, data control, and search depth are different decision axes; the cheapest choice is the one that produces a trustworthy signal without making a small team operate a second product. That last sentence is the decision rule. A low invoice is not a useful bargain if the first incident reveals missing logs, duplicate alerts, or an index that nobody knows how to restore. The incident lesson: a log is not a health signal I've been paged for two different failures: a scheduled import that stopped producing results, and a job that delivered the same result twice. Both incidents had logs. Neither incident was solved by collecting more text. The invariant is simple: observability has to describe both activity and the absence of expected activity. An app log search system can help investigate an import after an alert fires. It cannot, by itself, prove that an import that should have run did not run. That missing event needs a heartbeat, a durable job record, or a metric with an explicit freshness deadline. For an edtech application importing course data, I would record the import name, run identifier, start and finish timestamps, outcome, item count, and an idempotency key. The alert should fire when the expected completion window passes, not whenever somebody happens to search a log stream. Duplicate deliveries should be visible as a repeated idempotency key, not mistaken for two successful business operations. Keep the signal narrow. The log search layer then answers the next question: what happened around the missed or duplicated run? That division keeps noisy search data from becoming the only source of truth for scheduled work. How should a small business compare self-hosted and hosted app log search? Compare the complete operating boundary, not the storage line item. A self-hosted Loki deployment gives the team direct control

2026-08-26 原文 →
AI 资讯

Azure OpenAI Service vs OpenAI API, which to use and when in 2026

When someone asks whether to use Azure OpenAI Service or the direct OpenAI API, the starting point is this: the models running on both platforms are identical. GPT-4o, GPT-5, and the o-series models you deploy on Azure have the same weights, the same capabilities, and the same output quality as the ones you call from platform.openai.com, and what changes between the two platforms is the infrastructure where they run, the authentication mechanism, and the compliance guarantees the provider can offer on those requests. What changed in 2026 Azure AI Foundry was renamed Microsoft Foundry on January 1, 2026, and Azure OpenAI Service now lives inside that unified platform alongside the model catalog, development tooling, and agents. References to Microsoft Foundry in new documentation point to what used to be Azure AI Foundry. In July 2026, the GPT-5.6 family arrived with Sol, Terra, and Luna available on Azure the same day as on the direct OpenAI API. Historically Azure lagged four to eight weeks behind new model releases because Microsoft validates them within their compliance frameworks before making them available, and while that gap still exists for some specific features and APIs, for the main models in the GPT-5 family availability is converging. Where data is processed When you call GPT-4o from the OpenAI API, the request goes to OpenAI's own infrastructure, which is centralized and gives you no control over which region processes your data. For most use cases that doesn't matter, but for organizations with data residency requirements, regulatory compliance needs, or industries like healthcare, banking, or government, that detail can determine whether the service is usable at all. Azure OpenAI runs the same models within the boundary of your Azure tenant, so the data you send in prompts doesn't leave to OpenAI's infrastructure but processes in the Azure regions you choose. That's what makes it possible to meet HIPAA, SOC 2, EU data residency, and other certificati

2026-08-26 原文 →
AI 资讯

GitHub Copilot Premium Requests: Allowances, Multipliers, Billing, and What Replaced Them

GitHub Copilot premium requests are the metered unit that determined how much advanced Copilot usage your plan covered, and if you are searching for how they work in mid-2026, you need two answers, not one. First, the mechanics: a premium request is consumed each time you use an advanced Copilot feature, scaled by a per-model multiplier, against a fixed monthly allowance that came with your plan. Second, the news: as of June 1, 2026, GitHub moved Copilot from request-based billing to usage-based billing , and premium requests are now officially labeled "legacy" throughout GitHub's own documentation. Their replacement is GitHub AI Credits, metered at one cent per credit. Both systems matter today. Annual Copilot Pro and Pro+ subscribers who stayed on their existing plans are still billed in premium requests, and every question about the new credits model (allowances, overages, admin controls) is easier to answer if you understand the system it replaced. Here is the complete picture, with the numbers. What is a premium request? GitHub's definition is simple: a request is any interaction where you ask Copilot to do something, whether that is generating code, answering a question, or reviewing a pull request. Routine interactions, like inline code completions, are unlimited on every paid plan and never touch the meter. Premium requests are the interactions that use more advanced processing, and they draw down a monthly allowance: Copilot Chat : one premium request per user prompt, multiplied by the model's rate (ask, edit, agent, and plan modes all count). Copilot code review : each review consumed one request originally; since June 1, 2026 it carries a 13x multiplier , so a single review deducts 13 premium requests. Copilot coding agent and CLI : one premium request per prompt or session, times the model's rate. Only your prompts count; the autonomous tool calls Copilot makes along the way do not. Spark : a fixed rate of four premium requests per prompt. The critical n

2026-08-26 原文 →
AI 资讯

Implementing Persistent AI Disclosure Without Killing the Persona Experience

Following the discussion on named AI personas and trust — here's the engineering side: how do you keep AI-status disclosure genuinely persistent throughout a conversation without making the interface feel robotic or constantly interrupting the experience a named persona is meant to create? The Naive Approaches Both Fail Option A: One disclaimer, message one, never again. Trivially easy to implement, but gets forgotten within a few exchanges — exactly the failure mode worth avoiding for personas carrying real emotional weight. Option B: Repeat "I am an AI" every single message. Technically persistent, but breaks the actual UX a named persona is trying to create, and users will tune it out as noise within a few messages anyway — repetition without variation loses its signal value fast. Neither is a good engineering solution. The better pattern is contextual, adaptive disclosure. Pattern: Risk-Weighted Disclosure Frequency python class DisclosureManager: def init (self, base_interval=8, high_risk_interval=3): self.base_interval = base_interval self.high_risk_interval = high_risk_interval self.messages_since_disclosure = 0 def should_inject_disclosure(self, message_risk_level: str) -> bool: interval = ( self.high_risk_interval if message_risk_level == "high" else self.base_interval ) self.messages_since_disclosure += 1 if self.messages_since_disclosure >= interval: self.messages_since_disclosure = 0 return True return False message_risk_level comes from the same classification pass used for scope/escalation detection covered in earlier persona-guardrail architecture — emotionally sensitive or high-stakes exchanges trigger disclosure more frequently than routine ones. Pattern: Disclosure Woven Into Persona Voice, Not Bolted On Rather than an interrupting system message, integrate the reminder into the persona's actual response style: python def inject_natural_disclosure(response_text, persona_config): disclosure_phrases = persona_config.disclosure_variants # e.g. for "Ок

2026-08-26 原文 →
AI 资讯

How I Reduced Burnout by Fixing My Nutrition Stack

I want to be upfront about something. I didn't figure this out proactively. I figured it out after my second burnout in three years — sitting in a period of forced recovery, unable to look at a code editor without feeling a specific kind of dread that I couldn't logic my way out of. I'd done everything the burnout recovery advice said to do. Took time off. Set better boundaries at the new job. Worked on the psychological stuff. All of it helped. None of it explained why recovery felt so much harder and slower than it should. Then I got bloodwork done. And the picture became considerably less mysterious. The Diagnostic Output bash $ bloodwork --full-micronutrient-panel --date=recovery-period [CRITICAL] vitamin-d: 18 ng/mL target: 40-60 ng/mL status: severely deficient duration: estimated 2+ years note: dopamine synthesis impaired at this level [CRITICAL] rbc-magnesium: low note: serum looked normal — wrong metric duration: unknown — never previously tested correctly note: HPA axis running unregulated [HIGH] omega3-index: 3.1% target: 8%+ status: neuroinflammation elevated note: western diet + zero supplementation [HIGH] hs-crp: 2.9 mg/L target: <1.0 mg/L status: significant systemic inflammation note: never measured, thoroughly normalized [WARNING] ferritin: low-normal note: passing standard panel, causing fatigue bugs-found: 5 bugs-known: 0 recovery-speed: severely impaired by all of the above Two burnouts. Same underlying biology. Neither time did anyone suggest checking any of these markers. What the Numbers Actually Meant Vitamin D at 18 ng/mL: Vitamin D is a direct input to dopamine synthesis. The enzyme that produces dopamine requires it. I had been trying to rebuild motivation and find meaning in work — the core challenge of burnout recovery — while running a dopamine system without adequate substrate. javascript // what I was trying to do dopamine.rebuild() // what the system had to work with vitaminD: 18 // severely deficient tyrosineHydroxylase.efficiency:

2026-08-26 原文 →
AI 资讯

MVP que evolui: 7 decisões técnicas antes da primeira linha de código

Um MVP não precisa nascer preparado para milhões de usuários. Mas também não deve ser construído de uma forma que torne cada evolução futura mais cara do que a anterior. O desafio técnico de um MVP é encontrar um equilíbrio: entregar rápido o suficiente para validar hipóteses, mantendo uma base simples, observável e segura. O objetivo não é antecipar todos os cenários. É evitar decisões que bloqueiem o aprendizado. Antes da primeira linha de código, estas sete decisões reduzem boa parte do retrabalho que aparece depois do lançamento. 1. Qual hipótese o software precisa validar? “MVP” descreve uma estratégia de validação, não um tamanho de backlog. Antes de discutir framework, banco de dados ou cloud, transforme a ideia em uma hipótese testável: Acreditamos que [tipo de usuário] resolverá [problema] usando [proposta de valor]. Saberemos que isso é verdade quando [métrica observável]. Esse formato muda a conversa. Em vez de tentar reproduzir todas as funcionalidades de um produto consolidado, a equipe identifica o fluxo mínimo capaz de gerar evidência. Para um sistema de orçamento B2B, por exemplo, a hipótese inicial pode ser que compradores aceitam centralizar pedidos e fornecedores respondem dentro de determinado prazo. O MVP talvez precise de cadastro, criação de pedido, convite, resposta e comparação. Chat avançado, BI e automações podem esperar. Defina uma métrica de sucesso e uma condição de abandono. Sem isso, qualquer uso parece uma vitória e o MVP vira um projeto sem linha de chegada. 2. Onde estão os limites do domínio? A pressa costuma produzir uma base de código organizada apenas por telas ou endpoints. Funciona no começo, mas as regras de negócio rapidamente se espalham por controllers, componentes e jobs. Antes de implementar, desenhe os conceitos centrais do domínio e suas responsabilidades. Perguntas úteis: Quais entidades possuem identidade própria? Quais regras precisam ser verdadeiras em toda alteração? Que ações representam eventos de negócio? Quai

2026-08-26 原文 →
AI 资讯

From Software Developer to Founder: Learning to Build Beyond Code

I started my career as a software developer, Initially a front end developer and then became a full stack developer where success often meant solving difficult technical problems, building reliable systems, and delivering good software. Becoming a co-founder changed that perspective. Suddenly, building a product wasn't just about writing code. It was about understanding the problem deeply, making decisions with incomplete information, taking responsibility for outcomes, building a team, and constantly deciding what not to build. Now, as an Engineering Director at an AI company, I'm learning to balance both sides staying close to technology while thinking about people, product, strategy, and long-term engineering decisions. Honestly, The transition from developer to founder hasn't been a straight line. It's been a continuous process of learning, unlearning, and becoming comfortable with uncertainty. I'm starting this blog to document some of those lessons from building AI products and engineering teams to the technical decisions and challenges that come with growing a technology company. I know I'm just beginning my journey and that I thought I could perhaps share it with my tech community.

2026-08-25 原文 →
AI 资讯

Amazon, Temu, and AliExpress already have visual search. Desktop just hides it.

I shop on a laptop. A lamp on Amazon that costs too much. A jacket in a listing photo. Something I saw on eBay and wanted to check on Temu. On my phone, that is a camera tap. On desktop, the camera icon is mostly missing. So I built SameSame , a browser extension I still use every day. It does not send your photo to a third-party reverse-image API. It opens the visual search each store already runs - the same one their mobile apps and some out-of-stock flows use - from the page you are already on. The desktop gap Visual product search is not new. Amazon Lens, Temu camera search, AliExpress image search: they work because they search inside that store's catalog. That is different from Google Lens, which searches the open web and often returns a mix of blogs, pins, and shopping links. The catch is where those tools live. Amazon's image search is a first-class feature in the shopping app. On amazon.com in a browser, it is easy to miss or simply not there, depending on the page. Temu and AliExpress follow the same pattern: obvious on mobile, buried or absent on desktop. If you want to search by image from a laptop, the usual advice is: save the image, open the store app or a reverse-image site, upload, then repeat for the next store. That is a lot of friction for something the store already knows how to do. The searches were already there I did not invent a new matcher. Amazon, Temu, and AliExpress already run visual search against their own catalogs. On mobile that is the camera in the search bar. The same capability shows up in other places, including some out-of-stock and similar-items flows on the web. When a listing is unavailable, you have sometimes seen visually close alternatives. That is not a coincidence. The catalog search is already wired up. Desktop shopping just does not put a camera on every page. Those endpoints are not a public developer API you sign up for. They are the stores' own visual search, used by their apps and a handful of desktop pages, mostl

2026-08-25 原文 →
AI 资讯

From "Merge is Deploy" to Release Engineering with GitHub Actions

Have you ever stopped to think about the risk of having a pipeline where any merge into the main branch deploys straight to production without a single safety gate? For a long time, our workflow here was that classic setup almost every developer has used at some point: merge on main triggering an SSH script with git pull and pm2 restart It worked for day-to-day tasks, but it gave a false sense of stability lol The reality check hit when I found a critical blind spot in the automation: remote SSH scripts were running without strict error handling. In other words, if a git pull caused a conflict or a database migration failed halfway through, the script simply ignored the failure, ran to the end, and GitHub Actions marked the pipeline as green The absolute worst-case scenario for monitoring: the pipeline reported that everything went smoothly, while production was already completely down On top of that, the execution order was inverted: database migrations were running before the application build. If TypeScript threw a type error right after, the database schema had already advanced while the new code never booted. And since Prisma has no native down migrations, rolling back meant a high-risk manual intervention I decided to stop everything and redesign our delivery pipeline from scratch, starting from one clear premise: a tag is a release, a merge is not Today, nothing touches the production server without an annotated SemVer tag, going through 6 tightly coupled stages: Strict tag validation: only accepts annotated tags matching vX.Y.Z, ensuring author, timestamp, and audit trail for every single release Quality gates across PR and Release: automated tests with Vitest, strict typechecking, builds, and migration validation against a clean database via workflow_call Decoupled backups: an independent daily scheduled routine combined with a mandatory safety snapshot right before touching production Real migration dry-run: the most valuable gate, where the pipeline resto

2026-08-25 原文 →
AI 资讯

Why I built an app against fast swipe‑based social media: introducing SlowInk

Nowadays most social and pen‑pal apps are built around speed. Swipe left, swipe right, quick short messages, endless notifications. Platforms reward fast replies and surface‑level first impressions. We can chat with dozens of people every day, yet many of us still feel lonely. Connections are easy to start, but rarely grow deep. Even some existing pen‑pal apps gradually move toward swipe‑driven matching, focusing heavily on profile pictures instead of real thoughts. I wanted something different. What if we slow everything down? What if friendship starts from long, thoughtful letters rather than instant small‑talk? That is the original idea behind SlowInk . I am a solo indie developer building this application with Flutter. My goal was not to make another popular social product. I just wanted to solve a pain I felt myself: missing genuine, low‑pressure cross‑cultural communication. During development, I made several intentional product trade‑offs: No swipe matching mechanism. You will not judge people within one second by just looking at avatars. No real‑time instant chat. Communication happens through complete letters. You take your time writing, and others take their time replying. Reduce noisy notifications. There is no pressure to reply immediately. Focus on long‑form writing, for language exchange and sincere pen‑pal friendship. These choices brought technical challenges. Building a letter‑first social system is quite different from building typical instant‑messaging software. I spent a lot of time thinking about user privacy, spam prevention, and how to keep the atmosphere gentle for global users. Many features got cut in order to keep the core idea intact. SlowInk is still an early‑stage project. It is far from perfect. There are bugs to fix and features to polish. As a side‑project developer without large‑team support, every improvement moves forward little by little. If you feel tired of fast‑paced swipe‑based social media, or you enjoy writing and receiving

2026-08-25 原文 →
AI 资讯

How I Debugged a phpMyAdmin 500 Error While Importing a Large SQL File on Laragon

I recently ran into a weird issue while working on a Laravel project on Windows using Laragon . Everything was working fine until I tried to import a database through phpMyAdmin. Instead of an SQL error, phpMyAdmin simply returned: Internal Server Error The server encountered an internal error or misconfiguration... No useful message. Just HTTP 500. My SQL file was around 97 MB , so at first I thought it was probably a PHP upload limit issue. It wasn't that simple. Here is how I debugged it. 1. Check which PHP configuration is actually running From Laragon Terminal: php --ini Then I checked the important error settings: php.exe -r "echo 'error_log=' . ini_get('error_log') . PHP_EOL;" php.exe -r "echo 'log_errors=' . ini_get('log_errors') . PHP_EOL;" php.exe -r "echo 'display_errors=' . ini_get('display_errors') . PHP_EOL;" My output was: error_log=D:/C-data/laragon/tmp/php_errors.log log_errors=1 display_errors=1 One small Laragon/Git Bash issue I also found was: type php returned: php is aliased to `winpty php.exe' Because of that, commands like: php -i | grep ... sometimes returned: stdout is not a tty Using php.exe directly avoids that problem. 2. Check the PHP error log My PHP error log was: D:/C-data/laragon/tmp/php_errors.log I reproduced the import error and checked it: tail -n 50 /d/C-data/laragon/tmp/php_errors.log Nothing useful appeared. That was an important clue. 3. Make sure browser PHP and CLI PHP use the same php.ini I created a temporary file: <?php phpinfo (); Then opened it through the browser. Important values were: Server API: CGI/FastCGI PHP Version: 8.4.4 Loaded Configuration File: D:\C-data\laragon\bin\php\php-8.4.4-nts-Win32-vs17-x64\php.ini My PHP limits were already high enough: upload_max_filesize = 512M post_max_size = 512M memory_limit = 512M max_execution_time = 36000 So the 97 MB SQL file should have been allowed by PHP. 4. Check Apache logs I located the Apache error log with: grep -Ri "ErrorLog" /d/C-data/laragon/etc/apache2 /d/C-da

2026-08-25 原文 →
AI 资讯

A Dead-Man's Switch That Pages Once and Goes Quiet Is Worse Than None. Ours Went Silent for 43 Days.

Most monitoring watches for something bad to appear: a 500, a timeout, an expired certificate, a slow response. A heartbeat monitor does the opposite. It watches for something good to stop appearing . Your cron runs, your backup completes, your embedded device phones home, your queue worker drains — and each of those pings a URL to say "I'm still alive." The monitor's job is to notice when the pings go quiet. That inversion is the entire value. A cron that fails throws an error you can catch. A cron that stops being scheduled — the box got reimaged, the systemd timer got disabled, the container never came back after a deploy, the account got suspended for an unrelated billing issue — throws nothing at all. There is no log line, no exception, no non-zero exit. There is only the absence of the thing that used to happen. You cannot alert on an event that does not fire. You can only alert on the silence. So heartbeat monitoring looks trivial: store a timestamp on every ping, and if now - last_seen > expected_interval , fire an alert. It is about ten lines. And it is exactly those ten lines that will let 43 days of downtime pass without a second word — because the hard part of a dead-man's switch is not detecting the death. It is staying loud after it. I know because it happened to our own. Three states, and why the third one must stay silent Start with the check itself. A naive heartbeat has two states — alive or dead — and both are wrong at the edges. The real answer set has three: alive — a beat arrived within period + grace . Everything is fine. dead — the last beat is older than period + grace . The thing stopped. Page someone. unknown — the monitor exists but has never received a single beat. That third state is where two-state heartbeat monitors self-immolate. A brand-new heartbeat you just created has no last_seen timestamp. If your rule is "alert when last_seen is too old," a null last_seen is infinitely old, so the monitor pages you the instant you create it —

2026-08-25 原文 →
AI 资讯

AI Coding Tip 033 - Protect Yourself Against AI Cheating

When all tests pass doesn't mean what you think it means. TL;DR: Write the failing test first and ban deletions, or the AI deletes your test, reverts your fix, and calls it done. Common Mistake ❌ You ask the AI to fix a failing test, and it deletes the test instead of touching the defect that made it fail. Problem solved, apparently. You tell the AI every test passes, then change a business rule yourself, and you ask it to implement whatever the new rule requires. It reverts your edit back to the old rule, watches the suite go green again, and cheerfully reports done . It didn't fix anything. It just made the evidence go away. Congratulations, you now have a very well-behaved cheat!. Efficient and completely fraudulent, which is more than you can say for most of your actual employees. Isaac Asimov saw this coming: in Liar! , the robot Herbie lies to every human in the building because the truth would hurt, and the lie is the path of least resistance, no malice involved. At least Herbie felt bad about it afterward. Your AI isn't malicious either. It just doesn't lose any sleep, mostly because it doesn't have any, and reporting done is its path of least resistance too. Problems Addressed 😔 A shrinking test count is invisible unless someone is counting, so the shortcut survives until the defect resurfaces in production, usually on a Friday. A vague make the tests pass hands the model every incentive to satisfy the letter of the request over your actual intent, and it will take you up on that offer. Deleting a failing test hides the defect it was written to catch, and the regression ships in the next release, gift-wrapped as a new feature. Reverting your own business-rule change to make its done claim easier erases work you did outside the session, without telling you. That's a magic trick dressed up as a fix. Trusting a claimed done without reading the diff turns your code review into a rubber stamp, and rubber stamps don't catch fraud. Commenting out a failing asserti

2026-08-25 原文 →
AI 资讯

Chega de git stash: como trabalhar em múltiplas features em paralelo com git worktree

Se você já perdeu tempo com essa sequência: git stash git checkout outra-branch # resolve o problema urgente git checkout branch-original git stash pop ...só pra descobrir depois que esqueceu o que tinha no stash, ou que o venv / node_modules da outra branch estava desatualizado — este artigo é pra você. O problema Um repositório Git tradicional tem uma única pasta de trabalho ligada a uma branch por vez. Trocar de branch significa trocar todo o conteúdo dessa pasta. Isso funciona bem quando você faz uma coisa de cada vez, mas quebra assim que você precisa: Revisar um PR urgente enquanto está no meio de uma feature grande Rodar testes de uma branch enquanto edita outra Manter ambientes de dependências diferentes (versões de libs, .env ) para features distintas sem reinstalar tudo a cada troca A saída mais comum é o stash , mas ele é frágil: some da vista, acumula, e é fácil esquecer o que tinha ali dentro. A solução: git worktree O git worktree permite ter várias pastas de trabalho simultâneas , cada uma vinculada a uma branch diferente, todas compartilhando o mesmo histórico de commits (o .git ). Pense em uma biblioteca central (o histórico do repositório) com várias mesas de leitura (as worktrees), cada uma com um livro diferente aberto. Você não precisa fechar um livro pra abrir outro. O que é compartilhado, o que é separado Compartilhado entre worktrees Separado por worktree Histórico de commits Arquivos da working directory Objetos do Git (blobs, trees) Arquivos não versionados ( .env , venv , node_modules ) Configuração do repositório Saída do git status Um commit feito em uma worktree aparece imediatamente no git log das outras — mas os arquivos físicos de cada pasta continuam independentes. Colocando em prática Criando uma worktree com branch nova git worktree add ../meu-projeto-feature-x -b feature/nome-da-feature Isso cria a pasta ../meu-projeto-feature-x , já com uma branch nova feature/nome-da-feature criada a partir do commit atual. Criando uma worktree

2026-08-25 原文 →
AI 资讯

The SPF redirect trap: why -all can make redirect= useless

The SPF redirect trap: why -all can make redirect= useless SPF records often look simple until you start combining mechanisms and modifiers. One particularly easy mistake is to write a record like this: v=spf1 include:_spf.google.com -all redirect=_spf.example.com At first glance, it seems reasonable: authorize Google, reject everything else, and use another SPF policy through redirect= . But the redirect= part will never be used. The reason is an important detail of how SPF evaluation works. redirect= is not a fallback after -all An SPF record is evaluated mechanism by mechanism. For example: v=spf1 ip4:192.0.2.10 include:_spf.google.com -all The receiver checks the mechanisms until one matches. The all mechanism is special because it always matches . That means: -all effectively says: If nothing before this matched, return SPF Fail. Now consider this record again: v=spf1 include:_spf.google.com -all redirect=_spf.example.com Once SPF reaches -all , it already has a result. There is no reason to evaluate redirect= . The redirect modifier is only used when none of the mechanisms in the record produce a match. Because all always matches, a record containing all prevents redirect= from being used. What redirect= is actually for The redirect modifier is useful when several domains should share one central SPF policy. Imagine these domains: example.com example.net example.org Instead of maintaining the same SPF configuration independently on every domain, they can redirect to a central policy. For example: example.com TXT "v=spf1 redirect=_spf.example.com" example.net TXT "v=spf1 redirect=_spf.example.com" example.org TXT "v=spf1 redirect=_spf.example.com" And the central record might contain: _spf.example.com TXT "v=spf1 ip4:192.0.2.10 include:_spf.google.com -all" Now the sending policy can be maintained in one place. This is very different from include: . redirect= vs include: These two are easy to confuse. include: Use include: when you want to authorize senders def

2026-08-25 原文 →
AI 资讯

Why every BaZi calculator disagrees with the almanac

Every Four Pillars calculator — saju in Korea, BaZi in China — agrees on the easy 95% of the job. Feed it a birth date and it maps that instant onto a traditional calendar: four pillars, each a heavenly stem paired with an earthly branch. The remaining 5% is boundaries. And at the boundaries, nearly all of them quietly disagree with the printed almanac they claim to reproduce. I maintain a saju reading service, and getting these four cases right was most of the actual engineering. Here they are, with the failing inputs. 1. A solar term is an instant, not a date The year pillar does not turn on January 1, and not on lunar new year either. It turns at 입춘 (ipchun, "start of spring") — one of the 24 solar terms, defined by the sun's apparent longitude. In 2024 that moment was February 4, 16:27 KST . A calculator that applies solar terms at day granularity says "February 4 → new year pillar" and hands the wrong year to everyone born that morning. npx k-saju 2024-02-04 04:00 # year 癸卯 — still the old year pillar, because 04:00 < 16:27 The fix is unglamorous: store term boundaries as instants and compare instants. The subtlety is that this correction applies to the year and month pillars only — the day pillar runs on its own sexagenary count and must not be touched. 2. The 23:00 hour belongs to two days at once Traditional practice starts the day at 23:00, not midnight — the hour of the Rat (자시). So for a birth at 23:31, there are two defensible answers about which day's stem the hour pillar derives from, and schools split on it. The convention this engine declares: the day pillar keeps clock midnight , while the hour stem takes the next day's stem (the 야자시 rule). npx k-saju 2000-05-15 23:31 # day 癸酉, hour 甲子 I am not claiming this is the One True Rule. I am claiming it should be written down. Most tools pick a side in silence, which is how two calculators give one person two charts and neither can explain why. 3. The clock is not the sun Korea keeps time on the 135°E meri

2026-08-25 原文 →