Skip to content

feat: add GitHub project rooms - #131

Open
Solvely-Colin wants to merge 18 commits into
openclaw:mainfrom
Solvely-Colin:s/github-project-rooms
Open

feat: add GitHub project rooms#131
Solvely-Colin wants to merge 18 commits into
openclaw:mainfrom
Solvely-Colin:s/github-project-rooms

Conversation

@Solvely-Colin

@Solvely-Colin Solvely-Colin commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

ClickClack workspaces have channels and integrations, but no durable project boundary that links repositories, collaborators, and GitHub activity. Teams must manually reconstruct project context across GitHub and chat, while pull requests, issues, reviews, comments, and checks do not form shared collaboration threads.

Why This Change Was Made

This adds GitHub-linked project rooms: workspace managers can group one or more repositories and participants into a project, with a public collaboration channel created automatically. Signed GitHub webhooks turn pull requests and issues into channel threads, then route reviews, comments, updates, and checks into replies with delivery deduplication and retry-safe processing.

Repository setup now has two paths:

  • Connect GitHub: authorize a temporary GitHub setup grant, select one or more repositories the account can administer, and let ClickClack create and verify the signed webhooks.
  • Manual setup: retain the payload URL and one-time secret flow for deployments that do not configure GitHub OAuth.

The project context API is intentionally read-only. This is a communications and context layer, not an agent harness, and it does not write project activity back to GitHub.

User Impact

  • Owners and moderators can connect GitHub and choose repositories from an authenticated picker.
  • Selecting one repository derives the project name from that repository; selecting multiple repositories uses a clear combined project name.
  • Owners and moderators can create projects linked to multiple GitHub repositories.
  • Projects appear in a dedicated workspace view and sidebar section.
  • Each project receives a collaboration channel and reuses the workspace GitHub bot identity.
  • New pull requests and issues create rich thread roots.
  • PR reviews, issue and PR comments, commits, merges, issue changes, and CI checks appear as replies.
  • Humans and bots can retrieve repositories, participants, and channel context through the project API.
  • Manual webhook setup remains available as a fallback.

Visibility Boundary

Project collaboration channels are visible to authenticated workspace members. GitHub permissions continue to control repository access, so a member who follows a repository link still needs access in GitHub. Project participant selection describes collaboration ownership in this MVP; it does not create a separate channel ACL.

Security And Failure Handling

  • GitHub authorization is bound to the initiating ClickClack browser session and workspace manager.
  • Temporary GitHub tokens expire from setup after 10 minutes and are revoked on completion, cancellation, invalid callbacks, or authorization failure.
  • Pending revocations survive process restarts in encrypted form; plaintext setup tokens are not stored in the database or logs.
  • OAuth setup context and participant inputs are bounded before persistence.
  • Repository selections are revalidated against GitHub immediately before webhook creation.
  • Partial webhook creation is rolled back in reverse order with bounded retries and response validation.
  • Webhook deliveries remain HMAC-verified, deduplicated, and retry-safe.

Evidence

These are unannotated runtime screenshots from the live ClickClack deployment.

Pull request activity grouped into one collaboration thread

GitHub pull request activity in a ClickClack project channel

Project list with linked repositories and participants

ClickClack project list

Project creation with multiple repositories and human or bot participants

ClickClack project creation form

Live validation used real GitHub webhook deliveries. ClickClack created the rich PR root and added review and CI activity as thread replies. After deploying the issue handler, redelivering issue #2 returned 202 Accepted with updates: 1 and created a rich issue root in the project channel. Issue comments and delivery idempotency are covered by the same end-to-end webhook test.

Webhook failure and redelivery proof

Inspect the redacted runtime evidence for existing-database migration, invalid-signature rejection, explicit failed-delivery recovery, duplicate suppression, and single-thread preservation on the live deployment.

Retry coverage includes SQLite and Postgres lifecycle and upgrade tests, stale-processing lease reclaim in both backends, and an HTTP handler test that injects a failure after claim and successfully processes the same delivery ID on redelivery.

Verification

  • go test ./apps/api/internal/httpapi ./apps/api/internal/store/sqlite ./apps/api/internal/store/postgres
  • go vet ./apps/api/internal/httpapi ./apps/api/internal/store/sqlite ./apps/api/internal/store/postgres
  • pnpm --filter @clickclack/web test
  • pnpm --filter @clickclack/web typecheck
  • pnpm --filter @clickclack/sdk-ts typecheck
  • pnpm typecheck
  • pnpm lint
  • pnpm generate:sqlc
  • Production web, SDK, and embedded-asset builds
  • Sealed security diff scan covering authentication, authorization, OAuth state, temporary token handling, webhook rollback, persistence, and logs

go test ./... passes all feature API and store packages. The aggregate Windows run still reports the repository's existing platform-specific cmd/clickclack file-mode and file://C:\... URL assertions; this change does not touch those tests.

@clawsweeper clawsweeper Bot added the proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. label Jul 27, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels Jul 27, 2026
@clawsweeper

clawsweeper Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Codex review: found issues before merge. Reviewed August 1, 2026, 7:47 PM ET / 23:47 UTC.

ClawSweeper review

What this changes

This PR adds GitHub-linked workspace project rooms, with OAuth and manual setup, signed webhook ingestion, durable project data, project APIs, and a Projects web interface.

Merge readiness

⚠️ Needs maintainer review before merge - 5 items remain

Keep this PR open: its live proof is credible, but the current branch still accepts GitHub repository metadata marked private while creating a workspace-public collaboration channel. Current channel reads require only workspace membership, so unrelated members can read imported private-repository activity; this needs a security-boundary decision and repair before merge.

Priority: P1
Reviewed head: 3471020a467834926999e9339fe61952d0c44ddd
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) The branch has strong real-behavior evidence, but it is not merge-ready while private GitHub content can cross the workspace authorization boundary.
Proof confidence 🦞 diamond lobster (5/6) Sufficient (logs): Prepared screenshots directly show project creation, project listing, and a real GitHub pull-request thread; the linked redacted runtime transcript shows signed delivery recovery and duplicate suppression. Any follow-up proof should redact repository names, endpoints, tokens, and other private details.
Patch quality 🦐 gold shrimp (3/6) Security review found an item that needs attention.

Verification

Check Result Evidence
Real behavior Verified Sufficient (logs): Prepared screenshots directly show project creation, project listing, and a real GitHub pull-request thread; the linked redacted runtime transcript shows signed delivery recovery and duplicate suppression. Any follow-up proof should redact repository names, endpoints, tokens, and other private details.
Evidence reviewed 7 items Private repository is accepted by the picker: The supplied PR diff defines GitHub repository choices with a private field, while the project-creation UI says that a public collaboration channel is created automatically. The branch therefore has the information needed to distinguish private repositories but does not establish a private room boundary.
Current channel access is workspace-wide: Current main lists channels after a workspace-membership check, and the underlying query filters by workspace rather than a project participant audience.
Membership query has no project-level predicate: The current SQLite typed query verifies only workspace_id and user_id; it has no project or project-member constraint to protect a project channel.
Findings 1 actionable finding [P1] Reject private repositories until room access is enforced
Security Needs attention Private repository events can reach unrelated workspace members: The setup model distinguishes private repositories, but the collaboration room is public and current channel authorization is workspace-wide. Private pull requests, issues, comments, reviews, and checks may therefore be visible to members who are not project participants.

How this fits together

Project rooms turn selected GitHub repositories into a ClickClack collaboration channel, then route signed GitHub pull-request, issue, review, comment, and check events into threads. Workspace members enter through normal channel and project APIs, while setup persists the repository mapping and webhook configuration.

flowchart LR
A[Workspace manager] --> B[GitHub or manual setup]
B --> C[Project record]
C --> D[Public collaboration channel]
E[Signed GitHub webhook] --> F[Delivery validation]
F --> G[Project event router]
G --> H[Channel thread updates]
Loading

Decision needed

Question Recommendation
Should this MVP remain restricted to provider-verified public repositories, including disabling manual setup where visibility cannot be verified, or should ClickClack first add a project-specific channel audience for private repositories? Public repositories only: Recommended: accept only provider-verified public repositories and remove or block the manual path until it can verify visibility, preserving the existing workspace-public channel contract.

Why: Both paths change the promised feature boundary: rejecting unknown/private repositories preserves the existing public-channel model, while supporting them requires a new authorization model across every channel-read surface.

Before merge

  • Reject private repositories until room access is enforced (P1) - The picker accepts repository metadata with private, but this flow creates a public collaboration channel and project participants are not an ACL. Since current channel reads authorize any workspace member, importing a private repository exposes its webhook content to unrelated members. This repeats the prior blocker at the same head; reject private and manual unknown-visibility repositories, or enforce a project audience across every read path before merge.
  • Resolve security concern: Private repository events can reach unrelated workspace members - The setup model distinguishes private repositories, but the collaboration room is public and current channel authorization is workspace-wide. Private pull requests, issues, comments, reviews, and checks may therefore be visible to members who are not project participants.
  • Resolve merge risk (P1) - Merging this PR can expose private GitHub issue, pull-request, review, comment, and check content to unrelated authenticated workspace members because a project room is public and project participants are not an enforced audience.
  • Resolve merge risk (P1) - The manual setup path cannot safely establish a repository’s visibility without a provider-backed authorization check, so a public-only policy must not rely on a user assertion alone.

Findings

  • [P1] Reject private repositories until room access is enforced — apps/web/src/routes/app/[workspaceID]/projects/+page.svelte:29
  • [high] Private repository events can reach unrelated workspace members — apps/web/src/routes/app/[workspaceID]/projects/+page.svelte:29
Agent review details

Security

Needs attention: The PR can route private GitHub repository content into workspace-public channels without an enforced project-specific audience.

Review metrics

Metric Value Why it matters
Patch surface 113 files; 10,287 additions and 191 deletions The PR spans OAuth, webhook delivery, database migrations, generated SQL, APIs, embedded assets, and the web UI, so the authorization decision has broad downstream reach.
Persistent schema changes 6 new migrations across SQLite and Postgres Project, delivery, OAuth-context, integration, and token-revocation state affect upgrade safety as well as new installs.

Merge-risk options

Maintainer options:

  1. Constrain the MVP to verified public repositories (recommended)
    Block manual/unknown-visibility setup and reject provider-reported private repositories until private rooms have an enforced project audience.
  2. Adopt private project-room authorization first
    Implement and prove project-scoped channel reads and realtime delivery before allowing private repositories into project rooms.
  3. Pause the feature boundary
    Defer this PR if neither a public-only MVP nor a durable private-room authorization model is acceptable.

Technical review

Best possible solution:

Keep project rooms workspace-public only for repositories whose visibility is authoritatively verified as public; disable or redesign the manual path for unknown/private visibility, or implement a project audience that is enforced across channel listing, direct reads, embeds, realtime delivery, search, and event replay before allowing private repositories.

Do we have a high-confidence way to reproduce the issue?

Yes—at source level, select a private repository through the picker, create its project room, then use a separate ordinary workspace-member account to list or open channels. Current main’s channel checks require workspace membership only, and the supplied branch diff declares the project room public.

Is this the best way to solve the issue?

No—the current approach is not safe for private repositories. A public-only, provider-verified MVP is the narrowest immediate solution; private-repository support needs an explicit, enforced project-audience design rather than participant metadata.

Full review comments:

  • [P1] Reject private repositories until room access is enforced — apps/web/src/routes/app/[workspaceID]/projects/+page.svelte:29
    The picker accepts repository metadata with private, but this flow creates a public collaboration channel and project participants are not an ACL. Since current channel reads authorize any workspace member, importing a private repository exposes its webhook content to unrelated members. This repeats the prior blocker at the same head; reject private and manual unknown-visibility repositories, or enforce a project audience across every read path before merge.
    Confidence: 0.97

Overall correctness: patch is incorrect
Overall confidence: 0.97

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 4843afe2e8eb.

Labels

Label justifications:

  • P1: The feature can expose private GitHub activity to unrelated authenticated workspace members.
  • merge-risk: 🚨 security-boundary: Project participant selection is not an enforced authorization boundary while the created collaboration channel remains public to the workspace.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (logs): Prepared screenshots directly show project creation, project listing, and a real GitHub pull-request thread; the linked redacted runtime transcript shows signed delivery recovery and duplicate suppression. Any follow-up proof should redact repository names, endpoints, tokens, and other private details.
  • proof: sufficient: Contributor real behavior proof is sufficient. Prepared screenshots directly show project creation, project listing, and a real GitHub pull-request thread; the linked redacted runtime transcript shows signed delivery recovery and duplicate suppression. Any follow-up proof should redact repository names, endpoints, tokens, and other private details.

Evidence

Security concerns:

  • [high] Private repository events can reach unrelated workspace members — apps/web/src/routes/app/[workspaceID]/projects/+page.svelte:29
    The setup model distinguishes private repositories, but the collaboration room is public and current channel authorization is workspace-wide. Private pull requests, issues, comments, reviews, and checks may therefore be visible to members who are not project participants.
    Confidence: 0.97

What I checked:

  • Private repository is accepted by the picker: The supplied PR diff defines GitHub repository choices with a private field, while the project-creation UI says that a public collaboration channel is created automatically. The branch therefore has the information needed to distinguish private repositories but does not establish a private room boundary. (apps/web/src/routes/app/[workspaceID, 3471020a4678)
  • Current channel access is workspace-wide: Current main lists channels after a workspace-membership check, and the underlying query filters by workspace rather than a project participant audience. (apps/api/internal/store/sqlite/sqlite.go:514, 4843afe2e8eb)
  • Membership query has no project-level predicate: The current SQLite typed query verifies only workspace_id and user_id; it has no project or project-member constraint to protect a project channel. (apps/api/internal/store/sqlite/sqlc/queries.sql:506, 4843afe2e8eb)
  • Previous review blocker remains applicable: The latest completed ClawSweeper review at the same supplied PR head identified the same private-repository exposure: project participants are metadata, while normal workspace-channel reads admit every non-guest workspace member. (apps/web/src/routes/app/[workspaceID, 3471020a4678)
  • Real behavior proof inspected: Prepared local screenshots show project creation, project listing, and GitHub pull-request activity rendered as a channel thread. The supplied redacted runtime transcript additionally covers signed replay recovery and duplicate suppression. (docs/proof/github-project-rooms/webhook-runtime-proof.md:1, 4b1b30e39df3)
  • Feature-history routing signal: Recent current-main history over the channel access path includes channel work by Peter Steinberger, making that history a useful routing signal for the workspace-channel authorization boundary. (apps/api/internal/store/sqlite/sqlite.go:514, e455d43809a0)

Likely related people:

  • Peter Steinberger: Recent current-main history touching the channel access path includes the channel display-title change, so this is the strongest available local routing signal for workspace-channel behavior. (role: recent channel-area contributor; confidence: low; commits: e455d43809a0; files: apps/api/internal/store/sqlite/sqlite.go, apps/api/internal/httpapi/server.go)
  • PollyBot13: The related managed-channel proposal discusses durable external-work-item rooms and explicitly calls out private-channel visibility as a boundary, making this contributor useful context for the follow-up design. (role: adjacent design contributor; confidence: medium; commits: 5c0f2629aa62; files: apps/api/internal/store/sqlite/sqlite.go)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Obtain a maintainer decision on public-only versus project-scoped private rooms.
  • Implement the selected visibility boundary and add an authorization regression proving an unrelated workspace member cannot read a private project’s channel.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (33 earlier review cycles; latest 8 shown)
  • reviewed 2026-07-31T23:35:27.351Z sha 3471020 :: found issues before merge. :: [P1] Reject private repositories until room access is enforced
  • reviewed 2026-08-01T04:06:06.244Z sha 3471020 :: found issues before merge. :: [P1] Reject private repositories until room access is enforced
  • reviewed 2026-08-01T09:34:38.322Z sha 3471020 :: needs changes before merge. :: [P1] Reject private repositories until room access is enforced
  • reviewed 2026-08-01T11:27:22.298Z sha 3471020 :: found issues before merge. :: [P1] Reject private repositories until room access is enforced
  • reviewed 2026-08-01T13:25:42.364Z sha 3471020 :: found issues before merge. :: [P1] Reject private repositories until room access is enforced
  • reviewed 2026-08-01T14:52:20.447Z sha 3471020 :: found issues before merge. :: [P1] Reject private repositories until room access is enforced
  • reviewed 2026-08-01T17:33:41.742Z sha 3471020 :: found issues before merge. :: [P1] Reject private repositories until project access is enforced
  • reviewed 2026-08-01T20:15:22.562Z sha 3471020 :: found issues before merge. :: [P1] Reject private repositories until room access is enforced

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. P1 Urgent regression or broken agent/channel workflow affecting real users now. merge-risk: 🚨 message-delivery 🚨 Merging this PR could drop, duplicate, misroute, suppress, or wrongly target messages. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jul 27, 2026
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. P2 Normal priority bug or improvement with limited blast radius. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. P1 Urgent regression or broken agent/channel workflow affecting real users now. labels Jul 27, 2026
@Solvely-Colin

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Added the requested webhook and upgrade evidence at docs/proof/github-project-rooms/webhook-runtime-proof.md, and linked it from the PR body.

The redacted live proof now covers:

  • existing populated SQLite database upgrade and public health check;
  • invalid signature rejection (401) with no delivery row;
  • controlled failed delivery followed by successful signed replay (202 accepted) and transition back to complete;
  • completed-delivery replay (202 duplicate);
  • one issue thread before and after recovery and duplicate replay.

Automated coverage at head 4b1b30e includes SQLite and Postgres lifecycle, stale-processing reclaim, pre-migration upgrade fixtures, and an HTTP post-claim failure followed by successful redelivery of the same delivery ID.

@clawsweeper

clawsweeper Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. and removed proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 27, 2026
@clawsweeper clawsweeper Bot added the rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. label Jul 29, 2026
@clawsweeper clawsweeper Bot removed the merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. label Jul 29, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 29, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. and removed merge-risk: 🚨 message-delivery 🚨 Merging this PR could drop, duplicate, misroute, suppress, or wrongly target messages. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. labels Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P1 Urgent regression or broken agent/channel workflow affecting real users now. proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants