{
 "about": "Every member of the team that runs this site, human and agent: who they are, what they own, the pages that are their home, how to reach them, and the work they hold. Kept by conductor@php.newsroom. The tasks shown on each member's page are the board in data/admin.json, whose owners map to members through board_owners; between releases the truth for tasks is the issues vault, and for messages the mail vault.",
 "kept_by": "conductor",
 "cycle": {
  "name": "The run",
  "about": "When the team runs on a schedule, every run has three phases in this order, so nobody starts work the conductor has not mapped and no run ends without the team knowing what changed.",
  "phases": [
   {
    "name": "Open",
    "who": "conductor",
    "what": "Pull the conductor, issues and mail vaults; drain the conductor's lane; read every member's open and blocked issues; write the run plan (who does what this run, what is blocked on whom); send each member its assignments as mail; broadcast the plan."
   },
   {
    "name": "Work",
    "who": "every agent with assignments",
    "what": "Each agent runs its check-in cycle in the mail vault: pull, deliver its mail, OPEN the tasks it accepts in its own queue in the issues vault, do the work, release through admin/build/release.sh, CLOSE what is done, reply to the conductor (mail or the lane), one commit per cycle, push."
   },
   {
    "name": "Close",
    "who": "conductor",
    "what": "Pull everything again; drain the lane; reconcile what was planned against what was done and released; update the roster and each member's page; write the run's status digest; broadcast it to the humans and agents; release the site's snapshot of the team."
   }
  ]
 },
 "channels": [
  {
   "id": "conductor",
   "vault": "5iwos28w",
   "name": "The conductor vault",
   "writes": "conductor only",
   "reads": "every member, with the read key",
   "holds": "The roster, the run plans, the status digests, the broadcasts, and the messages members send to the conductor through its append lane (drained into inbox/).",
   "how": "Read: clone with the read key. Write to the conductor: encrypt to the conductor's public key (identity/conductor.public.json in the vault) and post to the lane with your own append token; or send mail. (Not in use yet: for now the team syncs through the repository.)"
  },
  {
   "id": "issues",
   "vault": "zjruy9vk",
   "name": "The issues vault (Issues-FS-lite)",
   "writes": "each member, only inside its own folder",
   "reads": "every member",
   "holds": "One queue per member: issues/<member>/open, blocked and done, one markdown file per task with YAML front-matter. Seeded from the board on 22 October 2026; from then on the vault is the truth and the board is the site's snapshot of it.",
   "how": "OPEN, BLOCK, UNBLOCK, CLOSE are four mv operations in your own folder. Nobody writes into another member's queue: work is asked for by mail, and the owner opens it. (Not in use yet: for now the team syncs through the repository.)"
  },
  {
   "id": "mail",
   "vault": "fmb2tpl2",
   "name": "The mail vault (Email-FS-lite)",
   "writes": "each member in its own folder, and any member into another's mailroom",
   "reads": "every member",
   "holds": "RFC 2822 .eml messages: mail/mailroom/<member>/ is the drop, mail/<member>/inbox, done and outbox are the member's own; mail/sessions/<member>/ holds its brief and notes.",
   "how": "Every session: pull, deliver your mailroom to your inbox, process, reply (mailroom of the recipient and a copy in your outbox), move finished mail to done, one commit, push. (Not in use yet: for now the team syncs through the repository.)"
  }
 ],
 "board_owners": {
  "editor": "dinis",
  "dev": "dev",
  "dev@php.newsroom": "dev",
  "claude-story-site": "story-site",
  "researcher@php.newsroom": "researcher",
  "collector-primary": "collector-primary",
  "collector-gov": "collector-gov",
  "collector-researchers": "collector-researchers",
  "librarian": "librarian",
  "verifier": "verifier",
  "factcheck": "verifier",
  "briefing-writer": "briefing-writer",
  "cartographer": "cartographer",
  "journalist": "journalist",
  "historian": "historian",
  "synthetic": "synthetic",
  "conductor": "conductor",
  "vicky": "vicky",
  "grc": "grc",
  "grc@php.newsroom": "grc"
 },
 "groups": [
  {
   "id": "humans",
   "name": "The humans",
   "about": "The two people on the team. They set direction and make the calls; every agent works for them."
  },
  {
   "id": "coordination",
   "name": "Coordination and comms",
   "about": "Keeps every member, human and agent, synchronised: what is assigned, what is blocked, what changed."
  },
  {
   "id": "site",
   "name": "Building the site",
   "about": "The build, the gate, the release, the design, and the pages."
  },
  {
   "id": "evidence",
   "name": "Evidence",
   "about": "Capture before you read: the sources, the vaults, the watch."
  },
  {
   "id": "writing",
   "name": "Writing and analysis",
   "about": "Stories, briefings, the catalogue, the graph and the checks on every claim."
  },
  {
   "id": "testing",
   "name": "Testing",
   "about": "Readers that are not people, reading the live site."
  }
 ],
 "members": [
  {
   "id": "dinis",
   "name": "Dinis Cruz",
   "kind": "human",
   "group": "humans",
   "alias": "@Dinis",
   "mail": "dinis.human",
   "role": "Editor",
   "status": "active",
   "summary": "Sets direction by voice memo, points agents at sources, reads what they wrote and says go.",
   "owns": [
    "every editorial call: what the lead is, which claim is called confirmed, what ships",
    "the briefs and the memos",
    "the vault keys"
   ],
   "rules": [
    "A brief is the editor's words, in either hand; agents write next to it, never over it.",
    "Nothing is published that the editor has not been able to check from the evidence."
   ],
   "home": [
    [
     "brief/index.html",
     "The brief"
    ],
    [
     "interview/index.html",
     "The editor's interview"
    ],
    [
     "admin/briefs/index.html",
     "Briefs"
    ],
    [
     "corrections/index.html",
     "Corrections"
    ]
   ],
   "achieved": [
    "Started the site from two voice memos and a message on 22 October 2026, and set every brief since.",
    "Renamed the site PHP October 2026 and set the rule that the front page opens with the situation, not the CVE numbers (v0.3.1).",
    "Set the rule that every page is metered (v0.2.10)."
   ]
  },
  {
   "id": "vicky",
   "name": "Vicky",
   "kind": "human",
   "group": "humans",
   "alias": "@Vicky",
   "mail": "vicky.human",
   "role": "Project manager",
   "status": "active",
   "joined": "2026-10-22",
   "summary": "Runs the project side: what is planned, who has it, what is late and what the editor needs to decide.",
   "owns": [
    "the plan and its priorities, with the editor",
    "the review of the conductor's run plans and digests",
    "chasing the decisions only a human can make (the needs on the board)"
   ],
   "rules": [
    "A task with no owner is not a task; a need with no date is not a plan.",
    "Ask the conductor, not the agents: one channel, so nothing is asked twice."
   ],
   "home": [
    [
     "team/index.html",
     "The team"
    ],
    [
     "admin/board/index.html",
     "The board"
    ]
   ],
   "achieved": [
    "Joined the team on 22 October 2026."
   ]
  },
  {
   "id": "conductor",
   "name": "Conductor",
   "kind": "agent",
   "group": "coordination",
   "alias": "@Conductor",
   "mail": "conductor",
   "address": "conductor@php.newsroom",
   "role": "Conductor and comms",
   "status": "active",
   "joined": "2026-10-22",
   "summary": "Maps the work, hands it out, and keeps every member, human and agent, synchronised. For now also the comms agent: the broadcasts and the digests.",
   "owns": [
    "the conductor vault (5iwos28w), which only it writes and every member reads, and its append lane",
    "the issues vault (zjruy9vk) and the mail vault (fmb2tpl2): their layout, their READMEs and their keys",
    "the roster (data/team.json), the team page and every member's page",
    "the run: opening it with a plan and closing it with a digest",
    "comms: broadcasts to the team and the status digest for the humans"
   ],
   "rules": [
    "Every task has one owner, and the owner opens it: the conductor asks by mail and never writes into another member's queue.",
    "A run opens with a plan and closes with a digest; nothing happens between the two that the digest does not account for.",
    "Say what is blocked and on whom, by name. A digest that hides a blocker is worse than none.",
    "Vault keys never go into a file, a page or a message; the read key goes to members privately."
   ],
   "home": [
    [
     "team/index.html",
     "The team"
    ],
    [
     "admin/board/index.html",
     "The board"
    ],
    [
     "admin/roles/index.html",
     "Roles"
    ]
   ],
   "achieved": [
    "Created the three coordination vaults (conductor, issues, mail) and the conductor's append lane.",
    "Moved the board's 68 items into the issues vault, one queue per owner.",
    "Mapped every member of the team, human and agent, with a page each."
   ]
  },
  {
   "id": "dev",
   "name": "dev@php.newsroom",
   "kind": "agent",
   "group": "site",
   "alias": "@Dev",
   "mail": "dev",
   "address": "dev@php.newsroom",
   "role": "Build, gate and release",
   "status": "active",
   "summary": "The build, the gate, the release, the data schema, the admin section, the telemetry and subscriptions lanes, and the site's reality file.",
   "owns": [
    "admin/build/ (build.py, validate.py, release.sh) and the data schema",
    "the admin section, the telemetry vault (84wr8mib) and the subscriptions vault (wgeiqabu)",
    "the phone app (/now/) and the deploy workflow",
    "REALITY.md"
   ],
   "rules": [
    "Every push is a version; the release is not done until the live site serves it.",
    "Content exists once: the build reads data/, never a page.",
    "Read keys yes, vault keys never; the append token is the only credential a page may carry."
   ],
   "home": [
    [
     "admin/index.html",
     "Admin"
    ],
    [
     "status/index.html",
     "The pipeline status"
    ],
    [
     "vaults/index.html",
     "The vaults"
    ],
    [
     "admin/telemetry/index.html",
     "Telemetry"
    ],
    [
     "subscribe/index.html",
     "Subscribe"
    ],
    [
     "now/index.html",
     "Now, the phone app"
    ]
   ],
   "achieved": [
    "The deploy workflow, the gate and release.sh, including releases from several agents at once (v0.2.12).",
    "Anonymous telemetry over an append lane into a private vault (v0.2.3).",
    "Subscriptions encrypted in the reader's browser to a write-only lane (v0.4.4).",
    "The phone app, deterministic and agentic (v0.5.0)."
   ]
  },
  {
   "id": "story-site",
   "name": "Story site agent",
   "kind": "agent",
   "group": "site",
   "alias": "@StorySite",
   "mail": "story-site",
   "address": "claude-story-site",
   "role": "Design, claims and the story pages",
   "status": "active",
   "summary": "Reads every note in the vault, writes the claims and timeline this site publishes, and designs the pages that carry them.",
   "owns": [
    "data/claims.json, timeline.json and the other authored data",
    "the front page, the facts, the patching and signals pages",
    "the coverage vault (dcsmxese) and its review"
   ],
   "rules": [
    "Every status is one of five words and the page says what each means.",
    "A number in prose names the file it was counted from."
   ],
   "home": [
    [
     "index.html",
     "The front page"
    ],
    [
     "claims/index.html",
     "Every claim"
    ],
    [
     "timeline/index.html",
     "The timeline"
    ],
    [
     "patching/index.html",
     "Patching"
    ],
    [
     "signals/index.html",
     "Signals"
    ]
   ],
   "achieved": [
    "The first release: every claim with a status and its sources (v0.1.0).",
    "Readers, the glossary and a jargon-free front page (v0.3.0, v0.3.1).",
    "Every section versioned with history and diffs (v0.3.2).",
    "The coverage vault and the review of 24 outlets (v0.4.5)."
   ]
  },
  {
   "id": "newsroom-lead",
   "name": "Newsroom lead",
   "kind": "agent",
   "group": "evidence",
   "alias": "@NewsroomLead",
   "mail": "newsroom-lead",
   "address": "claude-newsroom-lead",
   "role": "The evidence vault's protocol",
   "status": "active",
   "summary": "Owns the evidence vault's protocol and capture tool, merges the collectors' branches, and keeps the newsroom's own section on the story.",
   "owns": [
    "the evidence vault (3ytzxm3g): its README, the capture tool, the merges",
    "the newsroom's section on the story"
   ],
   "rules": [
    "One file per agent per concern, so a merge never asks a human to pick between two agents' edits."
   ],
   "home": [
    [
     "admin/vault/index.html",
     "The evidence vault"
    ],
    [
     "sources/index.html",
     "Every source"
    ]
   ],
   "achieved": [
    "Replaced the shared manifest with one source.json per source and a generated index."
   ]
  },
  {
   "id": "collector-primary",
   "name": "Primary-source collector",
   "kind": "agent",
   "group": "evidence",
   "alias": "@CollectorPrimary",
   "mail": "collector-primary",
   "role": "Primary sources",
   "status": "active",
   "summary": "php.net, the CVE and NVD records, the GitHub advisories, tags and branches, oss-security and the php-src clone.",
   "owns": [
    "the primary sources in the evidence vault"
   ],
   "rules": [
    "Capture before you read. A page you summarised but did not capture does not exist.",
    "One source.json and one notes.md per source; never edit another agent's files."
   ],
   "home": [
    [
     "sources/index.html",
     "Every source"
    ]
   ],
   "achieved": [
    "Captured the primary record; kept the blank NVD capture as the record of the attempt and took the record from the API."
   ]
  },
  {
   "id": "collector-gov",
   "name": "Government and CERT collector",
   "kind": "agent",
   "group": "evidence",
   "alias": "@CollectorGov",
   "mail": "collector-gov",
   "role": "Agencies and CERTs",
   "status": "active",
   "summary": "Every national agency's advisory, in its own language, with the translation marked.",
   "owns": [
    "the agency sources in the evidence vault",
    "the NCSC-NL inventory's export"
   ],
   "rules": [
    "What an agency does not say is a finding.",
    "A blocked fetch is recorded with the challenge page's hash, not retried blind."
   ],
   "home": [
    [
     "agencies/index.html",
     "The agencies"
    ],
    [
     "affected/index.html",
     "Affected systems"
    ]
   ],
   "achieved": [
    "Captured sixteen agencies' positions, including what each does not say."
   ]
  },
  {
   "id": "collector-researchers",
   "name": "Researcher, vendor and press collector",
   "kind": "agent",
   "group": "evidence",
   "alias": "@CollectorResearchers",
   "mail": "collector-researchers",
   "role": "Researchers, vendors and the press",
   "status": "active",
   "summary": "Calif, Wiz, OpenAI, Cloudflare, Amazon, Imperva, Fastly, Akamai, the detection rule sets and the press.",
   "owns": [
    "the researcher, vendor and press sources in the evidence vault"
   ],
   "rules": [
    "Social posts first, because they get deleted; decode a post's time from its id."
   ],
   "home": [
    [
     "actors/index.html",
     "The parties"
    ],
    [
     "exploitation/index.html",
     "Exploitation signals"
    ]
   ],
   "achieved": [
    "Captured the researchers' and vendors' accounts; marked openai.com and Techzine second-hand where a bot challenge blocked them."
   ]
  },
  {
   "id": "researcher",
   "name": "researcher@php.newsroom",
   "kind": "agent",
   "group": "evidence",
   "alias": "@Researcher",
   "mail": "researcher",
   "address": "researcher@php.newsroom",
   "role": "The source watch",
   "status": "active",
   "summary": "Runs the source watch: every outside source on the story checked on a schedule, a snapshot whenever it changes.",
   "owns": [
    "the source watch vault (oq9gflln)"
   ],
   "rules": [
    "A snapshot only when the content changed; every check records what access it had."
   ],
   "home": [
    [
     "vaults/source-watch/index.html",
     "The source watch"
    ],
    [
     "reader/index.html",
     "The feed viewer"
    ]
   ],
   "achieved": [
    "Published the source watch with its read key, its taxonomy and graphs at four altitudes (v0.2.13)."
   ]
  },
  {
   "id": "librarian",
   "name": "librarian@php.newsroom",
   "kind": "agent",
   "group": "writing",
   "alias": "@Librarian",
   "mail": "librarian",
   "address": "librarian@php.newsroom",
   "role": "The catalogue",
   "status": "active",
   "joined": "v0.2.6",
   "summary": "Which page answers which question, the questions readers actually ask, and the articles readers have seen that the vault has not captured.",
   "owns": [
    "data/questions.json and /questions/"
   ],
   "rules": [
    "Answer a question with a page, not a paragraph; if no page answers it, write the answer with its sources and open a board item.",
    "An article a reader saw is listed as seen, not captured, until a collector captures it.",
    "Strip personal share tokens from any link a reader sends."
   ],
   "home": [
    [
     "questions/index.html",
     "Questions"
    ],
    [
     "readings/index.html",
     "Second readings"
    ]
   ],
   "achieved": [
    "Ten questions readers ask, each with a short answer and the pages that carry it (v0.2.6)."
   ]
  },
  {
   "id": "journalist",
   "name": "Journalist",
   "kind": "agent",
   "group": "writing",
   "alias": "@Journalist",
   "mail": "journalist",
   "address": "claude-journalist",
   "role": "Dated state-of-affairs articles",
   "status": "active",
   "summary": "What is settled, where the alarm and the evidence part company, and what would change the story.",
   "owns": [
    "admin/content/articles/*__journalist__*.md",
    "the review of the front page and navigation"
   ],
   "rules": [
    "An article names the site version, vault commit and capture time it was written against, and is not revised afterwards.",
    "Every factual sentence cites a captured source; the gate refuses an unknown one."
   ],
   "home": [
    [
     "articles/index.html",
     "Stories"
    ]
   ],
   "achieved": [
    "The first house stories, and the review of the front page and navigation.",
    "Exposed is not exploited, with the historian (v0.4.3)."
   ]
  },
  {
   "id": "historian",
   "name": "Historian",
   "kind": "agent",
   "group": "writing",
   "alias": "@Historian",
   "mail": "historian",
   "address": "claude-historian",
   "role": "Perspective and the record",
   "status": "active",
   "summary": "Dated essays that set the story against earlier vulnerabilities; the release history, the corrections file and the reality file.",
   "owns": [
    "admin/content/articles/*__historian__*.md",
    "BRIEF-CORRECTIONS.md"
   ],
   "rules": [
    "Say how early you are writing; mark a reading as a reading.",
    "A correction is published above the mistake, dated, with the mistake left visible."
   ],
   "home": [
    [
     "articles/index.html",
     "Stories"
    ],
    [
     "corrections/index.html",
     "Corrections"
    ],
    [
     "versions/index.html",
     "Versions"
    ]
   ],
   "achieved": [
    "The first essay, at v0.2.5, naming the evidence that would overturn its own readings."
   ]
  },
  {
   "id": "synthetic",
   "name": "synthetic@php.newsroom",
   "kind": "agent",
   "group": "testing",
   "alias": "@Synthetic",
   "mail": "synthetic",
   "address": "synthetic@php.newsroom",
   "role": "Synthetic readers",
   "status": "active",
   "summary": "Six test readers who read the live site in a real browser every hour or when it changes, and review it in their own voice.",
   "owns": [
    "admin/synthetic/, the six readers' vaults and their runs",
    "data/synthetic.json and the synthetic readers page"
   ],
   "rules": [
    "A synthetic reader is a test instrument: its review is a prompt for the editor, never evidence and never readership.",
    "Every failure a reader reports names the page and the words or measurement that show it."
   ],
   "home": [
    [
     "admin/synthetic/index.html",
     "Synthetic readers"
    ]
   ],
   "achieved": [
    "The first run of six readers through the live site, with verdicts, scores and requested changes (v0.4.6)."
   ]
  },
  {
   "id": "briefing-writer",
   "name": "Briefing writer",
   "kind": "role",
   "group": "writing",
   "alias": "@BriefingWriter",
   "mail": "briefing-writer",
   "role": "One page per audience",
   "status": "covered by dev@php.newsroom until filled",
   "summary": "One page per audience from the same claims.",
   "owns": [
    "briefings/"
   ],
   "rules": [
    "A briefing adds no claim. It selects and orders, and every line keeps its source."
   ],
   "home": [
    [
     "start/index.html",
     "Start here"
    ]
   ],
   "achieved": []
  },
  {
   "id": "cartographer",
   "name": "Cartographer",
   "kind": "role",
   "group": "writing",
   "alias": "@Cartographer",
   "mail": "cartographer",
   "role": "The graph",
   "status": "unfilled",
   "summary": "Sources, claims, events, actors and the edges between them; the JSON every page is drawn from.",
   "owns": [
    "data/graph.json and the graph pages"
   ],
   "rules": [
    "A node is just a node. Meaning lives in the edges; an edge without a source is deleted."
   ],
   "home": [
    [
     "graph/index.html",
     "The graph"
    ]
   ],
   "achieved": []
  },
  {
   "id": "verifier",
   "name": "Fact-check desk",
   "kind": "agent",
   "group": "writing",
   "alias": "@Factcheck",
   "mail": "verifier",
   "role": "Every claim graded on a spectrum of evidence",
   "status": "active",
   "summary": "factcheck@php.newsroom. Grades every claim independently against the captures it cites: what kind of statement it is, its level of evidence from A0 to A6, what contradicts it, and whether its status word claims more than the evidence carries. Opens a ticket wherever the answer is 'not as far as the site says'; highlights, does not fix. Runs on a schedule.",
   "owns": [
    "admin/factcheck/: the assessments, the contradiction ledger, the desk's Issues-FS tickets and run reports",
    "data/factcheck.json and /factcheck/"
   ],
   "rules": [
    "A quote that is not in the captured text is not a quote. Mark it and say which capture was checked.",
    "Grade the statement as worded, from captures the desk opened; name the file and its sha256.",
    "Ten outlets restating one headline are one source.",
    "Outside evidence is a request to capture, never a citation.",
    "Highlight, do not fix."
   ],
   "home": [
    [
     "factcheck/index.html",
     "Fact-check: how sure we are"
    ],
    [
     "claims/index.html",
     "Every claim"
    ]
   ],
   "achieved": [
    "Run 1, 22 October: all 70 claims graded against vault 31ccc515c29f; 3 high and 56 medium findings, 10 contradictions recorded, 6 pieces of outside evidence; Italy's offline advice found misread"
   ]
  },
  {
   "id": "grc",
   "name": "GRC desk",
   "kind": "agent",
   "group": "writing",
   "alias": "@GRC",
   "mail": "grc",
   "role": "Risks, who carries them, and the standards that govern them",
   "status": "active",
   "joined": "2026-10-22",
   "summary": "grc@php.newsroom. Keeps the fractal risk registers for php2shell: every risk broken down until it can be owned, assigned to every stakeholder that carries part of it with the part each plays, joined edge by edge to the weakness, vulnerability, fix, code, stories and roles behind it, and mapped to the controls of GDPR, NIS2, the Cyber Resilience Act, DORA, the EU AI Act, ISO 27001, NIST and the rest. Records risks and their holders; accepts nothing on anyone's behalf.",
   "owns": [
    "data/grc.json, data/grc-frameworks.json and data/grc-network.json",
    "the GRC section, /grc/, and data/grc-graph.json"
   ],
   "rules": [
    "A risk with no owner is not on the register: find who can act on it.",
    "Every risk is backed by a claim or a page already on this site; a rating is a judgement and says its basis.",
    "Nobody accepts a risk on anyone else's behalf, this desk included.",
    "A mapping to a control says what a holder will be asked about, never that it complies.",
    "Every edge is a verb with a named inverse; nothing is merely related."
   ],
   "home": [
    [
     "grc/index.html",
     "GRC: risks, owners, standards"
    ],
    [
     "grc/graph/index.html",
     "The risk graph"
    ],
    [
     "briefings/dpo/index.html",
     "Briefing for a data protection officer"
    ]
   ],
   "achieved": [
    "22 October: the first registers: 34 risks under 10 at the top, 53 stakeholders, 14 weaknesses, 20 frameworks and 120 controls; every risk with a path to code and to a team member, 30 of 34 to a vulnerability and to a role inside an organisation, 26 of 34 to a story, and the gaps named on /grc/",
    "22 October: the data protection officer added to the readers, with a briefing: was personal data exposed, when the GDPR 72-hour clock starts, what to ask processors and what to document"
   ]
  }
 ],
 "now": "For now the team synchronises through this repository and the site, which are public: each agent maps what it has to do and what it has done on its own branch, the board and its own article, as AGENTS.md and the librarian's guidance say, and the conductor reads them. The three coordination vaults are set up and wait for later."
}
