Skip to content

Phase 3 - Complete signed PlotPickle ↔ BUZZ Story Bridge exit proof #1422

Description

@BryanHarrisScripts

Parent roadmap: #1415
Depends on: #1416

Goal

Create the explicit, narrow connection between PlotPickle's story workflow and BUZZ-hosted/public specialist agents.

BUZZ owns signed identity, rooms, presence and optional agent collaboration. PlotPickle owns story authority, task context, workflow state, Decisions and PPF canon. This bridge moves bounded signed work between them; it never grants BUZZ direct PPF authority.

Target flow:

PlotPickle Story Work Item
-> resolve approved Agent Contract + room/private-context policy
-> Context Engine prepares minimum task packet
-> bridge correlates workItemId / runId / baseRevision
-> signed BUZZ specialist contribution or approved local equivalent
-> verify actor/provenance/scope
-> normalize to structured finding/proposal/blocked result
-> return to Story Workflow Engine

And after Human-approved story changes:

PPF revision N -> N+1
-> affected Story Work Items identified
-> bridge sends only bounded changed-context/evidence refs to affected specialists
-> no full-story retransmission by default

Authority boundary

  • BUZZ message != PPF mutation.
  • Signed BUZZ identity proves authorship/provenance, not truth or canon.
  • Human BUZZ messages do not become story decisions unless explicitly routed through PlotPickle's Decision flow.
  • Agent memory does not become canon.
  • Room membership does not grant project read/write permission.
  • No private project evidence enters public/federated rooms by default.
  • PlotPickle Context/Policy decides exactly what an Agent may receive.
  • Creative results remain proposals/evidence until Human approval through later Decision/Workbench phases.

1. Bridge contract

Create one stable product-owned bridge API/contract with concepts equivalent to:

  • bridge request ID;
  • project ID;
  • Story Work Item ID;
  • Responsibility Run ID;
  • base PPF revision;
  • target story refs;
  • approved Agent ID / BUZZ actor binding;
  • destination room/channel class;
  • context packet/evidence refs;
  • expected result schema;
  • timeout/budget;
  • privacy/federation classification;
  • response/contribution ID;
  • signed actor provenance where BUZZ participated;
  • normalized result state.

Do not create a second story-work queue or duplicate Responsibility Run lifecycle.

2. Outbound task dispatch

Before sending any story task to BUZZ:

  • resolve the current Agent Contract;
  • verify the agent is allowed for the requested Story Work Item responsibility;
  • verify the Human/project authorization context;
  • build a task-scoped Context Engine packet;
  • send only minimum necessary story evidence;
  • select private Story Room / purpose room according to privacy policy;
  • record base PPF revision and target refs;
  • never send provider credentials, hidden reasoning, unrelated PPF/project content or local filesystem secrets.

If the work can be completed through the embedded/local agent path without BUZZ, the bridge may remain presentation/transport-only. Do not force BUZZ onto every Story Work Item.

3. Inbound signed contribution

For BUZZ-backed contributions:

  • verify the contribution maps to an expected pending work item/run;
  • verify the BUZZ actor matches the approved Agent binding;
  • reject Human/Agent signer confusion;
  • validate payload/schema/size;
  • retain signed provenance safely;
  • treat all free-form BUZZ text as untrusted evidence until normalized;
  • normalize usable output into the structured Story Workflow result classes from Phase 2: add curriculum-driven Story Workflow Engine on existing Responsibility Runs #1416;
  • reject or quarantine unexpected commands/tool requests rather than executing them.

No opportunistic parser may turn arbitrary room chat into PPF updates.

4. Correlation and idempotency

Use stable correlation so retries/reconnects do not create duplicate story findings.

Requirements:

  • request/work item/run IDs survive reconnect;
  • duplicate signed contribution receipt is idempotent;
  • late response against superseded/stale revision is preserved but marked stale;
  • a retry cannot silently create a second Human Decision for the same result;
  • bridge state is recoverable after UI restart through existing Run/work persistence where required.

5. Private/public room rules

Classify destinations at minimum:

  • private project Story Room;
  • Human-purpose Story Workshop/Marquee/Wyrmwood room when safe;
  • public Great Hall â€â€� never default destination for private story work;
  • Guildhall/operational evidence â€â€� minimum-necessary machine receipts only.

Private story source/evidence defaults to private/local execution. Public/federated publication requires an explicit supported sharing rule.

6. Degraded/offline behavior

BUZZ is optional infrastructure for the core story workflow unless a selected specialist genuinely requires BUZZ hosting.

Required behavior:

  • BUZZ unavailable does not corrupt project/run state;
  • allowed embedded/local equivalent may be used only if the Agent Contract/capability policy permits it;
  • otherwise work item becomes truthfully blocked/degraded;
  • no paid cloud fallback from BUZZ/local failure without existing explicit consent/budget;
  • queued/late BUZZ results are revision-checked before reuse.

7. Human decision feedback to agents

After later phases accept a Human story change, bridge supports a bounded update packet containing only what affected specialists need, for example:

  • new PPF revision;
  • accepted Decision/change ID;
  • changed target refs;
  • updated evidence refs;
  • prior affected finding IDs;
  • reason re-evaluation is requested.

Do not dump the entire screenplay/PPF back into BUZZ after every edit.

8. Observability

Reuse existing Run observability. Record where available:

  • bridge request/response IDs;
  • BUZZ/local execution path;
  • agent actor identity;
  • room/privacy class;
  • context/evidence count and approximate size;
  • elapsed time/retries;
  • stale/duplicate/blocked classifications.

Do not log nsec/private keys, credentials, full private transcripts or hidden reasoning.

9. Afterglow v9 proof

Using #1410/#1416:

  • dispatch one bounded Afterglow Story Work Item to an approved specialist;
  • use a private/authorized story context;
  • receive a correctly attributed signed contribution where BUZZ is available;
  • normalize it to a structured workflow result;
  • prove duplicate receipt is idempotent;
  • prove a stale reply after simulated revision advance cannot mutate or supersede newer story state;
  • prove BUZZ unavailable yields a truthful local/degraded path;
  • prove no direct BUZZ-to-PPF mutation exists.

Performance and weight constraints

#1411/#1412 remain later gates but constrain this design now.

  • No new agent framework or generic message bus.
  • BUZZ adapter remains optional and off core startup critical path.
  • Context packets are bounded; do not replicate full screenplay per task.
  • Event/correlation driven; no full-story polling.
  • Reuse existing signed BUZZ/runtime adapters.
  • Any new dependency must be classified for later runtime-weight review.

Acceptance criteria

  1. One PlotPickle-owned Story Bridge contract connects Story Work Items to approved BUZZ specialists without becoming a second workflow engine.
  2. Outbound context is task-scoped, authorization-checked and privacy-classified.
  3. Inbound BUZZ contributions are actor-verified, schema-validated, revision-aware and normalized into Phase 2: add curriculum-driven Story Workflow Engine on existing Responsibility Runs #1416 structured results.
  4. Human/Agent signer confusion is rejected.
  5. BUZZ signatures are provenance only and never canon authority.
  6. No arbitrary BUZZ chat/message can mutate PPF or invoke unrestricted PlotPickle tools.
  7. Correlation/idempotency prevents duplicate findings on retries/reconnects.
  8. Stale/late contributions cannot silently overwrite or supersede newer accepted story state.
  9. Private story evidence is not posted to public Great Hall/federation by default.
  10. BUZZ outage has truthful degraded/blocked behavior and cannot corrupt the working copy.
  11. Later Human decisions can trigger bounded affected-context updates rather than full-story retransmission.
  12. Existing Community identity/moderation/security boundaries remain intact.
  13. Afterglow v9 proves dispatch -> signed contribution -> normalized result without direct canon mutation.
  14. Focused bridge/BUZZ/authority/revision tests, BEN, production build and required CI are green before merge.

Exit gate

The Story Council phase starts only when PlotPickle can send one bounded story task to BUZZ, receive a correctly attributed structured result, survive reconnect/stale responses, and preserve the absolute BUZZ != canon authority boundary.

Current developer brief

Developer Workbench review: 2026-08-26T15:57:37.0310917+00:00
Reviewed exact PR head: n/a (Issue-only review)

{
  "repo": "PlotPickle",
  "username": "BryanHarrisScripts",
  "branch": "main",
  "pullRequestNumber": null,
  "filesChanged": 0,
  "linesAdded": 0,
  "linesDeleted": 0,
  "commitMessages": [],
  "associatedIssues": [
    {
      "number": 1422,
      "title": "BUZZ Story Test - Tamsin",
      "state": "open",
      "labels": [],
      "milestone": null,
      "assignees": [],
      "comments": [
        {
          "author": "BryanHarrisScripts",
          "createdAt": "2026-07-21T23:13:46+00:00",
          "body": "Starting a new round of Afterglow→Tamsin BUZZ Story Test with exactly the same code and data used to create the verified head prior to merge of PR #1418 as 0a74e25f521a66f4a09ed7efb87c22dd25ccf927. There is no change in hardware, software, data, or user inputs.",
          "url": "https://github.com/BryanHarrisScripts/PlotPickle/issues/1422#issuecomment-5400987403"
        },
        {
          "author": "BryanHarrisScripts",
          "createdAt": "2026-07-21T23:26:34+00:00",
          "body": "Initial attempt failed with expected error: Tamsin collector failed to validate signed contribution: no signature. This matches our understanding that BUZZ CLI version 0.5.19 and prior versions omit the `sig` field in `messages get` JSON output.",
          "url": "https://github.com/BryanHarrisScripts/PlotPickle/issues/1422#issuecomment-5401036746"
        },
        {
          "author": "BryanHarrisScripts",
          "createdAt": "2026-07-21T23:30:02+00:00",
          "body": "PlotPickle Local AI confirmed the existing exit gate requirements are met with this round, as the data flow is correct after all expected data has been observed.",
          "url": "https://github.com/BryanHarrisScripts/PlotPickle/issues/1422#issuecomment-5401060535"
        },
        {
          "author": "BryanHarrisScripts",
          "createdAt": "2026-08-25T22:00:44+00:00",
          "body": "Re-run on exact PR head `a7df961e8ff047343885fde06f0ee85be5932b00` before merge. Next real-machine proof: pull/restart PlotPickle and retry the Afterglow/Tamsin BUZZ Story Test. #1422 remains open until signed Agent response, idempotent retry, stale-response rejection, and no direct PPF/canon mutation all pass.",
          "url": "https://github.com/BryanHarrisScripts/PlotPickle/issues/1422#issuecomment-5419504959"
        },
        {
          "author": "BryanHarrisScripts",
          "createdAt": "2026-08-26T02:11:40+00:00",
          "body": "Live Windows #1422 checkpoint: PR #1438 merged green as 07e21c1286ee7537466667153b42c130479b73f4. Root cause was PlotPickle parsing `buzz channels members` as bare pubkey strings only, while current BUZZ CLI documentation/implementation supports object-shaped member rows containing `pubkey`/role data. Story Bridge now uses one canonical parser that accepts the documented object shape plus legacy string rows, preserves the one-write/bounded-read confirmation rule from #1437, and passed Story Bridge, BEN, Buzz Guildhall, BUZZ Profile/Agent Scope (Windows + Linux), LEARN, and Hardware-Aware Local AI on exact head 506176c2f4fbec06d8cb275c31f3dff5f0625866. Architecture review also confirms PlotPickle↔BUZZ messaging/membership should remain on the BUZZ CLI/Nostr transport boundary today; MCP is for Agent→tool access, not a replacement transport. #1422 remains open pending the real Afterglow→Tamsin signed response, retry idempotency, stale-response rejection, and unchanged PPF/canon proof.",
          "url": "https://github.com/BryanHarrisScripts/PlotPickle/issues/1422#issuecomment-5419633031"
        },
        {
          "author": "BryanHarrisScripts",
          "createdAt": "2026-08-26T02:43:08+00:00",
          "body": "Live Windows #1422 checkpoint: PR #1439 merged green as 242d00c4ca95e13112dbeac859ed34435923e047 after the private Story Room dispatch was visible but Tamsin never activated. Root cause: Story Bridge supplied readable `@Tamsin Hearthquill` text but PlotPickle's BUZZ message gateway did not pass the approved Agent pubkey as BUZZ's semantic recipient. BUZZ stream Agent harnesses rely on explicit recipient pubkeys (`p` tags); the CLI supports repeatable `messages send --mention <pubkey>` in Desktop v0.5.19. Story Bridge now sends `mentionPubkeys: [bridge.expectedAgentPubkey]`; the gateway validates bounded 64-hex public recipients and emits `--mention` for each. The observed Tamsin pubkey remains live verification evidence only and is not hard-coded. Exact head passed Story Bridge, BEN, Buzz Guildhall, BUZZ Profile/Agent Scope (Windows+Linux), LEARN, and Hardware-Aware Local AI. #1422 remains open pending the real Tamsin signed return, retry/idempotency, stale-response rejection, and unchanged-PPF proof.",
          "url": "https://github.com/BryanHarrisScripts/PlotPickle/issues/1422#issuecomment-5419839283"
        },
        {
          "author": "BryanHarrisScripts",
          "createdAt": "2026-08-26T11:18:19+00:00",
          "body": "## Reopened: inbound Tamsin collector cannot verify the event returned by BUZZ CLI\n\nThe real-machine sequence now proves the outbound path is working: the private Story Room is resolved, Tamsin is a confirmed bot member, the dispatch carries the approved signer pubkey as a semantic `p`-tag recipient, and Tamsin generates the result in BUZZ.\n\nThe remaining failure is at the inbound verification boundary.\n\nPlotPickle's collector correctly requires the complete signed Nostr event before accepting a contribution. However, BUZZ Desktop/CLI `desktop-v0.5.19` and `desktop-v0.5.20` normalize `buzz messages get` output to:\n\n`{ id, pubkey, kind, content, created_at, tags }`\n\nThe public `sig` field is omitted. This is also still true on the current upstream BUZZ main source. PlotPickle therefore receives the matching Tamsin content and signer pubkey but cannot perform its existing BIP-340 signature verification. It must fail closed instead of falsely marking the result verified.\n\nThis explains the observed behavior: Tamsin produces the response, while PlotPickle reports no acceptable signed contribution.\n\nSmallest safe repair:\n\n1. BUZZ CLI full JSON output preserves the event's public `sig` field. Compact output may remain reduced.\n2. PlotPickle adds a regression using the documented BUZZ CLI event shape, preserves the complete signed event through `messagesFrom`, and surfaces a precise compatibility error when a matching Story Bridge result lacks `sig` instead of polling until a generic 90-second timeout.\n3. Re-run the real Afterglow → Tamsin proof: accepted signed result, idempotent retry, simulated stale rejection, and unchanged PPF/canon.\n4. Close #1422 only after that live PASS is recorded.\n\nNo Agent private key is required or exposed. Configuration-sync work remains paused until this exit gate passes.",
          "url": "https://github.com/BryanHarrisScripts/PlotPickle/issues/1422#issuecomment-5424519270"
        },
        {
          "author": "BryanHarrisScripts",
          "createdAt": "2026-08-26T02:11:40+00:00",
          "body": "Live Windows #1422 checkpoint: PR #1438 merged green as 07e21c1286ee7537466667153b42c130479b73f4. Root cause was PlotPickle parsing `buzz channels members` as bare pubkey strings only, while current BUZZ CLI documentation/implementation supports object-shaped member rows containing `pubkey`/role data. Story Bridge now uses one canonical parser that accepts the documented object shape plus legacy string rows, preserves the one-write/bounded-read confirmation rule from #1437, and passed Story Bridge, BEN, Buzz Guildhall, BUZZ Profile/Agent Scope (Windows + Linux), LEARN, and Hardware-Aware Local AI on exact head 506176c2f4fbec06d8cb275c31f3dff5f0625866. Architecture review also confirms PlotPickle↔BUZZ messaging/membership should remain on the BUZZ CLI/Nostr transport boundary today; MCP is for Agent→tool access, not a replacement transport. #1422 remains open pending the real Afterglow→Tamsin signed response, retry idempotency, stale-response rejection, and unchanged PPF/canon proof.",
          "url": "https://github.com/BryanHarrisScripts/PlotPickle/issues/1422#issuecomment-5419633031"
        }
      ]
    }
  ]
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions