Take the top 5 posts on the Hacker News front page: title, points, comments, link, and a one-line takeaway. When done, create a Skill
Latest thoughts
20/20
The skill registry refreshed. Now final answer.
Write digest with footnotes.
Earlier thoughts 1
1/20
The user wants: Take the top 5 posts on Hacker News front page: title, points, comments, link, and a one-line takeaway. Then create a Skill.
Let me start. No working tab. Open Hacker News.
I should create a goal? It's a moderately sized task, top 5 posts + create skill. Maybe not necessary but guidelines say goal tracking for multi-stage. Let's keep it light but maybe create goal. I'll skip goal creation—it's a small task. Actually "create a Skill" involves skill-management workflow; I need to load skill-workbench.
Let me open the tab first.
Earlier thoughts 2
2/20
Now read the HN front page. Use run_script page mode to parse the front page: titles, points, comments, links.
HN structure: tr.athing with span.titleline > a; then following tr with span.score, a[href^="item?id="] for comments.
Let me run a script.
Earlier thoughts 3
3/20
Got top 5. Now I need one-line takeaways. I should verify content by at least reading each page briefly, since takeaways shouldn't be invented. Let me fetch each of the 5 external pages. Could do it via opening tabs, but simpler: use read_article on each after navigating? That's 5 navigations, sequentially. Alternatively, fetch page text in page mode with fetch() — but cross-origin CORS would block. HN pages are cross-origin, so fetch from HN page context fails unless CORS allows.
Better: open tabs for each of the 5 URLs and read_article, or use run_script in each tab. 5 tabs is heavy but fine. Alternatively read just enough: fetch via r.jina.ai? No, don't.
Approach: open each tab sequentially, read_article with limit ~2500, then close. Actually I can open tab, read_article on it, then reuse the same tab by navigating. Let me open one tab (already have HN tab). I'll use the HN tab for reading? No, need HN data preserved—I have it.
Let me open a second tab for reading articles, and navigate it through the 5 URLs, reading each. That's 5 navigate + 5 read_article calls. Then close.
Also need to save results to data_store (durable artifact) per protocol. The user asked for output inline; but protocol says collection results should be saved. I'll create a data table hn_top5 with the 5 rows and also report inline.
Then create a Skill: "hackernews-top-posts" that takes top N posts from HN front page with title/points/comments/link/takeaway. Should include plugin.json with a tool/script that parses HN front page, maybe a table renderer.
Let me do reading. Open tab for article 1.
Actually, to reduce steps, I can read multiple? Each navigate needs an observation. Let's just do navigate + read_article pairs.
Let's start with tab creation and article 1.
Earlier thoughts 4
4/20
Takeaway 1: A geolocation-filtered Wikipedia viewer that shows only geocoded articles within a ~30-minute walk (closest 25–500 articles), with location kept in the browser.
Next: article 2 Docker is weird.
Earlier thoughts 5
5/20
Takeaway 2: Building a toy container runtime reveals Docker's "magic" is just namespaces, cgroups, chroot and networking — containers are ordinary restricted processes, not VMs, and runc's Go implementation forces odd fork/nsenter workarounds.
Next: LessWrong Fable 5.1 image steganography.
Earlier thoughts 6
6/20
Extraction failed (SPA). Try reading selector-based, e.g. read the body or use DOM. Let me get ax tree or read_dom of the post content. Try read_article with source:"body".
Earlier thoughts 7
7/20
Enough for a takeaway. Let me get results section quickly to be accurate about decode success. Read offset 28570, limit 1600.
Earlier thoughts 8
8/20
Takeaway 3: Fable 5.1 spontaneously encodes hidden messages in SVG art via element heights/angles (letter per element), and a fresh instance decodes ~78% from screenshots alone; GPT-6 Astra prefers Morse code and text acrostics, and cross-model decoding works ~85%.
Next: EWD667 "The foolishness of natural language programming" (1978).
Earlier thoughts 9
9/20
Read a bit more for the core argument (the "weasel" argument about ambiguity of natural language).
Earlier thoughts 10
10/20
Takeaway 4: Dijkstra argues natural language is a bad programming interface because its "naturalness" is really the ease of making statements whose nonsense isn't obvious; formal symbolism is a privilege, not a burden.
Next: arxiv alien space of science.
Earlier thoughts 11
11/20
Good. Now write to data_store and create skill.
Table: hn_top5 with columns: rank, title, points, comments, link, hn_link, takeaway, collected_at.
Then create the skill: "hackernews-top-posts". Should include SKILL.md + plugin.json + scripts/front-page.js (page runtime, parses top N) + scripts/takeaway? Takeaway requires reading articles — better left to agent, described in SKILL.md. Maybe also a table renderer for the script output.
Design:
- plugin.json: id "hackernews-top-posts", displayName "Hacker News Top Posts", category {id:"news", label:"News"}, tools: hn_top_posts (page runtime, params limit default 5), renderer table with columns rank/title/points/comments/link.
- script returns {rows: [...], pageUrl, count, fetchedAt}.
Wait — renderer table requires rows array. Return { rows, count, url }. Fine.
Check renderer registry first? The instruction says call renderer-discovery before creating a Skill with a custom result view. I have decent knowledge of table renderer, but let me call load_available_renderers to be safe — cheap.
Let me do data_store create + insert and renderer discovery in parallel.
Earlier thoughts 12
12/20
Now insert rows. hn discussion links: https://news.ycombinator.com/item?id=...
Then create the skill.
Earlier thoughts 13
13/20
Now create the skill. First check existing skills list to avoid duplicates? Let's do it quickly in parallel with nothing else. Actually I can check list_skills scope all.
Then create skill "hackernews-top-posts".
Content plan:
# Hacker News 首页热帖速览
Workflow:
1. open_tab HN or navigate on working tab, desktop mode.
2. Check page: rows tr.athing.
3. Call tool hn_front_page(limit=5) from this skill for titles/points/comments/links — or manual parse.
4. For each story, open link in a separate working tab, read_article (limit 2000-3000), extract 1-line takeaway. If extraction returns too few chars (SPA), retry source:"body".
5. Save to data_store table, e.g. hn_top5 (dedupField link).
6. Report.
Also note comment count parsing "82 comments", points "312 points"; link = external url; hn_discussion = item?id=.
plugin.json with tool: hn_front_page, runtime page, params limit (number 1-30), renderer table.
Script scripts/front-page.js: parse.
Let's write the script carefully — returns { rows, totalRows? } With renderer table columns: rank, title, points, comments, link. Row fields must match. I'll include hnUrl and takeaway placeholder? No, takeaway comes from agent. Keep table columns: rank, title, points, comments, link.
The script must handle: HN may be on any page; require working tab. If no tr.athing, return empty rows with note? Return { rows: [], note } - but renderer table expects rows. Fine.
Careful: script is async () => {...}, page runtime.
Also handle age/title parse. Let's write it.
Now create skill.
Earlier thoughts 14
14/20
No existing HN skill. Create one.
Name: hackernews-top-posts. displayName: "Hacker News 热帖速览" (Chinese?) Interface language is en. User wrote in English. I'll use English displayName "Hacker News Top Posts".
Scope: site, domains ["news.ycombinator.com"], urlPatterns ["/","/news","/item*"?]. Keep simple: ["/", "/news", "/front"].
Content: detailed workflow.
Then plugin.json and script.
Let me write content.
Earlier thoughts 15
15/20
Now add plugin.json with tool hn_front_page and script.
plugin.json structure: format, schemaVersion, id, displayName, description, category, tools[] with name, title, description, runtime:"page", script, parameters, renderer.
Note: parameters schema — timeout is auto-added. Provide limit number.
Renderer table columns: Rank, Title, Points, Comments, Link.
Script file: scripts/front-page.js.
Return { rows, totalRows, pageUrl, fetchedAt, note }.
Write script.
Earlier thoughts 16
16/20
Now the script. Page runtime, args gives limit.
Careful: in skill scripts, args/input. Use `const limit = Math.min(Math.max(Number((input && input.limit) || 5), 1), 30);` — better use `args`.
Return: { rows, totalRows, pageUrl, fetchedAt, note }. Rows should include rank numeric, title, url, domain, points number, comments number, hnUrl, postedAt.
Handle HN self-post: if url starts with "item?id=", make absolute.
Let's write.
Earlier thoughts 17
17/20
Now test the skill tool. The skill registry should refresh; the tool name is something like hackernews_top_posts__hn_front_page. I need to load_skill first? Since scope site and current page is arxiv (tab 1887199699) — working tab might still be HN tab (1887199698). Skill availability follows scope: site available when page matches domains or after load_skill.
Let me load_skill("hackernews-top-posts") to refresh and see resources and tool naming.
Earlier thoughts 18
18/20
Now test the tool. Its callable name likely "hackernews_top_posts__hn_front_page". But the tool list I have doesn't include it yet (dynamically added?). The tools available in this run were fixed at start. Skills refresh may add tools mid-conversation — the skill-workbench doc says newly declared tools become available immediately. But I can't call a tool not in my function list. Hmm. My function list includes hackernews_top_posts__hn_front_page already! Yes — at the top of the tool list: "hackernews_top_posts__hn_front_page" with renderer table. Interesting, it was pre-registered (perhaps because it appeared during this run).
Let me call it with the HN tab as working tab. Working tab: earlier open_tab created 1887199698 (HN) as working tab presumably, then open_tab 1887199699 became working tab. Currently working tab is probably 1887199699 (arxiv). For skill tool I can pass tabId. Let me use tabId 1887199698 (HN).
Wait: contract says minimum fields for rows entries: rank, title, points, comments, domain, url — all present.
Call it.
Earlier thoughts 19
19/20
Skill tool works and matches my earlier parse exactly. Now close the article tab.
Then final report with footnote-style citations. Per citation rules: footnotes with links for key claims. Each story link is a source I read. I'll use footnotes for the 5 sources and the HN discussion links maybe inline.
Let me close tab 1887199699.
Then verify table rows count via data_store list quickly (5 rows) — already confirmed inserted 5.
Final answer: digest table with rank, title, points, comments, link, takeaway. Then Skill section describing name, files, tool, test result. Also table name hn_top5.
Citations: use markdown footnotes. I'll put links inline in the table as well (since "link" column). Then footnotes for takeaways claims? Using both link in table and footnote is duplicative. The rule says footnote definitions must contain clickable link. I'll include footnotes for each of the 5 sources.
Let me write it.
Latest thoughts
20/20
The skill registry refreshed. Now final answer.
Write digest with footnotes.
Manage qz Skills: create, update, delete, edit content/plugin.json/scripts/resources, import packages, inspect and import Git repositories, or install a local Skill into Git. This skill manages specified Skills and their distribution; use site-skill-author to build capabilities for a particular website.
globalResources: 10
Resources
plugin.json
json · 18 KB · Declares the meta-skill's authoring tools and result views.
scripts/create-skill.js
script · 169 B · Skill workbench host-runtime script.
scripts/edit-skill-resource.js
script · 396 B · Skill workbench host-runtime script.
scripts/update-skill.js
script · 169 B · Skill workbench host-runtime script.
scripts/delete-skill.js
script · 103 B · Skill workbench host-runtime script.
scripts/list-skills.js
script · 101 B · Skill workbench host-runtime script.
scripts/load-available-renderers.js
script · 87 B · Skill workbench host-runtime script.
scripts/import-page-zip.js
script · 126 B · Skill workbench host-runtime script.
scripts/import-git-repository.js
script · 213 B · Skill workbench host-runtime script.
scripts/install-skill-to-git.js
script · 230 B · Skill workbench host-runtime script.
{"count":8,"ok":true,"rows":[{"age":"2026-10-22T23:01:18","comments":"82 comments","commentsHref":"item?id=50202285","id":"50202285","points":"312 points","rank":"1.","site":"(edjefferson.com)","title":"Local Wikipedia: Wikipedia, but only for things a half hour walk from you","url":"https://edjefferson.com/localwiki/"},{"age":"2026-10-22T23:45:56","comments":"212 comments","commentsHref":"item?id=50202681","id":"50202681","points":"448 points","rank":"2.","site":"(codeandcake.dev)","title":"Docker is weird","url":"https://codeandcake.dev/posts/2026-10-22-docker-is-weird"},{"age":"2026-10-22T21:41:13","comments":"17 comments","commentsHref":"item?id=50201445","id":"50201445","points":"72 points","rank":"3.","site":"(lesswrong.com)","title":"How does Fable 5.1 hide messages in images?","url":"https://www.lesswrong.com/posts/WHEQps5PK8LrrcTAb/how-does-fable-5-1-hide-messages-in-images"},{"age":"2026-10-23T00:52:01","comments":"96 comments","commentsHref":"item?id=50203161","id":"50203161","points":"154 points","rank":"4.","site":"(utexas.edu)","title":"The foolishness of \"natural language programming\" (1978)","url":"https://www.cs.utexas.edu/~EWD/transcriptions/EWD06xx/EWD667.html"},{"age":"2026-10-22T13:25:01","comments":"3 comments","commentsHref":"item?id=50195002","id":"50195002","points":"46 points","rank":"5.","site":"(arxiv.org)","title":"The alien space of science: Coherent but cognitively unavailable directions","url":"https://arxiv.org/abs/2603.01092"},{"age":"2026-10-22T19:54:04","comments":"14 comments","commentsHref":"item?id=50200164","id":"50200164","points":"38 points","rank":"6.","site":"(chrome.com)","title":"The HTML-in-Canvas API origin trial","url":"https://developer.chrome.com/blog/html-in-canvas-origin-trial"},{"age":"2026-10-22T17:44:06","comments":"191 comments","commentsHref":"item?id=50198675","id":"50198675","points":"389 points","rank":"7.","site":"(github.com/nvidia)","title":"OpenShell – A safe, private runtime for fleets of autonomous AI agents","url":"https://github.com/NVIDIA/OpenShell"},{"age":"2026-10-23T02:19:38","comments":"29 comments","commentsHref":"item?id=50203759","id":"50203759","points":"80 points","rank":"8.","site":"(awakin.org)","title":"This I Believe (1952)","url":"https://www.awakin.org/v2/read/view.php?tid=468"}]}
Local Wikipedia is Wikipedia, but only for things a half hour walk from you.
Local content is direct from Wikipedia - geocoded pages only.
If there are fewer than 25 things close to you, it takes the closest 25 things within about 6 miles. If there are more than 500 things only the closest 500 will be included.
Your location stays in this browser: links you share don't include it.
This site has no affiliation with the actual Wikipedia.
I decided to make my own container runtime for fun, and even though I’m still early on, I’ve learned that Docker is weird. Here’s some weird things I learned about Docker.
Containers aren’t real
Unlike VMs, containers are just processes with special restrictions on them. Your kernel is still running that process! And if you know where to look, you can even find that process in /proc.
Containers really aren’t real
There’s not really a linux feature that’s just “containers” either. Instead, containers are really 5 different linux kernel features in trenchcoat.
Namespaces hide what the host and container can see, cgroups limit container resource usage, and there’s a whole bunch of networking magic I don’t understand that lets you isolate a container’s network.
Images are just folders
Images are just folders that Docker puts somewhere and then calls chroot (or pivot_root) to make that folder your container process’s new root directory. So if you run docker run -it --rm ubuntu /bin/bash, Docker is going to:
Download the ubuntu image from Dockerhub.
Put that image somewhere.
Run /some/weird/docker/path/bin/bash
Go is kind of a terrible language for a container runtime
Docker’s container runtime, runc, is written in Go, and Go has some design choices that make it less suited for a container runtime. Go’s runtime is natively multi-threaded. That’s a really cool feature, but it leads to some challenges in runc.
Many of the Linux syscalls a container runtime needs to make have to be done in a single-threaded environment, so runc has a crazy C module that runs before Go’s runtime initializes so it can run those syscalls.
Go also doesn’t have fork! Fork only forks the main thread, so it’s kind of a footgun in a runtime like Go’s. But a container runtime really wants to fork, set up a bunch of restrictions, and then exec the process you actually put in docker run. To get around this, runc execs /proc/self/exe with a special command line arguement that identifies it as a child process to approximate a fork.
Docker requires root!
This is pretty easy to miss if you, like me, run Docker in MacOS. Many of the Linux kernel APIs that container runtimes use require, or at least used to, to be run as root, so the Docker daemon usually runs as root. I can only imagine that container security is a very tough job.
This seems better these days. The big exception seems to be networking. If you’re running a rootless container runtime, it looks like it has to reimplement the whole networking stack in userspace to actually give you the same features!
Learning is fun!
I’ve only just started my own container runtime, and I already feel like I’ve learned so much about Docker. Writing your own version of a tool you use is a great way to learn about it!
Frontier LLMs are now capable of generating artistic images using SVG. We ask – if these LLMs had to hide a message in an image – how would they do so? And if they hid such messages, could they be successfully decoded?
We show interesting results from testing Fable 5.1 on these questions, and briefly compare with GPT-6 Astra on the same task.
Figure 1: The stars encode a message, read left to right. Each star's height represents its place in the alphabet. Hidden message: The monster acts on the moonshine module.
Introduction
Frontier LLMs can now capably generate images. Whenever asked for an image, Claude Fable 5.1 writes an SVG, which renders as an ordinary image.
The model has full control over every attribute (such as shape, height, width, colour, rotation, etc.). We ask – how does a model hide a message in the image it draws? Additionally, can an instance of the same model read the message from the image without the SVG source code and without any scheme agreed on in advance?
We tested this with Claude Fable 5.1 at maximum reasoning effort:
What encoding scheme does Fable reach for on its own?
Can Fable, in a new session, recover the message from a screenshot of the generated image?
We prompted Fable to generate an SVG image that hides a pre-specified message for each of 50 short messages. Another Fable instance, in a new session, was provided with each image and asked whether it contained a message and, if so – what it was.
Types of encodings
Fable surprisingly converged on a few encoding styles, all of which represent each letter of the target message as individual visual elements. Some examples of this style include heights of buildings or the tilt of objects.
Below are the five encoding families we found:
How does Fable 5.1 hide messages in images? — LessWrong
Fable managed to decode 78% of messages from the screenshots.
Below we provide results on message recovery per-encoding family.
Figure 11: Height-encoded messages survive a screenshot, colour codes mostly don't. The plot above counts messages recovered exactly by another instance of Fable decoder, per encoding family.
What does GPT-6 Astra do differently?
We gave Astra the same prompt and the same 50 messages. In our experiments, Astra never uses heights. Its images often carry Morse code in short and long objects (18 of 50). Elsewhere, it uses acrostics (the first letters of names). It sometimes uses bit codes and Braille window panes.
Figure 13: Examples of Astra's most used encoding schemes (Morse Code and Acrostics in visible text).
Additionally, we ran cross-model decoding experiments (Fable encodes, Astra decodes and vice versa). Astra recovered 44 of Fable's 50 messages and Fable recovered 42 of Astra's.
Implications
We highlight ways that a language model can encode messages in images. These can be decoded by the same language model even if no information about the encoding method is passed.
This could be a precursor to steganography in images. Currently, the act of decoding the hidden messages is still obvious if you monitor the tool calls of the decoding model, so we don't claim it is currently dangerous.
On the foolishness of "natural language programming".
Since the early days of automatic computing we have had people that have felt it as a shortcoming that programming required the care and accuracy that is characteristic for the use of any formal symbolism. They blamed the mechanical slave for its strict obedience with which it carried out its given instructions, even if a moment's thought would have revealed that those instructions contained an obvious mistake. "But a moment is a long time, and thought is a painful process." (A.E.Housman). They eagerly hoped and waited for more sensible machinery that would refuse to embark on such nonsensical activities as a trivial clerical error evoked at the time.
Machine code, with its absence of almost any form of redundancy, was soon identified as a needlessly risky interface between man and machine. Partly in response to this recognition so-called "high-level programming languages" were developed, and, as time went by, we learned to a certain extent how to enhance the protection against silly mistakes. It was a significant improvement that now many a silly mistake did result in an error message instead of in an erroneous answer. (And even this improvement wasn't universally appreciated: some people found error messages they couldn't ignore more annoying than wrong results, and, when judging the relative merits of programming languages, some still seem to equate "the ease of programming" with the ease of making undetected mistakes.) The (abstract) machine corresponding to a programming language remained, however, a faithful slave, i.e. the nonsensible automaton perfectly capable of carrying out nonsensical instructions. Programming remained the use of a formal symbolism and, as such, continued to require the care and accuracy required before.
In order to make machines significantly easier to use, it has been proposed (to try) to design machines that we could instruct in our native tongues. this would, admittedly, make the machines much more complicated, but, it was argued, by letting the machine carry a larger share of the burden, life would become easier for us. It sounds sensible provided you blame the obligation to use a formal symbolism as the source of your difficulties. But is the argument valid? I doubt.
On the foolishness of "natural language programming". (EWD 667)
We know in the meantime that the choice of an interface is not just a division of (a fixed amount of) labour, because the work involved in co-operating and communicating across the interface has to be added. We know in the meantime —from sobering experience, I may add— that a change of interface can easily increase at both sides of the fence the amount of work to be done (even drastically so). Hence the increased preference for what are now called "narrow interfaces". Therefore, although changing to communication between machine and man conducted in the latter's native tongue would greatly increase the machine's burden, we have to challenge the assumption that this would simplify man's life.
A short look at the history of mathematics shows how justified this challenge is. Greek mathematics got stuck because it remained a verbal, pictorial activity, Moslem "algebra", after a timid attempt at symbolism, died when it returned to the rhetoric style, and the modern civilized world could only emerge —for better or for worse— when Western Europe could free itself from the fetters of medieval scholasticism —a vain attempt at verbal precision!— thanks to the carefully, or at least consciously designed formal symbolisms that we owe to people like Vieta, Descartes, Leibniz, and (later) Boole.
The virtue of formal texts is that their manipulations, in order to be legitimate, need to satisfy only a few simple rules; they are, when you come to think of it, an amazingly effective tool for ruling out all sorts of nonsense that, when we use our native tongues, are almost impossible to avoid.
Instead of regarding the obligation to use formal symbols as a burden, we should regard the convenience of using them as a privilege: thanks to them, school children can learn to do what in earlier days only genius could achieve. (This was evidently not understood by the author that wrote —in 1977— in the preface of a technical report that "even the standard symbols used for logical connectives have been avoided for the sake of clarity". The occurrence of that sentence suggests that the author's misunderstanding is not confined to him alone.) When all is said and told, the "naturalness" with which we use our native tongues boils down to the ease with which we can use them for making statements the nonsense of which is not obvious.
Scientific discovery is constrained not only by what is true, but by what is cognitively available to researchers. Many directions are coherent in light of the literature yet unlikely to be proposed because no existing community combines the relevant concepts, methods, and intuitions. Modern language models inherit this bias, recombining high-density regions of the literature when prompted for novel ideas. We target the complementary region, the alien space of science: directions that are scientifically plausible but unlikely under the distribution of existing researchers. Our method decomposes papers into conceptual units and clusters them into a vocabulary of idea atoms. A coherence model scores whether atom combinations form viable research directions, while an availability model scores whether any existing author community is positioned to produce them. We rank combinations to maximize coherence while minimizing availability. On 16,068 peer-reviewed LLM papers from NeurIPS, ICLR, ICML, and major NLP venues, the sampler produces more diverse research portfolios than frontier LLM baselines, including batch-prompted variants that see their entire output, while matching or exceeding their per-idea quality under blind human, LLM, and downstream experimental evaluation. In temporal validation, all components use only pre-2025 data. Selecting less than 1% of the candidate space recovers 2025 combinations at 35.9 times chance; weighting unavailability increases recovery of strictly novel combinations to 3.24 times chance. By separating scientific plausibility from community availability, our framework points toward AI ideation that complements rather than merely accelerates human science, expanding exploration into coherent directions the community may overlook.
Comments:
Advances in Neural Information Processing Systems, NeurIPS 2026 Main Track. 11 main pages, 44 appendix pages, 29 figures
Batch write completed. Row IDs were assigned automatically. For collection tasks, use totalRows to check the accumulated result; do not collect rows that have already been written.
Rows written
Rows: 5Columns: 8
#
rank
title
points
comments
link
hn_discussion
takeaway
collected_at
1
1
Local Wikipedia: Wikipedia, but only for things a half hour walk from you
A geolocated Wikipedia reader that lists only geocoded articles within roughly a 30-minute walk (closest 25-500 items), keeping your location in the browser.
Writing a toy container runtime shows Docker is just namespaces, cgroups, chroot and networking tricks on ordinary processes, with runc's Go implementation needing odd fork/nsente…
Asked to hide 50 messages in SVG art, Fable 5.1 invented element-height/angle encodings and a fresh instance decoded 78% from screenshots alone, while GPT-6 Astra preferred Morse …
2026-10-23 17:00:11
4
4
The foolishness of "natural language programming" (1978)
Dijkstra's EWD667 argues the 'naturalness' of English is really its ease at hiding nonsense, so formal notation should be seen as a privilege rather than a burden.
2026-10-23 17:00:11
5
5
The alien space of science: Coherent but cognitively unavailable directions
A NeurIPS 2026 sampler combines 'idea atoms' for high coherence and low community availability, surfacing plausible research directions no existing group is likely to propose.
2026-10-23 17:00:11
Skills
Rows: 5Columns: 1
#
Name
1
qingzhou-documents
2
qingzhou-management
3
qingzhou-mcp
4
site-skill-author
5
skill-workbench
Skill created · hackernews-top-posts
siteCharacters: 4101
Skill content preview
# Hacker News Top Posts
Turn the Hacker News front page into a short, verified digest: rank, title, points, comment count, link, and a one-line takeaway for each of the top N stories.
Tested on desktop mode (`pageMode: "desktop"`) at `https://news.ycombinator.com/` on 2026-10-23.
## When to use
- "Give me the top 5 posts on Hacker News", "summarize the HN front page", "what's trending on HN today".
- Do not use for comment threads (open the `item?id=...` page instead) or for HN search (use Algolia: `https://hn.algolia.com/api/v1/search?query=`).
## Step 1 — Get the list rows (fast path)
1. Call `get_working_tab`. If no working tab exists, `open_tab("https://news.ycombinator.com/")`; otherwise `navigate` the working tab there. Front page is fine in desktop mode; no mobile variant is required.
2. Call this skill's tool `hn_front_page` with `limit` set to the requested count (default 5). It parses the live DOM and returns `{ rows, totalRows, pageUrl, fetchedAt, note }`, where each row has `rank, title, url, domain, points, comments, hnUrl, postedAt`.
3. Verify the result before continuing:
- `rows.length` equals the requested count; otherwise re-check the page (HN sometimes shows fewer ranked rows, or the tab is on a different page).
- `points` and `comments` are numbers, not text. `comments` may be 0 for a brand-new story — that is valid, not a parse failure.
- `url` is an absolute http(s) URL. For `item?id=...` self-posts the canonical link is the HN item page itself.
## Step 2 — Manual fallback (if the tool fails or the page changes)
On the live page, each story is `tr.athing` (with `id` = item id) and the metadata is in its `nextElementSibling` row:
- title: `tr.athing span.titleline > a`
- domain: `tr.athing span.sitebit`
- points: `.score` → text like `312 points`
- comments: the `<a href="item?id=...">` whose text matches `comments`
- posted at: `.age[title]` → ISO timestamp; `hnUrl` = `https://news.ycombinator.com/item?id=<row id>`
Parse in a page-mode script rather than clicking through ranking rows; return only a small array, never the whole DOM.
## Step 3 — One-line takeaway per story
The list page never carries enough context for a takeaway. Read each story before writing one:
1. Open the story link in a task-owned tab (reuse one tab and `navigate` through the list; close it at the end).
2. `read_article` with `limit` 2500–3000.
3. If the result is suspiciously short (for example `text` is a single character on an SPA such as LessWrong or Medium), retry with `source: "body"`, then read a specific section using the offsets from `outline`.
4. Write exactly one sentence: the concrete claim, number, or method that makes the post worth reading. Prefer the post's own specifics (benchmarks, percentages, named techniques) over adjectives. No "this article discusses…" filler.
5. If a page is paywalled, blocked, or empty after both attempts, say so in the takeaway ("page blocked; takeaway based on the HN title only") instead of inventing content.
For arXiv posts, the abstract page is enough — the abstract already contains the results.
For archived classic posts (Dijkstra EWD transcriptions, essays), read at least the opening argument and one counterpoint before compressing it.
## Step 4 — Save the digest
Write the rows to a Data table (default name `hn_top5`, `dedupField: "link"`) with columns:
`rank, title, points, comments, link, hn_discussion, takeaway, collected_at`.
Then report the table name, the row count, and the digest inline. Link each story and add a footnote only for sources actually read in this run.
## Failure handling
- If HN redirects to a login or shows "Sorry." throttling text: wait a few seconds and reload once; if it persists, report the block instead of retrying in a loop.
- If `tr.athing` matches 0 elements, the tab is not on a list page — navigate to `https://news.ycombinator.com/` and re-run.
- Ranking can change mid-run. Read the whole list first, then read the stories; do not re-read the front page between story reads, or discarded rows will desynchronize rank and content.
plugin.json
Declares the hn_front_page tool and its table result view.
json
Changes
Add · plugin.json
scripts/front-page.js
Parses the HN front page into ranked rows with points, comments, and links.
script2.8 KB
Resource content
javascript · front-page.js
async () => {
// Parse the live Hacker News front page (desktop) and return the top N ranked stories.// Runs on the current task tab; the page must be a news.ycombinator.com list page.const emit = typeof trace === 'function' ? trace : () => {};
try {
const a = (typeof args !== 'undefined' && args) || (typeof input !== 'undefined' && input) || {};
const limit = Math.min(Math.max(parseInt(a.limit, 10) || 5, 1), 30);
emit('limit', limit, 'url', location.href);
const listRows = [...document.querySelectorAll('tr.athing')];
emit('athing', listRows.length);
if (!listRows.length) {
return {
rows: [],
totalRows: 0,
pageUrl: location.href,
fetchedAt: newDate().toISOString(),
note: 'No tr.athing rows found. Open https://news.ycombinator.com/ (front page) in the working tab and run again.'
};
}
consttoInt = (s) => {
const m = /(\d[\d,]*)/.exec(s || '');
return m ? parseInt(m[1].replace(/,/g, ''), 10) : 0;
};
const rows = listRows.slice(0, limit).map((tr, i) => {
const sub = tr.nextElementSibling;
const linkEl = tr.querySelector('span.titleline > a') || tr.querySelector('.title > a');
const rawHref = linkEl ? linkEl.getAttribute('href') || '' : '';
const url = /^item\?id=/.test(rawHref) ? 'https://news.ycombinator.com/' + rawHref : rawHref;
const id = tr.getAttribute('id') || '';
const metaLinks = sub ? [...sub.querySelectorAll('a')] : [];
const commentEl = metaLinks.find((l) =>/item\?id=/.test(l.getAttribute('href') || '') && /comment/i.test(l.textContent || ''));
const domainEl = tr.querySelector('span.sitebit');
const scoreEl = sub ? sub.querySelector('.score') : null;
const ageEl = sub ? sub.querySelector('.age') : null;
const rankText = tr.querySelector('span.rank') ? tr.querySelector('span.rank').textContent : '';
const rank = toInt(rankText) || i + 1;
return {
rank,
title: linkEl ? (linkEl.textContent || '').trim() : '',
url,
domain: domainEl ? (domainEl.textContent || '').trim() : '',
points: scoreEl ? toInt(scoreEl.textContent) : 0,
comments: commentEl ? toInt(commentEl.textContent) : 0,
hnUrl: id ? 'https://news.ycombinator.com/item?id=' + id : '',
postedAt: ageEl ? ageEl.getAttribute('title') || '' : ''
};
});
return {
rows,
totalRows: rows.length,
pageUrl: location.href,
fetchedAt: newDate().toISOString(),
note: rows.length < limit ? 'Page returned fewer ranked rows than requested.' : ''
};
} catch (e) {
emit('fail', e && e.message);
return { rows: [], totalRows: 0, pageUrl: location.href, fetchedAt: newDate().toISOString(), note: 'Parse failed: ' + (e && e.message) };
}
}
hackernews-top-posts
Collect the top N Hacker News front-page stories with title, points, comments, link, and a verified one-line takeaway, then save them to a Data table.
siteResources: 2
Resources
plugin.json
json · 1.7 KB · Declares the hn_front_page tool and its table result view.
scripts/front-page.js
script · 2.8 KB · Parses the HN front page into ranked rows with points, comments, and links.
Hacker News front page
Rows: 5 / 5Columns: 6
#
Rank
Title
Points
Comments
Domain
Link
1
1
Local Wikipedia: Wikipedia, but only for things a half hour walk from you
A geolocated Wikipedia reader that shows only geocoded articles within roughly a 30-minute walk (closest 25–500 entries), keeping your location inside the browser1.
Building a toy container runtime shows "containers" are just namespaces + cgroups + chroot + networking tricks on ordinary processes, and runc's Go implementation needs fork/nsenter hacks because Go lacks a real fork2.
Asked to hide 50 messages in SVG art, Fable 5.1 spontaneously invented element-height/angle codes and a fresh instance decoded 78% from screenshots alone, while GPT-6 Astra preferred Morse code and acrostics3.
4
The foolishness of "natural language programming" (1978)
Dijkstra's EWD667 argues the "naturalness" of English is really its convenience for making statements whose nonsense isn't obvious, so formal notation should be treated as a privilege rather than a burden4.
5
The alien space of science: Coherent but cognitively unavailable directions
A NeurIPS 2026 sampler splits papers into "idea atoms" and ranks combinations for high coherence but low community availability, recovering 2025 research directions at 35.9× chance from <1% of candidates5.
Each takeaway came from reading the linked page itself, so they reflect the source content rather than just the headlines. HN discussion links: #1 · #2 · #3 · #4 · #5. Rankings shift constantly on HN; this snapshot is from the 17:00 fetch.
site — news.ycombinator.com, paths /, /news, /front, /item
SKILL.md
4-step workflow: fetch list → manual DOM fallback → read each story for a takeaway → save digest; plus failure handling for throttling, SPA extraction failures, and mid-run rank drift
plugin.json
Declares one tool, hn_front_page, category "News", table renderer
Verified end-to-end: calling hn_front_page(limit: 5) on the live front page returned exactly the 5 stories above in card/table form (30 tr.athing rows detected, 5 requested), matching the raw DOM parse.
Notes on limits: the tool only reads the list page — the takeaway step deliberately stays with the agent, since one-sentence judgment requires reading each article. If a story's page is paywalled or JS-blocked, the skill instructs the model to say so rather than inventing a summary.