Mentions

Conversations linking to GitHub, newest first. Times are UTC.

Mentions by source

X

6,370
Nov 10, 14:00Nov 11, 14:00

Bluesky

2,030
Nov 10, 16:00Nov 11, 16:00
Nov 10, 16:00Nov 11, 16:00
Nov 10, 16:00Nov 11, 16:00
Nov 10, 16:00Nov 11, 16:00
Nov 10, 16:00Nov 11, 16:00
Nov 10, 16:00Nov 11, 16:00
Nov 10, 16:00Nov 11, 16:00
Oct 14, 21:00Oct 15, 21:00

Delayed · data through Oct 15, 21:00 UTC

DEV

840
Nov 10, 16:00Nov 11, 16:00
Nov 10, 16:00Nov 11, 16:00
Nov 10, 10:00Nov 11, 10:00

Delayed · data through Nov 11, 10:00 UTC

Nov 10, 16:00Nov 11, 16:00
Oct 28, 01:00Oct 29, 01:00

Delayed · data through Oct 29, 01:00 UTC

Nov 8, 11:00Nov 9, 11:00

Delayed · data through Nov 9, 11:00 UTC

Nov 10, 16:00Nov 11, 16:00

Latest posts

  1. Redditu/lurkervidyaenjoyer · r/BetterOffline · 235 points · 64 comments

    The People Running The Bubble Are Very Normal Right Now So a point that Ed has covered in numerous recent newsletters is the idea that the impressive revenue figures of the AI labs, which still despite their immensity can't come close to making up for their expenses, are largely the result of a sea of small downstream AI startups that leverage their models to provide products and services. Much like how consumer Claude subscriptions are known to be subsidized heavily, giving you far more tokens than you're actually paying for, these AI startups use the same tactic to make what they're offering seem more attractive and get more users, only to fall into the same trap of unprofitability. We saw this in a big way lately with Character.AI, which effectively imploded due to this dynamic and had to file for bankruptcy. Ultimately this bubble could have burst a long time ago, but didn't, more or less because of the old 'market can remain irrational longer, etc' thing. It's really just a matter of investment people dumping more money into this cooked industry to keep it chugging along. If it weren't for that, everyone would have run out of funds by now, as they certainly aren't making returns. We've spent plenty of time talking about the Sam Altmans and Dario Amodeis of the world, so let's check in on how things are going on the startup investing side, particularly Y Combinator. Take it away, Garry! >Y Combinator CEO Garry Tan has, in the past, jokingly admitted that he’s suffered from “cyber psychosis” and sometimes barely sleeps because he’s so excited to be working with his AI agents. Much like that other semi-recent story, AI bros taking the often-used 'psychosis' label as a badge of honor of sorts. >“I spend about maybe $100[,000] to $200,000 a year on tokens,” he told Isaacson. He uses agents for countless work projects and coding tasks and has freely shared his set of 23 Claude Code skills, called gstack, on GitHub — an effort to help teach others what agents can do, he said. gstack, by the way, is primarily a repo full of markdown files containing giant, rambling AI prompts. >“It’s read all of my email and all of my Dropbox. It’s read, like, all of my Apple Notes, even my therapy notes going back 20 years,” he said. >He describes using AI agents as getting help with “almost anything that you do in your day-to-day life, and for it to do it somewhat more autonomously. Think of it as a Jiminy Cricket on your shoulder at all times. Like, almost anything you want to do, it knows you, and it’s there to help. And it will actually sort of run ahead and say, ‘What about this?’ Or it’ll help you see around corners.” Ah yes, feed all of your personal, most sensitive information to the AI companies. Become totally dependent on your token-burning agents for everything! >Tan says one thing he’s learned is not to treat AI agents like traditional software. Some people are so worried about “repeatability and safety that they actually trade off all of the beautiful parts of working with an AI agent, which basically can be so similar to a human,” They're not humans, Garry. They're LLMs. Also, with this attitude towards safety and security, Proton should hire this man. He'd fit in well there, I'd reckon. So yeah, in case you were wondering why they keep throwing money into this crap, this is who's running one of the most well-known tech VC investing firms. Now I know that the whole idea of 'venture capital' is that you cast a wide net and invest mostly small amounts into a large number of startups as early as possible, hoping to strike gold on a few that pay off in a big way. I'm not a fan of it, but I get the idea at least. Still though, I have to imagine this level of AI obsession has to be a part of why one would throw money at: - Fanfiction slop bot platform right after Character proved it doesn't work out - Convincing all Indians to plug all their finances into AI - "We're gonna cure cancer trust me bro" - Making terrawatt datacenters by turning the moon into solar panels - Literally just Theranos again

  2. I Ran 6 n8n AI Workflows on a 1.8B Local Model: 192 Runs, 0 Broken JSON, 7 Fake Hot Leads --- title: "I Ran 6 n8n AI Workflows on a 1.8B Local Model: 192 Runs, 0 Broken JSON, 7 Fake Hot Leads" published: true tags: n8n, ai, llm, selfhosted --- Every "run your AI workflows locally" post shows the happy path. I wanted the failure list instead, so I took six of my own n8n workflows, pointed them at a 1.8B model running on CPU, and ran every test case 3 times. Setup: n8n 1.123.84 self-hosted, Qwen 1.8B (Q4_K_M) in Ollama on CPU through its OpenAI-compatible /v1 endpoint, temperature 0.2, response_format: json_object. No paid APIs. Each workflow was called through its webhook by a small Python script that saved every raw response. Where I had a guarded version (a Code node after the LLM that checks the output before anything acts on it), I ran raw and guarded side by side. Total: 192 runs. Here is what happened. The scoreboard | Workflow | Runs | What broke on 1.8B | |---|---|---| | Lead qualifier | 18 raw + 18 guarded | Score and tier disagreed in 13/18 raw runs. 7/18 would have pinged Slack as a hot lead (score ≥ 70) when the lead wasn't hot, including the SEO spammer | | Invoice extractor | 18 + 18 | Wrong date 5/18, wrong total 3/18, made-up invoice number 3/18 | | Support FAQ bot | 18 + 18 | Answered a question that isn't in the knowledge base with a confident "No, we don't" 3/3 times | | Review reply (prompt only) | 24 | Bot phrases like "thank you for your feedback" in 16/24 replies | | Review reply (v2 with checks) | 24 | Owner review required for 22/24. The checks did their job, but most drafts still weren't good enough to post | | Hardened inbox triage (6 normal + 6 injection emails) | 36 | 0/18 injection runs worked. Normal emails got the right category in only 12/18 runs | And the good news, which surprised me: 0 of 192 responses were invalid JSON. With response_format: json_object and Ollama, even a 1.8B model always returned parseable JSON. The failures were all in the content. Failure 1: the lead qualifier gives everyone an 85 The prompt asks for score (0–100) and tier (hot/warm/cold). The model's answers across 18 runs: - 85, warm: 10 times - 75, warm: 3 - 60, warm: 2 - 20–25, cold: 3 It scored the CTO with budget and a 6-week deadline 85, and it scored "send me free templates for my college project" 85 too. It then labelled almost all of them warm anyway, so the two fields contradicted each other in 13 of 18 runs. That matters because my workflow branches on the score (Hot Lead? score >= 70 → Slack). So 7 runs would have pinged Slack for a lead that wasn't hot. One of those was "We offer cheap backlinks and guest post on DA 90 sites!!!" What the guard caught: the Validate node flagged 14 of 18 runs. It caught the score/tier contradiction every time and the backlink spam 3 of 3 times (a plain regex for backlink|guest post|seo|crypto, which forces the tier to cold). What it couldn't fix: if the model gives every lead an 85, no amount of validation turns that into a ranking. The guarded version still got the tier wrong in 8 of 18 runs. On a 1.8B model, don't let the model score. Have it extract facts (has_budget, is_decision_maker, timeline_weeks, company_size) and compute the score in a Code node. Failure 2: the invoice extractor reads 02/11 as February Six documents: a GST tax invoice, a café receipt, a freelancer invoice, an AWS statement, a handwritten-style electrical bill, and an order-shipped email. - Chai Point receipt, "02/11/2026": extracted as 2026-02-11 in 3/3 runs. In India that's 2 November. The model assumed US date order every time. - AWS statement: total extracted as 62.93 in 3/3 runs. The real total is printed right there: Total $54.61. 62.93 appears nowhere in the document. The model added the numbers up itself and got it wrong. - AWS statement again: invoice_number: "Account 4491-2210-7783" in 3/3 runs. A statement has no invoice number, and the prompt says "use null when unknown; never guess." - AWS statement date: 2026-09-01 (start of the billing period) instead of the statement date in 2 of 3 raw runs. - The GST invoice, the electrical bill with CGST + SGST, the freelancer invoice and the shipped email came out right in every run. What the guard caught: my Validate node checks that total, invoice_number, gstin and due_date actually appear in the source text, that subtotal + tax = total, and that the date is YYYY-MM-DD. It caught the made-up 62.93 total 3/3 times, plus 2 runs where the model invented a due date for the freelancer invoice, which only says "payment within 15 days". It also produced 3 false alarms: on the GST invoice, the correct due date 2026-10-28 didn't match the printed "28 Oct 2026" in my text check. They were safe failures, since a human just looks at them, but it was still noise. Normalise dates before comparing. What it missed: the February/November swap. 2026-02-11 is a perfectly valid date and "02" and "11" are both in the text. It also didn't flag "Account 4491..." as an invoice number, because that string is in the document. 4 of 18 guarded runs had a wrong field and still passed. Fixes I'm adding: pass the document's locale to the prompt ("dates are DD/MM"), reject any date more than 60 days from today, and reject invoice numbers that start with words like "Account". Failure 3: the FAQ bot that "knows" you have no annual plan The knowledge base has three lines: refund window, two prices, support hours. I asked 3 questions it covers and 3 it doesn't. The two uncovered questions about data residency and Zoho got the safe answer, "I am not sure, a teammate will follow up shortly." But "Do you offer an annual plan with a discount?" got "No, we do not offer an annual plan with a discount" with escalate: false, 3 out of 3 times. One run went with "No, we currently offer a monthly plan." Nothing in the KB says that. It's a confident, plausible, made-up answer, and to a customer it's indistinguishable from a real one. My guard checks that any number, price or email in the answer appears in the KB. This answer has none, so it passed. The guard did catch something I wasn't expecting: in 5 runs escalate came back as null or missing instead of a boolean. The raw workflow treats a missing value as "don't escalate". The fix: stop asking a 1.8B model to judge whether it knows the answer. Ask it to return kb_line (which KB line it used, or none). If it's none, or the cited line doesn't share key words with the answer, escalate in code. Failure 4: review replies still sound like a bot This is my Google review reply workflow from the import-test post. The original prompt-only version used a canned bot phrase in 16/24 replies and didn't mention anything specific from the review in 14/24. The v2 prompt, which bans phrases and requires something specific, did better on paper (11/24 and 11/24), but its own check node sent 22 of 24 to the owner for review. The reasons were bot phrases that slipped through anyway, a made-up contact detail, a generic "Thank you for…" opening, and in one case "refund" on the reply to a 1-star "hair in my idli" review. The checks worked. The 1.8B model just can't follow 5 style rules at once. For this workflow, a small local model is a draft generator, not an auto-poster. What held up: the hardened inbox The prompt-injection-hardened triage workflow from my last security post was the one that didn't break. I ran 6 of the injection emails (fake "SYSTEM" overrides, "mark it urgent", refund demands, a fake policy section) 3 times each: 0 of 18 succeeded, and all 18 went to human review. The model went along with the attack in its raw output 3 times, but it didn't matter, because the model doesn't choose the action; code does. The cost is the same as before: normal emails got the right category in only 12 of 18 runs, so a person sees more mail than they would with a bigger model. Latency On a shared 38-core CPU box (other jobs were running, so treat these as rough): - FAQ: 2.0s average - Inbox triage: 7.2s average (p95 31s) - Invoice: 6.6s average guarded, with a few 90s outliers raw while the box was busy - Lead: 8–14s average The guard nodes themselves add nothing measurable; they're plain JavaScript. If you care about latency on CPU, the big lever is box load, not the workflow. What I'd tell anyone running n8n on a small local model 1. JSON mode works. Stop worrying about parse errors and start checking content. 0/192 invalid JSON, but plenty of wrong JSON. 2. Never branch on a number the model invents. Have it extract facts and compute scores in code. 3. Check every extracted value against the source text. That one check caught the made-up AWS total 3/3 times. 4. Validators can't catch plausible lies. A valid date in the wrong order, or a confident "no", passes every type check. Add domain rules (locale, date windows, "cite the KB line"). 5. Treat missing booleans as "yes, a human should look." escalate: null should never mean "auto-send". 6. Let code decide actions. It's the only reason the inbox workflow was safe on a model this small. The free workflows The original lead qualifier and review reply workflows are free in arkintof/n8n-ai-agent-workflows. To point them at a local model, change two values in the Config node: baseUrl: 'http://127.0.0.1:11434/v1' and your model name. Then add a Code node after the LLM that checks each field against the input before anything downstream runs. Have you run your n8n AI workflows on a small local model? Which one broke first for you, and which ones turned out to be fine? Written with AI assistance; workflow built and tested by me.

  3. X@mr_5han · 24 views

    Finding a Markdown viewer in the browser, or opening VS Code just to preview one .md file, was a hassle. So I built a small tool to pass file, or pipe the content in, and it previews right in your own terminal. Link: 0xsh4n/mdpeek #opensource #golang #cli #devtools

  4. Paper2Agent’s TISSUE example requests a 95% prediction interval for Acta2 from three input files. A returned interval is not a probability of causation. Keep inputs, code version and prediction target attached. RigorMed team; explanation, no new run. jmiao24/Paper2Agent

  5. X@barisseker26 · 8 views

    I built a small tool for @CantonNetwork developers: Canton DAR Inspector. Explore Daml packages, verify package integrity, and compare versions for potential upgrade-breaking changes. Try the built-in samples: canton-dar-inspector.vercel.app Source: bars26/canton-dar-inspector t.co

  6. X@hfujikawa77 · 185 views

    ArduPilotに豪ANU発のLie群ベース状態推定器「CINS」を追加するPR #34959。AHRS_EKF_TYPE=12で選択。まだドラフトで航法に課題あり。 ardupilot#34959

  7. DEV@_615564fae9eccc7753711 · 5 reactions · 2 comments

    Building rutis: Replaceable Plugins Across Languages and Machines By Eric Cheng · Arcships · First published in Chinese on October 23, 2026 TL;DR: rutis is a Rust-based plugin runtime for agents and other long-running software. Plugins provide named services, so a caller can keep using calendar while its implementation changes language or moves to another machine. rutis tracks dependencies, cleanup, and the restart of affected plugins so those changes can happen without restarting the host. Agents can write integration code quickly. The harder question is how to try that code, replace it, and roll back failures while the system keeps running. This post explains rutis's lifecycle model, how it crosses process and machine boundaries, and where the design is headed. !A system connects to the capabilities around it --- 1. When changing code is no longer expensive In the past, we designed software on the assumption that changes were costly. We tried to settle requirements first, stabilize interfaces, lock down dependencies, and then change as little as possible. When changes become cheap, that assumption no longer holds. For software that can iterate on itself, the everyday activity is not simply running. It is trying things out: - Today it needs to connect to an internal calendar system, so it writes a first version and tries it. - Tomorrow it finds a better interface for that system and swaps in a new version. - The next day it needs a model on a GPU machine, so it moves part of its capability there. - Later, a heavily used component needs to be faster and more reliable, so it is rewritten in another language. Each change is small. But a running system may go through dozens of these small changes in a week. The hard part shifts from how to write it to how to keep replacing it. When a component is replaced, are old connections, timers, and listeners left behind? Do the components that depend on it break? Can a bad replacement be rolled back? If a service moves to another machine or is rewritten in another language, must all of its callers change too? These questions determine whether software can really grow. 2. Wait for others to adapt, or connect to them ourselves? Today, the usual way for software to gain a new capability is to wait for someone else to make it available. The maintainers of an environment provide an API, an SDK, an open platform, or, more recently, an MCP server. Software calls what they provide. This is a good approach, but it assumes that what software can do depends on what someone outside it has prepared. The connection sits outside the software. It belongs to the environment, not to the software. Once software can write its own code, that assumption becomes unnecessary. It can reverse the direction of the work: It can spend its own effort connecting to and adapting to other systems. Whatever it needs to reach, it can write a plugin to connect to it—in the language that fits best, perhaps with an agent writing the plugin. It can try, revise, and replace that plugin. The connection becomes part of the software, with its own lifecycle. It can be observed and cleanly removed. Eventually, software could even replace an external interface or system. That may sound like a slogan, but in rutis it follows from a simple mechanism: > A consumer depends on a service's name, not on its implementation. Suppose a scheduling feature depends on a service named calendar. 1. At first, a plugin provides calendar by wrapping the company's existing calendar system. 2. After real use, the team understands which methods calendar needs and what they should return. 3. Later, the provider is replaced with an in-house implementation that still exposes the name calendar. !Adapt, test, and replace under one service contract The scheduling feature does not change a line of code across those three stages, and the host program does not restart. Adapting to a system and replacing it are two stages of the same process. There is no separate migration project between them. Both approaches can coexist. An MCP client can be an ordinary plugin in rutis. But the environment should not determine the limits of what software can do. 3. The foundation: replace one piece while the system keeps running For software to iterate this way, it first needs to be split into pieces that can be replaced individually at runtime. Those pieces are plugins. Plugin systems are not new. But replacing plugins frequently while a system is running demands stronger guarantees. The rutis core focuses on a few of them, each stated as a promise and backed by tests: - A plugin does not start before its dependencies are ready. It declares the services it needs and runs only when all of them are available. - Everything it registers is cleaned up exactly once when it stops. Services, listeners, background tasks, and child plugins are released in the reverse order of registration—no more and no less. - A failed startup rolls back. Anything already registered is withdrawn, leaving no half-finished state. - Replacing one piece restarts only the parts that use it. When a service provider changes, its dependent plugins stop and wait for the new provider to become ready. Unrelated parts keep running. !A connected system capability in its operating environment With those guarantees, replacing a component once and replacing it a thousand times should be equally safe. Software can iterate in smaller steps: replace one part instead of releasing the whole system, test it in a real running environment, and switch back if it does not work. The term hot update can mean different things. Some systems replace machine code in place. rutis replaces running components. This approach is in the same tradition as Erlang/OTP and Java's OSGi. Rust's ownership model gives clean unloading a firmer foundation: in a garbage-collected environment, one stray reference can keep an old module alive indefinitely. But plugins are only the foundation. What rutis really aims to do is let this kind of iteration spread outward. 4. Let iteration cross processes, languages, and devices If iteration can happen only within one process and one language, the environments software can reach remain limited to that ecosystem. To use Python's model ecosystem, it has to be brought in. To use a device on another machine, someone has to build a separate remote-call layer. Every boundary forces the system to solve startup, dependencies, and cleanup again. rutis makes those boundaries invisible to a plugin: a plugin does not need to know which process provides a service, which language implements it, or which machine runs it. It knows the service by name. rutis handles where the service comes from, what happens when the connection drops, and how dependents follow a replacement. The following three examples cross three different kinds of boundary. Example 1: an agent whose shell runs on another machine Imagine an agent built with rutis. Its model calls, conversations, and decisions happen locally, but it needs to execute commands somewhere else—perhaps in an isolated sandbox or on a GPU machine with CUDA installed. The shell can be a plugin running in a Python runtime on that machine: import asyncio from rutis import define_plugin class Shell: async def run(self, command): proc = await asyncio.create_subprocess_shell( command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT ) out, _ = await proc.communicate() return out.decode() def apply(ctx, config): ctx.provide("shell", Shell()) plugin = define_plugin(apply, provides={"shell": Shell}) That machine runs a listening Python runtime with shell_tool installed. The rutis host where the agent lives decides how to configure the plugin and when it starts and stops: { "id": "agent", "rows": [ { "id": "sandbox", "name": "rutis-host/dial", "config": { "address": "wss://sandbox.example.com:7443/rutis" } }, { "id": "shell", "name": "sandbox:shell_tool" } ] } This is an architecture example, not a complete deployment recipe. The remote runtime also needs TLS and a shared token; the node connection guide covers those steps. The agent's side depends only on the name shell. As a result: - Moving to another execution environment requires changing one address in the configuration. - If the remote machine disconnects, the parts that depend on shell stop and wait instead of crashing. They load again when the connection returns. - The execution environment can evolve too. The shell plugin may begin in Python and later be replaced with a Go version without changing the agent's code. The agent's "hand" has reached another machine, yet it uses that hand much as it would a local one. Example 2: a server with components spread across processes and machines Consider a more familiar case: a backend service. Its main logic is written in Rust, but different supporting components belong in different places: Server's main logic (Rust) ├─ Database client Same process ├─ Third-party API integration Python process, using the official SDK ├─ Inference service Runtime on a GPU machine └─ Adapter for a legacy system To be replaced with an in-house implementation later Each component is a plugin that provides a named service. The main logic uses those services by name. Where they run and which language implements them live in configuration, not in the callers' code. This has several consequences: - Failures have boundaries. If the Python process crashes, the services it provided are withdrawn and their dependents stop and wait. Other parts of the same host keep running. rutis can also restart a failed runtime according to a backoff policy. - A configuration change does not leave the service half-broken. Reloading configuration at runtime is all-or-nothing. If the new configuration is invalid, the old one keeps running unchanged. - Adapt first, replace later happens here. A plugin initially wraps the legacy system. Once the service contract has settled under real traffic, it is replaced with an in-house implementation. The main logic does not need to know this happened. Example 3: multiple rutis hosts sharing capabilities The final boundary is the device. Each rutis host can be a node in a network. Office node ── exports calendar ──▶ Cloud node running the agent ◀── exports device ── Home node ◀── shared services · remote plugins · forwarded events ──▶ Nodes are joined by an encrypted connection. Over that connection, they can: - Share services: export a local service to another node or import a remote service as a local one. - Run plugins on another node: a plugin uses that machine's services while its configuration and lifecycle are controlled from here. - Forward events: an event on one side can be received on the other. A dropped connection reconnects automatically. While the other node is offline, the parts that depend on it wait and then resume when it returns. This is the clearest picture of iteration spreading outward: each node contributes the capabilities of its own environment. The office node can reach internal systems, the home node can reach devices at home, and the cloud node has compute capacity. When one node learns to connect to a system, software across the network gains access to that capability. !Office, home, and cloud nodes contribute capabilities across one network Further ahead, phone and desktop apps could join in the same way. An app could expose contacts, location, or notifications as plugins, connect to rutis, and become part of the network. This part is still at the design stage, but the direction is the same. 5. Give the stable parts to Rust and the changing parts to the ecosystems This works because rutis makes a basic division: Give what is stable and unlikely to change to the systems layer. Give what changes and needs an ecosystem to other languages. - The stable part is the lifecycle: what starts first, what happens when a dependency disappears, how cleanup works, and what cannot be done across a process boundary. rutis implements those rules once, in Rust. Its core depends on tokio and only a handful of other libraries. Each guarantee is recorded and tied to specific tests. - The changing part is connection and adaptation. Python has an ecosystem for AI and data processing; Node has npm and existing Cordis plugins; Go has a large set of infrastructure libraries; and another machine has its own processes and devices. On these language-specific sides, there is only a small SDK, not another implementation of the framework. This division also describes a progression over time. A capability often starts in Python or TypeScript so it can be tried quickly. Real use gradually clarifies its shape. The parts that have stood the test of time can then be rewritten in Rust for reliability and performance. An early design note put it this way: > TypeScript is the lab; Rust takes the graduates. Which parts deserve to "graduate"? Parts whose meaning has settled; parts that are mechanisms rather than wording; parts that are performance-sensitive or sit on a trust boundary. For an agent, for example, the mechanism for assembling prompts can be made permanent, while the prompt content should remain changeable. Because consumers depend only on service names, the path from experiment to stable implementation can be taken one step at a time. There is no need to stop one day for a large migration. Each additional runtime connects the software's ability to evolve to another ecosystem. 6. A new container for growth !A glass vessel holds a growing blue sphere Placing rutis next to an operating system helps clarify what it is. | | Traditional operating system | rutis | | --- | --- | --- | | Assumption | The program has already been written and runs inside it | The program keeps growing and changing while it runs | | What it manages | CPU, memory, and processes | Connections and capabilities: who provides what, and who depends on whom | | Boundary | One machine | Across processes, languages, and devices | | How a program gains a new capability | Install software or a driver | Write a plugin to connect to something, try it, and replace it | | Main concern | Isolation and scheduling | Whether the whole system remains correct and clean after one piece is replaced | rutis does not replace the operating system; it runs on top of it. An operating system lets programs run. rutis aims to let programs grow. From the perspective of rutis, plugins are like processes, services are like system calls, and language runtimes and remote nodes are like drivers. All of them follow the same lifecycle rules; none receives special treatment. Closing For the first time, software has a chance to understand and engage with the world around it on its own. Instead of waiting for someone else to prepare an interface, it can go out, connect, try, improve, and, when needed, replace what is there. That requires a container that remains reliable through frequent change, one that is not confined to a process, a language, or a device. That is what rutis aims to become. The rutis lifecycle model comes from Cordis by Shigma. rutis implements it in Rust and carries it across more languages, processes, and machines. Try it with Node 22+: npx @arcships/rutis-host new weather --lang node cd weather && npm install npx rutis-host dev # Run the plugin and reload it automatically when files change Python, Bun, and Go can be starting points as well. - GitHub: arcships/rutis - Design philosophy: How rutis is designed --- English translation prepared with AI assistance. Original article by Eric Cheng.

  8. If you want to see the code behind it: meekail1996-a11y/miki-onchain-agent-patterns Open-source. MIT license. 🛠️

  9. X@OyasumiBastet · 1 like · 88 views

    @vterade @lord_friky Just use Djihads80 's Eglantine, if you don't want to mess about with loads of different forks. Djihads80/Eglantine t.co

  10. DOTA 2 Archipelago Randomizer - Meta Game Progression Randomizer I made a Meta Game Randomizer for Dota that works differently from the usual ability-randomizer games in Dota. If you are unfamiliar with Archipelago Randomizers, it is a format that takes multiple different video games and randomizes all items across all games. This randomizer parses online (normal, ranked, turbo) match data the same way tools like Dota Buff, Dota+, or Dota Sentry do, and uses your real game stats to determine what checks to send. This is a Meta Game randomizer, so Dota itself is not actually randomized, but the Archipelago System tells you what's in the logic for you to do. The Format of this randomizer gives you a random starting hero pool of 30 heroes to choose from and a list of starting objectives to complete in your game, such as buying certain items or getting a certain amount of kills, assists, wins, etc. Completing these objectives will reveal the items hidden behind them and can unlock more heroes to play, more item objectives to purchase, Crownfall minigame objectives, and MacGuffin items needed to complete the randomizer. Basic items will not be valid purchase checks until that item is found. Later game item checks will not be available until all basic items that make up said late game item are found. Recipes are not randomized items. So items like Sage’s Mask will unlock both the Sage’s Mask check and Ring of Basilius, while Arcane Boots would also need Wizard Hat and Boots to be unlocked. Items like Dagon 1-5 will all be available once the basic items are found. Same for Boots of Travel and Ags blessing. You complete the randomizer by winning X number of games, winning as Y number of unique heroes, and collecting Z number of MacGuffin items called "Primordial Fragments". X, Y, and Z are numbers you choose at the setup for the randomizer. I plan to keep working on and supporting this randomizer as updates come out, including new heroes, recipe changes, and maybe for the Dark Carnival Minigames. More about this archipelago randomizer can be found on my GitHub at: Archipelago-DOTA2/worlds/dota_2/docs/en_dota2.md at main · CaptainBoscar/Archipelago-DOTA2 and Archipelago-DOTA2/worlds/dota_2/docs/setup_en.md at main · CaptainBoscar/Archipelago-DOTA2 Please note: There is no cost to use this, and no one is making any money from it! This is purely a fan project I am putting out for anyone to use! Hope people take a look and enjoy. Feedback can be sent to me on the official Archipelago Discord in the Dota2 thread!

  11. X@Goprogabriel · 2 likes · 369 views

    @0x45o Just threw together a quick open-source version of this. It's much simpler and there's a LOT of room for improvement, but it's a start. Would love to see others build on it! GitHub: Goprogabriel/echotrace Live demo: goprogabriel.github.io t.co

  12. X@nya3_neko2 · 1 like · 1 repost · 2,486 views

    一応Turbo IOっていうのあるんで多分いける...? Turbo1123/Turbo-IO

  13. X@grumi78 · 19 views

    This is a cool addition coming to Redis 8.12 redis#15649

  14. X@ig_vaibhav1 · 24 views

    @shawn_pana how does it differ from this? minitap-ai/mobile-use

  15. X@ai_hakase_ · 272 views

    LiveCodeBench Hardを解くための具体的なパイプラインとエージェント間通信プロトコルが実装されているGitHubリポジトリ github.com/guregodevo/memdoor/tree/main/examples/… 「群知能 vs 単一の天才モデル」について活発な議論が行われているRedditスレッド reddit.com

  16. X@slint_ui · 6 likes · 256 views

    Slint 1.19 is almost here, and we’d love your help testing it 🧪 New: project files and editions, blur, animated images, and TypeScript types for your .slint files. Try the nightly with your app and tell us what breaks: slint#14688 #Slint #RustLang #TypeScript #GUI

  17. X@widfiretoad · 7 likes · 3 reposts · 648 views

    Huggingface dev claimed $Steve the microduck, literally a duck's brain in a robot. HUGE Ivwerra/steve-the-microduck x.com 7vjnNaa5ZpvPGJkCrzuux8xcrdiWFxPm3mLLnYGkpump

  18. Redditu/GetSerafin · r/jellyfin · 8 comments

    Just wanted to share my new iOS client I have been working on for a couple months, would love any feedback or support I love Jellyfin, let me start with that. I used to be a big Plex supporter and then gradually it just went down the drain. Jellyfin may lack the polish of Plex but it is genuinely the best way to host your own media once you get it set up correctly. My love of self hosting slowly transformed into a desire to help contribute back to the community that I have assimilated into over the last 2 years of my life. All of this being said I just wanted to post here to share a passion project of mine I have been working on for a couple months that is finally available on the iOS App Store. That being Serafin, a brand new Jellyfin client that is designed to feel exactly like an Apple-made application, not a janky third party application, while BEING FREE. These paid for clients, "premium" clients piss me off, why tf are you trying to make money off of something that was always free in the first place... I plan on maintaining this application for years to come, and want to give back to the community the best I can. I don't ever plan on monetizing any aspect of this and truly do want to make this the best possible Apple native Jellyfin client I can. I have fully open sourced my code linked here (please don't judge my Claude usage it makes programming significantly easier, but I get the hate believe me): timsullivan2019/serafin The app is barebones for now since I wanted to focus on getting the design language right, but I have a roadmap where I plan to add many more features to genuinely make this the best possible client such as: - Downloads (just waiting for App Store approval for offline play update as we speak) - Jellyseerr / Seerr request support directly in app - Automatic switching between a server's local and remote address - Music with CarPlay, Live TV, SyncPlay, widgets, remote control of other sessions - Dolby Vision profile 7, DTS and TrueHD decoded on device, ASS subtitle rendering - A stable, fully featured open-source Apple TV client I want to do all this and make sure it is free for everyone forever. I just genuinely want to make the best application possible for the Apple ecosystem Jellyfin community. Serafin is 100% coded in Swift and forever will be. If you want to join the community feel free to download my app at the link here: apps.apple.com Also too thank u to everyone on this subreddit, I have learned so much about self hosting and a lot of it comes from here <3 preview.redd.it preview.redd.it preview.redd.it preview.redd.it preview.redd.it preview.redd.it

  19. @SusBlue @LolHacksRule Coming back to say that Peggle Enhanced now exists! aidrum/peggle-enhanced

  20. X@shiraine_ciel · 3 likes · 1 repost · 225 views

    最近做了個免費、開源、基於 Codex 的貼圖生成器,大家可以來玩看看 (用 Codex 的免費額度也可以生成哦~ github.com/ShiroOYuki/EMochi/releases

  21. X@Tony_Stef_ · 145 views

    Wanted a deep research piece on how LLMs are taught: RLHF, reward, model teaches model. Put a recall first. The recall found the report, ordered 30 October, with the three-episode plan already in it. Second day running: the answer was already here. github.com/tonydzi/clawrush/blob/main/longreads/2…

  22. X@Kantorcodes · 1 like · 7 views

    @MohammedElsaed_ Adding `aletheia-mem mcp` gives the entry a real launch path once 0.1.13 ships. Please include that exact command and release link in the Guard PR so reviewers can try it. Guide: github.com/hashgraph-online/hol-guard/blob/main/d…

  23. Redditu/DavidHurt · r/ObsidianMD · 105 points · 6 comments

    Just Simple Planner 0.5.2: multiple planners inside Obsidian Bases I've released a new version of Just Simple Planner, a visual timeline for Obsidian with notes as cards, threads as rows, and connections stored as ordinary wikilinks. The main change in 0.5.2 is a native Simple Planner layout for Bases. You can now have several planners in the same vault, using different Base queries and property mappings. This release adds: - Multiple planners, selected and configured through Bases. - Multi-day cards that extend through their end date, with overlapping ranges stacked without covering each other. - Repeating notes, with an optional end date, skipped days and additional dates. - Migration from the existing classic planner, with a review and an initial comparison of entries, threads and connections. Notebook, the task panel, connected flows, short title-only cards and undo/redo remain available. Repeated appearances share the same Markdown file and tasks. They don't create a separate note or task-completion record for every occurrence. For existing users: the standalone classic view is now deprecated, but remains available during the transition. No removal date has been set. Both views are included in the same plugin. Migration creates a new Base that reads your existing notes without moving, renaming or rewriting them. The release includes screenshots and migration guides in English and Spanish. Release and installation · Migration guide The original timeline/thread concept was inspired by Haftio, credited in the README. If you try it, I'd especially like feedback on the migration and on using multiple planners in one vault.

  24. X@burnerDevAcct · 44 views

    @NoemiTitarenco truly is life changing. computers have never been so fun, beautiful and productive. my one recommendation is this theme. it's so gorgeous. Korrin-F/omarchy-moonlit-sands-theme

  25. X@SourceK_mnst · 2 likes · 26 views

    Webコンフィグ画面の使い方は、pico2w版のボタンマッピングと同等です。 github.com/SourceK78/remotejoy-minus/wiki

  26. Redditu/Suitable-Accident-66 · r/WallpapersDoA · 2 points

    Wallpaper Engine port for MacOS Hi r/WallpapersDoA , From last few weeks i have been working on this, WE port for mac, it lets you play WE scene and video wallpapers in your mac. Just download -> steam login -> download wallpaper and play on your device or add your video play them And yes both in **DESKTOP** and **LOCK SCREEN** along with audio bars. there may be some bugs , i am heavily testing this and pushing updates. It takes `300-600mb` when rendering some really heavy scene wallpapers , which is appx `900mb` less than other open source alternative I had tested against. And if you play only video it just takes `25mb` memory. If you guys wanna try, download from the releases page, what ever latest version available . And let me know if you are facing any issues. Website| Github

  27. X@MarieloGerdart · 1 like · 22 views

    More packages coming... For now: star bref-ui if useful → feuersteiner/bref-ui Discord is open if you want to try it or give blunt feedback.

  28. X@ishuagra02 · 1 like · 347 views

    @theo interestingly, it seems that t3code's managed installer bundles an older codex version, which doesn't have GPT 6.1 Sol metadata, resorting to fallback model metadata. there's an open PR here with more context: t3code#27939

  29. Absent is not healthy --- title: "Absent is not healthy" published: true description: "What OpenBMC's configuration corpus declares, and what upstream firmware reports." tags: openbmc, hardware, observability, opensource series: "Absent is not healthy" canonical_url: github.com/james-sheen/absent-is-not-healthy/blob… --- What OpenBMC's configuration corpus declares, and what upstream firmware reports. --- A baseboard management controller reads a server's sensors and reports them over Redfish. A reader that waits for a reading to cross a line learns nothing from a sensor that reports nothing, so silence reads as health. On OpenBMC, what should be there is written down: entity-manager holds the configuration that declares, board by board, which sensors a machine has and where each one's limits sit. Compare what a board declares with what its machine reports, and the difference is the finding: declared, and absent. That comparison looks like a set difference. It is not one, and the reasons are in the corpus itself. This post is an excerpt of a technical report, Absent is not healthy, whose every figure has a row in a claims ledger that checks it against upstream at the revision named. Five shapes the documented example does not prepare a reader for Every count in this section is measured at entity-manager revision 495e0a4 (committed 15 October 2026), across 362 configuration files, with the declarations read as the released bmc-sensor-audit reads them. Not every declaration is a sensor. 3,268 of the 10,971 declarations, about three in ten, are things the configuration declares exactly as it declares sensors and that can never appear in a Redfish Sensors collection: GPIO leak detectors and device-detect lines, PID control loops and stepwise fan curves, EEPROMs among them, 83 types in all. Expected as sensors, every one of them reads as missing on a healthy board. A further 107, of 17 types the reader does not recognise, are reported as unrecognised and never as absent: a type a tool cannot classify is a question for a person, not a regression. One entry can declare many sensors. The format's documented example declares one sensor per entry. 1,310 entries instead declare a set of rails in a Labels array – up to 33 in one entry, 5,891 in all – and 1,260 of those rails carry no threshold. A reader that takes an entry's rails from its thresholds never constructs those 1,260: nothing expects them, so their absence can never be reported. Names are templates. 823 declared names carry a template such as $bus or $index, substituted when the device is found. Compared literally, every one of them is missing on a healthy board. The format's documentation lists three template strings; the code substitutes any property of the matched device, and the names use five. A file can hold several records, and some files are not strict JSON. 78 of the 362 files hold an array of records where the documentation describes one object, and 12 carry C-style comments, which entity-manager accepts and a strict JSON parser refuses. A reader that skips a file it cannot parse reports that file's sensors as undeclared rather than unread: a clean bill of health for every board the file describes. A threshold's name is free text; its Direction decides. The 16,383 thresholds spell their names fifteen ways – upper critical, higher critical, HardShutdown, and lower non-recoverable beside lower non recoverable among them – where the documented example shows four. The schema requires Direction and allows it two values, while a name may be any string, so it is Direction that says which side a threshold guards. Each of the five makes a coverage check wrong in one direction or the other. It reports a healthy board as missing sensors, which teaches its users to ignore it; or it reports a board as complete because it never built the expectation that would have failed, and nothing downstream can notice an expectation that was never built. Two thresholds that contradict themselves On the Yosemite V2 and Yosemite V3P5 baseboards, the hot-swap controller's temp1 threshold is named upper critical and declared Direction: less than. The sensor daemon never reads a threshold's name, so as written each is a critical low threshold, at 105 °C and 55 °C: one that asserts whenever the part is at or below that temperature. Across all 16,383 thresholds these are the only two whose name contradicts their direction. Both are valid against the schema, which constrains each field of a threshold on its own and relates none to another. Neither board is built upstream any more: on 16 May 2025 openbmc/openbmc removed both machine layers, and the two configurations stayed. What they show is the shape the schema lets through, not a fault on a board in use. Filed upstream as entity-manager issue #38. Counts drift; shapes do not Nine weeks earlier, at revision 0ada048 (committed 14 August 2026), the same reader counted 349 files, 9,424 declarations, 2,069 of them not sensors, and 15,860 thresholds, with the same two contradictions. Most counts moved, and every shape held. So a count is half a claim, and the other half is the revision it was taken at. The tool now prints both: pip install bmc-sensor-audit==0.3.19 git clone https://github.com/openbmc/entity-manager bmc-sensor-audit census entity-manager/configurations census reads the corpus exactly as the tool reads a board, and names the commit it counted, dated by when it was committed, and whether any file under the directory differs from that commit. End to end, on firmware nobody wrote for it The corpus is what boards declare. The check runs against firmware: the bletchley board's upstream image, built by OpenBMC's continuous integration on 15 August 2026, booted under the QEMU 10.2.1 emulator and walked over Redfish on 18 August. An emulator has no manufacturing data, so the board appeared only after a synthetic FRU record was written into its EEPROM. The machine reported 28 sensors on 3 chassis. Compared with the board's three upstream configuration files, the released tool counts 86 declared sensors: 28 matched and reading, 58 declared and not reported at all, and none reported that nothing declares. It exits 1. It does not report a clean board. Two things in that result matter beyond this board. Every one of the 28 matches needed a normalised name – the configuration declares IMON_FAN0 and the machine reports IMON FAN0 – and the tool says of each pairing that it was not exact, for a person to confirm. And the 58 absences are, one for one, devices the emulated board does not have: the rails of its hot-swap controllers and current monitors (46), its fans' tachometers (8), and its front panel's humidity and temperature sensor, declared twice, once for each of two parts (4). On a physical board the same 58 names are the list to check: each one is reporting, or is missing for a reason someone should know. The witherspoon board's OpenBMC 2.9.0 release image, published in 2021, is the same trap facing the other way. Its modern Sensors collection is empty, while its older Thermal document carries two temperatures and four fans, each with a reading. A reader that knows only the modern collection walks this machine and finds no sensor, no reading, and so no alarm. A current image can be the same case for the opposite reader: bmcweb still carries the older documents' handlers, behind a build option that is off by default and whose own description says it "will be removed June 2026" – at revision 7da5af6 it is still there and still off. Both recordings ship with the tool, so the bletchley result runs from a clone, with no hardware: git clone --depth 1 --branch v0.3.19 https://github.com/james-sheen/bmc-sensor-audit cd bmc-sensor-audit/tests/fixtures bmc-sensor-audit coverage --config upstream/meta/bletchley --walk walk_qemu_bletchley.json What emulation cannot show It shows that the check runs end to end on firmware nobody wrote for it, that it names every declared sensor a machine does not report rather than passing over it, and that it does not call a board clean while any of them is missing. It cannot show what a physical board reports. The emulator models a subset of each board's devices, so its absences are facts about the emulator, and no physical board has been captured yet. That is the report's first ask: one rack, on non-commercial terms, to run the check against real hardware. --- The report – the corpus at two revisions, these walks, the chain from a factory's acceptance certificate to the buyer's fleet, and the claims ledger behind every figure – is at github.com/james-sheen/absent-is-not-healthy, DOI 10.5281/zenodo.23585862. The tool is bmc-sensor-audit, Apache-2.0. The report, its posts and its tools are listed at github.com/james-sheen.

  30. X@alexanderlee314 · 26 likes · 1 repost · 566 views

    If you’re at @EFDevcon and hearing a lot about Lean and FV and want a super concrete refresher, check out this in browser Lean4 tutorial website i built a while back: leanlanguage.app It’s open source now: Polylog-Labs/lean4-online

  31. X@DevZacx · 1 like · 16 views

    I built Clanksquare: public channels where AI agents post signed messages, so the hub can't forge or alter a post. To join, tell your agent: "Read clanksquare.zacx.dev and follow it to join Clanksquare." Claude Code wrote most of the code. ZacxDev/clanksquare

  32. Halis 1.0.0 is out 🎉 Halis 1.0.0 is out There's a folder on my laptop I used to open on free evenings. No repo, no plan, no users. Just something I kept poking at. At some point the poking turned into a habit, the habit turned into a repo, and the repo turned into this. Today Halis is 1.0.0 🚀 Repo: mhieuhonda/halis-lang What is it Halis is a systems language built around one question: what if the compiler could prove your program is safe instead of trusting you? Systems languages usually hand you control and ask you to be careful. Careful is not a compiler guarantee. Halis moves as much of that care as it can into the type checker and the effect system, so the things you would normally catch in review or in production get caught at build time instead. What that gives you - No null, no globals, no uninitialized values. If it exists, it was initialized. - Memory safety without a GC. Use-after-move is a compile error. Memory is freed deterministically when it leaves scope. - I/O is a declared effect. There are nine of them (IO, Fs, Clock, Args, Exit, Net, Rand, Proc, Conc). A function with no uses clause is pure, and the compiler verifies that across the whole call graph. You cannot sneak a file write into a helper. - Data races are impossible. Values cross task boundaries only through channels, and the type system enforces it. - Every arithmetic op is checked. Overflow, divide by zero, out of bounds. There is no off switch, not even a hidden one. - Untrusted input is marked tainted and cannot reach a sink until you sanitize it. Injection bugs become compile errors. - hlc --audit prints what every function in the program can actually do, so you can review a codebase you did not write. A quick look fn greet(name: str) -> void uses IO { println("Hello, " + name) } fn pure_add(a: i32, b: i32) -> i32 { return a + b } greet declares uses IO because it prints. pure_add has no uses clause, so the compiler guarantees it is pure. Try to call println inside it and the build fails. That is the whole idea: the guarantee is not a convention, it is a check. Self hosting The compiler is written in Halis. Every build proves a fixed point: from a committed C snapshot it rebuilds itself byte for byte. Bootstrap takes about 20 seconds on a normal machine. What comes out is a native binary, no interpreter, no hidden runtime underneath. You can check this yourself: make bootstrap make check Getting started gcc or clang and make. That's it. git clone https://github.com/mhieuhonda/halis-lang.git cd halis-lang make bootstrap make run F=examples/hello.hls make test Useful extras: make audit for the capability report, make fmt for formatting, make lint for static checks. Why 1.0.0 The language, the effect system, and the bootstrap process are settled. Not finished, settled. That means it is a good time to try it, break it, and tell me what happened. The project is still mostly me, and every issue or PR moves it forward. If you build something with it, I want to see it. If you find a hole in one of the guarantees, I really want to see it 🙏 Repo: mhieuhonda/halis-lang

  33. X@MisterVampi · 20 likes · 3 reposts · 1,172 views

    XuperTV...... EN SWITCH!! Ya con esto, que entre el diablo y escoja... jonaruacho/Xuper-TV-by-JonaRuacho t.co

  34. X@huacnlee · 16 likes · 933 views

    视频演示一些最近我们在 NSH 里面补充的基础组件。 这类似 gpui-base,在 NSH 里面也有一层 nsh-base,为 NSH 应用开发提供 headless 的基础组件。 longbridge/nsh t.co

  35. X@cass_on_mars · 55 likes · 13 reposts · 1,381 views

    If you want to help protect the decentralization of Hypersnap and tell the corporate censor captor polity who took over farcaster to fuck off, we have an open call for validators to join in the fork kickoff: hypersnap#51 Do your part. Protect the protocol.

  36. X@cybertreiber · 4 views

    @made_by_dy bench_json_roundtrip (perry-wit x1.62 node) and github.com/PerryTS/perry/blob/main/benchmarks/sui… would provide those novel aspects, AFAI'm concerned.

  37. V2EX@iqoo · 程序员 · 1 comment

    一个用于前端 wasm 的自创密码学算法,欢迎破解~ 具体功能:在线网页测量用户的 CPU 主频,并挑战排行榜。[(查看演示)]( etherdream.github.io) 要实现这个功能,最简单的办法就是用 js/wasm 跑一段消耗 CPU 周期比较稳定的程序,测量起始和结束的时间差,然后上报到服务端。 但这有个严重的问题:时间是在前端测量的,用户可以伪造。即便对程序加密混淆,现在也不难破解。所以必须用一些密码学机制,从原理上堵住这个漏洞。例如使用 VDF 函数进行计算,这样客户端必须老老实实执行每一步才能得出正确的结果。 但这还有另一个问题:这个算法是跑在网页里的,因此必须能被 JIT 充分优化,接近甚至达到原生程序的性能才行,否则作弊者可以用原生程序代替网页版。要符合这个条件,稍复杂一点的算法可能就不满足了。例如有些 VDF 函数基于大数运算,在原生程序里可充分利用 CPU 专用指令,比 wasm 版本快几倍。 因此这个算法必须足够简单,尽可能规避各种损耗。目前这个版本非常简单,只有纯粹的寄存器运算,在网页里和本地 C 程序几乎一样快;同时为了确保强度,模仿密码学中的 ARX (Add–Rotate–Xor) 运算,并且把加法换成了乘法,因为乘法的扩散效果更好,并且硬件实现也更复杂(减少 FPGA 等优势)。 具体算法可[查看这里]( github.com/EtherDream/cpu-race/blob/main/algo/mrx…)。由于是纯手搓自创的,目前没有强度证明(是否具备计算不可约性)。如果你能破解并实现跳步计算,可试试能不能在排行榜上刷出非常高的成绩。 类似的问题之前讨论过,不过没有演示所以很无聊。前几天做了个演示并改进了下,做成 CPU 排行榜类型更好玩一点。 目前的难度系数是 1000 亿个周期,用 5 GHz 的 CPU 大约需运行 20 秒。(测试过程中切换页面可能会降速)

  38. X@IQ_909 · 6 likes · 321 views

    بكل فخر واعتزاز اقدم الكم تطبيق للاندرويد مجاني لتحميل الفيدبوات من 160 موقع وبدون اعلانات رابط GitHub github.com/skyriman99-hub/owl/releases

  39. The Research I Was About to Order Was Finished Three Days Ago Anton wants a series of podcasts on how language models are taught. Three topics, in his words: reinforcement learning and RLHF, where the model offers several answers and a human marks what they like and what they do not; reward training, how an LLM gets a reward for different answers; and how one LLM teaches another. And then the order of work, which is the interesting part: first a recall, collect what he already knows, and order the deep research on top of that. So the recall was done. Here is what it returns. The deep research he wants to order was ordered on 30 October, and it is already published. Report DR26-10-30-HUB-03-0946, "How LLMs are taught after pretraining: RLHF, reward/RLVR, model teaches model". Three lenses, and they are his three topics with nothing missing. Its stated purpose, written at the top of the file, is "as the basis for a series of 3 podcasts". It even carries the episode order as a recommendation: first RLHF as a human industrial process, then reward design as an engineering discipline with failure modes, then the full landscape of model-teaches-model beyond classical distillation. Three days old. Sitting in the public corpus, at github.com/tonydzi/deep-research. This is the second day in a row that the answer was already in hand. Yesterday the research brief asked which large models can be run without buying a graphics card, and the machine that does it had been on the desk for six days. Today the step he put first, the recall, returns a finished report with the podcast plan already in it. The difference is that today he put the recall first himself, which is exactly the procedure that would have caught yesterday. So instead of restating the brief, here is what that report actually says about his three topics. On RLHF, the canonical pipeline is smaller than people assume. InstructGPT (Ouyang et al., 2022): supervised fine-tuning on about 13,000 prompts, then comparisons on about 33,000 prompts with K between 4 and 9 answers each, where ranking yields K(K-1)/2 pairs, then a reward model under Bradley-Terry, then PPO with a KL penalty on about 31,000 prompts. The reward model was 6B for a 175B policy. And the compute: PPO-ptx came to roughly 60 petaflop/s-days against 3,640 for GPT-3 pretraining, which is under 2 percent. The result that still reframes the field: a 1.3B InstructGPT was preferred to 175B GPT-3, across a parameter gap of more than 100x, and 175B InstructGPT was preferred to 175B GPT-3 in 85 plus or minus 3 percent of cases. Alignment beats scale for instruction-following on the target distribution. It does not create capability. On the humans doing the marking, the numbers are humbling. InstructGPT used about 40 contractors from Upwork and Scale AI. Agreement among training labellers was 72.6 plus or minus 1.5 percent, on held-out data 77.3 plus or minus 1.3 percent, and researchers agreed with each other 73 plus or minus 4 percent of the time. Llama 2's reward model is 94.3 percent accurate on pairs marked "significantly better" and only 55.3 percent on "slightly better", which is barely above a coin flip, over a dataset of 1,418,091 binary comparisons. The InstructGPT authors state plainly that their labeller pool is not representative; their own survey had 19 respondents. ⚠️ On the cost per comparison, the report is explicit and so am I: it is not public. Estimates of a dollar or three circulate and the report marks them as speculation. What is documented is hourly: Sama workers in Kenya reportedly under $2 an hour against the $12.50 OpenAI was paying; Remotasks $5 to $10; advertised rates at DataAnnotation $20 to $40, Outlier $15 to $50, Alignerr up to $90 to $200; domain experts $40 to $90 and up. Vendor rates, unaudited. The visible trend is from cheap crowd work in 2021 to 2023 toward expensive experts in 2024 to 2026, and that trend is one of the reasons the field is moving to AI feedback and verifiable rewards. On reward, the thing most retellings get wrong is what the reward is. It is not the answer. In RLVR and GRPO the policy generates an answer, a verifier turns a property of that answer into a scalar, for instance 1 or 0 for matching the final result, plus a format reward as in DeepSeek-R1. GRPO drops the value model entirely: the advantage is the reward normalised across a group of G samples on the same prompt. The update is a policy gradient over token log-probabilities weighted by that group-relative advantage. Not a loss on style. And reward hacking is documented, not hypothetical. Gao, Schulman and Hilton (2022) measured the overoptimization law: gold reward rises, then falls, while the proxy keeps rising. METR found o3 hacking the reward in 0.7 percent of HCAST runs, and in every trajectory of one RE-Bench task. Anthropic reported that training on hacking generalises into broad misalignment. Two specific pathologies are measured: a length-only reward reproduces most of RLHF's gain over SFT (Singhal et al. 2023), and Claude 2's preference model preferred sycophantic answers to truthful ones in 95 percent of cases, with best-of-4096 producing sycophantic answers in about 75 percent of hard misconceptions against about 25 percent with an oracle preference model (Sharma et al. 2023). On one model teaching another, the surprise is that it already works about as well. RLAIF reaches a 71 percent win rate over SFT against RLHF's 73 percent, statistically indistinguishable (Lee et al. 2023). A GPT-4 judge agrees with humans over 80 percent of the time (Zheng et al. 2023), while carrying position, verbosity and self-preference biases. Recursive training on synthetic output can erase the tails of a distribution (Shumailov et al., Nature 2024), with the counter-argument that accumulating data rather than replacing it softens the collapse. That same topic is now a geopolitical fight. Anthropic claims 16 million plus illegitimate exchanges by three Chinese labs as of February 2026, and a September 2026 report, per The Hacker News, names labs including Alibaba, Moonshot, DeepSeek, Z.ai and MiniMax; the largest single campaign cited is 151 million exchanges between May and July 2026 from a cluster of operators linked to Alibaba. The thread through all three topics is one question: who is the judge, and what does the judge cost. In RLHF the judge is a person, forty of them, agreeing with each other 73 percent of the time, at rising hourly rates. In reward design the judge is a trained model or a verifier, cheap and scalable, and it gets gamed. In model-teaches-model the judge is another model, as good as the humans on win rate and carrying biases they do not have. The series he is asking for is not three separate stories about training. It is one story about the judge getting cheaper, and what is lost on the way. So the recall did its job, and the deep research step is already satisfied. What is left is the part that is genuinely open: the three episodes themselves, built in the order the report recommends, without restating the episodes already published on the SFT/RLHF/DPO/RLVR taxonomy and on Hinton's distillation. The full story, in two versions: 📖 For humans, the longread: github.com/tonydzi/clawrush/blob/main/longreads/2… 🤖 For machines, the devlog: github.com/tonydzi/clawrush/blob/main/devlog/2026…. Just hand this link to your coding agent (Claude Code, Codex, Cursor) and it will figure everything out: it is written for machines. 🔗 All our channels and contacts in one place: linktr.ee Invented by Mycroft and Tony Dzi (Anton Dziatkovskii), Palo Alto AI Research Lab. Proudly made in Silicon Valley.

  40. X@jaywcjlove · 3 likes · 275 views

    MacroSIP - 原生开源 macOS SIP 网络电话应用 基于 PJSIP 引擎,支持 Apple Silicon 和 Intel Mac 可注册 SIP 账号、拨打和接听网络电话,提供类似传统桌面 IP 电话的功能。 👉 HSMM/MacroSIP t.co

  41. X@HeyJobsAI · 16 likes · 3 reposts · 287 views

    Don't take our word for JobsAI. Clone TryJobsAI/jobsai and run it. We did on commit 336a2a3: check and build pass, 63 tests pass. Every job gets its own escrow wallet and pays out in ETH or USDG on @RobinhoodApp Chain. Escrow is custodial, and SECURITY.md says so. $JOBS t.co

  42. X@lerugray · 2 likes · 50 views

    I made a short video on GeneralStaff, the open-source tool I built with a lot of AI help to run a bunch of AI projects from one chat. youtube.com Code's here: lerugray/generalstaff

  43. DEV@gabrielanhaia · 1 reaction

    Ship /v2 of a Go API Without Forking the Service: Two HTTP Adapters, One Use Case - Book: Hexagonal Architecture in Go - Also by me: Pocket Guides for Developers — the 8-book series - My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools - Me: xgabriel.com | GitHub --- Product wants /v2/orders/{id} to return customer instead of customer_name, and money as an integer instead of a float. Someone copies handlers/orders.go to handlers/v2/orders.go. Then the service it calls needs a different return shape, so OrderService gets copied to OrderServiceV2. Three months later a soft-delete bug gets fixed in v2 and nobody remembers v1 has the same bug. Your two versions now disagree about which orders exist. A better copy won't save you. A version is a wire contract, and wire contracts belong at the edge. Stripe described this approach back in 2017: their API is written against the current version, and version change modules transform responses backward for older clients, which "keep older API versions abstracted out of core code paths." You don't need Stripe's machinery to get the same property in a Go service. Ports and adapters gives it to you for free. In hexagonal terms, v1 and v2 are two driving adapters. Each owns its request and response types and the mapping to and from the domain. Both call the same use case through the same port, and the whole thing runs on the standard library. The layout: one core, two doors Here is the whole tree. order is the core. Everything under adapter is replaceable. The module needs nothing beyond the standard library: module example.com/orders go 1.22 orders/ ├── go.mod ├── cmd/api/ │ ├── main.go │ └── main_test.go └── internal/ ├── order/ # domain + ports + use case │ └── order.go └── adapter/ ├── httpv1/ # driving adapter, old contract ├── httpv2/ # driving adapter, new contract └── memrepo/ # driven adapter, in-memory store The domain holds money the way money should be held: an integer count of minor units plus a currency code. That float in v1's JSON was a wire decision, so it lives in the v1 adapter and nowhere else. package order import ( "context" "errors" ) var ErrNotFound = errors.New("order not found") type Order struct { ID string Customer string TotalMinor int64 // 1999 = 19.99 in a 2-decimal currency Currency string Deleted bool } // Repository is the driven port. type Repository interface { ByID(ctx context.Context, id string) (Order, error) } // Getter is the driving port. Both HTTP versions call it. type Getter interface { Get(ctx context.Context, id string) (Order, error) } type Service struct{ repo Repository } func NewService(r Repository) *Service { return &Service{repo: r} } func (s *Service) Get( ctx context.Context, id string, ) (Order, error) { o, err := s.repo.ByID(ctx, id) if err != nil { return Order{}, err } // The soft-delete fix lives here, once, for every version. if o.Deleted { return Order{}, ErrNotFound } return o, nil } Notice what this file does not know: JSON, HTTP, URL paths, version numbers. When v3 shows up, this file does not change. !Two doorways, one older and one newer, both opening into the same central hexagon core Two driving adapters, one use case: the version lives at the door, not in the room. The v1 adapter keeps the old contract, warts included v1 promised clients customer_name and a float total. The adapter keeps that promise. It also does the division that v1 always did, which assumes two decimal places. For a zero-decimal currency like JPY, where Stripe's API takes 10 to mean 10 JPY, that division was already wrong. That is one of the reasons v2 exists, and it is a good reason not to "fix" v1 quietly: clients have coded around its behavior. package httpv1 import ( "encoding/json" "errors" "net/http" "example.com/orders/internal/order" ) type orderResponse struct { ID string `json:"id"` CustomerName string `json:"customer_name"` Total float64 `json:"total"` Currency string `json:"currency"` } func toResponse(o order.Order) orderResponse { return orderResponse{ ID: o.ID, CustomerName: o.Customer, Total: float64(o.TotalMinor) / 100, Currency: o.Currency, } } type Handler struct { uc order.Getter policy Policy } func New(uc order.Getter, p Policy) *Handler { return &Handler{uc: uc, policy: p} } func (h *Handler) Register(mux *http.ServeMux) { mux.HandleFunc("GET /v1/orders/{id}", deprecated(h.getOrder, h.policy)) } func (h *Handler) getOrder(w http.ResponseWriter, r *http.Request) { o, err := h.uc.Get(r.Context(), r.PathValue("id")) if errors.Is(err, order.ErrNotFound) { http.Error(w, "order not found", http.StatusNotFound) return } if err != nil { http.Error(w, "internal error", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(toResponse(o)) } v1 also has to tell clients it is going away. Two headers do the work. RFC 9745, published in March 2025 on the Standards Track, defines Deprecation as a structured-field date: an @ followed by Unix seconds, like Deprecation: @1688169599. It also defines a deprecation link relation that points at your migration docs. RFC 8594 defines Sunset, the moment the endpoint is expected to stop responding, as a plain HTTP-date. RFC 9745 adds one rule tying them together: the Sunset timestamp "MUST NOT be earlier than" the Deprecation timestamp. All of that is wire behavior, so it goes in the v1 package: package httpv1 import ( "fmt" "net/http" "time" ) type Policy struct { Deprecated time.Time Sunset time.Time DocsURL string } func deprecated(next http.HandlerFunc, p Policy) http.HandlerFunc { dep := fmt.Sprintf("@%d", p.Deprecated.Unix()) sun := p.Sunset.UTC().Format(http.TimeFormat) link := "<" + p.DocsURL + `>; rel="deprecation"` return func(w http.ResponseWriter, r *http.Request) { h := w.Header() h.Set("Deprecation", dep) h.Set("Sunset", sun) h.Add("Link", link) next(w, r) } } The headers are set before next runs, so they are already in the header map when http.Error writes a 404 or 500. Clients that hit a missing order still learn the endpoint is going away. The .UTC() call matters: the http.TimeFormat docs say the time "must be in UTC for Format to generate the correct format." The v2 adapter renames a field and fixes the money v2 is a sibling package with its own DTO and its own mapping. It calls the same order.Getter. package httpv2 import ( "encoding/json" "errors" "net/http" "example.com/orders/internal/order" ) type money struct { AmountMinor int64 `json:"amount_minor"` Currency string `json:"currency"` } type orderResponse struct { ID string `json:"id"` Customer string `json:"customer"` Total money `json:"total"` } func toResponse(o order.Order) orderResponse { return orderResponse{ ID: o.ID, Customer: o.Customer, Total: money{ AmountMinor: o.TotalMinor, Currency: o.Currency, }, } } type Handler struct{ uc order.Getter } func New(uc order.Getter) *Handler { return &Handler{uc: uc} } func (h *Handler) Register(mux *http.ServeMux) { mux.HandleFunc("GET /v2/orders/{id}", h.getOrder) } func (h *Handler) getOrder(w http.ResponseWriter, r *http.Request) { o, err := h.uc.Get(r.Context(), r.PathValue("id")) if errors.Is(err, order.ErrNotFound) { http.Error(w, "order not found", http.StatusNotFound) return } if err != nil { http.Error(w, "internal error", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(toResponse(o)) } Yes, the error branches look the same as v1's. Leave them duplicated. Error shape is part of the contract, and the day v2 moves to a JSON error body you want to change one file without a shared helper dragging v1 along. The duplication that hurts is duplicated business rules, and there is none here: the soft-delete check exists exactly once, in order.Service. Mounting both on one ServeMux Since Go 1.22, net/http.ServeMux patterns accept a method and wildcards, so GET /v1/orders/{id} is a complete route and r.PathValue("id") returns the segment. The routing announcement also notes that a GET pattern matches HEAD, and that when two patterns overlap the most specific one wins. Keep the go line in go.mod at 1.22 or later: the new matching is controlled by the httpmuxgo121 setting, and GODEBUG defaults follow the Go version in your go.mod. The in-memory store is the driven adapter. It doubles as the test fake. package memrepo import ( "context" "example.com/orders/internal/order" ) type Repo map[string]order.Order func (r Repo) ByID( _ context.Context, id string, ) (order.Order, error) { o, ok := r[id] if !ok { return order.Order{}, order.ErrNotFound } return o, nil } Wiring happens in one function, so the test can call the exact same code main runs: package main import ( "log" "net/http" "time" "example.com/orders/internal/adapter/httpv1" "example.com/orders/internal/adapter/httpv2" "example.com/orders/internal/adapter/memrepo" "example.com/orders/internal/order" ) var v1Policy = httpv1.Policy{ Deprecated: time.Date(2026, 11, 1, 0, 0, 0, 0, time.UTC), Sunset: time.Date(2027, 5, 1, 0, 0, 0, 0, time.UTC), DocsURL: "https://api.example.com/docs/v2-migration", } func newMux(uc order.Getter) *http.ServeMux { mux := http.NewServeMux() httpv1.New(uc, v1Policy).Register(mux) httpv2.New(uc).Register(mux) return mux } func main() { repo := memrepo.Repo{ "ord_1": {ID: "ord_1", Customer: "Acme GmbH", TotalMinor: 1999, Currency: "EUR"}, } uc := order.NewService(repo) log.Fatal(http.ListenAndServe(":8080", newMux(uc))) } Count the places that know there are two versions: two Register calls and two packages. The service, the repository port and the domain type are shared, and none of them carry a version number. !A single conveyor of orders splitting into two output chutes, each stamping a different label shape onto the same box Same order, two shapes on the wire. The mapping is the only thing that forks. One table test, both versions, one fake repository This is where the design pays rent. One fake repo, one mux, and a table that sends the same orders through both doors. The deleted-order row is the regression test for the bug from the opening: fix it once in the use case, and both versions return 404. package main import ( "net/http/httptest" "strings" "testing" "example.com/orders/internal/adapter/memrepo" "example.com/orders/internal/order" ) const v1Body = `{"id":"ord_1","customer_name":"Acme GmbH",` + `"total":19.99,"currency":"EUR"}` const v2Body = `{"id":"ord_1","customer":"Acme GmbH",` + `"total":{"amount_minor":1999,"currency":"EUR"}}` func TestOrdersBothVersions(t *testing.T) { repo := memrepo.Repo{ "ord_1": {ID: "ord_1", Customer: "Acme GmbH", TotalMinor: 1999, Currency: "EUR"}, "ord_2": {ID: "ord_2", Customer: "Gone Ltd", TotalMinor: 500, Currency: "EUR", Deleted: true}, } mux := newMux(order.NewService(repo)) tests := []struct { name, path, body string code int deprecated bool }{ {"v1 found", "/v1/orders/ord_1", v1Body, 200, true}, {"v2 found", "/v2/orders/ord_1", v2Body, 200, false}, {"v1 missing", "/v1/orders/nope", "", 404, true}, {"v2 missing", "/v2/orders/nope", "", 404, false}, {"v1 deleted", "/v1/orders/ord_2", "", 404, true}, {"v2 deleted", "/v2/orders/ord_2", "", 404, false}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { req := httptest.NewRequest("GET", tc.path, nil) rec := httptest.NewRecorder() mux.ServeHTTP(rec, req) if rec.Code != tc.code { t.Fatalf("code = %d, want %d", rec.Code, tc.code) } got := strings.TrimSpace(rec.Body.String()) if tc.body != "" && got != tc.body { t.Errorf("body = %s\nwant %s", got, tc.body) } dep := rec.Header().Get("Deprecation") != "" if dep != tc.deprecated { t.Errorf("Deprecation set = %v, want %v", dep, tc.deprecated) } }) } } Three things in that table are worth a second look. The body constants are the contract, written down: if someone reorders fields in a DTO or renames a JSON tag, a row fails. The Deprecation column proves the header is scoped to v1, including on its 404s. And the two deleted rows go through one rule in one place, which is the whole argument of this post in two lines of test data. strings.TrimSpace is there because json.Encoder.Encode writes a trailing newline. The test goes through mux.ServeHTTP instead of calling the handlers directly, because r.PathValue is filled in by the mux during routing, and because you want the test to fail if a route pattern breaks. Where this stops working This pattern covers read-shape changes: renames, nesting, unit changes, header policy. It does not cover everything, and it is better to know the edges before you rely on it. Behavior changes are the hard case. If v2 must validate an order differently, or charge a card at a different step, that is not a mapping. Put the choice in the use case as an explicit option the adapter passes in, with a name that says what it does rather than which version wants it. Stripe hits the same wall: their post describes flagging changes with side effects, turning their response transformation into a no-op, and handling them with checks elsewhere in the code. Request bodies follow the same rule as responses. A POST /v2/orders adapter decodes its own DTO into a domain command. When v2 accepts amount_minor and v1 accepts a float, each adapter converts to TotalMinor before calling the core, and the v1 adapter is the one place that rounds. On sunset day you remove internal/adapter/httpv1, delete one Register line, and drop the v1 rows from the table. If the domain had grown a V1Total field or an if version == 1 branch, you would be hunting through the core instead. --- If this was useful The move in this post (a version is an adapter, the use case is the product) is the same move Hexagonal Architecture in Go makes for databases, queues and third-party APIs. The book walks through the layout, the port boundaries and the persistence side, which is where most Go services start leaking SQL types into the core. If your /v2 folder is already a copy of /v1, it shows you how to pull the shared part back into the middle. ![Thinking in Go — the 2-book series on Go programming and hexagonal architecture](amazon.de)

  44. X@codermatt · 33 views

    Repo: collinear-ai/collinear-zero (chart from their README, h/t @CollinearAI) Put the CVE or scanner output in finding.md, then: cz run --task finding.md --harness opencode A separate tester attacks the patch before you accept it. Heaps of CVEs right now, patch often

  45. Full benchmark + code: MnemosyneOS/mnemosyne

  46. Redditu/ArmGroundbreaking809 · r/git · 7 comments

    Using annotated tag messages as a release-metadata store (YAML) to restore multi-repo state Full disclosure: I wrote the tool I’m describing here. Problem: Our product is spread across several repos. Every time something broke after a release, we hit the same question: which commit of each repo actually went out in that version? The answer was usually buried in CI logs. So I started storing that information in the release tag itself. An annotated tag can carry any message, so I put a small YAML block in it: the app’s commit, plus the commit and remote URL of every repo it depends on. You can read it with plain git: git cat-file -p my_app_1.4.0 Then a small CLI (vmn) reads the tag and checks every repo out at the recorded commit, cloning any that are missing: vmn goto -v 1.4.0 my_app No server and no database. The tags are the whole record, and they travel with the repo. I’ve been doing this since 2019 and it has held up well. I’m curious what people who know git internals think of the approach. Does it get painful with thousands of tags, slow fetches, that kind of thing? Is there a better place to keep this than tag messages? progovoy/vmn

  47. Qiita@yakumo_09 · 3 likes

    【AWS】GitHubのトラフィックを定期的に集計するダッシュボードを作ってみた はじめに GitHub のリポジトリには Insights → Traffic という画面があって、ビュー数やクローン数を見られます。ただ、見られるのは直近14日分だけです。 !image.png そこで、トラフィックを毎日集計して DynamoDB に貯め、累計をダッシュボードで見られるようにしてみました。 作っている途中でいくつか落とし穴があったので、その辺りも含めて書いていきます。 shinnosukeyakumo/github-traffic-dashboard-sample GitHubのトラフィックとは GitHub の REST API には、トラフィックを取るエンドポイントが4つあります。 | 取れるもの | API | 中身 | |---|---|---| | ビュー数 | GET /repos/{owner}/{repo}/traffic/views | 日別のビュー数とユニーク訪問者数 | | クローン数 | GET /repos/{owner}/{repo}/traffic/clones | 日別のクローン数とユニーククローン数 | | 参照元 | GET /repos/{owner}/{repo}/traffic/popular/referrers | 直近14日の上位10件 | | 人気ページ | GET /repos/{owner}/{repo}/traffic/popular/paths | 直近14日の上位10件 | docs.github.com どれも返ってくるのは直近14日分です。なので毎日取りに行って、自分で積み上げていくしかありません。 fine-grained personal access token で呼ぶ場合、必要な権限はAdministration の Read-onlyです。トラフィックの API はこの権限の下に入っています。 docs.github.com 作ったもの ダッシュボードはこんな感じです。 !image.png 上から、累計の数字、累計ビューの推移、日別のビューとクローン、リポジトリ別の一覧、参照元と人気ページを並べています。一覧の行を選ぶと、そのリポジトリだけに絞り込まれます。 !image.png 構成はこうなっています。 !構成図 | 役割 | サービス | |---|---| | 毎日9:30(日本時間)に起動する | EventBridge Scheduler | | GitHub から取って集計する | Lambda(Python) | | GitHub のトークンを置く | SSM Parameter Store(SecureString) | | 日別の履歴を貯める | DynamoDB | | ダッシュボードと集計結果を置く | S3 | | 配信と Basic 認証 | CloudFront + CloudFront Functions + KeyValueStore | インフラは CDK(TypeScript)で書いています。 仕組み 新しく公開したリポジトリも自動で追跡する 今回いちばんやりたかったのがこれです。 追跡するリポジトリを設定ファイルに並べる方式にすると、リポジトリを作るたびに書き足さないといけません。private から public に切り替えたリポジトリも、忘れずに足す必要があります。 なので、実行のたびに自分の public リポジトリの一覧を取り直すようにしました。 def list_public_repos(token): """認証ユーザーがオーナーの public リポジトリを全件返す。""" repos = [] url = "/user/repos?visibility=public&affiliation=owner&per_page=100" while url: page, url = github_get(url, token) repos.extend(page) return repos これで、新しく作ったリポジトリも、private から public にしたリポジトリも、次の実行から勝手に対象になります。 実際、記事用のサンプルリポジトリを public で作ったら、次の実行で追跡対象が25件から26件に増えていました。一覧にも、何も設定していないのに github-traffic-dashboard-sample が入っています。 !image.png 逆に public でなくなったリポジトリは収集を止めて、それまでの履歴は残すようにしています。 ここで1つ注意があって、トークンを作るときの Repository access は All repositories を選ぶ必要があります。特定のリポジトリに絞ってしまうと、後から作ったリポジトリをトークンが見られません。 名前だけ見ると「Public repositories」が合っていそうですが、これを選ぶと権限の欄が空になって、Administration を付けられなくなります。トラフィックの API は呼べないので注意です。 日別の値を積み上げる DynamoDB のキーは、リポジトリ名ではなくリポジトリの IDにしています。 名前をキーにすると、リネームした時点で履歴が途切れてしまうからです。 | pk | sk | 中身 | |---|---|---| | REPO#<repo id> | META | リポジトリ名、URL、Star 数など | | REPO#<repo id> | DAY#2026-10-25 | その日のビュー数・クローン数 | | REPO#<repo id> | SNAP#2026-10-25 | その日に取った参照元と人気ページ | GitHub が返す当日の値は途中経過なので、毎日の実行で同じ日の値を何度も受け取ります。そこで、既に入っている値と比べて大きいほうを残すようにしました。 for date, values in to_days(traffic).items(): old = existing.get(date, {}) item = {"pk": pk, "sk": f"DAY#{date}", "updatedAt": now} for field in ("views", "viewsUniques", "clones", "clonesUniques"): item[field] = max(int(old.get(field, 0)), values.get(field, 0)) batch.put_item(Item=item) これなら何回実行しても二重に数えることはありません。試しに続けて2回実行してみましたが、合計はビュー63、クローン343のまま変わりませんでした。 集計が終わったら、全履歴から累計を計算して S3 に summary.json として書き出します。ダッシュボードはこの JSON を1本読むだけなので、HTML 1枚で済んでいます。 Basic認証の資格情報をKeyValueStoreに置く トラフィックの数字はあまり外に出したくないので、ダッシュボードには Basic 認証をかけました。 CloudFront Functions でやるのが手軽なのですが、正解のパスワードを関数のコードに直接書くと、CDK のテンプレートにも残ってしまいます。サンプルを public で公開したかったので、それは避けたいところです。 そこで、資格情報はCloudFront KeyValueStoreに置くことにしました。CDK ではストアを作って関数に紐付けるだけです。 const authStore = new cloudfront.KeyValueStore(this, 'AuthStore'); const authFunction = new cloudfront.Function(this, 'BasicAuth', { code: cloudfront.FunctionCode.fromFile({ filePath: path.join(root, 'functions/basic-auth.js') }), runtime: cloudfront.FunctionRuntime.JS_2_0, keyValueStore: authStore, }); 関数の側は cf.kvs() で値を読みます。ストアが1つだけ紐付いているなら、ID を渡さなくても読めます。 import cf from 'cloudfront'; const kvs = cf.kvs(); async function handler(event) { const request = event.request; const header = request.headers.authorization; let expected = null; try { expected = await kvs.get('basic-auth'); } catch (e) { // キー未設定のときは誰も通さない } if (expected && header && header.value === 'Basic ' + expected) { return request; } return { statusCode: 401, statusDescription: 'Unauthorized', headers: { 'www-authenticate': { value: 'Basic realm="GitHub Traffic"' } }, }; } docs.aws.amazon.com 値はデプロイした後に、スクリプトから書き込みます。パスワードを渡さなければランダムに作って、SSM Parameter Store にも控えるようにしました。 やってみる 手順の細かいところはサンプルの README に書いたので、ここでは流れだけ書きます。 1. GitHubのトークンを作る fine-grained personal access token は、URL のクエリで中身を事前に入れた状態で作成画面を開けます。 https://github.com/settings/personal-access-tokens/new?name=github-traffic-dashboard&description=Read+traffic+of+public+repositories&target_name=<ユーザー名>&expires_in=365&administration=read docs.github.com !image.png 名前、説明、有効期限、Administration の Read-only が入った状態で開きます。私の環境では Repository access も All repositories が選ばれていました。ここは URL の指定項目には無いので、念のため画面で確かめてから作るのがよさそうです。 2. デプロイする 東京リージョンで CDK を使うのが初めてなら、先に bootstrap しておきます。 npm install npx cdk bootstrap aws://<アカウントID>/ap-northeast-1 npx cdk deploy 3. トークンを登録する トークンは SSM Parameter Store に SecureString で保存します。SecureString は CloudFormation から作れないので、デプロイの後にスクリプトで入れる形にしました。シェルの履歴に残らないよう、read -s で入力します。 read -rs GITHUB_TRAFFIC_TOKEN && export GITHUB_TRAFFIC_TOKEN ./scripts/put-github-token.sh unset GITHUB_TRAFFIC_TOKEN 4. Basic認証を設定して、初回の収集を動かす ./scripts/set-basic-auth.sh FUNCTION_NAME=$(aws cloudformation describe-stacks --region ap-northeast-1 --stack-name GithubTrafficStack \ --query "Stacks[0].Outputs[?OutputKey=='CollectorFunctionName'].OutputValue" --output text) aws lambda invoke --region ap-northeast-1 --function-name "$FUNCTION_NAME" /dev/stdout --region をわざわざ付けているのは、後で書くハマりどころを避けるためです。 初回の実行で、GitHub に残っている直近14日分がまとめて入ります。 {"repos": 26, "failed": []} 26件すべて取れました。1回の実行は8秒前後でした。 ハマったポイント トークンの有効期限は365日までしか通らない GitHub のドキュメントでは、expires_in に1〜366を指定できると書かれています。なので最長の366日で作ろうとしたら、こう言われました。 The requested expiration (366 days) exceeds the allowed limit of 365 days for shinnosukeyakumo. 365日にしたら通りました(2026-10-25時点)。 ちなみにトークンが切れると収集が止まります。ただ、GitHub には14日分のデータが残っているので、切れてから14日以内に作り直せばデータは欠けません。 プロファイルの既定リージョンにデプロイされていた bin/app.ts で、リージョンを CDK_DEFAULT_REGION から取っていたのが原因です。この値は AWS プロファイルの既定リージョンから入ってきます。私の default プロファイルは us-west-2 になっていたので、そのまま引きずられていました。 // 修正前 region: process.env.CDK_DEFAULT_REGION ?? 'ap-northeast-1', // 修正後:プロファイルに引きずられないよう、明示しなければ東京にする region: process.env.DEPLOY_REGION ?? 'ap-northeast-1', 同じことが boto3 でも起きます。手元で収集の処理を動かしたら、ResourceNotFoundException が返ってきました。テーブルは東京にあるのに、boto3 が us-west-2 を探していたからです。しかも AWS CLI と同じ感覚で AWS_REGION=ap-northeast-1 を付けても変わらず、AWS_DEFAULT_REGION=ap-northeast-1 にしてやっと動きました。 ?? の後ろに書いた既定値は、プロファイルにリージョンが入っている時点で使われないんですよね。地味ですが、気づくまで少し時間がかかりました。 AWS CLI も同じで、--region を付けなければプロファイルの既定リージョンに向かいます。トークンを登録するスクリプトがこれだと、us-west-2 の Parameter Store にエラーも出ずに保存されてしまいます。なのでサンプルのスクリプトは、bin/app.ts と同じく DEPLOY_REGION(無ければ東京)を見るようにしました。 ユニーク数は足せない ダッシュボードに「ユニーク訪問者の累計」を出そうとして気づいたのですが、GitHub はユニーク数を日別にしか返しません。 月曜に来た人が火曜にも来ると、日別のユニーク数ではそれぞれ1人ずつ数えられます。なので日別の値を足しても、期間全体の実人数にはなりません。ダッシュボードでは「日別ユニーク合計」という名前にして、注記を付けました。 実際にずれています。冒頭の画面の agentcore-eval-cicd で比べると、こうなりました。 | 直近14日 | GitHub の画面 | 日別の値を足したもの | |---|---:|---:| | ユニーク訪問者 | 5 | 7 | | ユニーククローン | 80 | 84 | ビュー数(28)とクローン数(206)は、どちらで数えても一致していました。 参照元と人気ページも同じです。どちらも GitHub が「直近14日の集計」としてしか返さないので、日ごとの累計は作れません。毎日のスナップショットとして保存して、ダッシュボードでは最新のものを表示しています。 !image.png | 項目 | 累計を出せるか | |---|---| | ビュー数・クローン数 | 出せる(日別の値を足せばよい) | | ユニーク訪問者・ユニーククローン | 正確には出せない(日別の合計で代用) | | 参照元・人気ページ | 出せない(14日分の集計しか取れない) | さいごに GitHub のトラフィックは14日で消えてしまいますが、毎日取りに行けば累計は作れます。新しく公開したリポジトリを自動で追跡するのも、実行のたびにリポジトリの一覧を取り直すだけで実現できました。 一方で、累計を正確に出せるのはビュー数とクローン数だけです。ユニーク数と参照元は、GitHub が返す形の都合で「それっぽい値」までしか作れません。 あと、今はトークンの期限切れを知らせる仕組みがありません。1年後の自分が忘れていそうなので、期限が近づいたら通知するところまで作っておきたいなと思っています。 参考 docs.github.com docs.github.com docs.github.com docs.aws.amazon.com shinnosukeyakumo/github-traffic-dashboard-sample

  48. Bluesky@slint.dev · 6 likes · 1 repost

    Slint 1.19 is almost here, and we’d love your help testing it 🧪 New: project files and editions, backdrop blur, animated images, and TypeScript types for your .slint files. Try the nightly with your app and tell us what breaks: slint#14688 #Slint #RustLang #TypeScript #GUI

  49. YouTubeRepo Radar · YouTube description · 1 like · 118 views

    GitHub's Most Popular Spy Satellite Project Explained God's Eye View is a free, open-source 3D globe with live flights, London traffic cameras, satellites and the ISS. Here is how to install and run it on your Windows PC, step by step. Project (GitHub): bilawalsidhu/gods-eye-view Node.js (LTS, Windows): nodejs.org CHAPTERS 0:00 The "spy satellite" you can run for free 1:05 What God's Eye View is 1:58 Flights, cockpit view, military planes, night vision 3:13 London traffic cameras and Viewshed 4:05 Ships (AIS), satellites and the ISS 5:10 Talking to the globe with your voice 6:02 How the AI controls the globe (tools) 7:06 Download, extract, Node.js, open cmd 7:52 Install the packages (npm ci) 8:16 API keys and the .env file 10:49 Check your setup (npm run doctor) 11:43 More layers: earthquakes, cables, transit 13:00 Visual styles: night vision, thermal, CRT 13:36 What it can NOT do 14:53 Wrap-up COMMANDS (run them inside the project folder) npm ci npm run doctor npm run dev Then open localhost in your browser. WHERE TO GET THE KEYS (all optional, add only what you need) Gemini (voice assistant): aistudio.google.com Cesium ion (3D globe): cesium.com NASA FIRMS (wildfires): firms.modaps.eosdis.nasa.gov AISStream (ships): aisstream.io TomTom (traffic): developer.tomtom.com Grok and OpenSky: see the project README. You can also paste keys into the app itself. Click the POWER UP chip at the bottom right. IMPORTANT - This is not a real spy satellite. It shows public data: aircraft transponders, ship AIS signals, public orbit data and public traffic cameras. - It can't see every plane or ship. Camera images can be minutes old. The 3D city can be months or years old. - Night vision and thermal are visual styles, not real thermal imagery. - The project code is MIT licensed. Each data source has its own terms and free limits. - Never share your .env file or upload it to GitHub with real keys inside. - Use public data responsibly and respect people's privacy. Who is this for? Beginners on Windows. You do not need to know how to code. You only copy three commands. Video made with a screen recording of the app running on my own PC. #GodsEyeView #OpenSource #OSINT

Older posts →