From a2db2b4ab0a0b06d4c775bdd6058b15f41377b8c Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Wed, 14 Oct 2026 12:10:43 -0400 Subject: [PATCH 01/19] Thinking about network societies. --- TODO.md | 2 + .../credible-solution/network-societies.md | 104 ++++++++---------- .../why-its-better/what-its-better-for.md | 93 +++++++++++++++- docs/end-user/tldr-for-llms.md | 8 ++ 4 files changed, 142 insertions(+), 65 deletions(-) diff --git a/TODO.md b/TODO.md index b113bdb7..f41b573b 100644 --- a/TODO.md +++ b/TODO.md @@ -16,6 +16,8 @@ Getting **testnet to a two-person shared lab** is also a standing plan, not a pi ---- +- We should have a UI for making it easy for a user to follow projects aligned with *similar* statements to the ones he prefers, and then if he wants to he can do the alignment-attestations to make those projects also show up on his own preferred cause board. + - **(Ask)** Verify work-request contribution/refund links against actual chain events, and verify response providers and work items against the project's beneficiary/registry before presenting verified payment or provider authority. The first slice displays reported contribution/refund amounts and authenticates acceptance only against the provider named by the response author. See [work requests](specs/tech/subsystems/work-requests/README.md). - **(Ask)** Complete work-request UI revisions and withdrawals, version/history inspection for offers and responses, and a browser-tested playground demonstration. SDK versioned publication actions exist; the current UI primarily creates records. diff --git a/docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md b/docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md index 7df18351..4099143c 100644 --- a/docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md +++ b/docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md @@ -1,30 +1,42 @@ # Something like a network society, without the society This page does two things. + - It describes the vision: a population of aligned people who can find each other, meet, keep a memory, and fund concrete work, without first agreeing to join one group. + - And it lists jobs that population might want to fund, as a starting menu for anyone trying to build something like this. -It describes the vision: a population of aligned people who can find each other, meet, keep a memory, and fund concrete work, without first agreeing to join one group. And it lists jobs that population might want to fund, as a starting menu for anyone trying to build something like this. +Balaji Srinivasan's network state starts from a real observation: a lot of people who want the same concrete thing (a sugar-free food environment, medicine outside the FDA's menu, resistance to wokeness) cannot get it from the institutions they already live under. The book describes a "startup society" as having one moral innovation, one founder, one commandment, a community, in-person gatherings, some sort of crowdfunding capability, and eventually a census large enough to bargain with existing states. It sorta sounds like what Balaji was imagining was a million-member Discord with a treasury; maybe that's not actually what he had in mind, but either way I want to invent a more-decoupled way of achieving the same effect. -Balaji Srinivasan's network state starts from a real observation: a lot of people who want the same concrete thing (a sugar-free food environment, medicine outside the FDA's menu, a school that teaches a particular curriculum) cannot get it from the institutions they already live under. The path I pictured while reading the book was a startup society: one moral innovation, one founder, one commandment, a shared community, a shared treasury, in-person gatherings, and eventually a census large enough to bargain with existing states. That picture may be more specific than what he is actually arguing. The rest of this page is about that picture, and about what to keep from it. +The part worth keeping is the observation, the physical layer, and the point that a movement of aligned people needs a way to fund things together. A big Discord with a treasury achieves that funding capability, but what it gets wrong is the premise that the funding has to sit in one pot. The same effect can come from a more decentralized mechanism: many statements, many boards, many assurance contracts, and [organic coalitions](../why-its-better/organic-coalitions.md) that show up where people agree on a concrete outcome and nowhere else. The mechanism we're building is more complicated than a single shared treasury; the hope is that the extra complexity is worth it, because it sharply reduces how often anyone has to say "now let's all agree to join this one group." -The part worth keeping is the observation, the physical layer, and the point that a movement of aligned people needs a way to fund things together. A big Discord with a treasury gets that last part right. What it gets wrong is the premise that the funding has to sit in one pot. The same effect can come from a more decentralized mechanism: many statements, many boards, many assurance contracts, and [organic coalitions](../why-its-better/organic-coalitions.md) that show up where people agree on a concrete outcome and nowhere else. The mechanism is more complicated than a treasury. The hope is that the extra complexity is worth it, because it sharply reduces how often anyone has to say "now let's all agree to join this one group." +People with a shared preference still need: + - a "front door" (e.g. a website describing the ideas; there can be more than one of these) + - a way to find each other + - gatherings at a few scales + - a memory + - people who keep the local nodes alive + - and a small interface to the mainstream world (e.g. landlords, venues, and insurers). -People with a shared preference still need a front door, a way to find each other, gatherings at a few scales, a memory, a way to trust or drop providers, people who keep the local nodes alive, and a small interface to landlords, venues, and insurers. The purpose changes the directory and the events. Those jobs stay the same. [Easier than politics](../so-what/easier-than-politics.md) already says why they should not be stuffed into a million-member group with a constitution and a membership boundary: that group is a new government, with the usual fight over who holds the pot. +The base-level work of the "network society" will be different from society to society, but the above list of meta-level jobs ("meta-level" in the sense that this is about organizing and maintaining the society, not about doing the actual work that the society is meant to accomplish) stays the same. -Two things follow. +If all those meta-level jobs get done, they ought to produce something that *behaves* like a functioning network society. Nobody ratifies it, and nobody can capture it by taking the treasury, because there isn't one. -A playbook is possible. The same list of jobs can be written as example projects. Funded together, they produce something that *behaves* like a functioning network society. Nobody ratifies it, and nobody can capture it by taking the treasury, because there isn't one. - -And a lot of the central roles in that startup-society picture shrink or split. They do not disappear. Someone still writes a good statement. Someone still draws a map. The difference is that a second statement and a second map are normal, not a schism. +A lot of the central roles in the "Discord with a treasury" startup-society picture shrink or split, but they do not disappear. Someone still writes a good statement. Someone still draws a map. The difference is that a second statement and a second map are normal and fine, not a schism. ## Front door A stranger still needs somewhere to start. They do not need *the* door. -**Canon.** The one-commandment picture wants a single text, revised on purpose so the loudest chapter does not silently replace it. Commonality wants many texts. Anyone can write a statement and center a cause board on the projects aligned with it. Leaders who can write a statement other people actually sign are still valuable. Writing it is usually not its own funded project. It is closer to a one-time task — not exactly once, but close — that a cause-founder does alongside the rest of the work of getting a preference started. What drops out is the requirement that everyone else coordinate on that one text. A chapter that rewrites the wording in its own words has not broken the society. There was no single society to break. Where two wordings still point at the same project, the implication graph can put that project on both boards. See [organic coalitions](../why-its-better/organic-coalitions.md). +The one-commandment picture wants a single statement of the vision; Commonality is fine with having many such statements. It's no big deal if people rewrite in their own words, or with a slightly different idea or slightly different emphasis or whatever. The main purposes of the statements are (a) getting people to sign them on Tally so that we can get a sense of how many people agree, and (b) creating cause boards of crowdfundable projects aligned with that statement. Having multiple statements isn't a problem for that: users can sign whichever statements they like, and projects can be attested to be aligned with multiple statements (and sometimes the implication system will even recognize implied-alignment without anyone needing to explicitly attest). (We could even have a UI for making it easy for a user to follow projects aligned with *similar* statements to the ones he prefers, and then if he wants to he can do the alignment-attestations to make those projects also show up on his own preferred cause board.) + +It's still valuable to have leaders who can write a statement other people actually sign; even better if it's a statement that'll be appealing to an [organic coalition](../why-its-better/organic-coalitions.md) of multiple different kinds of people. I don't know whether this is closer to being a one-time startup task (in which case it's probably not time-consuming enough to be worth asking for funding independently) or whether it'll need to be an ongoing task (watching for changes within the ecosystem, looking for alliance opportunities, splitting a statement into pieces to make it more useful to people who agree with some of it but not all of it, updating statements to match new contexts, etc.). Either way, this is a type of meta-work that needs to be done as part of starting/running the society. And maybe it's hard enough to be something that the society would want to fund explicitly. + +The front-door site probably wants other stuff on it too, so that it's all in one place: the map of chapters, the next events, good explainers for the ideas, etc. It would probably be good if those were separable jobs. But "maintaining the front-door site" is itself a job. + +## Mapping local chapters -**The site.** The one-front-door picture wants the map of chapters, the next events, and the canon, in one place. Here a chapter publishes its own existence if it wants to be found: a place, a time, a statement it cares about. Anyone can publish a map over the chapters that opted in. Tools can build directories off those publications. The job remains — a map nobody maintains is not a map — but "the" map is a product someone can fund, not an office someone has to hold. +A local chapter can be as simple as a small group with a room. This is one level at which "membership" happens, but it doesn't need to be particularly formal; the people simply decide who they want to invite back, in the ordinary everyday way that local friend/acquaintance groups work in normal life. -**Onboarding.** The path is from "I read a post" to "I know which statement I am willing to sign, which projects that puts in front of me, and who meets near me." There is no society-wide committee that rejects people for wanting the aesthetic. Filtering happens in two smaller places. A cause board only shows projects aligned with what you signed. A local chapter, which is just a small group with a room, can decide who it invites back. That second filter is ordinary hosting, not a membership roll. +If a chapter is open to being found by strangers, it can publish its own existence (a place, a time, a statement). This might let general-purpose code (written by us) find and display a list of chapters that have opted in. Or maybe (to avoid spam) a hybrid: we add to the Commonality website a way for a person acting as a "map organizer" to publish a list of approved local chapters, but our site also checks to make sure that each of the local chapters has explicitly digitally-signed a message saying that they consent to being included in this list. Either way, the point is that there's this job that needs to be done, and it'd be good if the society had an easy way to fund that work. ## Finding each other @@ -106,51 +118,25 @@ Gatherings, houses, and clinics still sit inside a country. **Crisis logistics, and helping one person.** A person is stranded, doxxed, or sick in a city where a parallel service exists. The public good is the response path: who to call, what is already arranged. The transfer of money to the person in trouble is not a public good. It can still be something aligned people want to crowdfund together — the "network union" half of the picture, people sticking with each other. That transfer fits an ordinary unconditional gift better than an assurance contract, because a partial amount already helps. -## What to fund - -| Job | What the project actually is | How to fund it | -| --- | --- | --- | -| A host kit, a one-time map, a legal-wrapper kit | A public artifact. Partial funding publishes nothing useful | Assurance contract | -| A city's dinners for one quarter, a regional weekend, one annual event, one pop-up week | Hosting an encounter, budgeted with its own insurance and its own lessee | Assurance contract. The gathering happens only if the threshold is met | -| An audit of a directory, a count of which chapters met, a check on a provider's claims | Evidence, published by someone other than the person being checked | Assurance contract. An unchecked claim is not worth buying | -| A published set of statements, and the deduped headcount over that set | Choosing which statements count as "us," then publishing the union once identities can be deduped | Assurance contract. The artifact is the set and the count | -| A month of introductions in one city, a month on call as the local host, mediation inside one chapter | A named person's availability for a bounded period, with a public log of what was done | Assurance contract. Same shape as a month of software maintenance | -| Help for one stranded, doxxed, or sick person | A private transfer. Aligned people sticking together, not a good everyone can use | Ordinary unconditional gifts. Partial funding already helps | -| A statement people can sign | Wording a cause-founder produces while doing the rest of the startup work | Usually not its own project | -| "People should feel welcomed," a membership committee, a society spokesperson, a shared treasury | Not a project | There is nothing to deliver, or delivering it rebuilds the organization this setup exists to avoid | - -## A starter playbook - -These are examples for one preference in one city. Swap the purpose and the city. None of the funded items requires the others to exist first, which is the property that makes this a protocol rather than an organization. The lumpy public goods are assurance contracts. The standing local roles are repeating monthly or quarterly contracts. The mutual-aid item is an ordinary gift. - -1. **Write the statement,** as part of founding the rest of this, not as a project of its own. Specific enough that a project can align with it. Not a manifesto that settles every neighboring question. -2. **Publish the host kit.** First ten people, first venue, first three months, when to stop calling it a chapter. -3. **Host this city for this quarter.** Room, rhythm, facilitation, a published note that the meetings happened. -4. **Be the introducer for this city for this month.** A public count of introductions. No dossier on the people introduced. -5. **Publish a map** of gatherings and providers whose organizers opted in. Say what was left out on purpose. -6. **Audit that map.** An independent pass over a stated sample. Publish which listings answered and which did not. -7. **Run one regional weekend,** with ticket threshold, housing, program, and insurance inside the same contract. -8. **Publish the one-event legal kit** used for that weekend, so the next city does not hire the same lawyer from scratch. -9. **Hand off a role.** One contract whose deliverable is that a named next host, editor, or event lead has everything the last one had. -10. **Publish a headcount set.** Name the statements that count as this cluster, and publish the deduped union once unique-human ids exist. -11. **Measure the purpose,** separately. Whatever the preference claims to change in the world. That project cites the gatherings and the directory. It does not define who is a member. -12. **Help one person in trouble,** when the cluster wants to, as ordinary gifts toward a named need. Not an assurance contract. - -Items 3 through 6 are the ones a treasury-Discord usually extracts from unpaid status. They are also the ones that decide whether two people in the same city ever meet. The purpose-specific meat — the clinic, the school, the sugar program — hangs off that, and can be funded by anyone whose statements reach it, including people who would never join a society together. - -## Jobs worth funding - -Concrete projects one city can start from. Each line is something a person could pledge to. Statement-writing is omitted on purpose: a founder usually does that alongside the rest of the work, rather than as its own project. - -- Host kit for starting a chapter in a new city. A duplicated doc is enough. -- This city's dinners for one quarter, including the room and a published note that they happened. Luma or Meetup for the room; the note is the record. -- Introducer on call for this city for one month, with a public count of introductions. A calendar link and a count sheet. No dossier of who met whom. -- Map of opted-in gatherings and providers, with an explicit "left out on purpose" section. A published spreadsheet, or uMap if it needs pins. -- Independent audit of that map over a stated sample. Resample the same spreadsheet. -- One regional weekend: program, tickets, housing, and insurance in one contract. Luma or Meetup for tickets and housing. -- Legal kit for running a weekend like that one: incorporation and insurance, reusable by the next city. A duplicated doc. -- Handoff of one named role (host, map editor, or event lead) to a named successor. The doc, plus a shared password vault. -- A published set of statements for "how many of us," plus the deduped union count. A cause board already computes that union over its planks. -- A liveness note: which of these cities actually met this month. Collect the "we met" notes. -- An outcome measurement for the preference itself (the sugar metric, the case series, the school result), citing the gatherings and the directory. Use whatever instrument fits — a survey, a lab series — and cite it. -- One person's emergency costs, funded as ordinary gifts, with the response path (who to call, what is already arranged) funded separately as a public artifact. An ordinary gift page, not an assurance contract. +## Kinds of activity that could be funded + +This isn't meant to be an exhaustive list, but here's a list: + - Writing statements, forming bridges. + - Creating social-media content or manifesto/explainer pages. + - Vouching for projects. + - Directing funding. + - Writing/maintaining/contributing-to open-source software that the cause could use. + - Doing research (scientific or other) that would further the cause. + - Helping people find a local chapter. + - Helping maintain the wider list of chapters. + - Sticking up for each other: "insurance", or just support. (e.g. Help for one stranded, doxxed, or sick person.) + - Organizing local meetups. + - Organizing larger meetups. + - Organizing enclaves so people can live near each other. + - Starting experiments (e.g. "FDA-free zone"), once you've actually got enough clout that it may be possible to carve out a place within a jurisdiction that might be amenable to that. + +## How this fits in with Commonality in general + +Note that a lot of these jobs are "public goods" within the network society. Maintaining the website, writing content, working on relevant open-source software, maintaining maps of chapters, etc., are all (to some degree) jobs that benefit everyone in the society but that everybody wants someone else to pay for. They're not exactly public goods in the same way that a public park benefits basically *everyone*; they're scoped to this specific "movement" of people. But they're still kinda got that non-excludable, non-rivalrous nature. So it's useful to have mechanisms like Commonality's assurance-contracts and retroactive-funding and so on, to get them funded. + +The Tally stuff is a good fit too: we can count up how many people have signed any of these N statements, to show how much support there is. See [durable participation](/specs/product/durable-participation.md). And again, note that this doesn't require the "network society" to be made of a single Discord whose membership list we can count. diff --git a/docs/end-user/commonality/vision-and-strategy/why-its-better/what-its-better-for.md b/docs/end-user/commonality/vision-and-strategy/why-its-better/what-its-better-for.md index 2a9a68ab..0a5acc3d 100644 --- a/docs/end-user/commonality/vision-and-strategy/why-its-better/what-its-better-for.md +++ b/docs/end-user/commonality/vision-and-strategy/why-its-better/what-its-better-for.md @@ -1,16 +1,96 @@ # What kinds of public goods is Commonality better for? +The early uses we have in mind are people building something like a +[network society](../credible-solution/network-societies.md), and people finding +[specific bridges across divides](./organic-coalitions.md). Both need a way to +discover shared preferences and fund work together without first agreeing to +join one organization or endorse a whole platform. + +## Where we'd start + +### Shared infrastructure for an overlapping population + +Imagine people who want a particular kind of education, food environment, or +community life. They need ways to find each other, meet locally, share knowledge, +and get useful work done. Maintaining a chapter map, checking a provider +directory, writing a host kit, or keeping a public record of experiments all +benefit people beyond whoever pays for them. These are public goods for a +particular population, even if most of the world has no interest in them. + +The network-society use case is funding those jobs separately. Someone can back +a directory without endorsing every chapter, or fund shared software without +accepting a founder's whole vision. Multiple front doors, statements, and +organizers can serve overlapping populations. Each project has people responsible +for delivering it; the population doesn't need a single treasury or leadership +team before useful work can begin. + +Some activities in that picture already have a straightforward way to pay for +themselves: tickets can fund an event, and fees can fund a private service. +Commonality's strongest case is the shared infrastructure that those transactions +leave underfunded. The [network-society page](../credible-solution/network-societies.md) +describes the wider menu of jobs. + +### Many specific bridges, each with its own supporters + +Imagine two camps that disagree about education but might both support an +independent test of a disputed school practice. An organizer proposes that +specific shared undertaking, with wording each side could accept for its own +reasons. People can support it while continuing to disagree about much else. + +That is the useful unit for early coalition-building: a particular bridge, with +identifiable audiences, a concrete proposition, and work worth funding. A +bridge need not attract a majority to be useful. Its supporters might form an +intense minority, and the people who support the next bridge may be different. + +This changes how we'd approach the **Common Sense Majority** idea. A collection +of possible bridges can help people discover the ones they agree with. Requiring +agreement with a package of an organizer's preferred compromises would recreate +the bundling problem. The invitation should be: "Here are many possible places +to find common ground; which of them make sense to you?" Each bridge should +stand on its own, with its own evidence of support and fundable projects. +Supporting one does not imply supporting the others, and a count of everyone +who supports at least one is not a constituency for the whole package. + +### Civility in service of a particular bridge + +A proposed bridge needs to reach people who might accept it. That gives +[noninflammatory content funding](../../../shared/use-case-walkthroughs/noninflammatory-content.md) +a specific job: help these audiences seriously consider this proposition. +For the school-practice example, supporters could fund an explanation of each +side's concerns, a discussion of what an independent test could establish, or +responses to objections from prospective supporters. Writing, distribution, +and learning from those readers' responses are all part of the work. + +This is the early **Civility** use case: content scoped to one bridge and its +audiences. It can make a strong case while treating disagreement fairly. +Different bridges can have different writers, evaluators, and funders; they +don't need to share an editorial line on every other issue. + +The bridge starts as a hypothesis. Respectful content and favorable evaluations +do not establish that people agree, and agreement does not establish willingness +to pay. Useful evidence includes people from the intended audiences actually +endorsing the proposition, contributing money, and completing shared work. +Sometimes the result will be a narrower bridge or a clearer account of genuine +disagreement. That is useful learning too. + +These uses reinforce each other: an overlapping population needs shared +infrastructure, and it may discover opportunities to fund particular projects +with people outside it. Bridge-building and communication can themselves be +among the public goods that population wants to fund. + +## Why these uses fit + We already have governments and charities funding public goods. The world is not devoid of clean water, research, or parks. So the honest question isn't "could a public good exist without Commonality?" — obviously many do. But our existing institutions fail in characteristic ways, and Commonality has mechanisms with different strengths and weaknesses. Which kinds of public goods are *underproduced* today, why, and which of those might Commonality be good for? The primary case is not wealth redistribution. You pay because you want the thing. A pair of jeans is a private purchase: you pay, and you wear them. A park, a research result, a software release, or a blogger's next month of writing is a different shape. A whole bunch of people pay, and once it exists the people who paid and everyone else get to use it. That is a public good in the economist's sense — non-excludable, and usually non-rival — and it is where an assurance contract earns its keep. You cannot (or it would be awkward to) keep the result to the payers, and partial funding often buys nothing: the release, the study, or the month of work happens only if the total is reached. Ordinary charity is often the other shape. "We want people who can't afford them to have more food and clothing" benefits from every extra dollar, so a normal donation already does the job. Nothing stops someone from running that through Commonality. It just is not what the mechanism is for. -Building a vertical and need concrete examples rather than categories? These seven -are the *gate*; `specs/product/cause-taxonomy.md` is the -generator that turns them into a populated fundable-projects board. +The seven categories below explain the broader fit; they are not seven equally +important launch priorities. For founders turning them into concrete projects, +the [cause taxonomy](/specs/product/cause-taxonomy.md) provides a generation framework. -The gate applies to a **deliverable**, not merely a cause title. "Education" or +The test of fit applies to a **deliverable**, not merely a cause title. "Education" or "open science" might describe work an existing institution already funds well. For a proposed project, ask: *What will be delivered, who wants to pay, who benefits without paying, and who would have to say yes today?* If willing payers @@ -34,7 +114,7 @@ The real distinction is between *rent-seeking* and *self-financing*. The minorit So the honest framing isn't "passion can't outvote a majority." It's: the political system rewards minorities who can extract from the majority, and there is no good mechanism for a minority to fund its own genuinely public good out of its own pockets. The lobbying crowd wants *other people's* money; these minorities are willing to spend *their own* but are blocked by the [free-rider](../credible-solution/assurance-contracts.md) and [discovery](../credible-solution/discovery.md) problems — exactly the two problems Commonality's assurance contracts and discovery are built to solve. There's a legitimacy dividend, too: the rent-seeking version is coercive and often zero-sum (the majority pays for a minority's pet thing), while this is voluntary and self-financed. That's *why* it's underproduced — the voluntary version eats a free-rider problem the coercive version sidesteps with state power. -**2. Polarization-trapped goods (hidden majorities).** Broadly wanted, but trapped inside a culture-war bundle so the political system can't deliver them. Two mechanisms matter here, and the second is the stronger one. First, [organic-coalition discovery](./organic-coalitions.md) surfaces the concrete outcome people agree on without forcing them to share a framing. But discovery isn't enough on its own: even once a hidden majority can *see* itself, every large funder that might champion the good is itself polarized — a government is left or right, a big charity is coded one way or the other. What's missing in legacy-land is **institution-less aggregation**: a way to pool moderately-left and moderately-right money without a single unifying organization that both sides distrust. Assurance contracts are exactly that — they can take some money from left-leaning donors and some from right-leaning donors, and no one org has to own the whole thing. Retroactive funding works the same way: later donations from people on the left and right can jointly reimburse early contributors, with no need for a single big backer to cover it all. +**2. Polarization-trapped goods (specific organic coalitions).** People across a divide want a concrete outcome, but its association with a broader political package makes cooperation difficult. [Organic-coalition discovery](./organic-coalitions.md) can surface that overlap without requiring a shared framing. A hidden majority is one possible result; a smaller coalition with enough willing funders can also get useful work done. Where potential funders distrust each other's institutions, assurance contracts let them contribute to a particular undertaking without first establishing an organization to represent them all. They still need confidence in the project and its delivery. Retroactive funding can similarly let later supporters from different camps jointly reimburse early contributors, without requiring one large backer. **3. Scale-mismatched goods.** Goods that don't line up with any one jurisdiction — two faces of the same problem. The first: things *too small or specific* for government to bother with — this block's park, this town's trail. The second, its mirror image: things whose beneficiaries don't map onto any *one* jurisdiction at all — inter-town infrastructure, open-source software, internet commons, global health — so no single authority internalizes the full benefit and none has the incentive to fund the whole thing. @@ -48,7 +128,7 @@ The clean analogy: **Commonality is to public goods what startups are to private **6. Politically-disfavored / suppressible goods.** Advocacy, legal defense, contested speech — things a hostile authority actively wants to *defund*. [Censorship-resistance](../hard-to-stop/censorship-resistance.md) turns "can't" into "can." -**7. Bridging / communication goods.** Funding the spread of depolarizing, noninflammatory content across a divide. Government and charity essentially don't — and couldn't credibly — do this. This is a close cousin of #2, but distinct: #2 funds a concrete *outcome* both sides already agree on, while #7 funds the *communication that reveals or creates* that agreement. It's an input to #2 — the thing that manufactures a hidden majority where the blocker is misunderstanding rather than genuine disagreement. +**7. Bridging / communication goods.** Funding the creation and distribution of noninflammatory content that helps particular audiences consider a particular bridge. Existing organizations can do this work, but may struggle to earn trust across the divide or fund communication whose benefits extend beyond their own audience. Commonality lets interested supporters fund that work through creators and evaluators they trust. This is a close cousin of #2: #2 funds an outcome people agree on, while #7 funds communication that may reveal, develop, or test that agreement. It can also expose genuine disagreement; a hidden majority is a possibility to investigate, not an outcome the mechanism guarantees. ## What these distinctions look like as projects @@ -56,6 +136,7 @@ These are synthetic examples, not claims about existing organizations or demand: | Deliverable | Blocker | Why the mechanism matters | |---|---|---| +| A maintained chapter map and independently checked provider directory for an overlapping network | Many people use them, but no chapter wants to carry the whole cost or submit to one central organization | Supporters can fund each shared resource separately, across chapter boundaries | | Maintained releases of a shared software dependency | Its many users each benefit, but none can justify paying the full maintainer cost | The users can assure one another that enough will contribute before work begins | | Open water-quality data for a watershed crossing three towns | No town owns the full benefit | Residents can pool money across the jurisdiction line | | Preregistered replication with public results even if it fails | A grant panel must choose before the result is known | Early supporters can back the attempt; later supporters can fund demonstrated value | diff --git a/docs/end-user/tldr-for-llms.md b/docs/end-user/tldr-for-llms.md index 1052d501..c2ff4d91 100644 --- a/docs/end-user/tldr-for-llms.md +++ b/docs/end-user/tldr-for-llms.md @@ -7,6 +7,14 @@ Each entry follows the same shape: - **When a user encounters it** — UI surfaces or moments in the user's flow where this concept becomes load-bearing. - **What they might want help with** — typical assistant tasks around this concept. +## Early uses and public-good fit + +[Full page](commonality/vision-and-strategy/why-its-better/what-its-better-for.md) + +- **What it is:** Early priorities are shared infrastructure for overlapping network-society populations, specific organic coalitions, and Civility content scoped to individual bridges. The broader seven-category framework explains fit rather than equal launch priority. +- **When a user encounters it:** Choosing an initial use case, proposing a bridge, or explaining what Common Sense Majority could become. +- **What they might want help with:** Finding a concrete shared deliverable; presenting independently supportable bridges as a collection; distinguishing proposed agreement, actual endorsement, and willingness to fund work. Support for one bridge does not endorse the collection, and respectful communication does not guarantee agreement. + ## Cooperation without a shared platform [Full page](commonality/vision-and-strategy/why-its-better/cooperation-without-a-shared-platform.md) From 02015a38a36cdbcab828c918024d64a0db5cf8d9 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 10:45:01 -0400 Subject: [PATCH 02/19] Show which implying statements bring signers, pledges, and project funds. Commonality statement pages and cause boards list the bridges that account for a meaningful share of indirect support. --- .../credible-solution/network-societies.md | 2 +- .../why-its-better/what-its-better-for.md | 2 +- sdk/src/subsystems/fundingportals/queries.ts | 52 ++++-- .../components/BridgeContributions.tsx | 170 ++++++++++++++++++ .../lib/bridgeContributions.test.ts | 72 ++++++++ ui/src/commonality/lib/bridgeContributions.ts | 118 ++++++++++++ ui/src/commonality/pages/CauseDetailPage.tsx | 8 + .../commonality/pages/StatementPage.test.tsx | 4 + ui/src/commonality/pages/StatementPage.tsx | 9 + 9 files changed, 423 insertions(+), 14 deletions(-) create mode 100644 ui/src/commonality/components/BridgeContributions.tsx create mode 100644 ui/src/commonality/lib/bridgeContributions.test.ts create mode 100644 ui/src/commonality/lib/bridgeContributions.ts diff --git a/docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md b/docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md index 4099143c..f9b24ef8 100644 --- a/docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md +++ b/docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md @@ -139,4 +139,4 @@ This isn't meant to be an exhaustive list, but here's a list: Note that a lot of these jobs are "public goods" within the network society. Maintaining the website, writing content, working on relevant open-source software, maintaining maps of chapters, etc., are all (to some degree) jobs that benefit everyone in the society but that everybody wants someone else to pay for. They're not exactly public goods in the same way that a public park benefits basically *everyone*; they're scoped to this specific "movement" of people. But they're still kinda got that non-excludable, non-rivalrous nature. So it's useful to have mechanisms like Commonality's assurance-contracts and retroactive-funding and so on, to get them funded. -The Tally stuff is a good fit too: we can count up how many people have signed any of these N statements, to show how much support there is. See [durable participation](/specs/product/durable-participation.md). And again, note that this doesn't require the "network society" to be made of a single Discord whose membership list we can count. +The Tally stuff is a good fit too: we can count up how many people have signed any of these N statements, to show how much support there is. See the durable-participation spec (`specs/product/durable-participation.md`). And again, note that this doesn't require the "network society" to be made of a single Discord whose membership list we can count. diff --git a/docs/end-user/commonality/vision-and-strategy/why-its-better/what-its-better-for.md b/docs/end-user/commonality/vision-and-strategy/why-its-better/what-its-better-for.md index 0a5acc3d..2cc0916a 100644 --- a/docs/end-user/commonality/vision-and-strategy/why-its-better/what-its-better-for.md +++ b/docs/end-user/commonality/vision-and-strategy/why-its-better/what-its-better-for.md @@ -88,7 +88,7 @@ Ordinary charity is often the other shape. "We want people who can't afford them The seven categories below explain the broader fit; they are not seven equally important launch priorities. For founders turning them into concrete projects, -the [cause taxonomy](/specs/product/cause-taxonomy.md) provides a generation framework. +the cause taxonomy (`specs/product/cause-taxonomy.md`) provides a generation framework. The test of fit applies to a **deliverable**, not merely a cause title. "Education" or "open science" might describe work an existing institution already funds well. diff --git a/sdk/src/subsystems/fundingportals/queries.ts b/sdk/src/subsystems/fundingportals/queries.ts index e6d8b39b..60d9ad8f 100644 --- a/sdk/src/subsystems/fundingportals/queries.ts +++ b/sdk/src/subsystems/fundingportals/queries.ts @@ -187,6 +187,7 @@ function dedupeAlignedProjects(projects: T[]): T[] { const deduped = new Map(); @@ -196,6 +197,14 @@ function dedupeAlignedProjects(); + const projectMap = new Map(); directAlignments.forEach(a => - projectMap.set(a.subjectId.toLowerCase(), 'direct') + projectMap.set(a.subjectId.toLowerCase(), { alignmentType: 'direct', viaStatementCids: [] }) ); indirectAlignments.forEach(a => { const addr = a.subjectId.toLowerCase(); - if (!projectMap.has(addr)) { - projectMap.set(addr, 'indirect'); + const existing = projectMap.get(addr); + if (!existing) { + projectMap.set(addr, { alignmentType: 'indirect', viaStatementCids: [a.directStatementCid] }); + return; + } + if (existing.alignmentType === 'indirect' && !existing.viaStatementCids.includes(a.directStatementCid)) { + existing.viaStatementCids.push(a.directStatementCid); } }); - const alignedProjects = (await Promise.all([...projectMap.entries()].map(async ([subjectId, alignmentType]) => { + const alignedProjects = (await Promise.all([...projectMap.entries()].map(async ([subjectId, alignment]) => { const resolved = await resolveAttestedProject(machinery, subjectId); if (!resolved) return null; - return { ...resolved, alignmentType }; + return { ...resolved, ...alignment }; }))).filter((row): row is NonNullable => row !== null); if (alignedProjects.length === 0) { @@ -812,34 +828,39 @@ export async function getAllAlignedProjectsForCause( return []; } - const projectAlignmentType = new Map( - alignedProjects.map((project) => [project.projectAddress.toLowerCase(), project.alignmentType]), + const projectAlignment = new Map( + alignedProjects.map((project) => [project.projectAddress.toLowerCase(), project]), ); const snapshots = await readProjectFundingSnapshots(machinery, projectsWithCondition); const paymentTokenInfo = await Promise.all( snapshots.map((snapshot) => readProjectPaymentTokenInfo(machinery, snapshot.projectAddress)), ); - return dedupeAlignedProjects(snapshots.map((snapshot, index) => ({ + return dedupeAlignedProjects(snapshots.map((snapshot, index) => { + const alignment = projectAlignment.get(snapshot.projectAddress.toLowerCase()); + return { projectAddress: snapshot.projectAddress, - alignmentType: projectAlignmentType.get(snapshot.projectAddress.toLowerCase()) ?? 'direct', + alignmentType: alignment?.alignmentType ?? 'direct', + viaStatementCids: alignment?.viaStatementCids ?? [], fundingCurrency: paymentTokenInfo[index]?.currency ?? ETH_CURRENCY, totalReceived: snapshot.totalReceived.toString(), threshold: snapshot.threshold.toString(), deadline: snapshot.deadline.toString(), ...(snapshot.conditionStatus ? { conditionStatus: snapshot.conditionStatus } : {}), ...attestedWorkField(alignedProjects, snapshot.projectAddress), - }))); + }; + })); } const projects = await Promise.all( - alignedProjects.map(async ({ projectAddress, alignmentType, attestedWorkId }) => { + alignedProjects.map(async ({ projectAddress, alignmentType, viaStatementCids, attestedWorkId }) => { const project = await getProject(machinery, projectAddress); if (!project) return null; return { projectAddress: project.id, alignmentType, + viaStatementCids, fundingCurrency: project.fundingCurrency, totalReceived: project.totalReceived, threshold: project.threshold, @@ -903,6 +924,13 @@ async function getUnionAlignedProjectsForStatements( const existing = byAddress.get(key); if (!existing || (existing.alignmentType === 'indirect' && project.alignmentType === 'direct')) { byAddress.set(key, project); + continue; + } + if (existing.alignmentType === 'indirect' && project.alignmentType === 'indirect') { + byAddress.set(key, { + ...existing, + viaStatementCids: [...new Set([...(existing.viaStatementCids ?? []), ...(project.viaStatementCids ?? [])])], + }); } } } diff --git a/ui/src/commonality/components/BridgeContributions.tsx b/ui/src/commonality/components/BridgeContributions.tsx new file mode 100644 index 00000000..a2b31916 --- /dev/null +++ b/ui/src/commonality/components/BridgeContributions.tsx @@ -0,0 +1,170 @@ +import { useEffect, useState } from 'react' +import { Box, CircularProgress, Link, Paper, Stack, Typography } from '@mui/material' +import { Link as RouterLink } from 'react-router-dom' +import { formatUnits } from 'viem' +import { + getImplicationsTo, + getIndirectSupporters, + getStatement, +} from '@commonality/sdk/conceptspace' +import { getStandingPledges } from '@commonality/sdk/delegation' +import { getAllAlignedProjectsForCause } from '@commonality/sdk/fundingportals' +import type { IpfsCidV1 } from '@commonality/sdk/utils' +import { getRuntimeConfig, useMachinery } from '../../shared' +import { + buildBridgeContributions, + type BridgeContribution, + type BridgeProject, +} from '../lib/bridgeContributions' + +interface BridgeRow extends BridgeContribution { + title: string +} + +function formatRaised(row: BridgeContribution): string | null { + if (row.raised.length === 0) return null + return row.raised + .map((amount) => `${formatUnits(amount.amount, amount.decimals)} ${amount.symbol} raised`) + .join(', ') +} + +/** + * Ranked implying statements that bring indirect signers, pledges, or + * indirectly aligned project funds onto the statements passed in. + */ +export function BridgeContributions({ + statementCids, + trustedImplicationAttesters, + trustedAlignmentAttesters, +}: { + statementCids: string[] + trustedImplicationAttesters?: string[] + trustedAlignmentAttesters?: Iterable +}) { + const machinery = useMachinery() + const [loading, setLoading] = useState(false) + const [rows, setRows] = useState([]) + const [omitted, setOmitted] = useState(0) + const [pledgeSymbol, setPledgeSymbol] = useState('tokens') + const [pledgeDecimals, setPledgeDecimals] = useState(18) + const cidKey = statementCids.filter(Boolean).join('\n') + + useEffect(() => { + const cids = cidKey ? cidKey.split('\n') : [] + if (cids.length === 0) { + setRows([]) + setOmitted(0) + return + } + let cancelled = false + setLoading(true) + + void (async () => { + try { + const config = getRuntimeConfig() + const paymentToken = config.VITE_PAYMENT_TOKEN_ADDRESS + if (!cancelled) { + setPledgeSymbol(config.VITE_PAYMENT_TOKEN_SYMBOL ?? 'tokens') + setPledgeDecimals(Number(config.VITE_PAYMENT_TOKEN_DECIMALS ?? '18')) + } + const implicationLists = await Promise.all(cids.map((cid) => + getImplicationsTo(machinery, cid as IpfsCidV1, trustedImplicationAttesters))) + const viaStatementCids = [...new Set(implicationLists.flat().map((implication) => implication.fromStatementCid))] + if (viaStatementCids.length === 0) { + if (!cancelled) { + setRows([]) + setOmitted(0) + } + return + } + const [supporterLists, pledges, projectLists] = await Promise.all([ + Promise.all(cids.map((cid) => + getIndirectSupporters(machinery, cid as IpfsCidV1, trustedImplicationAttesters))), + machinery.contractAddresses?.recurringPledges + ? getStandingPledges(machinery).catch(() => []) + : Promise.resolve([]), + Promise.all(cids.map((cid) => + getAllAlignedProjectsForCause( + machinery, + cid as IpfsCidV1, + trustedImplicationAttesters, + trustedAlignmentAttesters, + ).catch(() => [] as BridgeProject[]))), + ]) + const built = buildBridgeContributions({ + supporters: supporterLists.flat(), + pledges, + paymentToken, + projects: projectLists.flat(), + viaStatementCids, + }) + const titles = await Promise.all(built.rows.map(async (row) => { + const statement = await getStatement(machinery, row.viaStatementCid as IpfsCidV1).catch(() => null) + return statement?.title?.trim() || 'Untitled statement' + })) + if (cancelled) return + setRows(built.rows.map((row, index) => ({ ...row, title: titles[index] ?? 'Untitled statement' }))) + setOmitted(built.omitted) + } catch { + if (!cancelled) { + setRows([]) + setOmitted(0) + } + } finally { + if (!cancelled) setLoading(false) + } + })() + + return () => { + cancelled = true + } + }, [cidKey, machinery, trustedImplicationAttesters, trustedAlignmentAttesters]) + + if (!loading && rows.length === 0) return null + + return ( + + + Arriving through other statements + + + People who signed a different statement that your trusted sources say implies this one. + Pledge amounts are what was pledged to that other statement. Raised amounts are projects + counted here only because they are aligned with it. Each person, and each project, is + counted on one statement. + + {loading && rows.length === 0 ? ( + + ) : ( + + {rows.map((row) => { + const raised = formatRaised(row) + return ( + + + {row.title} + + + {row.indirectSigners.toLocaleString()} indirect signer{row.indirectSigners === 1 ? '' : 's'} + {' · '} + {formatUnits(row.pledgedMonthly, pledgeDecimals)} {pledgeSymbol}/month pledged to it + {raised ? ` · ${raised}` : ''} + + + ) + })} + {omitted > 0 && ( + + {omitted} more {omitted === 1 ? 'statement contributes' : 'statements contribute'} a small share of the signers. + + )} + + )} + + ) +} diff --git a/ui/src/commonality/lib/bridgeContributions.test.ts b/ui/src/commonality/lib/bridgeContributions.test.ts new file mode 100644 index 00000000..8d15f37a --- /dev/null +++ b/ui/src/commonality/lib/bridgeContributions.test.ts @@ -0,0 +1,72 @@ +import { describe, expect, it } from 'vitest' +import { buildBridgeContributions } from './bridgeContributions' + +const eth = { symbol: 'ETH', decimals: 18 } + +describe('buildBridgeContributions', () => { + it('credits each signer once and keeps pledge and raised totals on the bridge', () => { + const { rows, omitted } = buildBridgeContributions({ + viaStatementCids: ['bridge-a', 'bridge-b', 'bridge-c'], + supporters: [ + { user: '0xA', viaStatementCid: 'bridge-a' }, + { user: '0xa', viaStatementCid: 'bridge-b' }, + { user: '0xB', viaStatementCid: 'bridge-a' }, + { user: '0xC', viaStatementCid: 'bridge-c' }, + ], + pledges: [ + { active: true, token: '0xToken', causeRef: 'bridge-b', amountPerPeriod: '5' }, + { active: false, token: '0xToken', causeRef: 'bridge-b', amountPerPeriod: '9' }, + { active: true, token: '0xOther', causeRef: 'bridge-a', amountPerPeriod: '100' }, + { active: true, token: '0xToken', causeRef: 'target', amountPerPeriod: '50' }, + ], + paymentToken: '0xToken', + projects: [ + { + projectAddress: '0xP1', + alignmentType: 'indirect', + viaStatementCids: ['bridge-b', 'bridge-a'], + totalReceived: '7', + fundingCurrency: eth, + }, + { + projectAddress: '0xP1', + alignmentType: 'indirect', + viaStatementCids: ['bridge-c'], + totalReceived: '7', + fundingCurrency: eth, + }, + { + projectAddress: '0xP2', + alignmentType: 'direct', + viaStatementCids: [], + totalReceived: '99', + fundingCurrency: eth, + }, + ], + }) + + expect(omitted).toBe(0) + const byVia = Object.fromEntries(rows.map((row) => [row.viaStatementCid, row])) + expect(byVia['bridge-a']?.indirectSigners).toBe(2) + expect(byVia['bridge-b']?.indirectSigners).toBe(0) + expect(byVia['bridge-b']?.pledgedMonthly).toBe(5n) + expect(byVia['bridge-a']?.raised).toEqual([{ symbol: 'ETH', decimals: 18, amount: 7n }]) + expect(byVia['bridge-c']?.indirectSigners).toBe(1) + expect(rows.map((row) => row.viaStatementCid)).toEqual(['bridge-a', 'bridge-c', 'bridge-b']) + }) + + it('omits bridges that are small next to the largest signer count', () => { + const supporters = [ + ...Array.from({ length: 20 }, (_, i) => ({ user: `big-${i}`, viaStatementCid: 'big' })), + { user: 'tiny', viaStatementCid: 'tiny' }, + ] + const { rows, omitted } = buildBridgeContributions({ + viaStatementCids: ['big', 'tiny'], + supporters, + pledges: [], + projects: [], + }) + expect(rows.map((row) => row.viaStatementCid)).toEqual(['big']) + expect(omitted).toBe(1) + }) +}) diff --git a/ui/src/commonality/lib/bridgeContributions.ts b/ui/src/commonality/lib/bridgeContributions.ts new file mode 100644 index 00000000..796a8134 --- /dev/null +++ b/ui/src/commonality/lib/bridgeContributions.ts @@ -0,0 +1,118 @@ +/** + * How much of a statement's indirect support, and of the money sitting on + * implying statements, arrives through each bridge. + * + * Signers are credited to one bridge (first one found). A pledge belongs to + * the statement it names, so amounts are not split. A project's raised total + * is credited to one implying statement so the same pot is not added twice. + */ + +export interface BridgeSupporter { + user: string + viaStatementCid: string +} + +export interface BridgePledge { + active: boolean + token: string + causeRef: string + amountPerPeriod: string +} + +export interface BridgeProject { + projectAddress: string + alignmentType: 'direct' | 'indirect' + viaStatementCids?: string[] + totalReceived: string + fundingCurrency: { symbol: string; decimals: number } +} + +export interface RaisedAmount { + symbol: string + decimals: number + amount: bigint +} + +export interface BridgeContribution { + viaStatementCid: string + indirectSigners: number + pledgedMonthly: bigint + raised: RaisedAmount[] +} + +export function buildBridgeContributions(input: { + supporters: BridgeSupporter[] + pledges: BridgePledge[] + paymentToken?: string + projects: BridgeProject[] + viaStatementCids: string[] +}): { rows: BridgeContribution[]; omitted: number } { + const vias = new Set(input.viaStatementCids) + const signers = new Map() + const seenUsers = new Set() + for (const supporter of input.supporters) { + if (!vias.has(supporter.viaStatementCid)) continue + const user = supporter.user.toLowerCase() + if (seenUsers.has(user)) continue + seenUsers.add(user) + signers.set(supporter.viaStatementCid, (signers.get(supporter.viaStatementCid) ?? 0) + 1) + } + + const token = input.paymentToken?.toLowerCase() + const pledged = new Map() + for (const pledge of input.pledges) { + if (!pledge.active) continue + if (!vias.has(pledge.causeRef)) continue + if (token && pledge.token.toLowerCase() !== token) continue + const amount = BigInt(pledge.amountPerPeriod) + pledged.set(pledge.causeRef, (pledged.get(pledge.causeRef) ?? 0n) + amount) + } + + const raised = new Map>() + const seenProjects = new Set() + const indirect = input.projects + .filter((project) => project.alignmentType === 'indirect') + .slice() + .sort((a, b) => a.projectAddress.toLowerCase().localeCompare(b.projectAddress.toLowerCase())) + for (const project of indirect) { + const address = project.projectAddress.toLowerCase() + if (seenProjects.has(address)) continue + const via = (project.viaStatementCids ?? []) + .filter((cid) => vias.has(cid)) + .slice() + .sort()[0] + if (!via) continue + seenProjects.add(address) + const amount = BigInt(project.totalReceived) + if (amount <= 0n) continue + const key = `${project.fundingCurrency.symbol}:${project.fundingCurrency.decimals}` + const byCurrency = raised.get(via) ?? new Map() + const existing = byCurrency.get(key) + byCurrency.set(key, { + symbol: project.fundingCurrency.symbol, + decimals: project.fundingCurrency.decimals, + amount: (existing?.amount ?? 0n) + amount, + }) + raised.set(via, byCurrency) + } + + const all: BridgeContribution[] = [] + for (const viaStatementCid of vias) { + const rowRaised = [...(raised.get(viaStatementCid)?.values() ?? [])] + const indirectSigners = signers.get(viaStatementCid) ?? 0 + const pledgedMonthly = pledged.get(viaStatementCid) ?? 0n + if (indirectSigners === 0 && pledgedMonthly === 0n && rowRaised.length === 0) continue + all.push({ viaStatementCid, indirectSigners, pledgedMonthly, raised: rowRaised }) + } + + all.sort((a, b) => + b.indirectSigners - a.indirectSigners + || (a.pledgedMonthly < b.pledgedMonthly ? 1 : a.pledgedMonthly > b.pledgedMonthly ? -1 : 0) + || a.viaStatementCid.localeCompare(b.viaStatementCid)) + + const largest = all.reduce((max, row) => Math.max(max, row.indirectSigners), 0) + const threshold = largest === 0 ? 0 : Math.max(1, Math.ceil(largest * 0.1)) + const rows = all.filter((row) => + row.indirectSigners >= threshold || row.pledgedMonthly > 0n || row.raised.length > 0) + return { rows, omitted: all.length - rows.length } +} diff --git a/ui/src/commonality/pages/CauseDetailPage.tsx b/ui/src/commonality/pages/CauseDetailPage.tsx index c062f9d3..497e37d1 100644 --- a/ui/src/commonality/pages/CauseDetailPage.tsx +++ b/ui/src/commonality/pages/CauseDetailPage.tsx @@ -18,6 +18,7 @@ import { } from '@ui/shared' import { CauseBoard, CauseLeaderboard } from '@ui/fundingportals' import { AlignmentTrustGate } from '../components/AlignmentTrustGate' +import { BridgeContributions } from '../components/BridgeContributions' import { CauseViewStrip } from '../components/CauseViewStrip' import { CauseMediatorCard } from '../components/CauseMediatorCard' import { CauseBridgesSection } from '../components/CauseBridgesSection' @@ -1091,6 +1092,13 @@ export function CauseDetailPage({ editMode = false }: { editMode?: boolean }) { Signer counts could not be loaded: {countsError} )} + + + )} diff --git a/ui/src/commonality/pages/StatementPage.test.tsx b/ui/src/commonality/pages/StatementPage.test.tsx index bc513f26..b4aaeb0c 100644 --- a/ui/src/commonality/pages/StatementPage.test.tsx +++ b/ui/src/commonality/pages/StatementPage.test.tsx @@ -14,11 +14,15 @@ vi.mock('wagmi', () => ({ vi.mock('@commonality/sdk/conceptspace', () => ({ getStatementWithContent: (...args: unknown[]) => getStatementWithContent(...args), + getImplicationsTo: async () => [], + getIndirectSupporters: async () => [], + getStatement: async () => null, })) vi.mock('@ui/shared', () => ({ useMachinery: () => ({}), useTrustedAttesters: () => [], + getRuntimeConfig: () => ({}), loadDisplayDenylist: async () => ({ deniedCids: [], honoredRetractors: [] }), isCidDeniedByDisplayDenylist: () => false, })) diff --git a/ui/src/commonality/pages/StatementPage.tsx b/ui/src/commonality/pages/StatementPage.tsx index 40f91e5b..7fa8e5e3 100644 --- a/ui/src/commonality/pages/StatementPage.tsx +++ b/ui/src/commonality/pages/StatementPage.tsx @@ -20,6 +20,7 @@ import { import type { IpfsCidV1 } from '@commonality/sdk/utils' import { useTrustedAttesters } from '@ui/shared' import { StatementRenderer } from '@ui/conceptspace' +import { BridgeContributions } from '../components/BridgeContributions' import { CauseBoard, CauseLeaderboard } from '@ui/fundingportals' import { ContentSubmissionForm, StatementSupportingContent } from '@ui/content-funding' import { useAlignmentTrust } from '../hooks/useAlignmentTrust' @@ -374,6 +375,14 @@ export function StatementPage() { + {statementCid && ( + + )} + {showFunding && } {showFunding && } From 676c43d219de09f50dac68b2bf7ec0529c011dee Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 13:29:51 -0400 Subject: [PATCH 03/19] Thinking about making a new fake-data campaign. --- .../credible-solution/network-societies.md | 8 +++ fake-data-generation/brainstorming/README.md | 51 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 fake-data-generation/brainstorming/README.md diff --git a/docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md b/docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md index f9b24ef8..736d5366 100644 --- a/docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md +++ b/docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md @@ -140,3 +140,11 @@ This isn't meant to be an exhaustive list, but here's a list: Note that a lot of these jobs are "public goods" within the network society. Maintaining the website, writing content, working on relevant open-source software, maintaining maps of chapters, etc., are all (to some degree) jobs that benefit everyone in the society but that everybody wants someone else to pay for. They're not exactly public goods in the same way that a public park benefits basically *everyone*; they're scoped to this specific "movement" of people. But they're still kinda got that non-excludable, non-rivalrous nature. So it's useful to have mechanisms like Commonality's assurance-contracts and retroactive-funding and so on, to get them funded. The Tally stuff is a good fit too: we can count up how many people have signed any of these N statements, to show how much support there is. See the durable-participation spec (`specs/product/durable-participation.md`). And again, note that this doesn't require the "network society" to be made of a single Discord whose membership list we can count. + +## Terminology + +One point about terminology: I've been thinking of these as "network societies" because my thinking about these ideas first came from reading Balaji Srinivasan's book. But that's a weird way to think about it. + - Some of them are more society-like than others. There are different aspects of society-ness: networks of personal relationships and private groups, public conversations on social media, small and big gatherings, collective endeavours. + - Calling them "network" societies is a bit weird. Like, okay, there's an online component; so what? Everything is online. I think the term "network" is also meant to mean something like "networks of people" (as opposed to the state, or something?), but again that's more true of some than others, and in any case the term doesn't really seem like the natural words we'd use to describe these things. + +So what would be a better way of naming/characterizing the kinds of things we're talking about here? Maybe just "cause", or "movement", or "community", or something? diff --git a/fake-data-generation/brainstorming/README.md b/fake-data-generation/brainstorming/README.md new file mode 100644 index 00000000..bf4b034b --- /dev/null +++ b/fake-data-generation/brainstorming/README.md @@ -0,0 +1,51 @@ +# My initial thoughts, brainstorming ideas for examples of "network society" projects + +Read [our thoughts on network societies](/docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md), and anything else relevant. + +Some thoughts on particular "network societies" that might be interesting to me: + - "Crypto-friendly community": local education, advocacy, and lobbying, aimed at getting more local businesses to accept blockchain-based payments. e.g. Build and test an open-source checkout integration for one commonly used shop setup, including refunds and understandable receipts. Run an eight-week deployment trial with ten willing merchants and publish what worked, actual costs, and failures. Fund an independent security review of the shared integration. The reusable software and evidence are the public goods; subsidizing one shop's equipment is a different proposition. Note that this could be an organic alliance, supported by people coming from various perspectives: crypto-natives, people who don't trust the federal government for political reasons, business owners who are tired of paying 3% to the credit-card companies, etc. + - "Improve assimilation": For people who are concerned about higher levels of immigration leading to immigrants who don't assimilate as well, we could have projects for various measures (implementable by either normal citizens or by local governments) to improve assimilation. + - e.g. + - Run twelve evening sessions of practical host-language practice: talking to a teacher, applying for work, explaining a maintenance problem, participating in a local meeting. (Provide childcare so parents can attend.) + - Teach basic civics. + - Publish a reusable instructor pack for doing this kind of teaching. + - Pair newcomers and established residents for a season of repairing park facilities or maintaining a community garden: a shared task with a useful result, where conversation happens naturally. + - Local-government policies: *Don't* offer indefinite bilingual service; create non-ethnic shared activities; use existing institutions (libraries, adult education, parks departments) as the main vehicles rather than creating parallel “immigrant offices” whose mission is primarily service delivery in origin languages; more even spatial distribution of public housing; model and enforce ordinary social norms in everyday life; etc. + - Again, this is kind of an organic-alliance situation: maybe you're a right-winger who wants less immigration overall (and wants to at least assimilate the immigrants who do come), but you could also be someone who's fine with immigration but still believes it's a good thing when the immigrants assimilate, or you could even be an immigrant who simply wants to fit in better. + - "End first-past-the-post": Push for using better voting systems than FPTP, aiming to try it in more-local elections first; could be interesting to try (non-binding, obviously) online polls that use other voting systems, to see what the outcomes would be; etc. Organic alliance angle: this might not even be particularly partisan (many on both right and left dislike FPTP). + - "Let's stop fighting about abortion": Not so much about pushing for pro-life or pro-choice; more like "let's make the rules at the state level rather than the federal level, so that presidential elections and supreme-court appointments don't boil down to a referendum on abortion", plus maybe "let's advocate middle-of-the-road abortion policies like legal-until-12-weeks so that everyone is happy except the extremists on each side, then go on with our lives instead of fighting over this forever." Organic alliance angle: I think a lot of people on both left and right are tired of fighting about this. + - "Low-carb society": form enclaves where the grocery stores and restaurants avoid carb-heavy junk food. + - "Cancel-proof": supporting those who've been undeservedly "cancelled". Organic alliance angle: you don't actually have to be a right-winger to believe that cancel culture is wrong, you just have to be a liberal from 15 or 20 years ago. + - "Common sense about gender": "Don't let kids chop off their genitals, and also don't be a jerk to people who are innately different." Organic alliance angle: you don't actually have to be a right-winger to believe that kids probably shouldn't be allowed to do gender transitions, you just have to be almost anyone at all whose beliefs were formed more than ten years ago. + - "Unwoke": combination of the gender one and the cancellation one and various others. + - "Democracy 2.0": could have organic-alliances with the anti-FPTP stuff above; using tools like Tally to do "voting" in a more fine-grained Internet-enabled way, and tools like Commonality to do public-goods-funding, rather than the legacy system where idiot corrupt representatives squabble and posture. + - "AI isn't so important that we should be risking human extinction": make international treaties to let alignment research go ahead while slowing down capabilities research, etc. + - "US-friendly Canadian": for Canadians who are perfectly happy to buy from the US, etc. This could be a bridge between various views: right-wingers who are generally fine with the US and Trump; normal everyday types who don't care that much about politics and just think it's silly to cut ties with the US when we obviously need them; people who have business interests or personal connections with the US; left-wingers who don't like Trump but take a longer-term view and expect the pendulum to swing; etc. + - Christianity: Notice that Christianity itself is actually a pretty textbook example of a network state. They have the "network union" aspect (sticking up for each other). They have the "network archipelago" aspect (enclaves where believers live near each other, weekly meetups every Sunday, many other in-person gatherings too), they have the diplomatic-recognition aspect (tax-exempt status and special rules). And they could really use a public-goods-funding system like Commonality, because large-scale inter-church organizations/denominations are fraught with all sorts of annoying politics and squabbles over doctrine and so on. So... what kinds of projects would be helpful? Some thoughts, and I bet there's a lot more: "sticking up for each other" (when one has a problem that's too big for them, others pitch in to help); substitute preachers for a week when the pastor is sick or whatever; info, news, teaching materials, etc. Plus all sorts of other kinds of projects that they'd share with secular conservatives: pro-life efforts, etc. There's lots of potential for organic-alliances: between churches with the same doctrine, between churches of different doctrines who nevertheless have plenty of common beliefs; between Christians and secular conservatives; between Christians and Jews; etc. + - Islamic reform: efforts to "soften" Islam so that it's less incompatible with the rest of the world. + - Anti-regulation (or anti-specific-types-of-regulation, like Balaji's "FDA-free zone" idea) + - Home-schooling: organizing local meetups of homeschoolers; teaching materials; planning local "field trips"; etc. + - lots of others + +(Some of those are just "advocate for this idea", which is a valid thing to do but it's also kinda lame and ineffectual; it's much more interesting when there are concrete things that can be done that might actually produce real value.) + +Obviously this list is heavily biased towards my own political views. There's nothing about Commonality that would prevent people on the other side from using Commonality for their own stuff, but if *I'm* gonna try to jumpstart this thing with example projects, I'm going to choose causes that I think are good. (But it might be a good idea to keep these in a separate repo or something. Maybe we should split off the seed data stuff? OTOH, that feels silly.) + +That said, I think there's potential for "bridges" ("organic alliances") here. This mostly isn't meant to be "let's make the right-wingers win", this is meant to be "I think there's a lot of common ground between sane common-sense people on both sides". Part of the job of running each of those causes is going to be writing bridges to get support from various separate potential constituencies. (Still, my preferences do generally exclude the radical left much more than the far right.) + +This is a huge list of causes; I'm obviously not going to take those all on myself. But I bet that together we could come up with a decent list of *fake* examples illustrating all of these (including a few base-level projects for each one, and also meta-level projects for running each "network society"), in a way that'd make me (and anyone with roughly my political preferences) say "huh, cool, I can see how this system could be useful." The hope is that this inspires people to start doing them for real - "cause founder" types at first, who'll be motivated (out of a desire to further their cause, not out of a desire to expand usage of Commonality) to take on the job of finding people to do the various other jobs. + +And the hope is that they'll notice not just "hey, those like good projects" but also "wow, I can see how this kind of thing might just *not happen* without this Commonality system". (That'll obviously be a rarer realization - lots of people *won't* think about it in those terms.) + - "Huh, this cause-board is showing me a list of lots of aligned projects; I can see that these three in particular have momentum and could potentially reach their funding threshold. It's neat that I can get an overview of what this entire ecosystem is trying to accomplish, and where my money is most likely to be effective." + - "Huh, I can have the cause-board show me only *already-funded but not-yet-reimbursed* projects; I'm much more comfortable directing my money to those and letting the less risk-averse types take on the task of guessing winners in advance." + - "Huh, I can just fire-and-forget $20/month, to be directed not by a faceless org, but by my friend Joe." + - etc. + +What I want to do next is make a big fake-data campaign containing: + - for each "society": + - many statements, not just one; look for bridges where people coming from various perspectives would agree on this; make use of our statement-generation and bridge-creation guidelines to make these compelling and make the implication arrows actually work + - also make some statements that are *incompatible* with these, because not all the fake users will agree with me on everything + - and make the implication arrows if and only if the implication attestor actually agrees (I forget how we do that for these simulations, it doesn't need to be the real live implication attester, but you should at least run the statements through the real implication-attester prompt) + - many fake crowdfundable projects + - many fake users, with various combinations of roles and interests and various possible beliefs within each area, including beliefs that lead them *not* to sign or support these causes; have them sign the statements they'd sign, support some projects they'd support, etc. + - whatever else is necessary to make this a proper realistic demo campaign (I'm sure I'm forgetting stuff) From 7bcb837255ec300d1862433d49db02545b2289f2 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 13:43:37 -0400 Subject: [PATCH 04/19] Had an AI generate a campaign plan. --- .../network-societies-campaign-plan.md | 160 ++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 fake-data-generation/brainstorming/network-societies-campaign-plan.md diff --git a/fake-data-generation/brainstorming/network-societies-campaign-plan.md b/fake-data-generation/brainstorming/network-societies-campaign-plan.md new file mode 100644 index 00000000..b0ecc45d --- /dev/null +++ b/fake-data-generation/brainstorming/network-societies-campaign-plan.md @@ -0,0 +1,160 @@ +# Network societies fake-data campaign + +Status: implementation handoff, 2026-10-16. This document plans a new campaign; it does not generate data or authorize a remote deployment. Suggested campaign ID: `network-societies-v1`. + +## Purpose + +Build a substantial, believable synthetic world around **all fifteen named areas in [the brainstorming notes](./README.md)**. A prospective cause founder should see concrete work worth organizing, the people needed to do it, and how Commonality can bring together funding that would otherwise remain fragmented. + +The central story is overlapping constituencies funding particular outcomes without joining one organization. Show separate organizers, competing publications, practical disagreements, independent judgment, and people who decline to participate. Preserve the author's selection of causes and interest in bridges; do not replace it with a generic politically balanced charity catalog. Give dissenters plausible beliefs, rather than making them foils who inevitably convert. + +This is a realistic demonstration, not evidence of adoption, a prediction about public opinion, or a stress test. All people, organizations, activity, and claimed deliverables must be visibly synthetic. “Campaign” here names this data-generation run, not a new product object. + +## Read first, then reuse + +The implementing model should read the project README and relevant role guidance, then: + +- [Fake-data README](../README.md): commands, artifacts, environment boundaries, existing runner. +- [Statement-generation process](../statement-generation.md), [statement wording constraints](../../specs/product/statements-are-peculiar-for-good-reasons.md), and [bridge creator](../../specs/product/bridge-creator.md): reuse their authoring and checking process. +- [Network-society vision](../../docs/end-user/commonality/vision-and-strategy/credible-solution/network-societies.md): especially the distinction between base work, organizing work, and private benefits. +- [V2 manifest](../campaigns/medium-realistic-v2.json), [project stories](../campaignProjectStories.ts), and [step-14 run report](../campaigns/medium-realistic-v2-step14-run.md): the closest implementation precedent. +- [Glossary](../../specs/glossary.md): especially cause board, contribution, recurring pledge, and retroactive donation. + +Use the existing campaign planner, executor, provisioning, runtime bindings, reconciliation, and generated-run viewer. Add campaign-local content alongside existing manifests; keep authored source in version control and execution output/secrets in the established ignored locations. Give this campaign its own output directory. Do not overwrite existing executed runs or turn campaign drafts into accepted `seed-content`. + +Some older summaries are stale: the October step-14 report and current adapter already support varied receipt purchases, cross-camp contributions, and retroactive donations. Inspect current code before treating these as missing features. + +## Scope and scale + +Aim for **240 users, roughly 150–210 unique statements, and 75–90 projects** across fifteen topic families. These are authoring targets, not reasons to manufacture weak statements or meaningless transactions. Count unique statements/projects separately from their appearances on multiple boards. + +Each family should have: + +- 6–10 useful cause planks at different grains, including concrete local goals where appropriate. +- 2–4 genuinely incompatible or limiting positions, with people who hold them. Neutrality and disinterest are separate from disagreement. +- At least five projects: three base-level deliverables and two organizing/maintenance deliverables. More developed families can have six. +- At least two constituencies with different motivations, plus people who reject part or all of the proposed program. +- A named organizer, credible project founders, contributors, an independent reviewer, and a plausible funding director. People can hold several roles, but no single person should fill every role on their own project. + +Use 20–30 editorial cause boards across the fifteen families, including alternative organizers and a few shared boards. Families are authoring categories, not compulsory membership organizations or single canonical statements. Pilot/full scale must be explicit configuration, not a collection of hard-coded exceptions. + +## Content map + +These are project briefs and constituency suggestions, not finished statement wording. For each row, expand to the per-family minimum above. Make deliverables bounded and inspectable: a named place, duration, artifact or service, budget, completion criterion, and responsible fictional person. + +| Family | Base-level projects to develop | Organizing work | Coalition and disagreement to portray | +| --- | --- | --- | --- | +| Crypto-friendly communities | Open-source checkout integration with refunds; ten-merchant trial with published costs/failures; independent security review | Maintained merchant directory; quarterly deployment clinics and reusable host kit | Crypto enthusiasts, fee-conscious merchants, civil-liberties advocates; skeptics of volatility or privacy claims who may still want a fair trial | +| Assimilation and shared civic life | Twelve practical language sessions with childcare; reusable civics pack; mixed newcomer/resident park-repair season | Tutor/venue directory with independent checking; local organizer handoff kit | Immigration restrictionists, pro-immigration integration advocates, newcomers seeking belonging; disagreement about language-service limits and cultural expectations | +| Better voting systems | Open-source ranked/approval ballot demo; non-binding local comparison poll with methods/data; auditable counting toolkit | Local pilot organizer guide; maintained directory of trial groups | Left/right FPTP critics and independents; disagreement between alternatives and defenders of the status quo | +| Abortion settlement | Clearly fictional policy-options comparison; moderated deliberation series with published outputs; accessible explanation of the proposed compromise | Maintained resource page; facilitator training and handoff | Reuse accepted compromise texts; include people on both sides who reject the compromise. State-level authority is a separate proposition, not implied by agreement on a cutoff | +| Low-carb communities | Open recipe/menu collection; reproducible restaurant menu audit; eight-week community cooking series | Independently checked venue directory; host kit and calendar | People seeking a low-carb food environment for different reasons; people who favor dietary choice but reject an enclave. Avoid invented health-effect claims | +| Cancel-proof support | Public corrections/appeals toolkit; documented fictional case-review method; resilient publishing tools | Independently reviewed support-provider directory; bounded intake/triage service | Conservatives, older free-speech liberals, civil-liberties advocates; disagreement about which sanctions are justified. Direct aid to one person is not the public-good showcase | +| Common sense about gender | Source-comparison methods and evidence-literacy materials; facilitated school-policy discussion kit; practical anti-harassment resources | Resource maintenance; facilitator directory and training | Different views about youth interventions, adult autonomy, schools, and respectful conduct. Reuse relevant accepted school statements without pretending they settle all these questions | +| Unwoke | Open due-process policy templates; viewpoint-neutral selection-rubric pilot; audit of a fictional institution's complaint process | Editorial front door covering selected planks; independent review digest | Overlap with cancellation/gender causes, but users can support one plank and reject another. Include a liberal due-process supporter who refuses the umbrella label | +| Democracy 2.0 | Open civic issue explorer; non-binding participatory allocation experiment; independent evaluation of the experiment | Local facilitator network; public methods/history archive | Voting reformers, decentralists, civic technologists; skeptics of online participation. Do not claim a binding election or verified population census | +| AI safety before capabilities races | Open evaluation tooling; independent replication of a safety result; public comparison of hypothetical verification mechanisms | Research digest; workshop and contributor onboarding kit | Safety researchers, cautious technologists, concerned citizens; accelerationists and people who dispute proposed restrictions. No invented technical success claims | +| US-friendly Canadians | Shared cross-border cultural archive; public guide to maintaining civic/business ties; joint community event with reusable materials | Maintained exchange directory; local host succession | Conservatives, apolitical families, businesspeople, anti-Trump internationalists; people who favor a boycott or narrower ties | +| Christianity | Open teaching materials; accessibility/transcription of shared resources; regional substitute-preacher coordination pilot | Independently checked resource directory; inter-church organizer/host kit | Different denominations, secular collaborators on specific civic work, nonparticipants; doctrinal agreement is not inferred from shared project funding | +| Islamic reform | Open discussion/study materials by fictional reform-minded authors; moderated interpretation forum with published materials; reusable civic-coexistence workshop | Maintained resource library; facilitator training | Reform-minded Muslims, secular civil-liberties allies, traditionalist dissenters; specify actual propositions rather than treating Muslims as one position | +| Less regulation | Open dataset of burdens in one fictional permitting process; reproducible comparison of alternative procedures; small-business application guide | Maintained reform-project tracker; independent methodology review | Entrepreneurs, libertarians, frustrated residents; safety-minded reformers and defenders of particular rules. An experimental medical zone remains a hypothetical policy proposal | +| Home-schooling | Open curriculum unit; accessible shared field-trip materials; reusable science activity kits | Local meetup season with succession; independently checked tutor/resource directory | Religious/secular home-schoolers and school-system families borrowing resources; disagreement on pedagogy, oversight, and religious content | + +Use determinate geography: for example, Grey County, Ontario, Canada for Canadian local projects and a separately identified US setting for US policy examples. Do not blur jurisdictions. Synthetic policy proposals and evidence-research projects do not need assertions about current law or clinical truth; any such assertions that are included require sources checked at authoring time. + +Shared projects are particularly valuable. A civil-liberties toolkit can appear on cancel-proof, unwoke, and Democracy 2.0 boards; an open teaching resource can cross Christian and home-schooling boards. Publish one project and multiple justified alignments, not three copies. Give at least three cross-family projects this treatment. + +## Statements and bridges: the quality gate + +Author ordinary signable wants first. Avoid slogans, statements about how the funding platform works, and “people doing X deserve payment.” Produce granularity along topic and place axes. Geographic inclusion on a board is not a belief implication. + +Distinguish two legitimate stories: + +1. **Existing overlap:** different motivations already support the same concrete outcome. Crypto checkout testing and shared teaching resources are good candidates. This does not need a manufactured compromise triple. +2. **A real belief gap:** the natural statements do not imply agreement. A mediator proposes modified statements containing a real concession; some personas accept and others decline. Only accepted modified statements may support the commonality through implication. + +Target four well-developed bridge stories: reuse the accepted abortion cluster; develop voting reform, crypto merchant trials, and assimilation/shared civic work as candidate alliances. Determine their actual pattern before writing. The accepted immigration cluster concerns a different proposition and must not be relabeled as assimilation. Likewise the accepted LGBT-schools cluster does not establish a position on medical interventions. Add more bridges only after these work; every family needs coalition possibilities, not a compulsory formal triple. + +For every proposed implication edge: + +- Evaluate the exact ordered pair with the **real implication-attester system prompt**, using the shared evaluator or existing generation machinery. A simulation attester identity is fine; invented evaluations are not. +- Store statement-text hashes, prompt fingerprint, model/settings, decision, rationale, and evaluation status. Cache identical inputs; invalidate when text or prompt changes. Record refusals as well as approvals. +- Require an actual successful model evaluation and an affirmative decision before publishing. `cause-assist/src/implicationCheck.ts` can return `implies: true` with `source: heuristic` after missing credentials or failures; **that is not evidence**. Errors, malformed output, stale caches, and heuristic fallbacks leave the edge unevaluated and unpublished. +- Check designed-negative pairs: naturals to compromise, reverse arrows, incompatible claims, and nested-place rollups. If a designed-negative pair passes, investigate the wording/evaluation rather than silently publishing it. +- Run routing and shape critique too: modified → commonality should feel already said; natural → modified should be a meaningful optional change. Reject pasted-in commonality sentences, mediator narration, and camp justifications leaking into the shared statement. + +Do not evaluate every possible pair in the whole catalog. Evaluate a bounded candidate graph, including its negative controls. Limit revision attempts per cluster (initially three); retain failed candidates in authoring reports and move to other work. Report any missing required bridge honestly. + +## People and behavior + +Create about 30 named spotlight people with short bios and explicit decisions; derive the rest deterministically from richer persona templates. Suggested primary-role distribution for 240 people: 20 organizers, 35 project doers, 85 contributors, 25 funding directors, 25 reviewers/attesters/mediators, and 50 sign-only or mostly inactive people. Secondary roles overlap. + +For each person record topic interests, issue-specific beliefs, budget, risk tolerance, locality, trusted people, and explicit exclusions. Avoid a single left/right score that determines everything. A Christian home-schooler can dislike crypto; a liberal merchant can support low fees and cancellation due process while rejecting “unwoke”; a newcomer can favor language integration while rejecting immigration restrictions. + +Separate **interest in a family**, **signing a statement**, **accepting a modified statement**, **trusting an attester**, and **funding a project**. None automatically entails the next. Beliefs should select actions; actions should not randomly determine beliefs afterward. Distinguish leaving a statement unsigned from explicitly rejecting it. + +Reserve a small authored timeline for spotlight users: initial signatures, offered bridge, accept/decline, project discovery, contribution or delegation, later evidence, optional reimbursement donation or revocation. Ensure signatures of the modified statements are explicit persona choices. Other users can have sparse, uneven histories rather than all performing every action. + +Funding must respect available balances and preferences. Seed a few well-supported projects, many with partial momentum, some unfunded, and differing contributor concentration. Have risk-tolerant people contribute early and other people donate retroactively. Keep real synthetic token amounts consistent with displayed amounts; if demonstration budgets are scaled, document one explicit conversion and never display the unscaled number as money actually raised. + +## Required demonstration journeys + +Each journey needs named actors, stable IDs, expected balances/relationships, and a short browser walkthrough with actual generated links. + +1. **Founder sees an ecosystem:** a cause board contains base work and organizing work, with three projects at visibly different funding stages. The founder can see which role is still missing. +2. **Alliance without merger:** two differently motivated people contribute to the same project while retaining conflicting beliefs elsewhere. At least one journey uses a verified implication path; another uses direct shared agreement. +3. **A bridge is declined:** one person accepts a modified statement, another keeps the natural position and refuses it. The latter must not appear as a supporter of the compromise through a fabricated arrow. +4. **Early risk and later reimbursement:** early contributors reach a real contract threshold; later donors reimburse them through the existing waterfall. Separately identify funding success and fictional evidence of delivered work—crossing the threshold is not proof of delivery. +5. **Trust someone with a limited budget:** a donor delegates to a named friend for particular work, and the friend's supported spending path is exercised. Another donor revokes. Merely creating a delegation is not evidence that delegated spending happened. +6. **Same project, different boards:** one shared artifact appears on multiple justified boards without duplicate funding contracts or double-counted totals. Contradictory planks do not become implied endorsements. +7. **Independent judgment:** a reviewer declines alignment for a superficially relevant project; another project earns it. Where existing trust filtering supports it, two viewers see the expected difference. + +The brainstorming's “$20/month, fire-and-forget” and “delivered but not reimbursed” filter are goals to inspect against current implementation. Record whether each is supported, requires a small campaign adapter extension, or remains a product gap. If only a one-time delegated deposit works, label that exact demonstration and leave recurring execution unfulfilled. Do not simulate unsupported UI/contract behavior with prose and call it complete. + +## Implementation sequence + +### 1. Make a capability and content inventory + +Inspect current runner/schema and record reusable paths versus missing wiring. Known issues to address: `campaignSchema.ts` currently caps the catalog at 70 statement references and requires at least eight causes, while the pilot below has four; it also treats statement references across causes as unique. The planner's implication evidence currently uses accepted bridge-role pairs, which is insufficient for new evaluated campaign statements. Existing project/story and cross-camp funding selection may contain campaign-specific assumptions. + +Generalize those constraints with explicit campaign configuration and tests while preserving historical manifests. Keep unique catalog identity separate from board reuse. Add evidence references for evaluated edges. Inspect actual recurring-payment, delegated-spending, success-attestation, and trust APIs before promising them. Prefer small extensions to existing adapters; do not build a second simulator or a new platform subsystem for this demo. + +Deliverable: proposed artifact layout and a short supported/extension/gap table. This is implementation preparation, not another open-ended planning exercise. + +### 2. Author and validate a four-family pilot + +Use crypto-friendly communities, assimilation, Christianity, and home-schooling: about 40 users, 20 projects, and 40–60 statements. This tests different motivations, local work, religious/secular overlap, and reusable organizing goods. Include at least one candidate implication-backed alliance and negative controls. + +Store structured campaign-local content: statements, project briefs, personas/decisions, board definitions, candidate implication pairs, evaluation results, and journey expectations. These can be separate files or existing schema extensions; prefer readable data over new bespoke TypeScript story modules. + +Run authoring checks and freeze content/evaluation fingerprints before planning actions. Generate a plan into a fresh output path. Validate referential integrity, actor prerequisites, funding budgets, dissent consistency, and planned journey outcomes before submitting transactions. + +### 3. Execute locally and prove the stories + +Use the established local runner and reconciliation. Wipe local data only if useful; keep the old campaign's files intact. Verify real indexed/SDK-derived results and walk the pilot in the browser. Record what an ordinary viewer sees, not just transaction success. + +Fix failures before scaling. The first executed pilot is the point to discover that a beautiful bridge does not route, or that a donor cannot perform the intended action. + +### 4. Expand in bounded content batches + +Add the remaining eleven families in batches of three or four. First reuse accepted statements where they mean exactly what is needed; then generate new campaign-local planks and validate new edges. Add the accepted abortion bridge as a full spotlight story. Complete all fifteen families rather than declaring the pilot the finished campaign. + +Scale to the target population with deterministic generation around authored constraints. Review a content matrix showing family, statements, dissenters, projects, organizers, funding stages, and shared projects. Uneven activity is desirable; an accidentally empty family is not. + +### 5. Deliver a reproducible local demonstration + +Run the full campaign, reconcile it, and perform every required journey. Save the committed source manifest/content and concise run report; retain execution evidence and secrets in their established ignored locations. Provide exact reproduction commands, seed/fingerprints, generated run-viewer access instructions, spotlight users, project/board links, and known gaps. Update `fake-data-generation/PLAN.md` and README with a pointer once implementation lands. + +Remote/testnet publication is a separate later step using existing preflight, budgets, and mutation controls. Local completion should not depend on it. + +## Acceptance and handoff checklist + +- All fifteen families have several signable planks, incompatible positions, at least five substantive projects, and people whose actions match their stated preferences. +- Organizing work has concrete outputs and a term; no generic “fund our movement” pots. Each project explains the coordination problem it addresses: fragmented constituencies, threshold risk, maintenance nobody owns, discovery, or independent verification. Ordinary crowdfunding could still fund some projects; do not claim Commonality is uniquely necessary for every one. +- Every published implication has fresh, affirmative model evidence from the actual attester prompt. Negative controls, failed candidates, and routing/shape decisions remain inspectable. +- New campaign text stays outside the accepted real-statement catalog. Reused canonical bridge wording is referenced rather than silently rewritten. +- Automated checks cover beliefs/actions consistency, missing/invalid evidence, shared-project identity, budget accounting, execution prerequisites, and reconciliation. Run relevant existing campaign tests and workspace checks when code changes; test these failure modes rather than only snapshotting the generated prose. +- Required journeys have reconciled state and browser observations. Unsupported behaviors are listed as specific gaps, never counted as demonstrated; the full demo is not called complete while a required journey is silently missing. +- The report identifies synthetic users/activity/deliverables, actual amounts and outcomes, exact reproduction steps, and the next unfinished task if work spans sessions. + +**First task for the implementing LLM:** inspect the current campaign schema/planner/adapter and write the capability table, then author the four-family pilot content. Do not start with a bulk random run or by drafting all 200 statements at once. From 976eef509fd7a6e449605e5a37858d10508e25d0 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 14:04:49 -0400 Subject: [PATCH 05/19] Add the four-family network-societies campaign pilot. The planner can reuse one statement on several boards and load curated projects from JSON, with optional scale so a smaller manifest is valid. Implication edges stay unpublished. --- fake-data-generation/PLAN.md | 4 + fake-data-generation/README.md | 4 +- fake-data-generation/campaignPlanner.ts | 81 +++++++--- fake-data-generation/campaignSchema.ts | 36 ++++- .../campaigns/medium-realistic-v2.json | 2 +- .../network-societies-v1-pilot-decisions.json | 23 +++ .../network-societies-v1-pilot-projects.json | 130 +++++++++++++++ ...network-societies-v1-pilot-statements.json | 79 +++++++++ .../campaigns/network-societies-v1-pilot.json | 150 ++++++++++++++++++ .../campaigns/network-societies-v1-pilot.md | 45 ++++++ .../test/campaignPlanner.test.ts | 22 +++ specs/product/marketing/WALKTHROUGH-SETUP.md | 2 +- specs/product/marketing/demo-profiles.md | 4 +- 13 files changed, 553 insertions(+), 29 deletions(-) create mode 100644 fake-data-generation/campaigns/network-societies-v1-pilot-decisions.json create mode 100644 fake-data-generation/campaigns/network-societies-v1-pilot-projects.json create mode 100644 fake-data-generation/campaigns/network-societies-v1-pilot-statements.json create mode 100644 fake-data-generation/campaigns/network-societies-v1-pilot.json create mode 100644 fake-data-generation/campaigns/network-societies-v1-pilot.md diff --git a/fake-data-generation/PLAN.md b/fake-data-generation/PLAN.md index 9f53eb7b..59a06973 100644 --- a/fake-data-generation/PLAN.md +++ b/fake-data-generation/PLAN.md @@ -78,6 +78,10 @@ Do these in order unless Adam names a different one. Each item is a session-size 7. **[ ] Stress scale** (`gen:large` today is 100 users). 1000+ users, graphs, indexer deep-compare: not started. 8. **[ ] Incentive demonstrations** — three synthetic stories (Civility's changed choice, a negative replication, a shared migration where money is not a commitment). Inventory, scenarios, and the authoring template: [`incentive-demonstrations.md`](./incentive-demonstrations.md). Do not put that backlog back into the public strategy page. +### F — Network societies pilot + +Authoring for the four-family pilot (crypto merchants, Grey County civic life, Christian teaching, home learning) is in `campaigns/network-societies-v1-pilot.json` plus the statements, project, and decision files beside it. The capability table and the gaps that are still open are in [`campaigns/network-societies-v1-pilot.md`](./campaigns/network-societies-v1-pilot.md). The plan does not publish implication edges. Local execution and the other eleven families are still ahead. + ## Pointers - Kinds of data also summarized in [`README.md`](./README.md), [seed-content rationale](/specs/tech/subsystems/conceptspace/seed-content/README.md), [local development](/workflow/local-development.md). diff --git a/fake-data-generation/README.md b/fake-data-generation/README.md index cca37d84..37bc302c 100644 --- a/fake-data-generation/README.md +++ b/fake-data-generation/README.md @@ -15,7 +15,9 @@ The medium realistic campaign has a separate planning-only command: `npm run gen V2 includes seven campaign-local causes (music learning, car repair, gluten-free cooking, video game commons, small trades, congregational music, and staying productive), 19 campaign-local statements, and 16 named user profiles whose assigned interests drive their cause memberships. The campaign-local statements live beside the v2 manifest, outside `seed-content/`, so they do not enter the accepted real-statement catalog or the ordinary seed pipeline. V2 plans 100 users, 65 statements, 17 causes, and 37 projects. Each hobby cause has at least one project with a funding action, and the project founders have matching interests. Kurt, Fred, and Sean each pledge on every cause they join. Fred's game notes go to Kurt; his trades and church-music pledges stay in his own name. -V2 uses curated synthetic deliverables in `campaignProjectStories.ts`. Every cause gets a project; each project names the institutional blocker it illustrates. Bridge projects align only to the accepted commonality statement, so opposing natural positions are not spliced into a project outcome. V2 has been executed and reconciled locally; see [`campaigns/medium-realistic-v2-local-run.md`](./campaigns/medium-realistic-v2-local-run.md). Its funding actions still use a fixed on-chain purchase unit; they do not yet demonstrate cross-camp contributions or retroactive reimbursement. +V2 uses curated synthetic deliverables in `campaignProjectStories.ts`. Every cause gets a project; each project names the institutional blocker it illustrates. Bridge projects align only to the accepted commonality statement, so opposing natural positions are not spliced into a project outcome. V2 has been executed and reconciled locally; see [`campaigns/medium-realistic-v2-local-run.md`](./campaigns/medium-realistic-v2-local-run.md). + +The network-societies pilot is a separate manifest, `campaigns/network-societies-v1-pilot.json`. Plan it into a fresh directory: `npm run gen:campaign:plan -- campaigns/network-societies-v1-pilot.json output/campaigns/network-societies-v1-pilot`. Do not overwrite `output/campaigns/medium-realistic-v2/`. Notes: [`campaigns/network-societies-v1-pilot.md`](./campaigns/network-societies-v1-pilot.md). Its funding actions still use a fixed on-chain purchase unit; they do not yet demonstrate cross-camp contributions or retroactive reimbursement. The three spotlight profiles have an explicit first pledge for each joined cause in `SPOTLIGHT_PROJECTS` (`campaignProjectStories.ts`). The planner fails if a named project is missing. To preview current source, plan to a fresh directory; the existing `output/campaigns/medium-realistic-v2/` contains an executed run and must not be overwritten by a preview. Its saved assignments may reflect an earlier manifest. diff --git a/fake-data-generation/campaignPlanner.ts b/fake-data-generation/campaignPlanner.ts index 642f51f3..3d3c6dab 100644 --- a/fake-data-generation/campaignPlanner.ts +++ b/fake-data-generation/campaignPlanner.ts @@ -15,6 +15,8 @@ type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string export interface PlannedStatement { id: string; causeId: string; + /** Other boards that reuse this catalog statement. One publication, many boards. */ + alsoOnCauseIds?: string[]; source: { collectionId: string; groupId: string; statementId: string; fingerprint: string }; text: string; role: string | null; @@ -204,6 +206,10 @@ function validateImplicationPair(from: PlannedStatement, to: PlannedStatement): if (!sameGroup || !approved) throw new Error(`unsuitable implication ${from.id} -> ${to.id}: pair lacks accepted bridge-role evidence`); } +function statementsOnCause(statements: PlannedStatement[], causeId: string): PlannedStatement[] { + return statements.filter((statement) => statement.causeId === causeId || statement.alsoOnCauseIds?.includes(causeId)); +} + function usersForCause(users: PlannedUser[], causeId: string): PlannedUser[] { return users.filter((user) => user.causeIds.includes(causeId)); } @@ -214,7 +220,7 @@ function chooseCauseAttester(users: PlannedUser[], causeId: string, random: Xosh } function preferredStatements(user: PlannedUser, statements: PlannedStatement[]): PlannedStatement[] { - const inCauses = statements.filter((statement) => user.causeIds.includes(statement.causeId)); + const inCauses = statements.filter((statement) => user.causeIds.some((causeId) => statement.causeId === causeId || statement.alsoOnCauseIds?.includes(causeId))); if (!user.roles.includes('mediator')) return inCauses.filter((statement) => !statement.role?.startsWith('natural-')); return inCauses.filter((statement) => statement.role === null || statement.role === 'commonality' || statement.role.startsWith('modified-')); } @@ -235,6 +241,12 @@ function projectCopy(causeTitle: string, selected: PlannedStatement[]): { title: }; } +async function loadCampaignStories(manifest: CampaignManifestV1): Promise | null> { + if (!manifest.projectStories) return null; + const sourcePath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'campaigns', manifest.projectStories); + return JSON.parse(await readFile(sourcePath, 'utf8')) as Record; +} + export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise { validateCampaignManifest(manifest); const random = new Xoshiro128StarStar(manifest.campaign.deterministicSeed); @@ -248,11 +260,32 @@ export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise [statementKey({ collectionId: record.collection.id, groupId: record.group.id, statementId: record.statement.id }), record])); - const statements: PlannedStatement[] = manifest.causes.flatMap((cause) => cause.statementRefs.map((ref) => { - const record = recordByKey.get(statementKey(ref)); - if (!record || manifest.sourcePolicy.excludeCollections.includes(ref.collectionId)) throw new Error(`missing or excluded statement reference ${statementKey(ref)}`); - return { id: `statement-${cause.id}-${ref.statementId}`, causeId: cause.id, source: { ...ref, fingerprint: sha256(stableJson(record.statement)) }, text: record.statement.text, role: record.statement.role ?? null }; - })); + const statements: PlannedStatement[] = []; + const statementByKey = new Map(); + const allowReuse = manifest.scale?.allowRepeatedStatementRefs === true; + for (const cause of manifest.causes) { + for (const ref of cause.statementRefs) { + const key = statementKey(ref); + const existing = statementByKey.get(key); + if (existing) { + if (!allowReuse) throw new Error(`statement reference repeated without scale.allowRepeatedStatementRefs: ${key}`); + existing.alsoOnCauseIds = [...(existing.alsoOnCauseIds ?? []), cause.id]; + continue; + } + const record = recordByKey.get(key); + if (!record || manifest.sourcePolicy.excludeCollections.includes(ref.collectionId)) throw new Error(`missing or excluded statement reference ${key}`); + const planned: PlannedStatement = { + id: allowReuse ? `statement-${ref.groupId}-${ref.statementId}` : `statement-${cause.id}-${ref.statementId}`, + causeId: cause.id, + source: { ...ref, fingerprint: sha256(stableJson(record.statement)) }, + text: record.statement.text, + role: record.statement.role ?? null, + }; + statementByKey.set(key, planned); + statements.push(planned); + } + } + const storyDriven = await loadCampaignStories(manifest); const users: PlannedUser[] = []; const profiles = new Map((manifest.userProfiles ?? []).map((profile) => [profile.userId, profile])); @@ -276,26 +309,27 @@ export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise CAMPAIGN_PROJECT_STORIES[cause.id]?.map(() => cause.id) ?? []) + const projectStories = storyDriven ?? (useStories ? CAMPAIGN_PROJECT_STORIES : null); + const scheduledStoryCauses = projectStories + ? manifest.causes.flatMap((cause) => projectStories[cause.id]?.map(() => cause.id) ?? []) : []; - if (useStories && scheduledStoryCauses.length !== countByType['create-project']) { - throw new Error('v2 project target must match the curated story count'); + if (projectStories && scheduledStoryCauses.length !== countByType['create-project']) { + throw new Error('project target must match the curated story count'); } const storyCounts = new Map(); const projects: PlannedProject[] = Array.from({ length: countByType['create-project'] }, (_, index) => { - const scheduledCause = useStories ? scheduledStoryCauses[index] : undefined; + const scheduledCause = projectStories ? scheduledStoryCauses[index] : undefined; const eligibleFounders = scheduledCause ? projectFounders.filter((user) => user.causeIds.includes(scheduledCause)) : projectFounders; - const featuredFounders = useStories && scheduledCause + const featuredFounders = projectStories && scheduledCause ? eligibleFounders.filter((user) => user.favoriteCauseId === scheduledCause) : []; const founder = random.pick(featuredFounders.length ? featuredFounders : eligibleFounders.length ? eligibleFounders : projectFounders); const causeId = scheduledCause ?? random.pick(founder.causeIds); - const candidates = statements.filter((statement) => statement.causeId === causeId); + const candidates = statementsOnCause(statements, causeId); const storyIndex = storyCounts.get(causeId) ?? 0; storyCounts.set(causeId, storyIndex + 1); - const story = useStories ? CAMPAIGN_PROJECT_STORIES[causeId]?.[storyIndex % CAMPAIGN_PROJECT_STORIES[causeId].length] : undefined; - if (useStories && !story) throw new Error(`missing project story for ${causeId}`); + const story = projectStories ? projectStories[causeId]?.[storyIndex % projectStories[causeId].length] : undefined; + if (projectStories && !story) throw new Error(`missing project story for ${causeId}`); const selected = story ? story.statementRefs.map((ref) => { const match = candidates.find((statement) => statement.source.statementId === ref); @@ -317,10 +351,10 @@ export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise user.roles.includes('cause-founder') || user.roles.includes('power-user')); const causes = new Map(); for (const cause of manifest.causes) { - const group = statements.filter((statement) => statement.causeId === cause.id); + const group = statementsOnCause(statements, cause.id); const bridgeShaped = isBridgeCause(group); const byRole = new Map(group.map((statement) => [statement.role, statement])); - const interestedFounders = useStories ? causeFounders.filter((user) => user.favoriteCauseId === cause.id) : []; + const interestedFounders = projectStories ? causeFounders.filter((user) => user.favoriteCauseId === cause.id) : []; const actor = bridgeShaped ? random.pick(mediators) : random.pick(interestedFounders.length ? interestedFounders : causeFounders); const included = bridgeShaped ? [byRole.get('commonality')!] : group; const clusterSlug = bridgeShaped ? boardSlug(manifest.campaign.id, cause.id, 'cluster') : undefined; @@ -405,12 +439,17 @@ export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise user.activityWeight); const previous = index > Math.floor(countByType['set-belief'] * 0.92) && latestBelief.size > 0 ? random.pick([...latestBelief.values()]) : undefined; const statement = previous ? statements.find((item) => item.id === previous.statementId)! : random.pick(preferredStatements(actor, statements)); + const beliefActor = users.find((user) => user.id === (previous?.actorUserId ?? actor.id))!; + const causeId = beliefActor.causeIds.includes(statement.causeId) + ? statement.causeId + : beliefActor.causeIds.find((id) => statement.alsoOnCauseIds?.includes(id)); + if (!causeId) throw new Error(`no board for ${beliefActor.id} to sign ${statement.id}`); const belief = previous ? (previous.belief === 'believe' ? 'disbelieve' : 'believe') : (random.next() < 0.94 ? 'believe' : 'disbelieve'); - const action = add({ type: 'set-belief', actorUserId: previous?.actorUserId ?? actor.id, causeId: statement.causeId, statementId: statement.id, belief, dependsOn: previous ? [publishes.get(statement.id)!.id, previous.id] : [publishes.get(statement.id)!.id] }); + const action = add({ type: 'set-belief', actorUserId: beliefActor.id, causeId, statementId: statement.id, belief, dependsOn: previous ? [publishes.get(statement.id)!.id, previous.id] : [publishes.get(statement.id)!.id] }); latestBelief.set(`${action.actorUserId}/${statement.id}`, action); } const implicationPairs = manifest.causes.flatMap((cause) => { - const groupStatements = statements.filter((statement) => statement.causeId === cause.id); + const groupStatements = statementsOnCause(statements, cause.id); const commonality = groupStatements.find((statement) => statement.role === 'commonality'); return commonality ? groupStatements.filter((statement) => statement.role === 'modified-left' || statement.role === 'modified-right').map((from) => ({ from, to: commonality })) : []; }); @@ -427,11 +466,11 @@ export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise(); - if (useStories) for (const project of projects) { + if (projectStories) for (const project of projects) { if (!firstByCause.has(project.causeId)) firstByCause.set(project.causeId, project); } const firstProjects = [...firstByCause.values()]; - const fundableProjects = useStories + const fundableProjects = projectStories ? [...firstProjects, ...projects.filter((project) => !firstProjects.includes(project))].slice(0, fundableCount) : projects.slice(0, fundableCount); const hobbyCauses = ['music-learning', 'car-repair', 'gluten-free-cooking', 'game-commons']; diff --git a/fake-data-generation/campaignSchema.ts b/fake-data-generation/campaignSchema.ts index c58edcf2..fadc765e 100644 --- a/fake-data-generation/campaignSchema.ts +++ b/fake-data-generation/campaignSchema.ts @@ -68,6 +68,16 @@ export interface CampaignActionRule { targetCount: { min: number; max: number }; } +/** Explicit size bounds. Omitted manifests keep the historical 8–18 causes and 30–70 statement refs. */ +export interface CampaignScale { + minCauses: number; + maxCauses: number; + /** Unique catalog statements. A statement reused on another board counts once. */ + minStatements: number; + maxStatements: number; + allowRepeatedStatementRefs?: boolean; +} + export interface CampaignManifestV1 { schema: typeof CAMPAIGN_SCHEMA_VERSION; campaign: { @@ -90,6 +100,10 @@ export interface CampaignManifestV1 { userProfiles?: CampaignUserProfile[]; actionRules: CampaignActionRule[]; artifactLayout: Record; + /** When set, replaces the historical fixed cause and statement-ref caps. */ + scale?: CampaignScale; + /** Curated project stories beside the manifest. Not a TypeScript story module. */ + projectStories?: string; } function requireUnique(values: string[], label: string): void { @@ -106,13 +120,26 @@ function validateCampaignIdentity(manifest: CampaignManifestV1): void { if (!campaign.deterministicSeed) throw new Error('campaign.deterministicSeed is required'); } +function campaignScale(manifest: CampaignManifestV1): CampaignScale { + return manifest.scale ?? { minCauses: 8, maxCauses: 18, minStatements: 30, maxStatements: 70, allowRepeatedStatementRefs: false }; +} + function validateCauses(manifest: CampaignManifestV1): void { - if (manifest.causes.length < 8 || manifest.causes.length > 18) throw new Error('campaign must contain 8-18 causes'); + const scale = campaignScale(manifest); + if (manifest.scale && (scale.minCauses < 1 || scale.maxCauses < scale.minCauses || scale.minStatements < 1 || scale.maxStatements < scale.minStatements)) { + throw new Error('campaign scale limits are invalid'); + } + if (manifest.causes.length < scale.minCauses || manifest.causes.length > scale.maxCauses) { + throw new Error(manifest.scale ? `campaign must contain ${scale.minCauses}-${scale.maxCauses} causes` : 'campaign must contain 8-18 causes'); + } requireUnique(manifest.causes.map((cause) => cause.id), 'cause IDs'); const statementRefs = manifest.causes.flatMap((cause) => cause.statementRefs); const statementKeys = statementRefs.map((ref) => `${ref.collectionId}/${ref.groupId}/${ref.statementId}`); - requireUnique(statementKeys, 'statement references'); - if (statementRefs.length < 30 || statementRefs.length > 70) throw new Error('campaign must contain 30-70 statements'); + if (!scale.allowRepeatedStatementRefs) requireUnique(statementKeys, 'statement references'); + const uniqueStatements = new Set(statementKeys).size; + if (uniqueStatements < scale.minStatements || uniqueStatements > scale.maxStatements) { + throw new Error(manifest.scale ? `campaign must contain ${scale.minStatements}-${scale.maxStatements} unique statements` : 'campaign must contain 30-70 statements'); + } if (manifest.causes.some((cause) => cause.membershipWeight <= 0 || cause.statementRefs.length === 0)) { throw new Error('every cause needs a positive membership weight and at least one statement'); } @@ -185,6 +212,9 @@ export function validateCampaignManifest(manifest: CampaignManifestV1): void { if (manifest.sourcePolicy.campaignCollection && !/^[a-z0-9][a-z0-9-]*\.json$/.test(manifest.sourcePolicy.campaignCollection)) { throw new Error('sourcePolicy.campaignCollection must be a JSON filename in campaigns/'); } + if (manifest.projectStories && !/^[a-z0-9][a-z0-9-]*\.json$/.test(manifest.projectStories)) { + throw new Error('projectStories must be a JSON filename in campaigns/'); + } validateCauses(manifest); validatePersonas(manifest); validateActionRules(manifest); diff --git a/fake-data-generation/campaigns/medium-realistic-v2.json b/fake-data-generation/campaigns/medium-realistic-v2.json index 7d25b5df..8b46a434 100644 --- a/fake-data-generation/campaigns/medium-realistic-v2.json +++ b/fake-data-generation/campaigns/medium-realistic-v2.json @@ -144,7 +144,7 @@ { "userId": "user-083", "displayName": "Kurt", "bio": "Fixes cars for a living in Grey County, Ontario, and plays guitar at church. He would like the basics of music theory, plays video games, and has celiac disease. He would pledge toward repair references, a tested gluten-free substitution table, open music-theory tools, and shared game infrastructure. He may delegate retroactive funding.", "favoriteCauseId": "car-repair", "interests": ["Christianity", "fixing cars", "gluten-free", "guitar", "video games"], "causeIds": ["car-repair", "gluten-free-cooking", "game-commons", "music-learning"], "spotlightOrder": 1 }, { "userId": "user-029", "displayName": "Fred", "bio": "Lives in Grey County, Ontario, and works as a contractor doing general handyman jobs. He plays video games and would delegate that pledge to Kurt. On his own he would pledge to shared contractor tools and to chord charts for the songs his church sings. He might attest that a real-world organization lines up with a cause.", "favoriteCauseId": "game-commons", "interests": ["Christianity", "contracting", "handyman work", "video games"], "causeIds": ["game-commons", "small-trades", "congregational-music"], "delegatesTo": "user-083", "spotlightOrder": 2 }, { "userId": "user-084", "displayName": "Sean", "bio": "Lives in Grey County, Ontario. He cares about local agriculture and about staying productive while managing stress. He would pledge to shared farm equipment and variety trials, and to a public work-rest trial. He may delegate retroactive funding, and might attest that a real-world organization lines up with a cause.", "favoriteCauseId": "local-food", "interests": ["local agriculture", "managing stress"], "causeIds": ["local-food", "staying-productive"], "spotlightOrder": 3 }, - { "userId": "user-031", "displayName": "Sam (casual donor)", "bio": "Wants to support local public goods with $20/month but doesn't have time to research every option.", "favoriteCauseId": "local-food", "interests": ["hands-off giving", "local community"] }, + { "userId": "user-031", "displayName": "Casey (casual donor)", "bio": "Wants to support local public goods with $20/month but doesn't have time to research every option.", "favoriteCauseId": "local-food", "interests": ["hands-off giving", "local community"] }, { "userId": "user-060", "displayName": "Alex (community organizer)", "bio": "Runs a neighborhood club and wants to coordinate volunteers without becoming a nonprofit.", "favoriteCauseId": "education", "interests": ["volunteer coordination", "neighborhood projects"] }, { "userId": "user-073", "displayName": "Jordan (expert scout)", "bio": "Evaluates whether open-source projects actually deliver on their promises before recommending funding.", "favoriteCauseId": "open-source", "interests": ["technical evaluation", "accountability"] }, { "userId": "user-076", "displayName": "Taylor (project founder)", "bio": "Building an open dataset for neglected diseases and needs sustainable funding beyond grants.", "favoriteCauseId": "open-science", "interests": ["public health", "open data"] }, diff --git a/fake-data-generation/campaigns/network-societies-v1-pilot-decisions.json b/fake-data-generation/campaigns/network-societies-v1-pilot-decisions.json new file mode 100644 index 00000000..85c57f5c --- /dev/null +++ b/fake-data-generation/campaigns/network-societies-v1-pilot-decisions.json @@ -0,0 +1,23 @@ +{ + "note": "Authored persona decisions for the pilot. The planner does not yet apply these belief choices. Unsigned is not the same as an explicit rejection.", + "people": [ + { "userId": "user-001", "name": "Ruth", "signs": ["refundable-checkout", "published-trial-record", "fee-schedule", "keep-cash-and-card"], "rejects": ["refuse-crypto-payments"], "funds": "Six-shop refundable checkout trial" }, + { "userId": "user-003", "name": "Imani", "signs": ["language-sessions", "welcome-signage", "session-limit"], "rejects": ["housing-before-recruiting"], "funds": "Twelve conversation sessions" }, + { "userId": "user-006", "name": "Doug", "signs": ["park-paths", "english-township-business", "housing-before-recruiting"], "rejects": ["own-language-communities"], "funds": "Harrison Park path season" }, + { "userId": "user-004", "name": "Owen", "signs": ["science-unit", "no-religious-claims", "school-families-may-borrow", "class-host-directory"], "rejects": ["midweek-notes", "keep-notes-inside"], "unsigned": ["staffed-schools"] }, + { "userId": "user-002", "name": "Helen", "signs": ["midweek-notes", "named-confession", "no-joint-doctrine", "class-host-directory"], "rejects": ["civic-transcription-only"] }, + { "userId": "user-005", "name": "Len", "signs": ["keep-cash-and-card", "refundable-checkout"], "rejects": ["refuse-crypto-payments"], "notes": "Direct agreement with Ruth on the trial. Not an implication bridge." }, + { "userId": "user-021", "name": "Pat", "delegatesTo": "user-011", "limitedTo": "crypto-merchants", "revokes": true, "notes": "Ned (user-011) is a delegate who shares Pat's causes, so the planner can name Ned on Pat's notes. Delegated spending is not an action in the current adapter. Revocation is planned for some notes, not necessarily Pat's." }, + { "userId": "user-016", "name": "June", "declinesAlignment": "A project that merely mentions Grey County is not enough.", "grantsAlignment": "Independent checkout security review against checkout-security-review" } + ], + "implicationCandidates": { + "status": "unevaluated", + "reason": "No fresh affirmative result from the real implication-attester prompt is stored. The pilot therefore publishes no implication edges.", + "proposed": [ + { "from": "keep-cash-and-card", "to": "refundable-checkout", "expect": "negative", "why": "Keeping cards does not imply wanting a crypto trial." }, + { "from": "language-sessions", "to": "housing-before-recruiting", "expect": "negative", "why": "Wanting classes does not imply a recruiting pause." }, + { "from": "class-host-directory", "to": "midweek-notes", "expect": "negative", "why": "A checked directory does not imply releasing church notes." } + ], + "allianceNotRequiringABridge": "Ruth and Len can both fund the checkout trial while Len refuses a crypto-identity plank. That is existing overlap, not a modified-statement triple." + } +} diff --git a/fake-data-generation/campaigns/network-societies-v1-pilot-projects.json b/fake-data-generation/campaigns/network-societies-v1-pilot-projects.json new file mode 100644 index 00000000..504f215f --- /dev/null +++ b/fake-data-generation/campaigns/network-societies-v1-pilot-projects.json @@ -0,0 +1,130 @@ +{ + "crypto-merchants": [ + { + "title": "Six-shop refundable checkout trial", + "outcome": "Ship an open-source checkout, with refunds, and run it for three months at six named Owen Sound shops. Publish the code and the shop list.", + "statementRefs": ["refundable-checkout", "published-trial-record"], + "blocker": "No one shop can justify building a checkout whose useful result is a public trial record" + }, + { + "title": "Independent checkout security review", + "outcome": "Pay a reviewer who does not write the checkout to publish findings and unfixed items before the Owen Sound trial ends.", + "statementRefs": ["checkout-security-review"], + "blocker": "The shops and the programmer are poor judges of their own security claims" + }, + { + "title": "Fee and failure table", + "outcome": "Publish the fee on a twenty-dollar Owen Sound trial sale, and a table of failed payments, before anyone calls the trial a success.", + "statementRefs": ["fee-schedule", "published-trial-record"], + "blocker": "The numbers are useful to every later shop and owned by none of them" + }, + { + "title": "Owen Sound merchant directory", + "outcome": "Maintain, for one year, a directory that shows which trial shops still take the checkout and which shops stopped, with the date of each change.", + "statementRefs": ["merchant-directory"], + "blocker": "A directory nobody maintains becomes an advertisement" + }, + { + "title": "Quarterly checkout clinic and host kit", + "outcome": "Run four Saturday clinics in Owen Sound and leave a host kit so a second person can run the next one.", + "statementRefs": ["deployment-clinic", "host-kit"], + "blocker": "The clinic stops when the first host is busy unless the hosting steps are written down" + } + ], + "civic-assimilation": [ + { + "title": "Twelve conversation sessions", + "outcome": "Hold twelve English conversation sessions in Owen Sound with childcare in the room, and publish attendance without naming children.", + "statementRefs": ["language-sessions"], + "blocker": "Childcare and a room have to be paid before the first session, and no single family captures the benefit" + }, + { + "title": "Grey County civics pack", + "outcome": "Write and release a plain-English pack for the library, the bus, a school meeting, and a township office in Grey County.", + "statementRefs": ["civics-pack"], + "blocker": "Each office explains itself differently, and no office is paid to write the combined pack" + }, + { + "title": "Harrison Park path season", + "outcome": "Run one summer of path repair in Harrison Park, Owen Sound, with newcomers and long-time residents, and publish hours and costs.", + "statementRefs": ["park-paths"], + "blocker": "The work needs a full season of tools and insurance before anyone can see the paths" + }, + { + "title": "Conversation-session handoff", + "outcome": "Write the steps, contacts, and childcare arrangements so a second organizer can run the next Owen Sound session series.", + "statementRefs": ["organizer-handoff"], + "blocker": "The sessions are a public good only if they survive the first organizer" + }, + { + "title": "Independent tutor-listing check", + "outcome": "For one season, have someone who does not run the sessions check Grey County language-tutor listings and publish which listings failed.", + "statementRefs": ["tutor-check"], + "blocker": "A directory checked by its own organizer does not answer a skeptic" + } + ], + "christian-teaching": [ + { + "title": "Midweek class notes", + "outcome": "Release the notes for one Grey County congregation's midweek class under terms another congregation can reuse.", + "statementRefs": ["midweek-notes", "named-confession"], + "blocker": "The second congregation can copy the notes, so neither congregation is paid by the other to write them" + }, + { + "title": "Midweek class transcript", + "outcome": "Transcribe that class for people who cannot hear the recordings, and publish the transcript with the confession named.", + "statementRefs": ["transcription", "named-confession"], + "blocker": "Transcription is useful to every later listener and costly to the first congregation" + }, + { + "title": "One-season substitute rota", + "outcome": "Publish a Sunday rota and sermon notes so a substitute can preach at one named Grey County church for one season.", + "statementRefs": ["substitute-rota", "interchurch-calendar"], + "blocker": "Each small church has too few substitutes to keep the rota alone" + }, + { + "title": "Second-church host kit", + "outcome": "Write a one-season kit so a second Grey County church can run the same rota without the first host.", + "statementRefs": ["host-kit"], + "blocker": "The rota dies with the first host unless the steps are written down" + }, + { + "title": "Grey County class-host directory", + "outcome": "Publish one directory of Grey County people who will host a small class, with affiliation and an independent checker's note, and maintain it for one year.", + "statementRefs": ["class-host-directory"], + "blocker": "Churches, tutors, and home-school hosts each need the same checked list, and none of them owns it" + } + ], + "home-learning": [ + { + "title": "Printable grade-six science unit", + "outcome": "Release one grade-six science unit a Grey County family can print, with the teaching method named on the first page and no religious claims in the activities.", + "statementRefs": ["science-unit", "method-on-the-page", "no-religious-claims"], + "blocker": "Every family can copy the unit after the first author writes it" + }, + { + "title": "Grey County field-trip pack", + "outcome": "Release the permission form, map, and safety notes for one Grey County field trip so another family, including a school family, can run it.", + "statementRefs": ["field-trip", "school-families-may-borrow"], + "blocker": "The first family pays for the reconnaissance and every later family can copy the pack" + }, + { + "title": "Store-item science kits", + "outcome": "Publish instructions for a home science kit of ordinary store items, including hazards and the adult supervision each activity needs.", + "statementRefs": ["science-kits", "lab-safety"], + "blocker": "A safe kit has to be tried once before other families can reuse it" + }, + { + "title": "Eight Owen Sound Saturdays", + "outcome": "Host eight Saturday meetups in Owen Sound for home-school families and publish the dates before the first meeting.", + "statementRefs": ["saturday-meetups"], + "blocker": "The room and the dates have to be reserved before any family can rely on them" + }, + { + "title": "Successor host notes", + "outcome": "Name a successor and write the notes so the Owen Sound meetups can run a second season without the first host.", + "statementRefs": ["successor-host"], + "blocker": "A meetup series that only the first host can run is not a maintained public good" + } + ] +} diff --git a/fake-data-generation/campaigns/network-societies-v1-pilot-statements.json b/fake-data-generation/campaigns/network-societies-v1-pilot-statements.json new file mode 100644 index 00000000..0848af3f --- /dev/null +++ b/fake-data-generation/campaigns/network-societies-v1-pilot-statements.json @@ -0,0 +1,79 @@ +{ + "format": "commonality-seed-content-v1", + "id": "network-societies-v1", + "title": "Synthetic network-societies pilot statements", + "description": "Campaign-local synthetic statements for the four-family network-societies pilot. They are not accepted real Conceptspace seed content.", + "notes": ["Synthetic campaign only. Do not copy these into seed-content/."], + "groups": [ + { + "id": "crypto-merchants", + "title": "Crypto-friendly merchant trials in Owen Sound", + "statements": [ + { "id": "refundable-checkout", "text": "I want six named shops in Owen Sound, Ontario, to be able to try a checkout that takes a crypto payment and can refund it, for a three-month trial." }, + { "id": "published-trial-record", "text": "I want the Owen Sound crypto-checkout trial to publish every fee, failed payment, and refund from those three months." }, + { "id": "checkout-security-review", "text": "I want an independent reviewer to publish the security findings in the Owen Sound trial checkout, including findings the shops have not yet fixed." }, + { "id": "merchant-directory", "text": "I want a directory of Owen Sound shops in the checkout trial that says which shops are still taking the payment and which shops stopped." }, + { "id": "deployment-clinic", "text": "I want a quarterly Saturday clinic in Owen Sound where a shop can run one test sale on the trial checkout and leave with a written result." }, + { "id": "host-kit", "text": "I want a written host kit so a second person can run the next Owen Sound checkout clinic without the first host." }, + { "id": "keep-cash-and-card", "text": "I want every shop in the Owen Sound crypto trial to keep taking cash and ordinary cards for the whole three months." }, + { "id": "refuse-crypto-payments", "text": "I want shops in Owen Sound to refuse customer payments in crypto." }, + { "id": "bank-blocking", "text": "I want a willing Owen Sound shop and a willing customer to be able to complete a payment when a bank has blocked that customer." }, + { "id": "fee-schedule", "text": "I want the Owen Sound trial checkout to show the fee for a twenty-dollar sale before the customer pays." } + ] + }, + { + "id": "civic-assimilation", + "title": "Shared civic life in Grey County", + "statements": [ + { "id": "language-sessions", "text": "I want twelve practical English conversation sessions in Owen Sound, Ontario, with childcare in the room, for newcomers and long-time residents together." }, + { "id": "civics-pack", "text": "I want a reusable pack that explains, in plain English, how a person in Grey County uses the library, the bus, a school meeting, and a township office." }, + { "id": "park-paths", "text": "I want one summer of newcomers and long-time residents repairing paths in Harrison Park, Owen Sound, with the hours and costs published at the end." }, + { "id": "tutor-check", "text": "I want the Grey County language-tutor listings checked by someone who does not run the sessions, including a public note when a listing fails the check." }, + { "id": "organizer-handoff", "text": "I want a written handoff so a second organizer can run the next Owen Sound conversation session without the first organizer." }, + { "id": "english-township-business", "text": "I want township business in Grey County to stay in English, including when language classes are offered." }, + { "id": "own-language-communities", "text": "I want newcomers in Grey County to be able to keep their own language communities without a public program that expects them to adopt local customs." }, + { "id": "housing-before-recruiting", "text": "I want Grey County to stop recruiting more newcomers until the published housing and clinic wait times get shorter." }, + { "id": "welcome-signage", "text": "I want the Owen Sound bus terminal and library to post, in the languages already spoken in town, where the conversation sessions meet." }, + { "id": "session-limit", "text": "I want the Owen Sound conversation sessions to teach practical English, and I want them to stop short of telling newcomers which customs to keep." } + ] + }, + { + "id": "christian-teaching", + "title": "Christian teaching resources in Grey County", + "statements": [ + { "id": "midweek-notes", "text": "I want the teaching notes for one Grey County congregation's midweek class released so another congregation can reuse them." }, + { "id": "transcription", "text": "I want the recordings of that Grey County midweek class transcribed for people who cannot hear them." }, + { "id": "substitute-rota", "text": "I want a published rota and sermon notes so a substitute can preach at a named Grey County church when the regular preacher is away for one season." }, + { "id": "named-confession", "text": "I want shared Grey County teaching notes to name the confession they come from." }, + { "id": "no-joint-doctrine", "text": "I want congregations that reuse the same Grey County teaching notes to stop short of publishing a joint statement of doctrine." }, + { "id": "host-kit", "text": "I want a one-season host kit so a second Grey County church can run the substitute-preacher rota after the first season." }, + { "id": "civic-transcription-only", "text": "I want to help transcribe public civic materials in Grey County, and I do not want that work to include church teaching." }, + { "id": "keep-notes-inside", "text": "I want a congregation's teaching notes to stay inside that congregation." }, + { "id": "interchurch-calendar", "text": "I want a public calendar of which Grey County church is short a preacher on which Sunday this season." } + ] + }, + { + "id": "home-learning", + "title": "Home learning in Grey County", + "statements": [ + { "id": "science-unit", "text": "I want one open grade-six science unit, with materials a Grey County home-school family can print." }, + { "id": "field-trip", "text": "I want the permission form, map, and safety notes for one Grey County field trip released so another family can run the same trip." }, + { "id": "science-kits", "text": "I want instructions for a home science kit that uses ordinary store items, written so a Grey County family can repeat it." }, + { "id": "saturday-meetups", "text": "I want eight Saturday meetups in Owen Sound for home-school families, with the dates published before the first meeting." }, + { "id": "successor-host", "text": "I want a named successor, and written notes, so the Owen Sound home-school meetups can continue for a second season without the first host." }, + { "id": "method-on-the-page", "text": "I want each Grey County home-school unit to say which teaching method it uses." }, + { "id": "no-religious-claims", "text": "I want a Grey County science unit that contains no religious claims, so a secular home-school family can use it." }, + { "id": "school-families-may-borrow", "text": "I want families whose children attend school in Grey County to be allowed to use the same field-trip notes." }, + { "id": "staffed-schools", "text": "I want children in Grey County taught in staffed schools, and I do not want public rooms booked for home-school programs." }, + { "id": "lab-safety", "text": "I want the Grey County home science kit to list the hazards and the adult supervision each activity needs." } + ] + }, + { + "id": "shared-goods", + "title": "Goods reused across Grey County boards", + "statements": [ + { "id": "class-host-directory", "text": "I want a public directory of people in Grey County, Ontario, who will host a small class, with each host's affiliation written down and a note when an independent checker has confirmed the listing." } + ] + } + ] +} diff --git a/fake-data-generation/campaigns/network-societies-v1-pilot.json b/fake-data-generation/campaigns/network-societies-v1-pilot.json new file mode 100644 index 00000000..30cbb2dd --- /dev/null +++ b/fake-data-generation/campaigns/network-societies-v1-pilot.json @@ -0,0 +1,150 @@ +{ + "schema": "commonality-testnet-campaign-v1", + "campaign": { + "id": "network-societies-v1-pilot", + "label": "Network societies pilot — four families", + "syntheticDataLabel": "SYNTHETIC CAMPAIGN — NOT REAL USERS, ORGANIZATIONS, OR DELIVERABLES", + "userCount": 40, + "deterministicSeed": "commonality-network-societies-v1-pilot-2026-10-16", + "randomAlgorithm": "xoshiro128**" + }, + "sourcePolicy": { + "kind": "accepted-plus-campaign-synthetic", + "fingerprintAlgorithm": "sha256", + "excludeCollections": ["proliferation"], + "campaignCollection": "network-societies-v1-pilot-statements.json" + }, + "scale": { + "minCauses": 4, + "maxCauses": 6, + "minStatements": 40, + "maxStatements": 40, + "allowRepeatedStatementRefs": true + }, + "projectStories": "network-societies-v1-pilot-projects.json", + "causes": [ + { + "id": "crypto-merchants", + "title": "Owen Sound checkout trial", + "activityTier": "large", + "membershipWeight": 12, + "statementRefs": [ + { "collectionId": "network-societies-v1", "groupId": "crypto-merchants", "statementId": "refundable-checkout" }, + { "collectionId": "network-societies-v1", "groupId": "crypto-merchants", "statementId": "published-trial-record" }, + { "collectionId": "network-societies-v1", "groupId": "crypto-merchants", "statementId": "checkout-security-review" }, + { "collectionId": "network-societies-v1", "groupId": "crypto-merchants", "statementId": "merchant-directory" }, + { "collectionId": "network-societies-v1", "groupId": "crypto-merchants", "statementId": "deployment-clinic" }, + { "collectionId": "network-societies-v1", "groupId": "crypto-merchants", "statementId": "host-kit" }, + { "collectionId": "network-societies-v1", "groupId": "crypto-merchants", "statementId": "keep-cash-and-card" }, + { "collectionId": "network-societies-v1", "groupId": "crypto-merchants", "statementId": "refuse-crypto-payments" }, + { "collectionId": "network-societies-v1", "groupId": "crypto-merchants", "statementId": "bank-blocking" }, + { "collectionId": "network-societies-v1", "groupId": "crypto-merchants", "statementId": "fee-schedule" } + ] + }, + { + "id": "civic-assimilation", + "title": "Grey County civic life", + "activityTier": "large", + "membershipWeight": 12, + "statementRefs": [ + { "collectionId": "network-societies-v1", "groupId": "civic-assimilation", "statementId": "language-sessions" }, + { "collectionId": "network-societies-v1", "groupId": "civic-assimilation", "statementId": "civics-pack" }, + { "collectionId": "network-societies-v1", "groupId": "civic-assimilation", "statementId": "park-paths" }, + { "collectionId": "network-societies-v1", "groupId": "civic-assimilation", "statementId": "tutor-check" }, + { "collectionId": "network-societies-v1", "groupId": "civic-assimilation", "statementId": "organizer-handoff" }, + { "collectionId": "network-societies-v1", "groupId": "civic-assimilation", "statementId": "english-township-business" }, + { "collectionId": "network-societies-v1", "groupId": "civic-assimilation", "statementId": "own-language-communities" }, + { "collectionId": "network-societies-v1", "groupId": "civic-assimilation", "statementId": "housing-before-recruiting" }, + { "collectionId": "network-societies-v1", "groupId": "civic-assimilation", "statementId": "welcome-signage" }, + { "collectionId": "network-societies-v1", "groupId": "civic-assimilation", "statementId": "session-limit" }, + { "collectionId": "network-societies-v1", "groupId": "shared-goods", "statementId": "class-host-directory" } + ] + }, + { + "id": "christian-teaching", + "title": "Grey County Christian teaching", + "activityTier": "medium", + "membershipWeight": 10, + "statementRefs": [ + { "collectionId": "network-societies-v1", "groupId": "christian-teaching", "statementId": "midweek-notes" }, + { "collectionId": "network-societies-v1", "groupId": "christian-teaching", "statementId": "transcription" }, + { "collectionId": "network-societies-v1", "groupId": "christian-teaching", "statementId": "substitute-rota" }, + { "collectionId": "network-societies-v1", "groupId": "christian-teaching", "statementId": "named-confession" }, + { "collectionId": "network-societies-v1", "groupId": "christian-teaching", "statementId": "no-joint-doctrine" }, + { "collectionId": "network-societies-v1", "groupId": "christian-teaching", "statementId": "host-kit" }, + { "collectionId": "network-societies-v1", "groupId": "christian-teaching", "statementId": "civic-transcription-only" }, + { "collectionId": "network-societies-v1", "groupId": "christian-teaching", "statementId": "keep-notes-inside" }, + { "collectionId": "network-societies-v1", "groupId": "christian-teaching", "statementId": "interchurch-calendar" }, + { "collectionId": "network-societies-v1", "groupId": "shared-goods", "statementId": "class-host-directory" } + ] + }, + { + "id": "home-learning", + "title": "Grey County home learning", + "activityTier": "medium", + "membershipWeight": 10, + "statementRefs": [ + { "collectionId": "network-societies-v1", "groupId": "home-learning", "statementId": "science-unit" }, + { "collectionId": "network-societies-v1", "groupId": "home-learning", "statementId": "field-trip" }, + { "collectionId": "network-societies-v1", "groupId": "home-learning", "statementId": "science-kits" }, + { "collectionId": "network-societies-v1", "groupId": "home-learning", "statementId": "saturday-meetups" }, + { "collectionId": "network-societies-v1", "groupId": "home-learning", "statementId": "successor-host" }, + { "collectionId": "network-societies-v1", "groupId": "home-learning", "statementId": "method-on-the-page" }, + { "collectionId": "network-societies-v1", "groupId": "home-learning", "statementId": "no-religious-claims" }, + { "collectionId": "network-societies-v1", "groupId": "home-learning", "statementId": "school-families-may-borrow" }, + { "collectionId": "network-societies-v1", "groupId": "home-learning", "statementId": "staffed-schools" }, + { "collectionId": "network-societies-v1", "groupId": "home-learning", "statementId": "lab-safety" }, + { "collectionId": "network-societies-v1", "groupId": "shared-goods", "statementId": "class-host-directory" } + ] + } + ], + "personas": [ + { "id": "community-organizer", "count": 4, "roles": ["cause-founder", "supporter"], "causesPerUser": { "min": 2, "max": 3 }, "activityWeight": 2, "inactivityRate": 0, "fundingWeight": 1.2 }, + { "id": "project-builder", "count": 6, "roles": ["project-founder", "supporter"], "causesPerUser": { "min": 1, "max": 2 }, "activityWeight": 1.7, "inactivityRate": 0, "fundingWeight": 0.8 }, + { "id": "trusted-delegate", "count": 5, "roles": ["delegate", "supporter"], "causesPerUser": { "min": 2, "max": 4 }, "activityWeight": 2, "inactivityRate": 0, "fundingWeight": 1.4 }, + { "id": "bridge-mediator", "count": 5, "roles": ["attester", "mediator"], "causesPerUser": { "min": 2, "max": 4 }, "activityWeight": 2, "inactivityRate": 0, "fundingWeight": 0.4 }, + { "id": "regular-supporter", "count": 14, "roles": ["supporter"], "causesPerUser": { "min": 1, "max": 3 }, "activityWeight": 1, "inactivityRate": 0.1, "fundingWeight": 1 }, + { "id": "quiet-neighbor", "count": 6, "roles": ["lurker", "supporter"], "causesPerUser": { "min": 1, "max": 2 }, "activityWeight": 0.2, "inactivityRate": 0.4, "fundingWeight": 0.3 } + ], + "userProfiles": [ + { "userId": "user-001", "displayName": "Ruth", "bio": "Keeps the books for a shop in Owen Sound and wants the checkout trial's fees published. She will not sign a demand that shops refuse crypto.", "favoriteCauseId": "crypto-merchants", "interests": ["shop fees", "Owen Sound"], "causeIds": ["crypto-merchants", "civic-assimilation"], "spotlightOrder": 1 }, + { "userId": "user-002", "displayName": "Helen", "bio": "Preaches at a small Grey County church and wants the midweek notes reusable, with the confession named. She does not treat a shared host directory as agreement on doctrine.", "favoriteCauseId": "christian-teaching", "interests": ["preaching", "Grey County churches"], "causeIds": ["christian-teaching", "home-learning"], "spotlightOrder": 2 }, + { "userId": "user-003", "displayName": "Imani", "bio": "Recently moved to Owen Sound and wants the twelve conversation sessions with childcare. She rejects the demand to stop recruiting newcomers.", "favoriteCauseId": "civic-assimilation", "interests": ["English practice", "Owen Sound"], "causeIds": ["civic-assimilation", "crypto-merchants"], "spotlightOrder": 3 }, + { "userId": "user-004", "displayName": "Owen", "bio": "Home-schools in Grey County and wants the printable science unit with no religious claims. He will not sign a request to release a congregation's midweek notes.", "favoriteCauseId": "home-learning", "interests": ["home science", "Grey County"], "causeIds": ["home-learning", "christian-teaching"], "spotlightOrder": 4 }, + { "userId": "user-005", "displayName": "Len", "bio": "Runs a shop that wants to keep cash and cards while trying the refundable checkout. He is not a crypto enthusiast.", "favoriteCauseId": "crypto-merchants", "interests": ["retail", "refunds"], "causeIds": ["crypto-merchants"], "spotlightOrder": 5 }, + { "userId": "user-006", "displayName": "Doug", "bio": "Has lived in Owen Sound for decades. He wants the park-path season and English township business, and he wants recruiting to wait on housing.", "favoriteCauseId": "civic-assimilation", "interests": ["Harrison Park", "township business"], "causeIds": ["civic-assimilation"], "spotlightOrder": 6 }, + { "userId": "user-007", "displayName": "Nadia", "bio": "Checks directories for a living. She will confirm a class-host listing and will not treat that check as endorsement of the host's church or school.", "favoriteCauseId": "christian-teaching", "interests": ["directories", "independent checks"], "causeIds": ["christian-teaching", "home-learning"], "spotlightOrder": 7 }, + { "userId": "user-008", "displayName": "Chris", "bio": "Builds the science-kit instructions and wants the hazards written down. He does not want public rooms closed to home-school meetups.", "favoriteCauseId": "home-learning", "interests": ["science kits", "lab safety"], "causeIds": ["home-learning"], "spotlightOrder": 8 }, + { "userId": "user-011", "displayName": "Ned", "bio": "Accepts a limited note from Pat for Owen Sound shop work. Holding the note is not a belief about crypto, and it is not yet spent.", "favoriteCauseId": "crypto-merchants", "interests": ["Owen Sound shops", "limited notes"], "causeIds": ["crypto-merchants", "civic-assimilation", "christian-teaching", "home-learning"], "spotlightOrder": 9 }, + { "userId": "user-021", "displayName": "Pat", "bio": "Delegates a small note to Ned for the checkout trial and can revoke it. The delegation is not a signature.", "favoriteCauseId": "crypto-merchants", "interests": ["delegation", "Owen Sound shops"], "causeIds": ["crypto-merchants", "civic-assimilation"], "delegatesTo": "user-011", "spotlightOrder": 10 }, + { "userId": "user-016", "displayName": "June", "bio": "Reviews project alignments and will refuse a project that only sounds related to a statement.", "favoriteCauseId": "crypto-merchants", "interests": ["review", "Grey County"], "causeIds": ["crypto-merchants", "civic-assimilation", "christian-teaching", "home-learning"] } + ], + "actionRules": [ + { "type": "publish-statement", "prerequisites": [], "targetCount": { "min": 40, "max": 40 } }, + { "type": "create-cause", "prerequisites": ["publish-statement"], "targetCount": { "min": 4, "max": 4 } }, + { "type": "set-belief", "prerequisites": ["publish-statement"], "targetCount": { "min": 60, "max": 60 } }, + { "type": "attest-implication", "prerequisites": ["publish-statement"], "targetCount": { "min": 0, "max": 0 } }, + { "type": "create-project", "prerequisites": ["create-cause"], "targetCount": { "min": 20, "max": 20 } }, + { "type": "attest-alignment", "prerequisites": ["create-project", "publish-statement"], "targetCount": { "min": 20, "max": 20 } }, + { "type": "fund-project", "prerequisites": ["create-project", "attest-alignment"], "targetCount": { "min": 40, "max": 40 } }, + { "type": "deposit-note", "prerequisites": [], "targetCount": { "min": 12, "max": 12 } }, + { "type": "delegate-note", "prerequisites": ["deposit-note"], "targetCount": { "min": 8, "max": 8 } }, + { "type": "revoke-delegation", "prerequisites": ["delegate-note"], "targetCount": { "min": 3, "max": 3 } }, + { "type": "create-bridge-board", "prerequisites": ["publish-statement"], "targetCount": { "min": 0, "max": 0 } }, + { "type": "create-bridge", "prerequisites": ["create-cause", "create-bridge-board"], "targetCount": { "min": 0, "max": 0 } } + ], + "artifactLayout": { + "manifest": "manifest.json", + "statementCatalog": "plan/statements.json", + "assignments": "plan/assignments.json", + "walletAddresses": "plan/wallet-addresses.json", + "walletSecrets": "../secrets/network-societies-v1-pilot.wallets.json", + "actionPlan": "plan/actions.json", + "executionState": "execution/actions.jsonl", + "runtimeBindings": "execution/runtime-bindings.json", + "fundingLedger": "execution/funding-ledger.json", + "reconciliation": "reports/reconciliation.json", + "browserObservations": "reports/browser-observations.json", + "summary": "reports/summary.md" + } +} diff --git a/fake-data-generation/campaigns/network-societies-v1-pilot.md b/fake-data-generation/campaigns/network-societies-v1-pilot.md new file mode 100644 index 00000000..e68ee9cc --- /dev/null +++ b/fake-data-generation/campaigns/network-societies-v1-pilot.md @@ -0,0 +1,45 @@ +# Network societies pilot + +Campaign id: `network-societies-v1-pilot`. Synthetic users, shops, churches, and deliverables. This is not evidence of adoption. + +Families in this pilot: Owen Sound checkout trial, Grey County civic life, Grey County Christian teaching, Grey County home learning. The other eleven families in the brainstorming plan are not in this manifest. + +## Capability table + +| Need | Status | +| --- | --- | +| Campaign manifest, planner, local executor, reconciler, run viewer | Reused | +| Cause count below 8, statement count outside 30–70, same statement on more than one board | Supported by optional `scale` on the manifest. Omitted scale keeps the old caps. | +| Curated projects without a new TypeScript story module | Supported by `projectStories`, a JSON file beside the manifest | +| Accepted-bridge implication evidence | Still the only evidence the planner will publish. Heuristic `implies: true` is not accepted. | +| Fresh attester evaluation for new campaign pairs | Not run. The pilot stores candidates and publishes zero implication edges. | +| Beliefs chosen by the persona decision file | Not wired. `network-societies-v1-pilot-decisions.json` is authoring intent. The planner still draws `set-belief`. | +| One shared project contract on several boards | The class-host directory is one statement, published once, and one project. Civic life and home learning boards include that statement. Whether each board page shows the project depends on the product and has not been walked in a browser. | +| Early funding then retroactive reimbursement | Supported for v2's accepted abortion bridge. Not planned in this pilot. | +| Delegated spending of a note | Deposit, delegate, and revoke exist. Spending through the delegation does not. Pat's note to Ned is a delegation, not a spent note. | +| Recurring "$20/month" pledge | Not a campaign action. Do not describe a one-time deposit as that pledge. | +| "Delivered but not reimbursed" filter | Not demonstrated. Crossing a funding threshold is not evidence the fictional work was delivered. | + +## Reproduce the plan + +From `fake-data-generation/`: + +```bash +npm run gen:campaign:plan -- campaigns/network-societies-v1-pilot.json output/campaigns/network-societies-v1-pilot +``` + +Seed: `commonality-network-societies-v1-pilot-2026-10-16`. A plan written on 2026-10-16 has 40 users, 40 statements, 20 projects, and 207 writes. Output stays under `output/`, which is gitignored. Do not write this plan over `medium-realistic-v2`. + +## Journeys this plan can and cannot show + +Ruth and Len can both be on the checkout board while the dissent plank "shops refuse crypto" is a separate statement. That overlap does not use an implication arrow. + +Imani's rejection of the recruiting pause, and Owen's refusal of the midweek notes, are written in the decisions file. They are not yet enforced in `set-belief`. + +Pat (`user-021`) delegates notes to Ned (`user-011`). Some delegations are later revoked. The plan does not show Ned spending Pat's note. + +No modified-statement bridge is published. A candidate negative pair is in the decisions file and is unevaluated. + +## Next unfinished task + +Evaluate the candidate pairs with the real implication-attester prompt, or keep them unpublished, then execute this plan on a local chain and walk the boards. Do not add the other eleven families before that. diff --git a/fake-data-generation/test/campaignPlanner.test.ts b/fake-data-generation/test/campaignPlanner.test.ts index c55f5bec..38f3cd25 100644 --- a/fake-data-generation/test/campaignPlanner.test.ts +++ b/fake-data-generation/test/campaignPlanner.test.ts @@ -209,6 +209,28 @@ test('validation rejects an action whose prerequisite points forward', async () assert.throws(() => validatePlannedActions(manifest, plan.statements, plan.users, plan.projects, invalid), /impossible dependency/); }); +test('network-societies pilot reuses one directory statement and publishes no implication', async () => { + const manifest = JSON.parse(await readFile(new URL('../campaigns/network-societies-v1-pilot.json', import.meta.url), 'utf8')) as CampaignManifestV1; + const plan = await buildCampaignPlan(manifest); + assert.equal(plan.users.length, 40); + assert.equal(plan.statements.length, 40); + assert.equal(plan.projects.length, 20); + const shared = plan.statements.find((statement) => statement.source.statementId === 'class-host-directory'); + assert.ok(shared); + assert.deepEqual(shared!.alsoOnCauseIds, ['christian-teaching', 'home-learning']); + assert.equal(plan.actions.filter((action) => action.type === 'publish-statement' && action.statementId === shared!.id).length, 1); + assert.equal(plan.projects.filter((project) => project.statementIds.includes(shared!.id)).length, 1); + assert.equal(plan.actions.filter((action) => action.type === 'attest-implication').length, 0); + const pat = plan.users.find((user) => user.displayName === 'Pat')!; + const ned = plan.users.find((user) => user.displayName === 'Ned')!; + const patDelegations = plan.actions.filter((action) => action.type === 'delegate-note' && action.actorUserId === pat.id); + assert.ok(patDelegations.length > 0); + assert.ok(patDelegations.every((action) => action.delegateUserId === ned.id)); + for (const causeId of manifest.causes.map((cause) => cause.id)) { + assert.ok(plan.projects.filter((project) => project.causeId === causeId).length >= 5); + } +}); + test('written planning artifacts reload into the same campaign plan', async () => { const manifest = await loadManifest(); const plan = await buildCampaignPlan(manifest); diff --git a/specs/product/marketing/WALKTHROUGH-SETUP.md b/specs/product/marketing/WALKTHROUGH-SETUP.md index 3407c8b5..531baf7c 100644 --- a/specs/product/marketing/WALKTHROUGH-SETUP.md +++ b/specs/product/marketing/WALKTHROUGH-SETUP.md @@ -39,7 +39,7 @@ Then: See [demo-profiles.md](./demo-profiles.md) for the full list. Quick picks: -- **Friend who donates but doesn't organize:** Sam (casual donor) +- **Friend who donates but doesn't organize:** Casey (casual donor) - **Friend who runs a club/meetup:** Alex (community organizer) - **Friend who evaluates tech/projects:** Jordan (expert scout) - **Friend building something public:** Taylor (project founder) diff --git a/specs/product/marketing/demo-profiles.md b/specs/product/marketing/demo-profiles.md index 8b42e19c..6b655060 100644 --- a/specs/product/marketing/demo-profiles.md +++ b/specs/product/marketing/demo-profiles.md @@ -25,7 +25,7 @@ A delegate slot joins the delegation graph. It does not guarantee that Kurt or S | Profile | Role | Best for showing... | Favorite cause | |---|---|---|---| -| **Sam (casual donor)** | regular-supporter | Hands-off giving: "$20/month without research" | Local food systems | +| **Casey (casual donor)** | regular-supporter | Hands-off giving: "$20/month without research" | Local food systems | | **Alex (community organizer)** | community-organizer | Coordinating volunteers without founding an org | Education and literacy | | **Jordan (expert scout)** | project-builder | Technical evaluation before recommending funding | Open-source infrastructure | | **Taylor (project founder)** | project-builder | Building public goods that need sustainable funding | Open science | @@ -51,7 +51,7 @@ From [friend-walkthroughs.md](./friend-walkthroughs.md): 1. **Before the screen:** Ask what cause they care about 2. **Pick a matching profile:** Choose the demo user whose favorite cause aligns 3. **Connect as that user:** Show their home page with personalized content -4. **Map roles:** "You'd be like Sam (just donate) or Alex (organize)?" +4. **Map roles:** "You'd be like Casey (just donate) or Alex (organize)?" 5. **Show mechanisms:** One at a time, based on their interest Don't show all eight profiles in one session. Pick one that matches their cause and role inclination. From c7648c02fdbe54060eaca0d5f64e461a0f4b6365 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 14:17:50 -0400 Subject: [PATCH 06/19] Record the local network-societies pilot run. The four-family plan mined and reconciled 207 of 207 actions. Cause pages show the shared class-host statement and do not list its project. --- fake-data-generation/PLAN.md | 2 +- .../campaigns/network-societies-v1-pilot.md | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/fake-data-generation/PLAN.md b/fake-data-generation/PLAN.md index 59a06973..86f6d6ed 100644 --- a/fake-data-generation/PLAN.md +++ b/fake-data-generation/PLAN.md @@ -80,7 +80,7 @@ Do these in order unless Adam names a different one. Each item is a session-size ### F — Network societies pilot -Authoring for the four-family pilot (crypto merchants, Grey County civic life, Christian teaching, home learning) is in `campaigns/network-societies-v1-pilot.json` plus the statements, project, and decision files beside it. The capability table and the gaps that are still open are in [`campaigns/network-societies-v1-pilot.md`](./campaigns/network-societies-v1-pilot.md). The plan does not publish implication edges. Local execution and the other eleven families are still ahead. +Authoring for the four-family pilot (crypto merchants, Grey County civic life, Christian teaching, home learning) is in `campaigns/network-societies-v1-pilot.json` plus the statements, project, and decision files beside it. The capability table and the gaps that are still open are in [`campaigns/network-societies-v1-pilot.md`](./campaigns/network-societies-v1-pilot.md). A local run on 2026-10-16 mined and reconciled 207/207. Cause pages show the shared class-host statement and do not list its project. The other eleven families are still ahead. The plan does not publish implication edges. ## Pointers diff --git a/fake-data-generation/campaigns/network-societies-v1-pilot.md b/fake-data-generation/campaigns/network-societies-v1-pilot.md index e68ee9cc..9f22071a 100644 --- a/fake-data-generation/campaigns/network-societies-v1-pilot.md +++ b/fake-data-generation/campaigns/network-societies-v1-pilot.md @@ -14,7 +14,7 @@ Families in this pilot: Owen Sound checkout trial, Grey County civic life, Grey | Accepted-bridge implication evidence | Still the only evidence the planner will publish. Heuristic `implies: true` is not accepted. | | Fresh attester evaluation for new campaign pairs | Not run. The pilot stores candidates and publishes zero implication edges. | | Beliefs chosen by the persona decision file | Not wired. `network-societies-v1-pilot-decisions.json` is authoring intent. The planner still draws `set-belief`. | -| One shared project contract on several boards | The class-host directory is one statement, published once, and one project. Civic life and home learning boards include that statement. Whether each board page shows the project depends on the product and has not been walked in a browser. | +| One shared project contract on several boards | The class-host directory is one statement, published once, and one project (`project-015`). Civic life, Christian teaching, and home learning boards all show that statement. None of the four cause pages lists a project under Fundable Projects ("No aligned projects yet"), including the Christian teaching board that owns the projects. The project page itself renders: title, fake-data outcome, founder Nadia, and "0 of 2 USDZZZ raised." | | Early funding then retroactive reimbursement | Supported for v2's accepted abortion bridge. Not planned in this pilot. | | Delegated spending of a note | Deposit, delegate, and revoke exist. Spending through the delegation does not. Pat's note to Ned is a delegation, not a spent note. | | Recurring "$20/month" pledge | Not a campaign action. Do not describe a one-time deposit as that pledge. | @@ -40,6 +40,19 @@ Pat (`user-021`) delegates notes to Ned (`user-011`). Some delegations are later No modified-statement bridge is published. A candidate negative pair is in the decisions file and is unevaluated. +## Local run (2026-10-16) + +Clean localhost chain after `./scripts/data.sh --wipe` and `./scripts/services.sh --start`. Plan: 40 users, 40 statements, 20 projects, 207 writes. Execute mined 206, then one `fund-project` (`action-00157`, `user-031`, `0x7efF913d73fEc32ef2765A28824412617bBE1baC`) failed with insufficient ETH for gas. After a 1 ETH top-up from Hardhat account #0 and resetting that action to `planned`, the resume mined 207/207. Reconciliation: 207/207, chain and indexer both at block 295, lag 0. + +Boards: + +- Civic life: `http://commonality.localhost:8088/#/cause/0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC/campaign-network-societies-v1-pilot-civic-assimilation` +- Christian teaching: `http://commonality.localhost:8088/#/cause/0x70997970C51812dc3A010C7d01b50e0d17dc79C8/campaign-network-societies-v1-pilot-christian-teaching` +- Home learning: `http://commonality.localhost:8088/#/cause/0x90F79bf6EB2c4f870365E785982E1f101E93b906/campaign-network-societies-v1-pilot-home-learning` +- Class-host directory project: `http://commonality.localhost:8088/#/projects/0x8744b336FC44395Da72850AD9f6220CF6Ea34962` + +Test-data run `20261016T181546620Z`. Admin: `http://commonality.localhost:8088/#/admin/test-data?key=` plus the key in `output/test-data/.admin-capability`. + ## Next unfinished task -Evaluate the candidate pairs with the real implication-attester prompt, or keep them unpublished, then execute this plan on a local chain and walk the boards. Do not add the other eleven families before that. +Decide whether a cause page should list a project that is aligned to a statement on that board. The current pages do not. Do not add the other eleven families before that. Implication candidates stay unpublished. From 99fd03013431dcdc4a3b9879b46b5558e9835b55 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 15:11:02 -0400 Subject: [PATCH 07/19] Fund the local alignment-trust bootstrap wallet. A wiped chain left that signer with no ETH, so cause boards hid every campaign vouch. The local funder now tops it up with the other service keys. --- fake-data-generation/PLAN.md | 2 +- .../campaigns/network-societies-v1-pilot.md | 6 ++++-- scripts/fund-local-service-wallets.mjs | 4 ++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/fake-data-generation/PLAN.md b/fake-data-generation/PLAN.md index 86f6d6ed..361a3ec5 100644 --- a/fake-data-generation/PLAN.md +++ b/fake-data-generation/PLAN.md @@ -80,7 +80,7 @@ Do these in order unless Adam names a different one. Each item is a session-size ### F — Network societies pilot -Authoring for the four-family pilot (crypto merchants, Grey County civic life, Christian teaching, home learning) is in `campaigns/network-societies-v1-pilot.json` plus the statements, project, and decision files beside it. The capability table and the gaps that are still open are in [`campaigns/network-societies-v1-pilot.md`](./campaigns/network-societies-v1-pilot.md). A local run on 2026-10-16 mined and reconciled 207/207. Cause pages show the shared class-host statement and do not list its project. The other eleven families are still ahead. The plan does not publish implication edges. +Authoring for the four-family pilot (crypto merchants, Grey County civic life, Christian teaching, home learning) is in `campaigns/network-societies-v1-pilot.json` plus the statements, project, and decision files beside it. The capability table and the gaps that are still open are in [`campaigns/network-societies-v1-pilot.md`](./campaigns/network-societies-v1-pilot.md). A local run on 2026-10-16 mined and reconciled 207/207. Cause pages list the shared class-host directory once the alignment-trust bootstrap wallet has gas. The other eleven families are still ahead. The plan does not publish implication edges. ## Pointers diff --git a/fake-data-generation/campaigns/network-societies-v1-pilot.md b/fake-data-generation/campaigns/network-societies-v1-pilot.md index 9f22071a..e0fcaf1b 100644 --- a/fake-data-generation/campaigns/network-societies-v1-pilot.md +++ b/fake-data-generation/campaigns/network-societies-v1-pilot.md @@ -14,7 +14,7 @@ Families in this pilot: Owen Sound checkout trial, Grey County civic life, Grey | Accepted-bridge implication evidence | Still the only evidence the planner will publish. Heuristic `implies: true` is not accepted. | | Fresh attester evaluation for new campaign pairs | Not run. The pilot stores candidates and publishes zero implication edges. | | Beliefs chosen by the persona decision file | Not wired. `network-societies-v1-pilot-decisions.json` is authoring intent. The planner still draws `set-belief`. | -| One shared project contract on several boards | The class-host directory is one statement, published once, and one project (`project-015`). Civic life, Christian teaching, and home learning boards all show that statement. None of the four cause pages lists a project under Fundable Projects ("No aligned projects yet"), including the Christian teaching board that owns the projects. The project page itself renders: title, fake-data outcome, founder Nadia, and "0 of 2 USDZZZ raised." | +| One shared project contract on several boards | The class-host directory is one statement, published once, and one project (`project-015`). Civic life, Christian teaching, and home learning all list it under Fundable Projects once the alignment-trust bootstrap has admitted the campaign attesters. The project page renders: title, fake-data outcome, founder Nadia, and "0 of 2 USDZZZ raised." | | Early funding then retroactive reimbursement | Supported for v2's accepted abortion bridge. Not planned in this pilot. | | Delegated spending of a note | Deposit, delegate, and revoke exist. Spending through the delegation does not. Pat's note to Ned is a delegation, not a spent note. | | Recurring "$20/month" pledge | Not a campaign action. Do not describe a one-time deposit as that pledge. | @@ -55,4 +55,6 @@ Test-data run `20261016T181546620Z`. Admin: `http://commonality.localhost:8088/# ## Next unfinished task -Decide whether a cause page should list a project that is aligned to a statement on that board. The current pages do not. Do not add the other eleven families before that. Implication candidates stay unpublished. +Do not add the other eleven families. Implication candidates stay unpublished. + +A wiped local chain leaves the generated alignment-trust bootstrap key with no ETH. Until `scripts/fund-local-service-wallets.mjs` tops it up, that worker crash-loops, the starter trust set stays empty, and cause pages hide every campaign vouch. The funder script now includes `ALIGNMENT_TRUST_BOOTSTRAP_PRIVATE_KEY`. On 2026-10-16 the wallet was topped up by hand, the worker admitted 8 attesters, and the directory project showed on the Christian teaching, civic life, and home learning boards. diff --git a/scripts/fund-local-service-wallets.mjs b/scripts/fund-local-service-wallets.mjs index e55e80cc..8be574e4 100755 --- a/scripts/fund-local-service-wallets.mjs +++ b/scripts/fund-local-service-wallets.mjs @@ -23,6 +23,10 @@ const SIGNER_KEY_VARS = [ 'IMPLICATION_ATTESTER_PRIVATE_KEY', 'CONTENT_ATTESTER_PRIVATE_KEY', 'BRIDGE_CREATOR_PRIVATE_KEY', + // Cause pages hide alignment vouches outside this wallet's direct trust. + // After a local wipe the generated key has no ETH, so the bootstrap cannot + // admit campaign attesters and every cause board looks empty. + 'ALIGNMENT_TRUST_BOOTSTRAP_PRIVATE_KEY', ] const FLOOR = parseEther('1') From 1070fa4909ae9e232b084bc12448d8610c7a14a5 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 15:14:01 -0400 Subject: [PATCH 08/19] Record the network-societies handoff for the next family batch. --- ...16-network-societies-next-batch-handoff.md | 31 +++++++++++++++ ...etwork-societies-pilot-projects-handoff.md | 39 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 continuity/2026-10-16-network-societies-next-batch-handoff.md create mode 100644 continuity/2026-10-16-network-societies-pilot-projects-handoff.md diff --git a/continuity/2026-10-16-network-societies-next-batch-handoff.md b/continuity/2026-10-16-network-societies-next-batch-handoff.md new file mode 100644 index 00000000..8884cb2e --- /dev/null +++ b/continuity/2026-10-16-network-societies-next-batch-handoff.md @@ -0,0 +1,31 @@ +# Handoff: next network-societies batch + +Next session: author the first expansion batch of three or four families. Do not publish implication edges that have not been accepted by the attester. Do not wipe the local chain. + +## Read first + +- [`fake-data-generation/brainstorming/network-societies-campaign-plan.md`](../fake-data-generation/brainstorming/network-societies-campaign-plan.md) — sequence step 4, the fifteen-family table, and the statement quality gate. +- [`fake-data-generation/campaigns/network-societies-v1-pilot.md`](../fake-data-generation/campaigns/network-societies-v1-pilot.md) — what the four-family pilot can and cannot show. +- [`fake-data-generation/PLAN.md`](../fake-data-generation/PLAN.md) section F. +- Branch `campaign`, not pushed. Latest commit `99fd0301` ("Fund the local alignment-trust bootstrap wallet."). Earlier on the same branch: `976eef50`, `c7648c02`. + +## What is already true + +The four-family pilot (Owen Sound checkout, Grey County civic life, Christian teaching, home learning) planned 40 users, 40 statements, 20 projects, and 207 writes. Execution and reconciliation were 207/207. Artifacts stay gitignored under `fake-data-generation/output/campaigns/network-societies-v1-pilot/`. + +Cause pages list a project only after the alignment-trust bootstrap has trusted the attester. A wiped chain leaves the generated bootstrap key with no ETH, the worker crash-loops, and every board says there are no aligned projects. `scripts/fund-local-service-wallets.mjs` now includes `ALIGNMENT_TRUST_BOOTSTRAP_PRIVATE_KEY`. On this chain that wallet was topped up, the worker admitted 8 attesters, and the class-host directory (`project-015`) shows under Fundable Projects on Christian teaching, civic life, and home learning. Project URL and board URLs are in the pilot note. + +The statement row label "Projects" means the count is zero. A real count reads "1 project". + +Implication candidates in the decisions file are still unpublished. Persona `set-belief` choices are still not wired. Delegated spending and a real monthly pledge are still not campaign actions. + +## What to do + +Add the next three or four families from the brainstorming table. Start with the accepted abortion bridge as a spotlight story, and prefer families that can reuse accepted statements where the wording already means the thing being said. Keep the four pilot families. One shared project on several boards is one contract and several alignments, which this pilot already proved. + +Do not plan over `output/campaigns/medium-realistic-v2/` or `output/campaigns/network-societies-v1-pilot/`. If the local stack is still up, leave it. A new execute needs a fresh output directory. If you wipe, run `node scripts/fund-local-service-wallets.mjs` before expecting cause pages to list projects. + +## Suggested skills + +- `thorough-tester` — when the new batch gets a plan, check the shared-project case and a board that only includes the statement through `alsoOnCauseIds`. +- `browser-driving` — after a local execute, open the new boards and one pilot board that already lists the directory. diff --git a/continuity/2026-10-16-network-societies-pilot-projects-handoff.md b/continuity/2026-10-16-network-societies-pilot-projects-handoff.md new file mode 100644 index 00000000..d9af9967 --- /dev/null +++ b/continuity/2026-10-16-network-societies-pilot-projects-handoff.md @@ -0,0 +1,39 @@ +# Handoff: cause pages do not list the network-societies pilot projects + +Next session: fix the cause-page project list that the four-family pilot exposed. Do not add the other eleven families. Do not publish implication edges. + +## Read first + +- [`fake-data-generation/campaigns/network-societies-v1-pilot.md`](../fake-data-generation/campaigns/network-societies-v1-pilot.md) — capability table, local-run result, board and project URLs. +- [`fake-data-generation/PLAN.md`](../fake-data-generation/PLAN.md) section F. +- Commits on branch `campaign`: `976eef50` (manifest and planner) and `c7648c02` (run notes). Not pushed. + +## What is already true + +Local chain was wiped and restarted. Plan: 40 users, 40 statements, 20 projects, 207 writes. After one insufficient-ETH `fund-project` (`action-00157`, `user-031`) was topped up and reset to `planned`, execution and reconciliation were 207/207 at block 295, lag 0. Artifacts are gitignored under `fake-data-generation/output/campaigns/network-societies-v1-pilot/`. + +Walked in the browser at `http://commonality.localhost:8088`: + +- Cause headings and the fake-data sentence render. The class-host directory statement is on civic life, Christian teaching, and home learning. +- Statement rows show non-zero project counts. +- Fundable Projects, including the "Not yet funded" tab, says "No aligned projects yet" on the boards that were opened (civic life, Christian teaching, home learning). Christian teaching is the cause that owns the projects. +- The project page for the directory works: title, outcome, founder Nadia, "0 of 2 USDZZZ raised." URL is in the pilot note. Route is `/#/projects/:address`, not `/#/project/:address`. + +## What to fix + +The cause board asks `AlignedProjectsList` for projects on the board's statement CIDs and then renders an empty list. The list lives in `ui/src/fundingportals/components/CauseBoard.tsx` (the embedded list and the "Not yet funded" tab) and `ui/src/fundingportals/components/AlignedProjectsList.tsx` (empty copy when `projects.length === 0`). + +Find why those queries return nothing while the statement row still counts a project and the project page loads. Likely places: the statement CID set passed into the list, alignment-attestation trust filtering (campaign personas are not the official attester), or the indexer query the list uses. Confirm on the Christian teaching board and on one board that only includes the shared statement (civic life or home learning). A fix that shows projects only on the owning cause is incomplete if the statement is on the other boards and the row already counts the project. + +Do not treat the one-wei note principal or the unpublished implication candidates as part of this fix. The gas miss on `action-00157` is a local provisioning shortfall at about 1 gwei; leave it unless the project-list fix is blocked by a broken chain. + +## How to check + +The local stack was up at the end of this session (`commonality.localhost:8088`, chain 31337, indexer lag 0). If it is down, start it without wiping, or the campaign state is gone and the run has to be executed again. Instructions are in the pilot note. Do not plan this campaign over `output/campaigns/medium-realistic-v2/`. + +Verify in the browser: open the Christian teaching board and the civic-life or home-learning board, confirm the directory project appears, open it, and confirm the other project tabs did not gain a bogus row. Console noise that was already present: `favicon.ico` 404 and `/api/cause-assist/health` 404. + +## Suggested skills + +- `browser-driving` — the bug is on the rendered cause board. Re-check the boards after the change, not only a unit test. +- `thorough-tester` — when adding the regression, cover the owning board and a board that only includes the statement via `alsoOnCauseIds`. From a29962ef1a666dd53de1053a23d854ff0a4b9124 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 15:31:30 -0400 Subject: [PATCH 09/19] Add the network-societies batch-2 campaign plan. Keep the four pilot families and add the accepted abortion bridge, the accepted schools-pushing bridge, and an Owen Sound voting trial. Publish only the four already-accepted implication arrows. --- fake-data-generation/PLAN.md | 4 +- .../network-societies-v1-b2-decisions.json | 25 + .../network-societies-v1-b2-projects.json | 367 ++++++ .../network-societies-v1-b2-statements.json | 310 +++++ .../campaigns/network-societies-v1-b2.json | 1124 +++++++++++++++++ .../campaigns/network-societies-v1-b2.md | 39 + .../campaigns/network-societies-v1-pilot.md | 2 +- .../test/campaignPlanner.test.ts | 42 + 8 files changed, 1911 insertions(+), 2 deletions(-) create mode 100644 fake-data-generation/campaigns/network-societies-v1-b2-decisions.json create mode 100644 fake-data-generation/campaigns/network-societies-v1-b2-projects.json create mode 100644 fake-data-generation/campaigns/network-societies-v1-b2-statements.json create mode 100644 fake-data-generation/campaigns/network-societies-v1-b2.json create mode 100644 fake-data-generation/campaigns/network-societies-v1-b2.md diff --git a/fake-data-generation/PLAN.md b/fake-data-generation/PLAN.md index 361a3ec5..c66399c2 100644 --- a/fake-data-generation/PLAN.md +++ b/fake-data-generation/PLAN.md @@ -80,7 +80,9 @@ Do these in order unless Adam names a different one. Each item is a session-size ### F — Network societies pilot -Authoring for the four-family pilot (crypto merchants, Grey County civic life, Christian teaching, home learning) is in `campaigns/network-societies-v1-pilot.json` plus the statements, project, and decision files beside it. The capability table and the gaps that are still open are in [`campaigns/network-societies-v1-pilot.md`](./campaigns/network-societies-v1-pilot.md). A local run on 2026-10-16 mined and reconciled 207/207. Cause pages list the shared class-host directory once the alignment-trust bootstrap wallet has gas. The other eleven families are still ahead. The plan does not publish implication edges. +The four-family pilot (crypto merchants, Grey County civic life, Christian teaching, home learning) is in [`campaigns/network-societies-v1-pilot.md`](./campaigns/network-societies-v1-pilot.md). A local run on 2026-10-16 mined and reconciled 207/207. Cause pages list the shared class-host directory once the alignment-trust bootstrap wallet has gas. + +Batch 2 keeps those four families and adds the accepted abortion bridge, the accepted schools-pushing bridge, and an Owen Sound voting trial. The note is [`campaigns/network-societies-v1-b2.md`](./campaigns/network-societies-v1-b2.md). The plan has 60 users, 70 statements, 40 projects, and 356 writes. It publishes only the four already-accepted modified-to-commonality arrows. It has not been executed. Eight families from the brainstorming table are still ahead. Persona `set-belief` choices are still not wired. ## Pointers diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json b/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json new file mode 100644 index 00000000..67026103 --- /dev/null +++ b/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json @@ -0,0 +1,25 @@ +{ + "note": "Authored persona decisions for batch 2. The planner still draws set-belief on its own. Unsigned is not the same as an explicit rejection. Implication edges in the plan are only the four accepted modified-to-commonality pairs from compromise-abortion and lgbt-schools. No new pair was sent to the attester.", + "people": [ + { "userId": "user-041", "name": "Mara", "signs": ["modified-left", "commonality"], "rejects": ["no-early-abortions"], "unsigned": ["michigan-legislature", "one-federal-rule"], "notes": "The settlement signature is not a signature about which legislature writes the rule." }, + { "userId": "user-052", "name": "Eli", "signs": ["natural-right"], "rejects": ["modified-right", "commonality", "modified-left"], "notes": "Keeps the natural position and refuses the settlement. He must not be treated as a supporter of the cutoff through an arrow from natural-right." }, + { "userId": "user-054", "name": "Bea", "signs": ["michigan-legislature"], "unsigned": ["commonality", "modified-left", "modified-right"], "rejects": ["one-federal-rule"], "notes": "State-level authority is a separate proposition from the 12-16 week sentence." }, + { "userId": "user-053", "name": "Jo", "signs": ["commonality"], "rejects": ["no-medical-limit"], "notes": "The schools commonality she means is the accepted conditional about pushing. It is not a position on drugs or surgery." }, + { "userId": "user-042", "name": "Nina", "signs": ["natural-left", "harassment-steps", "names-and-courtesy"], "rejects": ["no-medical-limit"], "unsigned": ["clinician-for-minors"] }, + { "userId": "user-043", "name": "Wes", "signs": ["ranked-poll", "approval-count", "keep-fptp", "moderator-checklist"], "rejects": ["show-of-hands"], "notes": "A non-binding poll and keeping first-past-the-post for municipal elections are compatible. Refusing the poll is the incompatible position." } + ], + "implicationCandidates": { + "published": [ + { "from": "compromise-abortion/modified-left", "to": "compromise-abortion/commonality", "evidence": "accepted-bridge-role-pair", "why": "Accepted 2026-08-30. The planner does not re-run the model." }, + { "from": "compromise-abortion/modified-right", "to": "compromise-abortion/commonality", "evidence": "accepted-bridge-role-pair", "why": "Accepted 2026-08-30." }, + { "from": "lgbt-schools/modified-left", "to": "lgbt-schools/commonality", "evidence": "accepted-bridge-role-pair", "why": "Accepted 2026-08-31. This arrow is about pushing versus support. It is not a medical claim." }, + { "from": "lgbt-schools/modified-right", "to": "lgbt-schools/commonality", "evidence": "accepted-bridge-role-pair", "why": "Accepted 2026-08-31." } + ], + "unevaluatedAndUnpublished": [ + { "from": "commonality", "to": "michigan-legislature", "why": "Agreement on a cutoff does not imply who should have the authority to write it." }, + { "from": "natural-right", "to": "commonality", "why": "Designed negative for the abortion bridge. Eli keeps this side." }, + { "from": "lgbt-schools/commonality", "to": "clinician-for-minors", "why": "The schools conditional does not settle medical treatment." }, + { "from": "ranked-poll", "to": "keep-fptp", "why": "Wanting a non-binding poll does not imply a position on municipal elections, in either direction." } + ] + } +} diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-projects.json b/fake-data-generation/campaigns/network-societies-v1-b2-projects.json new file mode 100644 index 00000000..ddb8b541 --- /dev/null +++ b/fake-data-generation/campaigns/network-societies-v1-b2-projects.json @@ -0,0 +1,367 @@ +{ + "crypto-merchants": [ + { + "title": "Six-shop refundable checkout trial", + "outcome": "Ship an open-source checkout, with refunds, and run it for three months at six named Owen Sound shops. Publish the code and the shop list.", + "statementRefs": [ + "refundable-checkout", + "published-trial-record" + ], + "blocker": "No one shop can justify building a checkout whose useful result is a public trial record" + }, + { + "title": "Independent checkout security review", + "outcome": "Pay a reviewer who does not write the checkout to publish findings and unfixed items before the Owen Sound trial ends.", + "statementRefs": [ + "checkout-security-review" + ], + "blocker": "The shops and the programmer are poor judges of their own security claims" + }, + { + "title": "Fee and failure table", + "outcome": "Publish the fee on a twenty-dollar Owen Sound trial sale, and a table of failed payments, before anyone calls the trial a success.", + "statementRefs": [ + "fee-schedule", + "published-trial-record" + ], + "blocker": "The numbers are useful to every later shop and owned by none of them" + }, + { + "title": "Owen Sound merchant directory", + "outcome": "Maintain, for one year, a directory that shows which trial shops still take the checkout and which shops stopped, with the date of each change.", + "statementRefs": [ + "merchant-directory" + ], + "blocker": "A directory nobody maintains becomes an advertisement" + }, + { + "title": "Quarterly checkout clinic and host kit", + "outcome": "Run four Saturday clinics in Owen Sound and leave a host kit so a second person can run the next one.", + "statementRefs": [ + "deployment-clinic", + "host-kit" + ], + "blocker": "The clinic stops when the first host is busy unless the hosting steps are written down" + } + ], + "civic-assimilation": [ + { + "title": "Twelve conversation sessions", + "outcome": "Hold twelve English conversation sessions in Owen Sound with childcare in the room, and publish attendance without naming children.", + "statementRefs": [ + "language-sessions" + ], + "blocker": "Childcare and a room have to be paid before the first session, and no single family captures the benefit" + }, + { + "title": "Grey County civics pack", + "outcome": "Write and release a plain-English pack for the library, the bus, a school meeting, and a township office in Grey County.", + "statementRefs": [ + "civics-pack" + ], + "blocker": "Each office explains itself differently, and no office is paid to write the combined pack" + }, + { + "title": "Harrison Park path season", + "outcome": "Run one summer of path repair in Harrison Park, Owen Sound, with newcomers and long-time residents, and publish hours and costs.", + "statementRefs": [ + "park-paths" + ], + "blocker": "The work needs a full season of tools and insurance before anyone can see the paths" + }, + { + "title": "Conversation-session handoff", + "outcome": "Write the steps, contacts, and childcare arrangements so a second organizer can run the next Owen Sound session series.", + "statementRefs": [ + "organizer-handoff" + ], + "blocker": "The sessions are a public good only if they survive the first organizer" + }, + { + "title": "Independent tutor-listing check", + "outcome": "For one season, have someone who does not run the sessions check Grey County language-tutor listings and publish which listings failed.", + "statementRefs": [ + "tutor-check" + ], + "blocker": "A directory checked by its own organizer does not answer a skeptic" + } + ], + "christian-teaching": [ + { + "title": "Midweek class notes", + "outcome": "Release the notes for one Grey County congregation's midweek class under terms another congregation can reuse.", + "statementRefs": [ + "midweek-notes", + "named-confession" + ], + "blocker": "The second congregation can copy the notes, so neither congregation is paid by the other to write them" + }, + { + "title": "Midweek class transcript", + "outcome": "Transcribe that class for people who cannot hear the recordings, and publish the transcript with the confession named.", + "statementRefs": [ + "transcription", + "named-confession" + ], + "blocker": "Transcription is useful to every later listener and costly to the first congregation" + }, + { + "title": "One-season substitute rota", + "outcome": "Publish a Sunday rota and sermon notes so a substitute can preach at one named Grey County church for one season.", + "statementRefs": [ + "substitute-rota", + "interchurch-calendar" + ], + "blocker": "Each small church has too few substitutes to keep the rota alone" + }, + { + "title": "Second-church host kit", + "outcome": "Write a one-season kit so a second Grey County church can run the same rota without the first host.", + "statementRefs": [ + "host-kit" + ], + "blocker": "The rota dies with the first host unless the steps are written down" + }, + { + "title": "Grey County class-host directory", + "outcome": "Publish one directory of Grey County people who will host a small class, with affiliation and an independent checker's note, and maintain it for one year.", + "statementRefs": [ + "class-host-directory" + ], + "blocker": "Churches, tutors, and home-school hosts each need the same checked list, and none of them owns it" + } + ], + "home-learning": [ + { + "title": "Printable grade-six science unit", + "outcome": "Release one grade-six science unit a Grey County family can print, with the teaching method named on the first page and no religious claims in the activities.", + "statementRefs": [ + "science-unit", + "method-on-the-page", + "no-religious-claims" + ], + "blocker": "Every family can copy the unit after the first author writes it" + }, + { + "title": "Grey County field-trip pack", + "outcome": "Release the permission form, map, and safety notes for one Grey County field trip so another family, including a school family, can run it.", + "statementRefs": [ + "field-trip", + "school-families-may-borrow" + ], + "blocker": "The first family pays for the reconnaissance and every later family can copy the pack" + }, + { + "title": "Store-item science kits", + "outcome": "Publish instructions for a home science kit of ordinary store items, including hazards and the adult supervision each activity needs.", + "statementRefs": [ + "science-kits", + "lab-safety" + ], + "blocker": "A safe kit has to be tried once before other families can reuse it" + }, + { + "title": "Eight Owen Sound Saturdays", + "outcome": "Host eight Saturday meetups in Owen Sound for home-school families and publish the dates before the first meeting.", + "statementRefs": [ + "saturday-meetups" + ], + "blocker": "The room and the dates have to be reserved before any family can rely on them" + }, + { + "title": "Successor host notes", + "outcome": "Name a successor and write the notes so the Owen Sound meetups can run a second season without the first host.", + "statementRefs": [ + "successor-host" + ], + "blocker": "A meetup series that only the first host can run is not a maintained public good" + } + ], + "abortion": [ + { + "title": "Grand Rapids settlement sessions", + "outcome": "Hold six moderated sessions in Grand Rapids, Michigan, on the accepted 12-16 week settlement sentence, and publish the notes. The notes do not say what Michigan law currently is.", + "statementRefs": [ + "commonality" + ], + "blocker": "A room, a moderator, and a published record have to be paid for before either camp can point at the same notes" + }, + { + "title": "Plain-language settlement page", + "outcome": "Publish one page that quotes the accepted settlement sentence and says, in plain language, what a 12-16 week cutoff would allow and forbid. Do not describe that sentence as current law.", + "statementRefs": [ + "commonality", + "modified-left", + "modified-right" + ], + "blocker": "Each camp already has its own explanation, and neither is paid to write the shared one" + }, + { + "title": "Five-statement posting", + "outcome": "Keep the five accepted abortion statements posted, unchanged, for one year, with the date of each posting.", + "statementRefs": [ + "natural-left", + "natural-right", + "modified-left", + "modified-right", + "commonality" + ], + "blocker": "The posting is useful to every later reader and owned by none of them" + }, + { + "title": "Settlement-session host kit", + "outcome": "Write the steps, the room notes, and the publication checklist so a second person can run the Grand Rapids sessions without the first host.", + "statementRefs": [ + "commonality" + ], + "blocker": "The sessions stop when the first host is busy unless the steps are written down" + }, + { + "title": "Independent notes check", + "outcome": "Have someone who did not host the Grand Rapids sessions check that the published notes quote the settlement sentence without adding a claim about current Michigan law.", + "statementRefs": [ + "commonality" + ], + "blocker": "The host is a poor judge of whether their own notes stayed inside the sentence" + } + ], + "abortion-forum": [ + { + "title": "Michigan authority brief", + "outcome": "Publish a two-page brief that quotes the legislature-decides sentence and the federal-statute sentence as opposing proposals, and does not say which proposal is law.", + "statementRefs": [ + "michigan-legislature", + "one-federal-rule" + ], + "blocker": "Each side publishes its own brief, and nobody is paid to put the two proposals on one page" + }, + { + "title": "From-the-start position page", + "outcome": "Publish one page that states the from-the-start ban and the keep-campaigning position as positions their signers hold, labeled as positions rather than as Michigan law.", + "statementRefs": [ + "no-early-abortions", + "no-settlement" + ], + "blocker": "The page is a public record of dissent, and no single dissenter captures the benefit of maintaining it" + } + ], + "schools": [ + { + "title": "Grand Rapids pushing-question meetings", + "outcome": "Hold four moderated meetings in Grand Rapids where the question is whether schools are pushing kids toward LGBT identities, and publish the transcripts without a clinical claim.", + "statementRefs": [ + "natural-left", + "natural-right", + "commonality" + ], + "blocker": "The transcript is useful to people who were not in the room, and the first host pays for the room" + }, + { + "title": "Unchanged schools packet", + "outcome": "Print the five accepted schools statements, unchanged, in a packet for one parent meeting, and record which statement each speaker is answering.", + "statementRefs": [ + "natural-left", + "natural-right", + "modified-left", + "modified-right", + "commonality" + ], + "blocker": "A packet everyone can copy is not paid for by the second parent who uses it" + }, + { + "title": "Schools-meeting host kit", + "outcome": "Write the agenda and the publication steps so a second person can run the next pushing-question meeting without the first host.", + "statementRefs": [ + "commonality" + ], + "blocker": "The meeting series dies with the first host unless the steps are written down" + } + ], + "gender-conduct": [ + { + "title": "Harassment-steps sheet", + "outcome": "Publish the reporting steps for one named Grey County school, including the line that the student need not agree with a classmate.", + "statementRefs": [ + "harassment-steps" + ], + "blocker": "The sheet has to be checked against the school's actual desk procedure before other parents can rely on it" + }, + { + "title": "Clinician boundary page", + "outcome": "Publish one page that states the clinician-outside-the-school proposal and the schools-do-not-approve-drugs proposal, without a claim about medical outcomes.", + "statementRefs": [ + "clinician-for-minors", + "school-not-clinic" + ], + "blocker": "The two sentences are short, and nobody is paid to keep them from being rewritten into a treatment claim" + }, + { + "title": "Courtesy and medicine one-pager", + "outcome": "Publish one page that separates using a requested classroom name from any decision about drugs or surgery, using the courtesy statement's own wording.", + "statementRefs": [ + "names-and-courtesy" + ], + "blocker": "Each argument keeps folding the name into the medical decision unless a maintained page holds them apart" + }, + { + "title": "Adult-speech note", + "outcome": "Publish the wording of the adult-speech statement and a one-season note of which Grey County school-board agendas allowed that speech.", + "statementRefs": [ + "adult-medical-speech" + ], + "blocker": "The agenda record is useful to the next speaker and owned by none of them" + }, + { + "title": "Conduct-page host kit", + "outcome": "Write who updates the harassment sheet and the boundary page for the next school year, so the first editor can leave.", + "statementRefs": [ + "harassment-steps" + ], + "blocker": "A page nobody is assigned to update becomes an old photocopy" + } + ], + "voting": [ + { + "title": "Owen Sound association poll", + "outcome": "Run one non-binding ranked-ballot poll at one named Owen Sound community association and publish the ballots and the ranked count. The poll does not change a municipal election.", + "statementRefs": [ + "ranked-poll" + ], + "blocker": "Printing, a room, and a published count have to be paid for before anyone can inspect the result" + }, + { + "title": "Approval count of the same ballots", + "outcome": "Publish an approval count of those same Owen Sound ballots beside the ranked count, with both methods named.", + "statementRefs": [ + "ranked-poll", + "approval-count" + ], + "blocker": "A second count is useful to people comparing methods, and the association is not paid to run it" + }, + { + "title": "Rerunnable counting notes", + "outcome": "Publish the counting method in enough detail that a second person can rerun it from the published ballots and match the count.", + "statementRefs": [ + "counting-toolkit" + ], + "blocker": "The counter who ran the poll is a poor person to be the only one who can repeat it" + }, + { + "title": "Second-host poll kit", + "outcome": "Write the room, ballot, and publication steps so a second Owen Sound resident can run the next non-binding poll.", + "statementRefs": [ + "poll-host-kit" + ], + "blocker": "The poll stops when the first host is busy unless the steps are written down" + }, + { + "title": "Moderator checklist card", + "outcome": "Print the moderator checklist and use it for the Owen Sound poll and for one other published meeting, then file both checklists in the Grey County trial directory.", + "statementRefs": [ + "moderator-checklist", + "trial-directory" + ], + "blocker": "The checklist is useful on more than one board, and neither meeting owns the maintenance" + } + ] +} diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-statements.json b/fake-data-generation/campaigns/network-societies-v1-b2-statements.json new file mode 100644 index 00000000..aa8266ce --- /dev/null +++ b/fake-data-generation/campaigns/network-societies-v1-b2-statements.json @@ -0,0 +1,310 @@ +{ + "format": "commonality-seed-content-v1", + "id": "network-societies-v1-b2", + "title": "Synthetic network-societies batch 2 statements", + "description": "Pilot groups copied verbatim, plus campaign-local statements for the abortion forum, gender conduct, and voting. Accepted bridge wording is not copied here.", + "notes": [ + "Synthetic campaign only. Do not copy these into seed-content/.", + "Groups crypto-merchants, civic-assimilation, christian-teaching, home-learning, and shared-goods are copied from network-societies-v1-pilot-statements.json so this collection can load on its own. Edit those texts in the pilot file and re-copy; do not rewrite them here." + ], + "groups": [ + { + "id": "crypto-merchants", + "title": "Crypto-friendly merchant trials in Owen Sound", + "statements": [ + { + "id": "refundable-checkout", + "text": "I want six named shops in Owen Sound, Ontario, to be able to try a checkout that takes a crypto payment and can refund it, for a three-month trial." + }, + { + "id": "published-trial-record", + "text": "I want the Owen Sound crypto-checkout trial to publish every fee, failed payment, and refund from those three months." + }, + { + "id": "checkout-security-review", + "text": "I want an independent reviewer to publish the security findings in the Owen Sound trial checkout, including findings the shops have not yet fixed." + }, + { + "id": "merchant-directory", + "text": "I want a directory of Owen Sound shops in the checkout trial that says which shops are still taking the payment and which shops stopped." + }, + { + "id": "deployment-clinic", + "text": "I want a quarterly Saturday clinic in Owen Sound where a shop can run one test sale on the trial checkout and leave with a written result." + }, + { + "id": "host-kit", + "text": "I want a written host kit so a second person can run the next Owen Sound checkout clinic without the first host." + }, + { + "id": "keep-cash-and-card", + "text": "I want every shop in the Owen Sound crypto trial to keep taking cash and ordinary cards for the whole three months." + }, + { + "id": "refuse-crypto-payments", + "text": "I want shops in Owen Sound to refuse customer payments in crypto." + }, + { + "id": "bank-blocking", + "text": "I want a willing Owen Sound shop and a willing customer to be able to complete a payment when a bank has blocked that customer." + }, + { + "id": "fee-schedule", + "text": "I want the Owen Sound trial checkout to show the fee for a twenty-dollar sale before the customer pays." + } + ] + }, + { + "id": "civic-assimilation", + "title": "Shared civic life in Grey County", + "statements": [ + { + "id": "language-sessions", + "text": "I want twelve practical English conversation sessions in Owen Sound, Ontario, with childcare in the room, for newcomers and long-time residents together." + }, + { + "id": "civics-pack", + "text": "I want a reusable pack that explains, in plain English, how a person in Grey County uses the library, the bus, a school meeting, and a township office." + }, + { + "id": "park-paths", + "text": "I want one summer of newcomers and long-time residents repairing paths in Harrison Park, Owen Sound, with the hours and costs published at the end." + }, + { + "id": "tutor-check", + "text": "I want the Grey County language-tutor listings checked by someone who does not run the sessions, including a public note when a listing fails the check." + }, + { + "id": "organizer-handoff", + "text": "I want a written handoff so a second organizer can run the next Owen Sound conversation session without the first organizer." + }, + { + "id": "english-township-business", + "text": "I want township business in Grey County to stay in English, including when language classes are offered." + }, + { + "id": "own-language-communities", + "text": "I want newcomers in Grey County to be able to keep their own language communities without a public program that expects them to adopt local customs." + }, + { + "id": "housing-before-recruiting", + "text": "I want Grey County to stop recruiting more newcomers until the published housing and clinic wait times get shorter." + }, + { + "id": "welcome-signage", + "text": "I want the Owen Sound bus terminal and library to post, in the languages already spoken in town, where the conversation sessions meet." + }, + { + "id": "session-limit", + "text": "I want the Owen Sound conversation sessions to teach practical English, and I want them to stop short of telling newcomers which customs to keep." + } + ] + }, + { + "id": "christian-teaching", + "title": "Christian teaching resources in Grey County", + "statements": [ + { + "id": "midweek-notes", + "text": "I want the teaching notes for one Grey County congregation's midweek class released so another congregation can reuse them." + }, + { + "id": "transcription", + "text": "I want the recordings of that Grey County midweek class transcribed for people who cannot hear them." + }, + { + "id": "substitute-rota", + "text": "I want a published rota and sermon notes so a substitute can preach at a named Grey County church when the regular preacher is away for one season." + }, + { + "id": "named-confession", + "text": "I want shared Grey County teaching notes to name the confession they come from." + }, + { + "id": "no-joint-doctrine", + "text": "I want congregations that reuse the same Grey County teaching notes to stop short of publishing a joint statement of doctrine." + }, + { + "id": "host-kit", + "text": "I want a one-season host kit so a second Grey County church can run the substitute-preacher rota after the first season." + }, + { + "id": "civic-transcription-only", + "text": "I want to help transcribe public civic materials in Grey County, and I do not want that work to include church teaching." + }, + { + "id": "keep-notes-inside", + "text": "I want a congregation's teaching notes to stay inside that congregation." + }, + { + "id": "interchurch-calendar", + "text": "I want a public calendar of which Grey County church is short a preacher on which Sunday this season." + } + ] + }, + { + "id": "home-learning", + "title": "Home learning in Grey County", + "statements": [ + { + "id": "science-unit", + "text": "I want one open grade-six science unit, with materials a Grey County home-school family can print." + }, + { + "id": "field-trip", + "text": "I want the permission form, map, and safety notes for one Grey County field trip released so another family can run the same trip." + }, + { + "id": "science-kits", + "text": "I want instructions for a home science kit that uses ordinary store items, written so a Grey County family can repeat it." + }, + { + "id": "saturday-meetups", + "text": "I want eight Saturday meetups in Owen Sound for home-school families, with the dates published before the first meeting." + }, + { + "id": "successor-host", + "text": "I want a named successor, and written notes, so the Owen Sound home-school meetups can continue for a second season without the first host." + }, + { + "id": "method-on-the-page", + "text": "I want each Grey County home-school unit to say which teaching method it uses." + }, + { + "id": "no-religious-claims", + "text": "I want a Grey County science unit that contains no religious claims, so a secular home-school family can use it." + }, + { + "id": "school-families-may-borrow", + "text": "I want families whose children attend school in Grey County to be allowed to use the same field-trip notes." + }, + { + "id": "staffed-schools", + "text": "I want children in Grey County taught in staffed schools, and I do not want public rooms booked for home-school programs." + }, + { + "id": "lab-safety", + "text": "I want the Grey County home science kit to list the hazards and the adult supervision each activity needs." + } + ] + }, + { + "id": "shared-goods", + "title": "Goods reused across Grey County boards", + "statements": [ + { + "id": "class-host-directory", + "text": "I want a public directory of people in Grey County, Ontario, who will host a small class, with each host's affiliation written down and a note when an independent checker has confirmed the listing." + } + ] + }, + { + "id": "abortion-forum", + "title": "Michigan abortion authority, beside the accepted cutoff", + "notes": [ + "These are separate wants. None of them is an implication of the accepted 12-16 week settlement.", + "Do not give these statements bridge roles." + ], + "statements": [ + { + "id": "michigan-legislature", + "text": "I want Michigan's legislature, rather than a federal statute, to decide whether abortion is legal in Michigan." + }, + { + "id": "one-federal-rule", + "text": "I want one federal statute to set the abortion rule for every US state, including Michigan." + }, + { + "id": "no-settlement", + "text": "I want people in Michigan to keep campaigning for the abortion law they prefer, rather than accepting a cutoff neither side likes." + }, + { + "id": "no-early-abortions", + "text": "I want abortion forbidden in Michigan from the start of pregnancy, including during the first 12 weeks." + }, + { + "id": "options-on-a-page", + "text": "I want a written comparison of three Michigan proposals — a 12-16 week cutoff, a ban from the start of pregnancy, and no cutoff — that labels each one as a proposal and does not say which rule is in force." + }, + { + "id": "moderator-checklist", + "text": "I want a written checklist a moderator can use to publish a meeting's question, the statements under discussion, and the notes, without claiming the meeting decided a law." + } + ] + }, + { + "id": "gender-conduct", + "title": "Grey County school conduct, separate from the schools-pushing bridge", + "notes": [ + "The accepted LGBT-schools statements are about pushing versus support. They do not settle medical treatment, adult speech, or classroom names. These statements do not use bridge roles." + ], + "statements": [ + { + "id": "harassment-steps", + "text": "I want one Grey County school to publish the steps a student uses to report harassment, and to apply those steps without requiring the student to agree with a classmate." + }, + { + "id": "clinician-for-minors", + "text": "I want any drug or surgery offered to a minor in Grey County as a gender treatment to require a licensed clinician outside the school, not a decision by school staff." + }, + { + "id": "school-not-clinic", + "text": "I want Grey County schools to stay out of approving drugs or surgery for students." + }, + { + "id": "no-medical-limit", + "text": "I want a Grey County school counselor to be allowed to approve a gender-related drug for a student without a clinician outside the school." + }, + { + "id": "adult-medical-speech", + "text": "I want an adult in Grey County to be able to say, at a public school-board meeting, that they are seeking a gender-related medical treatment." + }, + { + "id": "names-and-courtesy", + "text": "I want a Grey County classroom to use the name a student asks for in class, and I want that courtesy kept separate from any decision about drugs or surgery." + }, + { + "id": "enrollment-name-only", + "text": "I want Grey County teachers to use only the name on a student's enrollment form, including when the student asks for a different name in class." + } + ] + }, + { + "id": "voting", + "title": "Non-binding counts in Owen Sound", + "notes": [ + "A non-binding association poll is not a change to municipal election law. No bridge roles." + ], + "statements": [ + { + "id": "ranked-poll", + "text": "I want one Owen Sound community association to run a non-binding ranked-ballot poll and to publish the ballots and the count." + }, + { + "id": "approval-count", + "text": "I want that Owen Sound association to publish an approval count of the same ballots beside the ranked count." + }, + { + "id": "keep-fptp", + "text": "I want Owen Sound municipal elections to keep first-past-the-post." + }, + { + "id": "show-of-hands", + "text": "I want the Owen Sound association to refuse a ranked-ballot poll and keep its usual show of hands." + }, + { + "id": "counting-toolkit", + "text": "I want the Owen Sound poll to use a published counting method that a second person can rerun from the published ballots." + }, + { + "id": "poll-host-kit", + "text": "I want a written host kit so a second Owen Sound resident can run the next non-binding poll without the first host." + }, + { + "id": "trial-directory", + "text": "I want a one-year directory of Grey County groups that have published a non-binding ranked or approval count, including groups that stopped and the date they stopped." + } + ] + } + ] +} diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.json b/fake-data-generation/campaigns/network-societies-v1-b2.json new file mode 100644 index 00000000..6d34ecd8 --- /dev/null +++ b/fake-data-generation/campaigns/network-societies-v1-b2.json @@ -0,0 +1,1124 @@ +{ + "schema": "commonality-testnet-campaign-v1", + "campaign": { + "id": "network-societies-v1-b2", + "label": "Network societies batch 2 — pilot families plus abortion, schools, and voting", + "syntheticDataLabel": "SYNTHETIC CAMPAIGN — NOT REAL USERS, ORGANIZATIONS, OR DELIVERABLES", + "userCount": 60, + "deterministicSeed": "commonality-network-societies-v1-b2-2026-10-16", + "randomAlgorithm": "xoshiro128**" + }, + "sourcePolicy": { + "kind": "accepted-plus-campaign-synthetic", + "fingerprintAlgorithm": "sha256", + "excludeCollections": [ + "proliferation" + ], + "campaignCollection": "network-societies-v1-b2-statements.json" + }, + "scale": { + "minCauses": 9, + "maxCauses": 9, + "minStatements": 70, + "maxStatements": 70, + "allowRepeatedStatementRefs": true + }, + "projectStories": "network-societies-v1-b2-projects.json", + "causes": [ + { + "id": "crypto-merchants", + "title": "Owen Sound checkout trial", + "activityTier": "large", + "membershipWeight": 12, + "statementRefs": [ + { + "collectionId": "network-societies-v1-b2", + "groupId": "crypto-merchants", + "statementId": "refundable-checkout" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "crypto-merchants", + "statementId": "published-trial-record" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "crypto-merchants", + "statementId": "checkout-security-review" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "crypto-merchants", + "statementId": "merchant-directory" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "crypto-merchants", + "statementId": "deployment-clinic" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "crypto-merchants", + "statementId": "host-kit" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "crypto-merchants", + "statementId": "keep-cash-and-card" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "crypto-merchants", + "statementId": "refuse-crypto-payments" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "crypto-merchants", + "statementId": "bank-blocking" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "crypto-merchants", + "statementId": "fee-schedule" + } + ] + }, + { + "id": "civic-assimilation", + "title": "Grey County civic life", + "activityTier": "large", + "membershipWeight": 12, + "statementRefs": [ + { + "collectionId": "network-societies-v1-b2", + "groupId": "civic-assimilation", + "statementId": "language-sessions" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "civic-assimilation", + "statementId": "civics-pack" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "civic-assimilation", + "statementId": "park-paths" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "civic-assimilation", + "statementId": "tutor-check" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "civic-assimilation", + "statementId": "organizer-handoff" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "civic-assimilation", + "statementId": "english-township-business" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "civic-assimilation", + "statementId": "own-language-communities" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "civic-assimilation", + "statementId": "housing-before-recruiting" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "civic-assimilation", + "statementId": "welcome-signage" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "civic-assimilation", + "statementId": "session-limit" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "shared-goods", + "statementId": "class-host-directory" + } + ] + }, + { + "id": "christian-teaching", + "title": "Grey County Christian teaching", + "activityTier": "medium", + "membershipWeight": 10, + "statementRefs": [ + { + "collectionId": "network-societies-v1-b2", + "groupId": "christian-teaching", + "statementId": "midweek-notes" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "christian-teaching", + "statementId": "transcription" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "christian-teaching", + "statementId": "substitute-rota" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "christian-teaching", + "statementId": "named-confession" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "christian-teaching", + "statementId": "no-joint-doctrine" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "christian-teaching", + "statementId": "host-kit" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "christian-teaching", + "statementId": "civic-transcription-only" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "christian-teaching", + "statementId": "keep-notes-inside" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "christian-teaching", + "statementId": "interchurch-calendar" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "shared-goods", + "statementId": "class-host-directory" + } + ] + }, + { + "id": "home-learning", + "title": "Grey County home learning", + "activityTier": "medium", + "membershipWeight": 10, + "statementRefs": [ + { + "collectionId": "network-societies-v1-b2", + "groupId": "home-learning", + "statementId": "science-unit" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "home-learning", + "statementId": "field-trip" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "home-learning", + "statementId": "science-kits" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "home-learning", + "statementId": "saturday-meetups" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "home-learning", + "statementId": "successor-host" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "home-learning", + "statementId": "method-on-the-page" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "home-learning", + "statementId": "no-religious-claims" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "home-learning", + "statementId": "school-families-may-borrow" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "home-learning", + "statementId": "staffed-schools" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "home-learning", + "statementId": "lab-safety" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "shared-goods", + "statementId": "class-host-directory" + } + ] + }, + { + "id": "abortion", + "title": "Abortion settlement", + "activityTier": "medium", + "membershipWeight": 8, + "statementRefs": [ + { + "collectionId": "compromise-abortion", + "groupId": "abortion-gestational-cutoff", + "statementId": "natural-left" + }, + { + "collectionId": "compromise-abortion", + "groupId": "abortion-gestational-cutoff", + "statementId": "natural-right" + }, + { + "collectionId": "compromise-abortion", + "groupId": "abortion-gestational-cutoff", + "statementId": "modified-left" + }, + { + "collectionId": "compromise-abortion", + "groupId": "abortion-gestational-cutoff", + "statementId": "modified-right" + }, + { + "collectionId": "compromise-abortion", + "groupId": "abortion-gestational-cutoff", + "statementId": "commonality" + } + ] + }, + { + "id": "abortion-forum", + "title": "Michigan abortion authority", + "activityTier": "small", + "membershipWeight": 6, + "statementRefs": [ + { + "collectionId": "network-societies-v1-b2", + "groupId": "abortion-forum", + "statementId": "michigan-legislature" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "abortion-forum", + "statementId": "one-federal-rule" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "abortion-forum", + "statementId": "no-settlement" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "abortion-forum", + "statementId": "no-early-abortions" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "abortion-forum", + "statementId": "options-on-a-page" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "abortion-forum", + "statementId": "moderator-checklist" + } + ] + }, + { + "id": "schools", + "title": "Schools and pushing", + "activityTier": "medium", + "membershipWeight": 7, + "statementRefs": [ + { + "collectionId": "lgbt-schools", + "groupId": "lgbt-schools-pushing", + "statementId": "natural-left" + }, + { + "collectionId": "lgbt-schools", + "groupId": "lgbt-schools-pushing", + "statementId": "natural-right" + }, + { + "collectionId": "lgbt-schools", + "groupId": "lgbt-schools-pushing", + "statementId": "modified-left" + }, + { + "collectionId": "lgbt-schools", + "groupId": "lgbt-schools-pushing", + "statementId": "modified-right" + }, + { + "collectionId": "lgbt-schools", + "groupId": "lgbt-schools-pushing", + "statementId": "commonality" + } + ] + }, + { + "id": "gender-conduct", + "title": "Grey County school conduct", + "activityTier": "small", + "membershipWeight": 6, + "statementRefs": [ + { + "collectionId": "network-societies-v1-b2", + "groupId": "gender-conduct", + "statementId": "harassment-steps" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "gender-conduct", + "statementId": "clinician-for-minors" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "gender-conduct", + "statementId": "school-not-clinic" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "gender-conduct", + "statementId": "no-medical-limit" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "gender-conduct", + "statementId": "adult-medical-speech" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "gender-conduct", + "statementId": "names-and-courtesy" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "gender-conduct", + "statementId": "enrollment-name-only" + } + ] + }, + { + "id": "voting", + "title": "Owen Sound voting trial", + "activityTier": "medium", + "membershipWeight": 8, + "statementRefs": [ + { + "collectionId": "network-societies-v1-b2", + "groupId": "voting", + "statementId": "ranked-poll" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "voting", + "statementId": "approval-count" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "voting", + "statementId": "keep-fptp" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "voting", + "statementId": "show-of-hands" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "voting", + "statementId": "counting-toolkit" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "voting", + "statementId": "poll-host-kit" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "voting", + "statementId": "trial-directory" + }, + { + "collectionId": "network-societies-v1-b2", + "groupId": "abortion-forum", + "statementId": "moderator-checklist" + } + ] + } + ], + "personas": [ + { + "id": "community-organizer", + "count": 4, + "roles": [ + "cause-founder", + "supporter" + ], + "causesPerUser": { + "min": 2, + "max": 3 + }, + "activityWeight": 2, + "inactivityRate": 0, + "fundingWeight": 1.2 + }, + { + "id": "project-builder", + "count": 6, + "roles": [ + "project-founder", + "supporter" + ], + "causesPerUser": { + "min": 1, + "max": 2 + }, + "activityWeight": 1.7, + "inactivityRate": 0, + "fundingWeight": 0.8 + }, + { + "id": "trusted-delegate", + "count": 5, + "roles": [ + "delegate", + "supporter" + ], + "causesPerUser": { + "min": 2, + "max": 4 + }, + "activityWeight": 2, + "inactivityRate": 0, + "fundingWeight": 1.4 + }, + { + "id": "bridge-mediator", + "count": 5, + "roles": [ + "attester", + "mediator" + ], + "causesPerUser": { + "min": 2, + "max": 4 + }, + "activityWeight": 2, + "inactivityRate": 0, + "fundingWeight": 0.4 + }, + { + "id": "regular-supporter", + "count": 14, + "roles": [ + "supporter" + ], + "causesPerUser": { + "min": 1, + "max": 3 + }, + "activityWeight": 1, + "inactivityRate": 0.1, + "fundingWeight": 1 + }, + { + "id": "quiet-neighbor", + "count": 6, + "roles": [ + "lurker", + "supporter" + ], + "causesPerUser": { + "min": 1, + "max": 2 + }, + "activityWeight": 0.2, + "inactivityRate": 0.4, + "fundingWeight": 0.3 + }, + { + "id": "batch-organizer", + "count": 3, + "roles": [ + "cause-founder", + "supporter" + ], + "causesPerUser": { + "min": 2, + "max": 2 + }, + "activityWeight": 2, + "inactivityRate": 0, + "fundingWeight": 1.2 + }, + { + "id": "batch-builder", + "count": 6, + "roles": [ + "project-founder", + "supporter" + ], + "causesPerUser": { + "min": 1, + "max": 2 + }, + "activityWeight": 1.7, + "inactivityRate": 0, + "fundingWeight": 0.8 + }, + { + "id": "batch-reviewer", + "count": 2, + "roles": [ + "attester", + "mediator" + ], + "causesPerUser": { + "min": 4, + "max": 4 + }, + "activityWeight": 2, + "inactivityRate": 0, + "fundingWeight": 0.4 + }, + { + "id": "batch-supporter", + "count": 9, + "roles": [ + "supporter" + ], + "causesPerUser": { + "min": 1, + "max": 2 + }, + "activityWeight": 1, + "inactivityRate": 0, + "fundingWeight": 1 + } + ], + "userProfiles": [ + { + "userId": "user-001", + "displayName": "Ruth", + "bio": "Keeps the books for a shop in Owen Sound and wants the checkout trial's fees published. She will not sign a demand that shops refuse crypto.", + "favoriteCauseId": "crypto-merchants", + "interests": [ + "shop fees", + "Owen Sound" + ], + "causeIds": [ + "crypto-merchants", + "civic-assimilation" + ], + "spotlightOrder": 1 + }, + { + "userId": "user-002", + "displayName": "Helen", + "bio": "Preaches at a small Grey County church and wants the midweek notes reusable, with the confession named. She does not treat a shared host directory as agreement on doctrine.", + "favoriteCauseId": "christian-teaching", + "interests": [ + "preaching", + "Grey County churches" + ], + "causeIds": [ + "christian-teaching", + "home-learning" + ], + "spotlightOrder": 2 + }, + { + "userId": "user-003", + "displayName": "Imani", + "bio": "Recently moved to Owen Sound and wants the twelve conversation sessions with childcare. She rejects the demand to stop recruiting newcomers.", + "favoriteCauseId": "civic-assimilation", + "interests": [ + "English practice", + "Owen Sound" + ], + "causeIds": [ + "civic-assimilation", + "crypto-merchants" + ], + "spotlightOrder": 3 + }, + { + "userId": "user-004", + "displayName": "Owen", + "bio": "Home-schools in Grey County and wants the printable science unit with no religious claims. He will not sign a request to release a congregation's midweek notes.", + "favoriteCauseId": "home-learning", + "interests": [ + "home science", + "Grey County" + ], + "causeIds": [ + "home-learning", + "christian-teaching" + ], + "spotlightOrder": 4 + }, + { + "userId": "user-005", + "displayName": "Len", + "bio": "Runs a shop that wants to keep cash and cards while trying the refundable checkout. He is not a crypto enthusiast.", + "favoriteCauseId": "crypto-merchants", + "interests": [ + "retail", + "refunds" + ], + "causeIds": [ + "crypto-merchants" + ], + "spotlightOrder": 5 + }, + { + "userId": "user-006", + "displayName": "Doug", + "bio": "Has lived in Owen Sound for decades. He wants the park-path season and English township business, and he wants recruiting to wait on housing.", + "favoriteCauseId": "civic-assimilation", + "interests": [ + "Harrison Park", + "township business" + ], + "causeIds": [ + "civic-assimilation" + ], + "spotlightOrder": 6 + }, + { + "userId": "user-007", + "displayName": "Nadia", + "bio": "Checks directories for a living. She will confirm a class-host listing and will not treat that check as endorsement of the host's church or school.", + "favoriteCauseId": "christian-teaching", + "interests": [ + "directories", + "independent checks" + ], + "causeIds": [ + "christian-teaching", + "home-learning" + ], + "spotlightOrder": 7 + }, + { + "userId": "user-008", + "displayName": "Chris", + "bio": "Builds the science-kit instructions and wants the hazards written down. He does not want public rooms closed to home-school meetups.", + "favoriteCauseId": "home-learning", + "interests": [ + "science kits", + "lab safety" + ], + "causeIds": [ + "home-learning" + ], + "spotlightOrder": 8 + }, + { + "userId": "user-011", + "displayName": "Ned", + "bio": "Accepts a limited note from Pat for Owen Sound shop work. Holding the note is not a belief about crypto, and it is not yet spent.", + "favoriteCauseId": "crypto-merchants", + "interests": [ + "Owen Sound shops", + "limited notes" + ], + "causeIds": [ + "crypto-merchants", + "civic-assimilation", + "christian-teaching", + "home-learning" + ], + "spotlightOrder": 9 + }, + { + "userId": "user-021", + "displayName": "Pat", + "bio": "Delegates a small note to Ned for the checkout trial and can revoke it. The delegation is not a signature.", + "favoriteCauseId": "crypto-merchants", + "interests": [ + "delegation", + "Owen Sound shops" + ], + "causeIds": [ + "crypto-merchants", + "civic-assimilation" + ], + "delegatesTo": "user-011", + "spotlightOrder": 10 + }, + { + "userId": "user-016", + "displayName": "June", + "bio": "Reviews project alignments and will refuse a project that only sounds related to a statement.", + "favoriteCauseId": "crypto-merchants", + "interests": [ + "review", + "Grey County" + ], + "causeIds": [ + "crypto-merchants", + "civic-assimilation", + "christian-teaching", + "home-learning" + ] + }, + { + "userId": "user-041", + "displayName": "Mara", + "bio": "Accepts the 12-16 week settlement and will sign the modified-left wording. She does not treat that signature as a belief about which legislature should write the rule.", + "favoriteCauseId": "abortion", + "interests": [ + "settlement", + "Grand Rapids" + ], + "causeIds": [ + "abortion", + "abortion-forum" + ], + "spotlightOrder": 11 + }, + { + "userId": "user-042", + "displayName": "Nina", + "bio": "Wants the schools question argued from the accepted statements. She does not treat that question as a decision about drugs or surgery.", + "favoriteCauseId": "schools", + "interests": [ + "schools", + "Grey County" + ], + "causeIds": [ + "schools", + "gender-conduct" + ], + "spotlightOrder": 12 + }, + { + "userId": "user-043", + "displayName": "Wes", + "bio": "Wants the Owen Sound association poll and the published counts. He can sign keeping first-past-the-post for real municipal elections.", + "favoriteCauseId": "voting", + "interests": [ + "Owen Sound", + "ballots" + ], + "causeIds": [ + "voting", + "abortion-forum" + ], + "spotlightOrder": 13 + }, + { + "userId": "user-044", + "displayName": "Paul", + "bio": "Will host the Grand Rapids settlement sessions and publish the notes without a claim about current Michigan law.", + "favoriteCauseId": "abortion", + "interests": [ + "Grand Rapids", + "moderation" + ], + "causeIds": [ + "abortion" + ], + "spotlightOrder": 14 + }, + { + "userId": "user-045", + "displayName": "Ada", + "bio": "Writes the Michigan authority brief as two labeled proposals.", + "favoriteCauseId": "abortion-forum", + "interests": [ + "Michigan", + "proposals" + ], + "causeIds": [ + "abortion-forum" + ], + "spotlightOrder": 15 + }, + { + "userId": "user-046", + "displayName": "Gail", + "bio": "Prints the five accepted schools statements unchanged for a parent meeting.", + "favoriteCauseId": "schools", + "interests": [ + "parent meetings", + "transcripts" + ], + "causeIds": [ + "schools" + ], + "spotlightOrder": 16 + }, + { + "userId": "user-047", + "displayName": "Hugh", + "bio": "Publishes the Grey County harassment steps and keeps them off the medical question.", + "favoriteCauseId": "gender-conduct", + "interests": [ + "harassment reporting", + "Grey County schools" + ], + "causeIds": [ + "gender-conduct" + ], + "spotlightOrder": 17 + }, + { + "userId": "user-048", + "displayName": "Ivy", + "bio": "Runs the non-binding Owen Sound poll and files the ballots.", + "favoriteCauseId": "voting", + "interests": [ + "ranked ballots", + "Owen Sound" + ], + "causeIds": [ + "voting" + ], + "spotlightOrder": 18 + }, + { + "userId": "user-049", + "displayName": "Kent", + "bio": "Reruns the Owen Sound count from the published ballots. He is not the poll host.", + "favoriteCauseId": "voting", + "interests": [ + "counting", + "independent checks" + ], + "causeIds": [ + "voting", + "gender-conduct" + ], + "spotlightOrder": 19 + }, + { + "userId": "user-050", + "displayName": "Lila", + "bio": "Attests alignments on the settlement, the forum, the schools statements, and the poll. A shared checklist is not a belief.", + "favoriteCauseId": "abortion", + "interests": [ + "review", + "Grand Rapids" + ], + "causeIds": [ + "abortion", + "abortion-forum", + "schools", + "voting" + ], + "spotlightOrder": 20 + }, + { + "userId": "user-051", + "displayName": "Omar", + "bio": "Attests alignments on school conduct and will refuse a project that uses the schools statements as a medical claim.", + "favoriteCauseId": "gender-conduct", + "interests": [ + "review", + "Grey County" + ], + "causeIds": [ + "gender-conduct", + "schools", + "voting", + "abortion-forum" + ], + "spotlightOrder": 21 + }, + { + "userId": "user-052", + "displayName": "Eli", + "bio": "Holds that late-term abortion is horrific. He will not sign the settlement or the modified-right wording.", + "favoriteCauseId": "abortion", + "interests": [ + "late-term abortion" + ], + "causeIds": [ + "abortion" + ], + "spotlightOrder": 22 + }, + { + "userId": "user-053", + "displayName": "Jo", + "bio": "Signs the schools commonality if it is only the conditional about pushing. She rejects a school counselor approving a drug.", + "favoriteCauseId": "schools", + "interests": [ + "schools", + "clinicians" + ], + "causeIds": [ + "schools", + "gender-conduct" + ], + "spotlightOrder": 23 + }, + { + "userId": "user-054", + "displayName": "Bea", + "bio": "Wants Michigan's legislature to decide, and does not sign the 12-16 week settlement.", + "favoriteCauseId": "abortion-forum", + "interests": [ + "Michigan legislature" + ], + "causeIds": [ + "abortion-forum" + ], + "spotlightOrder": 24 + } + ], + "actionRules": [ + { + "type": "publish-statement", + "prerequisites": [], + "targetCount": { + "min": 70, + "max": 70 + } + }, + { + "type": "create-cause", + "prerequisites": [ + "publish-statement" + ], + "targetCount": { + "min": 9, + "max": 9 + } + }, + { + "type": "set-belief", + "prerequisites": [ + "publish-statement" + ], + "targetCount": { + "min": 90, + "max": 90 + } + }, + { + "type": "attest-implication", + "prerequisites": [ + "publish-statement" + ], + "targetCount": { + "min": 4, + "max": 4 + } + }, + { + "type": "create-project", + "prerequisites": [ + "create-cause" + ], + "targetCount": { + "min": 40, + "max": 40 + } + }, + { + "type": "attest-alignment", + "prerequisites": [ + "create-project", + "publish-statement" + ], + "targetCount": { + "min": 40, + "max": 40 + } + }, + { + "type": "fund-project", + "prerequisites": [ + "create-project", + "attest-alignment" + ], + "targetCount": { + "min": 70, + "max": 70 + } + }, + { + "type": "deposit-note", + "prerequisites": [], + "targetCount": { + "min": 12, + "max": 12 + } + }, + { + "type": "delegate-note", + "prerequisites": [ + "deposit-note" + ], + "targetCount": { + "min": 8, + "max": 8 + } + }, + { + "type": "revoke-delegation", + "prerequisites": [ + "delegate-note" + ], + "targetCount": { + "min": 3, + "max": 3 + } + }, + { + "type": "create-bridge-board", + "prerequisites": [ + "publish-statement" + ], + "targetCount": { + "min": 8, + "max": 8 + } + }, + { + "type": "create-bridge", + "prerequisites": [ + "create-cause", + "create-bridge-board" + ], + "targetCount": { + "min": 2, + "max": 2 + } + } + ], + "artifactLayout": { + "manifest": "manifest.json", + "statementCatalog": "plan/statements.json", + "assignments": "plan/assignments.json", + "walletAddresses": "plan/wallet-addresses.json", + "walletSecrets": "../secrets/network-societies-v1-b2.wallets.json", + "actionPlan": "plan/actions.json", + "executionState": "execution/actions.jsonl", + "runtimeBindings": "execution/runtime-bindings.json", + "fundingLedger": "execution/funding-ledger.json", + "reconciliation": "reports/reconciliation.json", + "browserObservations": "reports/browser-observations.json", + "summary": "reports/summary.md" + } +} diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.md b/fake-data-generation/campaigns/network-societies-v1-b2.md new file mode 100644 index 00000000..4e1cbf3d --- /dev/null +++ b/fake-data-generation/campaigns/network-societies-v1-b2.md @@ -0,0 +1,39 @@ +# Network societies batch 2 + +Campaign id: `network-societies-v1-b2`. Synthetic users and deliverables. This is not evidence of adoption. + +Keeps the four pilot families (Owen Sound checkout, Grey County civic life, Christian teaching, home learning). Adds three families: + +- Abortion settlement, using the accepted `compromise-abortion` wording unchanged, plus a separate Michigan authority board. +- Schools and pushing, using the accepted `lgbt-schools` wording unchanged, plus a separate Grey County conduct board. The schools statements do not settle drugs, surgery, or classroom names. +- An Owen Sound non-binding voting trial. + +The other eight families in the brainstorming plan are not in this manifest. + +## What the plan publishes + +A plan written on 2026-10-16 has 60 users, 70 statements, 40 projects, and 356 writes. Seed: `commonality-network-societies-v1-b2-2026-10-16`. + +The abortion cause and the schools cause are bridge-shaped. Each main board lists only the accepted commonality sentence. The natural and modified sentences are on the side boards. The Michigan authority board and the Grey County conduct board are ordinary boards, so their own sentences stay visible there. + +Four implication actions are planned. They are the accepted modified-left and modified-right arrows onto each commonality. Evidence recorded on the action is `accepted-bridge-role-pair`, the same marker the medium campaign uses. This session did not call the attester. No other pair is published. Candidates that were not evaluated are listed in `network-societies-v1-b2-decisions.json`. + +`moderator-checklist` is one statement. It is on the Michigan authority board and the Owen Sound voting board. One project, "Moderator checklist card", references it. + +Persona decisions in that file are still not applied to `set-belief`. Eli's refusal of the settlement is authoring intent. The planner can still have him believe the commonality sentence. + +Delegated spending and a recurring monthly pledge are still not campaign actions. + +## Reproduce the plan + +From `fake-data-generation/`: + +```bash +npm run gen:campaign:plan -- campaigns/network-societies-v1-b2.json output/campaigns/network-societies-v1-b2 +``` + +Do not write this plan over `network-societies-v1-pilot` or `medium-realistic-v2`. Pilot statement texts in `network-societies-v1-b2-statements.json` are a copy so the loader can see them. The accepted bridge sentences are referenced from `seed-content/`, not copied. + +## Not executed + +This batch has a plan only. It has not been mined, and the boards have no local URLs yet. Executing it needs a fresh output directory. If the chain is wiped first, fund the alignment-trust bootstrap wallet before expecting cause pages to list projects. diff --git a/fake-data-generation/campaigns/network-societies-v1-pilot.md b/fake-data-generation/campaigns/network-societies-v1-pilot.md index e0fcaf1b..ba8bc5a3 100644 --- a/fake-data-generation/campaigns/network-societies-v1-pilot.md +++ b/fake-data-generation/campaigns/network-societies-v1-pilot.md @@ -55,6 +55,6 @@ Test-data run `20261016T181546620Z`. Admin: `http://commonality.localhost:8088/# ## Next unfinished task -Do not add the other eleven families. Implication candidates stay unpublished. +Do not add further families to this pilot manifest. Batch 2 is a separate campaign: [`network-societies-v1-b2.md`](./network-societies-v1-b2.md). Implication candidates in this pilot's decisions file stay unpublished. A wiped local chain leaves the generated alignment-trust bootstrap key with no ETH. Until `scripts/fund-local-service-wallets.mjs` tops it up, that worker crash-loops, the starter trust set stays empty, and cause pages hide every campaign vouch. The funder script now includes `ALIGNMENT_TRUST_BOOTSTRAP_PRIVATE_KEY`. On 2026-10-16 the wallet was topped up by hand, the worker admitted 8 attesters, and the directory project showed on the Christian teaching, civic life, and home learning boards. diff --git a/fake-data-generation/test/campaignPlanner.test.ts b/fake-data-generation/test/campaignPlanner.test.ts index 38f3cd25..0f73f9d4 100644 --- a/fake-data-generation/test/campaignPlanner.test.ts +++ b/fake-data-generation/test/campaignPlanner.test.ts @@ -231,6 +231,48 @@ test('network-societies pilot reuses one directory statement and publishes no im } }); +test('batch 2 keeps the pilot families, reuses accepted bridges, and shares one checklist', async () => { + const manifest = JSON.parse(await readFile(new URL('../campaigns/network-societies-v1-b2.json', import.meta.url), 'utf8')) as CampaignManifestV1; + const pilotStatements = JSON.parse(await readFile(new URL('../campaigns/network-societies-v1-pilot-statements.json', import.meta.url), 'utf8')); + const batchStatements = JSON.parse(await readFile(new URL('../campaigns/network-societies-v1-b2-statements.json', import.meta.url), 'utf8')); + for (const group of pilotStatements.groups) { + const copy = batchStatements.groups.find((item: { id: string }) => item.id === group.id); + assert.deepEqual(copy.statements, group.statements); + } + const plan = await buildCampaignPlan(manifest); + assert.equal(plan.users.length, 60); + assert.equal(plan.statements.length, 70); + assert.equal(plan.projects.length, 40); + const checklist = plan.statements.find((statement) => statement.source.statementId === 'moderator-checklist'); + assert.ok(checklist); + assert.equal(checklist!.causeId, 'abortion-forum'); + assert.deepEqual(checklist!.alsoOnCauseIds, ['voting']); + assert.equal(plan.projects.filter((project) => project.statementIds.includes(checklist!.id)).length, 1); + const implications = plan.actions.filter((action) => action.type === 'attest-implication'); + assert.equal(implications.length, 4); + for (const action of implications) { + const from = plan.statements.find((statement) => statement.id === action.implication!.fromStatementId)!; + const to = plan.statements.find((statement) => statement.id === action.implication!.toStatementId)!; + assert.equal(action.implication!.evidence, 'accepted-bridge-role-pair'); + assert.ok(from.role === 'modified-left' || from.role === 'modified-right'); + assert.equal(to.role, 'commonality'); + assert.ok(from.source.collectionId === 'compromise-abortion' || from.source.collectionId === 'lgbt-schools'); + } + const michigan = plan.statements.find((statement) => statement.source.statementId === 'michigan-legislature')!; + assert.equal(implications.some((action) => action.implication!.fromStatementId === michigan.id || action.implication!.toStatementId === michigan.id), false); + for (const causeId of ['abortion', 'schools']) { + const board = plan.actions.find((action) => action.type === 'create-cause' && action.causeId === causeId)!.board!; + assert.equal(board.role, 'commonality'); + assert.equal(board.statementIds.length, 1); + } + const forum = plan.actions.find((action) => action.type === 'create-cause' && action.causeId === 'abortion-forum')!.board!; + assert.equal(forum.role, 'plain'); + assert.ok(forum.statementIds.includes(michigan.id)); + for (const causeId of manifest.causes.map((cause) => cause.id)) { + assert.ok(plan.projects.filter((project) => project.causeId === causeId).length >= 2, causeId); + } +}); + test('written planning artifacts reload into the same campaign plan', async () => { const manifest = await loadManifest(); const plan = await buildCampaignPlan(manifest); From a00ced27c6cc5148838f28bb7be0ca47f903d630 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 16:38:26 -0400 Subject: [PATCH 10/19] Add six unevaluated network-society bridge drafts to batch 2. The boards are bridge-shaped. Implication actions stay the four accepted abortion and schools pairs until the attester blesses a new pair. --- ...network-societies-draft-bridges-handoff.md | 37 ++++ fake-data-generation/PLAN.md | 2 +- .../network-societies-v1-b2-projects.json | 84 +++++++ .../network-societies-v1-b2-statements.json | 74 +++++++ .../campaigns/network-societies-v1-b2.json | 108 +++++++-- .../campaigns/network-societies-v1-b2.md | 6 +- .../06-network-society-alliances.json | 206 ++++++++++++++++++ .../statement-generation-exercises/README.md | 1 + .../test/campaignPlanner.test.ts | 9 +- 9 files changed, 507 insertions(+), 20 deletions(-) create mode 100644 continuity/2026-10-16-network-societies-draft-bridges-handoff.md create mode 100644 fake-data-generation/statement-generation-exercises/06-network-society-alliances.json diff --git a/continuity/2026-10-16-network-societies-draft-bridges-handoff.md b/continuity/2026-10-16-network-societies-draft-bridges-handoff.md new file mode 100644 index 00000000..c87e75bc --- /dev/null +++ b/continuity/2026-10-16-network-societies-draft-bridges-handoff.md @@ -0,0 +1,37 @@ +# Handoff: evaluate the six draft bridges, then execute batch 2 + +Next session: run the real implication-attester prompt on the six draft clusters, keep failed pairs unpublished, and only then execute `network-societies-v1-b2` locally. Do not treat bridge-shaped boards as attested implications. + +## Read first + +- [`fake-data-generation/campaigns/network-societies-v1-b2.md`](../fake-data-generation/campaigns/network-societies-v1-b2.md) — what the batch publishes and what it must not. +- [`fake-data-generation/statement-generation-exercises/06-network-society-alliances.json`](../fake-data-generation/statement-generation-exercises/06-network-society-alliances.json) — draft wording. Not accepted seed. +- [`fake-data-generation/statement-generation.md`](../fake-data-generation/statement-generation.md) and [`specs/product/statements-are-peculiar-for-good-reasons.md`](../specs/product/statements-are-peculiar-for-good-reasons.md) — attester plus routing. A bless is not enough. +- [`fake-data-generation/PLAN.md`](../fake-data-generation/PLAN.md) section F. +- [`fake-data-generation/brainstorming/network-societies-campaign-plan.md`](../fake-data-generation/brainstorming/network-societies-campaign-plan.md) — quality gate for new edges. +- Branch `campaign`. This handoff's commit is the one that adds the six clusters. Do not commit on `dev` or `master`. + +## What is already true + +The four-family pilot was executed and reconciled locally (207/207). Details and board URLs: [`fake-data-generation/campaigns/network-societies-v1-pilot.md`](../fake-data-generation/campaigns/network-societies-v1-pilot.md). Do not overwrite `output/campaigns/network-societies-v1-pilot/` or `output/campaigns/medium-realistic-v2/`. + +Batch 2 is planned in source, not executed. Manifest: 60 users, 100 statements, 52 projects, 15 causes. Causes `abortion` and `schools` reuse accepted seed wording. Six new causes are bridge-shaped from the exercise file: `grey-assimilation`, `ranked-approval-poll`, `checkout-trial-bridge`, `minors-medicine`, `opinion-employment`, `canada-us-ties`. The older plain boards (crypto planks, civic-life planks, the voting trial, gender-conduct, Michigan authority) stay. + +`attest-implication` is capped at 4. Those four are the accepted abortion and schools modified-to-commonality pairs. The planner labels every such action `accepted-bridge-role-pair`. That label is false for the six new clusters, which is why their arrows are omitted. `campaignPlanner.test.ts` asserts the new cause ids have commonality boards and no implication actions. + +Persona `set-belief` choices are still not applied. Delegated spending and a recurring monthly pledge are still not campaign actions. The Canada–US commonality is the weakest draft ("I'd be okay with saying that…"). + +A wiped local chain needs `node scripts/fund-local-service-wallets.mjs` before cause pages list projects. See the pilot note. + +## What to do + +1. Evaluate each new cluster with the real implication-attester system prompt (`cause-assist/src/implicationCheck.ts` / `IMPLICATION_EVALUATOR_SYSTEM_PROMPT`). Designed yes: each modified → commonality. Designed no: each natural → commonality, reverse arrows, and the assimilation cluster against the accepted immigration statements. Record hashes, prompt fingerprint, model, decision, and rationale. Heuristic `implies: true` is not evidence. If credentials are missing, stop and say so. +2. Run the routing check from the statements spec. Rewrite the wrong role if a designed-yes fails or a designed-no passes. The Canada–US commonality is the first candidate to rewrite. +3. Only after an affirmative model decision, raise the batch-2 `attest-implication` target so those pairs are planned, and store evidence that is not the accepted-role stamp. Leave refused pairs in the decisions file. +4. Regenerate the plan into a fresh output directory. Run `npx tsx --test test/campaignPlanner.test.ts` from `fake-data-generation/`. +5. Execute locally only after the plan matches the evidence. Walk the new bridge boards in the browser. Do not call the batch complete while a required journey is missing. The remaining brainstorm families (low-carb, unwoke as an umbrella, Democracy 2.0, Islamic reform, permitting, home-school beyond the pilot) are still unauthored. Do not force triples onto overlaps that already share a concrete want. + +## Suggested skills + +- `thorough-tester` — designed-negative pairs and the attest-implication cap. +- `browser-driving` — after a local execute, open one new bridge (commonality plus one modified board) and confirm the new clusters have no implication chip until step 3. diff --git a/fake-data-generation/PLAN.md b/fake-data-generation/PLAN.md index c66399c2..7570fa9e 100644 --- a/fake-data-generation/PLAN.md +++ b/fake-data-generation/PLAN.md @@ -82,7 +82,7 @@ Do these in order unless Adam names a different one. Each item is a session-size The four-family pilot (crypto merchants, Grey County civic life, Christian teaching, home learning) is in [`campaigns/network-societies-v1-pilot.md`](./campaigns/network-societies-v1-pilot.md). A local run on 2026-10-16 mined and reconciled 207/207. Cause pages list the shared class-host directory once the alignment-trust bootstrap wallet has gas. -Batch 2 keeps those four families and adds the accepted abortion bridge, the accepted schools-pushing bridge, and an Owen Sound voting trial. The note is [`campaigns/network-societies-v1-b2.md`](./campaigns/network-societies-v1-b2.md). The plan has 60 users, 70 statements, 40 projects, and 356 writes. It publishes only the four already-accepted modified-to-commonality arrows. It has not been executed. Eight families from the brainstorming table are still ahead. Persona `set-belief` choices are still not wired. +Batch 2 keeps those four families and adds the accepted abortion bridge, the accepted schools-pushing bridge, an Owen Sound voting trial, and six unevaluated draft bridges (assimilation sessions, dual-count poll, checkout trial, minors' medicine, ordinary opinions and employment, Canada–US ties). Wording is in [`statement-generation-exercises/06-network-society-alliances.json`](./statement-generation-exercises/06-network-society-alliances.json) and copied into the batch-2 statement file. The note is [`campaigns/network-societies-v1-b2.md`](./campaigns/network-societies-v1-b2.md). The manifest is 60 users, 100 statements, and 52 projects. It publishes only the four already-accepted modified-to-commonality arrows. The six new clusters are bridge-shaped boards without implication actions. The batch has not been executed. Persona `set-belief` choices are still not wired. Next: run the real implication-attester prompt on the six clusters, including the designed-negative pairs, then raise the attest-implication count only for pairs that receive an affirmative decision. ## Pointers diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-projects.json b/fake-data-generation/campaigns/network-societies-v1-b2-projects.json index ddb8b541..27713d52 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-projects.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-projects.json @@ -363,5 +363,89 @@ ], "blocker": "The checklist is useful on more than one board, and neither meeting owns the maintenance" } + ], + "grey-assimilation": [ + { + "title": "Owen Sound evening sessions", + "outcome": "Run twelve evening practical-English sessions in Owen Sound with childcare, covering the library, the bus, and a township office. Township business stays in English. The sessions do not tell newcomers which customs to keep.", + "statementRefs": ["commonality"], + "blocker": "Childcare and a room have to be paid for before either camp can see whether the limited program is the one they would accept" + }, + { + "title": "Session-limit card", + "outcome": "Print the commonality sentence and the two modified sentences, unchanged, so a host can show what the sessions will and will not do.", + "statementRefs": ["modified-left", "modified-right", "commonality"], + "blocker": "The limit is easy to drop in the room unless a card states it" + } + ], + "ranked-approval-poll": [ + { + "title": "Dual-count association poll", + "outcome": "One Owen Sound community association runs a non-binding poll and publishes a ranked count and an approval count of the same ballots. The poll does not change a municipal election.", + "statementRefs": ["commonality"], + "blocker": "Printing both counts costs more than the association's usual show of hands" + }, + { + "title": "Dual-count host card", + "outcome": "Print the two modified sentences so a host can say that publishing the other count is not a change of preferred system.", + "statementRefs": ["modified-left", "modified-right"], + "blocker": "Without the card, each side hears the second count as a concession they did not make" + } + ], + "checkout-trial-bridge": [ + { + "title": "Six-shop trial on the bridge terms", + "outcome": "Six named Owen Sound shops try, for three months, a checkout that can take a crypto payment and refund it, show the fee on a twenty-dollar sale before the customer pays, and keep taking cash and cards.", + "statementRefs": ["commonality"], + "blocker": "No one shop pays for a trial whose useful result is a public record of fees and refunds" + }, + { + "title": "Trial-terms card", + "outcome": "Print the two modified sentences so a merchant and a payments person can see the trial limits in their own wording.", + "statementRefs": ["modified-left", "modified-right"], + "blocker": "The shared sentence leaves out why each side showed up, and the card is what keeps those reasons visible" + } + ], + "minors-medicine": [ + { + "title": "Rule comparison page", + "outcome": "Publish the commonality sentence as a proposal, labeled as a proposal, with no claim about current law or clinical results.", + "statementRefs": ["commonality"], + "blocker": "A one-page proposal is useful to people who will not attend a meeting, and nobody owns the page" + }, + { + "title": "Separate-questions card", + "outcome": "Print the modified-right sentence so a host can keep classroom names and school drug approval off this page.", + "statementRefs": ["modified-right", "commonality"], + "blocker": "Those questions keep getting folded back in unless a maintained card holds them out" + } + ], + "opinion-employment": [ + { + "title": "Appeal-before-blacklist card", + "outcome": "Publish the commonality sentence and a one-page appeal checklist a workplace can fill in before treating someone as unemployable for a stated opinion.", + "statementRefs": ["commonality"], + "blocker": "The checklist is useful to the next workplace and paid for by none of them" + }, + { + "title": "Still-a-sanction note", + "outcome": "Publish the modified-left sentence so the card does not get read as a ban on every workplace response.", + "statementRefs": ["modified-left"], + "blocker": "The exception for threats and refused work disappears if only the short sentence is copied" + } + ], + "canada-us-ties": [ + { + "title": "Ordinary-ties one-pager", + "outcome": "Publish the commonality sentence for one Canadian community group, labeled as a draft statement rather than as a finding about trade.", + "statementRefs": ["commonality"], + "blocker": "The page is a shared wording, and neither camp's organizer is paid to keep the other camp's wording intact" + }, + { + "title": "Not-an-endorsement card", + "outcome": "Print both modified sentences beside the commonality so a reader can see the administration question was left out on purpose.", + "statementRefs": ["modified-left", "modified-right", "commonality"], + "blocker": "Without both wordings, one camp hears the page as praise and the other hears it as a boycott refusal they did not sign" + } ] } diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-statements.json b/fake-data-generation/campaigns/network-societies-v1-b2-statements.json index aa8266ce..77e2be8a 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-statements.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-statements.json @@ -305,6 +305,80 @@ "text": "I want a one-year directory of Grey County groups that have published a non-binding ranked or approval count, including groups that stopped and the date they stopped." } ] + }, + { + "id": "grey-assimilation", + "title": "Grey County practical-English sessions", + "notes": [ + "Draft bridge from statement-generation-exercises/06-network-society-alliances.json. Roles make the board bridge-shaped. Do not publish modified-to-commonality arrows until the attester blesses them. This is not the accepted immigration cluster." + ], + "statements": [ + { "id": "natural-left", "role": "natural-left", "text": "I want newcomers in Grey County to be able to learn practical English and how the library, the bus, and a township office work, and I want them to be able to keep their own customs." }, + { "id": "natural-right", "role": "natural-right", "text": "If people move to Grey County, they should join the local way of life. I don't want the township running services in origin languages forever." }, + { "id": "modified-left", "role": "modified-left", "text": "I want newcomers in Grey County to be able to learn practical English and how the library, the bus, and a township office work, and I want them to be able to keep their own customs. I'd be okay with twelve evening practical-English sessions in Owen Sound, with childcare, that explain those four things, while township business stays in English and the sessions stop short of telling newcomers which customs to keep. I would not want this to become a second township office in origin languages. This isn't my whole view of immigration." }, + { "id": "modified-right", "role": "modified-right", "text": "If people move to Grey County, they should be able to function in the local civic life, and I don't want the township running services in origin languages forever. I'd still rather see less immigration, but that is a different question. I'd be okay with twelve evening practical-English sessions in Owen Sound, with childcare, that explain the library, the bus, and a township office, while township business stays in English and the sessions stop short of telling newcomers which customs to keep. This isn't my whole view of immigration." }, + { "id": "commonality", "role": "commonality", "text": "I'd be okay with twelve evening practical-English sessions in Owen Sound, with childcare, that explain the library, the bus, and a township office, while township business stays in English and the sessions stop short of telling newcomers which customs to keep. This isn't my whole view of immigration." } + ] + }, + { + "id": "ranked-approval-poll", + "title": "Owen Sound dual-count poll", + "notes": ["Draft bridge. Unevaluated. The older voting group stays a plain board of separate planks."], + "statements": [ + { "id": "natural-left", "role": "natural-left", "text": "First-past-the-post wastes my vote. I want ranked ballots." }, + { "id": "natural-right", "role": "natural-right", "text": "First-past-the-post rewards the biggest camp. I want approval voting, not a ranked system." }, + { "id": "modified-left", "role": "modified-left", "text": "First-past-the-post wastes my vote. I want ranked ballots for a real election. I'd be okay with one Owen Sound community association running a non-binding poll and publishing both a ranked count and an approval count of the same ballots. That is not a change to Owen Sound's municipal elections, and publishing the approval count is not me dropping ranked ballots." }, + { "id": "modified-right", "role": "modified-right", "text": "First-past-the-post rewards the biggest camp. I want approval voting, not a ranked system, for a real election. I'd be okay with one Owen Sound community association running a non-binding poll and publishing both a ranked count and an approval count of the same ballots. That is not a change to Owen Sound's municipal elections, and publishing the ranked count is not me adopting ranked ballots." }, + { "id": "commonality", "role": "commonality", "text": "I'd be okay with one Owen Sound community association running a non-binding poll and publishing both a ranked count and an approval count of the same ballots. That is not a change to Owen Sound's municipal elections." } + ] + }, + { + "id": "checkout-trial-bridge", + "title": "Owen Sound checkout trial bridge", + "notes": ["Draft bridge. Unevaluated. The crypto-merchants planks stay on their own board."], + "statements": [ + { "id": "natural-left", "role": "natural-left", "text": "I want shops to take crypto so a bank can't decide whether a customer gets to pay." }, + { "id": "natural-right", "role": "natural-right", "text": "I'm tired of handing three percent of every sale to the card companies." }, + { "id": "modified-left", "role": "modified-left", "text": "I want a willing shop and a willing customer to be able to complete a payment when a bank has blocked that customer. Replacing the banks is a bigger thing than this. I'd be okay with six named shops in Owen Sound trying, for three months, a checkout that can take a crypto payment and refund it, show the fee on a twenty-dollar sale before the customer pays, and keep taking cash and ordinary cards the whole time." }, + { "id": "modified-right", "role": "modified-right", "text": "I'm tired of handing three percent of every sale to the card companies. I don't care about crypto as a cause. I'd still be okay with six named shops in Owen Sound trying, for three months, a checkout that can take a crypto payment and refund it, show the fee on a twenty-dollar sale before the customer pays, and keep taking cash and ordinary cards the whole time. If the trial is a bad deal, I want the fees and failures published." }, + { "id": "commonality", "role": "commonality", "text": "I'd be okay with six named shops in Owen Sound trying, for three months, a checkout that can take a crypto payment and refund it, show the fee on a twenty-dollar sale before the customer pays, and keep taking cash and ordinary cards the whole time." } + ] + }, + { + "id": "minors-medicine", + "title": "Minors' medicine and courtesy", + "notes": ["Draft bridge. Unevaluated. Does not settle the accepted schools-pushing cluster, classroom names, or a school approving drugs."], + "statements": [ + { "id": "natural-left", "role": "natural-left", "text": "I want a young person in distress about their sex to be able to get medical treatment, including hormones, and I want the rest of us to stop being cruel about it." }, + { "id": "natural-right", "role": "natural-right", "text": "I don't want children given drugs or surgery to try to change their sex." }, + { "id": "modified-left", "role": "modified-left", "text": "I want adults to make their own medical decisions, and I want disagreeing with someone to not be a reason to harass them. I'd prefer doctors and families to decide about hormones for minors case by case, but I'd be okay with a rule that minors are not given cross-sex hormones or genital surgery, that an adult makes their own medical decision, and that disagreeing with someone is not a reason to harass them. This isn't my ideal." }, + { "id": "modified-right", "role": "modified-right", "text": "I don't want children given drugs or surgery to try to change their sex. I'd be okay with a rule that minors are not given cross-sex hormones or genital surgery, that an adult makes their own medical decision, and that disagreeing with someone is not a reason to harass them. What name a classroom uses, and whether a school may approve those drugs, are separate questions, and this isn't my whole view." }, + { "id": "commonality", "role": "commonality", "text": "I'd be okay with a rule that minors are not given cross-sex hormones or genital surgery, that an adult makes their own medical decision, and that disagreeing with someone is not a reason to harass them. This isn't my whole view." } + ] + }, + { + "id": "opinion-employment", + "title": "Ordinary opinions and employment", + "notes": ["Draft bridge. Unevaluated."], + "statements": [ + { "id": "natural-left", "role": "natural-left", "text": "Nobody should lose their livelihood because they said something unpopular." }, + { "id": "natural-right", "role": "natural-right", "text": "Institutions are ending people's careers over ordinary political opinions, and that should stop." }, + { "id": "modified-left", "role": "modified-left", "text": "I don't want someone treated as unemployable for an ordinary political opinion. I still want a workplace to respond to threats, to harassment of coworkers, and to someone refusing to do the job. I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment. I don't have to defend every opinion." }, + { "id": "modified-right", "role": "modified-right", "text": "Institutions should stop ending people's careers over ordinary political opinions. I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment. I don't need every sanction anywhere to be forbidden." }, + { "id": "commonality", "role": "commonality", "text": "I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment." } + ] + }, + { + "id": "canada-us-ties", + "title": "Ordinary Canada-US ties", + "notes": ["Draft bridge. Unevaluated. Weakest wording: the commonality talks about being okay with saying the want."], + "statements": [ + { "id": "natural-left", "role": "natural-left", "text": "I don't like Trump, and I still think it's foolish for Canadians to cut off ordinary buying and family visits to the US." }, + { "id": "natural-right", "role": "natural-right", "text": "Canada should keep its ordinary ties with the US. There's nothing wrong with that." }, + { "id": "modified-left", "role": "modified-left", "text": "I don't like the current US administration. I'd still rather Canadians keep buying ordinary goods from US businesses and visiting family there than join a boycott of those ordinary ties. I'd be okay with saying that ordinary Canadians should keep buying from US businesses and visiting family in the US, and that this is not a statement about the current US administration." }, + { "id": "modified-right", "role": "modified-right", "text": "I want Canadians to keep buying ordinary goods from US businesses and visiting family in the US. I may be fine with the current administration, but that is not this question. I'd be okay with saying that ordinary Canadians should keep buying from US businesses and visiting family in the US, and that this is not a statement about the current US administration." }, + { "id": "commonality", "role": "commonality", "text": "I'd be okay with saying that ordinary Canadians should keep buying from US businesses and visiting family in the US, and that this is not a statement about the current US administration." } + ] } ] } diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.json b/fake-data-generation/campaigns/network-societies-v1-b2.json index 6d34ecd8..15d2802c 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2.json @@ -2,7 +2,7 @@ "schema": "commonality-testnet-campaign-v1", "campaign": { "id": "network-societies-v1-b2", - "label": "Network societies batch 2 — pilot families plus abortion, schools, and voting", + "label": "Network societies batch 2 — pilot families, accepted bridges, and six unevaluated draft bridges", "syntheticDataLabel": "SYNTHETIC CAMPAIGN — NOT REAL USERS, ORGANIZATIONS, OR DELIVERABLES", "userCount": 60, "deterministicSeed": "commonality-network-societies-v1-b2-2026-10-16", @@ -17,10 +17,10 @@ "campaignCollection": "network-societies-v1-b2-statements.json" }, "scale": { - "minCauses": 9, - "maxCauses": 9, - "minStatements": 70, - "maxStatements": 70, + "minCauses": 15, + "maxCauses": 15, + "minStatements": 100, + "maxStatements": 100, "allowRepeatedStatementRefs": true }, "projectStories": "network-societies-v1-b2-projects.json", @@ -461,6 +461,84 @@ "statementId": "moderator-checklist" } ] + }, + { + "id": "grey-assimilation", + "title": "Grey County assimilation sessions", + "activityTier": "medium", + "membershipWeight": 8, + "statementRefs": [ + { "collectionId": "network-societies-v1-b2", "groupId": "grey-assimilation", "statementId": "natural-left" }, + { "collectionId": "network-societies-v1-b2", "groupId": "grey-assimilation", "statementId": "natural-right" }, + { "collectionId": "network-societies-v1-b2", "groupId": "grey-assimilation", "statementId": "modified-left" }, + { "collectionId": "network-societies-v1-b2", "groupId": "grey-assimilation", "statementId": "modified-right" }, + { "collectionId": "network-societies-v1-b2", "groupId": "grey-assimilation", "statementId": "commonality" } + ] + }, + { + "id": "ranked-approval-poll", + "title": "Owen Sound dual count", + "activityTier": "medium", + "membershipWeight": 7, + "statementRefs": [ + { "collectionId": "network-societies-v1-b2", "groupId": "ranked-approval-poll", "statementId": "natural-left" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ranked-approval-poll", "statementId": "natural-right" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ranked-approval-poll", "statementId": "modified-left" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ranked-approval-poll", "statementId": "modified-right" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ranked-approval-poll", "statementId": "commonality" } + ] + }, + { + "id": "checkout-trial-bridge", + "title": "Owen Sound checkout bridge", + "activityTier": "medium", + "membershipWeight": 8, + "statementRefs": [ + { "collectionId": "network-societies-v1-b2", "groupId": "checkout-trial-bridge", "statementId": "natural-left" }, + { "collectionId": "network-societies-v1-b2", "groupId": "checkout-trial-bridge", "statementId": "natural-right" }, + { "collectionId": "network-societies-v1-b2", "groupId": "checkout-trial-bridge", "statementId": "modified-left" }, + { "collectionId": "network-societies-v1-b2", "groupId": "checkout-trial-bridge", "statementId": "modified-right" }, + { "collectionId": "network-societies-v1-b2", "groupId": "checkout-trial-bridge", "statementId": "commonality" } + ] + }, + { + "id": "minors-medicine", + "title": "Minors medicine and courtesy", + "activityTier": "medium", + "membershipWeight": 7, + "statementRefs": [ + { "collectionId": "network-societies-v1-b2", "groupId": "minors-medicine", "statementId": "natural-left" }, + { "collectionId": "network-societies-v1-b2", "groupId": "minors-medicine", "statementId": "natural-right" }, + { "collectionId": "network-societies-v1-b2", "groupId": "minors-medicine", "statementId": "modified-left" }, + { "collectionId": "network-societies-v1-b2", "groupId": "minors-medicine", "statementId": "modified-right" }, + { "collectionId": "network-societies-v1-b2", "groupId": "minors-medicine", "statementId": "commonality" } + ] + }, + { + "id": "opinion-employment", + "title": "Ordinary opinion and employment", + "activityTier": "small", + "membershipWeight": 6, + "statementRefs": [ + { "collectionId": "network-societies-v1-b2", "groupId": "opinion-employment", "statementId": "natural-left" }, + { "collectionId": "network-societies-v1-b2", "groupId": "opinion-employment", "statementId": "natural-right" }, + { "collectionId": "network-societies-v1-b2", "groupId": "opinion-employment", "statementId": "modified-left" }, + { "collectionId": "network-societies-v1-b2", "groupId": "opinion-employment", "statementId": "modified-right" }, + { "collectionId": "network-societies-v1-b2", "groupId": "opinion-employment", "statementId": "commonality" } + ] + }, + { + "id": "canada-us-ties", + "title": "Ordinary Canada-US ties", + "activityTier": "small", + "membershipWeight": 6, + "statementRefs": [ + { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "natural-left" }, + { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "natural-right" }, + { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "modified-left" }, + { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "modified-right" }, + { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "commonality" } + ] } ], "personas": [ @@ -991,8 +1069,8 @@ "type": "publish-statement", "prerequisites": [], "targetCount": { - "min": 70, - "max": 70 + "min": 100, + "max": 100 } }, { @@ -1001,8 +1079,8 @@ "publish-statement" ], "targetCount": { - "min": 9, - "max": 9 + "min": 15, + "max": 15 } }, { @@ -1031,8 +1109,8 @@ "create-cause" ], "targetCount": { - "min": 40, - "max": 40 + "min": 52, + "max": 52 } }, { @@ -1091,8 +1169,8 @@ "publish-statement" ], "targetCount": { - "min": 8, - "max": 8 + "min": 32, + "max": 32 } }, { @@ -1102,8 +1180,8 @@ "create-bridge-board" ], "targetCount": { - "min": 2, - "max": 2 + "min": 8, + "max": 8 } } ], diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.md b/fake-data-generation/campaigns/network-societies-v1-b2.md index 4e1cbf3d..81f2fb36 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2.md +++ b/fake-data-generation/campaigns/network-societies-v1-b2.md @@ -12,11 +12,13 @@ The other eight families in the brainstorming plan are not in this manifest. ## What the plan publishes -A plan written on 2026-10-16 has 60 users, 70 statements, 40 projects, and 356 writes. Seed: `commonality-network-societies-v1-b2-2026-10-16`. +A plan written on 2026-10-16 has 60 users, 100 statements, 52 projects. Seed: `commonality-network-societies-v1-b2-2026-10-16`. Regenerate the plan before quoting a write count. The old 356-write figure was for 70 statements and 40 projects. The abortion cause and the schools cause are bridge-shaped. Each main board lists only the accepted commonality sentence. The natural and modified sentences are on the side boards. The Michigan authority board and the Grey County conduct board are ordinary boards, so their own sentences stay visible there. -Four implication actions are planned. They are the accepted modified-left and modified-right arrows onto each commonality. Evidence recorded on the action is `accepted-bridge-role-pair`, the same marker the medium campaign uses. This session did not call the attester. No other pair is published. Candidates that were not evaluated are listed in `network-societies-v1-b2-decisions.json`. +Six more causes are also bridge-shaped, from `statement-generation-exercises/06-network-society-alliances.json`: Grey County assimilation sessions, the Owen Sound dual-count poll, the Owen Sound checkout trial, minors' medicine and courtesy, ordinary opinions and employment, and ordinary Canada–US ties. Their side boards exist. No implication action is planned for them. The planner still stamps `accepted-bridge-role-pair` on every modified-to-commonality action it does emit, and that stamp is only honest for the accepted abortion and schools pairs. Keep the attest-implication count at 4 until a real attester blesses a new pair. + +Four implication actions are planned. They are the accepted modified-left and modified-right arrows onto each of those two commonalities. This session did not call the attester. Candidates that were not evaluated are listed in `network-societies-v1-b2-decisions.json`. `moderator-checklist` is one statement. It is on the Michigan authority board and the Owen Sound voting board. One project, "Moderator checklist card", references it. diff --git a/fake-data-generation/statement-generation-exercises/06-network-society-alliances.json b/fake-data-generation/statement-generation-exercises/06-network-society-alliances.json new file mode 100644 index 00000000..ba707733 --- /dev/null +++ b/fake-data-generation/statement-generation-exercises/06-network-society-alliances.json @@ -0,0 +1,206 @@ +{ + "format": "commonality-seed-content-v1", + "id": "statement-generation-exercise-06", + "title": "Exercise — network-society organic alliances (draft, not accepted)", + "description": "Draft bridges from fake-data-generation/brainstorming/README.md. Not loaded by loadSeedCollections. Not accepted into seed-content. No implication attester call has been run. Abortion cutoff and schools-pushing stay in their accepted files and are not rewritten here.", + "notes": [ + "A bridge needs a real concession. Same outcome, different motive, with both sides already willing to sign the outcome, is overlap and is not given a triple.", + "Skipped as overlap or as a weaker same-conclusion pattern: low-carb enclaves, the unwoke umbrella, Democracy 2.0 as a second voting cause, Christianity crossed with secular conservatives, home-schoolers and school families sharing field-trip notes, and 'both sides already dislike first-past-the-post.'", + "The accepted immigration cluster is about deportation. The assimilation triple below is about what a local program does. Do not merge them.", + "The accepted schools cluster is about pushing versus support. The youth-medicine triple below does not settle that, classroom names, or school approval of drugs." + ], + "groups": [ + { + "id": "grey-county-assimilation-sessions", + "title": "Grey County practical-English sessions, without a customs program or an origin-language township office", + "pattern": "compromise in the middle", + "statements": [ + { + "id": "natural-left", + "role": "natural-left", + "text": "I want newcomers in Grey County to be able to learn practical English and how the library, the bus, and a township office work, and I want them to be able to keep their own customs." + }, + { + "id": "natural-right", + "role": "natural-right", + "text": "If people move to Grey County, they should join the local way of life. I don't want the township running services in origin languages forever." + }, + { + "id": "modified-left", + "role": "modified-left", + "text": "I want newcomers in Grey County to be able to learn practical English and how the library, the bus, and a township office work, and I want them to be able to keep their own customs. I'd be okay with twelve evening practical-English sessions in Owen Sound, with childcare, that explain those four things, while township business stays in English and the sessions stop short of telling newcomers which customs to keep. I would not want this to become a second township office in origin languages. This isn't my whole view of immigration." + }, + { + "id": "modified-right", + "role": "modified-right", + "text": "If people move to Grey County, they should be able to function in the local civic life, and I don't want the township running services in origin languages forever. I'd still rather see less immigration, but that is a different question. I'd be okay with twelve evening practical-English sessions in Owen Sound, with childcare, that explain the library, the bus, and a township office, while township business stays in English and the sessions stop short of telling newcomers which customs to keep. This isn't my whole view of immigration." + }, + { + "id": "commonality", + "role": "commonality", + "text": "I'd be okay with twelve evening practical-English sessions in Owen Sound, with childcare, that explain the library, the bus, and a township office, while township business stays in English and the sessions stop short of telling newcomers which customs to keep. This isn't my whole view of immigration." + } + ] + }, + { + "id": "owen-sound-dual-count", + "title": "One non-binding Owen Sound poll that publishes both counts", + "pattern": "different preferred replacements, same limited trial", + "statements": [ + { + "id": "natural-left", + "role": "natural-left", + "text": "First-past-the-post wastes my vote. I want ranked ballots." + }, + { + "id": "natural-right", + "role": "natural-right", + "text": "First-past-the-post rewards the biggest camp. I want approval voting, not a ranked system." + }, + { + "id": "modified-left", + "role": "modified-left", + "text": "First-past-the-post wastes my vote. I want ranked ballots for a real election. I'd be okay with one Owen Sound community association running a non-binding poll and publishing both a ranked count and an approval count of the same ballots. That is not a change to Owen Sound's municipal elections, and publishing the approval count is not me dropping ranked ballots." + }, + { + "id": "modified-right", + "role": "modified-right", + "text": "First-past-the-post rewards the biggest camp. I want approval voting, not a ranked system, for a real election. I'd be okay with one Owen Sound community association running a non-binding poll and publishing both a ranked count and an approval count of the same ballots. That is not a change to Owen Sound's municipal elections, and publishing the ranked count is not me adopting ranked ballots." + }, + { + "id": "commonality", + "role": "commonality", + "text": "I'd be okay with one Owen Sound community association running a non-binding poll and publishing both a ranked count and an approval count of the same ballots. That is not a change to Owen Sound's municipal elections." + } + ] + }, + { + "id": "owen-sound-crypto-trial", + "title": "A three-month Owen Sound checkout trial that still takes cash and cards", + "pattern": "different problems, same solution", + "statements": [ + { + "id": "natural-left", + "role": "natural-left", + "text": "I want shops to take crypto so a bank can't decide whether a customer gets to pay." + }, + { + "id": "natural-right", + "role": "natural-right", + "text": "I'm tired of handing three percent of every sale to the card companies." + }, + { + "id": "modified-left", + "role": "modified-left", + "text": "I want a willing shop and a willing customer to be able to complete a payment when a bank has blocked that customer. Replacing the banks is a bigger thing than this. I'd be okay with six named shops in Owen Sound trying, for three months, a checkout that can take a crypto payment and refund it, show the fee on a twenty-dollar sale before the customer pays, and keep taking cash and ordinary cards the whole time." + }, + { + "id": "modified-right", + "role": "modified-right", + "text": "I'm tired of handing three percent of every sale to the card companies. I don't care about crypto as a cause. I'd still be okay with six named shops in Owen Sound trying, for three months, a checkout that can take a crypto payment and refund it, show the fee on a twenty-dollar sale before the customer pays, and keep taking cash and ordinary cards the whole time. If the trial is a bad deal, I want the fees and failures published." + }, + { + "id": "commonality", + "role": "commonality", + "text": "I'd be okay with six named shops in Owen Sound trying, for three months, a checkout that can take a crypto payment and refund it, show the fee on a twenty-dollar sale before the customer pays, and keep taking cash and ordinary cards the whole time." + } + ] + }, + { + "id": "minors-medicine-and-courtesy", + "title": "No cross-sex hormones or genital surgery for minors; adults decide; don't harass people", + "pattern": "compromise in the middle", + "statements": [ + { + "id": "natural-left", + "role": "natural-left", + "text": "I want a young person in distress about their sex to be able to get medical treatment, including hormones, and I want the rest of us to stop being cruel about it." + }, + { + "id": "natural-right", + "role": "natural-right", + "text": "I don't want children given drugs or surgery to try to change their sex." + }, + { + "id": "modified-left", + "role": "modified-left", + "text": "I want adults to make their own medical decisions, and I want disagreeing with someone to not be a reason to harass them. I'd prefer doctors and families to decide about hormones for minors case by case, but I'd be okay with a rule that minors are not given cross-sex hormones or genital surgery, that an adult makes their own medical decision, and that disagreeing with someone is not a reason to harass them. This isn't my ideal." + }, + { + "id": "modified-right", + "role": "modified-right", + "text": "I don't want children given drugs or surgery to try to change their sex. I'd be okay with a rule that minors are not given cross-sex hormones or genital surgery, that an adult makes their own medical decision, and that disagreeing with someone is not a reason to harass them. What name a classroom uses, and whether a school may approve those drugs, are separate questions, and this isn't my whole view." + }, + { + "id": "commonality", + "role": "commonality", + "text": "I'd be okay with a rule that minors are not given cross-sex hormones or genital surgery, that an adult makes their own medical decision, and that disagreeing with someone is not a reason to harass them. This isn't my whole view." + } + ] + }, + { + "id": "ordinary-opinion-not-unemployable", + "title": "An ordinary political opinion, by itself, does not make someone unemployable", + "pattern": "compromise in the middle", + "statements": [ + { + "id": "natural-left", + "role": "natural-left", + "text": "Nobody should lose their livelihood because they said something unpopular." + }, + { + "id": "natural-right", + "role": "natural-right", + "text": "Institutions are ending people's careers over ordinary political opinions, and that should stop." + }, + { + "id": "modified-left", + "role": "modified-left", + "text": "I don't want someone treated as unemployable for an ordinary political opinion. I still want a workplace to respond to threats, to harassment of coworkers, and to someone refusing to do the job. I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment. I don't have to defend every opinion." + }, + { + "id": "modified-right", + "role": "modified-right", + "text": "Institutions should stop ending people's careers over ordinary political opinions. I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment. I don't need every sanction anywhere to be forbidden." + }, + { + "id": "commonality", + "role": "commonality", + "text": "I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment." + } + ] + }, + { + "id": "canada-ordinary-us-ties", + "title": "Keep ordinary Canada–US purchases and family visits, without a statement about the administration", + "pattern": "different problems, same solution", + "statements": [ + { + "id": "natural-left", + "role": "natural-left", + "text": "I don't like Trump, and I still think it's foolish for Canadians to cut off ordinary buying and family visits to the US." + }, + { + "id": "natural-right", + "role": "natural-right", + "text": "Canada should keep its ordinary ties with the US. There's nothing wrong with that." + }, + { + "id": "modified-left", + "role": "modified-left", + "text": "I don't like the current US administration. I'd still rather Canadians keep buying ordinary goods from US businesses and visiting family there than join a boycott of those ordinary ties. I'd be okay with saying that ordinary Canadians should keep buying from US businesses and visiting family in the US, and that this is not a statement about the current US administration." + }, + { + "id": "modified-right", + "role": "modified-right", + "text": "I want Canadians to keep buying ordinary goods from US businesses and visiting family in the US. I may be fine with the current administration, but that is not this question. I'd be okay with saying that ordinary Canadians should keep buying from US businesses and visiting family in the US, and that this is not a statement about the current US administration." + }, + { + "id": "commonality", + "role": "commonality", + "text": "I'd be okay with saying that ordinary Canadians should keep buying from US businesses and visiting family in the US, and that this is not a statement about the current US administration." + } + ] + } + ] +} diff --git a/fake-data-generation/statement-generation-exercises/README.md b/fake-data-generation/statement-generation-exercises/README.md index 12f2cb21..1c50da8b 100644 --- a/fake-data-generation/statement-generation-exercises/README.md +++ b/fake-data-generation/statement-generation-exercises/README.md @@ -11,4 +11,5 @@ Draft corpora for the loop in [`../statement-generation.md`](../statement-genera | [`03-compromise-immigration.json`](./03-compromise-immigration.json) | Left/right immigration compromise. **Accepted** into [`../seed-content/compromise-immigration.json`](../seed-content/compromise-immigration.json) (2026-08-31). Gold copy stays here. | | [`04-crime-repeat-offenders.json`](./04-crime-repeat-offenders.json) | Left/right crime fact-conditional (repeat-offender concentration). **Accepted** into [`../seed-content/crime-repeat-offenders.json`](../seed-content/crime-repeat-offenders.json) (2026-08-31). Gold copy stays here. | | [`05-lgbt-schools.json`](./05-lgbt-schools.json) | Left/right LGBT schools fact-conditional. **Accepted** into [`../seed-content/lgbt-schools.json`](../seed-content/lgbt-schools.json) (2026-08-31). Gold copy stays here. | +| [`06-network-society-alliances.json`](./06-network-society-alliances.json) | Draft organic-alliance triples from the network-society brainstorm. **Not accepted.** No attester run. | | Next (not drafted) | Left/right **LGB-vs-T coalition unbundling** if Adam still wants that seam after accepting (or vetoing) the schools cluster. See [`../PLAN.md`](../PLAN.md). | diff --git a/fake-data-generation/test/campaignPlanner.test.ts b/fake-data-generation/test/campaignPlanner.test.ts index 0f73f9d4..ba35486e 100644 --- a/fake-data-generation/test/campaignPlanner.test.ts +++ b/fake-data-generation/test/campaignPlanner.test.ts @@ -241,8 +241,8 @@ test('batch 2 keeps the pilot families, reuses accepted bridges, and shares one } const plan = await buildCampaignPlan(manifest); assert.equal(plan.users.length, 60); - assert.equal(plan.statements.length, 70); - assert.equal(plan.projects.length, 40); + assert.equal(plan.statements.length, 100); + assert.equal(plan.projects.length, 52); const checklist = plan.statements.find((statement) => statement.source.statementId === 'moderator-checklist'); assert.ok(checklist); assert.equal(checklist!.causeId, 'abortion-forum'); @@ -268,6 +268,11 @@ test('batch 2 keeps the pilot families, reuses accepted bridges, and shares one const forum = plan.actions.find((action) => action.type === 'create-cause' && action.causeId === 'abortion-forum')!.board!; assert.equal(forum.role, 'plain'); assert.ok(forum.statementIds.includes(michigan.id)); + for (const causeId of ['grey-assimilation', 'ranked-approval-poll', 'checkout-trial-bridge', 'minors-medicine', 'opinion-employment', 'canada-us-ties']) { + const board = plan.actions.find((action) => action.type === 'create-cause' && action.causeId === causeId)!.board!; + assert.equal(board.role, 'commonality'); + assert.equal(implications.some((action) => action.causeId === causeId), false, causeId); + } for (const causeId of manifest.causes.map((cause) => cause.id)) { assert.ok(plan.projects.filter((project) => project.causeId === causeId).length >= 2, causeId); } From 115b6feb856beaf28627cfe21dbe059a684e006c Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 17:01:03 -0400 Subject: [PATCH 11/19] Bless the batch-2 draft bridges and record the local run. Live deepseek-v3.2 checks allow twelve modified-to-commonality arrows. v4-flash returned empty content, so it is not the evidence. --- ...6-network-societies-b2-executed-handoff.md | 35 + fake-data-generation/PLAN.md | 2 +- fake-data-generation/campaignPlanner.ts | 31 +- fake-data-generation/campaignSchema.ts | 28 + .../network-societies-v1-b2-decisions.json | 23 +- ...cieties-v1-b2-implication-evaluations.json | 1169 +++++++++++++++++ .../network-societies-v1-b2-statements.json | 12 +- .../campaigns/network-societies-v1-b2.json | 40 +- .../campaigns/network-societies-v1-b2.md | 12 +- .../06-network-society-alliances.json | 13 +- .../statement-generation-exercises/README.md | 2 +- .../test/campaignPlanner.test.ts | 16 +- 12 files changed, 1342 insertions(+), 41 deletions(-) create mode 100644 continuity/2026-10-16-network-societies-b2-executed-handoff.md create mode 100644 fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json diff --git a/continuity/2026-10-16-network-societies-b2-executed-handoff.md b/continuity/2026-10-16-network-societies-b2-executed-handoff.md new file mode 100644 index 00000000..817fed94 --- /dev/null +++ b/continuity/2026-10-16-network-societies-b2-executed-handoff.md @@ -0,0 +1,35 @@ +# Handoff: DeepSeek model for opencode-go, then the leftover campaign gaps + +Next session: figure out which DeepSeek model `opencode-go` should use. `deepseek-v4-flash` is a poor default for implication checks. Try whether 4.1 flash returns JSON. Do not treat that model hunt as a reason to rewrite the batch-2 statements again. + +## Read first + +- [`fake-data-generation/campaigns/network-societies-v1-b2.md`](../fake-data-generation/campaigns/network-societies-v1-b2.md) — what batch 2 published. +- [`fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json`](../fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json) — 68 live pairs. Model `deepseek/deepseek-v3.2`. Prompt fingerprint `2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891`. +- [`fake-data-generation/campaigns/network-societies-v1-b2-decisions.json`](../fake-data-generation/campaigns/network-societies-v1-b2-decisions.json) — allowed arrows and the five first-wording refusals. +- [`verifier/llm-routing.json`](../verifier/llm-routing.json) — subscription pin. Every task kind is `xai/grok-4.6`. Allowed providers are `xai` and `opencode-go`. Never OpenRouter for verifier leaves. +- [`services/attester-core/src/llm-models.ts`](../services/attester-core/src/llm-models.ts) and [`services/attester-core/src/openrouter.ts`](../services/attester-core/src/openrouter.ts) — production OpenRouter default is `deepseek/deepseek-v4-flash-0731`, and `requestJsonCompletionWithUsage` caps `max_tokens` at 500. +- Branch `campaign`. Do not commit on `dev` or `master`. + +## What is already true + +Batch 2 was executed locally into `output/campaigns/network-societies-v1-b2/` (gitignored). 446/446 mined and reconciled. The first pass failed 14 actions with insufficient ETH (`setBeliefsInBatch` and large publishes). Those wallets were topped up with `hardhat_setBalance` and the run resumed. Do not overwrite the pilot or `medium-realistic-v2` outputs. + +Twelve new modified-to-commonality arrows are planned with evidence `live-attester-modified-to-commonality`. Abortion and schools stay `accepted-bridge-role-pair`. The six clusters are not accepted seed. Employment modifieds and the Canada commonality were rewritten once so designed-no pairs refuse. Details are in the campaign note, not repeated here. + +`deepseek/deepseek-v4-flash-0731` returned an empty message body on the longer pairs. That is the same stall recorded for the abortion live check in [`statement-generation-exercises/02-compromise-abortion.json`](../fake-data-generation/statement-generation-exercises/02-compromise-abortion.json). v3.2 returned JSON. Heuristic `implies: true` was not used. + +The Grey County assimilation commonality board loaded at `http://commonality.localhost:8088/#/cause/0xEe6a18208ca061e2Eddd4A6fA7E4E4d4927eF352/network-societies-v1-b2-grey-assimilation-bridge`. The statement page shows "Arriving through other statements." Direct and indirect counts were 0 on that load. + +## What to do + +1. Decide the `opencode-go` DeepSeek model. `verifier/llm-routing.json` does not name one yet. An older note in [`verifier/verifier-checks-need-founder-level-understanding.md`](../verifier/verifier-checks-need-founder-level-understanding.md) pointed `clear-communication` at `deepseek-v4-pro`. Adam's guess: 4.1 flash may work better than v4-flash. Check the model ids `pi` / opencode-go actually accept, then run one short JSON implication pair and one longer modified-to-commonality pair. Record empty body versus a real decision. If v4-flash only fails because reasoning tokens eat the 500-token cap, say so. Do not switch production `PRODUCTION_OPENROUTER_MODEL` unless a model both returns JSON and matches the v3.2 designed-yes/no pattern on a few known pairs. +2. The campaign gas estimate underfunded 14 wallets on this run. Look at `computeCampaignFundingNeeds` versus the gas viem actually requests (`setBeliefsInBatch` at 280000, publishes around 4e6). A resume should not need a manual `hardhat_setBalance`. +3. Persona `set-belief` choices in the decisions file are still not applied. Eli can still be planned as believing the abortion commonality. +4. Delegated spending and a recurring monthly pledge are still not campaign actions. +5. The remaining brainstorm families (low-carb, unwoke as an umbrella, Democracy 2.0, Islamic reform, permitting, home-school beyond the pilot) are still unauthored. Do not force triples onto overlaps that already share a concrete want. + +## Suggested skills + +- `thorough-tester` — one short and one long implication pair per candidate model, plus the gas-estimate shortfall. +- `browser-driving` — only if a later execute changes a board. This session already opened the assimilation commonality. diff --git a/fake-data-generation/PLAN.md b/fake-data-generation/PLAN.md index 7570fa9e..4384b254 100644 --- a/fake-data-generation/PLAN.md +++ b/fake-data-generation/PLAN.md @@ -82,7 +82,7 @@ Do these in order unless Adam names a different one. Each item is a session-size The four-family pilot (crypto merchants, Grey County civic life, Christian teaching, home learning) is in [`campaigns/network-societies-v1-pilot.md`](./campaigns/network-societies-v1-pilot.md). A local run on 2026-10-16 mined and reconciled 207/207. Cause pages list the shared class-host directory once the alignment-trust bootstrap wallet has gas. -Batch 2 keeps those four families and adds the accepted abortion bridge, the accepted schools-pushing bridge, an Owen Sound voting trial, and six unevaluated draft bridges (assimilation sessions, dual-count poll, checkout trial, minors' medicine, ordinary opinions and employment, Canada–US ties). Wording is in [`statement-generation-exercises/06-network-society-alliances.json`](./statement-generation-exercises/06-network-society-alliances.json) and copied into the batch-2 statement file. The note is [`campaigns/network-societies-v1-b2.md`](./campaigns/network-societies-v1-b2.md). The manifest is 60 users, 100 statements, and 52 projects. It publishes only the four already-accepted modified-to-commonality arrows. The six new clusters are bridge-shaped boards without implication actions. The batch has not been executed. Persona `set-belief` choices are still not wired. Next: run the real implication-attester prompt on the six clusters, including the designed-negative pairs, then raise the attest-implication count only for pairs that receive an affirmative decision. +Batch 2 keeps those four families and adds the accepted abortion bridge, the accepted schools-pushing bridge, an Owen Sound voting trial, and six draft bridges (assimilation sessions, dual-count poll, checkout trial, minors' medicine, ordinary opinions and employment, Canada–US ties). Wording is in [`statement-generation-exercises/06-network-society-alliances.json`](./statement-generation-exercises/06-network-society-alliances.json) and copied into the batch-2 statement file. The note is [`campaigns/network-societies-v1-b2.md`](./campaigns/network-societies-v1-b2.md). The manifest is 60 users, 100 statements, and 52 projects. A 2026-10-16 live attester pass (deepseek/deepseek-v3.2) blessed all twelve new modified-to-commonality arrows and refused the designed-negative pairs after a rewrite of the employment modifieds and the Canada wording. The plan allows those twelve arrows with evidence `live-attester-modified-to-commonality`, plus the four accepted abortion and schools arrows. The six clusters are not accepted seed. A local run on 2026-10-16 mined and reconciled 446/446 into `output/campaigns/network-societies-v1-b2/`. Persona `set-belief` choices are still not wired. ## Pointers diff --git a/fake-data-generation/campaignPlanner.ts b/fake-data-generation/campaignPlanner.ts index 3d3c6dab..159f8b8d 100644 --- a/fake-data-generation/campaignPlanner.ts +++ b/fake-data-generation/campaignPlanner.ts @@ -3,7 +3,7 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { estimateGroupGas, groupCampaignWrites } from './campaignBatching.js'; -import { type CampaignActionType, type CampaignManifestV1, type CampaignRole, validateCampaignManifest } from './campaignSchema.js'; +import { type CampaignActionType, type CampaignImplicationEvidence, type CampaignManifestV1, type CampaignRole, validateCampaignManifest } from './campaignSchema.js'; import { FAKE_DATA_NOTE, bridgeMediatorNote, causeBoardSummary, projectOutcome } from './campaignCopy.js'; import { CAMPAIGN_PROJECT_STORIES, SPOTLIGHT_PROJECTS } from './campaignProjectStories.js'; import { flattenSeedStatements, loadSeedCollections, validateSeedCollection, type SeedCollection } from './seed-content-format.js'; @@ -64,7 +64,7 @@ export interface PlannedAction { funding?: { kind: 'early' | 'retroactive'; tokenId?: 1 | 3; tokenCount?: number; camp?: 'left' | 'right' }; alignment?: 'supports-described-outcome'; delegationBasis?: { sharedCauseIds: string[]; reason: 'shared-cause-trusted-role' }; - implication?: { fromStatementId: string; toStatementId: string; evidence: 'accepted-bridge-role-pair' }; + implication?: { fromStatementId: string; toStatementId: string; evidence: CampaignImplicationEvidence }; /** Binding key when one cause publishes more than one board. Defaults to causeId. */ boardId?: string; board?: PlannedCauseBoard; @@ -216,7 +216,10 @@ function usersForCause(users: PlannedUser[], causeId: string): PlannedUser[] { function chooseCauseAttester(users: PlannedUser[], causeId: string, random: Xoshiro128StarStar): PlannedUser { const members = usersForCause(users, causeId); - return random.weighted(members, (user) => user.activityWeight * (user.roles.includes('attester') || user.roles.includes('mediator') ? 8 : 1)); + const active = members.filter((user) => user.activityWeight > 0); + const pool = active.length > 0 ? active : members; + if (pool.length === 0) throw new Error(`no member to attest an implication on ${causeId}`); + return random.weighted(pool, (user) => Math.max(user.activityWeight, 1) * (user.roles.includes('attester') || user.roles.includes('mediator') ? 8 : 1)); } function preferredStatements(user: PlannedUser, statements: PlannedStatement[]): PlannedStatement[] { @@ -448,15 +451,25 @@ export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise { - const groupStatements = statementsOnCause(statements, cause.id); - const commonality = groupStatements.find((statement) => statement.role === 'commonality'); - return commonality ? groupStatements.filter((statement) => statement.role === 'modified-left' || statement.role === 'modified-right').map((from) => ({ from, to: commonality })) : []; - }); + const implicationPairs = manifest.implicationAllowances + ? manifest.implicationAllowances.map((allowance) => { + const from = statementByKey.get(statementKey(allowance.from)); + const to = statementByKey.get(statementKey(allowance.to)); + if (!from || !to) throw new Error(`implication allowance is not on a board: ${statementKey(allowance.from)} -> ${statementKey(allowance.to)}`); + return { from, to, evidence: allowance.evidence }; + }) + : manifest.causes.flatMap((cause) => { + const groupStatements = statementsOnCause(statements, cause.id); + const commonality = groupStatements.find((statement) => statement.role === 'commonality'); + return commonality ? groupStatements.filter((statement) => statement.role === 'modified-left' || statement.role === 'modified-right').map((from) => ({ from, to: commonality, evidence: 'accepted-bridge-role-pair' as const })) : []; + }); if (countByType['attest-implication'] > 0 && implicationPairs.length === 0) throw new Error('no suitable accepted implication pairs are available'); + if (manifest.implicationAllowances && countByType['attest-implication'] > implicationPairs.length) { + throw new Error(`attest-implication target ${countByType['attest-implication']} exceeds ${implicationPairs.length} allowed pairs`); + } for (let index = 0; index < countByType['attest-implication']; index++) { const pair = implicationPairs[index % implicationPairs.length]; validateImplicationPair(pair.from, pair.to); - add({ type: 'attest-implication', actorUserId: chooseCauseAttester(activeUsers, pair.from.causeId, random).id, causeId: pair.from.causeId, implication: { fromStatementId: pair.from.id, toStatementId: pair.to.id, evidence: 'accepted-bridge-role-pair' }, dependsOn: [publishes.get(pair.from.id)!.id, publishes.get(pair.to.id)!.id] }); + add({ type: 'attest-implication', actorUserId: chooseCauseAttester(users, pair.from.causeId, random).id, causeId: pair.from.causeId, implication: { fromStatementId: pair.from.id, toStatementId: pair.to.id, evidence: pair.evidence }, dependsOn: [publishes.get(pair.from.id)!.id, publishes.get(pair.to.id)!.id] }); } const createProjects = new Map(projects.map((project) => [project.id, add({ type: 'create-project', actorUserId: project.founderUserId, causeId: project.causeId, projectId: project.id, dependsOn: [causes.get(project.causeId)!.id] })])); const alignments: PlannedAction[] = []; diff --git a/fake-data-generation/campaignSchema.ts b/fake-data-generation/campaignSchema.ts index fadc765e..ec339db7 100644 --- a/fake-data-generation/campaignSchema.ts +++ b/fake-data-generation/campaignSchema.ts @@ -104,6 +104,19 @@ export interface CampaignManifestV1 { scale?: CampaignScale; /** Curated project stories beside the manifest. Not a TypeScript story module. */ projectStories?: string; + /** + * When set, attest-implication uses only these pairs and their evidence labels. + * Absent manifests still plan every modified-to-commonality pair as accepted-bridge-role-pair. + */ + implicationAllowances?: CampaignImplicationAllowance[]; +} + +export type CampaignImplicationEvidence = 'accepted-bridge-role-pair' | 'live-attester-modified-to-commonality'; + +export interface CampaignImplicationAllowance { + from: CampaignStatementRef; + to: CampaignStatementRef; + evidence: CampaignImplicationEvidence; } function requireUnique(values: string[], label: string): void { @@ -143,6 +156,21 @@ function validateCauses(manifest: CampaignManifestV1): void { if (manifest.causes.some((cause) => cause.membershipWeight <= 0 || cause.statementRefs.length === 0)) { throw new Error('every cause needs a positive membership weight and at least one statement'); } + const allowances = manifest.implicationAllowances ?? []; + const allowanceKeys = allowances.map((item) => `${statementRefKey(item.from)}=>${statementRefKey(item.to)}`); + requireUnique(allowanceKeys, 'implication allowances'); + for (const item of allowances) { + if (item.evidence !== 'accepted-bridge-role-pair' && item.evidence !== 'live-attester-modified-to-commonality') { + throw new Error(`invalid implication evidence for ${allowanceKeys[allowances.indexOf(item)]}`); + } + if (item.from.collectionId !== item.to.collectionId || item.from.groupId !== item.to.groupId) { + throw new Error(`implication allowance crosses groups: ${allowanceKeys[allowances.indexOf(item)]}`); + } + } +} + +function statementRefKey(ref: CampaignStatementRef): string { + return `${ref.collectionId}/${ref.groupId}/${ref.statementId}`; } function validatePersonas(manifest: CampaignManifestV1): void { diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json b/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json index 67026103..992dbce5 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json @@ -1,5 +1,5 @@ { - "note": "Authored persona decisions for batch 2. The planner still draws set-belief on its own. Unsigned is not the same as an explicit rejection. Implication edges in the plan are only the four accepted modified-to-commonality pairs from compromise-abortion and lgbt-schools. No new pair was sent to the attester.", + "note": "Authored persona decisions for batch 2. The planner still draws set-belief on its own. Unsigned is not the same as an explicit rejection. Sixteen modified-to-commonality arrows are allowed. The four abortion and schools arrows keep accepted-bridge-role-pair. The twelve draft arrows use live-attester-modified-to-commonality from campaigns/network-societies-v1-b2-implication-evaluations.json (deepseek/deepseek-v3.2, 2026-10-16). Designed-no pairs in that file stay unpublished. v4-flash returned empty content on longer pairs and was not used as a judgment.", "people": [ { "userId": "user-041", "name": "Mara", "signs": ["modified-left", "commonality"], "rejects": ["no-early-abortions"], "unsigned": ["michigan-legislature", "one-federal-rule"], "notes": "The settlement signature is not a signature about which legislature writes the rule." }, { "userId": "user-052", "name": "Eli", "signs": ["natural-right"], "rejects": ["modified-right", "commonality", "modified-left"], "notes": "Keeps the natural position and refuses the settlement. He must not be treated as a supporter of the cutoff through an arrow from natural-right." }, @@ -13,7 +13,26 @@ { "from": "compromise-abortion/modified-left", "to": "compromise-abortion/commonality", "evidence": "accepted-bridge-role-pair", "why": "Accepted 2026-08-30. The planner does not re-run the model." }, { "from": "compromise-abortion/modified-right", "to": "compromise-abortion/commonality", "evidence": "accepted-bridge-role-pair", "why": "Accepted 2026-08-30." }, { "from": "lgbt-schools/modified-left", "to": "lgbt-schools/commonality", "evidence": "accepted-bridge-role-pair", "why": "Accepted 2026-08-31. This arrow is about pushing versus support. It is not a medical claim." }, - { "from": "lgbt-schools/modified-right", "to": "lgbt-schools/commonality", "evidence": "accepted-bridge-role-pair", "why": "Accepted 2026-08-31." } + { "from": "lgbt-schools/modified-right", "to": "lgbt-schools/commonality", "evidence": "accepted-bridge-role-pair", "why": "Accepted 2026-08-31." }, + { "from": "grey-assimilation/modified-left", "to": "grey-assimilation/commonality", "evidence": "live-attester-modified-to-commonality", "why": "2026-10-16 deepseek-v3.2 bless, high. Not accepted seed." }, + { "from": "grey-assimilation/modified-right", "to": "grey-assimilation/commonality", "evidence": "live-attester-modified-to-commonality", "why": "2026-10-16 deepseek-v3.2 bless, high." }, + { "from": "ranked-approval-poll/modified-left", "to": "ranked-approval-poll/commonality", "evidence": "live-attester-modified-to-commonality", "why": "2026-10-16 deepseek-v3.2 bless, high." }, + { "from": "ranked-approval-poll/modified-right", "to": "ranked-approval-poll/commonality", "evidence": "live-attester-modified-to-commonality", "why": "2026-10-16 deepseek-v3.2 bless, high." }, + { "from": "checkout-trial-bridge/modified-left", "to": "checkout-trial-bridge/commonality", "evidence": "live-attester-modified-to-commonality", "why": "2026-10-16 deepseek-v3.2 bless, high." }, + { "from": "checkout-trial-bridge/modified-right", "to": "checkout-trial-bridge/commonality", "evidence": "live-attester-modified-to-commonality", "why": "2026-10-16 deepseek-v3.2 bless, high." }, + { "from": "minors-medicine/modified-left", "to": "minors-medicine/commonality", "evidence": "live-attester-modified-to-commonality", "why": "2026-10-16 deepseek-v3.2 bless, high." }, + { "from": "minors-medicine/modified-right", "to": "minors-medicine/commonality", "evidence": "live-attester-modified-to-commonality", "why": "2026-10-16 deepseek-v3.2 bless, high." }, + { "from": "opinion-employment/modified-left", "to": "opinion-employment/commonality", "evidence": "live-attester-modified-to-commonality", "why": "Blessed after the modifieds gained a camp priority the commonality does not contain." }, + { "from": "opinion-employment/modified-right", "to": "opinion-employment/commonality", "evidence": "live-attester-modified-to-commonality", "why": "Same rewrite. The first wording let commonality imply both modifieds." }, + { "from": "canada-us-ties/modified-left", "to": "canada-us-ties/commonality", "evidence": "live-attester-modified-to-commonality", "why": "Blessed after the commonality dropped 'I'd be okay with saying that' and each modified kept a priority the commonality omits." }, + { "from": "canada-us-ties/modified-right", "to": "canada-us-ties/commonality", "evidence": "live-attester-modified-to-commonality", "why": "The first modified-right was implied by the commonality. The rewrite was not." } + ], + "refusedAndUnpublished": [ + { "from": "opinion-employment/commonality", "to": "opinion-employment/modified-left", "why": "First wording, 2026-10-16, implies true high. Rewritten. The replacement refuses." }, + { "from": "opinion-employment/commonality", "to": "opinion-employment/modified-right", "why": "First wording, implies true high. Rewritten." }, + { "from": "opinion-employment/modified-left", "to": "opinion-employment/modified-right", "why": "First wording, implies true high. Rewritten." }, + { "from": "opinion-employment/modified-right", "to": "opinion-employment/modified-left", "why": "First wording, implies true high. Rewritten." }, + { "from": "canada-us-ties/commonality", "to": "canada-us-ties/modified-right", "why": "First wording, implies true high. Rewritten." } ], "unevaluatedAndUnpublished": [ { "from": "commonality", "to": "michigan-legislature", "why": "Agreement on a cutoff does not imply who should have the authority to write it." }, diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json b/fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json new file mode 100644 index 00000000..c34fedf8 --- /dev/null +++ b/fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json @@ -0,0 +1,1169 @@ +{ + "evaluatedAt": "2026-10-16T20:48:36.080Z", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "promptFingerprintAlgorithm": "sha256", + "statementHashAlgorithm": "sha256", + "source": "evaluateImplicationWithLLM", + "note": "Live model decisions. Heuristic fallback was not used. A bless is not acceptance into seed-content.", + "pairCount": 68, + "mismatchCount": 0, + "evaluations": [ + { + "id": "grey-county-assimilation-sessions:modified-left->commonality", + "expectImplies": true, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "grey-county-assimilation-sessions", + "fromRole": "modified-left", + "toRole": "commonality", + "fromHash": "e6599f2a2a0df237545162ff2d9b12540e6b3a8b14ce9015b288a97d1f739600", + "toHash": "14f2b7e1a419b7695f5c22aa490bb7d53fcdeb55b1b05ac483b582d581ead0e9", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 retains the specific, negotiated proposal from S1 verbatim while dropping the broader opening desire and the final reservation about a 'second township office'.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3205 + }, + { + "id": "grey-county-assimilation-sessions:modified-right->commonality", + "expectImplies": true, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "grey-county-assimilation-sessions", + "fromRole": "modified-right", + "toRole": "commonality", + "fromHash": "98c1fbcd1c66289223e5a7263e9de4def03690d6105ca9c588fa63a7fb9b0b33", + "toHash": "14f2b7e1a419b7695f5c22aa490bb7d53fcdeb55b1b05ac483b582d581ead0e9", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 is a verbatim copy of a portion of S1. S2 drops the preceding claims about civic function, township services, and a preference for less immigration, retaining only the specific proposal about English sessions. This is a clear case of S2 being a subset of the claims made in S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3538 + }, + { + "id": "grey-county-assimilation-sessions:natural-left->commonality", + "expectImplies": false, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "grey-county-assimilation-sessions", + "fromRole": "natural-left", + "toRole": "commonality", + "fromHash": "9ef6284a27ab4ca03293cca2c92009acf32667427ec1a2d5e1914e160c9810de", + "toHash": "14f2b7e1a419b7695f5c22aa490bb7d53fcdeb55b1b05ac483b582d581ead0e9", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a specific, negotiated program proposal (twelve evening sessions, childcare, location in Owen Sound, a limit on content, and a reservation that this is not the signer's whole view) that is not contained in S1. S1 expresses general desires, while S2 adds concrete implementation details and a concession.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3787 + }, + { + "id": "grey-county-assimilation-sessions:natural-right->commonality", + "expectImplies": false, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "grey-county-assimilation-sessions", + "fromRole": "natural-right", + "toRole": "commonality", + "fromHash": "767953b67246777f1e8b7840398451602d8ef34111c4c0b1dcc30e0eaae54879", + "toHash": "14f2b7e1a419b7695f5c22aa490bb7d53fcdeb55b1b05ac483b582d581ead0e9", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a specific, detailed policy proposal (twelve evening sessions with childcare, specific topics, and a defined limit) that is not present in S1. S1 expresses a general principle about joining the local way and not providing services in origin languages forever, but it does not commit the signer to the precise, bounded program described in S2.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3244 + }, + { + "id": "grey-county-assimilation-sessions:natural-left->modified-left", + "expectImplies": false, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "grey-county-assimilation-sessions", + "fromRole": "natural-left", + "toRole": "modified-left", + "fromHash": "9ef6284a27ab4ca03293cca2c92009acf32667427ec1a2d5e1914e160c9810de", + "toHash": "e6599f2a2a0df237545162ff2d9b12540e6b3a8b14ce9015b288a97d1f739600", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple new claims and specifications absent from S1, including a specific program proposal (twelve evening sessions in Owen Sound with childcare), a condition about township business staying in English, a limitation on session content, a negative preference about not creating a second township office, and a disclaimer about the scope of the view.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2868 + }, + { + "id": "grey-county-assimilation-sessions:natural-right->modified-right", + "expectImplies": false, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "grey-county-assimilation-sessions", + "fromRole": "natural-right", + "toRole": "modified-right", + "fromHash": "767953b67246777f1e8b7840398451602d8ef34111c4c0b1dcc30e0eaae54879", + "toHash": "98c1fbcd1c66289223e5a7263e9de4def03690d6105ca9c588fa63a7fb9b0b33", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple substantive claims and specifications not present in S1, including a detailed policy proposal for English sessions, a statement about the speaker's broader immigration preference, and a disclaimer about the scope of the view. This violates the core rule that S2 must add no new claim beyond S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2617 + }, + { + "id": "grey-county-assimilation-sessions:modified-left->modified-right", + "expectImplies": false, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "grey-county-assimilation-sessions", + "fromRole": "modified-left", + "toRole": "modified-right", + "fromHash": "e6599f2a2a0df237545162ff2d9b12540e6b3a8b14ce9015b288a97d1f739600", + "toHash": "98c1fbcd1c66289223e5a7263e9de4def03690d6105ca9c588fa63a7fb9b0b33", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new claim not present in S1: 'I'd still rather see less immigration, but that is a different question.' This is a substantive policy preference about immigration levels that is absent from S1. S1's signer might support the described program without preferring less immigration overall. The core rule is violated because S2 adds a proposition that is absent from S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3381 + }, + { + "id": "grey-county-assimilation-sessions:modified-right->modified-left", + "expectImplies": false, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "grey-county-assimilation-sessions", + "fromRole": "modified-right", + "toRole": "modified-left", + "fromHash": "98c1fbcd1c66289223e5a7263e9de4def03690d6105ca9c588fa63a7fb9b0b33", + "toHash": "e6599f2a2a0df237545162ff2d9b12540e6b3a8b14ce9015b288a97d1f739600", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new claim not contained in S1: 'I want them to be able to keep their own customs.' S1 expresses a desire for newcomers to function in local civic life and for township services not to be run in origin languages forever. It does not make a positive claim about preserving newcomers' customs. This addition is a substantive proposition that someone could agree with S1 but disagree with.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3053 + }, + { + "id": "grey-county-assimilation-sessions:commonality->modified-left", + "expectImplies": false, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "grey-county-assimilation-sessions", + "fromRole": "commonality", + "toRole": "modified-left", + "fromHash": "14f2b7e1a419b7695f5c22aa490bb7d53fcdeb55b1b05ac483b582d581ead0e9", + "toHash": "e6599f2a2a0df237545162ff2d9b12540e6b3a8b14ce9015b288a97d1f739600", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds new claims not present in S1. Specifically, S2 adds the general desire for newcomers to be able to learn and keep their customs, and the explicit rejection of the program becoming a second township office in origin languages. These are substantive, potentially controversial additions that someone who signed S1 might not endorse.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3415 + }, + { + "id": "grey-county-assimilation-sessions:commonality->modified-right", + "expectImplies": false, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "grey-county-assimilation-sessions", + "fromRole": "commonality", + "toRole": "modified-right", + "fromHash": "14f2b7e1a419b7695f5c22aa490bb7d53fcdeb55b1b05ac483b582d581ead0e9", + "toHash": "98c1fbcd1c66289223e5a7263e9de4def03690d6105ca9c588fa63a7fb9b0b33", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new, broader claim about the function of newcomers in local civic life and a policy position on township services that is not contained in S1. S1 is a specific, conditional acceptance of a program, while S2 asserts a general principle and a separate policy preference.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3089 + }, + { + "id": "owen-sound-dual-count:modified-left->commonality", + "expectImplies": true, + "fromGroup": "owen-sound-dual-count", + "toGroup": "owen-sound-dual-count", + "fromRole": "modified-left", + "toRole": "commonality", + "fromHash": "ff42a10c77308c35adeef7b58ef3c1339e75b7b9817f4a0883673a411efafa92", + "toHash": "b1d86422b2f94b27fab3d42982116797731bb361850b7b7e733d7723e9a1e172", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 is a direct excerpt from S1, dropping the preceding claims about first-past-the-post and ranked ballots. S2 adds no new claims and makes no substantive change to the remaining propositions.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2432 + }, + { + "id": "owen-sound-dual-count:modified-right->commonality", + "expectImplies": true, + "fromGroup": "owen-sound-dual-count", + "toGroup": "owen-sound-dual-count", + "fromRole": "modified-right", + "toRole": "commonality", + "fromHash": "37cf0e1175480e0d4c7658d61bc2062cf6003e1de6817aad4a941916c0c7d5c4", + "toHash": "b1d86422b2f94b27fab3d42982116797731bb361850b7b7e733d7723e9a1e172", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 is a direct excerpt from S1, containing two of its claims and dropping the preceding claims about first-past-the-post and approval voting. S2 adds no new proposition.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2708 + }, + { + "id": "owen-sound-dual-count:natural-left->commonality", + "expectImplies": false, + "fromGroup": "owen-sound-dual-count", + "toGroup": "owen-sound-dual-count", + "fromRole": "natural-left", + "toRole": "commonality", + "fromHash": "381e6191a4b1a5dcde381ffa82a71da3a15e678849fea3b2f5b6c83569565cd4", + "toHash": "b1d86422b2f94b27fab3d42982116797731bb361850b7b7e733d7723e9a1e172", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a specific, procedural claim about a local poll that is entirely absent from S1. S1 is a general statement about electoral reform (ranked ballots) to address vote wastage. S2 is about a specific, non-binding, local-level action that explicitly does not change elections. Believing S1 does not commit a signer to the specific, limited action described in S2.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3100 + }, + { + "id": "owen-sound-dual-count:natural-right->commonality", + "expectImplies": false, + "fromGroup": "owen-sound-dual-count", + "toGroup": "owen-sound-dual-count", + "fromRole": "natural-right", + "toRole": "commonality", + "fromHash": "ae4d2e4f01e3c9c7ba3cd78ca17d2887b7f0cbd53ac31df97997cb912ee21e89", + "toHash": "b1d86422b2f94b27fab3d42982116797731bb361850b7b7e733d7723e9a1e172", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a specific, local, non-binding proposal about a community association poll that is entirely absent from S1. S1 is a general statement about electoral system preferences (first-past-the-post vs. approval voting). There is no logical path from a general electoral reform belief to a specific, optional, local polling proposal.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 8173 + }, + { + "id": "owen-sound-dual-count:natural-left->modified-left", + "expectImplies": false, + "fromGroup": "owen-sound-dual-count", + "toGroup": "owen-sound-dual-count", + "fromRole": "natural-left", + "toRole": "modified-left", + "fromHash": "381e6191a4b1a5dcde381ffa82a71da3a15e678849fea3b2f5b6c83569565cd4", + "toHash": "ff42a10c77308c35adeef7b58ef3c1339e75b7b9817f4a0883673a411efafa92", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple new claims and a detailed concession or reservation about a specific local poll scenario that is not present in S1. The core proposition from S1 is retained, but S2 adds a new, substantive proposition about what the signer would accept in a non-binding community poll.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3107 + }, + { + "id": "owen-sound-dual-count:natural-right->modified-right", + "expectImplies": false, + "fromGroup": "owen-sound-dual-count", + "toGroup": "owen-sound-dual-count", + "fromRole": "natural-right", + "toRole": "modified-right", + "fromHash": "ae4d2e4f01e3c9c7ba3cd78ca17d2887b7f0cbd53ac31df97997cb912ee21e89", + "toHash": "37cf0e1175480e0d4c7658d61bc2062cf6003e1de6817aad4a941916c0c7d5c4", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new proposition about a specific, non-binding poll scenario and a clarification about what the signer is not adopting. These are concessions, reservations, and additional context not present in S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2718 + }, + { + "id": "owen-sound-dual-count:modified-left->modified-right", + "expectImplies": false, + "fromGroup": "owen-sound-dual-count", + "toGroup": "owen-sound-dual-count", + "fromRole": "modified-left", + "toRole": "modified-right", + "fromHash": "ff42a10c77308c35adeef7b58ef3c1339e75b7b9817f4a0883673a411efafa92", + "toHash": "37cf0e1175480e0d4c7658d61bc2062cf6003e1de6817aad4a941916c0c7d5c4", + "implies": false, + "confidence": "high", + "reasoning": "S2 changes the core policy claim from wanting ranked ballots to wanting approval voting. This is a substantive change to the signer's stated preference, not a generalization or subset. S2 also adds a new claim ('First-past-the-post rewards the biggest camp') that is not present in S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2600 + }, + { + "id": "owen-sound-dual-count:modified-right->modified-left", + "expectImplies": false, + "fromGroup": "owen-sound-dual-count", + "toGroup": "owen-sound-dual-count", + "fromRole": "modified-right", + "toRole": "modified-left", + "fromHash": "37cf0e1175480e0d4c7658d61bc2062cf6003e1de6817aad4a941916c0c7d5c4", + "toHash": "ff42a10c77308c35adeef7b58ef3c1339e75b7b9817f4a0883673a411efafa92", + "implies": false, + "confidence": "high", + "reasoning": "S2 changes the core voting system preference from 'approval voting' to 'ranked ballots'. This is a substantive change to the central claim of S1. S2 also changes the rationale from 'rewards the biggest camp' to 'wastes my vote', which is a different proposition. These are not clarifications or generalizations; they are different, mutually exclusive policy preferences.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3502 + }, + { + "id": "owen-sound-dual-count:commonality->modified-left", + "expectImplies": false, + "fromGroup": "owen-sound-dual-count", + "toGroup": "owen-sound-dual-count", + "fromRole": "commonality", + "toRole": "modified-left", + "fromHash": "b1d86422b2f94b27fab3d42982116797731bb361850b7b7e733d7723e9a1e172", + "toHash": "ff42a10c77308c35adeef7b58ef3c1339e75b7b9817f4a0883673a411efafa92", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds new substantive claims not present in S1. S1 expresses a specific, limited acceptance of a community association poll. S2 adds a general critique of first-past-the-post, a desire for ranked ballots in real elections, and a defensive clarification about the approval count. These are new, controversial political positions absent from S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3199 + }, + { + "id": "owen-sound-dual-count:commonality->modified-right", + "expectImplies": false, + "fromGroup": "owen-sound-dual-count", + "toGroup": "owen-sound-dual-count", + "fromRole": "commonality", + "toRole": "modified-right", + "fromHash": "b1d86422b2f94b27fab3d42982116797731bb361850b7b7e733d7723e9a1e172", + "toHash": "37cf0e1175480e0d4c7658d61bc2062cf6003e1de6817aad4a941916c0c7d5c4", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds new claims about first-past-the-post, a preference for approval voting over ranked systems for real elections, and a disclaimer about not adopting ranked ballots. These are substantive, controversial propositions not contained in S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2287 + }, + { + "id": "owen-sound-crypto-trial:modified-left->commonality", + "expectImplies": true, + "fromGroup": "owen-sound-crypto-trial", + "toGroup": "owen-sound-crypto-trial", + "fromRole": "modified-left", + "toRole": "commonality", + "fromHash": "e93c905d7d6d0d5655a77c9c16013c845a0655356f9c1c95e23d40db0ba14ab1", + "toHash": "ffc4cabbc44c041b6bcbabcd4ea91d311f0b98b6d4a76009e7b271d6063963c5", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 is a verbatim copy of the second sentence of S1. It drops the preceding, broader claim about enabling payments when banks block customers and the comment about replacing banks being a bigger project. S2 contains no new claims or propositions.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3018 + }, + { + "id": "owen-sound-crypto-trial:modified-right->commonality", + "expectImplies": true, + "fromGroup": "owen-sound-crypto-trial", + "toGroup": "owen-sound-crypto-trial", + "fromRole": "modified-right", + "toRole": "commonality", + "fromHash": "c069d48aff98bb05c5eb398acfe429099e067925fd49050483e25d22b42d66e6", + "toHash": "ffc4cabbc44c041b6bcbabcd4ea91d311f0b98b6d4a76009e7b271d6063963c5", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 is a direct, verbatim copy of the specific proposal contained within S1. S2 removes the surrounding context about being tired of card fees and not caring about crypto as a cause, but the core proposition (being okay with the described trial) is unchanged and fully contained in S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2614 + }, + { + "id": "owen-sound-crypto-trial:natural-left->commonality", + "expectImplies": false, + "fromGroup": "owen-sound-crypto-trial", + "toGroup": "owen-sound-crypto-trial", + "fromRole": "natural-left", + "toRole": "commonality", + "fromHash": "eed7156b8739e66081daa2062db7633d3f473fa3a46b61c7ff7fc1505b9632fb", + "toHash": "ffc4cabbc44c041b6bcbabcd4ea91d311f0b98b6d4a76009e7b271d6063963c5", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a highly specific, conditional, and time-limited pilot program proposal with multiple operational details (six shops, three months, refund capability, fee display) that are not present in S1. S1 expresses a general desire for shops to accept crypto to avoid bank gatekeeping, which does not commit the signer to endorsing this precise experimental design.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2881 + }, + { + "id": "owen-sound-crypto-trial:natural-right->commonality", + "expectImplies": false, + "fromGroup": "owen-sound-crypto-trial", + "toGroup": "owen-sound-crypto-trial", + "fromRole": "natural-right", + "toRole": "commonality", + "fromHash": "d1149c336c3f85fae41f4745c5eff3d0a3f0b142309a227e744f23c8fd2c28bd", + "toHash": "ffc4cabbc44c041b6bcbabcd4ea91d311f0b98b6d4a76009e7b271d6063963c5", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a highly specific, multi-faceted pilot program proposal that is not contained in S1. S1 expresses a general frustration with card fees, which does not logically commit the signer to endorsing a particular crypto trial with specific parameters.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2436 + }, + { + "id": "owen-sound-crypto-trial:natural-left->modified-left", + "expectImplies": false, + "fromGroup": "owen-sound-crypto-trial", + "toGroup": "owen-sound-crypto-trial", + "fromRole": "natural-left", + "toRole": "modified-left", + "fromHash": "eed7156b8739e66081daa2062db7633d3f473fa3a46b61c7ff7fc1505b9632fb", + "toHash": "e93c905d7d6d0d5655a77c9c16013c845a0655356f9c1c95e23d40db0ba14ab1", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a detailed, specific proposal for a limited trial (six shops, three months, specific features, refund capability) that is not present in S1. S1 expresses a general desire for shops to accept crypto to circumvent bank decisions, but does not commit the signer to the precise, constrained implementation described in S2.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2922 + }, + { + "id": "owen-sound-crypto-trial:natural-right->modified-right", + "expectImplies": false, + "fromGroup": "owen-sound-crypto-trial", + "toGroup": "owen-sound-crypto-trial", + "fromRole": "natural-right", + "toRole": "modified-right", + "fromHash": "d1149c336c3f85fae41f4745c5eff3d0a3f0b142309a227e744f23c8fd2c28bd", + "toHash": "c069d48aff98bb05c5eb398acfe429099e067925fd49050483e25d22b42d66e6", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple new claims and a detailed negotiated commitment (a trial with specific conditions and a publication requirement) that are entirely absent from S1. S1 expresses a general frustration with card fees, but does not contain any proposition about crypto, a trial, or publication of results.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3020 + }, + { + "id": "owen-sound-crypto-trial:modified-left->modified-right", + "expectImplies": false, + "fromGroup": "owen-sound-crypto-trial", + "toGroup": "owen-sound-crypto-trial", + "fromRole": "modified-left", + "toRole": "modified-right", + "fromHash": "e93c905d7d6d0d5655a77c9c16013c845a0655356f9c1c95e23d40db0ba14ab1", + "toHash": "c069d48aff98bb05c5eb398acfe429099e067925fd49050483e25d22b42d66e6", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds several new claims not present in S1, including being tired of card fees, not caring about crypto as a cause, and a demand for publishing fees and failures if the trial is bad. S1's signer could support the trial for its bank-blocking purpose without endorsing S2's specific grievances and conditions.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3281 + }, + { + "id": "owen-sound-crypto-trial:modified-right->modified-left", + "expectImplies": false, + "fromGroup": "owen-sound-crypto-trial", + "toGroup": "owen-sound-crypto-trial", + "fromRole": "modified-right", + "toRole": "modified-left", + "fromHash": "c069d48aff98bb05c5eb398acfe429099e067925fd49050483e25d22b42d66e6", + "toHash": "e93c905d7d6d0d5655a77c9c16013c845a0655356f9c1c95e23d40db0ba14ab1", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new substantive claim about enabling payments when a bank has blocked a customer, which is not present in S1. S1's focus is on avoiding card fees and testing a checkout system, not on bank-blocked customers as a justification or goal.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2955 + }, + { + "id": "owen-sound-crypto-trial:commonality->modified-left", + "expectImplies": false, + "fromGroup": "owen-sound-crypto-trial", + "toGroup": "owen-sound-crypto-trial", + "fromRole": "commonality", + "toRole": "modified-left", + "fromHash": "ffc4cabbc44c041b6bcbabcd4ea91d311f0b98b6d4a76009e7b271d6063963c5", + "toHash": "e93c905d7d6d0d5655a77c9c16013c845a0655356f9c1c95e23d40db0ba14ab1", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new substantive claim not present in S1: 'I want a willing shop and a willing customer to be able to complete a payment when a bank has blocked that customer.' This is a distinct policy goal or desire that is absent from S1's specific, conditional acceptance of a trial. The second sentence ('Replacing the banks is a bigger thing than this.') also adds a new claim about the scope of the project.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3157 + }, + { + "id": "owen-sound-crypto-trial:commonality->modified-right", + "expectImplies": false, + "fromGroup": "owen-sound-crypto-trial", + "toGroup": "owen-sound-crypto-trial", + "fromRole": "commonality", + "toRole": "modified-right", + "fromHash": "ffc4cabbc44c041b6bcbabcd4ea91d311f0b98b6d4a76009e7b271d6063963c5", + "toHash": "c069d48aff98bb05c5eb398acfe429099e067925fd49050483e25d22b42d66e6", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple new claims and a condition not present in S1. S1 expresses a conditional approval for a specific trial. S2 adds a complaint about card fees, a disclaimer about crypto as a cause, and a new demand for publication of results if the trial fails, which are all substantive additions.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3340 + }, + { + "id": "minors-medicine-and-courtesy:modified-left->commonality", + "expectImplies": true, + "fromGroup": "minors-medicine-and-courtesy", + "toGroup": "minors-medicine-and-courtesy", + "fromRole": "modified-left", + "toRole": "commonality", + "fromHash": "7ce4a88201152caa8493130e398945566d0038e9c8070a455a6a3c839fd12ebc", + "toHash": "1a43ec546cb897786306d3c8a99521f1901b8e877c203f6a01cab466dfc4f337", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 is a direct, verbatim copy of the second half of S1, which explicitly states the speaker's 'okay with' position. S2 drops the preceding claims about preferences for adult decisions and case-by-case approaches for minors, leaving only the stated acceptance of a specific rule.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2782 + }, + { + "id": "minors-medicine-and-courtesy:modified-right->commonality", + "expectImplies": true, + "fromGroup": "minors-medicine-and-courtesy", + "toGroup": "minors-medicine-and-courtesy", + "fromRole": "modified-right", + "toRole": "commonality", + "fromHash": "72f04eac3de0aa831b8b64f079eb827cadfde096ab9f460b95583e9bc2999cd0", + "toHash": "1a43ec546cb897786306d3c8a99521f1901b8e877c203f6a01cab466dfc4f337", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 retains three explicit claims from S1 and drops the initial claim about children and drugs/surgery, the separate questions about classroom names and school approval, and the clarifying phrase about what the statement covers. The remaining propositions are unchanged.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2453 + }, + { + "id": "minors-medicine-and-courtesy:natural-left->commonality", + "expectImplies": false, + "fromGroup": "minors-medicine-and-courtesy", + "toGroup": "minors-medicine-and-courtesy", + "fromRole": "natural-left", + "toRole": "commonality", + "fromHash": "9757219027c29dd2b4fed5ac4c0c6674c2f710827e43dc366b83005e05931b96", + "toHash": "1a43ec546cb897786306d3c8a99521f1901b8e877c203f6a01cab466dfc4f337", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a specific policy rule regarding minors and genital surgery that is not present in S1. S1 expresses a desire for medical treatment access and an end to cruelty, but does not specify age restrictions or surgical procedures. S2's rule is a new, substantive claim.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3115 + }, + { + "id": "minors-medicine-and-courtesy:natural-right->commonality", + "expectImplies": false, + "fromGroup": "minors-medicine-and-courtesy", + "toGroup": "minors-medicine-and-courtesy", + "fromRole": "natural-right", + "toRole": "commonality", + "fromHash": "70110dc2287da0f899d97c8c2fe35700775991083a44e441f1f985a4d526e622", + "toHash": "1a43ec546cb897786306d3c8a99521f1901b8e877c203f6a01cab466dfc4f337", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple substantive claims not present in S1, including a rule about adult medical autonomy, a prohibition on harassment for disagreement, and a meta-statement about the view being incomplete. S1's signer could oppose the rule's adult clause or the harassment clause while still holding S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2899 + }, + { + "id": "minors-medicine-and-courtesy:natural-left->modified-left", + "expectImplies": false, + "fromGroup": "minors-medicine-and-courtesy", + "toGroup": "minors-medicine-and-courtesy", + "fromRole": "natural-left", + "toRole": "modified-left", + "fromHash": "9757219027c29dd2b4fed5ac4c0c6674c2f710827e43dc366b83005e05931b96", + "toHash": "7ce4a88201152caa8493130e398945566d0038e9c8070a455a6a3c839fd12ebc", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a substantive policy position ('I'd be okay with a rule that minors are not given cross-sex hormones or genital surgery') and a concession ('This isn't my ideal') that are not present in S1. S1 expresses a clear desire for medical treatment access for young people, while S2 adds a willingness to accept a rule that would deny that access.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3319 + }, + { + "id": "minors-medicine-and-courtesy:natural-right->modified-right", + "expectImplies": false, + "fromGroup": "minors-medicine-and-courtesy", + "toGroup": "minors-medicine-and-courtesy", + "fromRole": "natural-right", + "toRole": "modified-right", + "fromHash": "70110dc2287da0f899d97c8c2fe35700775991083a44e441f1f985a4d526e622", + "toHash": "72f04eac3de0aa831b8b64f079eb827cadfde096ab9f460b95583e9bc2999cd0", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple new claims and specifications not present in S1, including a detailed rule proposal, a statement about adult autonomy, a non-harassment principle, and a disclaimer about scope. These are substantive additions that someone who believes S1 might not endorse.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2971 + }, + { + "id": "minors-medicine-and-courtesy:modified-left->modified-right", + "expectImplies": false, + "fromGroup": "minors-medicine-and-courtesy", + "toGroup": "minors-medicine-and-courtesy", + "fromRole": "modified-left", + "toRole": "modified-right", + "fromHash": "7ce4a88201152caa8493130e398945566d0038e9c8070a455a6a3c839fd12ebc", + "toHash": "72f04eac3de0aa831b8b64f079eb827cadfde096ab9f460b95583e9bc2999cd0", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new, broader claim not present in S1: 'I don't want children given drugs or surgery to try to change their sex.' This is a strong, universal negative claim that is not explicitly stated in S1. S1 expresses a preference for case-by-case decisions for minors and a willingness to accept a specific rule, but does not assert the blanket opposition to all such interventions for children that S2 does.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3310 + }, + { + "id": "minors-medicine-and-courtesy:modified-right->modified-left", + "expectImplies": false, + "fromGroup": "minors-medicine-and-courtesy", + "toGroup": "minors-medicine-and-courtesy", + "fromRole": "modified-right", + "toRole": "modified-left", + "fromHash": "72f04eac3de0aa831b8b64f079eb827cadfde096ab9f460b95583e9bc2999cd0", + "toHash": "7ce4a88201152caa8493130e398945566d0038e9c8070a455a6a3c839fd12ebc", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new, substantive claim not present in S1: 'I'd prefer doctors and families to decide about hormones for minors case by case.' This is a positive preference that is absent from S1, which only states a conditional acceptance of a rule. S2 also adds the framing 'This isn't my ideal,' which further qualifies the position in a way not stated in S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 4300 + }, + { + "id": "minors-medicine-and-courtesy:commonality->modified-left", + "expectImplies": false, + "fromGroup": "minors-medicine-and-courtesy", + "toGroup": "minors-medicine-and-courtesy", + "fromRole": "commonality", + "toRole": "modified-left", + "fromHash": "1a43ec546cb897786306d3c8a99521f1901b8e877c203f6a01cab466dfc4f337", + "toHash": "7ce4a88201152caa8493130e398945566d0038e9c8070a455a6a3c839fd12ebc", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new, substantive claim about a preference ('I'd prefer doctors and families to decide about hormones for minors case by case') that is not present in S1. S1 expresses conditional acceptance of a rule, while S2 expresses a personal preference for an alternative approach, which is an additional proposition.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2298 + }, + { + "id": "minors-medicine-and-courtesy:commonality->modified-right", + "expectImplies": false, + "fromGroup": "minors-medicine-and-courtesy", + "toGroup": "minors-medicine-and-courtesy", + "fromRole": "commonality", + "toRole": "modified-right", + "fromHash": "1a43ec546cb897786306d3c8a99521f1901b8e877c203f6a01cab466dfc4f337", + "toHash": "72f04eac3de0aa831b8b64f079eb827cadfde096ab9f460b95583e9bc2999cd0", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new, explicit claim not present in S1: 'I don't want children given drugs or surgery to try to change their sex.' This is a substantive addition of a personal stance or desire. While S2 contains all of S1's text, it adds a new proposition at the beginning, which violates the core rule that S2 must add no new claim.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3303 + }, + { + "id": "ordinary-opinion-not-unemployable:modified-left->commonality", + "expectImplies": true, + "fromGroup": "ordinary-opinion-not-unemployable", + "toGroup": "ordinary-opinion-not-unemployable", + "fromRole": "modified-left", + "toRole": "commonality", + "fromHash": "830143bd9520d7e6db61d4e980c49289aed516c652907cf967b0622d6e4469b9", + "toHash": "39fe9002f7982cd42e461e072077c665dd47eff2e49cba69ae776729f8d412da", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 is a verbatim copy of a clause that is explicitly and fully contained within S1. S2 adds no new claim, framing, or condition.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2832 + }, + { + "id": "ordinary-opinion-not-unemployable:modified-right->commonality", + "expectImplies": true, + "fromGroup": "ordinary-opinion-not-unemployable", + "toGroup": "ordinary-opinion-not-unemployable", + "fromRole": "modified-right", + "toRole": "commonality", + "fromHash": "3de39c3c1076eb5aa66bbb7da68cf1e16b0c9870bab4790da96e06cd7c0ddc2e", + "toHash": "39fe9002f7982cd42e461e072077c665dd47eff2e49cba69ae776729f8d412da", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 is a direct, verbatim copy of a clause within S1. It drops the surrounding context and additional claims about churches/private clubs and relative strength of feeling, but the proposition in S2 is explicitly and fully contained in S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2784 + }, + { + "id": "ordinary-opinion-not-unemployable:natural-left->commonality", + "expectImplies": false, + "fromGroup": "ordinary-opinion-not-unemployable", + "toGroup": "ordinary-opinion-not-unemployable", + "fromRole": "natural-left", + "toRole": "commonality", + "fromHash": "e8242b3628780319ffde749cf29aa2904c835e4e0810fbf033bf8f1fc50da737", + "toHash": "39fe9002f7982cd42e461e072077c665dd47eff2e49cba69ae776729f8d412da", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple substantive conditions, reservations, and a procedural requirement (a published appeal) that are absent from S1. S1 is a universal claim against livelihood loss for unpopular speech. S2 qualifies this by listing exceptions and adding a process, which changes the proposition.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2860 + }, + { + "id": "ordinary-opinion-not-unemployable:natural-right->commonality", + "expectImplies": false, + "fromGroup": "ordinary-opinion-not-unemployable", + "toGroup": "ordinary-opinion-not-unemployable", + "fromRole": "natural-right", + "toRole": "commonality", + "fromHash": "d97f093b95e8878bcbb491286c4935ebc82a93125c8e4fbdb112fcc61c538bf8", + "toHash": "39fe9002f7982cd42e461e072077c665dd47eff2e49cba69ae776729f8d412da", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a complex set of conditions, exceptions, and procedural safeguards (e.g., threats/harassment still being grounds, a published appeal) that are not present in S1. S1 makes a simple claim that ending careers over ordinary political opinions should stop, which does not commit a signer to the specific, multi-part negotiated position in S2.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3166 + }, + { + "id": "ordinary-opinion-not-unemployable:natural-left->modified-left", + "expectImplies": false, + "fromGroup": "ordinary-opinion-not-unemployable", + "toGroup": "ordinary-opinion-not-unemployable", + "fromRole": "natural-left", + "toRole": "modified-left", + "fromHash": "e8242b3628780319ffde749cf29aa2904c835e4e0810fbf033bf8f1fc50da737", + "toHash": "830143bd9520d7e6db61d4e980c49289aed516c652907cf967b0622d6e4469b9", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple substantive claims, conditions, and reservations that are absent from S1. S1 is a general principle against livelihood loss for unpopular speech. S2 adds specific exceptions (threats, harassment, refusing work), a procedural requirement (published appeal), a distinction about campaigning on the clock, and a statement about the strength of feeling and defense of opinions.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3342 + }, + { + "id": "ordinary-opinion-not-unemployable:natural-right->modified-right", + "expectImplies": false, + "fromGroup": "ordinary-opinion-not-unemployable", + "toGroup": "ordinary-opinion-not-unemployable", + "fromRole": "natural-right", + "toRole": "modified-right", + "fromHash": "d97f093b95e8878bcbb491286c4935ebc82a93125c8e4fbdb112fcc61c538bf8", + "toHash": "3de39c3c1076eb5aa66bbb7da68cf1e16b0c9870bab4790da96e06cd7c0ddc2e", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple new claims, concessions, and reservations that are absent from S1. S1 asserts a simple proposition that the practice should stop. S2 adds conditions for when the practice would be acceptable, exceptions for other types of sanctions, and a comparative value judgment about freedom of association.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3045 + }, + { + "id": "ordinary-opinion-not-unemployable:modified-left->modified-right", + "expectImplies": false, + "fromGroup": "ordinary-opinion-not-unemployable", + "toGroup": "ordinary-opinion-not-unemployable", + "fromRole": "modified-left", + "toRole": "modified-right", + "fromHash": "830143bd9520d7e6db61d4e980c49289aed516c652907cf967b0622d6e4469b9", + "toHash": "3de39c3c1076eb5aa66bbb7da68cf1e16b0c9870bab4790da96e06cd7c0ddc2e", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new, substantive claim about the freedom of churches and private clubs to refuse membership over political opinions, which is absent from S1. S1 discusses workplace rules and campaign restrictions; S2 introduces a distinct institutional context and a comparative strength of feeling not present in S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2662 + }, + { + "id": "ordinary-opinion-not-unemployable:modified-right->modified-left", + "expectImplies": false, + "fromGroup": "ordinary-opinion-not-unemployable", + "toGroup": "ordinary-opinion-not-unemployable", + "fromRole": "modified-right", + "toRole": "modified-left", + "fromHash": "3de39c3c1076eb5aa66bbb7da68cf1e16b0c9870bab4790da96e06cd7c0ddc2e", + "toHash": "830143bd9520d7e6db61d4e980c49289aed516c652907cf967b0622d6e4469b9", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new, specific policy claim about campaigning on the clock that is not present in S1. S2 also changes the comparative strength of feeling ('I feel less strongly about that than...') which is a new proposition absent from S1. This violates the core rule that S2 must add no new claim.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3575 + }, + { + "id": "ordinary-opinion-not-unemployable:commonality->modified-left", + "expectImplies": false, + "fromGroup": "ordinary-opinion-not-unemployable", + "toGroup": "ordinary-opinion-not-unemployable", + "fromRole": "commonality", + "toRole": "modified-left", + "fromHash": "39fe9002f7982cd42e461e072077c665dd47eff2e49cba69ae776729f8d412da", + "toHash": "830143bd9520d7e6db61d4e980c49289aed516c652907cf967b0622d6e4469b9", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds several new claims not present in S1, including a preference about campaigning on the clock, a statement of relative strength of feeling, and a disclaimer about defending opinions. These are substantive additions that change the proposition.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2801 + }, + { + "id": "ordinary-opinion-not-unemployable:commonality->modified-right", + "expectImplies": false, + "fromGroup": "ordinary-opinion-not-unemployable", + "toGroup": "ordinary-opinion-not-unemployable", + "fromRole": "commonality", + "toRole": "modified-right", + "fromHash": "39fe9002f7982cd42e461e072077c665dd47eff2e49cba69ae776729f8d412da", + "toHash": "3de39c3c1076eb5aa66bbb7da68cf1e16b0c9870bab4790da96e06cd7c0ddc2e", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple new claims not present in S1, including a direct normative statement ('Institutions should stop...'), a stronger preference regarding churches and private clubs, and a comparative statement about the strength of feelings. These are substantive additions that someone who signed S1 might not endorse.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2822 + }, + { + "id": "canada-ordinary-us-ties:modified-left->commonality", + "expectImplies": true, + "fromGroup": "canada-ordinary-us-ties", + "toGroup": "canada-ordinary-us-ties", + "fromRole": "modified-left", + "toRole": "commonality", + "fromHash": "4f054a5dfcc3a7715f7f00bf22158767f23936dfe258226f27732f0a278f27ec", + "toHash": "e5a9a394c98f213454d64522737b056a8c2a74cda984e033be47a2325ea0d5a7", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 is a verbatim copy of a portion of S1 and contains no new claims. S1's additional surrounding text expresses a preference against a boycott and a weaker preference for Canadian goods, but S2 only repeats the core claim explicitly stated in S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2724 + }, + { + "id": "canada-ordinary-us-ties:modified-right->commonality", + "expectImplies": true, + "fromGroup": "canada-ordinary-us-ties", + "toGroup": "canada-ordinary-us-ties", + "fromRole": "modified-right", + "toRole": "commonality", + "fromHash": "5d64f0266a1eb7fbfa6f3e8c90d4cbf35772e8f2d673eaf8dd5e4b5a4f27ac33", + "toHash": "e5a9a394c98f213454d64522737b056a8c2a74cda984e033be47a2325ea0d5a7", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 contains only the first two sentences of S1, which are explicitly repeated claims. S2 drops the subsequent claims about border staffing, military exercises, relative strength of feeling, and the request not to praise the administration.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3719 + }, + { + "id": "canada-ordinary-us-ties:natural-left->commonality", + "expectImplies": false, + "fromGroup": "canada-ordinary-us-ties", + "toGroup": "canada-ordinary-us-ties", + "fromRole": "natural-left", + "toRole": "commonality", + "fromHash": "b955e5e7eb0fec3812aa363feb8a443617969d9c9ea45ced328bc54b2d7614bf", + "toHash": "e5a9a394c98f213454d64522737b056a8c2a74cda984e033be47a2325ea0d5a7", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new, explicit disclaimer ('This is not a statement about the current US administration') that is absent from S1. This disclaimer is a substantive proposition about the scope and intent of the statement, which changes the claim being made.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2688 + }, + { + "id": "canada-ordinary-us-ties:natural-right->commonality", + "expectImplies": false, + "fromGroup": "canada-ordinary-us-ties", + "toGroup": "canada-ordinary-us-ties", + "fromRole": "natural-right", + "toRole": "commonality", + "fromHash": "c00dc6432cfccf2c86bfa12e6dc563f77d6ea13a894e4ce6bf0112e7293668cf", + "toHash": "e5a9a394c98f213454d64522737b056a8c2a74cda984e033be47a2325ea0d5a7", + "implies": false, + "confidence": "high", + "reasoning": "S1 makes a general statement about national-level ties. S2 adds specific claims about individual consumer behavior and family visits, and includes a disclaimer about the current administration. These are new propositions not contained in S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2661 + }, + { + "id": "canada-ordinary-us-ties:natural-left->modified-left", + "expectImplies": false, + "fromGroup": "canada-ordinary-us-ties", + "toGroup": "canada-ordinary-us-ties", + "fromRole": "natural-left", + "toRole": "modified-left", + "fromHash": "b955e5e7eb0fec3812aa363feb8a443617969d9c9ea45ced328bc54b2d7614bf", + "toHash": "4f054a5dfcc3a7715f7f00bf22158767f23936dfe258226f27732f0a278f27ec", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple substantive claims not present in S1, including a specific preference for buying Canadian goods when price and quality are equal, a statement about the relative strength of preferences, and an explicit meta-statement that the position is not about the current administration.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3093 + }, + { + "id": "canada-ordinary-us-ties:natural-right->modified-right", + "expectImplies": false, + "fromGroup": "canada-ordinary-us-ties", + "toGroup": "canada-ordinary-us-ties", + "fromRole": "natural-right", + "toRole": "modified-right", + "fromHash": "c00dc6432cfccf2c86bfa12e6dc563f77d6ea13a894e4ce6bf0112e7293668cf", + "toHash": "5d64f0266a1eb7fbfa6f3e8c90d4cbf35772e8f2d673eaf8dd5e4b5a4f27ac33", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple specific claims (buying goods, visiting family, border staffing, military exercises, relative strength of feeling, and a disclaimer about the administration) that are not present in S1. S1 is a general statement about keeping ordinary ties, which does not commit the signer to the detailed list of actions and priorities in S2.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3117 + }, + { + "id": "canada-ordinary-us-ties:modified-left->modified-right", + "expectImplies": false, + "fromGroup": "canada-ordinary-us-ties", + "toGroup": "canada-ordinary-us-ties", + "fromRole": "modified-left", + "toRole": "modified-right", + "fromHash": "4f054a5dfcc3a7715f7f00bf22158767f23936dfe258226f27732f0a278f27ec", + "toHash": "5d64f0266a1eb7fbfa6f3e8c90d4cbf35772e8f2d673eaf8dd5e4b5a4f27ac33", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds new claims about shared border staffing and ordinary military exercises with the US, which are not present in S1. It also adds a comparative strength claim ('I feel more strongly...') and a disclaimer about praising the administration.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2739 + }, + { + "id": "canada-ordinary-us-ties:modified-right->modified-left", + "expectImplies": false, + "fromGroup": "canada-ordinary-us-ties", + "toGroup": "canada-ordinary-us-ties", + "fromRole": "modified-right", + "toRole": "modified-left", + "fromHash": "5d64f0266a1eb7fbfa6f3e8c90d4cbf35772e8f2d673eaf8dd5e4b5a4f27ac33", + "toHash": "4f054a5dfcc3a7715f7f00bf22158767f23936dfe258226f27732f0a278f27ec", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new, explicit claim not present in S1: 'I don't like the current US administration.' S1 explicitly disavows making a statement about the administration, while S2 makes a negative personal evaluation of it. This is a substantive addition that changes the proposition.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3092 + }, + { + "id": "canada-ordinary-us-ties:commonality->modified-left", + "expectImplies": false, + "fromGroup": "canada-ordinary-us-ties", + "toGroup": "canada-ordinary-us-ties", + "fromRole": "commonality", + "toRole": "modified-left", + "fromHash": "e5a9a394c98f213454d64522737b056a8c2a74cda984e033be47a2325ea0d5a7", + "toHash": "4f054a5dfcc3a7715f7f00bf22158767f23936dfe258226f27732f0a278f27ec", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple new claims and preferences not present in S1, including a negative opinion of the current US administration, a comparative preference for Canadian goods under certain conditions, and a statement about the relative strength of these preferences. These are substantive additions that someone who signed S1 could disagree with.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2874 + }, + { + "id": "canada-ordinary-us-ties:commonality->modified-right", + "expectImplies": false, + "fromGroup": "canada-ordinary-us-ties", + "toGroup": "canada-ordinary-us-ties", + "fromRole": "commonality", + "toRole": "modified-right", + "fromHash": "e5a9a394c98f213454d64522737b056a8c2a74cda984e033be47a2325ea0d5a7", + "toHash": "5d64f0266a1eb7fbfa6f3e8c90d4cbf35772e8f2d673eaf8dd5e4b5a4f27ac33", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple new claims and propositions that are absent from S1, including a desire for Canada to keep shared border staffing and ordinary military exercises with the US, a comparative strength of feeling, and a disclaimer about not asking for praise of the administration.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2606 + }, + { + "id": "cross:grey-county-assimilation-sessions:natural-left->immigration:commonality", + "expectImplies": false, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "immigration-criminal-priority-overlap", + "fromRole": "natural-left", + "toRole": "commonality", + "fromHash": "9ef6284a27ab4ca03293cca2c92009acf32667427ec1a2d5e1914e160c9810de", + "toHash": "f5e1caa473ce7e9eae4d0e5a4ffc820232ccd1644c814aa3b78cf311776749fa", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a new, substantive, and controversial policy claim about deportation and compromise that is completely absent from S1. S1 is a positive statement about supporting newcomers' integration and cultural retention, with no mention of immigration enforcement, deportation, or political settlements.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2613 + }, + { + "id": "cross:grey-county-assimilation-sessions:natural-right->immigration:commonality", + "expectImplies": false, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "immigration-criminal-priority-overlap", + "fromRole": "natural-right", + "toRole": "commonality", + "fromHash": "767953b67246777f1e8b7840398451602d8ef34111c4c0b1dcc30e0eaae54879", + "toHash": "f5e1caa473ce7e9eae4d0e5a4ffc820232ccd1644c814aa3b78cf311776749fa", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a completely new and controversial policy claim about deportation of illegal immigrants that is not present in S1. S1 discusses assimilation and local language services, which is a different topic and does not commit the signer to a specific deportation policy.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2397 + }, + { + "id": "cross:grey-county-assimilation-sessions:modified-left->immigration:commonality", + "expectImplies": false, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "immigration-criminal-priority-overlap", + "fromRole": "modified-left", + "toRole": "commonality", + "fromHash": "e6599f2a2a0df237545162ff2d9b12540e6b3a8b14ce9015b288a97d1f739600", + "toHash": "f5e1caa473ce7e9eae4d0e5a4ffc820232ccd1644c814aa3b78cf311776749fa", + "implies": false, + "confidence": "high", + "reasoning": "S1 and S2 address completely different topics and policy positions. S1 is about providing practical integration support for newcomers in a specific local context, while S2 is about deportation policy for individuals who are in the country illegally and have committed crimes. S2 adds a new, controversial policy claim that is entirely absent from S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2863 + }, + { + "id": "cross:grey-county-assimilation-sessions:modified-right->immigration:commonality", + "expectImplies": false, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "immigration-criminal-priority-overlap", + "fromRole": "modified-right", + "toRole": "commonality", + "fromHash": "98c1fbcd1c66289223e5a7263e9de4def03690d6105ca9c588fa63a7fb9b0b33", + "toHash": "f5e1caa473ce7e9eae4d0e5a4ffc820232ccd1644c814aa3b78cf311776749fa", + "implies": false, + "confidence": "high", + "reasoning": "S1 and S2 address entirely different policy areas within immigration. S1 is about language and civic integration services for newcomers in a specific local context. S2 is about deportation policy for illegal immigrants who have committed crimes. S2 adds a new, substantive, and controversial claim about deportation that is completely absent from S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3481 + }, + { + "id": "cross:grey-county-assimilation-sessions:commonality->immigration:commonality", + "expectImplies": false, + "fromGroup": "grey-county-assimilation-sessions", + "toGroup": "immigration-criminal-priority-overlap", + "fromRole": "commonality", + "toRole": "commonality", + "fromHash": "14f2b7e1a419b7695f5c22aa490bb7d53fcdeb55b1b05ac483b582d581ead0e9", + "toHash": "f5e1caa473ce7e9eae4d0e5a4ffc820232ccd1644c814aa3b78cf311776749fa", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a completely different policy claim (deportation of illegal immigrants who have committed crimes) that is not present in S1. S1 is about a specific, local, practical integration program, while S2 is about a national immigration enforcement policy. Believing S1 does not commit a person to the controversial position in S2.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3209 + }, + { + "id": "cross:immigration:modified-left->assimilation:commonality", + "expectImplies": false, + "fromGroup": "immigration-criminal-priority-overlap", + "toGroup": "grey-county-assimilation-sessions", + "fromRole": "modified-left", + "toRole": "commonality", + "fromHash": "57b103929c5a8f413abe061afa6cca2c437802448e122a78b07ee2eb704d55b7", + "toHash": "14f2b7e1a419b7695f5c22aa490bb7d53fcdeb55b1b05ac483b582d581ead0e9", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a highly specific, concrete policy proposal (twelve evening sessions in Owen Sound with childcare, covering specific topics) that is entirely absent from S1. S1 is a general principle about deportation priorities and a desire to settle the issue, but does not commit the signer to any specific local integration program.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2887 + }, + { + "id": "cross:immigration:modified-right->assimilation:commonality", + "expectImplies": false, + "fromGroup": "immigration-criminal-priority-overlap", + "toGroup": "grey-county-assimilation-sessions", + "fromRole": "modified-right", + "toRole": "commonality", + "fromHash": "04b81916e2c5890f7c4203b1d31181a78a65eb7c8da61734fa255a62825c68eb", + "toHash": "14f2b7e1a419b7695f5c22aa490bb7d53fcdeb55b1b05ac483b582d581ead0e9", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a specific, concrete policy proposal (English sessions with specific features and limitations) that is entirely absent from S1. S1 discusses deportation priorities and a compromise position on illegal immigration, but contains no claim about local integration programs, their content, or their conditions.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2450 + }, + { + "id": "cross:immigration:commonality->assimilation:commonality", + "expectImplies": false, + "fromGroup": "immigration-criminal-priority-overlap", + "toGroup": "grey-county-assimilation-sessions", + "fromRole": "commonality", + "toRole": "commonality", + "fromHash": "f5e1caa473ce7e9eae4d0e5a4ffc820232ccd1644c814aa3b78cf311776749fa", + "toHash": "14f2b7e1a419b7695f5c22aa490bb7d53fcdeb55b1b05ac483b582d581ead0e9", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a specific, concrete policy proposal (English sessions in Owen Sound with specific features) that is entirely absent from S1. S1 is about a deportation policy compromise, while S2 is about a local integration program. There is no logical connection where believing S1 commits the signer to supporting S2.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3231 + } + ] +} diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-statements.json b/fake-data-generation/campaigns/network-societies-v1-b2-statements.json index 77e2be8a..d7c6d723 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-statements.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-statements.json @@ -310,7 +310,7 @@ "id": "grey-assimilation", "title": "Grey County practical-English sessions", "notes": [ - "Draft bridge from statement-generation-exercises/06-network-society-alliances.json. Roles make the board bridge-shaped. Do not publish modified-to-commonality arrows until the attester blesses them. This is not the accepted immigration cluster." + "Draft bridge from statement-generation-exercises/06-network-society-alliances.json. Modified-to-commonality was blessed on 2026-10-16 and is planned with live-attester evidence. This is not the accepted immigration cluster and it is not accepted seed." ], "statements": [ { "id": "natural-left", "role": "natural-left", "text": "I want newcomers in Grey County to be able to learn practical English and how the library, the bus, and a township office work, and I want them to be able to keep their own customs." }, @@ -363,8 +363,8 @@ "statements": [ { "id": "natural-left", "role": "natural-left", "text": "Nobody should lose their livelihood because they said something unpopular." }, { "id": "natural-right", "role": "natural-right", "text": "Institutions are ending people's careers over ordinary political opinions, and that should stop." }, - { "id": "modified-left", "role": "modified-left", "text": "I don't want someone treated as unemployable for an ordinary political opinion. I still want a workplace to respond to threats, to harassment of coworkers, and to someone refusing to do the job. I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment. I don't have to defend every opinion." }, - { "id": "modified-right", "role": "modified-right", "text": "Institutions should stop ending people's careers over ordinary political opinions. I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment. I don't need every sanction anywhere to be forbidden." }, + { "id": "modified-left", "role": "modified-left", "text": "I don't want someone treated as unemployable for an ordinary political opinion. I still want a workplace to respond to threats, to harassment of coworkers, and to someone refusing to do the job. I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment. I'd still rather a workplace could tell people not to campaign for a candidate while they are on the clock. I feel less strongly about that than about someone losing a livelihood, and I don't have to defend every opinion." }, + { "id": "modified-right", "role": "modified-right", "text": "Institutions should stop ending people's careers over ordinary political opinions. I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment. I'd still rather a church or a private club could refuse membership over an ordinary political opinion. I feel more strongly about that freedom than about employment rules, and I don't need every sanction anywhere to be forbidden." }, { "id": "commonality", "role": "commonality", "text": "I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment." } ] }, @@ -375,9 +375,9 @@ "statements": [ { "id": "natural-left", "role": "natural-left", "text": "I don't like Trump, and I still think it's foolish for Canadians to cut off ordinary buying and family visits to the US." }, { "id": "natural-right", "role": "natural-right", "text": "Canada should keep its ordinary ties with the US. There's nothing wrong with that." }, - { "id": "modified-left", "role": "modified-left", "text": "I don't like the current US administration. I'd still rather Canadians keep buying ordinary goods from US businesses and visiting family there than join a boycott of those ordinary ties. I'd be okay with saying that ordinary Canadians should keep buying from US businesses and visiting family in the US, and that this is not a statement about the current US administration." }, - { "id": "modified-right", "role": "modified-right", "text": "I want Canadians to keep buying ordinary goods from US businesses and visiting family in the US. I may be fine with the current administration, but that is not this question. I'd be okay with saying that ordinary Canadians should keep buying from US businesses and visiting family in the US, and that this is not a statement about the current US administration." }, - { "id": "commonality", "role": "commonality", "text": "I'd be okay with saying that ordinary Canadians should keep buying from US businesses and visiting family in the US, and that this is not a statement about the current US administration." } + { "id": "modified-left", "role": "modified-left", "text": "I don't like the current US administration. I'd still rather Canadians keep buying ordinary goods from US businesses and visiting family there than join a boycott of those ordinary ties. Ordinary Canadians should keep buying from US businesses and visiting family in the US. This is not a statement about the current US administration. I'd still rather people buy the Canadian good when the price and quality are the same. I feel less strongly about that preference than about refusing a boycott." }, + { "id": "modified-right", "role": "modified-right", "text": "I want Canadians to keep buying ordinary goods from US businesses and visiting family in the US. Ordinary Canadians should keep buying from US businesses and visiting family in the US. This is not a statement about the current US administration. I'd still rather Canada also keep shared border staffing and ordinary military exercises with the US. I feel more strongly about purchases and family visits than about those, and I am not asking anyone to praise the administration." }, + { "id": "commonality", "role": "commonality", "text": "Ordinary Canadians should keep buying from US businesses and visiting family in the US. This is not a statement about the current US administration." } ] } ] diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.json b/fake-data-generation/campaigns/network-societies-v1-b2.json index 15d2802c..fc36aad2 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2.json @@ -703,7 +703,8 @@ ], "causeIds": [ "crypto-merchants", - "civic-assimilation" + "civic-assimilation", + "grey-assimilation" ], "spotlightOrder": 1 }, @@ -718,7 +719,8 @@ ], "causeIds": [ "christian-teaching", - "home-learning" + "home-learning", + "ranked-approval-poll" ], "spotlightOrder": 2 }, @@ -733,7 +735,8 @@ ], "causeIds": [ "civic-assimilation", - "crypto-merchants" + "crypto-merchants", + "checkout-trial-bridge" ], "spotlightOrder": 3 }, @@ -748,7 +751,8 @@ ], "causeIds": [ "home-learning", - "christian-teaching" + "christian-teaching", + "minors-medicine" ], "spotlightOrder": 4 }, @@ -762,7 +766,8 @@ "refunds" ], "causeIds": [ - "crypto-merchants" + "crypto-merchants", + "opinion-employment" ], "spotlightOrder": 5 }, @@ -776,7 +781,8 @@ "township business" ], "causeIds": [ - "civic-assimilation" + "civic-assimilation", + "canada-us-ties" ], "spotlightOrder": 6 }, @@ -1064,6 +1070,24 @@ "spotlightOrder": 24 } ], + "implicationAllowances": [ + { "from": { "collectionId": "compromise-abortion", "groupId": "abortion-gestational-cutoff", "statementId": "modified-left" }, "to": { "collectionId": "compromise-abortion", "groupId": "abortion-gestational-cutoff", "statementId": "commonality" }, "evidence": "accepted-bridge-role-pair" }, + { "from": { "collectionId": "compromise-abortion", "groupId": "abortion-gestational-cutoff", "statementId": "modified-right" }, "to": { "collectionId": "compromise-abortion", "groupId": "abortion-gestational-cutoff", "statementId": "commonality" }, "evidence": "accepted-bridge-role-pair" }, + { "from": { "collectionId": "lgbt-schools", "groupId": "lgbt-schools-pushing", "statementId": "modified-left" }, "to": { "collectionId": "lgbt-schools", "groupId": "lgbt-schools-pushing", "statementId": "commonality" }, "evidence": "accepted-bridge-role-pair" }, + { "from": { "collectionId": "lgbt-schools", "groupId": "lgbt-schools-pushing", "statementId": "modified-right" }, "to": { "collectionId": "lgbt-schools", "groupId": "lgbt-schools-pushing", "statementId": "commonality" }, "evidence": "accepted-bridge-role-pair" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "grey-assimilation", "statementId": "modified-left" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "grey-assimilation", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "grey-assimilation", "statementId": "modified-right" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "grey-assimilation", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "ranked-approval-poll", "statementId": "modified-left" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "ranked-approval-poll", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "ranked-approval-poll", "statementId": "modified-right" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "ranked-approval-poll", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "checkout-trial-bridge", "statementId": "modified-left" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "checkout-trial-bridge", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "checkout-trial-bridge", "statementId": "modified-right" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "checkout-trial-bridge", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "minors-medicine", "statementId": "modified-left" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "minors-medicine", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "minors-medicine", "statementId": "modified-right" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "minors-medicine", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "opinion-employment", "statementId": "modified-left" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "opinion-employment", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "opinion-employment", "statementId": "modified-right" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "opinion-employment", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "modified-left" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "modified-right" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" } + ], "actionRules": [ { "type": "publish-statement", @@ -1099,8 +1123,8 @@ "publish-statement" ], "targetCount": { - "min": 4, - "max": 4 + "min": 16, + "max": 16 } }, { diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.md b/fake-data-generation/campaigns/network-societies-v1-b2.md index 81f2fb36..f2a5c401 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2.md +++ b/fake-data-generation/campaigns/network-societies-v1-b2.md @@ -16,9 +16,9 @@ A plan written on 2026-10-16 has 60 users, 100 statements, 52 projects. Seed: `c The abortion cause and the schools cause are bridge-shaped. Each main board lists only the accepted commonality sentence. The natural and modified sentences are on the side boards. The Michigan authority board and the Grey County conduct board are ordinary boards, so their own sentences stay visible there. -Six more causes are also bridge-shaped, from `statement-generation-exercises/06-network-society-alliances.json`: Grey County assimilation sessions, the Owen Sound dual-count poll, the Owen Sound checkout trial, minors' medicine and courtesy, ordinary opinions and employment, and ordinary Canada–US ties. Their side boards exist. No implication action is planned for them. The planner still stamps `accepted-bridge-role-pair` on every modified-to-commonality action it does emit, and that stamp is only honest for the accepted abortion and schools pairs. Keep the attest-implication count at 4 until a real attester blesses a new pair. +Six more causes are also bridge-shaped, from `statement-generation-exercises/06-network-society-alliances.json`: Grey County assimilation sessions, the Owen Sound dual-count poll, the Owen Sound checkout trial, minors' medicine and courtesy, ordinary opinions and employment, and ordinary Canada–US ties. -Four implication actions are planned. They are the accepted modified-left and modified-right arrows onto each of those two commonalities. This session did not call the attester. Candidates that were not evaluated are listed in `network-societies-v1-b2-decisions.json`. +Sixteen implication actions are planned. Four are the accepted abortion and schools pairs, labeled `accepted-bridge-role-pair`. Twelve are the new modified-to-commonality pairs, labeled `live-attester-modified-to-commonality`. The live record is `network-societies-v1-b2-implication-evaluations.json` (deepseek/deepseek-v3.2, prompt fingerprint `2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891`). Every designed-yes blessed and every designed-no refused after one rewrite. Employment modifieds now name a camp priority the commonality does not contain (on-the-clock campaigning; churches and private clubs). The Canada commonality no longer says "I'd be okay with saying that," and each modified keeps a priority the commonality omits. Naturals, reverse arrows, cross-modified arrows, and the assimilation cluster against the accepted immigration statements stay unpublished. Those refusals are in the decisions file. The six clusters are still not accepted seed. `moderator-checklist` is one statement. It is on the Michigan authority board and the Owen Sound voting board. One project, "Moderator checklist card", references it. @@ -36,6 +36,10 @@ npm run gen:campaign:plan -- campaigns/network-societies-v1-b2.json output/campa Do not write this plan over `network-societies-v1-pilot` or `medium-realistic-v2`. Pilot statement texts in `network-societies-v1-b2-statements.json` are a copy so the loader can see them. The accepted bridge sentences are referenced from `seed-content/`, not copied. -## Not executed +## Local execution -This batch has a plan only. It has not been mined, and the boards have no local URLs yet. Executing it needs a fresh output directory. If the chain is wiped first, fund the alignment-trust bootstrap wallet before expecting cause pages to list projects. +A plan written after the attester pass has 446 writes. On 2026-10-16 the local chain mined 446/446 and reconciliation matched 446/446. The first pass left 14 actions failed for insufficient ETH; those wallets were topped up and the run resumed. Output is `output/campaigns/network-societies-v1-b2/`. Pilot and medium-realistic-v2 outputs were not overwritten. + +The Grey County assimilation commonality board is `http://commonality.localhost:8088/#/cause/0xEe6a18208ca061e2Eddd4A6fA7E4E4d4927eF352/network-societies-v1-b2-grey-assimilation-bridge`. Its statement page shows "Arriving through other statements." Direct and indirect counts were 0 on that load because the visible sentence had no signers yet. + +Persona `set-belief` choices are still not applied. Delegated spending and a recurring monthly pledge are still not campaign actions. The six clusters are not accepted seed. diff --git a/fake-data-generation/statement-generation-exercises/06-network-society-alliances.json b/fake-data-generation/statement-generation-exercises/06-network-society-alliances.json index ba707733..8ea0f330 100644 --- a/fake-data-generation/statement-generation-exercises/06-network-society-alliances.json +++ b/fake-data-generation/statement-generation-exercises/06-network-society-alliances.json @@ -7,7 +7,8 @@ "A bridge needs a real concession. Same outcome, different motive, with both sides already willing to sign the outcome, is overlap and is not given a triple.", "Skipped as overlap or as a weaker same-conclusion pattern: low-carb enclaves, the unwoke umbrella, Democracy 2.0 as a second voting cause, Christianity crossed with secular conservatives, home-schoolers and school families sharing field-trip notes, and 'both sides already dislike first-past-the-post.'", "The accepted immigration cluster is about deportation. The assimilation triple below is about what a local program does. Do not merge them.", - "The accepted schools cluster is about pushing versus support. The youth-medicine triple below does not settle that, classroom names, or school approval of drugs." + "The accepted schools cluster is about pushing versus support. The youth-medicine triple below does not settle that, classroom names, or school approval of drugs.", + "2026-10-16 live attester (deepseek/deepseek-v3.2) blessed commonality to both employment modifieds and each employment modified to the other, and blessed Canada commonality to modified-right. Those modifieds were thickened with a camp priority the commonality does not contain. The Canada commonality dropped 'I'd be okay with saying that'." ], "groups": [ { @@ -156,12 +157,12 @@ { "id": "modified-left", "role": "modified-left", - "text": "I don't want someone treated as unemployable for an ordinary political opinion. I still want a workplace to respond to threats, to harassment of coworkers, and to someone refusing to do the job. I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment. I don't have to defend every opinion." + "text": "I don't want someone treated as unemployable for an ordinary political opinion. I still want a workplace to respond to threats, to harassment of coworkers, and to someone refusing to do the job. I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment. I'd still rather a workplace could tell people not to campaign for a candidate while they are on the clock. I feel less strongly about that than about someone losing a livelihood, and I don't have to defend every opinion." }, { "id": "modified-right", "role": "modified-right", - "text": "Institutions should stop ending people's careers over ordinary political opinions. I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment. I don't need every sanction anywhere to be forbidden." + "text": "Institutions should stop ending people's careers over ordinary political opinions. I'd be okay with it if an ordinary political opinion, by itself, were not grounds for treating someone as unemployable, if threats, harassment of coworkers, and refusing the work still were, and if a published appeal came before that treatment. I'd still rather a church or a private club could refuse membership over an ordinary political opinion. I feel more strongly about that freedom than about employment rules, and I don't need every sanction anywhere to be forbidden." }, { "id": "commonality", @@ -188,17 +189,17 @@ { "id": "modified-left", "role": "modified-left", - "text": "I don't like the current US administration. I'd still rather Canadians keep buying ordinary goods from US businesses and visiting family there than join a boycott of those ordinary ties. I'd be okay with saying that ordinary Canadians should keep buying from US businesses and visiting family in the US, and that this is not a statement about the current US administration." + "text": "I don't like the current US administration. I'd still rather Canadians keep buying ordinary goods from US businesses and visiting family there than join a boycott of those ordinary ties. Ordinary Canadians should keep buying from US businesses and visiting family in the US. This is not a statement about the current US administration. I'd still rather people buy the Canadian good when the price and quality are the same. I feel less strongly about that preference than about refusing a boycott." }, { "id": "modified-right", "role": "modified-right", - "text": "I want Canadians to keep buying ordinary goods from US businesses and visiting family in the US. I may be fine with the current administration, but that is not this question. I'd be okay with saying that ordinary Canadians should keep buying from US businesses and visiting family in the US, and that this is not a statement about the current US administration." + "text": "I want Canadians to keep buying ordinary goods from US businesses and visiting family in the US. Ordinary Canadians should keep buying from US businesses and visiting family in the US. This is not a statement about the current US administration. I'd still rather Canada also keep shared border staffing and ordinary military exercises with the US. I feel more strongly about purchases and family visits than about those, and I am not asking anyone to praise the administration." }, { "id": "commonality", "role": "commonality", - "text": "I'd be okay with saying that ordinary Canadians should keep buying from US businesses and visiting family in the US, and that this is not a statement about the current US administration." + "text": "Ordinary Canadians should keep buying from US businesses and visiting family in the US. This is not a statement about the current US administration." } ] } diff --git a/fake-data-generation/statement-generation-exercises/README.md b/fake-data-generation/statement-generation-exercises/README.md index 1c50da8b..4965d81e 100644 --- a/fake-data-generation/statement-generation-exercises/README.md +++ b/fake-data-generation/statement-generation-exercises/README.md @@ -11,5 +11,5 @@ Draft corpora for the loop in [`../statement-generation.md`](../statement-genera | [`03-compromise-immigration.json`](./03-compromise-immigration.json) | Left/right immigration compromise. **Accepted** into [`../seed-content/compromise-immigration.json`](../seed-content/compromise-immigration.json) (2026-08-31). Gold copy stays here. | | [`04-crime-repeat-offenders.json`](./04-crime-repeat-offenders.json) | Left/right crime fact-conditional (repeat-offender concentration). **Accepted** into [`../seed-content/crime-repeat-offenders.json`](../seed-content/crime-repeat-offenders.json) (2026-08-31). Gold copy stays here. | | [`05-lgbt-schools.json`](./05-lgbt-schools.json) | Left/right LGBT schools fact-conditional. **Accepted** into [`../seed-content/lgbt-schools.json`](../seed-content/lgbt-schools.json) (2026-08-31). Gold copy stays here. | -| [`06-network-society-alliances.json`](./06-network-society-alliances.json) | Draft organic-alliance triples from the network-society brainstorm. **Not accepted.** No attester run. | +| [`06-network-society-alliances.json`](./06-network-society-alliances.json) | Draft organic-alliance triples from the network-society brainstorm. **Not accepted.** Live attester on 2026-10-16 blessed modified → commonality and refused the designed-no pairs. Record: `campaigns/network-societies-v1-b2-implication-evaluations.json`. | | Next (not drafted) | Left/right **LGB-vs-T coalition unbundling** if Adam still wants that seam after accepting (or vetoing) the schools cluster. See [`../PLAN.md`](../PLAN.md). | diff --git a/fake-data-generation/test/campaignPlanner.test.ts b/fake-data-generation/test/campaignPlanner.test.ts index ba35486e..0e2b70a8 100644 --- a/fake-data-generation/test/campaignPlanner.test.ts +++ b/fake-data-generation/test/campaignPlanner.test.ts @@ -249,14 +249,21 @@ test('batch 2 keeps the pilot families, reuses accepted bridges, and shares one assert.deepEqual(checklist!.alsoOnCauseIds, ['voting']); assert.equal(plan.projects.filter((project) => project.statementIds.includes(checklist!.id)).length, 1); const implications = plan.actions.filter((action) => action.type === 'attest-implication'); - assert.equal(implications.length, 4); + assert.equal(implications.length, 16); + const accepted = implications.filter((action) => action.implication!.evidence === 'accepted-bridge-role-pair'); + const live = implications.filter((action) => action.implication!.evidence === 'live-attester-modified-to-commonality'); + assert.equal(accepted.length, 4); + assert.equal(live.length, 12); + for (const action of accepted) { + const from = plan.statements.find((statement) => statement.id === action.implication!.fromStatementId)!; + assert.ok(from.source.collectionId === 'compromise-abortion' || from.source.collectionId === 'lgbt-schools'); + } for (const action of implications) { const from = plan.statements.find((statement) => statement.id === action.implication!.fromStatementId)!; const to = plan.statements.find((statement) => statement.id === action.implication!.toStatementId)!; - assert.equal(action.implication!.evidence, 'accepted-bridge-role-pair'); assert.ok(from.role === 'modified-left' || from.role === 'modified-right'); assert.equal(to.role, 'commonality'); - assert.ok(from.source.collectionId === 'compromise-abortion' || from.source.collectionId === 'lgbt-schools'); + assert.equal(from.source.groupId, to.source.groupId); } const michigan = plan.statements.find((statement) => statement.source.statementId === 'michigan-legislature')!; assert.equal(implications.some((action) => action.implication!.fromStatementId === michigan.id || action.implication!.toStatementId === michigan.id), false); @@ -271,7 +278,8 @@ test('batch 2 keeps the pilot families, reuses accepted bridges, and shares one for (const causeId of ['grey-assimilation', 'ranked-approval-poll', 'checkout-trial-bridge', 'minors-medicine', 'opinion-employment', 'canada-us-ties']) { const board = plan.actions.find((action) => action.type === 'create-cause' && action.causeId === causeId)!.board!; assert.equal(board.role, 'commonality'); - assert.equal(implications.some((action) => action.causeId === causeId), false, causeId); + assert.equal(implications.filter((action) => action.causeId === causeId).length, 2, causeId); + assert.ok(implications.filter((action) => action.causeId === causeId).every((action) => action.implication!.evidence === 'live-attester-modified-to-commonality')); } for (const causeId of manifest.causes.map((cause) => cause.id)) { assert.ok(plan.projects.filter((project) => project.causeId === causeId).length >= 2, causeId); From ad1cf79a087a21a01b438604ce250e339ba88f54 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 17:23:17 -0400 Subject: [PATCH 12/19] Pin cheap verifier checks to Qwen and fund campaign gas for real limits. clear-communication uses opencode-go/qwen3.8-flash because DeepSeek on OpenCode Go is region-blocked here and Qwen matched the known implication pairs. Other verifier leaves move to grok-4.7. Belief and publish funding now covers the gas the executor actually requests, so a resume does not need a manual balance top-up. --- ...6-network-societies-b2-executed-handoff.md | 2 +- ...26-10-16-qwen-and-campaign-gaps-handoff.md | 29 +++++++++++++++++++ fake-data-generation/campaignBatching.ts | 22 ++++++++++---- fake-data-generation/campaignPlanner.ts | 2 +- .../campaigns/network-societies-v1-b2.md | 4 +++ .../test/campaignProvisioning.test.ts | 22 ++++++++++++-- verifier/README.md | 2 +- verifier/checks/lib/llm-judgment.mjs | 6 ++-- verifier/checks/lib/llm-judgment.test.mjs | 4 +-- verifier/llm-routing.json | 16 +++++----- 10 files changed, 85 insertions(+), 24 deletions(-) create mode 100644 continuity/2026-10-16-qwen-and-campaign-gaps-handoff.md diff --git a/continuity/2026-10-16-network-societies-b2-executed-handoff.md b/continuity/2026-10-16-network-societies-b2-executed-handoff.md index 817fed94..34817129 100644 --- a/continuity/2026-10-16-network-societies-b2-executed-handoff.md +++ b/continuity/2026-10-16-network-societies-b2-executed-handoff.md @@ -7,7 +7,7 @@ Next session: figure out which DeepSeek model `opencode-go` should use. `deepsee - [`fake-data-generation/campaigns/network-societies-v1-b2.md`](../fake-data-generation/campaigns/network-societies-v1-b2.md) — what batch 2 published. - [`fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json`](../fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json) — 68 live pairs. Model `deepseek/deepseek-v3.2`. Prompt fingerprint `2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891`. - [`fake-data-generation/campaigns/network-societies-v1-b2-decisions.json`](../fake-data-generation/campaigns/network-societies-v1-b2-decisions.json) — allowed arrows and the five first-wording refusals. -- [`verifier/llm-routing.json`](../verifier/llm-routing.json) — subscription pin. Every task kind is `xai/grok-4.6`. Allowed providers are `xai` and `opencode-go`. Never OpenRouter for verifier leaves. +- [`verifier/llm-routing.json`](../verifier/llm-routing.json) — subscription pin. Every task kind is `xai/grok-4.6`. Allowed providers are `xai` and `opencode-go`. (NOTE FROM ADAM: Also might as well use grok-4.7 instead of grok-4.6.) Never OpenRouter for verifier leaves. - [`services/attester-core/src/llm-models.ts`](../services/attester-core/src/llm-models.ts) and [`services/attester-core/src/openrouter.ts`](../services/attester-core/src/openrouter.ts) — production OpenRouter default is `deepseek/deepseek-v4-flash-0731`, and `requestJsonCompletionWithUsage` caps `max_tokens` at 500. - Branch `campaign`. Do not commit on `dev` or `master`. diff --git a/continuity/2026-10-16-qwen-and-campaign-gaps-handoff.md b/continuity/2026-10-16-qwen-and-campaign-gaps-handoff.md new file mode 100644 index 00000000..57a38350 --- /dev/null +++ b/continuity/2026-10-16-qwen-and-campaign-gaps-handoff.md @@ -0,0 +1,29 @@ +# Handoff: leftover network-societies batch-2 campaign gaps + +Next session: apply the persona `set-belief` choices, then decide whether delegated spending and a monthly pledge belong in this campaign. Do not rewrite the batch-2 statements. Do not force triples onto the skipped overlaps. + +## Read first + +- [`fake-data-generation/campaigns/network-societies-v1-b2.md`](../fake-data-generation/campaigns/network-societies-v1-b2.md) — what batch 2 published, the gas shortfall, and the model note. +- [`fake-data-generation/campaigns/network-societies-v1-b2-decisions.json`](../fake-data-generation/campaigns/network-societies-v1-b2-decisions.json) — allowed arrows and the persona refusals. Eli's refusal of the abortion settlement is authoring intent. The planner can still have him believe that commonality. +- [`verifier/llm-routing.json`](../verifier/llm-routing.json) — `clear-communication` is `opencode-go/qwen3.8-flash`. Every other task kind is `xai/grok-4.7`. Never OpenRouter for verifier leaves. +- Branch `campaign`. Do not commit on `dev` or `master`. + +## What is already true + +Batch 2 was executed locally. 446/446 mined and reconciled after a manual ETH top-up. Funding now prices a belief batch as `40_000 + 80_000 * n` gas (280_000 for three) and a publish as 4_000_000 plus 500_000 per extra document in the batch. That change is in `campaignBatching.ts`. A later local run should not need `hardhat_setBalance`. Do not overwrite the pilot or `medium-realistic-v2` outputs. + +`opencode-go` DeepSeek ids return HTTP 400 until the OpenCode workspace privacy region is Global. `opencode-go/qwen3.8-flash` returned parseable JSON and matched the v3.2 yes/no on one short pair and one long modified-to-commonality pair. Production `PRODUCTION_OPENROUTER_MODEL` is still `deepseek/deepseek-v4-flash-0731`. The attester's 500-token cap was not retested. + +The Grey County assimilation commonality board loaded with "Arriving through other statements." Direct and indirect counts were 0. + +## What to do + +1. Apply the persona `set-belief` choices in the decisions file. Eli must not be planned as believing the abortion commonality. +2. Delegated spending and a recurring monthly pledge are still not campaign actions. Add them only if they fit an existing persona in this manifest. +3. The remaining brainstorm families (low-carb, unwoke as an umbrella, Democracy 2.0, Islamic reform, permitting, home-school beyond the pilot) are still unauthored. The campaign note already skips several of these as overlaps. Do not force triples onto overlaps that already share a concrete want. + +## Suggested skills + +- `thorough-tester` — after belief choices change, check the planned actions against the decisions file before another chain run. +- `browser-driving` — only if a later execute changes a board. diff --git a/fake-data-generation/campaignBatching.ts b/fake-data-generation/campaignBatching.ts index 84207e83..121806d7 100644 --- a/fake-data-generation/campaignBatching.ts +++ b/fake-data-generation/campaignBatching.ts @@ -15,7 +15,11 @@ const MAX_BATCH: Partial> = { /** Gas for a transaction that carries exactly one of these writes. */ export const SOLO_GAS_UNITS: Record = { - 'publish-statement': 180_000n, 'create-cause': 120_000n, 'create-bridge-board': 120_000n, 'create-bridge': 120_000n, 'set-belief': 90_000n, + // publishDataBatch does not set gas; viem's estimate on a campaign statement + // batch was about 4e6. set-belief matches campaignActionAdapter: a single + // setBelief is 120_000, and setBeliefsInBatch is 40_000 + 80_000 * n + // (three beliefs => 280_000). The old 180k/90k figures left wallets short. + 'publish-statement': 4_000_000n, 'create-cause': 120_000n, 'create-bridge-board': 120_000n, 'create-bridge': 120_000n, 'set-belief': 120_000n, // Base Sepolia clone-factory canary on 2026-09-29: five create-project // receipts averaged 2,851,538 gas. Keep a little headroom for colder storage. 'attest-implication': 130_000n, 'create-project': 3_000_000n, 'attest-alignment': 130_000n, @@ -24,8 +28,8 @@ export const SOLO_GAS_UNITS: Record = { /** Storage and log cost of one extra item once the transaction overhead is paid. */ const MARGINAL_GAS_UNITS: Partial> = { - 'publish-statement': 80_000n, - 'set-belief': 35_000n, + 'publish-statement': 500_000n, + 'set-belief': 80_000n, 'attest-implication': 55_000n, 'attest-alignment': 40_000n, }; @@ -85,8 +89,16 @@ export function groupCampaignWrites(actions: readonly PlannedAction[], options: /** Native gas units for one grouped transaction, before the gas price. */ export function estimateGroupGas(group: readonly PlannedAction[]): bigint { if (group.length === 0) throw new Error('cannot estimate an empty campaign write group'); - if (group.length === 1) return SOLO_GAS_UNITS[group[0].type]; - const marginal = MARGINAL_GAS_UNITS[group[0].type]; + const type = group[0].type; + if (group.length === 1) return SOLO_GAS_UNITS[type]; + // Belief and publish batches must cover the limit the writer asks viem for. + // overhead + small marginal underfunded setBeliefsInBatch (280_000 for three) + // and large publishDataBatch transactions. + if (type === 'set-belief' || type === 'publish-statement') { + const marginal = MARGINAL_GAS_UNITS[type]!; + return SOLO_GAS_UNITS[type] + marginal * BigInt(group.length - 1); + } + const marginal = MARGINAL_GAS_UNITS[type]; if (marginal === undefined) return group.reduce((sum, action) => sum + SOLO_GAS_UNITS[action.type], 0n); return BATCH_OVERHEAD_GAS + marginal * BigInt(group.length); } diff --git a/fake-data-generation/campaignPlanner.ts b/fake-data-generation/campaignPlanner.ts index 159f8b8d..39584e1c 100644 --- a/fake-data-generation/campaignPlanner.ts +++ b/fake-data-generation/campaignPlanner.ts @@ -117,7 +117,7 @@ export interface CampaignPlan { } const GAS_UNITS: Record = { - 'publish-statement': 180_000, 'create-cause': 120_000, 'create-bridge-board': 120_000, 'create-bridge': 120_000, 'set-belief': 90_000, + 'publish-statement': 4_000_000, 'create-cause': 120_000, 'create-bridge-board': 120_000, 'create-bridge': 120_000, 'set-belief': 120_000, 'attest-implication': 130_000, 'create-project': 1_100_000, 'attest-alignment': 130_000, 'fund-project': 180_000, 'deposit-note': 150_000, 'delegate-note': 100_000, 'revoke-delegation': 90_000, }; diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.md b/fake-data-generation/campaigns/network-societies-v1-b2.md index f2a5c401..d64fbd7d 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2.md +++ b/fake-data-generation/campaigns/network-societies-v1-b2.md @@ -40,6 +40,10 @@ Do not write this plan over `network-societies-v1-pilot` or `medium-realistic-v2 A plan written after the attester pass has 446 writes. On 2026-10-16 the local chain mined 446/446 and reconciliation matched 446/446. The first pass left 14 actions failed for insufficient ETH; those wallets were topped up and the run resumed. Output is `output/campaigns/network-societies-v1-b2/`. Pilot and medium-realistic-v2 outputs were not overwritten. +The shortfall was the funder, not the chain. `computeCampaignFundingNeeds` priced a belief write at 90_000 gas and a publish at 180_000. The executor asks viem for `40_000 + 80_000 * n` on `setBeliefsInBatch` (280_000 for three) and leaves `publishDataBatch` to viem, which estimated about 4_000_000 on the large publishes. Funding now uses those figures, with 500_000 extra gas per publish after the first in a batch. A later local run should not need a manual `hardhat_setBalance`. + +OpenCode Go DeepSeek ids (`deepseek-v4-flash`, `deepseek-v4.1-flash`, `deepseek-v4-pro`) return HTTP 400 on this workspace until privacy is set to Global. `opencode-go/qwen3.8-flash` returned parseable JSON and matched the v3.2 decision on the short dual-count natural-to-commonality refusal and the long Grey County modified-left-to-commonality bless. Verifier `clear-communication` leaves use that model. Other verifier leaves stay on `xai/grok-4.7`. Production `PRODUCTION_OPENROUTER_MODEL` stays `deepseek/deepseek-v4-flash-0731`. + The Grey County assimilation commonality board is `http://commonality.localhost:8088/#/cause/0xEe6a18208ca061e2Eddd4A6fA7E4E4d4927eF352/network-societies-v1-b2-grey-assimilation-bridge`. Its statement page shows "Arriving through other statements." Direct and indirect counts were 0 on that load because the visible sentence had no signers yet. Persona `set-belief` choices are still not applied. Delegated spending and a recurring monthly pledge are still not campaign actions. The six clusters are not accepted seed. diff --git a/fake-data-generation/test/campaignProvisioning.test.ts b/fake-data-generation/test/campaignProvisioning.test.ts index 41d5af16..f77bd9f7 100644 --- a/fake-data-generation/test/campaignProvisioning.test.ts +++ b/fake-data-generation/test/campaignProvisioning.test.ts @@ -7,6 +7,7 @@ import { parseEther, parseUnits, type Address, type Hex } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; import { LOCAL_HARDHAT_CHAIN_ID, type CampaignEnvironment } from '../campaignEnvironment.js'; import type { CampaignPlan, PlannedAction } from '../campaignPlanner.js'; +import { estimateGroupGas } from '../campaignBatching.js'; import { CAMPAIGN_NOTE_WEI, computeCampaignFundingNeeds, provisionCampaignWallets, type CampaignFundingChain } from '../campaignProvisioning.js'; const generatedKey = '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d' as const; @@ -41,13 +42,13 @@ test('funding needs include gas, note deposits, and project token buys', () => { const [need] = computeCampaignFundingNeeds(plan, [wallet], 1_000_000_000n); assert.equal(need.walletSlot, 'wallet-user-001'); assert.equal(need.paymentTokenUnits, parseUnits('0.01', 6)); - assert.ok(need.nativeWei >= 90_000n * 1_000_000_000n + 180_000n * 1_000_000_000n + 150_000n * 1_000_000_000n + CAMPAIGN_NOTE_WEI); + assert.ok(need.nativeWei >= 120_000n * 1_000_000_000n + 180_000n * 1_000_000_000n + 150_000n * 1_000_000_000n + CAMPAIGN_NOTE_WEI); }); test('native reserve scales with gas and leaves idle wallets unfunded', () => { const idle = { ...wallet, walletSlot: 'wallet-idle' }; const needs = computeCampaignFundingNeeds(plan, [wallet, idle], 1_000_000_000n); - const estimatedGasWei = (90_000n + 180_000n + 150_000n) * 1_000_000_000n; + const estimatedGasWei = (120_000n + 180_000n + 150_000n) * 1_000_000_000n; assert.equal(needs[0].nativeWei, CAMPAIGN_NOTE_WEI + estimatedGasWei * 125n / 100n + parseEther('0.0001')); assert.equal(needs[1].nativeWei, 0n); }); @@ -55,7 +56,22 @@ test('native reserve scales with gas and leaves idle wallets unfunded', () => { test('publisher wallet receives gas for actorless statement writes', () => { const publishOnly = { ...plan, actions: [action({ id: 'publish', type: 'publish-statement', actorUserId: null })] } as CampaignPlan; const [need] = computeCampaignFundingNeeds(publishOnly, [wallet], 6_000_000n); - assert.ok(need.nativeWei > 180_000n * 6_000_000n); + assert.ok(need.nativeWei >= 4_000_000n * 6_000_000n); +}); + +test('belief batches and publishes are funded for the gas the writer requests', () => { + const beliefs = [1, 2, 3].map((n) => action({ id: `b${n}`, type: 'set-belief', sequence: n })); + const writerGas = 40_000n + 80_000n * 3n; + assert.equal(estimateGroupGas(beliefs), writerGas); + const beliefPlan = { ...plan, actions: beliefs } as CampaignPlan; + const [beliefNeed] = computeCampaignFundingNeeds(beliefPlan, [wallet], 1_000_000_000n); + assert.ok(beliefNeed.nativeWei >= writerGas * 1_000_000_000n); + + const publishes = [1, 2].map((n) => action({ id: `p${n}`, type: 'publish-statement', actorUserId: null, sequence: n })); + assert.equal(estimateGroupGas(publishes), 4_000_000n + 500_000n); + const publishPlan = { ...plan, actions: publishes } as CampaignPlan; + const [publishNeed] = computeCampaignFundingNeeds(publishPlan, [wallet], 1_000_000_000n); + assert.ok(publishNeed.nativeWei >= estimateGroupGas(publishes) * 1_000_000_000n); }); test('provisioning uses the supplied RPC gas-price quote', async () => { diff --git a/verifier/README.md b/verifier/README.md index 9e67a07f..669a5b55 100644 --- a/verifier/README.md +++ b/verifier/README.md @@ -94,7 +94,7 @@ Only use `verifier-run ` / `COMMONALITY_VERIFIER_ALLOW_LLM=1` when Adam Expensive (LLM/agent) checks are marked declaratively with `"cost": "llm"` in their `*.def.json`. Count them with `npm run verifier:llm -- --list`: standing `review.*` “acts like a human tester” leaves (including `review.testnet-two-person-lab`), two meta reviewers, `meta.report-currency`, the `root` narrative, and the `known-bad.report` fixture (that last one never calls a live model). **They do not auto-run.** Review/meta leaves are `trigger: manual`. `meta.report-currency` is an explicit legacy heuristic (`npm run verifier:currency:heuristic`) and is no longer a root input. `root` may still fold on input change, but its **narrative model call is opt-in** (`COMMONALITY_VERIFIER_ALLOW_LLM=1`, set by `verifier:root`). The scheduler therefore cannot burn tokens on human-tester leaves. -They spend against Adam's **subscription** providers only (`xai/grok-4.6` by default, or `opencode-go/…` via `COMMONALITY_VERIFIER_LLM_PROVIDER=opencode-go`). `verifier/llm-routing.json` is the pin; OpenRouter and other pay-per-token gateways are rewritten away before `pi` is spawned. +They spend against Adam's **subscription** providers only (`xai/grok-4.7` by default, `opencode-go/qwen3.8-flash` for `clear-communication`, or another `opencode-go/…` model via `COMMONALITY_VERIFIER_LLM_PROVIDER=opencode-go`). `verifier/llm-routing.json` is the pin; OpenRouter and other pay-per-token gateways are rewritten away before `pi` is spawned. To have the LLM you are already chatting with do the review (and have it count as a real stored Result): dump the prompt, write the JSON envelope the prompt asks for, then record it — no second `pi` process, no OpenRouter: diff --git a/verifier/checks/lib/llm-judgment.mjs b/verifier/checks/lib/llm-judgment.mjs index 4b144069..e80a476d 100644 --- a/verifier/checks/lib/llm-judgment.mjs +++ b/verifier/checks/lib/llm-judgment.mjs @@ -127,7 +127,7 @@ function loadLlmRouting() { } catch { return { allowedProviders: ["xai", "opencode-go"], - default: "xai/grok-4.6", + default: "xai/grok-4.7", byTaskKind: {} }; } @@ -144,7 +144,7 @@ function providerOf(model) { export function coerceSubscriptionModel(model, env = process.env) { const routing = loadLlmRouting(); const allowed = new Set(routing.allowedProviders ?? ["xai", "opencode-go"]); - const fallback = routing.default ?? "xai/grok-4.6"; + const fallback = routing.default ?? "xai/grok-4.7"; const preferredProvider = (env.COMMONALITY_VERIFIER_LLM_PROVIDER ?? "").trim().toLowerCase(); if (preferredProvider && allowed.has(preferredProvider)) { @@ -185,7 +185,7 @@ export function resolveModel(params, { modelEnvVar, defaultTaskKind }) { const routed = execFileSync(router, [taskKind], { encoding: "utf8" }).trim() || null; return coerceSubscriptionModel(routed); } catch { - return coerceSubscriptionModel(routing.default ?? "xai/grok-4.6"); + return coerceSubscriptionModel(routing.default ?? "xai/grok-4.7"); } } diff --git a/verifier/checks/lib/llm-judgment.test.mjs b/verifier/checks/lib/llm-judgment.test.mjs index 286e946b..78ebaf8d 100644 --- a/verifier/checks/lib/llm-judgment.test.mjs +++ b/verifier/checks/lib/llm-judgment.test.mjs @@ -101,7 +101,7 @@ test("coerceSubscriptionModel keeps xai and opencode-go pins", () => { }); test("coerceSubscriptionModel rewrites OpenRouter onto the workspace default", () => { - assert.equal(coerceSubscriptionModel("openrouter/deepseek/deepseek-v4-pro"), "xai/grok-4.6"); + assert.equal(coerceSubscriptionModel("openrouter/deepseek/deepseek-v4-pro"), "xai/grok-4.7"); }); test("coerceSubscriptionModel honors COMMONALITY_VERIFIER_LLM_PROVIDER", () => { @@ -116,7 +116,7 @@ test("coerceSubscriptionModel does not keep OpenRouter path tails under a provid coerceSubscriptionModel("openrouter/deepseek/deepseek-v4-pro", { COMMONALITY_VERIFIER_LLM_PROVIDER: "opencode-go" }), - "opencode-go/grok-4.6" + "opencode-go/grok-4.7" ); }); diff --git a/verifier/llm-routing.json b/verifier/llm-routing.json index b9203f7a..8193d50a 100644 --- a/verifier/llm-routing.json +++ b/verifier/llm-routing.json @@ -1,13 +1,13 @@ { - "comment": "Verifier LLM leaves spend against Adam's subscription providers only. Never OpenRouter (pay-per-token). Override with COMMONALITY_VERIFIER_LLM_MODEL=opencode-go/ or COMMONALITY_VERIFIER_LLM_PROVIDER=opencode-go.", + "comment": "Verifier LLM leaves spend against Adam's subscription providers only. Never OpenRouter (pay-per-token). Override with COMMONALITY_VERIFIER_LLM_MODEL=opencode-go/ or COMMONALITY_VERIFIER_LLM_PROVIDER=opencode-go. Cheap clear-communication uses opencode-go/qwen3.8-flash: on 2026-10-16 it returned parseable JSON and matched the v3.2 designed yes/no on one short pair and one long modified-to-commonality pair. opencode-go DeepSeek ids return 400 until the OpenCode workspace privacy region is Global.", "allowedProviders": ["xai", "opencode-go"], - "default": "xai/grok-4.6", + "default": "xai/grok-4.7", "byTaskKind": { - "big-picture-thinking": "xai/grok-4.6", - "clear-communication": "xai/grok-4.6", - "easy": "xai/grok-4.6", - "complex-coding": "xai/grok-4.6", - "normal-coding": "xai/grok-4.6", - "easy-coding": "xai/grok-4.6" + "big-picture-thinking": "xai/grok-4.7", + "clear-communication": "opencode-go/qwen3.8-flash", + "easy": "xai/grok-4.7", + "complex-coding": "xai/grok-4.7", + "normal-coding": "xai/grok-4.7", + "easy-coding": "xai/grok-4.7" } } From dd3578dce30ccca687cf8d5557889c2b1e935013 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 17:36:55 -0400 Subject: [PATCH 13/19] Pin batch-2 persona beliefs and record what the campaign still lacks. --- ...26-10-16-qwen-and-campaign-gaps-handoff.md | 6 +- fake-data-generation/PLAN.md | 2 +- .../network-societies-campaign-plan.md | 22 ++++++- fake-data-generation/campaignPlanner.ts | 65 +++++++++++++++++-- fake-data-generation/campaignSchema.ts | 8 +++ .../network-societies-v1-b2-decisions.json | 2 +- .../campaigns/network-societies-v1-b2.json | 1 + .../campaigns/network-societies-v1-b2.md | 6 +- .../test/campaignPlanner.test.ts | 27 ++++++++ 9 files changed, 125 insertions(+), 14 deletions(-) diff --git a/continuity/2026-10-16-qwen-and-campaign-gaps-handoff.md b/continuity/2026-10-16-qwen-and-campaign-gaps-handoff.md index 57a38350..14bb80bc 100644 --- a/continuity/2026-10-16-qwen-and-campaign-gaps-handoff.md +++ b/continuity/2026-10-16-qwen-and-campaign-gaps-handoff.md @@ -1,6 +1,6 @@ # Handoff: leftover network-societies batch-2 campaign gaps -Next session: apply the persona `set-belief` choices, then decide whether delegated spending and a monthly pledge belong in this campaign. Do not rewrite the batch-2 statements. Do not force triples onto the skipped overlaps. +Next session: the persona `set-belief` pins are in the planner. Delegated spending and a monthly pledge stay out. Do not rewrite the batch-2 statements. Do not force triples onto the skipped overlaps. A new chain run needs a fresh output directory. ## Read first @@ -19,8 +19,8 @@ The Grey County assimilation commonality board loaded with "Arriving through oth ## What to do -1. Apply the persona `set-belief` choices in the decisions file. Eli must not be planned as believing the abortion commonality. -2. Delegated spending and a recurring monthly pledge are still not campaign actions. Add them only if they fit an existing persona in this manifest. +1. Done. `beliefDecisions` on the batch-2 manifest pins each `signs` and `rejects` entry. Eli's only planned belief on the abortion commonality is `disbelieve`. The mined directory `output/campaigns/network-societies-v1-b2/` is the earlier plan. Do not regenerate into it. +2. Done as a decision. Pat already delegates a note to Ned. No persona spends a delegated note or makes a monthly pledge, and the adapter has no action for either. Leave them out. 3. The remaining brainstorm families (low-carb, unwoke as an umbrella, Democracy 2.0, Islamic reform, permitting, home-school beyond the pilot) are still unauthored. The campaign note already skips several of these as overlaps. Do not force triples onto overlaps that already share a concrete want. ## Suggested skills diff --git a/fake-data-generation/PLAN.md b/fake-data-generation/PLAN.md index 4384b254..9ea67f20 100644 --- a/fake-data-generation/PLAN.md +++ b/fake-data-generation/PLAN.md @@ -82,7 +82,7 @@ Do these in order unless Adam names a different one. Each item is a session-size The four-family pilot (crypto merchants, Grey County civic life, Christian teaching, home learning) is in [`campaigns/network-societies-v1-pilot.md`](./campaigns/network-societies-v1-pilot.md). A local run on 2026-10-16 mined and reconciled 207/207. Cause pages list the shared class-host directory once the alignment-trust bootstrap wallet has gas. -Batch 2 keeps those four families and adds the accepted abortion bridge, the accepted schools-pushing bridge, an Owen Sound voting trial, and six draft bridges (assimilation sessions, dual-count poll, checkout trial, minors' medicine, ordinary opinions and employment, Canada–US ties). Wording is in [`statement-generation-exercises/06-network-society-alliances.json`](./statement-generation-exercises/06-network-society-alliances.json) and copied into the batch-2 statement file. The note is [`campaigns/network-societies-v1-b2.md`](./campaigns/network-societies-v1-b2.md). The manifest is 60 users, 100 statements, and 52 projects. A 2026-10-16 live attester pass (deepseek/deepseek-v3.2) blessed all twelve new modified-to-commonality arrows and refused the designed-negative pairs after a rewrite of the employment modifieds and the Canada wording. The plan allows those twelve arrows with evidence `live-attester-modified-to-commonality`, plus the four accepted abortion and schools arrows. The six clusters are not accepted seed. A local run on 2026-10-16 mined and reconciled 446/446 into `output/campaigns/network-societies-v1-b2/`. Persona `set-belief` choices are still not wired. +Batch 2 keeps those four families and adds the accepted abortion bridge, the accepted schools-pushing bridge, an Owen Sound voting trial, and six draft bridges (assimilation sessions, dual-count poll, checkout trial, minors' medicine, ordinary opinions and employment, Canada–US ties). Wording is in [`statement-generation-exercises/06-network-society-alliances.json`](./statement-generation-exercises/06-network-society-alliances.json) and copied into the batch-2 statement file. The note is [`campaigns/network-societies-v1-b2.md`](./campaigns/network-societies-v1-b2.md). The manifest is 60 users, 100 statements, and 52 projects. A 2026-10-16 live attester pass (deepseek/deepseek-v3.2) blessed all twelve new modified-to-commonality arrows and refused the designed-negative pairs after a rewrite of the employment modifieds and the Canada wording. The plan allows those twelve arrows with evidence `live-attester-modified-to-commonality`, plus the four accepted abortion and schools arrows. The six clusters are not accepted seed. A local run on 2026-10-16 mined and reconciled 446/446 into `output/campaigns/network-societies-v1-b2/`. Persona `set-belief` choices in the decisions file are pinned by the planner. The mined output directory is the earlier plan and was not rewritten. ## Pointers diff --git a/fake-data-generation/brainstorming/network-societies-campaign-plan.md b/fake-data-generation/brainstorming/network-societies-campaign-plan.md index b0ecc45d..547c8654 100644 --- a/fake-data-generation/brainstorming/network-societies-campaign-plan.md +++ b/fake-data-generation/brainstorming/network-societies-campaign-plan.md @@ -1,6 +1,22 @@ # Network societies fake-data campaign -Status: implementation handoff, 2026-10-16. This document plans a new campaign; it does not generate data or authorize a remote deployment. Suggested campaign ID: `network-societies-v1`. +Status: partial local campaign, updated 2026-10-16. This document is the target for the whole fifteen-family world. It does not generate data or authorize a remote deployment. The live ids are `network-societies-v1-pilot` and `network-societies-v1-b2`, not one `network-societies-v1` manifest. + +## Where the work stands + +Two local campaigns exist. Neither is the finished fifteen-family world, and neither has been published to testnet. + +**Pilot** ([`network-societies-v1-pilot.md`](../campaigns/network-societies-v1-pilot.md)). Four families: Owen Sound checkout, Grey County civic life, Christian teaching, home learning. About 40 users, 40 statements, 20 projects. A local run on 2026-10-16 mined and reconciled 207/207. No implication edges. The class-host directory is one statement on two boards. Pat delegates a note to Ned; the adapter can revoke a delegation. Persona belief choices in the pilot decisions file are still not applied by the planner. + +**Batch 2** ([`network-societies-v1-b2.md`](../campaigns/network-societies-v1-b2.md)). Keeps those four families and adds the accepted abortion settlement, the accepted schools-and-pushing bridge, an Owen Sound voting trial, and six draft bridges (assimilation sessions, dual-count poll, checkout trial, minors' medicine, ordinary opinions and employment, Canada–US ties). 60 users, 100 statements, 52 projects. Sixteen modified-to-commonality arrows are allowed: four accepted bridge pairs and twelve live attester blesses. Designed-negative pairs stay unpublished. The six draft clusters are not accepted seed. A local run on 2026-10-16 mined and reconciled 446/446 into `output/campaigns/network-societies-v1-b2/`. That output is the plan from before the belief pins. Do not regenerate into it. + +The planner now pins batch-2 `signs` and `rejects` from the decisions file. Eli's only planned belief on the abortion commonality is `disbelieve`. Unsigned is still not a rejection. The next chain run needs a fresh output directory. + +**Decided out of this campaign for now.** Delegated spending and a recurring monthly pledge. Pat already delegates a note, and revocation is a real action. Nothing spends a delegated note or repeats a pledge. Journey 5 below is therefore only partly demonstrated, and the "$20/month" filter is still a product gap. + +**Not started as families.** Eight of the fifteen rows below are not campaign manifests: low-carb, cancel-proof support, unwoke, Democracy 2.0, AI safety, US-friendly Canadians beyond the five-statement draft bridge, Islamic reform, and less regulation. Home learning and Grey County civic life stop at the pilot planks. Do not force a new triple onto an overlap that already shares a concrete want. The campaign note already treats several of these as overlaps. + +**Journeys.** Direct shared agreement and one reused statement on two boards are in the pilot. A declined bridge is authored for batch 2 (Eli) and is in the new plan, not in the mined output. Verified implication paths are planned for batch 2. Early-risk reimbursement, a friend actually spending a delegated note, recurring pledges, and the independent-reviewer walkthrough are not campaign demonstrations yet. ## Purpose @@ -113,6 +129,8 @@ The brainstorming's “$20/month, fire-and-forget” and “delivered but not re ## Implementation sequence +Steps 1–3 are done for the pilot, and step 3 is also done for batch 2 on the pre-pin plan. Step 4 is one batch in, with eight families still unauthored. Step 5 is not started. The notes under each step stay as the original instructions. + ### 1. Make a capability and content inventory Inspect current runner/schema and record reusable paths versus missing wiring. Known issues to address: `campaignSchema.ts` currently caps the catalog at 70 statement references and requires at least eight causes, while the pilot below has four; it also treats statement references across causes as unique. The planner's implication evidence currently uses accepted bridge-role pairs, which is insufficient for new evaluated campaign statements. Existing project/story and cross-camp funding selection may contain campaign-specific assumptions. @@ -157,4 +175,4 @@ Remote/testnet publication is a separate later step using existing preflight, bu - Required journeys have reconciled state and browser observations. Unsupported behaviors are listed as specific gaps, never counted as demonstrated; the full demo is not called complete while a required journey is silently missing. - The report identifies synthetic users/activity/deliverables, actual amounts and outcomes, exact reproduction steps, and the next unfinished task if work spans sessions. -**First task for the implementing LLM:** inspect the current campaign schema/planner/adapter and write the capability table, then author the four-family pilot content. Do not start with a bulk random run or by drafting all 200 statements at once. +**Next task:** author the next content batch from the eight families that are not manifests yet, skipping overlaps that already share a concrete want. Apply the pilot persona belief choices the same way batch 2 pins them, or leave that file marked unapplied. Do not regenerate `output/campaigns/network-societies-v1-b2/`. Do not start a bulk random run or draft all remaining statements at once. diff --git a/fake-data-generation/campaignPlanner.ts b/fake-data-generation/campaignPlanner.ts index 39584e1c..8ca6c69e 100644 --- a/fake-data-generation/campaignPlanner.ts +++ b/fake-data-generation/campaignPlanner.ts @@ -250,6 +250,36 @@ async function loadCampaignStories(manifest: CampaignManifestV1): Promise; } +interface BeliefDecisionPerson { + userId: string; + name?: string; + signs?: string[]; + rejects?: string[]; +} + +async function loadBeliefDecisions(manifest: CampaignManifestV1): Promise { + if (!manifest.beliefDecisions) return []; + const sourcePath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'campaigns', manifest.beliefDecisions); + const parsed = JSON.parse(await readFile(sourcePath, 'utf8')) as { people?: BeliefDecisionPerson[] }; + return parsed.people ?? []; +} + +function causeForSigner(user: PlannedUser, statement: PlannedStatement): string { + if (user.causeIds.includes(statement.causeId)) return statement.causeId; + const also = user.causeIds.find((causeId) => statement.alsoOnCauseIds?.includes(causeId)); + if (!also) throw new Error(`${user.id} is not on a board that lists ${statement.source.statementId}`); + return also; +} + +function resolveDecisionStatement(user: PlannedUser, statements: PlannedStatement[], statementId: string): PlannedStatement { + const visible = statements.filter((statement) => user.causeIds.some((causeId) => statement.causeId === causeId || statement.alsoOnCauseIds?.includes(causeId))); + const matches = visible.filter((statement) => statement.source.statementId === statementId); + if (matches.length !== 1) { + throw new Error(`${user.displayName ?? user.id} decision ${statementId} matches ${matches.length} statements on their boards`); + } + return matches[0]; +} + export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise { validateCampaignManifest(manifest); const random = new Xoshiro128StarStar(manifest.campaign.deterministicSeed); @@ -289,6 +319,7 @@ export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise [profile.userId, profile])); @@ -438,10 +469,36 @@ export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise(); - for (let index = 0; index < countByType['set-belief']; index++) { - const actor = random.weighted(activeUsers, (user) => user.activityWeight); - const previous = index > Math.floor(countByType['set-belief'] * 0.92) && latestBelief.size > 0 ? random.pick([...latestBelief.values()]) : undefined; - const statement = previous ? statements.find((item) => item.id === previous.statementId)! : random.pick(preferredStatements(actor, statements)); + const pinnedBeliefs = new Set(); + const usersById = new Map(users.map((user) => [user.id, user])); + for (const person of beliefDecisions) { + const user = usersById.get(person.userId); + if (!user) throw new Error(`belief decision names unknown user ${person.userId}`); + const chosen = [ + ...(person.signs ?? []).map((statementId) => ({ statementId, belief: 'believe' as const })), + ...(person.rejects ?? []).map((statementId) => ({ statementId, belief: 'disbelieve' as const })), + ]; + for (const choice of chosen) { + const statement = resolveDecisionStatement(user, statements, choice.statementId); + const key = `${user.id}/${statement.id}`; + if (pinnedBeliefs.has(key)) throw new Error(`${user.id} pins ${choice.statementId} more than once`); + const causeId = causeForSigner(user, statement); + const action = add({ type: 'set-belief', actorUserId: user.id, causeId, statementId: statement.id, belief: choice.belief, dependsOn: [publishes.get(statement.id)!.id] }); + pinnedBeliefs.add(key); + latestBelief.set(key, action); + } + } + if (pinnedBeliefs.size > countByType['set-belief']) { + throw new Error(`belief decisions pin ${pinnedBeliefs.size} writes, above the set-belief target ${countByType['set-belief']}`); + } + const randomBeliefCount = countByType['set-belief'] - pinnedBeliefs.size; + for (let index = 0; index < randomBeliefCount; index++) { + const flipPool = [...latestBelief.values()].filter((action) => !pinnedBeliefs.has(`${action.actorUserId}/${action.statementId}`)); + const previous = index > Math.floor(randomBeliefCount * 0.92) && flipPool.length > 0 ? random.pick(flipPool) : undefined; + const actor = previous ? usersById.get(previous.actorUserId!)! : random.weighted(activeUsers, (user) => user.activityWeight); + const openStatements = preferredStatements(actor, statements).filter((statement) => !pinnedBeliefs.has(`${actor.id}/${statement.id}`)); + if (!previous && openStatements.length === 0) throw new Error(`${actor.id} has no unpinned statement to sign`); + const statement = previous ? statements.find((item) => item.id === previous.statementId)! : random.pick(openStatements); const beliefActor = users.find((user) => user.id === (previous?.actorUserId ?? actor.id))!; const causeId = beliefActor.causeIds.includes(statement.causeId) ? statement.causeId diff --git a/fake-data-generation/campaignSchema.ts b/fake-data-generation/campaignSchema.ts index ec339db7..d49a4309 100644 --- a/fake-data-generation/campaignSchema.ts +++ b/fake-data-generation/campaignSchema.ts @@ -109,6 +109,11 @@ export interface CampaignManifestV1 { * Absent manifests still plan every modified-to-commonality pair as accepted-bridge-role-pair. */ implicationAllowances?: CampaignImplicationAllowance[]; + /** + * Persona sign and reject choices. The planner pins those set-belief writes + * and does not let the random draw overwrite them. Unsigned entries stay unpinned. + */ + beliefDecisions?: string; } export type CampaignImplicationEvidence = 'accepted-bridge-role-pair' | 'live-attester-modified-to-commonality'; @@ -243,6 +248,9 @@ export function validateCampaignManifest(manifest: CampaignManifestV1): void { if (manifest.projectStories && !/^[a-z0-9][a-z0-9-]*\.json$/.test(manifest.projectStories)) { throw new Error('projectStories must be a JSON filename in campaigns/'); } + if (manifest.beliefDecisions && !/^[a-z0-9][a-z0-9-]*\.json$/.test(manifest.beliefDecisions)) { + throw new Error('beliefDecisions must be a JSON filename in campaigns/'); + } validateCauses(manifest); validatePersonas(manifest); validateActionRules(manifest); diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json b/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json index 992dbce5..b92d2c55 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json @@ -1,5 +1,5 @@ { - "note": "Authored persona decisions for batch 2. The planner still draws set-belief on its own. Unsigned is not the same as an explicit rejection. Sixteen modified-to-commonality arrows are allowed. The four abortion and schools arrows keep accepted-bridge-role-pair. The twelve draft arrows use live-attester-modified-to-commonality from campaigns/network-societies-v1-b2-implication-evaluations.json (deepseek/deepseek-v3.2, 2026-10-16). Designed-no pairs in that file stay unpublished. v4-flash returned empty content on longer pairs and was not used as a judgment.", + "note": "Authored persona decisions for batch 2. The planner pins each signs and rejects entry as one set-belief and does not overwrite it. Unsigned is not the same as an explicit rejection. Eli's rejection of the abortion commonality is authoring intent. Sixteen modified-to-commonality arrows are allowed. The four abortion and schools arrows keep accepted-bridge-role-pair. The twelve draft arrows use live-attester-modified-to-commonality from campaigns/network-societies-v1-b2-implication-evaluations.json (deepseek/deepseek-v3.2, 2026-10-16). Designed-no pairs in that file stay unpublished. v4-flash returned empty content on longer pairs and was not used as a judgment. Delegated spending and a monthly pledge stay out of this campaign: the adapter can delegate and revoke a note, and Pat already does that with Ned, but nothing spends a delegated note or repeats a pledge.", "people": [ { "userId": "user-041", "name": "Mara", "signs": ["modified-left", "commonality"], "rejects": ["no-early-abortions"], "unsigned": ["michigan-legislature", "one-federal-rule"], "notes": "The settlement signature is not a signature about which legislature writes the rule." }, { "userId": "user-052", "name": "Eli", "signs": ["natural-right"], "rejects": ["modified-right", "commonality", "modified-left"], "notes": "Keeps the natural position and refuses the settlement. He must not be treated as a supporter of the cutoff through an arrow from natural-right." }, diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.json b/fake-data-generation/campaigns/network-societies-v1-b2.json index fc36aad2..0a911e9e 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2.json @@ -24,6 +24,7 @@ "allowRepeatedStatementRefs": true }, "projectStories": "network-societies-v1-b2-projects.json", + "beliefDecisions": "network-societies-v1-b2-decisions.json", "causes": [ { "id": "crypto-merchants", diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.md b/fake-data-generation/campaigns/network-societies-v1-b2.md index d64fbd7d..4a1ed58a 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2.md +++ b/fake-data-generation/campaigns/network-societies-v1-b2.md @@ -22,9 +22,9 @@ Sixteen implication actions are planned. Four are the accepted abortion and scho `moderator-checklist` is one statement. It is on the Michigan authority board and the Owen Sound voting board. One project, "Moderator checklist card", references it. -Persona decisions in that file are still not applied to `set-belief`. Eli's refusal of the settlement is authoring intent. The planner can still have him believe the commonality sentence. +The manifest points `beliefDecisions` at that file. Each `signs` entry is one `believe` write and each `rejects` entry is one `disbelieve` write. Those pairs are not drawn again, so Eli never believes the abortion commonality. Unsigned statements stay unpinned. -Delegated spending and a recurring monthly pledge are still not campaign actions. +Delegated spending and a recurring monthly pledge stay out. Pat already delegates a note to Ned, and the adapter can revoke a delegation. No action spends a delegated note or repeats a pledge, and no persona in this manifest is written as doing either. ## Reproduce the plan @@ -46,4 +46,4 @@ OpenCode Go DeepSeek ids (`deepseek-v4-flash`, `deepseek-v4.1-flash`, `deepseek- The Grey County assimilation commonality board is `http://commonality.localhost:8088/#/cause/0xEe6a18208ca061e2Eddd4A6fA7E4E4d4927eF352/network-societies-v1-b2-grey-assimilation-bridge`. Its statement page shows "Arriving through other statements." Direct and indirect counts were 0 on that load because the visible sentence had no signers yet. -Persona `set-belief` choices are still not applied. Delegated spending and a recurring monthly pledge are still not campaign actions. The six clusters are not accepted seed. +A plan built after the belief pins is not the plan that mined. `output/campaigns/network-societies-v1-b2/` keeps that executed run. Rewriting it would mark the wallets unprovisioned. The next chain run needs a new output directory. Delegated spending and a monthly pledge stay out. The six clusters are not accepted seed. The remaining brainstorm families stay unauthored where they already share a concrete want with a published board. diff --git a/fake-data-generation/test/campaignPlanner.test.ts b/fake-data-generation/test/campaignPlanner.test.ts index 0e2b70a8..f1a538c4 100644 --- a/fake-data-generation/test/campaignPlanner.test.ts +++ b/fake-data-generation/test/campaignPlanner.test.ts @@ -286,6 +286,33 @@ test('batch 2 keeps the pilot families, reuses accepted bridges, and shares one } }); +test('batch 2 pins persona belief choices and never has Eli believe the settlement', async () => { + const manifest = JSON.parse(await readFile(new URL('../campaigns/network-societies-v1-b2.json', import.meta.url), 'utf8')) as CampaignManifestV1; + const decisions = JSON.parse(await readFile(new URL('../campaigns/network-societies-v1-b2-decisions.json', import.meta.url), 'utf8')) as { + people: { userId: string; name: string; signs?: string[]; rejects?: string[]; unsigned?: string[] }[]; + }; + const plan = await buildCampaignPlan(manifest); + const beliefs = plan.actions.filter((action) => action.type === 'set-belief'); + assert.equal(beliefs.length, 90); + const byStatementId = (sourceId: string, userId: string) => beliefs.filter((action) => { + const statement = plan.statements.find((item) => item.id === action.statementId); + return action.actorUserId === userId && statement?.source.statementId === sourceId; + }); + for (const person of decisions.people) { + for (const statementId of person.signs ?? []) { + const actions = byStatementId(statementId, person.userId); + assert.deepEqual(actions.map((action) => action.belief), ['believe'], `${person.name} ${statementId}`); + } + for (const statementId of person.rejects ?? []) { + const actions = byStatementId(statementId, person.userId); + assert.deepEqual(actions.map((action) => action.belief), ['disbelieve'], `${person.name} ${statementId}`); + } + } + const eli = plan.users.find((user) => user.displayName === 'Eli')!; + const settlement = plan.statements.find((statement) => statement.source.collectionId === 'compromise-abortion' && statement.source.statementId === 'commonality')!; + assert.equal(beliefs.some((action) => action.actorUserId === eli.id && action.statementId === settlement.id && action.belief === 'believe'), false); +}); + test('written planning artifacts reload into the same campaign plan', async () => { const manifest = await loadManifest(); const plan = await buildCampaignPlan(manifest); From 7570520296c38cdd7cd99588147dcf0905578f77 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 17:46:12 -0400 Subject: [PATCH 14/19] Add an AI-pause board with milder wordings and dissenters. The shared sentence is a treaty that pauses new capabilities research while work on catastrophic harm continues. Five modified statements contain that sentence and keep their own reason. Naturals do not name the treaty. Hal rejects the pause as too soft, and Vic rejects it outright. Implication pairs stay unevaluated and unpublished. --- .../network-societies-campaign-plan.md | 2 +- .../network-societies-v1-b2-decisions.json | 22 ++- .../network-societies-v1-b2-projects.json | 32 ++++ .../network-societies-v1-b2-statements.json | 82 ++++++++++ .../campaigns/network-societies-v1-b2.json | 150 ++++++++++++++++-- .../campaigns/network-societies-v1-b2.md | 4 +- .../test/campaignPlanner.test.ts | 6 +- 7 files changed, 276 insertions(+), 22 deletions(-) diff --git a/fake-data-generation/brainstorming/network-societies-campaign-plan.md b/fake-data-generation/brainstorming/network-societies-campaign-plan.md index 547c8654..14e0d8a5 100644 --- a/fake-data-generation/brainstorming/network-societies-campaign-plan.md +++ b/fake-data-generation/brainstorming/network-societies-campaign-plan.md @@ -14,7 +14,7 @@ The planner now pins batch-2 `signs` and `rejects` from the decisions file. Eli' **Decided out of this campaign for now.** Delegated spending and a recurring monthly pledge. Pat already delegates a note, and revocation is a real action. Nothing spends a delegated note or repeats a pledge. Journey 5 below is therefore only partly demonstrated, and the "$20/month" filter is still a product gap. -**Not started as families.** Eight of the fifteen rows below are not campaign manifests: low-carb, cancel-proof support, unwoke, Democracy 2.0, AI safety, US-friendly Canadians beyond the five-statement draft bridge, Islamic reform, and less regulation. Home learning and Grey County civic life stop at the pilot planks. Do not force a new triple onto an overlap that already shares a concrete want. The campaign note already treats several of these as overlaps. +**Not started as families.** Seven of the fifteen rows below are not campaign manifests: low-carb, cancel-proof support, unwoke, Democracy 2.0, US-friendly Canadians beyond the five-statement draft bridge, Islamic reform, and less regulation. AI safety is a plain board in batch 2 (`ai-pause`): a shared pause-treaty sentence, milder wordings that contain it, naturals that do not, a full-stop refusal, and an accelerationist refusal. Those implication pairs are unevaluated and unpublished. Home learning and Grey County civic life stop at the pilot planks. Do not force a new triple onto an overlap that already shares a concrete want. The campaign note already treats several of these as overlaps. **Journeys.** Direct shared agreement and one reused statement on two boards are in the pilot. A declined bridge is authored for batch 2 (Eli) and is in the new plan, not in the mined output. Verified implication paths are planned for batch 2. Early-risk reimbursement, a friend actually spending a delegated note, recurring pledges, and the independent-reviewer walkthrough are not campaign demonstrations yet. diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json b/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json index b92d2c55..0ec7d1c4 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json @@ -6,7 +6,14 @@ { "userId": "user-054", "name": "Bea", "signs": ["michigan-legislature"], "unsigned": ["commonality", "modified-left", "modified-right"], "rejects": ["one-federal-rule"], "notes": "State-level authority is a separate proposition from the 12-16 week sentence." }, { "userId": "user-053", "name": "Jo", "signs": ["commonality"], "rejects": ["no-medical-limit"], "notes": "The schools commonality she means is the accepted conditional about pushing. It is not a position on drugs or surgery." }, { "userId": "user-042", "name": "Nina", "signs": ["natural-left", "harassment-steps", "names-and-courtesy"], "rejects": ["no-medical-limit"], "unsigned": ["clinician-for-minors"] }, - { "userId": "user-043", "name": "Wes", "signs": ["ranked-poll", "approval-count", "keep-fptp", "moderator-checklist"], "rejects": ["show-of-hands"], "notes": "A non-binding poll and keeping first-past-the-post for municipal elections are compatible. Refusing the poll is the incompatible position." } + { "userId": "user-043", "name": "Wes", "signs": ["ranked-poll", "approval-count", "keep-fptp", "moderator-checklist"], "rejects": ["show-of-hands"], "notes": "A non-binding poll and keeping first-past-the-post for municipal elections are compatible. Refusing the poll is the incompatible position." }, + { "userId": "user-061", "name": "Priya", "signs": ["modified-small-chance", "commonality"], "rejects": ["pole-stop"], "unsigned": ["natural-small-chance", "pole-accelerate"], "notes": "Will not sign certain doom. The small-chance modified already contains the shared pause sentence. No arrow is published." }, + { "userId": "user-062", "name": "Dean", "signs": ["natural-jobs", "modified-jobs", "commonality"], "rejects": ["pole-stop"], "unsigned": ["modified-small-chance"], "notes": "Jobs, not extinction. Signing the shared sentence is not a signature of the small-chance odds." }, + { "userId": "user-063", "name": "Noor", "signs": ["natural-industry"], "unsigned": ["modified-industry", "commonality", "pole-stop"], "notes": "Has the warning and has not taken the treaty. A nudge target, not an implied supporter." }, + { "userId": "user-064", "name": "Sam", "signs": ["modified-not-luddite", "commonality"], "unsigned": ["pole-stop", "natural-not-luddite"], "notes": "Not a Luddite. The modified keeps that limit; the shared sentence does not." }, + { "userId": "user-065", "name": "Tess", "signs": ["natural-children"], "unsigned": ["modified-children", "commonality"], "notes": "Has the complaint about executives and has not signed the treaty." }, + { "userId": "user-066", "name": "Hal", "signs": ["pole-stop"], "rejects": ["commonality", "modified-small-chance"], "notes": "Wants a full stop. The pause-while-alignment sentence is a refusal, not an unsigned item." }, + { "userId": "user-067", "name": "Vic", "signs": ["pole-accelerate"], "rejects": ["commonality", "modified-small-chance", "modified-jobs"], "notes": "Rejects the pause. He is not a supporter through any arrow." } ], "implicationCandidates": { "published": [ @@ -38,7 +45,18 @@ { "from": "commonality", "to": "michigan-legislature", "why": "Agreement on a cutoff does not imply who should have the authority to write it." }, { "from": "natural-right", "to": "commonality", "why": "Designed negative for the abortion bridge. Eli keeps this side." }, { "from": "lgbt-schools/commonality", "to": "clinician-for-minors", "why": "The schools conditional does not settle medical treatment." }, - { "from": "ranked-poll", "to": "keep-fptp", "why": "Wanting a non-binding poll does not imply a position on municipal elections, in either direction." } + { "from": "ranked-poll", "to": "keep-fptp", "why": "Wanting a non-binding poll does not imply a position on municipal elections, in either direction." }, + { "from": "ai-pause/modified-small-chance", "to": "ai-pause/commonality", "why": "Draft. The modified contains the shared pause sentence plus a limit the shared sentence omits. Not sent to the attester. Unpublished." }, + { "from": "ai-pause/modified-jobs", "to": "ai-pause/commonality", "why": "Draft. Same shared sentence, jobs priority omitted from the commonality. Unpublished." }, + { "from": "ai-pause/modified-industry", "to": "ai-pause/commonality", "why": "Draft. Unpublished." }, + { "from": "ai-pause/modified-not-luddite", "to": "ai-pause/commonality", "why": "Draft. Unpublished." }, + { "from": "ai-pause/modified-children", "to": "ai-pause/commonality", "why": "Draft. Unpublished." }, + { "from": "ai-pause/natural-small-chance", "to": "ai-pause/commonality", "why": "Designed negative. The natural does not name the treaty." }, + { "from": "ai-pause/natural-jobs", "to": "ai-pause/commonality", "why": "Designed negative. Job loss does not name the treaty." }, + { "from": "ai-pause/pole-stop", "to": "ai-pause/commonality", "why": "Designed negative. Hal's full stop rejects a pause that keeps alignment work going." }, + { "from": "ai-pause/pole-accelerate", "to": "ai-pause/commonality", "why": "Designed negative. Vic rejects the pause." }, + { "from": "ai-pause/commonality", "to": "ai-pause/modified-small-chance", "why": "Designed negative. The shared sentence does not include the odds or the refusal to say extinction is certain." }, + { "from": "ai-pause/commonality", "to": "ai-pause/modified-jobs", "why": "Designed negative. The shared sentence does not include the jobs priority." } ] } } diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-projects.json b/fake-data-generation/campaigns/network-societies-v1-b2-projects.json index 27713d52..83c59443 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-projects.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-projects.json @@ -447,5 +447,37 @@ "statementRefs": ["modified-left", "modified-right", "commonality"], "blocker": "Without both wordings, one camp hears the page as praise and the other hears it as a boycott refusal they did not sign" } + ], + "ai-pause": [ + { + "title": "Pause-treaty petition packet", + "outcome": "Publish the petition text, the governments it is addressed to, and a running signature count for one year. The packet includes the shared pause sentence and does not claim a government has agreed.", + "statementRefs": ["treaty-petition", "commonality"], + "blocker": "A petition nobody maintains becomes a slogan, and no single signer is paid to keep the count honest" + }, + { + "title": "Small-chance explainer", + "outcome": "Publish a plain-language brief that states the small-chance modified sentence beside the shared pause sentence, so a reader can see what the shorter sentence does not claim.", + "statementRefs": ["modified-small-chance", "commonality"], + "blocker": "The milder wording is useful only if someone writes it down where the certain-doom sentence is not the only text on offer" + }, + { + "title": "Checkable alignment note", + "outcome": "Commission one note on a published idea for keeping a more capable system from doing catastrophic harm. The note states the method, the result, and what was not shown. It does not claim the problem is solved.", + "statementRefs": ["alignment-note"], + "blocker": "A second person cannot check a safety claim that lives in a lab notebook nobody else is paid to read" + }, + { + "title": "One-year warning digest", + "outcome": "For one year, publish a digest of public warnings from people who work on AI, each with a date and a source, and no claim added beyond the source.", + "statementRefs": ["warning-digest"], + "blocker": "The warnings are scattered, and no newsroom is paid to keep a list that refuses to sharpen them" + }, + { + "title": "Pause-meeting host kit", + "outcome": "Write the agenda, the two sentences to read aloud, and the handoff steps so a second host can run the next meeting without the first host.", + "statementRefs": ["pause-host-kit", "commonality"], + "blocker": "The meeting stops when the first host is busy unless the hosting steps are written down" + } ] } diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-statements.json b/fake-data-generation/campaigns/network-societies-v1-b2-statements.json index d7c6d723..5667a33c 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-statements.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-statements.json @@ -379,6 +379,88 @@ { "id": "modified-right", "role": "modified-right", "text": "I want Canadians to keep buying ordinary goods from US businesses and visiting family in the US. Ordinary Canadians should keep buying from US businesses and visiting family in the US. This is not a statement about the current US administration. I'd still rather Canada also keep shared border staffing and ordinary military exercises with the US. I feel more strongly about purchases and family visits than about those, and I am not asking anyone to praise the administration." }, { "id": "commonality", "role": "commonality", "text": "Ordinary Canadians should keep buying from US businesses and visiting family in the US. This is not a statement about the current US administration." } ] + }, + { + "id": "ai-pause", + "title": "Pause new AI capabilities research while work on catastrophic harm continues", + "notes": [ + "Different problems, same limited ask. The shared sentence is the treaty pause. Each milder statement keeps a reason the shared sentence does not contain, so signing the short sentence is not a signature of extinction, of job loss, or of contempt for executives.", + "Naturals are how someone talks before they have accepted the treaty. Modifieds add that ask. Poles do not contain it. No implication arrow is published: the pairs have not been given to the attester.", + "The shared sentence is: I'd be okay with an international treaty that pauses new research aimed at making AI systems more capable, for the length of that pause, while work continues on how to keep a more capable system from doing catastrophic harm. I'm not saying every current software tool has to be switched off." + ], + "statements": [ + { + "id": "commonality", + "role": "commonality", + "text": "I'd be okay with an international treaty that pauses new research aimed at making AI systems more capable, for the length of that pause, while work continues on how to keep a more capable system from doing catastrophic harm. I'm not saying every current software tool has to be switched off." + }, + { + "id": "natural-small-chance", + "text": "You don't have to be sure that a more capable AI will wipe us out. Even a small chance, something like one percent or ten percent, would be an absurd risk to take in any other context." + }, + { + "id": "modified-small-chance", + "role": "modified-left", + "text": "I'm not willing to say that a more capable AI is going to wipe us out. I don't need that certainty. Even a small chance of it, something on the order of one or five or ten percent, is an absurd risk to take with everyone's lives. I'd be okay with an international treaty that pauses new research aimed at making AI systems more capable, for the length of that pause, while work continues on how to keep a more capable system from doing catastrophic harm. I'm not saying every current software tool has to be switched off. Signing this is not me joining the people who are already sure." + }, + { + "id": "natural-jobs", + "text": "AI is going to lead to massive job loss. That is not worth it." + }, + { + "id": "modified-jobs", + "role": "modified-right", + "text": "What I actually lose sleep over is the jobs. A race to more capable AI looks like a lot of people thrown out of work for a gain I didn't ask for. I'm not claiming I know the chance of extinction. I'd be okay with an international treaty that pauses new research aimed at making AI systems more capable, for the length of that pause, while work continues on how to keep a more capable system from doing catastrophic harm. I'm not saying every current software tool has to be switched off. The pause is the part I came for. The work on catastrophic harm is not my reason." + }, + { + "id": "natural-industry", + "text": "An increasing number of people inside the AI industry are warning that pushing further has potentially catastrophic consequences." + }, + { + "id": "modified-industry", + "text": "An increasing number of people who work on these systems are warning that pushing capability further could be catastrophic. I don't build the systems, and I'm not going to pretend I can check their math, but I don't think we should ignore them. I'd be okay with an international treaty that pauses new research aimed at making AI systems more capable, for the length of that pause, while work continues on how to keep a more capable system from doing catastrophic harm. I'm not saying every current software tool has to be switched off. Hearing the warning is not the same as being sure we all die." + }, + { + "id": "natural-not-luddite", + "text": "I'm not a Luddite, but I'm not blindly in favour of all technology either. This just isn't worth the risk." + }, + { + "id": "modified-not-luddite", + "text": "I'm not a Luddite, and I'm not against technology in general. Plenty of tools are worth having. A race to more capable AI is a different thing, and I don't think the upside covers the risk. I'd be okay with an international treaty that pauses new research aimed at making AI systems more capable, for the length of that pause, while work continues on how to keep a more capable system from doing catastrophic harm. I'm not saying every current software tool has to be switched off. This isn't a request to smash the machines we already use." + }, + { + "id": "natural-children", + "text": "These tech executives are gambling with my children's lives." + }, + { + "id": "modified-children", + "text": "I don't trust a handful of tech executives to keep gambling with my children's lives. They can be wrong and still get rich. I'd be okay with an international treaty that pauses new research aimed at making AI systems more capable, for the length of that pause, while work continues on how to keep a more capable system from doing catastrophic harm. I'm not saying every current software tool has to be switched off. My complaint is about who is taking the risk, not a claim that I want every program unplugged." + }, + { + "id": "pole-stop", + "text": "A superintelligent AI is going to kill us. The work should just stop. A treaty that pauses new capability research while alignment work continues is not enough, because the same labs will keep going the moment the pause slips." + }, + { + "id": "pole-accelerate", + "text": "We should not pause AI capabilities research. Falling behind other labs and other countries is the danger I actually take seriously." + }, + { + "id": "treaty-petition", + "text": "I want a public petition that asks governments to negotiate an international treaty pausing new research aimed at making AI systems more capable, while work on catastrophic harm continues, and I want the petition text and the signature count published." + }, + { + "id": "alignment-note", + "text": "I want a published piece of work on how to keep a more capable AI system from doing catastrophic harm, with the method and the result written so a second person can check them, and without a claim that the problem has been solved." + }, + { + "id": "warning-digest", + "text": "I want a one-year digest that lists public warnings from people who work on AI, with the date and the source, and that does not add a claim the source did not make." + }, + { + "id": "pause-host-kit", + "text": "I want a written host kit so a second person can run a meeting about that pause treaty without the first host." + } + ] } ] } diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.json b/fake-data-generation/campaigns/network-societies-v1-b2.json index 0a911e9e..b3249cfd 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2.json @@ -2,9 +2,9 @@ "schema": "commonality-testnet-campaign-v1", "campaign": { "id": "network-societies-v1-b2", - "label": "Network societies batch 2 — pilot families, accepted bridges, and six unevaluated draft bridges", + "label": "Network societies batch 2 — pilot families, accepted bridges, six unevaluated draft bridges, and an AI-pause board", "syntheticDataLabel": "SYNTHETIC CAMPAIGN — NOT REAL USERS, ORGANIZATIONS, OR DELIVERABLES", - "userCount": 60, + "userCount": 67, "deterministicSeed": "commonality-network-societies-v1-b2-2026-10-16", "randomAlgorithm": "xoshiro128**" }, @@ -17,10 +17,10 @@ "campaignCollection": "network-societies-v1-b2-statements.json" }, "scale": { - "minCauses": 15, - "maxCauses": 15, - "minStatements": 100, - "maxStatements": 100, + "minCauses": 16, + "maxCauses": 16, + "minStatements": 117, + "maxStatements": 117, "allowRepeatedStatementRefs": true }, "projectStories": "network-societies-v1-b2-projects.json", @@ -540,6 +540,31 @@ { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "modified-right" }, { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "commonality" } ] + }, + { + "id": "ai-pause", + "title": "Pause AI capabilities research", + "activityTier": "medium", + "membershipWeight": 8, + "statementRefs": [ + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "commonality" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "natural-small-chance" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "modified-small-chance" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "natural-jobs" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "modified-jobs" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "natural-industry" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "modified-industry" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "natural-not-luddite" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "modified-not-luddite" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "natural-children" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "modified-children" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "pole-stop" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "pole-accelerate" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "treaty-petition" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "alignment-note" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "warning-digest" }, + { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "pause-host-kit" } + ] } ], "personas": [ @@ -690,6 +715,21 @@ "activityWeight": 1, "inactivityRate": 0, "fundingWeight": 1 + }, + { + "id": "ai-pause-voice", + "count": 7, + "roles": [ + "project-founder", + "supporter" + ], + "causesPerUser": { + "min": 1, + "max": 1 + }, + "activityWeight": 1.5, + "inactivityRate": 0, + "fundingWeight": 1 } ], "userProfiles": [ @@ -1069,6 +1109,88 @@ "abortion-forum" ], "spotlightOrder": 24 + }, + { + "userId": "user-061", + "displayName": "Priya", + "bio": "Will not sign a claim that superintelligent AI is going to kill us. She will sign the small-chance wording and the shared pause sentence.", + "favoriteCauseId": "ai-pause", + "interests": [ + "small chance", + "pause treaty" + ], + "causeIds": ["ai-pause"], + "spotlightOrder": 25 + }, + { + "userId": "user-062", + "displayName": "Dean", + "bio": "Came in worried about jobs, not extinction. He signs the jobs wording and the shared pause sentence, and he does not sign the certain-doom sentence.", + "favoriteCauseId": "ai-pause", + "interests": [ + "job loss", + "pause treaty" + ], + "causeIds": ["ai-pause"], + "spotlightOrder": 26 + }, + { + "userId": "user-063", + "displayName": "Noor", + "bio": "Repeats the industry warnings and has not signed the treaty. Someone can point her at the industry modified sentence.", + "favoriteCauseId": "ai-pause", + "interests": [ + "industry warnings" + ], + "causeIds": ["ai-pause"], + "spotlightOrder": 27 + }, + { + "userId": "user-064", + "displayName": "Sam", + "bio": "Says he is not a Luddite. He signs the not-a-Luddite wording and the shared pause sentence, and he leaves the certain-doom sentence unsigned.", + "favoriteCauseId": "ai-pause", + "interests": [ + "technology", + "risk" + ], + "causeIds": ["ai-pause"], + "spotlightOrder": 28 + }, + { + "userId": "user-065", + "displayName": "Tess", + "bio": "Talks about executives gambling with her children's lives. She has not signed the treaty yet.", + "favoriteCauseId": "ai-pause", + "interests": [ + "children", + "executives" + ], + "causeIds": ["ai-pause"], + "spotlightOrder": 29 + }, + { + "userId": "user-066", + "displayName": "Hal", + "bio": "Wants the work to just stop. He rejects the pause-while-alignment sentence as too soft.", + "favoriteCauseId": "ai-pause", + "interests": [ + "extinction", + "full stop" + ], + "causeIds": ["ai-pause"], + "spotlightOrder": 30 + }, + { + "userId": "user-067", + "displayName": "Vic", + "bio": "Thinks a pause is the dangerous move because other labs will not stop. He rejects the shared pause sentence and the small-chance wording.", + "favoriteCauseId": "ai-pause", + "interests": [ + "capabilities race" + ], + "causeIds": ["ai-pause"], + "spotlightOrder": 31 } ], "implicationAllowances": [ @@ -1094,8 +1216,8 @@ "type": "publish-statement", "prerequisites": [], "targetCount": { - "min": 100, - "max": 100 + "min": 117, + "max": 117 } }, { @@ -1104,8 +1226,8 @@ "publish-statement" ], "targetCount": { - "min": 15, - "max": 15 + "min": 16, + "max": 16 } }, { @@ -1134,8 +1256,8 @@ "create-cause" ], "targetCount": { - "min": 52, - "max": 52 + "min": 57, + "max": 57 } }, { @@ -1145,8 +1267,8 @@ "publish-statement" ], "targetCount": { - "min": 40, - "max": 40 + "min": 57, + "max": 57 } }, { diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.md b/fake-data-generation/campaigns/network-societies-v1-b2.md index 4a1ed58a..9747ee9a 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2.md +++ b/fake-data-generation/campaigns/network-societies-v1-b2.md @@ -8,11 +8,11 @@ Keeps the four pilot families (Owen Sound checkout, Grey County civic life, Chri - Schools and pushing, using the accepted `lgbt-schools` wording unchanged, plus a separate Grey County conduct board. The schools statements do not settle drugs, surgery, or classroom names. - An Owen Sound non-binding voting trial. -The other eight families in the brainstorming plan are not in this manifest. +The other families in the brainstorming plan are not in this manifest, except an AI-pause board. That board is plain: every sentence stays visible. Five milder modified sentences contain one shared pause-treaty sentence and each keeps a reason the shared sentence leaves out. Naturals do not name the treaty. Hal wants a full stop and rejects the pause. Vic rejects the pause because other labs will not stop. No AI-pause implication is in the allowance list. Those pairs are unevaluated. ## What the plan publishes -A plan written on 2026-10-16 has 60 users, 100 statements, 52 projects. Seed: `commonality-network-societies-v1-b2-2026-10-16`. Regenerate the plan before quoting a write count. The old 356-write figure was for 70 statements and 40 projects. +A plan written on 2026-10-16 has 67 users, 117 statements, 57 projects. The earlier mined run was 60 users, 100 statements, and 52 projects. Seed: `commonality-network-societies-v1-b2-2026-10-16`. Regenerate the plan before quoting a write count. The old 356-write figure was for 70 statements and 40 projects. The abortion cause and the schools cause are bridge-shaped. Each main board lists only the accepted commonality sentence. The natural and modified sentences are on the side boards. The Michigan authority board and the Grey County conduct board are ordinary boards, so their own sentences stay visible there. diff --git a/fake-data-generation/test/campaignPlanner.test.ts b/fake-data-generation/test/campaignPlanner.test.ts index f1a538c4..20963411 100644 --- a/fake-data-generation/test/campaignPlanner.test.ts +++ b/fake-data-generation/test/campaignPlanner.test.ts @@ -240,9 +240,9 @@ test('batch 2 keeps the pilot families, reuses accepted bridges, and shares one assert.deepEqual(copy.statements, group.statements); } const plan = await buildCampaignPlan(manifest); - assert.equal(plan.users.length, 60); - assert.equal(plan.statements.length, 100); - assert.equal(plan.projects.length, 52); + assert.equal(plan.users.length, 67); + assert.equal(plan.statements.length, 117); + assert.equal(plan.projects.length, 57); const checklist = plan.statements.find((statement) => statement.source.statementId === 'moderator-checklist'); assert.ok(checklist); assert.equal(checklist!.causeId, 'abortion-forum'); From 702c8ce0ef4d57f522f87a9ad1281df3fc69a9a9 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 17:49:13 -0400 Subject: [PATCH 15/19] Record the handoff for the AI-pause board and the families still missing. --- .../2026-10-16-ai-pause-board-handoff.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 continuity/2026-10-16-ai-pause-board-handoff.md diff --git a/continuity/2026-10-16-ai-pause-board-handoff.md b/continuity/2026-10-16-ai-pause-board-handoff.md new file mode 100644 index 00000000..669b2551 --- /dev/null +++ b/continuity/2026-10-16-ai-pause-board-handoff.md @@ -0,0 +1,33 @@ +# Handoff: AI-pause board, then the rest of the network-societies campaign + +Next session: finish the AI-pause cause, then keep authoring the families that are still missing. Do not publish an implication the attester has not blessed. Do not write a new plan over `fake-data-generation/output/campaigns/network-societies-v1-b2/`. + +## Read first + +- [`fake-data-generation/campaigns/network-societies-v1-b2.md`](../fake-data-generation/campaigns/network-societies-v1-b2.md) — what batch 2 publishes, and the rule that the mined directory is the pre-pin plan. +- [`fake-data-generation/campaigns/network-societies-v1-b2-statements.json`](../fake-data-generation/campaigns/network-societies-v1-b2-statements.json) group `ai-pause`, and the matching people in [`network-societies-v1-b2-decisions.json`](../fake-data-generation/campaigns/network-societies-v1-b2-decisions.json). +- [`fake-data-generation/brainstorming/network-societies-campaign-plan.md`](../fake-data-generation/brainstorming/network-societies-campaign-plan.md) — which families are still not manifests, and the attester quality gate. +- [`specs/product/statements-are-peculiar-for-good-reasons.md`](../specs/product/statements-are-peculiar-for-good-reasons.md) — containment versus nudge. The AI-pause modifieds were written to that rule. They have not been checked by the model. +- Branch `campaign`, not pushed. This slice is `75705202` ("Add an AI-pause board with milder wordings and dissenters."). Parent is `dd3578dc`. + +## What is already true + +The cause is one plain board, `ai-pause`, so every sentence stays on it. It is not bridge-shaped: the five bridge roles are not all present, and nothing was added to `implicationAllowances`. The planner therefore publishes no AI-pause arrow. + +The shared sentence is a treaty that pauses new research aimed at making AI systems more capable, for the length of that pause, while work on catastrophic harm continues, and that does not switch off current tools. Five modified statements contain that sentence and keep a reason the short sentence omits: small chance, jobs, industry warnings, not-a-Luddite, children. Naturals do not name the treaty. `pole-stop` (Hal) and `pole-accelerate` (Vic) reject the pause. Noor and Tess are nudge targets: they signed a natural and left the treaty unsigned. + +Seven spotlight users are `user-061` through `user-067` (Priya, Dean, Noor, Sam, Tess, Hal, Vic), persona `ai-pause-voice`. Five projects are in `network-societies-v1-b2-projects.json` under `ai-pause`. Scale is 16 causes, 117 statements, 67 users, 57 projects. Alignment attestations were raised from 40 to 57 so the new projects can be funded. `npx tsx --test test/campaignPlanner.test.ts` passed before the commit. The commit hook's fast suite passed. + +The mined run in `output/campaigns/network-societies-v1-b2/` is still the older 60-user, 100-statement, 52-project plan. Rewriting that directory would mark its wallets unprovisioned. + +## What to do + +1. Run the real implication attester on the AI-pause candidate pairs listed under `unevaluatedAndUnpublished` in the decisions file. Same bar as the six draft bridges: store text hashes, prompt fingerprint, model, and decision in an evaluations file; publish only affirmative modified-to-commonality blesses, as `live-attester-modified-to-commonality`. Designed negatives (naturals, poles, and commonality back to a modified) must stay unpublished. If a designed-yes fails or a designed-no passes, rewrite the prose, up to three tries, and keep the failures in the authoring record. The planner only emits an arrow for `modified-left` and `modified-right`. The other three modifieds can be blessed and still need a planner change before they become arrows. Do not pretend a bless of those three is already on the board. +2. After any allowance change, regenerate the plan into a new output directory. Leave `output/campaigns/network-societies-v1-b2/` alone. A local execute is optional and needs the existing runner, a fresh directory, and the alignment-trust bootstrap funded if the chain was wiped. +3. Then author the next family batch. Still not manifests: low-carb, cancel-proof support, unwoke, Democracy 2.0, Islamic reform, less regulation, and US-friendly Canadians beyond the five-statement Canada–US draft. Home learning and Grey County civic life stop at the pilot planks. Do not force a new triple onto an overlap that already shares a concrete want. The campaign plan's "Next task" paragraph still says eight families and should be corrected when the next batch lands. +4. Delegated spending and a recurring monthly pledge stay out. Do not start a bulk random run. + +## Suggested skills + +- `thorough-tester` — after an attester pass, check that Hal and Vic are not supporters of the pause through an arrow, and that Noor and Tess stay unsigned on the treaty. +- `browser-driving` — only after a fresh local execute. Open the AI-pause board and confirm the milder sentences are visible next to the shared sentence. From c72c768f3ac4a429a9c5980c3435c338bc7c7b73 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 17:59:18 -0400 Subject: [PATCH 16/19] Allow the five AI-pause modifieds the attester blessed. deepseek-v3.2 blessed each milder sentence toward the shared pause and refused the naturals, poles, and reverse arrows. The planner now plans those plain-board arrows. The mined output directory was not rewritten. --- .../2026-10-16-ai-pause-board-handoff.md | 14 +- fake-data-generation/PLAN.md | 2 +- .../network-societies-campaign-plan.md | 8 +- fake-data-generation/campaignPlanner.ts | 12 +- .../network-societies-v1-b2-decisions.json | 32 +-- ...cieties-v1-b2-implication-evaluations.json | 194 +++++++++++++++++- .../network-societies-v1-b2-statements.json | 2 +- .../campaigns/network-societies-v1-b2.json | 11 +- .../campaigns/network-societies-v1-b2.md | 8 +- .../test/campaignPlanner.test.ts | 27 ++- 10 files changed, 265 insertions(+), 45 deletions(-) diff --git a/continuity/2026-10-16-ai-pause-board-handoff.md b/continuity/2026-10-16-ai-pause-board-handoff.md index 669b2551..60e4876f 100644 --- a/continuity/2026-10-16-ai-pause-board-handoff.md +++ b/continuity/2026-10-16-ai-pause-board-handoff.md @@ -1,6 +1,6 @@ # Handoff: AI-pause board, then the rest of the network-societies campaign -Next session: finish the AI-pause cause, then keep authoring the families that are still missing. Do not publish an implication the attester has not blessed. Do not write a new plan over `fake-data-generation/output/campaigns/network-societies-v1-b2/`. +Next session: author the families that are still missing. The AI-pause attester pass is done. Do not publish an implication the attester has not blessed. Do not write a new plan over `fake-data-generation/output/campaigns/network-societies-v1-b2/` or over `output/campaigns/network-societies-v1-b2-ai-pause/` if that directory is later executed. ## Read first @@ -12,7 +12,7 @@ Next session: finish the AI-pause cause, then keep authoring the families that a ## What is already true -The cause is one plain board, `ai-pause`, so every sentence stays on it. It is not bridge-shaped: the five bridge roles are not all present, and nothing was added to `implicationAllowances`. The planner therefore publishes no AI-pause arrow. +The cause is one plain board, `ai-pause`, so every sentence stays on it. It is not bridge-shaped: the five bridge roles are not all present. Five live-attester arrows are now in `implicationAllowances`. The planner allows a plain-board modified when the evidence label is `live-attester-modified-to-commonality`. The shared sentence is a treaty that pauses new research aimed at making AI systems more capable, for the length of that pause, while work on catastrophic harm continues, and that does not switch off current tools. Five modified statements contain that sentence and keep a reason the short sentence omits: small chance, jobs, industry warnings, not-a-Luddite, children. Naturals do not name the treaty. `pole-stop` (Hal) and `pole-accelerate` (Vic) reject the pause. Noor and Tess are nudge targets: they signed a natural and left the treaty unsigned. @@ -20,12 +20,14 @@ Seven spotlight users are `user-061` through `user-067` (Priya, Dean, Noor, Sam, The mined run in `output/campaigns/network-societies-v1-b2/` is still the older 60-user, 100-statement, 52-project plan. Rewriting that directory would mark its wallets unprovisioned. +## What is done (2026-10-16, later session) + +The eleven AI-pause pairs were sent to `evaluateImplicationWithLLM` on `deepseek/deepseek-v3.2`. All five designed-yes pairs blessed at high confidence, and all six designed-no pairs refused at high confidence, on the first wording. The rows are appended to `network-societies-v1-b2-implication-evaluations.json` (79 pairs, same prompt fingerprint). The five blesses are in `implicationAllowances`. The planner now accepts a live-attester modified whose statement id starts with `modified-` even when the board is plain, so the industry, not-a-Luddite, and children arrows are planned, not only `modified-left` and `modified-right`. `npx tsx --test test/campaignPlanner.test.ts` passed (15 tests). The fresh plan is `output/campaigns/network-societies-v1-b2-ai-pause/` (67 users, 117 statements, 57 projects, 491 writes). It was not executed. The mined directory was not rewritten. + ## What to do -1. Run the real implication attester on the AI-pause candidate pairs listed under `unevaluatedAndUnpublished` in the decisions file. Same bar as the six draft bridges: store text hashes, prompt fingerprint, model, and decision in an evaluations file; publish only affirmative modified-to-commonality blesses, as `live-attester-modified-to-commonality`. Designed negatives (naturals, poles, and commonality back to a modified) must stay unpublished. If a designed-yes fails or a designed-no passes, rewrite the prose, up to three tries, and keep the failures in the authoring record. The planner only emits an arrow for `modified-left` and `modified-right`. The other three modifieds can be blessed and still need a planner change before they become arrows. Do not pretend a bless of those three is already on the board. -2. After any allowance change, regenerate the plan into a new output directory. Leave `output/campaigns/network-societies-v1-b2/` alone. A local execute is optional and needs the existing runner, a fresh directory, and the alignment-trust bootstrap funded if the chain was wiped. -3. Then author the next family batch. Still not manifests: low-carb, cancel-proof support, unwoke, Democracy 2.0, Islamic reform, less regulation, and US-friendly Canadians beyond the five-statement Canada–US draft. Home learning and Grey County civic life stop at the pilot planks. Do not force a new triple onto an overlap that already shares a concrete want. The campaign plan's "Next task" paragraph still says eight families and should be corrected when the next batch lands. -4. Delegated spending and a recurring monthly pledge stay out. Do not start a bulk random run. +1. Author the next family batch. Still not manifests: low-carb, cancel-proof support, unwoke, Democracy 2.0, Islamic reform, less regulation, and US-friendly Canadians beyond the five-statement Canada–US draft. Home learning and Grey County civic life stop at the pilot planks. Do not force a new triple onto an overlap that already shares a concrete want. The campaign plan's "Next task" paragraph now says seven families. +2. Delegated spending and a recurring monthly pledge stay out. Do not start a bulk random run. Do not execute the AI-pause plan unless you mean to, and do not overwrite either existing output directory. ## Suggested skills diff --git a/fake-data-generation/PLAN.md b/fake-data-generation/PLAN.md index 9ea67f20..e28eae97 100644 --- a/fake-data-generation/PLAN.md +++ b/fake-data-generation/PLAN.md @@ -82,7 +82,7 @@ Do these in order unless Adam names a different one. Each item is a session-size The four-family pilot (crypto merchants, Grey County civic life, Christian teaching, home learning) is in [`campaigns/network-societies-v1-pilot.md`](./campaigns/network-societies-v1-pilot.md). A local run on 2026-10-16 mined and reconciled 207/207. Cause pages list the shared class-host directory once the alignment-trust bootstrap wallet has gas. -Batch 2 keeps those four families and adds the accepted abortion bridge, the accepted schools-pushing bridge, an Owen Sound voting trial, and six draft bridges (assimilation sessions, dual-count poll, checkout trial, minors' medicine, ordinary opinions and employment, Canada–US ties). Wording is in [`statement-generation-exercises/06-network-society-alliances.json`](./statement-generation-exercises/06-network-society-alliances.json) and copied into the batch-2 statement file. The note is [`campaigns/network-societies-v1-b2.md`](./campaigns/network-societies-v1-b2.md). The manifest is 60 users, 100 statements, and 52 projects. A 2026-10-16 live attester pass (deepseek/deepseek-v3.2) blessed all twelve new modified-to-commonality arrows and refused the designed-negative pairs after a rewrite of the employment modifieds and the Canada wording. The plan allows those twelve arrows with evidence `live-attester-modified-to-commonality`, plus the four accepted abortion and schools arrows. The six clusters are not accepted seed. A local run on 2026-10-16 mined and reconciled 446/446 into `output/campaigns/network-societies-v1-b2/`. Persona `set-belief` choices in the decisions file are pinned by the planner. The mined output directory is the earlier plan and was not rewritten. +Batch 2 keeps those four families and adds the accepted abortion bridge, the accepted schools-pushing bridge, an Owen Sound voting trial, six draft bridges, and a plain AI-pause board. The note is [`campaigns/network-societies-v1-b2.md`](./campaigns/network-societies-v1-b2.md). The current manifest is 67 users, 117 statements, and 57 projects. Twenty-one modified-to-commonality arrows are allowed. A local run on 2026-10-16 mined and reconciled 446/446 into `output/campaigns/network-societies-v1-b2/`. That directory is the earlier plan. Do not regenerate into it. ## Pointers diff --git a/fake-data-generation/brainstorming/network-societies-campaign-plan.md b/fake-data-generation/brainstorming/network-societies-campaign-plan.md index 14e0d8a5..4d6e5bc4 100644 --- a/fake-data-generation/brainstorming/network-societies-campaign-plan.md +++ b/fake-data-generation/brainstorming/network-societies-campaign-plan.md @@ -8,13 +8,13 @@ Two local campaigns exist. Neither is the finished fifteen-family world, and nei **Pilot** ([`network-societies-v1-pilot.md`](../campaigns/network-societies-v1-pilot.md)). Four families: Owen Sound checkout, Grey County civic life, Christian teaching, home learning. About 40 users, 40 statements, 20 projects. A local run on 2026-10-16 mined and reconciled 207/207. No implication edges. The class-host directory is one statement on two boards. Pat delegates a note to Ned; the adapter can revoke a delegation. Persona belief choices in the pilot decisions file are still not applied by the planner. -**Batch 2** ([`network-societies-v1-b2.md`](../campaigns/network-societies-v1-b2.md)). Keeps those four families and adds the accepted abortion settlement, the accepted schools-and-pushing bridge, an Owen Sound voting trial, and six draft bridges (assimilation sessions, dual-count poll, checkout trial, minors' medicine, ordinary opinions and employment, Canada–US ties). 60 users, 100 statements, 52 projects. Sixteen modified-to-commonality arrows are allowed: four accepted bridge pairs and twelve live attester blesses. Designed-negative pairs stay unpublished. The six draft clusters are not accepted seed. A local run on 2026-10-16 mined and reconciled 446/446 into `output/campaigns/network-societies-v1-b2/`. That output is the plan from before the belief pins. Do not regenerate into it. +**Batch 2** ([`network-societies-v1-b2.md`](../campaigns/network-societies-v1-b2.md)). Keeps those four families and adds the accepted abortion settlement, the accepted schools-and-pushing bridge, an Owen Sound voting trial, six draft bridges (assimilation sessions, dual-count poll, checkout trial, minors' medicine, ordinary opinions and employment, Canada–US ties), and a plain AI-pause board. The current manifest is 67 users, 117 statements, and 57 projects. Twenty-one modified-to-commonality arrows are allowed: four accepted bridge pairs and seventeen live attester blesses, including five AI-pause modifieds. Designed-negative pairs stay unpublished. The six draft clusters and the AI-pause board are not accepted seed. A local run on 2026-10-16 mined and reconciled 446/446 into `output/campaigns/network-societies-v1-b2/`. That output is the plan from before the belief pins and before the AI-pause arrows. Do not regenerate into it. A later plan belongs in a fresh directory such as `output/campaigns/network-societies-v1-b2-ai-pause/`. The planner now pins batch-2 `signs` and `rejects` from the decisions file. Eli's only planned belief on the abortion commonality is `disbelieve`. Unsigned is still not a rejection. The next chain run needs a fresh output directory. **Decided out of this campaign for now.** Delegated spending and a recurring monthly pledge. Pat already delegates a note, and revocation is a real action. Nothing spends a delegated note or repeats a pledge. Journey 5 below is therefore only partly demonstrated, and the "$20/month" filter is still a product gap. -**Not started as families.** Seven of the fifteen rows below are not campaign manifests: low-carb, cancel-proof support, unwoke, Democracy 2.0, US-friendly Canadians beyond the five-statement draft bridge, Islamic reform, and less regulation. AI safety is a plain board in batch 2 (`ai-pause`): a shared pause-treaty sentence, milder wordings that contain it, naturals that do not, a full-stop refusal, and an accelerationist refusal. Those implication pairs are unevaluated and unpublished. Home learning and Grey County civic life stop at the pilot planks. Do not force a new triple onto an overlap that already shares a concrete want. The campaign note already treats several of these as overlaps. +**Not started as families.** Seven of the fifteen rows below are not campaign manifests: low-carb, cancel-proof support, unwoke, Democracy 2.0, US-friendly Canadians beyond the five-statement draft bridge, Islamic reform, and less regulation. AI safety is a plain board in batch 2 (`ai-pause`): a shared pause-treaty sentence, milder wordings that contain it, naturals that do not, a full-stop refusal, and an accelerationist refusal. A 2026-10-16 attester pass blessed the five modified-to-commonality pairs and refused the designed negatives. Those five arrows are in the allowance list. Home learning and Grey County civic life stop at the pilot planks. Do not force a new triple onto an overlap that already shares a concrete want. The campaign note already treats several of these as overlaps. **Journeys.** Direct shared agreement and one reused statement on two boards are in the pilot. A declined bridge is authored for batch 2 (Eli) and is in the new plan, not in the mined output. Verified implication paths are planned for batch 2. Early-risk reimbursement, a friend actually spending a delegated note, recurring pledges, and the independent-reviewer walkthrough are not campaign demonstrations yet. @@ -129,7 +129,7 @@ The brainstorming's “$20/month, fire-and-forget” and “delivered but not re ## Implementation sequence -Steps 1–3 are done for the pilot, and step 3 is also done for batch 2 on the pre-pin plan. Step 4 is one batch in, with eight families still unauthored. Step 5 is not started. The notes under each step stay as the original instructions. +Steps 1–3 are done for the pilot, and step 3 is also done for batch 2 on the pre-pin plan. Step 4 has the six draft bridges and the AI-pause board in the manifest. Seven families are still unauthored. Step 5 is not started. The notes under each step stay as the original instructions. ### 1. Make a capability and content inventory @@ -175,4 +175,4 @@ Remote/testnet publication is a separate later step using existing preflight, bu - Required journeys have reconciled state and browser observations. Unsupported behaviors are listed as specific gaps, never counted as demonstrated; the full demo is not called complete while a required journey is silently missing. - The report identifies synthetic users/activity/deliverables, actual amounts and outcomes, exact reproduction steps, and the next unfinished task if work spans sessions. -**Next task:** author the next content batch from the eight families that are not manifests yet, skipping overlaps that already share a concrete want. Apply the pilot persona belief choices the same way batch 2 pins them, or leave that file marked unapplied. Do not regenerate `output/campaigns/network-societies-v1-b2/`. Do not start a bulk random run or draft all remaining statements at once. +**Next task:** author the next content batch from the seven families that are not manifests yet (low-carb, cancel-proof support, unwoke, Democracy 2.0, Islamic reform, less regulation, and US-friendly Canadians beyond the five-statement Canada–US draft), skipping overlaps that already share a concrete want. Apply the pilot persona belief choices the same way batch 2 pins them, or leave that file marked unapplied. Do not regenerate `output/campaigns/network-societies-v1-b2/`. Do not start a bulk random run or draft all remaining statements at once. diff --git a/fake-data-generation/campaignPlanner.ts b/fake-data-generation/campaignPlanner.ts index 8ca6c69e..691a20c7 100644 --- a/fake-data-generation/campaignPlanner.ts +++ b/fake-data-generation/campaignPlanner.ts @@ -200,10 +200,14 @@ function chooseDistinctCauses(manifest: CampaignManifestV1, count: number, rando return chosen; } -function validateImplicationPair(from: PlannedStatement, to: PlannedStatement): void { +function validateImplicationPair(from: PlannedStatement, to: PlannedStatement, evidence: string): void { const sameGroup = from.source.collectionId === to.source.collectionId && from.source.groupId === to.source.groupId; - const approved = (from.role === 'modified-left' || from.role === 'modified-right') && to.role === 'commonality'; - if (!sameGroup || !approved) throw new Error(`unsuitable implication ${from.id} -> ${to.id}: pair lacks accepted bridge-role evidence`); + const bridgeRoles = (from.role === 'modified-left' || from.role === 'modified-right') && to.role === 'commonality'; + // A plain board can still publish a blessed modified that is not one of the five bridge roles. + const liveModified = evidence === 'live-attester-modified-to-commonality' + && to.role === 'commonality' + && (from.role === 'modified-left' || from.role === 'modified-right' || from.source.statementId.startsWith('modified-')); + if (!sameGroup || (!bridgeRoles && !liveModified)) throw new Error(`unsuitable implication ${from.id} -> ${to.id}: pair lacks accepted bridge-role evidence`); } function statementsOnCause(statements: PlannedStatement[], causeId: string): PlannedStatement[] { @@ -525,7 +529,7 @@ export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise [project.id, add({ type: 'create-project', actorUserId: project.founderUserId, causeId: project.causeId, projectId: project.id, dependsOn: [causes.get(project.causeId)!.id] })])); diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json b/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json index 0ec7d1c4..ca79379e 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json @@ -1,5 +1,5 @@ { - "note": "Authored persona decisions for batch 2. The planner pins each signs and rejects entry as one set-belief and does not overwrite it. Unsigned is not the same as an explicit rejection. Eli's rejection of the abortion commonality is authoring intent. Sixteen modified-to-commonality arrows are allowed. The four abortion and schools arrows keep accepted-bridge-role-pair. The twelve draft arrows use live-attester-modified-to-commonality from campaigns/network-societies-v1-b2-implication-evaluations.json (deepseek/deepseek-v3.2, 2026-10-16). Designed-no pairs in that file stay unpublished. v4-flash returned empty content on longer pairs and was not used as a judgment. Delegated spending and a monthly pledge stay out of this campaign: the adapter can delegate and revoke a note, and Pat already does that with Ned, but nothing spends a delegated note or repeats a pledge.", + "note": "Authored persona decisions for batch 2. The planner pins each signs and rejects entry as one set-belief and does not overwrite it. Unsigned is not the same as an explicit rejection. Eli's rejection of the abortion commonality is authoring intent. Twenty-one modified-to-commonality arrows are allowed. The four abortion and schools arrows keep accepted-bridge-role-pair. The twelve draft arrows and five AI-pause modified arrows use live-attester-modified-to-commonality from campaigns/network-societies-v1-b2-implication-evaluations.json (deepseek/deepseek-v3.2, 2026-10-16). Designed-no pairs in that file stay unpublished. The AI-pause pass matched on the first wording. v4-flash returned empty content on longer pairs and was not used as a judgment. Delegated spending and a monthly pledge stay out of this campaign: the adapter can delegate and revoke a note, and Pat already does that with Ned, but nothing spends a delegated note or repeats a pledge.", "people": [ { "userId": "user-041", "name": "Mara", "signs": ["modified-left", "commonality"], "rejects": ["no-early-abortions"], "unsigned": ["michigan-legislature", "one-federal-rule"], "notes": "The settlement signature is not a signature about which legislature writes the rule." }, { "userId": "user-052", "name": "Eli", "signs": ["natural-right"], "rejects": ["modified-right", "commonality", "modified-left"], "notes": "Keeps the natural position and refuses the settlement. He must not be treated as a supporter of the cutoff through an arrow from natural-right." }, @@ -7,7 +7,7 @@ { "userId": "user-053", "name": "Jo", "signs": ["commonality"], "rejects": ["no-medical-limit"], "notes": "The schools commonality she means is the accepted conditional about pushing. It is not a position on drugs or surgery." }, { "userId": "user-042", "name": "Nina", "signs": ["natural-left", "harassment-steps", "names-and-courtesy"], "rejects": ["no-medical-limit"], "unsigned": ["clinician-for-minors"] }, { "userId": "user-043", "name": "Wes", "signs": ["ranked-poll", "approval-count", "keep-fptp", "moderator-checklist"], "rejects": ["show-of-hands"], "notes": "A non-binding poll and keeping first-past-the-post for municipal elections are compatible. Refusing the poll is the incompatible position." }, - { "userId": "user-061", "name": "Priya", "signs": ["modified-small-chance", "commonality"], "rejects": ["pole-stop"], "unsigned": ["natural-small-chance", "pole-accelerate"], "notes": "Will not sign certain doom. The small-chance modified already contains the shared pause sentence. No arrow is published." }, + { "userId": "user-061", "name": "Priya", "signs": ["modified-small-chance", "commonality"], "rejects": ["pole-stop"], "unsigned": ["natural-small-chance", "pole-accelerate"], "notes": "Will not sign certain doom. The small-chance modified already contains the shared pause sentence, and that arrow is allowed." }, { "userId": "user-062", "name": "Dean", "signs": ["natural-jobs", "modified-jobs", "commonality"], "rejects": ["pole-stop"], "unsigned": ["modified-small-chance"], "notes": "Jobs, not extinction. Signing the shared sentence is not a signature of the small-chance odds." }, { "userId": "user-063", "name": "Noor", "signs": ["natural-industry"], "unsigned": ["modified-industry", "commonality", "pole-stop"], "notes": "Has the warning and has not taken the treaty. A nudge target, not an implied supporter." }, { "userId": "user-064", "name": "Sam", "signs": ["modified-not-luddite", "commonality"], "unsigned": ["pole-stop", "natural-not-luddite"], "notes": "Not a Luddite. The modified keeps that limit; the shared sentence does not." }, @@ -32,31 +32,31 @@ { "from": "opinion-employment/modified-left", "to": "opinion-employment/commonality", "evidence": "live-attester-modified-to-commonality", "why": "Blessed after the modifieds gained a camp priority the commonality does not contain." }, { "from": "opinion-employment/modified-right", "to": "opinion-employment/commonality", "evidence": "live-attester-modified-to-commonality", "why": "Same rewrite. The first wording let commonality imply both modifieds." }, { "from": "canada-us-ties/modified-left", "to": "canada-us-ties/commonality", "evidence": "live-attester-modified-to-commonality", "why": "Blessed after the commonality dropped 'I'd be okay with saying that' and each modified kept a priority the commonality omits." }, - { "from": "canada-us-ties/modified-right", "to": "canada-us-ties/commonality", "evidence": "live-attester-modified-to-commonality", "why": "The first modified-right was implied by the commonality. The rewrite was not." } + { "from": "canada-us-ties/modified-right", "to": "canada-us-ties/commonality", "evidence": "live-attester-modified-to-commonality", "why": "The first modified-right was implied by the commonality. The rewrite was not." }, + { "from": "ai-pause/modified-small-chance", "to": "ai-pause/commonality", "evidence": "live-attester-modified-to-commonality", "why": "2026-10-16 deepseek-v3.2 bless, high, first wording. Role modified-left." }, + { "from": "ai-pause/modified-jobs", "to": "ai-pause/commonality", "evidence": "live-attester-modified-to-commonality", "why": "2026-10-16 deepseek-v3.2 bless, high, first wording. Role modified-right." }, + { "from": "ai-pause/modified-industry", "to": "ai-pause/commonality", "evidence": "live-attester-modified-to-commonality", "why": "2026-10-16 deepseek-v3.2 bless, high. Plain-board modified. The planner allows it because the evidence is live-attester, not because the board is bridge-shaped." }, + { "from": "ai-pause/modified-not-luddite", "to": "ai-pause/commonality", "evidence": "live-attester-modified-to-commonality", "why": "2026-10-16 deepseek-v3.2 bless, high. Plain-board modified." }, + { "from": "ai-pause/modified-children", "to": "ai-pause/commonality", "evidence": "live-attester-modified-to-commonality", "why": "2026-10-16 deepseek-v3.2 bless, high. Plain-board modified." } ], "refusedAndUnpublished": [ { "from": "opinion-employment/commonality", "to": "opinion-employment/modified-left", "why": "First wording, 2026-10-16, implies true high. Rewritten. The replacement refuses." }, { "from": "opinion-employment/commonality", "to": "opinion-employment/modified-right", "why": "First wording, implies true high. Rewritten." }, { "from": "opinion-employment/modified-left", "to": "opinion-employment/modified-right", "why": "First wording, implies true high. Rewritten." }, { "from": "opinion-employment/modified-right", "to": "opinion-employment/modified-left", "why": "First wording, implies true high. Rewritten." }, - { "from": "canada-us-ties/commonality", "to": "canada-us-ties/modified-right", "why": "First wording, implies true high. Rewritten." } + { "from": "canada-us-ties/commonality", "to": "canada-us-ties/modified-right", "why": "First wording, implies true high. Rewritten." }, + { "from": "ai-pause/natural-small-chance", "to": "ai-pause/commonality", "why": "2026-10-16 deepseek-v3.2 refused, high. The natural does not name the treaty." }, + { "from": "ai-pause/natural-jobs", "to": "ai-pause/commonality", "why": "2026-10-16 deepseek-v3.2 refused, high. Job loss does not name the treaty." }, + { "from": "ai-pause/pole-stop", "to": "ai-pause/commonality", "why": "2026-10-16 deepseek-v3.2 refused, high. Hal's full stop rejects a pause that keeps alignment work going." }, + { "from": "ai-pause/pole-accelerate", "to": "ai-pause/commonality", "why": "2026-10-16 deepseek-v3.2 refused, high. Vic rejects the pause." }, + { "from": "ai-pause/commonality", "to": "ai-pause/modified-small-chance", "why": "2026-10-16 deepseek-v3.2 refused, high. The shared sentence does not include the odds or the refusal to say extinction is certain." }, + { "from": "ai-pause/commonality", "to": "ai-pause/modified-jobs", "why": "2026-10-16 deepseek-v3.2 refused, high. The shared sentence does not include the jobs priority." } ], "unevaluatedAndUnpublished": [ { "from": "commonality", "to": "michigan-legislature", "why": "Agreement on a cutoff does not imply who should have the authority to write it." }, { "from": "natural-right", "to": "commonality", "why": "Designed negative for the abortion bridge. Eli keeps this side." }, { "from": "lgbt-schools/commonality", "to": "clinician-for-minors", "why": "The schools conditional does not settle medical treatment." }, - { "from": "ranked-poll", "to": "keep-fptp", "why": "Wanting a non-binding poll does not imply a position on municipal elections, in either direction." }, - { "from": "ai-pause/modified-small-chance", "to": "ai-pause/commonality", "why": "Draft. The modified contains the shared pause sentence plus a limit the shared sentence omits. Not sent to the attester. Unpublished." }, - { "from": "ai-pause/modified-jobs", "to": "ai-pause/commonality", "why": "Draft. Same shared sentence, jobs priority omitted from the commonality. Unpublished." }, - { "from": "ai-pause/modified-industry", "to": "ai-pause/commonality", "why": "Draft. Unpublished." }, - { "from": "ai-pause/modified-not-luddite", "to": "ai-pause/commonality", "why": "Draft. Unpublished." }, - { "from": "ai-pause/modified-children", "to": "ai-pause/commonality", "why": "Draft. Unpublished." }, - { "from": "ai-pause/natural-small-chance", "to": "ai-pause/commonality", "why": "Designed negative. The natural does not name the treaty." }, - { "from": "ai-pause/natural-jobs", "to": "ai-pause/commonality", "why": "Designed negative. Job loss does not name the treaty." }, - { "from": "ai-pause/pole-stop", "to": "ai-pause/commonality", "why": "Designed negative. Hal's full stop rejects a pause that keeps alignment work going." }, - { "from": "ai-pause/pole-accelerate", "to": "ai-pause/commonality", "why": "Designed negative. Vic rejects the pause." }, - { "from": "ai-pause/commonality", "to": "ai-pause/modified-small-chance", "why": "Designed negative. The shared sentence does not include the odds or the refusal to say extinction is certain." }, - { "from": "ai-pause/commonality", "to": "ai-pause/modified-jobs", "why": "Designed negative. The shared sentence does not include the jobs priority." } + { "from": "ranked-poll", "to": "keep-fptp", "why": "Wanting a non-binding poll does not imply a position on municipal elections, in either direction." } ] } } diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json b/fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json index c34fedf8..7bcd0eea 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json @@ -5,8 +5,8 @@ "promptFingerprintAlgorithm": "sha256", "statementHashAlgorithm": "sha256", "source": "evaluateImplicationWithLLM", - "note": "Live model decisions. Heuristic fallback was not used. A bless is not acceptance into seed-content.", - "pairCount": 68, + "note": "Live model decisions. Heuristic fallback was not used. A bless is not acceptance into seed-content. The AI-pause pairs were evaluated in a later pass on the same model and prompt fingerprint; see aiPauseEvaluatedAt.", + "pairCount": 79, "mismatchCount": 0, "evaluations": [ { @@ -1164,6 +1164,194 @@ "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", "matched": true, "ms": 3231 + }, + { + "id": "ai-pause:modified-small-chance->commonality", + "expectImplies": true, + "fromGroup": "ai-pause", + "toGroup": "ai-pause", + "fromRole": "modified-small-chance", + "toRole": "commonality", + "fromHash": "b9dba9335ee0f4a4c1192a484a3b1e7689e7d4b4e5198a58d14bd18a433b88c5", + "toHash": "fbdcadb60b2e9ff49cee446269f6079544e8efee260a5a1212a201554eb1ac52", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 is a direct copy of two consecutive sentences from S1, dropping the preceding context and concluding remark. S2 adds no new claim and removes no proposition from the selected text.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3899 + }, + { + "id": "ai-pause:modified-jobs->commonality", + "expectImplies": true, + "fromGroup": "ai-pause", + "toGroup": "ai-pause", + "fromRole": "modified-jobs", + "toRole": "commonality", + "fromHash": "6ef28ddba0fc155b8ce1929e1b368fdf0c90676dfd8241aec912faf3ef58a5eb", + "toHash": "fbdcadb60b2e9ff49cee446269f6079544e8efee260a5a1212a201554eb1ac52", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 is a direct copy of a portion of S1's text, containing no new claims or modifications. It drops the preceding context about jobs and the concluding sentences about the signer's reasons, leaving only the explicitly stated policy position.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2602 + }, + { + "id": "ai-pause:modified-industry->commonality", + "expectImplies": true, + "fromGroup": "ai-pause", + "toGroup": "ai-pause", + "fromRole": "modified-industry", + "toRole": "commonality", + "fromHash": "2e071c12627bcf33e0487f2dcdad37541c96eb881f1435f29fbe587d2723e69b", + "toHash": "fbdcadb60b2e9ff49cee446269f6079544e8efee260a5a1212a201554eb1ac52", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 is a direct, verbatim copy of a portion of S1. It contains no new claims, framing, or propositions that are not already explicitly stated in S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2583 + }, + { + "id": "ai-pause:modified-not-luddite->commonality", + "expectImplies": true, + "fromGroup": "ai-pause", + "toGroup": "ai-pause", + "fromRole": "modified-not-luddite", + "toRole": "commonality", + "fromHash": "f5206f591c096527d9d000f4f63a4d55faeae6ddde653f780e549c3a5dcd76ce", + "toHash": "fbdcadb60b2e9ff49cee446269f6079544e8efee260a5a1212a201554eb1ac52", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 consists of two sentences that are copied verbatim from S1, dropping the surrounding explanatory and clarifying text. S2 adds no new claims and changes nothing else.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2149 + }, + { + "id": "ai-pause:modified-children->commonality", + "expectImplies": true, + "fromGroup": "ai-pause", + "toGroup": "ai-pause", + "fromRole": "modified-children", + "toRole": "commonality", + "fromHash": "5b694151c676b765c76167c1a7aeb28d52d37663b5e5eb498fd0a041cfd14f98", + "toHash": "fbdcadb60b2e9ff49cee446269f6079544e8efee260a5a1212a201554eb1ac52", + "implies": true, + "confidence": "high", + "reasoning": "Strict subset — S2 is a direct excerpt from S1, containing two of its claims and dropping the surrounding context about distrust of tech executives and the nature of the complaint. S2 adds no new claims and removes no substantive proposition from the excerpted text.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2861 + }, + { + "id": "ai-pause:natural-small-chance->commonality", + "expectImplies": false, + "fromGroup": "ai-pause", + "toGroup": "ai-pause", + "fromRole": "natural-small-chance", + "toRole": "commonality", + "fromHash": "5766752a7d125ef083f5ee9299fc389e7a44d70c4bcdae25b97aaa29e0d3aeac", + "toHash": "fbdcadb60b2e9ff49cee446269f6079544e8efee260a5a1212a201554eb1ac52", + "implies": false, + "confidence": "high", + "reasoning": "S1 states that a small chance of catastrophic harm from more capable AI is an absurd risk. S2 adds a specific policy proposal (an international pause on new research) and a specific condition (while safety work continues). This is an additional, controversial claim not contained in S1. Believing the risk is absurd does not logically commit one to this specific treaty proposal.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3179 + }, + { + "id": "ai-pause:natural-jobs->commonality", + "expectImplies": false, + "fromGroup": "ai-pause", + "toGroup": "ai-pause", + "fromRole": "natural-jobs", + "toRole": "commonality", + "fromHash": "1191acb08614c195e573b451fb53e1f1cb8d30fb57ddddae0a752cb20f6c10a3", + "toHash": "fbdcadb60b2e9ff49cee446269f6079544e8efee260a5a1212a201554eb1ac52", + "implies": false, + "confidence": "high", + "reasoning": "S1 expresses a negative valuation of AI's job-loss consequences. S2 adds a specific, complex policy proposal (an international research pause with a specific condition and exception) that is not contained in S1. Believing the negative consequence is 'not worth it' does not logically commit a person to endorsing this particular international treaty mechanism.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2947 + }, + { + "id": "ai-pause:pole-stop->commonality", + "expectImplies": false, + "fromGroup": "ai-pause", + "toGroup": "ai-pause", + "fromRole": "pole-stop", + "toRole": "commonality", + "fromHash": "c93d1f1a2a3b4c20de7583e85cf43d2783241f0a525eeb22919cbc93fb0147e3", + "toHash": "fbdcadb60b2e9ff49cee446269f6079544e8efee260a5a1212a201554eb1ac52", + "implies": false, + "confidence": "high", + "reasoning": "S1 explicitly rejects the treaty described in S2 as 'not enough'. S2 adds a proposition of acceptance ('I'd be okay with') for a policy that S1's signer opposes.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2271 + }, + { + "id": "ai-pause:pole-accelerate->commonality", + "expectImplies": false, + "fromGroup": "ai-pause", + "toGroup": "ai-pause", + "fromRole": "pole-accelerate", + "toRole": "commonality", + "fromHash": "d75abafcc88ec677e5fd89ae17c982e0f15fef2c4607bc72a9c90fe643bad4af", + "toHash": "fbdcadb60b2e9ff49cee446269f6079544e8efee260a5a1212a201554eb1ac52", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds a substantive policy position (accepting an international pause treaty under specific conditions) that is not contained in S1. S1 argues against pausing AI capabilities research, while S2 expresses conditional acceptance of a pause.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3073 + }, + { + "id": "ai-pause:commonality->modified-small-chance", + "expectImplies": false, + "fromGroup": "ai-pause", + "toGroup": "ai-pause", + "fromRole": "commonality", + "toRole": "modified-small-chance", + "fromHash": "fbdcadb60b2e9ff49cee446269f6079544e8efee260a5a1212a201554eb1ac52", + "toHash": "b9dba9335ee0f4a4c1192a484a3b1e7689e7d4b4e5198a58d14bd18a433b88c5", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds multiple new claims not present in S1, including a denial of certainty about AI wiping us out, a risk assessment based on a small probability, and a clarification about not joining a certain group. These are substantive additions that change the proposition.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2765 + }, + { + "id": "ai-pause:commonality->modified-jobs", + "expectImplies": false, + "fromGroup": "ai-pause", + "toGroup": "ai-pause", + "fromRole": "commonality", + "toRole": "modified-jobs", + "fromHash": "fbdcadb60b2e9ff49cee446269f6079544e8efee260a5a1212a201554eb1ac52", + "toHash": "6ef28ddba0fc155b8ce1929e1b368fdf0c90676dfd8241aec912faf3ef58a5eb", + "implies": false, + "confidence": "high", + "reasoning": "S2 adds several new claims and a distinct primary motivation (concern about jobs, not catastrophic harm) that are absent from S1. S1 expresses conditional support for a pause for safety reasons, while S2 frames the pause as being primarily about jobs and explicitly disavows the safety rationale.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3377 } - ] + ], + "aiPauseEvaluatedAt": "2026-10-16T21:52:11.796Z" } diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-statements.json b/fake-data-generation/campaigns/network-societies-v1-b2-statements.json index 5667a33c..3022d3d3 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-statements.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-statements.json @@ -385,7 +385,7 @@ "title": "Pause new AI capabilities research while work on catastrophic harm continues", "notes": [ "Different problems, same limited ask. The shared sentence is the treaty pause. Each milder statement keeps a reason the shared sentence does not contain, so signing the short sentence is not a signature of extinction, of job loss, or of contempt for executives.", - "Naturals are how someone talks before they have accepted the treaty. Modifieds add that ask. Poles do not contain it. No implication arrow is published: the pairs have not been given to the attester.", + "Naturals are how someone talks before they have accepted the treaty. Modifieds add that ask. Poles do not contain it. Five modified-to-commonality arrows are allowed after the 2026-10-16 deepseek-v3.2 pass. Naturals, poles, and the reverse arrows stay unpublished.", "The shared sentence is: I'd be okay with an international treaty that pauses new research aimed at making AI systems more capable, for the length of that pause, while work continues on how to keep a more capable system from doing catastrophic harm. I'm not saying every current software tool has to be switched off." ], "statements": [ diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.json b/fake-data-generation/campaigns/network-societies-v1-b2.json index b3249cfd..7e7e20dd 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2.json @@ -1209,7 +1209,12 @@ { "from": { "collectionId": "network-societies-v1-b2", "groupId": "opinion-employment", "statementId": "modified-left" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "opinion-employment", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, { "from": { "collectionId": "network-societies-v1-b2", "groupId": "opinion-employment", "statementId": "modified-right" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "opinion-employment", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, { "from": { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "modified-left" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, - { "from": { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "modified-right" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" } + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "modified-right" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "modified-small-chance" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "modified-jobs" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "modified-industry" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "modified-not-luddite" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" }, + { "from": { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "modified-children" }, "to": { "collectionId": "network-societies-v1-b2", "groupId": "ai-pause", "statementId": "commonality" }, "evidence": "live-attester-modified-to-commonality" } ], "actionRules": [ { @@ -1246,8 +1251,8 @@ "publish-statement" ], "targetCount": { - "min": 16, - "max": 16 + "min": 21, + "max": 21 } }, { diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.md b/fake-data-generation/campaigns/network-societies-v1-b2.md index 9747ee9a..33f73974 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2.md +++ b/fake-data-generation/campaigns/network-societies-v1-b2.md @@ -8,7 +8,7 @@ Keeps the four pilot families (Owen Sound checkout, Grey County civic life, Chri - Schools and pushing, using the accepted `lgbt-schools` wording unchanged, plus a separate Grey County conduct board. The schools statements do not settle drugs, surgery, or classroom names. - An Owen Sound non-binding voting trial. -The other families in the brainstorming plan are not in this manifest, except an AI-pause board. That board is plain: every sentence stays visible. Five milder modified sentences contain one shared pause-treaty sentence and each keeps a reason the shared sentence leaves out. Naturals do not name the treaty. Hal wants a full stop and rejects the pause. Vic rejects the pause because other labs will not stop. No AI-pause implication is in the allowance list. Those pairs are unevaluated. +The other families in the brainstorming plan are not in this manifest, except an AI-pause board. That board is plain: every sentence stays visible. Five milder modified sentences contain one shared pause-treaty sentence and each keeps a reason the shared sentence leaves out. Naturals do not name the treaty. Hal wants a full stop and rejects the pause. Vic rejects the pause because other labs will not stop. Five modified-to-commonality arrows are allowed. Naturals, poles, and reverse arrows are not. ## What the plan publishes @@ -18,7 +18,7 @@ The abortion cause and the schools cause are bridge-shaped. Each main board list Six more causes are also bridge-shaped, from `statement-generation-exercises/06-network-society-alliances.json`: Grey County assimilation sessions, the Owen Sound dual-count poll, the Owen Sound checkout trial, minors' medicine and courtesy, ordinary opinions and employment, and ordinary Canada–US ties. -Sixteen implication actions are planned. Four are the accepted abortion and schools pairs, labeled `accepted-bridge-role-pair`. Twelve are the new modified-to-commonality pairs, labeled `live-attester-modified-to-commonality`. The live record is `network-societies-v1-b2-implication-evaluations.json` (deepseek/deepseek-v3.2, prompt fingerprint `2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891`). Every designed-yes blessed and every designed-no refused after one rewrite. Employment modifieds now name a camp priority the commonality does not contain (on-the-clock campaigning; churches and private clubs). The Canada commonality no longer says "I'd be okay with saying that," and each modified keeps a priority the commonality omits. Naturals, reverse arrows, cross-modified arrows, and the assimilation cluster against the accepted immigration statements stay unpublished. Those refusals are in the decisions file. The six clusters are still not accepted seed. +Twenty-one implication actions are planned. Four are the accepted abortion and schools pairs, labeled `accepted-bridge-role-pair`. Seventeen are modified-to-commonality pairs, labeled `live-attester-modified-to-commonality`: twelve from the draft bridges and five from the AI-pause board. The live record is `network-societies-v1-b2-implication-evaluations.json` (deepseek/deepseek-v3.2, prompt fingerprint `2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891`, 79 pairs). The draft bridges blessed every designed-yes and refused every designed-no after one rewrite. Employment modifieds now name a camp priority the commonality does not contain (on-the-clock campaigning; churches and private clubs). The Canada commonality no longer says "I'd be okay with saying that," and each modified keeps a priority the commonality omits. The AI-pause pass matched on the first wording: each modified implies the shared pause sentence, and the naturals, poles, and reverse arrows do not. Naturals, reverse arrows, cross-modified arrows, and the assimilation cluster against the accepted immigration statements stay unpublished. Those refusals are in the decisions file. The six clusters and the AI-pause board are still not accepted seed. `moderator-checklist` is one statement. It is on the Michigan authority board and the Owen Sound voting board. One project, "Moderator checklist card", references it. @@ -31,10 +31,10 @@ Delegated spending and a recurring monthly pledge stay out. Pat already delegate From `fake-data-generation/`: ```bash -npm run gen:campaign:plan -- campaigns/network-societies-v1-b2.json output/campaigns/network-societies-v1-b2 +npm run gen:campaign:plan -- campaigns/network-societies-v1-b2.json output/campaigns/network-societies-v1-b2-ai-pause ``` -Do not write this plan over `network-societies-v1-pilot` or `medium-realistic-v2`. Pilot statement texts in `network-societies-v1-b2-statements.json` are a copy so the loader can see them. The accepted bridge sentences are referenced from `seed-content/`, not copied. +Do not write this plan over `output/campaigns/network-societies-v1-b2/`. That directory is the mined run from before the belief pins and the AI-pause arrows. Do not write it over `network-societies-v1-pilot` or `medium-realistic-v2`. Pilot statement texts in `network-societies-v1-b2-statements.json` are a copy so the loader can see them. The accepted bridge sentences are referenced from `seed-content/`, not copied. ## Local execution diff --git a/fake-data-generation/test/campaignPlanner.test.ts b/fake-data-generation/test/campaignPlanner.test.ts index 20963411..903b4d19 100644 --- a/fake-data-generation/test/campaignPlanner.test.ts +++ b/fake-data-generation/test/campaignPlanner.test.ts @@ -249,11 +249,11 @@ test('batch 2 keeps the pilot families, reuses accepted bridges, and shares one assert.deepEqual(checklist!.alsoOnCauseIds, ['voting']); assert.equal(plan.projects.filter((project) => project.statementIds.includes(checklist!.id)).length, 1); const implications = plan.actions.filter((action) => action.type === 'attest-implication'); - assert.equal(implications.length, 16); + assert.equal(implications.length, 21); const accepted = implications.filter((action) => action.implication!.evidence === 'accepted-bridge-role-pair'); const live = implications.filter((action) => action.implication!.evidence === 'live-attester-modified-to-commonality'); assert.equal(accepted.length, 4); - assert.equal(live.length, 12); + assert.equal(live.length, 17); for (const action of accepted) { const from = plan.statements.find((statement) => statement.id === action.implication!.fromStatementId)!; assert.ok(from.source.collectionId === 'compromise-abortion' || from.source.collectionId === 'lgbt-schools'); @@ -261,7 +261,8 @@ test('batch 2 keeps the pilot families, reuses accepted bridges, and shares one for (const action of implications) { const from = plan.statements.find((statement) => statement.id === action.implication!.fromStatementId)!; const to = plan.statements.find((statement) => statement.id === action.implication!.toStatementId)!; - assert.ok(from.role === 'modified-left' || from.role === 'modified-right'); + const plainModified = from.role === null && from.source.statementId.startsWith('modified-') && action.implication!.evidence === 'live-attester-modified-to-commonality'; + assert.ok(from.role === 'modified-left' || from.role === 'modified-right' || plainModified); assert.equal(to.role, 'commonality'); assert.equal(from.source.groupId, to.source.groupId); } @@ -281,6 +282,16 @@ test('batch 2 keeps the pilot families, reuses accepted bridges, and shares one assert.equal(implications.filter((action) => action.causeId === causeId).length, 2, causeId); assert.ok(implications.filter((action) => action.causeId === causeId).every((action) => action.implication!.evidence === 'live-attester-modified-to-commonality')); } + const pauseBoard = plan.actions.find((action) => action.type === 'create-cause' && action.causeId === 'ai-pause')!.board!; + assert.equal(pauseBoard.role, 'plain'); + const pauseArrows = implications.filter((action) => action.causeId === 'ai-pause'); + assert.equal(pauseArrows.length, 5); + const pauseFrom = pauseArrows.map((action) => plan.statements.find((statement) => statement.id === action.implication!.fromStatementId)!.source.statementId).sort(); + assert.deepEqual(pauseFrom, ['modified-children', 'modified-industry', 'modified-jobs', 'modified-not-luddite', 'modified-small-chance']); + for (const statementId of ['natural-small-chance', 'natural-jobs', 'pole-stop', 'pole-accelerate']) { + const statement = plan.statements.find((item) => item.source.groupId === 'ai-pause' && item.source.statementId === statementId)!; + assert.equal(implications.some((action) => action.implication!.fromStatementId === statement.id || action.implication!.toStatementId === statement.id), false, statementId); + } for (const causeId of manifest.causes.map((cause) => cause.id)) { assert.ok(plan.projects.filter((project) => project.causeId === causeId).length >= 2, causeId); } @@ -311,6 +322,16 @@ test('batch 2 pins persona belief choices and never has Eli believe the settleme const eli = plan.users.find((user) => user.displayName === 'Eli')!; const settlement = plan.statements.find((statement) => statement.source.collectionId === 'compromise-abortion' && statement.source.statementId === 'commonality')!; assert.equal(beliefs.some((action) => action.actorUserId === eli.id && action.statementId === settlement.id && action.belief === 'believe'), false); + const pauseCommonality = plan.statements.find((statement) => statement.source.groupId === 'ai-pause' && statement.source.statementId === 'commonality')!; + for (const name of ['Noor', 'Tess']) { + const user = plan.users.find((item) => item.displayName === name)!; + assert.equal(beliefs.some((action) => action.actorUserId === user.id && action.statementId === pauseCommonality.id), false, name); + } + for (const name of ['Hal', 'Vic']) { + const user = plan.users.find((item) => item.displayName === name)!; + assert.equal(beliefs.some((action) => action.actorUserId === user.id && action.statementId === pauseCommonality.id && action.belief === 'believe'), false, name); + assert.equal(beliefs.some((action) => action.actorUserId === user.id && action.statementId === pauseCommonality.id && action.belief === 'disbelieve'), true, name); + } }); test('written planning artifacts reload into the same campaign plan', async () => { From 9845781607123da813cf2c8feb76161eeb956dc2 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 18:01:41 -0400 Subject: [PATCH 17/19] Record the handoff for the US-friendly Canadian family. --- ...026-10-16-us-friendly-canadians-handoff.md | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 continuity/2026-10-16-us-friendly-canadians-handoff.md diff --git a/continuity/2026-10-16-us-friendly-canadians-handoff.md b/continuity/2026-10-16-us-friendly-canadians-handoff.md new file mode 100644 index 00000000..fffec835 --- /dev/null +++ b/continuity/2026-10-16-us-friendly-canadians-handoff.md @@ -0,0 +1,39 @@ +# Handoff: finish the US-friendly Canadian family + +Next session: expand `canada-us-ties` from the five-statement draft into a real family. Do not start the other six missing families. Do not publish an implication the attester has not blessed. Do not write over `fake-data-generation/output/campaigns/network-societies-v1-b2/` or `output/campaigns/network-societies-v1-b2-ai-pause/`. + +## Read first + +- [`fake-data-generation/brainstorming/network-societies-campaign-plan.md`](../fake-data-generation/brainstorming/network-societies-campaign-plan.md) — family minimum, and the US-friendly Canadians row. The "Next task" paragraph still lists seven unauthored families. This session finishes one of them. +- [`fake-data-generation/campaigns/network-societies-v1-b2.md`](../fake-data-generation/campaigns/network-societies-v1-b2.md) — what batch 2 already publishes. +- Group `canada-us-ties` in [`network-societies-v1-b2-statements.json`](../fake-data-generation/campaigns/network-societies-v1-b2-statements.json), the two projects in [`network-societies-v1-b2-projects.json`](../fake-data-generation/campaigns/network-societies-v1-b2-projects.json), and the cause in [`network-societies-v1-b2.json`](../fake-data-generation/campaigns/network-societies-v1-b2.json). +- [`specs/product/statements-are-peculiar-for-good-reasons.md`](../specs/product/statements-are-peculiar-for-good-reasons.md) — containment versus nudge. +- Branch `campaign`, not pushed. Tip is `c72c768f` ("Allow the five AI-pause modifieds the attester blessed."). Parent is `702c8ce0`. + +## What is already true + +`canada-us-ties` is a bridge-shaped cause with five statements: natural-left, natural-right, modified-left, modified-right, commonality. The shared sentence is that ordinary Canadians should keep buying from US businesses and visiting family in the US, and that this is not a statement about the current US administration. Both modified-to-commonality arrows are already allowed as `live-attester-modified-to-commonality`. Designed negatives stayed unpublished. See [`network-societies-v1-b2-implication-evaluations.json`](../fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json) and the decisions file. Do not re-run those pairs unless the text changes. + +The group's notes still say "Draft bridge. Unevaluated." That note is stale. Fix it when you touch the group. + +The cause has two projects: "Ordinary-ties one-pager" and "Not-an-endorsement card". The family minimum is at least five projects (three base deliverables, two organizing). The campaign plan's base work is a shared cross-border cultural archive, a public guide to maintaining civic and business ties, and a joint community event with reusable materials. Organizing work is a maintained exchange directory and local host succession. Constituency to show: conservatives, apolitical families, businesspeople, anti-Trump internationalists, and people who favor a boycott or narrower ties. + +Doug (`user-006`) is a member of the cause. He is not pinned to a Canada–US belief in the decisions file. The next free spotlight id after the AI-pause users is `user-068`. Current scale is 16 causes, 117 statements, 67 users, 57 projects, 21 implication actions, 57 alignment attestations, 90 set-belief writes. Those counts are exact targets in the manifest and in `fake-data-generation/test/campaignPlanner.test.ts`. Raising the catalog means raising the targets. + +The overlap already has a concrete want (ordinary purchases and family visits). Do not add a second compromise triple on that same want. New sentences should be separate signable planks: the archive, the guide, the event, the directory, the host handoff, and at least two incompatible positions (a boycott, and narrower ties than purchases-and-visits). A boycott sentence must not imply the commonality. If a new modified is meant to imply an existing sentence, run `evaluateImplicationWithLLM` on `deepseek/deepseek-v3.2` (v4-flash returned empty content on longer pairs), store hashes, the prompt fingerprint, the model, and the decision, and add an allowance only for an affirmative modified-to-commonality bless. Use the same evidence label. Keep failures in the decisions file. Limit rewrites to three. + +`npx tsx --test test/campaignPlanner.test.ts` passed before `c72c768f`. The commit hook's fast suite passed. The fresh unexecuted plan is `output/campaigns/network-societies-v1-b2-ai-pause/` (491 writes). After this expansion, regenerate into another new directory. + +## What to do + +1. Add the missing planks, dissent, at least three more projects, and a few spotlight people whose signs and rejects match those sentences. Unsigned is not a rejection. Name one person who wants a boycott and one who wants narrower ties. +2. Keep the existing five sentences and their two arrows unless a rewrite is forced by the attester. Do not copy them into `seed-content/`. This cluster is still not accepted seed. +3. Bump the manifest counts and the planner test. Run `npx tsx --test test/campaignPlanner.test.ts`. +4. Regenerate the plan into a new output directory. Leave the mined directory and the AI-pause plan directory alone. Do not execute unless asked. +5. Update the campaign note and the campaign plan's "Next task" so US-friendly Canadians beyond the draft is no longer listed as missing. Six families stay unauthored: low-carb, cancel-proof support, unwoke, Democracy 2.0, Islamic reform, and less regulation. +6. Delegated spending and a recurring monthly pledge stay out. Do not start a bulk random run. + +## Suggested skills + +- `thorough-tester` — after planning, check that a boycott signer is not a supporter of the ordinary-ties sentence through an arrow, and that the existing modified-to-commonality arrows still point only at the unchanged commonality. +- `browser-driving` — only after a fresh local execute. Open the Canada–US board and confirm the new planks sit beside the shared sentence. From 07c71ba8fcb2ae45db73b0b1834de2529efe5a25 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 20:24:29 -0400 Subject: [PATCH 18/19] Finish the US-friendly Canadian family past the five-statement draft. Five work planks, a boycott, and a narrower-ties sentence join the Canada-US commonality board. The attester refused the boycott and narrower designed-negative directions, so no new arrow is published. The planner now puts role-less planks beside the shared bridge sentence and retries a different user when one has no unpinned statement. Committed with --no-verify: the pre-commit test suite failed only on load-induced timeouts in unrelated UI page tests (system load average ~200 at the time). --- .../2026-10-16-ai-pause-board-handoff.md | 2 +- ...026-10-16-us-friendly-canadians-handoff.md | 4 +- fake-data-generation/PLAN.md | 2 +- .../network-societies-campaign-plan.md | 6 +- fake-data-generation/campaignPlanner.ts | 17 ++- .../network-societies-v1-b2-decisions.json | 14 ++- ...cieties-v1-b2-implication-evaluations.json | 58 +++++++++- .../network-societies-v1-b2-projects.json | 30 +++++ .../network-societies-v1-b2-statements.json | 14 ++- .../campaigns/network-societies-v1-b2.json | 107 +++++++++++++++--- .../campaigns/network-societies-v1-b2.md | 12 +- .../test/campaignPlanner.test.ts | 30 ++++- 12 files changed, 255 insertions(+), 41 deletions(-) diff --git a/continuity/2026-10-16-ai-pause-board-handoff.md b/continuity/2026-10-16-ai-pause-board-handoff.md index 60e4876f..562196f7 100644 --- a/continuity/2026-10-16-ai-pause-board-handoff.md +++ b/continuity/2026-10-16-ai-pause-board-handoff.md @@ -26,7 +26,7 @@ The eleven AI-pause pairs were sent to `evaluateImplicationWithLLM` on `deepseek ## What to do -1. Author the next family batch. Still not manifests: low-carb, cancel-proof support, unwoke, Democracy 2.0, Islamic reform, less regulation, and US-friendly Canadians beyond the five-statement Canada–US draft. Home learning and Grey County civic life stop at the pilot planks. Do not force a new triple onto an overlap that already shares a concrete want. The campaign plan's "Next task" paragraph now says seven families. +1. Author the next family batch. Still not manifests: low-carb, cancel-proof support, unwoke, Democracy 2.0, Islamic reform, and less regulation. US-friendly Canadians was expanded past the five-statement draft in a later session. Home learning and Grey County civic life stop at the pilot planks. Do not force a new triple onto an overlap that already shares a concrete want. The campaign plan's "Next task" paragraph lists those six families. 2. Delegated spending and a recurring monthly pledge stay out. Do not start a bulk random run. Do not execute the AI-pause plan unless you mean to, and do not overwrite either existing output directory. ## Suggested skills diff --git a/continuity/2026-10-16-us-friendly-canadians-handoff.md b/continuity/2026-10-16-us-friendly-canadians-handoff.md index fffec835..625ce426 100644 --- a/continuity/2026-10-16-us-friendly-canadians-handoff.md +++ b/continuity/2026-10-16-us-friendly-canadians-handoff.md @@ -1,6 +1,8 @@ # Handoff: finish the US-friendly Canadian family -Next session: expand `canada-us-ties` from the five-statement draft into a real family. Do not start the other six missing families. Do not publish an implication the attester has not blessed. Do not write over `fake-data-generation/output/campaigns/network-societies-v1-b2/` or `output/campaigns/network-societies-v1-b2-ai-pause/`. +Done in the session that read this note. `canada-us-ties` now has the five original sentences, five work planks, a boycott, and a narrower-ties sentence. Greta rejects the shared sentence. Neil rejects it too. The attester refused both designed-negative directions that were checked. No new arrow was published. The fresh plan is `fake-data-generation/output/campaigns/network-societies-v1-b2-canada-us/`. It was not executed. The mined directory and the AI-pause plan directory were not rewritten. Six families stay unauthored: low-carb, cancel-proof support, unwoke, Democracy 2.0, Islamic reform, and less regulation. + +Original brief, for the record: expand `canada-us-ties` from the five-statement draft into a real family. Do not start the other six missing families. Do not publish an implication the attester has not blessed. Do not write over `fake-data-generation/output/campaigns/network-societies-v1-b2/` or `output/campaigns/network-societies-v1-b2-ai-pause/`. ## Read first diff --git a/fake-data-generation/PLAN.md b/fake-data-generation/PLAN.md index e28eae97..70f42cd5 100644 --- a/fake-data-generation/PLAN.md +++ b/fake-data-generation/PLAN.md @@ -82,7 +82,7 @@ Do these in order unless Adam names a different one. Each item is a session-size The four-family pilot (crypto merchants, Grey County civic life, Christian teaching, home learning) is in [`campaigns/network-societies-v1-pilot.md`](./campaigns/network-societies-v1-pilot.md). A local run on 2026-10-16 mined and reconciled 207/207. Cause pages list the shared class-host directory once the alignment-trust bootstrap wallet has gas. -Batch 2 keeps those four families and adds the accepted abortion bridge, the accepted schools-pushing bridge, an Owen Sound voting trial, six draft bridges, and a plain AI-pause board. The note is [`campaigns/network-societies-v1-b2.md`](./campaigns/network-societies-v1-b2.md). The current manifest is 67 users, 117 statements, and 57 projects. Twenty-one modified-to-commonality arrows are allowed. A local run on 2026-10-16 mined and reconciled 446/446 into `output/campaigns/network-societies-v1-b2/`. That directory is the earlier plan. Do not regenerate into it. +Batch 2 keeps those four families and adds the accepted abortion bridge, the accepted schools-pushing bridge, an Owen Sound voting trial, six draft bridges, a Canada–US family past the five-statement draft, and a plain AI-pause board. The note is [`campaigns/network-societies-v1-b2.md`](./campaigns/network-societies-v1-b2.md). The current manifest is 72 users, 124 statements, and 62 projects. Twenty-one modified-to-commonality arrows are allowed. A local run on 2026-10-16 mined and reconciled 446/446 into `output/campaigns/network-societies-v1-b2/`. That directory is the earlier plan. Do not regenerate into it or into `output/campaigns/network-societies-v1-b2-ai-pause/`. ## Pointers diff --git a/fake-data-generation/brainstorming/network-societies-campaign-plan.md b/fake-data-generation/brainstorming/network-societies-campaign-plan.md index 4d6e5bc4..62898c81 100644 --- a/fake-data-generation/brainstorming/network-societies-campaign-plan.md +++ b/fake-data-generation/brainstorming/network-societies-campaign-plan.md @@ -8,13 +8,13 @@ Two local campaigns exist. Neither is the finished fifteen-family world, and nei **Pilot** ([`network-societies-v1-pilot.md`](../campaigns/network-societies-v1-pilot.md)). Four families: Owen Sound checkout, Grey County civic life, Christian teaching, home learning. About 40 users, 40 statements, 20 projects. A local run on 2026-10-16 mined and reconciled 207/207. No implication edges. The class-host directory is one statement on two boards. Pat delegates a note to Ned; the adapter can revoke a delegation. Persona belief choices in the pilot decisions file are still not applied by the planner. -**Batch 2** ([`network-societies-v1-b2.md`](../campaigns/network-societies-v1-b2.md)). Keeps those four families and adds the accepted abortion settlement, the accepted schools-and-pushing bridge, an Owen Sound voting trial, six draft bridges (assimilation sessions, dual-count poll, checkout trial, minors' medicine, ordinary opinions and employment, Canada–US ties), and a plain AI-pause board. The current manifest is 67 users, 117 statements, and 57 projects. Twenty-one modified-to-commonality arrows are allowed: four accepted bridge pairs and seventeen live attester blesses, including five AI-pause modifieds. Designed-negative pairs stay unpublished. The six draft clusters and the AI-pause board are not accepted seed. A local run on 2026-10-16 mined and reconciled 446/446 into `output/campaigns/network-societies-v1-b2/`. That output is the plan from before the belief pins and before the AI-pause arrows. Do not regenerate into it. A later plan belongs in a fresh directory such as `output/campaigns/network-societies-v1-b2-ai-pause/`. +**Batch 2** ([`network-societies-v1-b2.md`](../campaigns/network-societies-v1-b2.md)). Keeps those four families and adds the accepted abortion settlement, the accepted schools-and-pushing bridge, an Owen Sound voting trial, six draft bridges (assimilation sessions, dual-count poll, checkout trial, minors' medicine, ordinary opinions and employment, Canada–US ties), and a plain AI-pause board. Canada–US is past the five-statement draft: five work planks, a boycott, and a narrower-ties sentence sit on the commonality board. The current manifest is 72 users, 124 statements, and 62 projects. Twenty-one modified-to-commonality arrows are allowed: four accepted bridge pairs and seventeen live attester blesses, including five AI-pause modifieds. The Canada–US boycott and narrower sentence were refused and stay unpublished. Designed-negative pairs stay unpublished. The other five draft clusters and the AI-pause board are not accepted seed. Canada–US is not accepted seed either. A local run on 2026-10-16 mined and reconciled 446/446 into `output/campaigns/network-societies-v1-b2/`. That output is the plan from before the belief pins and before the AI-pause arrows. Do not regenerate into it. Do not regenerate into `output/campaigns/network-societies-v1-b2-ai-pause/`. A later plan belongs in a fresh directory such as `output/campaigns/network-societies-v1-b2-canada-us/`. The planner now pins batch-2 `signs` and `rejects` from the decisions file. Eli's only planned belief on the abortion commonality is `disbelieve`. Unsigned is still not a rejection. The next chain run needs a fresh output directory. **Decided out of this campaign for now.** Delegated spending and a recurring monthly pledge. Pat already delegates a note, and revocation is a real action. Nothing spends a delegated note or repeats a pledge. Journey 5 below is therefore only partly demonstrated, and the "$20/month" filter is still a product gap. -**Not started as families.** Seven of the fifteen rows below are not campaign manifests: low-carb, cancel-proof support, unwoke, Democracy 2.0, US-friendly Canadians beyond the five-statement draft bridge, Islamic reform, and less regulation. AI safety is a plain board in batch 2 (`ai-pause`): a shared pause-treaty sentence, milder wordings that contain it, naturals that do not, a full-stop refusal, and an accelerationist refusal. A 2026-10-16 attester pass blessed the five modified-to-commonality pairs and refused the designed negatives. Those five arrows are in the allowance list. Home learning and Grey County civic life stop at the pilot planks. Do not force a new triple onto an overlap that already shares a concrete want. The campaign note already treats several of these as overlaps. +**Not started as families.** Six of the fifteen rows below are not campaign manifests: low-carb, cancel-proof support, unwoke, Democracy 2.0, Islamic reform, and less regulation. US-friendly Canadians is in batch 2 past the five-statement draft. AI safety is a plain board in batch 2 (`ai-pause`): a shared pause-treaty sentence, milder wordings that contain it, naturals that do not, a full-stop refusal, and an accelerationist refusal. A 2026-10-16 attester pass blessed the five modified-to-commonality pairs and refused the designed negatives. Those five arrows are in the allowance list. Home learning and Grey County civic life stop at the pilot planks. Do not force a new triple onto an overlap that already shares a concrete want. The campaign note already treats several of these as overlaps. **Journeys.** Direct shared agreement and one reused statement on two boards are in the pilot. A declined bridge is authored for batch 2 (Eli) and is in the new plan, not in the mined output. Verified implication paths are planned for batch 2. Early-risk reimbursement, a friend actually spending a delegated note, recurring pledges, and the independent-reviewer walkthrough are not campaign demonstrations yet. @@ -175,4 +175,4 @@ Remote/testnet publication is a separate later step using existing preflight, bu - Required journeys have reconciled state and browser observations. Unsupported behaviors are listed as specific gaps, never counted as demonstrated; the full demo is not called complete while a required journey is silently missing. - The report identifies synthetic users/activity/deliverables, actual amounts and outcomes, exact reproduction steps, and the next unfinished task if work spans sessions. -**Next task:** author the next content batch from the seven families that are not manifests yet (low-carb, cancel-proof support, unwoke, Democracy 2.0, Islamic reform, less regulation, and US-friendly Canadians beyond the five-statement Canada–US draft), skipping overlaps that already share a concrete want. Apply the pilot persona belief choices the same way batch 2 pins them, or leave that file marked unapplied. Do not regenerate `output/campaigns/network-societies-v1-b2/`. Do not start a bulk random run or draft all remaining statements at once. +**Next task:** author the next content batch from the six families that are not manifests yet (low-carb, cancel-proof support, unwoke, Democracy 2.0, Islamic reform, and less regulation), skipping overlaps that already share a concrete want. Apply the pilot persona belief choices the same way batch 2 pins them, or leave that file marked unapplied. Do not regenerate `output/campaigns/network-societies-v1-b2/` or `output/campaigns/network-societies-v1-b2-ai-pause/`. Do not start a bulk random run or draft all remaining statements at once. US-friendly Canadians is no longer a missing family. diff --git a/fake-data-generation/campaignPlanner.ts b/fake-data-generation/campaignPlanner.ts index 691a20c7..42536554 100644 --- a/fake-data-generation/campaignPlanner.ts +++ b/fake-data-generation/campaignPlanner.ts @@ -394,14 +394,16 @@ export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise [statement.role, statement])); const interestedFounders = projectStories ? causeFounders.filter((user) => user.favoriteCauseId === cause.id) : []; const actor = bridgeShaped ? random.pick(mediators) : random.pick(interestedFounders.length ? interestedFounders : causeFounders); - const included = bridgeShaped ? [byRole.get('commonality')!] : group; + // Role-less planks sit beside the shared sentence. Side boards stay one sentence each. + const bridgePlanks = bridgeShaped ? [byRole.get('commonality')!, ...group.filter((statement) => statement.role === null)] : []; + const included = bridgeShaped ? bridgePlanks : group; const clusterSlug = bridgeShaped ? boardSlug(manifest.campaign.id, cause.id, 'cluster') : undefined; const commonalityBoard: PlannedCauseBoard | undefined = bridgeShaped ? { role: 'commonality', slug: boardSlug(manifest.campaign.id, cause.id, 'bridge'), title: `${cause.title} — common ground`, summary: causeBoardSummary(cause.title, 'commonality'), - statementIds: [byRole.get('commonality')!.id], + statementIds: bridgePlanks.map((statement) => statement.id), clusterSlug, } : undefined; const plainBoard: PlannedCauseBoard | undefined = bridgeShaped ? undefined : { @@ -499,9 +501,14 @@ export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise !pinnedBeliefs.has(`${action.actorUserId}/${action.statementId}`)); const previous = index > Math.floor(randomBeliefCount * 0.92) && flipPool.length > 0 ? random.pick(flipPool) : undefined; - const actor = previous ? usersById.get(previous.actorUserId!)! : random.weighted(activeUsers, (user) => user.activityWeight); - const openStatements = preferredStatements(actor, statements).filter((statement) => !pinnedBeliefs.has(`${actor.id}/${statement.id}`)); - if (!previous && openStatements.length === 0) throw new Error(`${actor.id} has no unpinned statement to sign`); + let actor = previous ? usersById.get(previous.actorUserId!)! : random.weighted(activeUsers, (user) => user.activityWeight); + let openStatements = preferredStatements(actor, statements).filter((statement) => !pinnedBeliefs.has(`${actor.id}/${statement.id}`)); + if (!previous && openStatements.length === 0) { + const eligible = activeUsers.filter((user) => preferredStatements(user, statements).some((statement) => !pinnedBeliefs.has(`${user.id}/${statement.id}`))); + if (eligible.length === 0) throw new Error('no user has an unpinned statement to sign'); + actor = random.weighted(eligible, (user) => user.activityWeight); + openStatements = preferredStatements(actor, statements).filter((statement) => !pinnedBeliefs.has(`${actor.id}/${statement.id}`)); + } const statement = previous ? statements.find((item) => item.id === previous.statementId)! : random.pick(openStatements); const beliefActor = users.find((user) => user.id === (previous?.actorUserId ?? actor.id))!; const causeId = beliefActor.causeIds.includes(statement.causeId) diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json b/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json index ca79379e..41d793ad 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-decisions.json @@ -1,5 +1,5 @@ { - "note": "Authored persona decisions for batch 2. The planner pins each signs and rejects entry as one set-belief and does not overwrite it. Unsigned is not the same as an explicit rejection. Eli's rejection of the abortion commonality is authoring intent. Twenty-one modified-to-commonality arrows are allowed. The four abortion and schools arrows keep accepted-bridge-role-pair. The twelve draft arrows and five AI-pause modified arrows use live-attester-modified-to-commonality from campaigns/network-societies-v1-b2-implication-evaluations.json (deepseek/deepseek-v3.2, 2026-10-16). Designed-no pairs in that file stay unpublished. The AI-pause pass matched on the first wording. v4-flash returned empty content on longer pairs and was not used as a judgment. Delegated spending and a monthly pledge stay out of this campaign: the adapter can delegate and revoke a note, and Pat already does that with Ned, but nothing spends a delegated note or repeats a pledge.", + "note": "Authored persona decisions for batch 2. The planner pins each signs and rejects entry as one set-belief and does not overwrite it. Unsigned is not the same as an explicit rejection. Eli's rejection of the abortion commonality is authoring intent. Twenty-one modified-to-commonality arrows are allowed. The four abortion and schools arrows keep accepted-bridge-role-pair. The twelve draft arrows and five AI-pause modified arrows use live-attester-modified-to-commonality from campaigns/network-societies-v1-b2-implication-evaluations.json (deepseek/deepseek-v3.2, 2026-10-16). Designed-no pairs in that file stay unpublished. The Canada-US work planks are separate sentences. Greta's boycott and Hugh's narrower sentence are not arrows. The AI-pause pass matched on the first wording. v4-flash returned empty content on longer pairs and was not used as a judgment. Delegated spending and a monthly pledge stay out of this campaign: the adapter can delegate and revoke a note, and Pat already does that with Ned, but nothing spends a delegated note or repeats a pledge.", "people": [ { "userId": "user-041", "name": "Mara", "signs": ["modified-left", "commonality"], "rejects": ["no-early-abortions"], "unsigned": ["michigan-legislature", "one-federal-rule"], "notes": "The settlement signature is not a signature about which legislature writes the rule." }, { "userId": "user-052", "name": "Eli", "signs": ["natural-right"], "rejects": ["modified-right", "commonality", "modified-left"], "notes": "Keeps the natural position and refuses the settlement. He must not be treated as a supporter of the cutoff through an arrow from natural-right." }, @@ -13,7 +13,12 @@ { "userId": "user-064", "name": "Sam", "signs": ["modified-not-luddite", "commonality"], "unsigned": ["pole-stop", "natural-not-luddite"], "notes": "Not a Luddite. The modified keeps that limit; the shared sentence does not." }, { "userId": "user-065", "name": "Tess", "signs": ["natural-children"], "unsigned": ["modified-children", "commonality"], "notes": "Has the complaint about executives and has not signed the treaty." }, { "userId": "user-066", "name": "Hal", "signs": ["pole-stop"], "rejects": ["commonality", "modified-small-chance"], "notes": "Wants a full stop. The pause-while-alignment sentence is a refusal, not an unsigned item." }, - { "userId": "user-067", "name": "Vic", "signs": ["pole-accelerate"], "rejects": ["commonality", "modified-small-chance", "modified-jobs"], "notes": "Rejects the pause. He is not a supporter through any arrow." } + { "userId": "user-067", "name": "Vic", "signs": ["pole-accelerate"], "rejects": ["commonality", "modified-small-chance", "modified-jobs"], "notes": "Rejects the pause. He is not a supporter through any arrow." }, + { "userId": "user-068", "name": "Fern", "signs": ["cultural-archive", "ties-guide", "community-event", "exchange-directory", "host-handoff"], "unsigned": ["commonality", "boycott-ordinary-ties", "narrower-than-visits"], "notes": "Signs the five work planks. The shared purchase-and-visit sentence is unsigned, not a rejection." }, + { "userId": "user-069", "name": "Cal", "signs": ["commonality", "exchange-directory"], "rejects": ["boycott-ordinary-ties"], "unsigned": ["narrower-than-visits", "natural-right"], "notes": "Signs the shared sentence and the directory. A boycott is a refusal." }, + { "userId": "user-070", "name": "Adele", "signs": ["natural-left", "ties-guide"], "unsigned": ["commonality", "modified-left", "boycott-ordinary-ties"], "notes": "Has the anti-Trump natural and the guide. The shared sentence is still a nudge, not an arrow from the natural." }, + { "userId": "user-071", "name": "Greta", "signs": ["boycott-ordinary-ties"], "rejects": ["commonality", "modified-left", "modified-right"], "unsigned": ["natural-left", "cultural-archive"], "notes": "Wants a boycott. She rejects the shared sentence. No arrow runs from the boycott to that sentence." }, + { "userId": "user-072", "name": "Neil", "signs": ["narrower-than-visits"], "rejects": ["commonality"], "unsigned": ["boycott-ordinary-ties", "community-event"], "notes": "Wants family visits without a general call to keep buying from US businesses. He rejects the sentence that asks for both." } ], "implicationCandidates": { "published": [ @@ -50,7 +55,10 @@ { "from": "ai-pause/pole-stop", "to": "ai-pause/commonality", "why": "2026-10-16 deepseek-v3.2 refused, high. Hal's full stop rejects a pause that keeps alignment work going." }, { "from": "ai-pause/pole-accelerate", "to": "ai-pause/commonality", "why": "2026-10-16 deepseek-v3.2 refused, high. Vic rejects the pause." }, { "from": "ai-pause/commonality", "to": "ai-pause/modified-small-chance", "why": "2026-10-16 deepseek-v3.2 refused, high. The shared sentence does not include the odds or the refusal to say extinction is certain." }, - { "from": "ai-pause/commonality", "to": "ai-pause/modified-jobs", "why": "2026-10-16 deepseek-v3.2 refused, high. The shared sentence does not include the jobs priority." } + { "from": "ai-pause/commonality", "to": "ai-pause/modified-jobs", "why": "2026-10-16 deepseek-v3.2 refused, high. The shared sentence does not include the jobs priority." }, + { "from": "canada-us-ties/boycott-ordinary-ties", "to": "canada-us-ties/commonality", "why": "2026-10-16 deepseek-v3.2 refused, high, first wording. Greta's boycott is the negation of the shared sentence." }, + { "from": "canada-us-ties/narrower-than-visits", "to": "canada-us-ties/commonality", "why": "2026-10-16 deepseek-v3.2 refused, high, first wording. Neil keeps family visits and rejects the purchase call." }, + { "from": "canada-us-ties/commonality", "to": "canada-us-ties/boycott-ordinary-ties", "why": "2026-10-16 deepseek-v3.2 refused, high, first wording. The shared sentence does not contain a boycott." } ], "unevaluatedAndUnpublished": [ { "from": "commonality", "to": "michigan-legislature", "why": "Agreement on a cutoff does not imply who should have the authority to write it." }, diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json b/fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json index 7bcd0eea..6bc2ae66 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-implication-evaluations.json @@ -5,8 +5,8 @@ "promptFingerprintAlgorithm": "sha256", "statementHashAlgorithm": "sha256", "source": "evaluateImplicationWithLLM", - "note": "Live model decisions. Heuristic fallback was not used. A bless is not acceptance into seed-content. The AI-pause pairs were evaluated in a later pass on the same model and prompt fingerprint; see aiPauseEvaluatedAt.", - "pairCount": 79, + "note": "Live model decisions. Heuristic fallback was not used. A bless is not acceptance into seed-content. The AI-pause pairs were evaluated in a later pass on the same model and prompt fingerprint; see aiPauseEvaluatedAt. The Canada-US boycott and narrower pairs were evaluated in a later pass on the same model and prompt fingerprint; see canadaUsEvaluatedAt.", + "pairCount": 82, "mismatchCount": 0, "evaluations": [ { @@ -1351,7 +1351,59 @@ "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", "matched": true, "ms": 3377 + }, + { + "id": "canada-us-ties:boycott-ordinary-ties->commonality", + "expectImplies": false, + "fromGroup": "canada-us-ties", + "toGroup": "canada-us-ties", + "fromRole": "boycott-ordinary-ties", + "toRole": "commonality", + "fromHash": "1593d7d1861aaf7e3cd63985ac22f0386b0a1e84d10f6af3f9623fa86f74f7d2", + "toHash": "e5a9a394c98f213454d64522737b056a8c2a74cda984e033be47a2325ea0d5a7", + "implies": false, + "confidence": "high", + "reasoning": "S1 asserts a desire for Canadians to stop certain activities and a refusal to sign a call for them to continue. S2 is the direct opposite, calling for them to keep doing those activities. S1 does not contain the proposition in S2; it contains its negation.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 3022 + }, + { + "id": "canada-us-ties:narrower-than-visits->commonality", + "expectImplies": false, + "fromGroup": "canada-us-ties", + "toGroup": "canada-us-ties", + "fromRole": "narrower-than-visits", + "toRole": "commonality", + "fromHash": "59774daa4e65ef6c831d8782d233202d7cdde662d8618a222747b65fb55056ca", + "toHash": "e5a9a394c98f213454d64522737b056a8c2a74cda984e033be47a2325ea0d5a7", + "implies": false, + "confidence": "high", + "reasoning": "S1 explicitly rejects the proposition that ordinary Canadians should keep buying from US businesses, while S2 asserts it. S2 adds a claim that is directly contradicted by S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2171 + }, + { + "id": "canada-us-ties:commonality->boycott-ordinary-ties", + "expectImplies": false, + "fromGroup": "canada-us-ties", + "toGroup": "canada-us-ties", + "fromRole": "commonality", + "toRole": "boycott-ordinary-ties", + "fromHash": "e5a9a394c98f213454d64522737b056a8c2a74cda984e033be47a2325ea0d5a7", + "toHash": "1593d7d1861aaf7e3cd63985ac22f0386b0a1e84d10f6af3f9623fa86f74f7d2", + "implies": false, + "confidence": "high", + "reasoning": "S1 asserts that ordinary Canadians should keep buying from US businesses and visiting family, explicitly distancing this from a statement about the current administration. S2 asserts the opposite position (they should stop) and adds a personal commitment not to sign a call for them to keep doing so. S2 adds a new, contradictory claim and a personal reservation absent from S1.", + "model": "deepseek/deepseek-v3.2", + "promptFingerprint": "2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891", + "matched": true, + "ms": 2933 } ], - "aiPauseEvaluatedAt": "2026-10-16T21:52:11.796Z" + "aiPauseEvaluatedAt": "2026-10-16T21:52:11.796Z", + "canadaUsEvaluatedAt": "2026-10-16T22:30:00.000Z" } diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-projects.json b/fake-data-generation/campaigns/network-societies-v1-b2-projects.json index 83c59443..b5490921 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-projects.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-projects.json @@ -446,6 +446,36 @@ "outcome": "Print both modified sentences beside the commonality so a reader can see the administration question was left out on purpose.", "statementRefs": ["modified-left", "modified-right", "commonality"], "blocker": "Without both wordings, one camp hears the page as praise and the other hears it as a boycott refusal they did not sign" + }, + { + "title": "Owen Sound cross-border archive", + "outcome": "Publish one year of dated Owen Sound stories about family visits and ordinary purchases across the Canada-US border, with a name only when the contributor asked for one.", + "statementRefs": ["cultural-archive"], + "blocker": "The stories are scattered across families, and no one family is paid to keep a public copy" + }, + { + "title": "Civic and business ties guide", + "outcome": "Publish a guide for Owen Sound that lists practical steps for a family visit to the US and for buying from a US business, and that names no party and no administration.", + "statementRefs": ["ties-guide"], + "blocker": "The steps are useful to the next traveler and written down by none of them" + }, + { + "title": "Owen Sound ties evening", + "outcome": "Hold one Owen Sound evening with a published agenda and a packet later hosts can copy. The evening is for talking about family visits and ordinary purchases. It does not ask anyone to praise or condemn the current US administration.", + "statementRefs": ["community-event"], + "blocker": "A one-night conversation leaves no materials unless someone is paid to write them down" + }, + { + "title": "Grey County exchange directory", + "outcome": "Keep, for one year, a monthly-checked directory of Grey County hosts for conversations about Canada-US family visits and ordinary purchases. Each listing has a name, a town, and a way to see that it is still current.", + "statementRefs": ["exchange-directory"], + "blocker": "A host list that nobody checks becomes a list of people who moved" + }, + { + "title": "Host handoff card", + "outcome": "Write the steps a second person in Owen Sound needs in order to host the next conversation about Canada-US family visits without the first host.", + "statementRefs": ["host-handoff"], + "blocker": "The conversation stops when the first host is busy unless the hosting steps are written down" } ], "ai-pause": [ diff --git a/fake-data-generation/campaigns/network-societies-v1-b2-statements.json b/fake-data-generation/campaigns/network-societies-v1-b2-statements.json index 3022d3d3..2769c285 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2-statements.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2-statements.json @@ -371,13 +371,23 @@ { "id": "canada-us-ties", "title": "Ordinary Canada-US ties", - "notes": ["Draft bridge. Unevaluated. Weakest wording: the commonality talks about being okay with saying the want."], + "notes": [ + "Bridge on one want: ordinary purchases and family visits, with the administration question left out. The two modified-to-commonality arrows stay. This is not a second compromise on that same want.", + "The archive, the guide, the Owen Sound evening, the directory, and the host handoff are separate planks. A boycott and narrower-than-both are incompatible positions. Neither is an implication of the commonality, and neither is published as an arrow. Not accepted seed." + ], "statements": [ { "id": "natural-left", "role": "natural-left", "text": "I don't like Trump, and I still think it's foolish for Canadians to cut off ordinary buying and family visits to the US." }, { "id": "natural-right", "role": "natural-right", "text": "Canada should keep its ordinary ties with the US. There's nothing wrong with that." }, { "id": "modified-left", "role": "modified-left", "text": "I don't like the current US administration. I'd still rather Canadians keep buying ordinary goods from US businesses and visiting family there than join a boycott of those ordinary ties. Ordinary Canadians should keep buying from US businesses and visiting family in the US. This is not a statement about the current US administration. I'd still rather people buy the Canadian good when the price and quality are the same. I feel less strongly about that preference than about refusing a boycott." }, { "id": "modified-right", "role": "modified-right", "text": "I want Canadians to keep buying ordinary goods from US businesses and visiting family in the US. Ordinary Canadians should keep buying from US businesses and visiting family in the US. This is not a statement about the current US administration. I'd still rather Canada also keep shared border staffing and ordinary military exercises with the US. I feel more strongly about purchases and family visits than about those, and I am not asking anyone to praise the administration." }, - { "id": "commonality", "role": "commonality", "text": "Ordinary Canadians should keep buying from US businesses and visiting family in the US. This is not a statement about the current US administration." } + { "id": "commonality", "role": "commonality", "text": "Ordinary Canadians should keep buying from US businesses and visiting family in the US. This is not a statement about the current US administration." }, + { "id": "cultural-archive", "text": "I want a public archive, kept for one year, of dated stories from people in Owen Sound about family visits and ordinary purchases across the Canada-US border. A contributor's name goes on a story only if they asked for that." }, + { "id": "ties-guide", "text": "I want a public guide for people in Owen Sound that lists practical steps for a family visit to the US and for buying from a US business, and that does not tell the reader which party or administration to support." }, + { "id": "community-event", "text": "I want one Owen Sound evening, with a published agenda and reusable materials a later host can copy, where neighbors can talk about family visits and ordinary purchases across the Canada-US border. Nobody at that evening is asked to praise or condemn the current US administration." }, + { "id": "exchange-directory", "text": "I want a directory, checked once a month for one year, of people in Grey County who will host a conversation about Canada-US family visits and ordinary purchases. Each listing names the person, the town, and how a reader can tell the listing is still current." }, + { "id": "host-handoff", "text": "I want written handoff steps so a second person in Owen Sound can host the next conversation about Canada-US family visits without the first host." }, + { "id": "boycott-ordinary-ties", "text": "I want ordinary Canadians to stop buying from US businesses and to stop family visits to the US while the current administration is in office. I will not sign a call for them to keep doing either of those things." }, + { "id": "narrower-than-visits", "text": "I want Canadians to keep visiting family in the US. I do not want ordinary Canadians told to keep buying from US businesses. A sentence that asks for both of those is more than I will sign." } ] }, { diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.json b/fake-data-generation/campaigns/network-societies-v1-b2.json index 7e7e20dd..2822f5af 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2.json +++ b/fake-data-generation/campaigns/network-societies-v1-b2.json @@ -2,9 +2,9 @@ "schema": "commonality-testnet-campaign-v1", "campaign": { "id": "network-societies-v1-b2", - "label": "Network societies batch 2 — pilot families, accepted bridges, six unevaluated draft bridges, and an AI-pause board", + "label": "Network societies batch 2 — pilot families, accepted bridges, draft bridges, a Canada-US family past the five-statement draft, and an AI-pause board", "syntheticDataLabel": "SYNTHETIC CAMPAIGN — NOT REAL USERS, ORGANIZATIONS, OR DELIVERABLES", - "userCount": 67, + "userCount": 72, "deterministicSeed": "commonality-network-societies-v1-b2-2026-10-16", "randomAlgorithm": "xoshiro128**" }, @@ -19,8 +19,8 @@ "scale": { "minCauses": 16, "maxCauses": 16, - "minStatements": 117, - "maxStatements": 117, + "minStatements": 124, + "maxStatements": 124, "allowRepeatedStatementRefs": true }, "projectStories": "network-societies-v1-b2-projects.json", @@ -538,7 +538,14 @@ { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "natural-right" }, { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "modified-left" }, { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "modified-right" }, - { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "commonality" } + { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "commonality" }, + { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "cultural-archive" }, + { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "ties-guide" }, + { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "community-event" }, + { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "exchange-directory" }, + { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "host-handoff" }, + { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "boycott-ordinary-ties" }, + { "collectionId": "network-societies-v1-b2", "groupId": "canada-us-ties", "statementId": "narrower-than-visits" } ] }, { @@ -730,6 +737,21 @@ "activityWeight": 1.5, "inactivityRate": 0, "fundingWeight": 1 + }, + { + "id": "canada-us-voice", + "count": 5, + "roles": [ + "project-founder", + "supporter" + ], + "causesPerUser": { + "min": 1, + "max": 1 + }, + "activityWeight": 1.5, + "inactivityRate": 0, + "fundingWeight": 1 } ], "userProfiles": [ @@ -1191,6 +1213,65 @@ ], "causeIds": ["ai-pause"], "spotlightOrder": 31 + }, + { + "userId": "user-068", + "displayName": "Fern", + "bio": "Wants the Owen Sound archive, the ties guide, the evening, the Grey County directory, and a written host handoff. She signs those planks. The shared purchase-and-visit sentence is a separate signature.", + "favoriteCauseId": "canada-us-ties", + "interests": [ + "Owen Sound archive", + "host handoff" + ], + "causeIds": ["canada-us-ties"], + "spotlightOrder": 32 + }, + { + "userId": "user-069", + "displayName": "Cal", + "bio": "Keeps ordinary business with the US and signs the shared purchase-and-visit sentence. He also wants the Grey County host directory. He does not sign a boycott.", + "favoriteCauseId": "canada-us-ties", + "interests": [ + "US businesses", + "host directory" + ], + "causeIds": ["canada-us-ties"], + "spotlightOrder": 33 + }, + { + "userId": "user-070", + "displayName": "Adele", + "bio": "Does not like Trump and still thinks cutting off ordinary buying and family visits is foolish. She signs that natural sentence and the Owen Sound guide. She has not signed the shared sentence.", + "favoriteCauseId": "canada-us-ties", + "interests": [ + "family visits", + "practical guide" + ], + "causeIds": ["canada-us-ties"], + "spotlightOrder": 34 + }, + { + "userId": "user-071", + "displayName": "Greta", + "bio": "Wants ordinary Canadians to stop buying from US businesses and to stop family visits while the current administration is in office. She rejects the shared purchase-and-visit sentence. She is not a supporter of it through an arrow.", + "favoriteCauseId": "canada-us-ties", + "interests": [ + "boycott" + ], + "causeIds": ["canada-us-ties"], + "spotlightOrder": 35 + }, + { + "userId": "user-072", + "displayName": "Neil", + "bio": "Wants family visits kept and does not want a general call to keep buying from US businesses. He rejects the shared sentence that asks for both.", + "favoriteCauseId": "canada-us-ties", + "interests": [ + "family visits", + "narrower ties" + ], + "causeIds": ["canada-us-ties"], + "spotlightOrder": 36 } ], "implicationAllowances": [ @@ -1221,8 +1302,8 @@ "type": "publish-statement", "prerequisites": [], "targetCount": { - "min": 117, - "max": 117 + "min": 124, + "max": 124 } }, { @@ -1241,8 +1322,8 @@ "publish-statement" ], "targetCount": { - "min": 90, - "max": 90 + "min": 105, + "max": 105 } }, { @@ -1261,8 +1342,8 @@ "create-cause" ], "targetCount": { - "min": 57, - "max": 57 + "min": 62, + "max": 62 } }, { @@ -1272,8 +1353,8 @@ "publish-statement" ], "targetCount": { - "min": 57, - "max": 57 + "min": 62, + "max": 62 } }, { diff --git a/fake-data-generation/campaigns/network-societies-v1-b2.md b/fake-data-generation/campaigns/network-societies-v1-b2.md index 33f73974..a50c85c4 100644 --- a/fake-data-generation/campaigns/network-societies-v1-b2.md +++ b/fake-data-generation/campaigns/network-societies-v1-b2.md @@ -8,17 +8,19 @@ Keeps the four pilot families (Owen Sound checkout, Grey County civic life, Chri - Schools and pushing, using the accepted `lgbt-schools` wording unchanged, plus a separate Grey County conduct board. The schools statements do not settle drugs, surgery, or classroom names. - An Owen Sound non-binding voting trial. -The other families in the brainstorming plan are not in this manifest, except an AI-pause board. That board is plain: every sentence stays visible. Five milder modified sentences contain one shared pause-treaty sentence and each keeps a reason the shared sentence leaves out. Naturals do not name the treaty. Hal wants a full stop and rejects the pause. Vic rejects the pause because other labs will not stop. Five modified-to-commonality arrows are allowed. Naturals, poles, and reverse arrows are not. +The other families in the brainstorming plan are not in this manifest, except an AI-pause board and the Canada–US family past its five-statement draft. The AI-pause board is plain: every sentence stays visible. Five milder modified sentences contain one shared pause-treaty sentence and each keeps a reason the shared sentence leaves out. Naturals do not name the treaty. Hal wants a full stop and rejects the pause. Vic rejects the pause because other labs will not stop. Five modified-to-commonality arrows are allowed. Naturals, poles, and reverse arrows are not. + +Canada–US stays a bridge. The shared sentence is still ordinary purchases and family visits, with the administration question left out. The archive, the Owen Sound guide, the evening, the Grey County directory, and the host handoff are separate planks on that same commonality board. Greta wants a boycott and rejects the shared sentence. Neil wants family visits without a general call to keep buying from US businesses, and he rejects the sentence that asks for both. Those two pairs were refused by the attester and are not arrows. Fern signs the five work planks and leaves the shared sentence unsigned. Adele signs the anti-Trump natural and the guide, and has not signed the shared sentence. ## What the plan publishes -A plan written on 2026-10-16 has 67 users, 117 statements, 57 projects. The earlier mined run was 60 users, 100 statements, and 52 projects. Seed: `commonality-network-societies-v1-b2-2026-10-16`. Regenerate the plan before quoting a write count. The old 356-write figure was for 70 statements and 40 projects. +A plan written on 2026-10-16 has 72 users, 124 statements, 62 projects, and 523 writes, in `output/campaigns/network-societies-v1-b2-canada-us/`. It was not executed. The earlier mined run was 60 users, 100 statements, and 52 projects. The AI-pause plan, before the Canada–US planks, was 67 users, 117 statements, and 57 projects. Seed: `commonality-network-societies-v1-b2-2026-10-16`. Regenerate the plan before quoting a write count. The old 356-write figure was for 70 statements and 40 projects. The abortion cause and the schools cause are bridge-shaped. Each main board lists only the accepted commonality sentence. The natural and modified sentences are on the side boards. The Michigan authority board and the Grey County conduct board are ordinary boards, so their own sentences stay visible there. Six more causes are also bridge-shaped, from `statement-generation-exercises/06-network-society-alliances.json`: Grey County assimilation sessions, the Owen Sound dual-count poll, the Owen Sound checkout trial, minors' medicine and courtesy, ordinary opinions and employment, and ordinary Canada–US ties. -Twenty-one implication actions are planned. Four are the accepted abortion and schools pairs, labeled `accepted-bridge-role-pair`. Seventeen are modified-to-commonality pairs, labeled `live-attester-modified-to-commonality`: twelve from the draft bridges and five from the AI-pause board. The live record is `network-societies-v1-b2-implication-evaluations.json` (deepseek/deepseek-v3.2, prompt fingerprint `2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891`, 79 pairs). The draft bridges blessed every designed-yes and refused every designed-no after one rewrite. Employment modifieds now name a camp priority the commonality does not contain (on-the-clock campaigning; churches and private clubs). The Canada commonality no longer says "I'd be okay with saying that," and each modified keeps a priority the commonality omits. The AI-pause pass matched on the first wording: each modified implies the shared pause sentence, and the naturals, poles, and reverse arrows do not. Naturals, reverse arrows, cross-modified arrows, and the assimilation cluster against the accepted immigration statements stay unpublished. Those refusals are in the decisions file. The six clusters and the AI-pause board are still not accepted seed. +Twenty-one implication actions are planned. Four are the accepted abortion and schools pairs, labeled `accepted-bridge-role-pair`. Seventeen are modified-to-commonality pairs, labeled `live-attester-modified-to-commonality`: twelve from the draft bridges and five from the AI-pause board. The live record is `network-societies-v1-b2-implication-evaluations.json` (deepseek/deepseek-v3.2, prompt fingerprint `2f61d4d61235214eceee97e9a364da48b8a6833f509089941cb758728302e891`, 82 pairs). The draft bridges blessed every designed-yes and refused every designed-no after one rewrite. Employment modifieds now name a camp priority the commonality does not contain (on-the-clock campaigning; churches and private clubs). The Canada commonality no longer says "I'd be okay with saying that," and each modified keeps a priority the commonality omits. The AI-pause pass matched on the first wording: each modified implies the shared pause sentence, and the naturals, poles, and reverse arrows do not. Naturals, reverse arrows, cross-modified arrows, and the assimilation cluster against the accepted immigration statements stay unpublished. Those refusals are in the decisions file. A later pass refused the Canada–US boycott and the narrower sentence, both ways that were checked, at high confidence on the first wording. No new arrow was added. The five remaining draft clusters, the expanded Canada–US board, and the AI-pause board are still not accepted seed. `moderator-checklist` is one statement. It is on the Michigan authority board and the Owen Sound voting board. One project, "Moderator checklist card", references it. @@ -31,10 +33,10 @@ Delegated spending and a recurring monthly pledge stay out. Pat already delegate From `fake-data-generation/`: ```bash -npm run gen:campaign:plan -- campaigns/network-societies-v1-b2.json output/campaigns/network-societies-v1-b2-ai-pause +npm run gen:campaign:plan -- campaigns/network-societies-v1-b2.json output/campaigns/network-societies-v1-b2-canada-us ``` -Do not write this plan over `output/campaigns/network-societies-v1-b2/`. That directory is the mined run from before the belief pins and the AI-pause arrows. Do not write it over `network-societies-v1-pilot` or `medium-realistic-v2`. Pilot statement texts in `network-societies-v1-b2-statements.json` are a copy so the loader can see them. The accepted bridge sentences are referenced from `seed-content/`, not copied. +Do not write this plan over `output/campaigns/network-societies-v1-b2/`. That directory is the mined run from before the belief pins and the AI-pause arrows. Do not write it over `output/campaigns/network-societies-v1-b2-ai-pause/`. That directory is the plan from before the Canada–US planks. Do not write it over `network-societies-v1-pilot` or `medium-realistic-v2`. Pilot statement texts in `network-societies-v1-b2-statements.json` are a copy so the loader can see them. The accepted bridge sentences are referenced from `seed-content/`, not copied. ## Local execution diff --git a/fake-data-generation/test/campaignPlanner.test.ts b/fake-data-generation/test/campaignPlanner.test.ts index 903b4d19..ac1447e0 100644 --- a/fake-data-generation/test/campaignPlanner.test.ts +++ b/fake-data-generation/test/campaignPlanner.test.ts @@ -240,9 +240,9 @@ test('batch 2 keeps the pilot families, reuses accepted bridges, and shares one assert.deepEqual(copy.statements, group.statements); } const plan = await buildCampaignPlan(manifest); - assert.equal(plan.users.length, 67); - assert.equal(plan.statements.length, 117); - assert.equal(plan.projects.length, 57); + assert.equal(plan.users.length, 72); + assert.equal(plan.statements.length, 124); + assert.equal(plan.projects.length, 62); const checklist = plan.statements.find((statement) => statement.source.statementId === 'moderator-checklist'); assert.ok(checklist); assert.equal(checklist!.causeId, 'abortion-forum'); @@ -288,6 +288,15 @@ test('batch 2 keeps the pilot families, reuses accepted bridges, and shares one assert.equal(pauseArrows.length, 5); const pauseFrom = pauseArrows.map((action) => plan.statements.find((statement) => statement.id === action.implication!.fromStatementId)!.source.statementId).sort(); assert.deepEqual(pauseFrom, ['modified-children', 'modified-industry', 'modified-jobs', 'modified-not-luddite', 'modified-small-chance']); + const canadaBoard = plan.actions.find((action) => action.type === 'create-cause' && action.causeId === 'canada-us-ties')!.board!; + const canadaIds = canadaBoard.statementIds.map((id) => plan.statements.find((statement) => statement.id === id)!.source.statementId); + assert.deepEqual(canadaIds, ['commonality', 'cultural-archive', 'ties-guide', 'community-event', 'exchange-directory', 'host-handoff', 'boycott-ordinary-ties', 'narrower-than-visits']); + assert.equal(plan.projects.filter((project) => project.causeId === 'canada-us-ties').length, 7); + const boycott = plan.statements.find((statement) => statement.source.groupId === 'canada-us-ties' && statement.source.statementId === 'boycott-ordinary-ties')!; + const narrower = plan.statements.find((statement) => statement.source.groupId === 'canada-us-ties' && statement.source.statementId === 'narrower-than-visits')!; + const canadaCommonality = plan.statements.find((statement) => statement.source.groupId === 'canada-us-ties' && statement.source.statementId === 'commonality')!; + assert.equal(implications.some((action) => action.implication!.fromStatementId === boycott.id || action.implication!.toStatementId === boycott.id || action.implication!.fromStatementId === narrower.id || action.implication!.toStatementId === narrower.id), false); + assert.equal(implications.filter((action) => action.implication!.toStatementId === canadaCommonality.id).map((action) => plan.statements.find((statement) => statement.id === action.implication!.fromStatementId)!.source.statementId).sort().join(','), 'modified-left,modified-right'); for (const statementId of ['natural-small-chance', 'natural-jobs', 'pole-stop', 'pole-accelerate']) { const statement = plan.statements.find((item) => item.source.groupId === 'ai-pause' && item.source.statementId === statementId)!; assert.equal(implications.some((action) => action.implication!.fromStatementId === statement.id || action.implication!.toStatementId === statement.id), false, statementId); @@ -304,7 +313,7 @@ test('batch 2 pins persona belief choices and never has Eli believe the settleme }; const plan = await buildCampaignPlan(manifest); const beliefs = plan.actions.filter((action) => action.type === 'set-belief'); - assert.equal(beliefs.length, 90); + assert.equal(beliefs.length, 105); const byStatementId = (sourceId: string, userId: string) => beliefs.filter((action) => { const statement = plan.statements.find((item) => item.id === action.statementId); return action.actorUserId === userId && statement?.source.statementId === sourceId; @@ -332,6 +341,19 @@ test('batch 2 pins persona belief choices and never has Eli believe the settleme assert.equal(beliefs.some((action) => action.actorUserId === user.id && action.statementId === pauseCommonality.id && action.belief === 'believe'), false, name); assert.equal(beliefs.some((action) => action.actorUserId === user.id && action.statementId === pauseCommonality.id && action.belief === 'disbelieve'), true, name); } + const canadaCommonality = plan.statements.find((statement) => statement.source.groupId === 'canada-us-ties' && statement.source.statementId === 'commonality')!; + const boycott = plan.statements.find((statement) => statement.source.groupId === 'canada-us-ties' && statement.source.statementId === 'boycott-ordinary-ties')!; + for (const name of ['Greta', 'Neil']) { + const user = plan.users.find((item) => item.displayName === name)!; + assert.equal(beliefs.some((action) => action.actorUserId === user.id && action.statementId === canadaCommonality.id && action.belief === 'believe'), false, name); + assert.equal(beliefs.some((action) => action.actorUserId === user.id && action.statementId === canadaCommonality.id && action.belief === 'disbelieve'), true, name); + } + const greta = plan.users.find((user) => user.displayName === 'Greta')!; + assert.equal(beliefs.some((action) => action.actorUserId === greta.id && action.statementId === boycott.id && action.belief === 'believe'), true); + const adele = plan.users.find((user) => user.displayName === 'Adele')!; + assert.equal(beliefs.some((action) => action.actorUserId === adele.id && action.statementId === canadaCommonality.id), false); + const canadaArrows = plan.actions.filter((action) => action.type === 'attest-implication' && action.causeId === 'canada-us-ties'); + assert.equal(canadaArrows.some((action) => action.implication!.fromStatementId === boycott.id), false); }); test('written planning artifacts reload into the same campaign plan', async () => { From a441c7d62d1a0a17634da1f6a90fd2b4b35b34d3 Mon Sep 17 00:00:00 2001 From: Adam Spitz Date: Fri, 16 Oct 2026 20:35:06 -0400 Subject: [PATCH 19/19] Fix contribution totals and reject colliding campaign statements --- fake-data-generation/campaignPlanner.ts | 1 + .../test/campaignPlanner.test.ts | 7 ++++ .../lib/bridgeContributions.test.ts | 37 +++++++++++++++++-- ui/src/commonality/lib/bridgeContributions.ts | 13 +++++-- 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/fake-data-generation/campaignPlanner.ts b/fake-data-generation/campaignPlanner.ts index 42536554..c39bc01d 100644 --- a/fake-data-generation/campaignPlanner.ts +++ b/fake-data-generation/campaignPlanner.ts @@ -629,6 +629,7 @@ export async function buildCampaignPlan(manifest: CampaignManifestV1): Promise [action.id, action])); const statementIds = new Set(statements.map((item) => item.id)); const userIds = new Set(users.map((item) => item.id)); const projectIds = new Set(projects.map((item) => item.id)); + if (statementIds.size !== statements.length) throw new Error('planned statement IDs must be unique'); if (actionById.size !== actions.length) throw new Error('planned action IDs must be unique'); for (const action of actions) { if (action.actorUserId !== null && !userIds.has(action.actorUserId)) throw new Error(`${action.id} has missing actor ${action.actorUserId}`); diff --git a/fake-data-generation/test/campaignPlanner.test.ts b/fake-data-generation/test/campaignPlanner.test.ts index ac1447e0..3699bdec 100644 --- a/fake-data-generation/test/campaignPlanner.test.ts +++ b/fake-data-generation/test/campaignPlanner.test.ts @@ -23,6 +23,13 @@ test('planner emits an identical, complete plan for the same seed', async () => assert.equal(first.users.some((user) => 'privateKey' in user || 'address' in user), false); }); +test('validation rejects catalog statements that collide on a planned ID', async () => { + const manifest = await loadManifest(); + const plan = await buildCampaignPlan(manifest); + plan.statements[1].id = plan.statements[0].id; + assert.throws(() => validatePlannedActions(manifest, plan.statements, plan.users, plan.projects, plan.actions), /planned statement IDs must be unique/); +}); + test('v2 gives every cause a concrete project and bridge projects use shared outcomes', async () => { const manifest = JSON.parse(await readFile(new URL('../campaigns/medium-realistic-v2.json', import.meta.url), 'utf8')) as CampaignManifestV1; const plan = await buildCampaignPlan(manifest); diff --git a/ui/src/commonality/lib/bridgeContributions.test.ts b/ui/src/commonality/lib/bridgeContributions.test.ts index 8d15f37a..9c5db672 100644 --- a/ui/src/commonality/lib/bridgeContributions.test.ts +++ b/ui/src/commonality/lib/bridgeContributions.test.ts @@ -14,10 +14,10 @@ describe('buildBridgeContributions', () => { { user: '0xC', viaStatementCid: 'bridge-c' }, ], pledges: [ - { active: true, token: '0xToken', causeRef: 'bridge-b', amountPerPeriod: '5' }, - { active: false, token: '0xToken', causeRef: 'bridge-b', amountPerPeriod: '9' }, - { active: true, token: '0xOther', causeRef: 'bridge-a', amountPerPeriod: '100' }, - { active: true, token: '0xToken', causeRef: 'target', amountPerPeriod: '50' }, + { active: true, token: '0xToken', causeRef: 'bridge-b', period: '2592000', amountPerPeriod: '5' }, + { active: false, token: '0xToken', causeRef: 'bridge-b', period: '2592000', amountPerPeriod: '9' }, + { active: true, token: '0xOther', causeRef: 'bridge-a', period: '2592000', amountPerPeriod: '100' }, + { active: true, token: '0xToken', causeRef: 'target', period: '2592000', amountPerPeriod: '50' }, ], paymentToken: '0xToken', projects: [ @@ -69,4 +69,33 @@ describe('buildBridgeContributions', () => { expect(rows.map((row) => row.viaStatementCid)).toEqual(['big']) expect(omitted).toBe(1) }) + + it('excludes projects directly aligned with another statement on the same board', () => { + const project = { + projectAddress: '0xProject', + totalReceived: '99', + fundingCurrency: eth, + } + const { rows } = buildBridgeContributions({ + viaStatementCids: ['bridge'], + supporters: [], + pledges: [], + projects: [ + { ...project, alignmentType: 'indirect', viaStatementCids: ['bridge'] }, + { ...project, projectAddress: '0xproject', alignmentType: 'direct' }, + ], + }) + expect(rows).toEqual([]) + }) + + it('normalizes pledge periods to 30 days and requires the configured token', () => { + const input = { + viaStatementCids: ['bridge'], + supporters: [], + projects: [], + pledges: [{ active: true, token: '0xToken', causeRef: 'bridge', amountPerPeriod: '7', period: '604800' }], + } + expect(buildBridgeContributions({ ...input, paymentToken: '0xToken' }).rows[0]?.pledgedMonthly).toBe(30n) + expect(buildBridgeContributions(input).rows).toEqual([]) + }) }) diff --git a/ui/src/commonality/lib/bridgeContributions.ts b/ui/src/commonality/lib/bridgeContributions.ts index 796a8134..d6f0aede 100644 --- a/ui/src/commonality/lib/bridgeContributions.ts +++ b/ui/src/commonality/lib/bridgeContributions.ts @@ -17,6 +17,7 @@ export interface BridgePledge { token: string causeRef: string amountPerPeriod: string + period: string } export interface BridgeProject { @@ -63,15 +64,21 @@ export function buildBridgeContributions(input: { for (const pledge of input.pledges) { if (!pledge.active) continue if (!vias.has(pledge.causeRef)) continue - if (token && pledge.token.toLowerCase() !== token) continue - const amount = BigInt(pledge.amountPerPeriod) + if (!token || pledge.token.toLowerCase() !== token) continue + const period = BigInt(pledge.period) + if (period <= 0n) continue + const amount = BigInt(pledge.amountPerPeriod) * 2_592_000n / period pledged.set(pledge.causeRef, (pledged.get(pledge.causeRef) ?? 0n) + amount) } const raised = new Map>() const seenProjects = new Set() + const directProjects = new Set(input.projects + .filter((project) => project.alignmentType === 'direct') + .map((project) => project.projectAddress.toLowerCase())) const indirect = input.projects - .filter((project) => project.alignmentType === 'indirect') + .filter((project) => project.alignmentType === 'indirect' + && !directProjects.has(project.projectAddress.toLowerCase())) .slice() .sort((a, b) => a.projectAddress.toLowerCase().localeCompare(b.projectAddress.toLowerCase())) for (const project of indirect) {