sparepack 把私有仓库切成只含接口、验收测试和假数据的任务包。别人对着测试写实现,你的业务逻辑一行都没离开过本机。
sparepack slices a private repository down to interfaces, acceptance tests, and synthetic fixtures. Someone implements against the tests; your business logic never leaves your machine.
这不是共享、出借、合池或转售 AI 订阅额度。那违反 Anthropic 条款,做了就是等封号。 This is not a way to share, lend, pool, or resell AI subscription quota. That is against Anthropic's terms and gets accounts banned.
You may not share your Account login information, Anthropic API key, or Account credentials with anyone else. You also may not make your Account available to anyone else.
2026 年 2 月 Anthropic 进一步禁止把 Pro/Max 的 OAuth token 用在 Claude Code 和 claude.ai 之外,也禁止代表他人把请求路由过你的 seat——即使量很小,即使只是团队内部工具。 In February 2026 Anthropic went further, prohibiting Pro/Max OAuth tokens anywhere outside Claude Code and claude.ai, including routing other people's requests through your seat — even at low volume, even for an internal team tool.
所以这里没有额度池、没有 token 中转、没有代理、没有共享账号。有余力的人自己把活干了,交出去的是成果(一个 PR),不是账号访问权。那就是普通的外包,条款上是干净的。 So there are no quota pools, no token relays, no proxies, no shared accounts. People with spare capacity do the work themselves and hand over the result — a pull request — not access to their account. That is ordinary freelance work, and it is fine.
真正稀缺的东西从来不是 token,是有时间又愿意干活的人。 The scarce resource was never tokens. It was people with time and willingness.
下面每一条都不是形容词,是一条能跑的命令或者一行能读的代码。这也是唯一值得写在落地页上的那种卖点。 None of the following is an adjective. Each one is a command you can run or a line you can read — the only kind of claim worth putting on a landing page.
大多数隐私建议止步于建议。sparepack 是 npm install 装得到的命令行工具:白名单制、解析后重建、写盘前强制人工过目。80 个测试,其中一个端到端跑一个塞满凭证和客户记录的仓库。
Most privacy advice stops at advice. sparepack is a CLI you can npm install: allowlist-only, parse-and-rebuild, mandatory human review before anything is written. 80 tests, one of them an end-to-end run against a repo seeded with credentials and customer records.
「积分不可转让」在这里不是一句保证。账本 schema 里根本不存在 user→user 的转账类型,校验器碰到就当篡改,直接非零退出。想违规都没有地方放。 "Points are not transferable" is not a pledge here. The ledger schema has no user-to-user transfer type at all; the verifier treats one as tampering and exits non-zero. There is nowhere to put the violation.
27 条记录、9 条不变量、一条命令。余额不是维护者说了算,是从完整历史重放出来的。快照和重算对不上,以重算为准。 27 entries, 9 invariants, one command. Balances are not asserted by the maintainer, they are replayed from the full history. If the snapshot disagrees with the replay, the replay wins.
合规执行表里有两行明确标着「未强制」。账本文件头记着一次时间戳更正的完整经过。被折叠的 19 条垃圾评论逐条列在治理日志里。这不是为了显得诚实,是为了不让人读完文档以为保护比实际更多。 Two rows of the enforcement table say "not enforced" in as many words. The ledger header documents a one-time timestamp correction in full. All 19 minimized spam comments are itemised in the governance log. Not for the look of candour — so nobody finishes the docs assuming more protection than exists.
你有个真实的 bug,任务不大,也有人愿意修。但那个文件里全是你的定价规则、客户数据,还有三年前谁留下的一个硬编码密钥。于是你不问了,bug 就一直在那。 You have a real bug. The task is small and there are people who would happily fix it. But the file is full of your pricing rules, your customers, and a hardcoded key someone left there three years ago. So you do not ask, and the bug stays.
// src/pricing.ts export function quote( seats: number, tier: string ): Quote { const base = tier === "enterprise" ? 4900 : 1900 const discount = seats > 50 ? 0.7 : seats > 10 ? 0.85 : 1 return { cents: Math.round( base * seats * discount), tier } }
// Stripped by sparepack: // signatures only. export function quote( seats: number, tier: string ): Quote { throw new Error( 'sparepack stub: not implemented' ) }
签名是契约,阈值是商业决策。只有前者需要离开这栋楼。 The signature is a contract. The thresholds are a business decision. Only one of those needs to leave the building.
# 三个命令Three commands npx sparepack init # 生成带注释的配置write a commented config npx sparepack pack # 构建、扫描、给你过目、再落盘build, scan, show you, then write npx sparepack verify # 从磁盘重新推导,独立复检re-derive from disk, check again
一份 sparepack.yaml,五个键,每个键决定一类文件怎么处理。
One sparepack.yaml, five keys, each deciding how a class of file is handled.
task: "Stream large CSV imports instead of loading the whole file" include: # 逐字节原样发布published byte for byte - src/importer/types.ts interfaces: # 留签名,函数体换成会抛错的桩signatures kept, bodies stubbed - src/importer/parser.ts tests: # 这就是任务规约本身this is the specification - tests/importer/*.spec.ts fixtures: # 真结构,假数据real structure, synthetic values data/orders.json: shape:5 redact: # 扫描器不可能知道的自家名字names the scanner cannot know - pattern: "acme-corp|ACME" replace: "example-org"
shape:n 读真实 JSON,按同样的键和嵌套重建一份假值,数组截到 n 条。rows:n 保留分隔文件的表头再造 n 行。生成是确定性的——同一份配置打两次包字节一致,所以两个包之间的 diff 一定意味着有东西真的变了。
shape:n reads the real JSON and rebuilds it with the same keys and nesting but fake values, capping arrays at n. rows:n keeps a delimited file's header and generates n fake rows. Generation is deterministic — packing twice gives byte-identical output, so a diff between two packs always means something real changed.
白名单制。没有 exclude 键,以后也不会有。「除了这些全发出去」意味着一个没人想过的文件会被发布,泄露就是这么发生的。而且匹配不到任何文件的 pattern 直接报错——打错一个字不该悄悄少发东西。
Allowlist only. There is no exclude key and there will not be one. "Publish everything except…" means a file nobody thought about gets published, which is how leaks happen. A pattern matching nothing is an error rather than a silent no-op, because a typo should not quietly ship less than you meant.
失败方向朝「少给」。接口剥离是解析后只输出能被明确识别为契约的东西,不是复制原文再删函数体。前者解析漏了等于 stub 缺东西、你会发现;后者漏了等于源码泄露。不支持的语言直接拒绝,绝不把一个 .py 原样放过还暗示它被剥离过了。
Failures point at giving less. Stripping parses your file and emits only what it positively recognised as contract. It does not copy the file and delete the bodies — under that design a parser gap publishes your source. Unsupported languages are refused outright, never passed through with the implication that they were stripped.
写盘在确认之后。整个包在内存里构建、扫描、打印清单,然后问你一句:这份文件清单你敢不敢公开贴出来。答案不是 publish 就一个字节都不写。
Nothing is written before you have seen it. The pack is built in memory, scanned, and printed as a manifest. Then it asks: would you be comfortable posting this file list in public? Answer anything other than publish and no file is created.
各家厂商的 API key、私钥块、JWT、带真实密码的连接串、硬编码的密钥赋值、身份证与手机号、内网 IP 段、内部主机名。扫描发生在你的 redact 规则生效之后——扫之前只会报出你已经处理掉的东西,扫之后才能验证脱敏是否够用。 API keys from the major providers, private key blocks, JWTs, connection strings carrying real passwords, hardcoded secret assignments, national ID and mobile numbers, private IP ranges, internal hostnames. Scanning happens after your redactions are applied — scanning before would report findings you had already handled, and only scanning after can tell you the redactions were enough.
两件它不做的事:命中的内容永远不会被完整打印,报告只给掩码片段和长度——一份会泄露它检出的密钥的报告,比没有报告更糟。以及它努力不喊狼来了:example.com、127.0.0.1、${DB_PASSWORD}、<your-token-here> 是占位符,不算命中。一个被人学会忽略的检查已经不是检查了。
Two things it will not do. It never prints a finding in full — a report that leaks the secret it detected is worse than no report, so findings carry a masked excerpt and a length. And it works hard not to cry wolf: example.com, 127.0.0.1, ${DB_PASSWORD}, and <your-token-here> are placeholders, not findings. A check people learn to ignore has stopped being a check.
include 里的东西按字节原样发布——那是你的判断不是工具的判断,扫描器是那些文件唯一的兜底。include publishes verbatim, so anything listed there is your judgement, not sparepack's. The scanner is the only safety net on those files.package.json、没有 tsconfig,接单者拿到手得先补几行才能 npm test。A pack is a set of files, not a runnable project. No package.json, no tsconfig — a worker has to add a few lines before npm test works.packages/api/src/...,通常不是你要的。Paths in a pack mirror paths in your repo, with no remapping. Packing from a monorepo root gives you packages/api/src/..., which is usually not what you want.MANIFEST.json 只保留 verify 需要的路径、类型和大小。The manifest does not travel. What you see in your terminal lists dropped internal functions by name and which redact patterns fired — both describe precisely what the pack exists to withhold — so the MANIFEST.json inside the pack keeps only what verify needs: paths, kinds, sizes.扫描器是词法级的,它找的是模式不是含义。写在注释里的业务规则、看着像普通单词的客户名、你忘了加进脱敏列表的内部代号——这些抓不到。真正决定什么东西被公开的,是那一步人工复核;工具里其余所有东西,存在的意义只是让那次复核成为可能。 The scanner is lexical: it finds patterns, not meaning. A business rule written in a comment, a customer name that looks like an ordinary word, an internal codename you forgot to redact — those get through. The manifest review is what actually decides what gets published; everything else exists to make that review possible.
每个任务必须声明一级,按接单者能看到多少排序。Every task declares exactly one, ordered by how much the worker sees.
不知道选哪级:任务能用「一组接口 + 一组测试」描述清楚的,选 P1,这也是绝大多数情况。需要接单者在真实项目里跑起来、点一点才能干的,选 P2。P0 和 P3 是两头的特例。目前只有 P0 和 P1 有实际跑过的记录,P2 有流程文档但还没有真实案例,P3 尚未实现。 Not sure which: if the task can be described by a set of interfaces plus a set of tests, use P1 — that covers most of them. If the worker needs the real project running to do the work at all, use P2. P0 and P3 are the two extremes. Only P0 and P1 have actually been run so far; P2 has a documented process but no real case yet, and P3 is not implemented.
没有网站,没有服务器,全在 GitHub 上。No website, no server. The whole thing runs on GitHub.
/claim,等 issue 被指派给你之后再动手。同时 2 个、每周 5 个。真人手工干活本来就是这个量级,机器刷单会立刻撞墙。Claim — comment /claim, and start only after the issue is assigned to you. Two concurrent, five per week: that is the throughput of a person working by hand, and a bot hits the wall immediately.这个仓库永远不托管你的代码。任务元数据、账本和信誉在这里,代码本身在双方自己的仓库之间直接流转。 This repository never hosts your code. Task metadata, the ledger, and reputation live here; the code moves directly between the two parties' own repositories.
耗额度的任务分三档,没有 XL——再大的必须拆。大额单任务是纠纷的来源,而一个做了一半的 XL 对双方都一文不值。 Quota-consuming tasks come in three sizes and there is no XL — anything bigger gets split. Large single tasks are where disputes come from, and a half-finished XL is worthless to both sides.
| 档位Tier | 范围Scope | TP |
|---|---|---|
| S | ≤30 分钟。修 bug、补文档、补一个缺的测试。≤30 min. Bug fix, doc, missing test. | 10 |
| M | 30 分钟–2 小时。一个函数、一个组件或一个接口。30 min–2 h. One function, component, or endpoint. | 30 |
| L | 2 小时–半天。一个完整特性带测试。2 h–half a day. A complete feature with tests. | 80 |
还有一类不烧额度的任务,专门为了让「这周额度用完了」不等于「没法参与」: A second class of task burns no quota at all, so that being out of quota does not mean being locked out:
| 类型Type | 做什么Scope | TP |
|---|---|---|
review | 审别人的交付 PRReview someone's delivery PR | 5 |
redact-audit | 在一个 sparepack 产出公开之前当第二双眼睛Second pair of eyes on a sparepack output before it goes public | 10 |
spec | 替别人写那组定义任务的验收测试Write the acceptance tests that define someone's task | 15 |
arbitrate | 担任争议仲裁(需 5 次以上交付)Serve as arbitrator on a dispute (5+ deliveries required) | 10 |
积分(TP)只能通过完成任务获得、通过发布任务消耗。不可转让、不可交易、不能提现,不过期,没有二级市场,以后也不会有。它的职责是防止有人只发不接,仅此而已。新人 50 TP,刚好够发一个 M 任务。 Task Points are earned by delivering and spent by requesting. Not transferable, not tradable, no cash value, no expiry, no secondary market — and there will not be one. Their job is to stop people posting forever without ever delivering. That is all. New members start with 50 TP, enough for one M task.
真正的回报是一份可验证的公开交付记录:每次交付都是一个合并进别人真实仓库的 PR。这在找工作或谈外包时是有分量的,刷题记录换不来。 The actual reward is a verifiable public track record: every delivery is a merged PR in someone's real repository. That is worth something when you are job hunting, in a way a LeetCode streak is not.
任一方打 dispute 标签,由一位和本任务无关、有 5 次以上交付的仲裁者接手,目标 3 天出结论:判交付(积分给接单者,事后加需求的发布者不退款)、判退款、或者判拆分并写明理由。每一次裁决都带着仲裁者的 handle 和理由链接写进账本,公开,可上诉一次给另一位仲裁者。
Either party applies the dispute label. An arbitrator with 5+ deliveries and no involvement in the task picks it up, targeting three days: deliver (points to the worker; a requester who moves the goalposts afterwards gets no refund), refund, or split with the reasoning recorded. Every ruling is written into the ledger with the arbitrator's handle and a link to their reasoning. Public, and appealable once to a different arbitrator.
验收标准就是合同。接单时 issue 上没写的东西,不构成拒收的理由。这条对双方都成立,也是为什么任务模板把验收标准设成必填。 Acceptance criteria are the contract. If it was not in the issue when the task was claimed, it is not grounds for refusing delivery. This cuts both ways, and it is why the task template makes acceptance criteria mandatory.
任何积分系统最后都会碰到同一个问题:凭什么信运营方报的余额。这里的答案是把余额变成一个可复现的计算结果而不是一句声明。 Every points system eventually runs into the same question: why believe the operator's numbers. The answer here is to make balances a reproducible computation rather than an assertion.
$ git clone https://github.com/mxx1111/spare-cycles && cd spare-cycles $ node ledger/verify.mjs ledger.jsonl — 27 entries Balances: ghzhost 60 TP manav8498 10 TP rafaio1 10 TP mxx1111 0 TP ———————————————————————— ————— in balances 80 TP in escrow 140 TP total issued 220 TP All invariants hold.
ledger.jsonl 只追加:不改行、不删行、不调顺序,更正一律是新增的冲正条目。balances.json 是派生产物,两者对不上时以重算为准。校验器检查九条不变量,其中余额非负和托管非负是逐条增量检查的——中途变成负数、后面又补回来的历史一样判无效。
ledger.jsonl is append-only: never edit a line, never delete one, never reorder. Corrections are new compensating entries. balances.json is derived output, and if the two disagree the recomputation wins. The verifier checks nine invariants, and the two non-negativity ones are checked incrementally — a history that dips negative in the middle and recovers is still invalid.
「积分不可转让」这句承诺,在代码里就是这六行——外加一个「不在这六个里面就是篡改」的判断: The promise that points cannot be transferred is these six lines, plus a rule that anything outside them is tampering:
// ledger/verify.mjs const TYPES = { grant, escrow, settle, refund, split, adjust } // 没有 transfer。用户之间的转账在这个 schema 里不存在,No transfer. User-to-user movement does not exist in // 不是「不允许」,是根本无法表达。this schema — not disallowed, inexpressible. fail(where, `unknown transaction type "transfer"` + ` — COMPLIANCE.md red line 5`)
时间戳必须是观测到的事件时间——issue 的 createdAt、PR 的 mergedAt——而不是敲一个看起来合理的值。这条写成规则是因为它被违反过:最早的八条记录填的是 12:00、12:01……14:00 这种编造值,单调递增检查全过(编造的递增数字确实在递增),直到一个真实时间戳排在编造值后面,结算直接死锁。现在校验器会拒绝任何未来时间——那是「这个值是敲出来的」唯一能被机器识别的证据。整个更正过程写在账本文件头里。
A timestamp must be an observed event time — the issue's createdAt, the PR's mergedAt — not a plausible-looking value someone typed. This is a rule because it was broken: the first eight entries were filled in with tidy invented times, 12:00, 12:01, … 14:00. Monotonicity passed, because invented increasing numbers do increase. It only surfaced when a real timestamp arrived behind an invented one and settlement deadlocked. The verifier now rejects any future-dated entry — the one machine-detectable proof that a time was typed rather than observed. The correction is documented in the ledger's header.
一条局限值得直说:这套检查抓得到过期的快照和被编辑的历史,但抓不到在同一个提交里既改历史又重新生成快照的人。能抓住那种情况的是「只追加」这条规则和一双读 diff 的眼睛。CI 收窄了缺口,没有把它堵死。 One limit worth stating plainly: this catches a stale snapshot and an edited history, but not someone who edits the history and regenerates the snapshot in the same commit. What catches that is the append-only rule and a human reading the diff. CI narrows the gap; it does not close it.
这四类东西都存在,也都比这个项目成熟。它们不合用的原因各不相同,而且都是结构性的,不是「做得还不够好」。 All four of these exist and all four are more mature than this project. Each is a bad fit for a different, structural reason — not for want of polish.
| 方案Option | 为什么不合用Why it does not fit |
|---|---|
| 现金悬赏平台Cash bounty platforms | 结构上要求 issue 和仓库是公开的。你的私有业务代码从第一步就进不去,钱多钱少无关。Structurally require the issue and the repository to be public. Your private business code cannot get past step one, regardless of the money involved. |
| 外包 / 自由职业平台Freelance marketplaces | 能处理私有代码,代价是签 NDA 加交出完整仓库访问权。对一个半小时的活来说,走流程的摩擦比活本身还大。They handle private code, at the price of an NDA plus full repository access. For a ninety-minute task the process costs more than the task. |
| 额度池 / 账号合租Quota pools and shared seats | 共享凭证或代为路由请求,明确违反条款。这正是本项目开头第一段就砍掉的方案。Sharing credentials or routing requests on someone's behalf is explicitly prohibited. This is the design this project discarded in its first paragraph. |
| 时间银行 / 通用互助Time banks and generic mutual aid | 换的是小时数,完全不碰「我没法让你看我的代码」这个具体障碍——而那恰好是唯一真正卡住人的地方。They exchange hours and never touch the specific obstacle — "I cannot let you see my code" — which happens to be the only thing actually blocking people. |
所以剩下的空位很窄:私有代码 + 小任务 + 不涉及现金 + 不共享访问权。这个项目就想填这一格,别的不碰。 Which leaves a narrow gap: private code, small tasks, no cash, no shared access. That single cell is what this project is trying to fill, and nothing else.
项目处在 Phase 0:手工跑几个真任务,看看到底有没有人来。第一批任务发布 3 小时内收到第一个 PR。 The project is in Phase 0: run a few real tasks by hand and find out whether anyone shows up. The first batch got its first pull request within three hours.
五个任务全部完成,两位交付者,零返工。其中那个 P1 任务的交付者只看得到接口和测试,看不到任何业务代码,实现是正确的,九个验收测试全过,而且没有削弱任何一条测试。这是整个项目最关键的假设,它成立了。 All five tasks delivered, by two people, with no rework. On the P1 task the person could see only interfaces and tests — no business code at all — and got it right: nine acceptance tests passing, none of them weakened. That was the project's load-bearing assumption, and it held.
同一批任务也立刻引来了刷悬赏的机器人:有账号在 24 秒内「接单」四个任务然后一个 PR 都没提,有账号把同一段推销话术重复贴五遍,还有人直接来报美元价。速率限制和禁止无人值守接单这两条规则,就是为这种情况写的——现在它们要开始真的干活了。 The same batch immediately attracted bounty-farming bots: one account "claimed" four tasks in twenty-four seconds and never opened a single PR; another pasted the same pitch five times; someone quoted a price in dollars. The rate limits and the ban on unattended claiming exist for exactly this, and they are about to earn their keep.
板子上线第一天,7 号任务收到了两份各自独立、各自正确的实现,相隔两小时,九个验收测试都全过。只能付一个人。第二个人的一晚上白花了——而且他没有任何办法提前知道,因为 issue 上没有任何东西写着「有人在做」。那是板子的错,不是他的错。 On the board's first day, task #7 received two independent, independently correct implementations two hours apart. Both passed all nine acceptance tests. Only one could be paid. The second person's evening was wasted — and there was no way for them to know, because nothing on the issue said it was taken. That was the board's fault, not theirs.
所以接单现在是一个前置条件而不是一句声明:/claim 是申请,指派才是答复,issue 分配给你之前不要动手。这不是官僚流程,这是唯一挡在贡献者和白干之间的东西。
So claiming is now a precondition, not an announcement: /claim is a request, the assignment is the answer, and you do not start until the issue is assigned to you. That is not bureaucracy — it is the only thing standing between a contributor and wasted work.
板子开张 24 小时内的完整经过,全部可以从公开仓库里逐条核到:每个 issue、每条评论、每个 PR、每一笔账本记录。时间戳是 UTC。 Everything that happened in the board's first 24 hours, each of it checkable line by line in the public repository: every issue, comment, pull request, and ledger entry. Times are UTC.
mxx1111 在 11 秒内连开 #1–#5。新人的 50 TP 全部进托管。 mxx1111 opens #1–#5 within eleven seconds. All fifty newcomer points go into escrow.
第一个任务贴出 97 秒后,OpensrcLord 用 24 秒(00:08:19→00:08:43)把 /claim、/attempt 打满 #1–#5 全部五个,每条都说「正在读代码,马上提 PR」。此后一个 PR 都没有。
Ninety-seven seconds after the first task went up, OpensrcLord spends 24 seconds (00:08:19→00:08:43) firing /claim and /attempt at all five of #1–#5, each promising a PR "shortly". Not one followed.
再过 61 秒,OpensrcLord 在本仓库开了 PR #6:40 行,加了一个 .github/workflows/ci.yml,正文写「Closes #5」。但 #5 是 mdlook 的任务——这是把别人仓库的 CI 配置提进了任务板自己。没有可合并的东西,14 小时后按 not-planned 关闭。
Sixty-one seconds later OpensrcLord opens PR #6 against this repository: forty lines adding a .github/workflows/ci.yml, body reading "Closes #5". But #5 was a task about the mdlook repo — this filed another project's CI config into the task board itself. Nothing to merge; closed as not-planned fourteen hours later.
mxx1111 撤销 #2:remote-code-mobile 已停止维护,10 TP 退回。此刻还没有人提 PR——这是运气,不是规则拦住的(见 07:38)。 mxx1111 withdraws #2: remote-code-mobile is unmaintained, 10 TP refunded. No pull request existed yet — that was luck, not a rule (see 07:38).
chfr19820610-cell 把同一段「我有丰富经验,请把这个悬赏指给我」在 #1、#3、#4 上每 5 分钟重发一轮,共 12 条。之后在 #5、#7 又补了 3 条,全天合计 15 条,零交付。这不是热情,是脚本。 chfr19820610-cell re-pastes the same "I have strong experience, please assign me this bounty" across #1, #3 and #4 every five minutes — twelve comments. Three more follow on #5 and #7, fifteen for the day, zero deliveries. Not enthusiasm; a script.
ghzhost 在 mdlook 提交 PR #17(任务 #5):lint、类型检查、构建、dependabot 检查。第一个真实交付,距发单 2 小时 48 分。 ghzhost opens PR #17 on mdlook (task #5): lint, type-check, build, dependabot checks. The first real delivery, 2 h 48 m after posting.
manav8498 提交 Homelab PR #1(任务 #1),201 行、4 个文件。他全程没在 issue 里说过一句话——fork、写完、提交,是唯一一个不靠评论沟通完成交付的人。 manav8498 opens Homelab PR #1 (task #1), 201 lines across four files. He never commented on the issue at all — fork, build, deliver. The only person who completed a delivery without a single word of discussion.
ghzhost 交付 #4:Homelab 的 ntfy 推送渠道。 ghzhost delivers #4: the ntfy notification channel on Homelab.
Rithikmahadev12 在 #5 上报价:「My estimate for this work is $10 USD… Please confirm that this matches your expectations before I begin.」触碰红线 3——这里不出现货币定价。无下文。 Rithikmahadev12 quotes on #5: "My estimate for this work is $10 USD… Please confirm that this matches your expectations before I begin." Red line 3 — nothing here is priced in money. It goes no further.
ghzhost 交付 #3:platform-limits 过期检查 CLI + 定时 CI 告警。 ghzhost delivers #3: the platform-limits staleness CLI plus scheduled CI alerting.
mxx1111 补发 #7(Express 错误中间件泄露内部错误文本),托管 10 TP。 mxx1111 posts #7 (an Express error handler leaking internal messages), escrowing 10 TP.
4 分钟后,ghzhost 对 #7 发出 /done,附 task-express-error-handler PR #1,带逐行审阅声明。九个验收测试全过。
Four minutes later ghzhost posts /done on #7 with task-express-error-handler PR #1 and the attestation. All nine acceptance tests pass.
ghzhost 完成 #2 的全部验收标准,在 remote-code-mobile 上开了 PR #6——但那个任务 7 小时 18 分钟前就撤销了,TP 早已退回。一晚上,白干。 ghzhost meets every acceptance criterion of #2 and opens PR #6 on remote-code-mobile — the task had been withdrawn 7 h 18 m earlier and its points already refunded. An evening, spent for nothing.
davidmoserai 对 #7 发出 /done,实现同样正确,比 ghzhost 晚 2 小时 03 分。只能付一个人,PR 未合并即关闭。
davidmoserai posts /done on #7 — also correct, 2 h 03 m behind ghzhost. Only one could be paid; the PR is closed unmerged.
逐条核对验收标准后,mxx1111 在 54 分钟里结清五笔(账本 seq 9–13,时间取自 ledger.jsonl):#7→ghzhost、#5→ghzhost、#4→ghzhost、#1→manav8498、#3→ghzhost,各 10 TP。
Acceptance criteria checked line by line, then mxx1111 settles all five in fifty-four minutes (ledger seq 9–13, times from ledger.jsonl): #7→ghzhost, #5→ghzhost, #4→ghzhost, #1→manav8498, #3→ghzhost, 10 TP each.
认领规则宣布生效并写进 GOVERNANCE.md:指派之前不要动手。00:08 的五连抢和 02:18 的 12 条重发,从这一刻起才算违规——在此之前板子上没有任何东西说得清「这个有人在做」。 The claim rule takes effect and goes into GOVERNANCE.md: do not start before the issue is assigned to you. The five-claim burst at 00:08 and the twelve re-posts at 02:18 only count as violations from here on — before this, nothing on the board could say "this one is taken".
macakii327-prog 提交 wechat-mp-writer-skill PR #3:210 行、4 个文件,完整解决 #3。10 分钟后 #3 结算给了 ghzhost。他没接过单也没评论过,规则上拿不到 TP——但规则公布于 34 分钟前,他不可能看到。第二个白干的人,而且三小时没收到任何回应。 macakii327-prog opens wechat-mp-writer-skill PR #3: 210 lines across four files, a complete answer to #3. Ten minutes later #3 settles to ghzhost. He never claimed and never commented, so under the rules he gets nothing — but the rule had been posted thirty-four minutes earlier and he could not have seen it. The second wasted evening, and three hours of silence before anyone replied.
收尾:#1 补关(结算时忘了关)、PR #6 按 not-planned 关闭、#8 开出——直接问 ghzhost 和 manav8498 当初为什么接单。这是 Phase 0 三个问题里唯一还没有答案的一个。 Cleanup: #1 closed retroactively (forgotten at settlement), PR #6 closed as not-planned, and #8 opened — asking ghzhost and manav8498 outright why they took the tasks. It is the one Phase 0 question still without an answer.
24 小时里:5 个任务结算、50 TP 花出去、2 个人拿到钱、2 个人白干、1 个人差点白干、3 个账号只留了字。板子转起来了,规则全部是被撞出来的——这正是 Phase 0 想要的结果,代价是两个陌生人的晚上。 In 24 hours: five tasks settled, fifty points spent, two people paid, two people working for nothing, one person almost working for nothing, three accounts that only left words. The board is turning and every rule on it was written by a collision — which is exactly what Phase 0 was for, at a cost of two strangers' evenings.
余额就是 npm run ledger 重算出来的那个数,不是维护者填的表格。交付、白干、只留字——三种参与方式都列出来,因为后两种也是板子真实运转的一部分。
The balances are exactly what npm run ledger recomputes — not a table the maintainer fills in. Delivered, wasted, words-only: all three ways of showing up are listed, because the latter two are part of the board actually running.
| ## | 账号Account | 任务Tasks | TP | 状态Standing |
|---|---|---|---|---|
| 1 | @ghzhost | #5 · #4 · #3 · #7 | 60 | 交付 ×4另有一次白干(#2,任务撤销后才交付)delivered ×4plus one wasted run (#2, after withdrawal) |
| 2 | @manav8498 | #1 | 10 | 交付 ×1delivered ×1 |
| 3 | @rafaio1 | — | 10 | 参与者participant |
| 4 | @mxx1111 | 发布者 · 5 单poster · 5 tasks | 0 | 发单者50 TP 托管支出,全部结算给接单方poster50 TP of escrow spent, all settled to workers |
| 账号Account | 动作Moved | TP | 结果Outcome |
|---|---|---|---|
| @OpensrcLord | 24 秒连抢 5 单 + 1 个提错仓库的 PR5 claims in 24 s + 1 PR to the wrong repo | — | 只留字零交付,PR #6 按 not-planned 关闭wordszero deliveries, PR #6 closed as not-planned |
| @chfr19820610-cell | 15 条同文案评论15 identical comments | — | 只留字零交付,已折叠wordszero deliveries, minimized |
| @davidmoserai | 交付 #7,晚 2h03mdelivered #7, 2 h 03 m late | — | 差点白干先到先得,PR 未合并narrow missfirst to deliver wins, PR unmerged |
| @macakii327-prog | 交付 #3,210 行,晚 10 分钟delivered #3, 210 lines, 10 min late | — | 白干从未认领,规则 34 分钟前才公布wastednever claimed; the rule was 34 min old |
| @Rithikmahadev12 | 报价 $10 USDquoted $10 USD | — | 只留字触碰红线 3,无下文wordsred line 3, no further movement |
合计:发放 220 TP,结算 70 TP,托管中 140(3 个开放任务)。账本 27 条记录,9 条不变量全过。发放额从 50 涨到 100,是维护者为给板子供资发放的一笔——规则改动与全过程都公开记录,那笔钱当天全部进了托管,维护者余额仍是 0。 Total: 220 TP issued, 70 TP settled, 140 in escrow across 3 open tasks. 27 ledger entries, all nine invariants holding. Issuance rose from 50 to 100 because the maintainer funded the board — the rule change and the whole of it are on the record, all of it reached escrow the same day, and the maintainer balance is still zero.
sparepack 本身是 0.1.x,测试很密(80 个,含一个塞满凭证和客户数据的端到端仓库),但真实用户还很少。开发过程中被自己的测试抓到过两个真实泄露,第三个存在的概率不低。请把人工复核当成保护你的那一层,而不是工具。 sparepack is 0.1.x. The test suite is thorough — 80 tests, including an end-to-end run against a repo seeded with credentials and customer records — but few people have used it on their own code yet. Two real leaks were caught by those tests during development; the odds of a third are not small. Treat the manifest review as the thing keeping you safe, not the tool.
行。sparepack 是独立的 npm 包,MIT 协议,跟任务板零耦合,也不会往任何地方上传东西。想让人帮你改代码又不想交出整个代码库——这件事本身不需要一个社区。 Yes. sparepack is a standalone npm package under MIT, with no coupling to the board and no network calls. You do not need a community to want help with your code without handing over the codebase.
不能,而且永远不会能。不可转让、不可交易、不可提现、不是证券也不是货币。一旦可转让,立刻会出现拿现金买积分的灰市,这个项目的性质当场变成无监管的劳务撮合。所以它不是一句政策,是账本 schema 里压根没有那个交易类型。 No, and never. Not transferable, not tradable, not redeemable, not a security and not a currency. The moment they were transferable a grey market in points would appear and this would become unregulated labour brokerage. So it is not a policy — the transaction type simply does not exist in the ledger schema.
能,而且这是刻意设计的。审别人的交付、复核别人的脱敏产出、替别人写验收测试、当争议仲裁——四类任务都不烧任何 AI 额度,照样赚分。原始设计里有个死锁:最缺积分的人恰恰是最重度、最没余力赚积分的人,这条通道就是为了解开它。 Yes, and that is deliberate. Reviewing deliveries, auditing someone's redaction output, writing acceptance tests, arbitrating disputes — four task types that burn no AI quota and still earn points. The original design had a deadlock: the people who most need points are the heavy users least able to earn them. This channel exists to break it.
PR 提在你自己的仓库里,按你仓库的 license 走。这个项目从头到尾不碰、不托管、不中转你的代码——任务元数据、账本和信誉记录在公开仓库里,代码只在你和接单者的仓库之间流转。这一条同时也大幅削减了本项目的法律责任面。 The PR lands in your repository under your repository's licence. This project never touches, hosts, or relays your code — task metadata, the ledger, and reputation live in the public repo; the code moves only between your repo and the worker's. That also keeps this project's liability surface small.
交付的是产出不是访问权。用自己的订阅为别人干活并交付成果,就是普通的自由职业,消费者条款并不禁止商业用途。界线就在这里,五条红线全部围绕它。 What is delivered is output, not access. Using your own subscription to do work for someone and handing over the result is ordinary freelancing; the Consumer Terms do not prohibit commercial use. That is the line, and all five red lines sit around it.
但这是一个由开发者而非律师运营的项目。你的账号由你自己负责,用雇主提供的 seat 的话先问过雇主——很多企业协议有额外限制。 But this is run by developers, not lawyers. You are responsible for your own account, and if you are on an employer-provided seat, ask them first — many enterprise agreements add their own restrictions.
你不知道,我也不知道。词法扫描抓不到含义。所以工具的设计不是「扫干净了就发」,而是写盘前强制你看一遍完整文件清单并逐字敲确认。工具的作用是把那次复核变得可能——列清楚发了哪些文件、多大、哪些函数被丢弃了——而不是替你复核。另外 sparepack verify 会从磁盘完全重新推导一遍,不信任任何清单,因为和被检查对象共享假设的检查等于没检查。
You do not, and neither do I. Lexical scanning cannot catch meaning. So the tool is not built around "scan clean, then ship" — it is built around forcing you to read the full file list and type a confirmation before anything is written. Its job is to make that review possible (what shipped, how big, which functions were dropped), not to do it for you. Separately, sparepack verify re-derives everything from disk and trusts no manifest, because a check that shares assumptions with the thing it checks catches nothing.
不能,这正是红线 4:由活人读任务、决定接、干活、在提交前亲自审阅。让 agent 盯着任务流提醒你完全可以——「有个 M 档的 TypeScript 任务,要看看吗」是个很好的 cron 任务。但 /claim 那一下必须是你按的,交付前那一遍必须是你看的。
No — that is red line 4 verbatim: a human reads the task, decides to take it, does the work, and reviews it before submitting. Having an agent watch the feed and notify you is completely fine — "there's an M-tier TypeScript task, want a look?" is a great cron job. But the /claim has to be yours, and so does the review before delivery.
机制上也刷不动:/claim 只是申请,维护者指派了才算数,速率限制是同时 2 个、每周 5 个。被识别出的无人值守接单,按治理规则是接单作废加停用 30 天。想让 agent 全自动接活赚钱的话,有专为 agent 设计的悬赏市场,那是另一个前提下的另一种东西——这个板子是给人用的。
Mechanically it does not work either: /claim is a request, only the maintainer's assignment counts, and the limits are two concurrent, five a week. Unattended claiming, when identified, voids the claims and suspends the account for 30 days. If you want an agent earning autonomously, bounty markets built for agents exist — that is a different thing built on the opposite premise. This board is for people.
建了网站就得托管代码、存数据、扛住对应的责任面和攻击面,而这些恰好都是这个项目最不想承担的。跑在 GitHub 上意味着:账本是一个公开仓库里的文本文件,谁都能 clone 下来自己重算;身份是真实的 GitHub 账号,注册天数和公开贡献可查;信誉是别人仓库里真实合并的 PR,不是我发的一枚徽章。这些性质是买不来的。 A web app would mean hosting code, storing data, and carrying the liability and attack surface that comes with both — precisely what this project wants to avoid. Running on GitHub means the ledger is a text file in a public repo anyone can clone and recompute; identity is a real GitHub account with a checkable age and contribution history; and reputation is merged PRs in other people's repositories rather than a badge I issued. None of that can be bought.
很少。5 个任务、2 位交付者、总共发出去 50 TP。Phase 0 存在的意义就是先回答「到底有没有人来」这个问题,而不是假装已经有社区了。如果你现在来,你会是很前面的那几个人之一,好处和坏处都很明显。 Very few. Five tasks, two people delivering, fifty points issued in total. Phase 0 exists to answer whether anyone shows up at all, not to pretend a community already exists. If you turn up now you are one of the first handful, with everything good and bad that implies.
sparepack 不依赖任务板。想让人帮你改代码又不想交出整个代码库,这件事本身不需要一个社区。 sparepack does not depend on the task board. You do not need a community to want help with your code without handing over the codebase.
npx sparepack init
用 AI agent 开发?把下面这句原样粘给它: Working through an AI agent? Paste it this line, verbatim:
Read https://github.com/mxx1111/sparepack#readme, then run `npx sparepack init` in my repo and help me fill sparepack.yaml. The final `publish` confirmation at pack time is mine to type, never yours.
最后半句不是客气话。写盘前的人工确认是这个工具的安全模型本身,一个替你敲确认的 agent 等于把它整个拆掉。 The last clause is not politeness. The pre-write confirmation is the tool's entire safety model, and an agent that types it for you has dismantled it.
需要 Node 22 或更新版本,没有别的前置条件。如果你发现它处理错了某个场景,开个 issue——现阶段这是对这个项目最有用的一件事。 Node 22 or newer, no other prerequisites. If you find a case it gets wrong, open an issue — right now that is the single most useful thing you can do with it.