{ "host": "knotless.dev", "repo": "chadtmiller.com/knotless", "pull": { "uri": "at://did:plc:bcgltzqazw5tb6k2g3ttenbj/dev.knotless.pull/3mzth2v6xpbk7", "url": "https://knotless.dev/chadtmiller.com/knotless/pull/did:plc:bcgltzqazw5tb6k2g3ttenbj/3mzth2v6xpbk7", "title": "A profile's private repositories show their pushes to those who may read them", "author": "chadtmiller.com", "branch": "serve/private-activity", "base": "main", "opened": "2026-11-08T22:20:45.478Z", "state": "merged" }, "diff": { "files": [ { "path": "crates/knotless-serve/src/lib.rs", "added": 4, "removed": 4 }, { "path": "crates/knotless-serve/src/web/actor.rs", "added": 30, "removed": 3 }, { "path": "crates/knotless-serve/tests/gateway.rs", "added": 16, "removed": 9 }, { "path": "docs/design/access.md", "added": 1, "removed": 1 }, { "path": "docs/reference/api.md", "added": 5, "removed": 1 }, { "path": "lexicons/dev/knotless/getActorActivity.json", "added": 1, "removed": 1 } ], "excerpt": { "path": "crates/knotless-serve/src/web/actor.rs", "lines": [ { "mark": " ", "n": 373, "text": "}" }, { "mark": " ", "n": 374, "text": "" }, { "mark": "+", "n": 375, "text": "/// The pushes to `did`'s private repositories that `viewer` may read" }, { "mark": "+", "n": 376, "text": "/// ([`private_of`]), as this server's index of their spaces counts them." }, { "mark": "+", "n": 377, "text": "fn private_pushes(" }, { "mark": "+", "n": 378, "text": " app: &Arc," }, { "mark": "+", "n": 379, "text": " did: &str," }, { "mark": "+", "n": 380, "text": " viewer: Option," }, { "mark": "+", "n": 381, "text": " since: Option<&str>," }, { "mark": "+", "n": 382, "text": " tz: &str," }, { "mark": "+", "n": 383, "text": ") -> rusqlite::Result> {" }, { "mark": "+", "n": 384, "text": " let shown = private_of(app, did, viewer).unwrap_or_default();" }, { "mark": "+", "n": 385, "text": " let names: HashSet = shown.into_iter().map(|(name, _, _)| name).collect();" }, { "mark": "+", "n": 386, "text": " let Some(index) = app.spaces.as_ref().filter(|_| !names.is_empty()) else {" } ] } }, "pushes": [ { "commit": "65f5493b372769d9b5c4b6d07d4038af49109cda", "at": "2026-11-08T22:20:52.622Z", "checks": [ { "workflow": "docs", "status": "success", "skipped": false, "started": "2026-11-08T22:20:52.622Z", "finished": "2026-11-08T22:21:08.682Z" }, { "workflow": "check", "status": "success", "skipped": false, "started": "2026-11-08T22:20:52.941Z", "finished": "2026-11-08T22:21:15.894Z" }, { "workflow": "web", "status": "success", "skipped": false, "started": "2026-11-08T22:20:52.931Z", "finished": "2026-11-08T22:21:15.955Z" }, { "workflow": "lexicons", "status": "success", "skipped": false, "started": "2026-11-08T22:21:14.293Z", "finished": "2026-11-08T22:21:23.684Z" }, { "workflow": "ios", "status": "success", "skipped": false, "started": "2026-11-08T22:21:13.329Z", "finished": "2026-11-08T22:22:16.371Z" }, { "workflow": "shots", "status": "success", "skipped": false, "started": "2026-11-08T22:21:22.499Z", "finished": "2026-11-08T22:22:16.685Z" }, { "workflow": "e2e", "status": "success", "skipped": false, "started": "2026-11-08T22:20:52.623Z", "finished": "2026-11-08T22:25:49.817Z" }, { "workflow": "test", "status": "success", "skipped": false, "started": "2026-11-08T22:22:13.073Z", "finished": "2026-11-08T22:29:08.956Z" } ] }, { "commit": "d5a939294d78ef674a3ed1f988b34129feea48b3", "at": "2026-11-08T22:29:14.102Z", "checks": [ { "workflow": "docs", "status": "success", "skipped": false, "started": "2026-11-08T22:29:14.102Z", "finished": "2026-11-08T22:29:25.385Z" }, { "workflow": "check", "status": "success", "skipped": false, "started": "2026-11-08T22:29:14.417Z", "finished": "2026-11-08T22:29:33.042Z" }, { "workflow": "lexicons", "status": "success", "skipped": false, "started": "2026-11-08T22:29:31.445Z", "finished": "2026-11-08T22:29:35.737Z" }, { "workflow": "ios", "status": "success", "skipped": false, "started": "2026-11-08T22:29:23.795Z", "finished": "2026-11-08T22:30:05.990Z" }, { "workflow": "shots", "status": "success", "skipped": false, "started": "2026-11-08T22:29:35.268Z", "finished": "2026-11-08T22:30:12.063Z" }, { "workflow": "web", "status": "success", "skipped": false, "started": "2026-11-08T22:30:10.093Z", "finished": "2026-11-08T22:30:38.109Z" }, { "workflow": "e2e", "status": "success", "skipped": false, "started": "2026-11-08T22:29:14.102Z", "finished": "2026-11-08T22:33:25.681Z" }, { "workflow": "test", "status": "success", "skipped": false, "started": "2026-11-08T22:30:03.015Z", "finished": "2026-11-08T22:37:10.101Z" } ] } ], "reviews": [ { "by": "review.knotless.dev", "verdict": "changes", "at": "2026-11-08T22:22:05.245Z", "commit": "65f5493b372769d9b5c4b6d07d4038af49109cda", "said": "The activity change is sound. getActorActivity now sits behind the viewer middleware and adds only the private repositories private_of allows. The new test covers the member, no one, and an outsider.", "line": { "path": ".knotless/workflows/deploy.yml", "line": 104, "said": "Dropping chadtmiller.com/group-host here depends on an invite that was never left for the existing share." } }, { "by": "review.knotless.dev", "verdict": "approve", "at": "2026-11-08T22:29:30.940Z", "commit": "d5a939294d78ef674a3ed1f988b34129feea48b3", "said": "The unrelated commit is gone. pull_diff now shows only the activity change, with the matching docs and lexicon text, so the title and body describe the pull.", "line": null } ], "queued": "2026-11-08T22:37:24.182Z", "landed": { "commit": "9382c0bbb9f6ad694a8a39deaffc2ebc706c6ac5", "at": "2026-11-08T22:37:31Z", "batch": true }, "deploy": { "workflow": "deploy", "status": "success", "started": "2026-11-08T22:38:12.898Z", "finished": "2026-11-08T22:46:23.896Z", "steps": [ { "name": "tools", "ms": 1139, "status": "success" }, { "name": "build", "ms": 433042, "status": "success" }, { "name": "deploy", "ms": 40955, "status": "success" }, { "name": "image", "ms": 4894, "status": "success" }, { "name": "runner host", "ms": 6291, "status": "success" } ] } }