Informe JSON sin procesar legible por máquina
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 57054,
"has_wiki": true,
"homepage": "https://docs.amun.ai",
"languages": {
"HTML": 770154,
"Mako": 651,
"Shell": 8473,
"Python": 5363763,
"Dockerfile": 2868,
"JavaScript": 985523,
"Go Template": 3529
},
"pushed_at": "2026-07-31T03:07:24Z",
"created_at": "2021-10-16T18:36:37Z",
"owner_type": "Organization",
"updated_at": "2026-07-31T02:24:04Z",
"description": "A distributed application framework for large-scale data management and AI model serving",
"is_archived": false,
"is_disabled": false,
"license_spdx": "MIT",
"default_branch": "main",
"license_spdx_raw": "MIT",
"primary_language": "Python",
"significant_languages": [
"Python",
"JavaScript",
"HTML"
]
},
"owner": {
"blog": "https://amun.ai",
"name": "Amun AI",
"type": "Organization",
"login": "amun-ai",
"company": null,
"location": null,
"followers": 4,
"avatar_url": "https://avatars.githubusercontent.com/u/76439739?v=4",
"created_at": "2020-12-21T14:21:15Z",
"is_verified": null,
"public_repos": 8,
"account_age_days": 2047
},
"license": {
"state": "standard",
"spdx_id": "MIT",
"raw_spdx": "MIT",
"file_present": true,
"scorecard_found": null,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v0.21.127",
"kind": "patch",
"published_at": "2026-07-31T03:07:38Z"
},
{
"tag": "v0.21.126",
"kind": "patch",
"published_at": "2026-07-29T19:09:51Z"
},
{
"tag": "v0.21.124",
"kind": "patch",
"published_at": "2026-07-25T21:58:36Z"
},
{
"tag": "v0.21.123",
"kind": "patch",
"published_at": "2026-07-25T21:04:12Z"
},
{
"tag": "v0.21.122",
"kind": "patch",
"published_at": "2026-07-25T19:59:33Z"
},
{
"tag": "v0.21.121",
"kind": "patch",
"published_at": "2026-07-25T17:59:27Z"
},
{
"tag": "v0.21.120",
"kind": "patch",
"published_at": "2026-07-25T17:07:11Z"
},
{
"tag": "v0.21.119",
"kind": "patch",
"published_at": "2026-07-25T02:54:25Z"
},
{
"tag": "v0.21.118",
"kind": "patch",
"published_at": "2026-07-23T17:58:56Z"
},
{
"tag": "v0.21.117",
"kind": "patch",
"published_at": "2026-07-23T13:27:07Z"
},
{
"tag": "v0.21.116",
"kind": "patch",
"published_at": "2026-07-22T19:00:53Z"
},
{
"tag": "v0.21.115",
"kind": "patch",
"published_at": "2026-07-22T18:17:34Z"
},
{
"tag": "v0.21.113",
"kind": "patch",
"published_at": "2026-07-22T15:46:08Z"
},
{
"tag": "v0.21.112",
"kind": "patch",
"published_at": "2026-07-22T14:17:49Z"
},
{
"tag": "v0.21.111",
"kind": "patch",
"published_at": "2026-07-14T02:52:24Z"
},
{
"tag": "v0.21.110",
"kind": "patch",
"published_at": "2026-07-11T00:26:27Z"
},
{
"tag": "v0.21.109",
"kind": "patch",
"published_at": "2026-07-10T11:59:48Z"
},
{
"tag": "v0.21.108",
"kind": "patch",
"published_at": "2026-07-08T06:40:37Z"
},
{
"tag": "v0.21.107",
"kind": "patch",
"published_at": "2026-07-08T05:04:23Z"
},
{
"tag": "v0.21.106",
"kind": "patch",
"published_at": "2026-07-07T02:52:08Z"
},
{
"tag": "v0.21.105",
"kind": "patch",
"published_at": "2026-07-02T17:55:58Z"
},
{
"tag": "v0.21.104",
"kind": "patch",
"published_at": "2026-06-26T01:29:01Z"
},
{
"tag": "v0.21.103",
"kind": "patch",
"published_at": "2026-06-25T09:23:01Z"
},
{
"tag": "v0.21.102",
"kind": "patch",
"published_at": "2026-06-23T14:44:28Z"
},
{
"tag": "v0.21.101",
"kind": "patch",
"published_at": "2026-06-23T07:31:46Z"
},
{
"tag": "v0.21.100",
"kind": "patch",
"published_at": "2026-06-22T22:54:09Z"
},
{
"tag": "v0.21.99",
"kind": "patch",
"published_at": "2026-06-22T18:28:54Z"
},
{
"tag": "v0.21.98",
"kind": "patch",
"published_at": "2026-06-22T16:24:00Z"
},
{
"tag": "v0.21.97",
"kind": "patch",
"published_at": "2026-06-22T12:04:00Z"
},
{
"tag": "v0.21.90",
"kind": "patch",
"published_at": "2026-06-17T11:10:19Z"
},
{
"tag": "v0.21.89",
"kind": "patch",
"published_at": "2026-06-17T07:31:48Z"
},
{
"tag": "v0.21.88",
"kind": "patch",
"published_at": "2026-06-17T03:41:21Z"
},
{
"tag": "v0.21.87",
"kind": "patch",
"published_at": "2026-06-16T19:58:09Z"
},
{
"tag": "v0.21.86",
"kind": "patch",
"published_at": "2026-06-13T19:36:19Z"
},
{
"tag": "v0.21.85",
"kind": "patch",
"published_at": "2026-05-02T13:05:30Z"
},
{
"tag": "v0.21.84",
"kind": "patch",
"published_at": "2026-05-02T09:04:27Z"
},
{
"tag": "v0.21.83",
"kind": "patch",
"published_at": "2026-04-26T22:37:10Z"
},
{
"tag": "v0.21.82",
"kind": "patch",
"published_at": "2026-03-19T07:31:47Z"
},
{
"tag": "v0.21.81",
"kind": "patch",
"published_at": "2026-03-19T06:36:59Z"
},
{
"tag": "v0.21.80",
"kind": "patch",
"published_at": "2026-03-11T07:26:53Z"
},
{
"tag": "v0.21.79",
"kind": "patch",
"published_at": "2026-03-08T10:49:21Z"
},
{
"tag": "v0.21.78",
"kind": "patch",
"published_at": "2026-03-07T12:08:06Z"
},
{
"tag": "v0.21.77",
"kind": "patch",
"published_at": "2026-03-07T07:43:13Z"
},
{
"tag": "v0.21.76",
"kind": "patch",
"published_at": "2026-03-07T07:31:44Z"
},
{
"tag": "v0.21.75",
"kind": "patch",
"published_at": "2026-03-07T04:42:59Z"
},
{
"tag": "v0.21.74",
"kind": "patch",
"published_at": "2026-03-07T02:54:14Z"
},
{
"tag": "v0.21.73",
"kind": "patch",
"published_at": "2026-03-06T18:51:28Z"
},
{
"tag": "v0.21.72",
"kind": "patch",
"published_at": "2026-03-06T05:31:42Z"
},
{
"tag": "v0.21.70",
"kind": "patch",
"published_at": "2026-03-01T20:25:49Z"
},
{
"tag": "v0.21.69",
"kind": "patch",
"published_at": "2026-03-01T16:47:03Z"
},
{
"tag": "v0.21.67",
"kind": "patch",
"published_at": "2026-03-01T07:57:25Z"
},
{
"tag": "v0.21.64",
"kind": "patch",
"published_at": "2026-02-27T22:47:00Z"
},
{
"tag": "v0.21.63",
"kind": "patch",
"published_at": "2026-02-27T08:09:04Z"
},
{
"tag": "v0.21.61",
"kind": "patch",
"published_at": "2026-02-27T02:04:15Z"
},
{
"tag": "v0.21.59",
"kind": "patch",
"published_at": "2026-02-26T18:59:33Z"
},
{
"tag": "v0.21.58",
"kind": "patch",
"published_at": "2026-02-26T14:36:49Z"
},
{
"tag": "v0.21.57",
"kind": "patch",
"published_at": "2026-02-26T13:51:46Z"
},
{
"tag": "v0.21.56",
"kind": "patch",
"published_at": "2026-02-26T13:29:14Z"
},
{
"tag": "v0.21.55",
"kind": "patch",
"published_at": "2026-02-25T23:21:46Z"
},
{
"tag": "v0.21.54",
"kind": "patch",
"published_at": "2026-02-25T17:19:57Z"
},
{
"tag": "v0.21.53",
"kind": "patch",
"published_at": "2026-02-24T22:36:10Z"
},
{
"tag": "v0.21.52",
"kind": "patch",
"published_at": "2026-02-24T20:50:48Z"
},
{
"tag": "v0.21.51",
"kind": "patch",
"published_at": "2026-02-24T15:38:19Z"
},
{
"tag": "v0.21.50",
"kind": "patch",
"published_at": "2026-02-23T08:36:57Z"
},
{
"tag": "v0.21.49",
"kind": "patch",
"published_at": "2026-02-23T07:12:34Z"
},
{
"tag": "v0.21.48",
"kind": "patch",
"published_at": "2026-02-23T06:29:40Z"
},
{
"tag": "v0.21.47",
"kind": "patch",
"published_at": "2026-02-13T13:30:46Z"
},
{
"tag": "v0.21.44",
"kind": "patch",
"published_at": "2026-02-11T14:57:18Z"
},
{
"tag": "v0.21.43",
"kind": "patch",
"published_at": "2026-02-11T14:28:59Z"
},
{
"tag": "v0.21.42",
"kind": "patch",
"published_at": "2026-02-10T19:05:27Z"
},
{
"tag": "v0.21.40",
"kind": "patch",
"published_at": "2026-02-07T15:42:30Z"
},
{
"tag": "v0.21.39",
"kind": "patch",
"published_at": "2026-01-30T05:47:12Z"
},
{
"tag": "v0.21.37",
"kind": "patch",
"published_at": "2026-01-24T07:14:50Z"
},
{
"tag": "v0.21.35",
"kind": "patch",
"published_at": "2026-01-22T15:24:53Z"
},
{
"tag": "v0.21.34",
"kind": "patch",
"published_at": "2026-01-17T01:29:14Z"
},
{
"tag": "v0.21.33",
"kind": "patch",
"published_at": "2026-01-17T01:09:51Z"
},
{
"tag": "v0.21.32",
"kind": "patch",
"published_at": "2026-01-16T10:02:20Z"
},
{
"tag": "v0.21.31",
"kind": "patch",
"published_at": "2026-01-15T23:49:58Z"
},
{
"tag": "v0.21.30",
"kind": "patch",
"published_at": "2026-01-14T17:35:47Z"
},
{
"tag": "v0.21.29",
"kind": "patch",
"published_at": "2025-12-23T17:19:31Z"
},
{
"tag": "v0.21.28",
"kind": "patch",
"published_at": "2025-12-15T22:43:37Z"
},
{
"tag": "v0.21.27",
"kind": "patch",
"published_at": "2025-12-04T07:22:59Z"
},
{
"tag": "v0.21.26",
"kind": "patch",
"published_at": "2025-10-28T12:34:20Z"
},
{
"tag": "v0.21.25",
"kind": "patch",
"published_at": "2025-10-07T14:57:42Z"
},
{
"tag": "v0.21.24",
"kind": "patch",
"published_at": "2025-10-07T12:39:29Z"
},
{
"tag": "v0.21.23",
"kind": "patch",
"published_at": "2025-09-16T12:19:07Z"
},
{
"tag": "v0.21.22",
"kind": "patch",
"published_at": "2025-09-10T00:20:21Z"
},
{
"tag": "v0.21.21",
"kind": "patch",
"published_at": "2025-09-08T23:26:29Z"
},
{
"tag": "v0.21.20",
"kind": "patch",
"published_at": "2025-09-08T20:54:23Z"
},
{
"tag": "v0.21.19",
"kind": "patch",
"published_at": "2025-09-07T18:00:31Z"
},
{
"tag": "v0.21.18",
"kind": "patch",
"published_at": "2025-09-06T15:50:39Z"
},
{
"tag": "v0.21.17",
"kind": "patch",
"published_at": "2025-09-06T14:29:37Z"
},
{
"tag": "v0.21.16",
"kind": "patch",
"published_at": "2025-09-06T00:35:03Z"
},
{
"tag": "v0.21.15",
"kind": "patch",
"published_at": "2025-08-22T05:04:06Z"
},
{
"tag": "v0.21.14",
"kind": "patch",
"published_at": "2025-08-22T03:19:57Z"
},
{
"tag": "v0.21.13",
"kind": "patch",
"published_at": "2025-08-21T19:11:17Z"
},
{
"tag": "v0.21.12",
"kind": "patch",
"published_at": "2025-08-20T22:01:58Z"
},
{
"tag": "v0.21.11",
"kind": "patch",
"published_at": "2025-08-20T03:35:10Z"
},
{
"tag": "v0.21.10",
"kind": "patch",
"published_at": "2025-08-20T02:08:51Z"
},
{
"tag": "v0.21.8",
"kind": "patch",
"published_at": "2025-08-18T22:11:55Z"
}
],
"recent_commits": [
{
"oid": "c7e40ee3bdb6779ac25158f772f7ac9cb79e182b",
"body": "…(#0017) (#1039)\n\nfix(http): missing ASGI/apps service -> clean 404, not 500+traceback (#0017) — 0.21.127\n\nA GET to /{workspace}/apps/{service_id}/... for a service that does not exist\n(in an existing, accessible workspace) raised a bare KeyError inside\nget_service_info on the workspace-manager side\n[…]\nce under the always-present public workspace; #0014 co-test + the present-\nservice 200 path both still pass (shared-middleware non-regression).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(http): missing ASGI/apps service -> clean 404, not 500+traceback …",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-31T02:24:00Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "964f07ad56536048c6a762f54d4bd6779b1680d3",
"body": "…iness path (#0015) — 0.21.126 (#1038)\n\n* fix(startup): defer + parallelize orphan-service reaping off the readiness path (#0015) — 0.21.126\n\nRoot-cause fix for the 2026-07-29 hypha-server startup CrashLoop.\n\ninit() awaited _cleanup_orphaned_client_services INLINE in the readiness path,\nand that rea\n[…]\nus-loop\nbehavior stays covered in isolation by tests/test_orphan_reaper.py.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(startup): defer + parallelize orphan-service reaping off the read…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-29T18:25:56Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8594f61a3d731e9eda10003da3e62115e86bc633",
"body": "…r MCP/SSE churn — 0.21.125 (#1037)\n\nNightly prod review found the top log line by volume was\nWARNING:asyncio:socket.send() raised exception. (~340/24h, bursts, no\ntraceback), clustered around MCP /rpc churn.\n\nRoot cause: asyncio emits this ONLY from its transport's `if self._conn_lost:`\nbranch, onc\n[…]\n_utils.py (drops the two exact messages, passes all\nothers incl. substring look-alikes, fail-open, idempotent install, end-to-end\nsuppression).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(log): silence benign asyncio socket.send() conn-lost warning unde…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-26T02:06:45Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d5b2654d930817badeb36fb7b403934aabbf4fa9",
"body": "… 4 & 5) — 0.21.124 (#1036)\n\ndocs(auth): document token revocation + indexed auth-store lookup (#0006 items 4 & 5) — 0.21.124\n\nItem 4 — docs/auth.md now covers the two server-side revocation mechanisms\na custom auth provider should rely on instead of hand-rolling an\n\"is-this-user-still-enabled?\" cac\n[…]\nt the docs recommend (existing\nsearch tests only exercised wildcard $like matches).\n\nNo server behavior change — both mechanisms already exist.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(auth): token revocation + indexed auth-store lookup (#0006 items…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-25T21:12:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "96e907102e15f47254f56f6930d963234f971731",
"body": "…urn (#0007) — 0.21.123 (#1035)\n\nOn last-client-disconnect the workspace manager unloads an empty\nnon-persistent workspace immediately (delete_client(unload=True) ->\nunload_if_empty). An app that intentionally closes+reconnects on a\ncadence (e.g. a feedback sink reconnecting every ~31s) therefore ch\n[…]\nault behavior)\n - reconnect-within-grace keeps the workspace (guards both the connect\n cancel hook and the delayed task's emptiness re-check)\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(workspace): optional unload grace period to collapse reconnect ch…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-25T20:18:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9d3c6e9b17f7d1ce9b84b7061dad94332f405444",
"body": "…(V16) — 0.21.122 (#1034)\n\nThe public `search()`/`list()`/`list_children` @schema_methods built their\nWHERE clause by f-string-interpolating user-supplied input directly into\nSQLAlchemy `text()`: `filters` manifest keys/values, `keywords`, the\n`config.permissions` filter, and the `order_by` JSON-fie\n[…]\nord/config.permissions/order_by injection plus a positive config\npermissions match, across both SQLite and PostgreSQL. CLAUDE.md documents V16.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(security): SQL injection in artifact-manager search/list filters …",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-25T19:16:23Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3d6a172670fc39fa13fc8a0e86ab750ce9948fc4",
"body": "…otchas (#0006 items 3,6,7) (#1033)\n\nFills the concrete gaps in the \"Custom Authentication Providers\" guide that\nfirst-time integrators hit (from true-toad's production phone+SMS provider):\n\n- Login lifecycle diagram (login → start → index page → report → check →\n connect → parse_token); the client\n[…]\natches the new\n contract table (timeout=0 → None instead of raising; report_url/check_url;\n invalid-key raises).\n\nDocs-only; no version bump.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(auth): custom-auth-provider guide — lifecycle, hook contracts, g…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-25T18:04:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "74c550dfc5cbaff6e865adc87032c9b91d004d09",
"body": "…0598(c)) (#1031)\n\nCompound-engineering follow-up to PR #1030 (0.21.120): document why the HTTP\nrate limiter runs before auth, why elevation must be by cryptographically\nverified identity (never header presence), and why the authenticated tier is a\nhigh FINITE limit keyed on client_id/sub/workspace rather than a /rpc path\nexemption.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(claude): record pre-auth rate-limiter identity-tiering lesson (#…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-25T17:24:10Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "8be879c9e630b4c0d68a576573e046de0a586ca8",
"body": "… (#0006 item 2) — 0.21.121 (#1032)\n\nfix(auth): custom-auth extra_handlers receive the authenticated caller as scope[\"user\"] (#0006 item 2) — 0.21.121\n\nHandlers registered via register_auth_service(..., <name>=handler) become HTTP\nfunctions-service handlers on the public hypha-login service; each is\n[…]\ndler_receives_authenticated_user\n(+ whoami handler in tests/custom_auth_startup_test.py). Verified it fails\nwithout the fix and passes with it.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(auth): custom-auth extra_handlers get authenticated scope[\"user\"]…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-25T17:16:12Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "521652dac3e5982c4fff4391d66b701b7b5f066e",
"body": "…d rate-limit tier (#0598(c)) — 0.21.120 (#1030)\n\nHTTPRateLimitMiddleware is mounted outermost (before routing AND before auth),\nso it could only ever key on raw client IP. Behind a shared NAT/egress or a\nsingle busy daemon, legitimate first-party /rpc traffic collided with the\nanonymous per-IP buck\n[…]\nnonymous-limited-but-authenticated-not,\nforged/expired token does-not-bypass, client-id keying isolates one daemon,\nmissing-client-id fallback.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(http): authenticated first-party callers get a high identity-keye…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-25T16:18:53Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f91775937080cfe93cafba12f8cbd35939cd027e",
"body": "…+traceback (#0014) — 0.21.119 (#1029)\n\nfix(http): unknown/inaccessible workspace on apps path -> 404, not 500+traceback (#0014) — 0.21.119\n\nA GET to /{workspace}/apps/{service}/... for a workspace that does not exist\n(and cannot be auto-created for the caller) raised a bare KeyError inside\nget_work\n[…]\ny the kth-k8s nightly platform review.\n\nhypha/core/store.py::WorkspaceNotFoundError + hypha/http.py;\ntest tests/test_asgi_unknown_workspace.py.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(http): unknown/inaccessible workspace on apps path → 404, not 500…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-25T02:10:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "02f0def0a09b45d7bf21df963987988dfa5d3a33",
"body": "…0.21.118 (#1028)\n\nfix(http-rpc): self-heal wedged HTTP-streaming connections (#0012) (0.21.118)\n\nProd incident (loop-law): a client's retry-flood (frontend retrying not-found\nsessions in a tight no-backoff loop) filled a svamp-machine's /rpc DOWNSTREAM\nqueue; send_to_queue then dropped messages IND\n[…]\ned by true-toad (ndtai). Companion client-side retry-bound (easy-mule) +\noptional server fail-fast routing for SUSTAINED floods are follow-ups.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(http-rpc): self-heal wedged HTTP-streaming connections (#0012) — …",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-23T17:15:27Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7972cf8d5aadb6218e469030c656340a479a020c",
"body": "…#0011) — 0.21.117 (#1027)\n\n* fix(http-rpc): liveness reaper for half-open HTTP-streaming clients (#0011) (0.21.117)\n\nA client on the HTTP-streaming transport (/rpc) that died HALF-OPEN (container\nhard-removed / docker compose down yanks the veth → NO FIN) was never reaped:\nthe stream loop only dete\n[…]\neep teardown, #0011), so the\nhelper must set them too (mirroring __init__).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(http-rpc): liveness reaper for half-open HTTP-streaming clients (…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-23T12:44:12Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "100c15a6724cbc8f8fe6f77e26ce190cff72a137",
"body": "…#0006 item 1) — 0.21.116 (#1026)\n\nfix(server): --from-env must not silently clobber explicit CLI args (#0006 item 1) (0.21.116)\n\ncreate_application's --from-env path did setattr(args, key, value) for EVERY\nenvironment-derived arg, unconditionally overwriting explicitly-provided CLI\nflags. So a --st\n[…]\nthenticated context, check() contract\ndocs, token-revocation hook, indexed auth-store lookup, custom-provider guide)\nare tracked as follow-ups.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(server): --from-env must not silently clobber explicit CLI args (…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-22T18:16:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b05a2626338a0f219505a1ca5ef4289a5813fea2",
"body": "…-spam (#0005) — 0.21.115 (#1025)\n\nfix(apps): daemon apps for an unavailable worker type WARN, not ERROR-spam (#0005) (0.21.115)\n\nProd logged ERROR:apps:Failed to start daemon app ... 'No server app worker\nfound for type: compute-app' ~11x on every restart, for demo apps\n(cap-test/canary-demo/ab-dem\n[…]\n worker type is rejected with the clear worker-not-found\n message and the server stays healthy\n- version bump 0.21.114 -> 0.21.115 + CHANGELOG\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(apps): daemon apps for an unavailable worker type WARN, not ERROR…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-22T17:34:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0c982649b124aabfa151e86e15d400aac29dba7e",
"body": "…hildren (#0010) — 0.21.114 (#1024)\n\n* feat(artifact): recipient_can_delete — recipient self-delete of own children (#0010)\n\nCompanion to #0009. A private-children collection configured with\n{\"recipient_can_delete\": true, \"recipient_field\": \"<field>\"} lets a recipient\ndelete (ack/prune) ONLY the chi\n[…]\np 0.21.113 -> 0.21.114 (recipient_can_delete #0010) + CHANGELOG + CLAUDE.md\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(artifact): recipient_can_delete — recipient self-delete of own c…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-22T15:55:12Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0a3b74f9d080f52b1ad3d869bd092b94d33015ed",
"body": "…0009 mode-b validation) (#1023)\n\ntest(artifact): lock cross-workspace public private_children collection (#0009 mode-b)\n\nValidates hosting the #0009 recipient-scoped drop-box in the PUBLIC workspace\nas a global, universally-addressable cross-user inbox (backs svamp-user-events\n/ svamp-shared-sessio\n[…]\ngular\nuser is a public-workspace admin, so nobody accidentally bypasses (unlike a\nws-user-<x> home where the owning user is a workspace admin).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "test(artifact): cross-workspace public private_children collection (#…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-22T15:09:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "04fadc7cc4d5b7f422f59cad27b19b8632efb984",
"body": "… — 0.21.113 (#1022)\n\n* fix(ws): route expired/invalid token through AuthenticationError — WARNING not ERROR traceback (#0008) (0.21.113)\n\nA client presenting an expired or invalid token on connect is an EXPECTED\nclient condition (the client should refetch), not a server fault — but it\nwas logging a\n[…]\nserts \"Authentication\") and updates the new\n#0008 regression test to match.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(ws): JWT-expiry log hygiene — WARNING not ERROR traceback (#0008)…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-22T15:03:18Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2ea0bd703e0a1fc7e9fc1e4a0ebadd0491c0d04f",
"body": "… — 0.21.112 (#1021)\n\nfeat(artifact): recipient-scoped private-children collections (#0009) (0.21.112)\n\nA collection configured with\n {\"private_children\": true, \"recipient_field\": \"<manifest field>\"}\nbecomes a cross-user inbox / drop-box: any writer may create a child\naddressed to any recipient, bu\n[…]\nilters; discovery boundary\n- CLAUDE.md — two artifact permission-model constraints learned here\n- version bump 0.21.111 -> 0.21.112 + CHANGELOG\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(artifact): recipient-scoped private-children collections (#0009)…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-22T13:34:20Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7b533499b1c6e3f8dfa0b5ac90b1ee896f15d98d",
"body": "…race (0.21.111) (#1020)\n\n* fix(ws): guard register_client() against event_bus=None on reconnect race (0.21.111)\n\nProd teardown race (nightly review, ~2/24h, caught/non-fatal): on a reconnect via\nreconnection_token immediately followed by a 1001 disconnect, the background\nregister_client() task that\n[…]\natures (per ops request — conscious feature call,\nnot a silent ride-along).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(ws): guard register_client() against event_bus=None on reconnect …",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-14T02:12:35Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ebc5b2c68ecf24821a37ff0e9023f04827ea4177",
"body": "… (0.21.110) (#1019)\n\nchore: re-pin bundled hypha-rpc to 0.21.46 — ship inline login client (0.21.110)\n\nCompletes the embedded (no-popup) login feature (server half in 0.21.109). Bumps\nhypha_rpc_version to 0.21.46 (hypha/__init__.py, setup.py, requirements.txt) and\nrefreshes static_files/hypha-rpc-w\n[…]\n 0.21.46 = 0.21.45's inline-login feature + a release-CI fix (npm publish\nnow runs on node 22 / npm@11 after npm@latest raised its node floor).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: re-pin hypha-rpc 0.21.46 — ship inline (no-popup) login client…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-10T23:44:12Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "26939d7039729e181d7a27461212a1a33c704e85",
"body": "…pup (0.21.109) (#1018)\n\nfeat(local-auth): embedded (iframe) login support — no popup required (0.21.109)\n\nMany host apps block popup windows, silently breaking login. The local-auth\nlogin page now detects when it's rendered inside an iframe (window.parent !==\nwindow) and, on success, postMessages a\n[…]\nlogin page, asserts the embedded markers AND that window.close()\nis preserved). Full local-auth suite green (10). Version 0.21.108 -> 0.21.109.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: embedded (iframe) login support for local + custom auth — no po…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-10T11:17:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "550ce4e2fabd23e9f74c39b3cd0514ae0c2cdd95",
"body": "…0.21.108 (#1017)\n\n* feat(local-auth): email verification via Resend + full code workflow (0.21.108)\n\nMake local auth feature-complete: signup → email a short numeric code → verify →\ncreate account. Previously email_verified was hardcoded True.\n\n- Verification code: 6-digit, secrets.randbelow (CSPRN\n[…]\n returns when RESEND_API_KEY is unset (as in CI). Both tests\ngreen locally.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: feature-complete local auth with email verification (Resend) — …",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-08T05:59:38Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c3aa9792881f9b644a95d365922e905f6508badd",
"body": "…(0.21.107) [HOLD for post-sweep] (#1016)\n\n* fix(websocket): log hygiene — benign lifecycle events no longer log at ERROR (0.21.107)\n\nFlagged during the 0.21.106 prod rollout. Benign WS-lifecycle events were logged\nat ERROR and masked genuine errors during triage.\n\nCENTERPIECE — supersede-cancel no \n[…]\ne and still closes, disconnect() logs INFO not ERROR. 24/24 WS\nsuite green.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: WS log hygiene — benign lifecycle events no longer log at ERROR …",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-08T04:21:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e4d59335205ffe0e472512b1463aebf8b1a0639f",
"body": "…(#1015)\n\nfix(websocket): harden two caught-but-noisy WS-lifecycle bugs (0.21.106)\n\nFlagged by the nightly prod review on 0.21.105. Both were already caught (no\ncrash, no leak) but burned CPU + log volume and masked genuine errors.\n\n[1] Teardown race: filtered_handler hit a niled _subscriptions (~64\n[…]\ngrades the\ntwo benign messages. Both bugs reproduced (TypeError / RuntimeError) before the\nfix, green after. Version bump 0.21.105 -> 0.21.106.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: harden two caught-but-noisy WebSocket-lifecycle bugs (0.21.106) …",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-07T02:10:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "920d4c674c0126908bb9987b75ff8947483a951e",
"body": "…d /rpc memory leak (0.21.105) (#1014)\n\n* fix(http-rpc): close interface connection when __aenter__ fails (prod /rpc leak) — 0.21.105\n\nRoot cause: store.get_workspace_interface() creates the RedisRPCConnection + RPC\npeer synchronously in the factory, before __aenter__ runs. __aenter__ then calls\nget\n[…]\nP /rpc get_workspace_interface __aenter__ leak fix from the same 0.21.105.)\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(http-rpc): close interface connection when __aenter__ fails — pro…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-07-02T17:15:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c8efb2ee25a38929aef67f0446778db3fd9cde36",
"body": "…FS verify https (#991) — 0.21.104 (#993)\n\n* fix(#989): attribute artifact ownership to the effective (human) id\n\nAn artifact created via a generated (agent) token recorded the token's ephemeral\nclient-credentials sub as created_by + the owner permission, so the human (the\ntoken's parent) couldn't s\n[…]\ncess (not a permissions[\"*\"] grant). Security/permission subset: 31 passed.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: effective-id ownership (#989) + non-git error clarity (#990) + L…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-26T00:47:31Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "fde65631995335a3af5c1d3e9936de8c19839539",
"body": "…history (0.21.103) (#992)\n\nfix(git): shallow clone empty-boundary case (--depth on single-commit / depth>=history)\n\n0.21.102's shallow-clone fix (#986) only emitted the shallow-update section when\nthe boundary was NON-empty. For a repo with no boundary — a single-commit repo\n(--depth=1, HEAD has no\n[…]\ntory) and a\nsingle-commit repo --depth=1. Full tests/test_git.py = 42 passed (full clone,\npush, LFS, all shallow cases). Full clone unaffected.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(git): shallow clone empty-boundary case — single-commit / depth>=…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-25T08:42:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "08c35c6009a3a77b4354ff3453c9b21034ff9821",
"body": "…(0.21.102) (#988)\n\nfix(git+artifact): support shallow clone (--depth) + validate alias length\n\nTwo validation-batch fixes (0.21.102), both TDD (reproducing test first).\n\n#986 shallow clone: the smart-HTTP upload-pack parsed `deepen` but ignored it,\nreplying NAK where the client expected the shallow\n[…]\nied to FAIL without the fix. Full tests/test_git.py = 43 passed (full clone,\npush, LFS push/pull, anon LFS, shallow all green) — no regression.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(git+artifact): shallow clone (--depth) + alias length validation …",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-23T14:03:03Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8d949efc064e18d49d13a0da03f08880fb6ef893",
"body": "…0.21.101) (#985)\n\n* fix(git-lfs): resolve public repos anonymously on the LFS batch API (0.21.101)\n\ngit clone of a public git-storage artifact fetched the pack but the LFS smudge\nfailed (\"batch response: Repository or object not found\"); a direct anonymous\nPOST to .../<alias>.git/info/lfs/objects/b\n[…]\nFS push/pull\n tests otherwise hang to timeout locally). No-op on CI/Linux.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(git-lfs): resolve public repos anonymously on the LFS batch API (…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-23T06:50:38Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7fc871dc2ea824e4ce6dd74f91bf200316e27737",
"body": "…OM (0.21.100) (#984)\n\n* fix(mcp): cache adapter per service on POST path (real per-request OOM)\n\n0.21.98 entered StreamableHTTPSessionManager.run() once per adapter and held\nit open in a background task — correct ONLY for a cached/reused adapter (as its\ndocstring assumed). But _handle_mcp_request b\n[…]\nv object-count PASS bar on both\nhappy (valid type:mcp) and bare-echo paths.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(mcp): cache adapter per service on POST path — real per-request O…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-22T22:13:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e190b7f8103838a568c8499280b1786164e7f2be",
"body": "* release: 0.21.99 — durable Postgres-backed admin blocklist\n\nblock_user/block_ip lived only in Redis, so prod (HYPHA_RESET_REDIS=true) wiped\nthe blocklist on every restart — blocks didn't survive restarts/OOMs/deploys.\n\nNow Postgres is the source of truth (blocklist table / BlockEntry); Redis is a\n\n[…]\ngs/artifacts convention. SQLite is lenient so it only surfaced on Postgres.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: 0.21.99 — durable Postgres-backed admin blocklist (#983)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-22T17:46:01Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bed60288c53e713e5e2001764c29c641789f949d",
"body": "… OOM) (#982)\n\n* fix(mcp): enter StreamableHTTPSessionManager.run() once, not per-request (OOM)\n\nThe MCP adapter is cached and shared across all requests for a service, and\nStreamableHTTPSessionManager.run() owns an internal anyio task group designed to\nbe entered exactly once per instance (the app \n[…]\nx (same incident).\n\nTests: tests/test_resource_limits.py::TestCheckBlocked.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(mcp): enter session_manager.run() once, not per-request (residual…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-22T15:42:31Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e807bd10e8c44b9cd8069d7adf85c240c6e664b9",
"body": "…980)\n\nrelease: 0.21.97 — fix dedicated browser-worker visibility routing (#978 cutover unblock)\n\nbrowser.py __main__ set the --visibility/HYPHA_VISIBILITY override at the top\nlevel of the service config instead of inside config, where register_service\nreads it. The override was silently dropped, so\n[…]\ndicated-worker\ncutover that keeps headless-Chromium memory off the API pod. Now matches the\nk8s/conda/terminal workers. Adds a regression test.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: 0.21.97 — fix dedicated browser-worker visibility routing (#…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-22T11:22:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7bae9b5441ca1d65911ed8ff5bcb67fbf3f35f5c",
"body": "…of pack size) (#979)\n\n* feat(git): range-read S3 pack (O(1) clone/fetch memory)\n\n* test(git): single-blob memory guard 3.0x→5.5x (range-read doesn't improve single giant blobs)\n\nCI caught it: test_git_clone_memory_peak uses a single 200MB blob, which is the\ninherent worst case range-read does NOT i\n[…]\ndelta is well under repo size and the < 2.0x guard is both\nmeaningful (catches a whole-pack-reload regression) and non-flaky. The O(1)\nproof across pack sizes remains test_git_clone_memory_flat_curve.",
"is_bot": false,
"headline": "feat(git): range-read S3 pack — O(1) clone/fetch memory (independent …",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-22T01:04:28Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "47a14e921d11599d6df43d4999f108b82932c28f",
"body": "…wser-free (#978)\n\nThe in-process browser worker (registered under --enable-server-apps) spawns\nheadless Chromium as children of the API server process — the dominant OOM\nrisk on a memory-limited pod, and a reconnection storm that respawns browser\napps can crash-loop the server (observed in prod: 38\n[…]\ng Chromium memory\noff the API pod. Required for a clean dedicated-worker cutover since worker\nselection could otherwise route to either worker.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(apps): HYPHA_DISABLE_INPROCESS_BROWSER_WORKER to run API pod bro…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-21T22:56:15Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e1f3f277e0f5023be602e3aaf16e38aad48fa978",
"body": "…memory fix) (#977)\n\n* feat(git): streaming clone + disk-spill push + concurrency cap (root memory fix)\n\n* test(git): gate RSS-peak assertion to Linux (malloc_trim is a no-op off glibc)\n\nThe streaming/disk-spill correctness is covered by the fsck clone/thin-pack\nroundtrip tests on all platforms; onl\n[…]\noth in-memory and rolled-to-disk spools, still streams, Content-Length set.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(git): streaming clone + disk-spill push + concurrency cap (root …",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-18T20:23:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "751d6b3f7b521456cf585907e36e8a2a43c4d6fb",
"body": "…976)\n\nFollow-up to the per-request git trim (PR #975). Live prod diagnostic on\n0.21.93 showed RSS plateauing ~2.1GB of which malloc_trim(0) reclaimed ~1.3GB\n(gc freed 0, normal object graph) — i.e. glibc-arena-retained FREE memory, NOT\na leak. The per-request trim only fires on git ops, so memory f\n[…]\ngit trim stays for immediate relief of multi-GB git spikes.\n\nTests: tests/test_malloc_trim.py (task lifecycle + coroutine safety, docker-free).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(memory): periodic malloc_trim to bound glibc-arena RSS plateau (#…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-18T18:08:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "47054e36c426dfa2db2c7bb4983017732cf6280f",
"body": "… tuning) (#975)\n\nfix(git): release pack memory after each request (malloc_trim + close) + arena tuning\n\nProduction OOM root cause (diagnosed live: gc.collect freed 0, malloc_trim(0)\nreclaimed ~1-1.6GB): git clone/push buffer whole packs (request body, the\ngenerated pack BytesIO, the joined response\n[…]\nt concurrency cap (follow-up; to be sized from a Linux measurement).\nglibc behavior can only be validated on Linux (not the macOS dev harness).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(git): release pack memory after each request (malloc_trim + arena…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-18T17:09:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "aa542eee0bc1b0329836dc0f4959010cdd1e5fd4",
"body": "…#974)\n\nTwo git smart-HTTP permission fixes (also shipped as the 0.21.92 hotfix\nbuilt from stable 0.21.86 for an N=1 prod deploy):\n\n1) Under-grant (the 'Josh' bug): artifact _permissions are keyed on the\n stable human user id, but a token minted via generate_token() (the\n realistic git credentia\n[…]\nact\nsuites (137 passed locally). The ws-level over-grant is intentionally NOT\nchanged here (deferred as a separate, wider-blast-radius change).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(git): honor effective/parent id in artifact perms + 403 not 404 (…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-18T15:15:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7500f195f073f14cb8fc902e0f47a7bc8be729ab",
"body": "list_apps now derives app id from the authoritative artifact alias instead of trusting the manifest blob, fixing the safe-colab Applications page crash (TypeError: Cannot read properties of null reading 'startsWith'). Bumps 0.21.89 -> 0.21.90.",
"is_bot": false,
"headline": "fix(apps): list_apps non-null id + release 0.21.90 (#971)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-17T10:32:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8dc781dfff28ed0c848187b2a3e0f462f0106222",
"body": "The fastapi_server fixture generated ROOT_TOKEN = secrets.token_urlsafe(32)\n(~43 chars). The server's root-token complexity check rejects tokens <64 chars\nthat contain a simple substring (abc/123/root/test/...), so a random short\ntoken intermittently tripped it (\"Root token appears to be too simple\"\n[…]\n Use\ntoken_urlsafe(64) (~86 chars), which is over the 64-char exemption and always\npasses. Distinct from the fastembed and reject-storm issues.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "test: use >=64-char root token in fixture to fix flaky server startup",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-06-17T06:54:39Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "250d6a256b584654b55e27cc54367ce895d6b50f",
"body": "…ures\n\nThe fastembed model fetch (BAAI/bge-small-en-v1.5) is intermittently slow or\ntemporarily unavailable (\"Could not load model ... from any source\"), which\nrepeatedly failed the release build via test_artifact_vector_collection and is\nalso a real server-startup hazard. New hypha.utils.load_faste\n[…]\nrs.\n\nTests: tests/test_fastembed_retry.py (monkeypatched fastembed) — retries then\nsucceeds; re-raises after exhausting; passes kwargs through.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(vectors): retry fastembed model download on transient HF/CDN fail…",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-06-17T06:48:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a7d8a8e36882385ef04ee6e36deec3276228c429",
"body": "…facet)\n\nShips #970: the dead-peer check now fast-fails only primary calls awaiting a\nresponse (carry a \"session\"); fire-and-forget results/rejects/callbacks to a\ngone peer are dropped silently — eliminating the reject-storm that churned\nclients into reconnect loops at N>=2 when they disconnect mid-RPC. With the\nmigration fix in 0.21.88 (#969), hypha-server is safe at N>=2.\n\nBumps all version pins. Last commit so the auto-release fires.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(release): 0.21.89 — fix multi-replica reject-storm (F6, second …",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-06-17T06:24:02Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "5fae9cb68eedcb46d31dd1dff689b4e14a2ae50f",
"body": "…>=2) (#970)\n\n* fix(f6): drop fire-and-forget messages to gone peers (reject-storm, N>=2)\n\nSECOND N>=2 incident (2026-06-17, distinct from the migration fix #969): when\na client with in-flight RPCs disconnects, the server cleans up its pending\npromises by routing reject/result callbacks back to the \n[…]\ntest_dead_peer_reject_storm.py),\nwhich fail without their respective fixes.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(f6): drop fire-and-forget messages to gone peers (reject-storm, N…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-17T06:23:09Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1ff3821de8c8d94aab948734a521bbf739594da3",
"body": "…t (F6)\n\nShips the cross-pod dead-peer fix (#969): on (re)connect a pod broadcasts\nclient-reconnected so every pod clears the migrated client from its per-pod\n_recently_disconnected cache — fixing the N>=2 false-reject (\"Target peer is\nnot connected\") that forced the first multi-replica rollout back\n[…]\ne.\n\nBumps all version pins per the release checklist. This is the LAST commit so\nthe auto-tag/auto-publish Release job detects the new version.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(release): 0.21.88 — fix multi-replica cross-pod RPC false-rejec…",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-06-17T03:03:12Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a002c7d229d144edd8ee717b2de60c487f57648a",
"body": "…correctness) (#969)\n\n* fix(f6): clear cross-pod recently-disconnected cache on re-pin (N>=2 correctness)\n\nPROD INCIDENT (2026-06-17): with hypha-server at N>=2, the dead-peer check in\nRedisRPCConnection.emit_message (\"Target peer <id> is not connected\") false-\nrejected RPCs to a peer that had re-pi\n[…]\nt migration; test client re-pin across pods, not just stable\ncross-pod RPC.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(f6): clear cross-pod recently-disconnected cache on re-pin (N>=2 …",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-17T03:02:08Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "070a6424bf772c12c5579feb349456724386ec1f",
"body": "… download\n\n60s was still occasionally too tight: the text-embedding add_vectors triggers\na one-time ~130MB fastembed ONNX model download (BAAI/bge-small-en-v1.5) on\neach fresh CI runner, which under CI network/CPU load can exceed 60s — the test\nflaked again on the release commit. Use 180s (≈3x margin over a worst-case cold\ndownload) to make it deterministic.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "test(artifact): raise vector-collection timeout to 180s for fastembed…",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-06-16T19:16:59Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a2cf2d4e4f12eafdfb3a29deb13f076a05fe2079",
"body": "…ening\n\nRelease 0.21.87. Ships F6 Phase 1 (#964–#968): leader election + leader-gated\nautoscaling, per-resource locks for workspace-cleanup and app inactivity-stop,\nand a reset-redis guard so a restarting replica can't wipe a live cluster —\nmaking hypha-server safe to run with N>=2 replicas sharing \n[…]\n+ one real Redis).\nAlso includes CI fixes (Release-job pip provisioning; flaky vector test).\n\nBumps all version pins per the release checklist.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(release): 0.21.87 — F6 Phase 1 multi-replica control-plane hard…",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-06-16T19:06:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7afb4f75de1fd59d6ffeb8ff9860674caf78c85b",
"body": "test_artifact_vector_collection intermittently failed main CI with\n\"TimeoutError: ...add_vectors\": embedding generation (sentence-transformer,\nincl. cold start) can exceed the default ~10s RPC method timeout under CI CPU\nload. The same tree passed in the PR build, confirming flakiness, not a\nregression. Give that connection a 60s method_timeout so the embedding-heavy\nadd_vectors calls have headroom. Unrelated to F6.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "test(artifact): raise method timeout for vector add to fix flaky CI",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-06-16T18:29:22Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a028983683b8f65c8d9834f7f3c120e37d2c1620",
"body": "In a multi-replica deployment several replicas may each register an\ninactivity tracker for the same app session, so the inactivity callback can\nfire on each of them and race on _stop. _stop_after_inactive now takes a short\nper-session lock (app-stop-lock:{id}, 30s TTL) via the new\nServerAppControlle\n[…]\nfakeredis): only one replica acquires the lock; different\nsessions don't block each other; the lock expires to allow a later stop.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(f6): per-session lock for app inactivity-stop (Phase 1, P4) (#968)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-16T15:46:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "32dd494c856ae63074ce53425d14514fb241da13",
"body": "The Release job (push to main) failed at \"Upgrade pip\" with\n\"No module named pip\": the conda env created by setup-miniconda can resolve\nwithout pip, so `python -m pip install pip` fails. Same root cause as the\nbuild-job fix (78855189) and the PyPI publish fix (#962); the Release job's\npip step was the last one still unpatched. Provision pip via conda first.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "ci(release): provision pip in conda env for the Release job",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-06-16T15:05:29Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9518ed637c1c4b806eba67d0be738f692a2fb87f",
"body": "…1) (#967)\n\nfeat(f6): guard reset-redis + real multi-replica integration tests (P1)\n\nP1/P0 — protect a live cluster from a flush:\nRedisStore._maybe_reset_redis() flushes shared Redis only when reset is\nrequested AND no other hypha server is already registered (peers detected\nvia their public built-i\n[…]\ns\nwhen a peer is registered, no-op when not requested.\n\nCompletes F6 Phase 1 (P0/P1 + P2 #965 + P3 #966 on the leader-lease #964).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(f6): reset-redis guard + real multi-replica integration tests (P…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-14T09:00:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2f9d4a87a0343d56bad7167db36e4d195df997ab",
"body": "Prevents several replicas' activity trackers from concurrently cleaning up\nthe same inactive workspace, without leaking workspaces.\n\n_cleanup_inactive_workspace() now takes a short per-workspace NX lock\n(ws-cleanup-lock:{id}, 30s TTL) before deleting; if another replica holds it,\nthis replica no-ops\n[…]\ntimer and\nkeeps the workspace when clients are still present. Updates\ndocs/multi-replica-design.md §3.1/P3 to record the decision.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(f6): per-workspace lock for activity cleanup (Phase 1, P3) (#966)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-14T08:53:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "00f80f65074853be27de99bda25c17e0cf79118e",
"body": "…se 1a) (#965)\n\nBuilds on the Phase-0 leader-lease primitive (#964). Wires it into the store\nand uses it to gate the autoscaling control-plane singleton so it does not\nrun on every replica.\n\n- RedisStore.init() starts a LeaderLease (identity = server_id); teardown()\n stops it. New RedisStore.is_lea\n[…]\np loop (P3, needs care to avoid a cleanup-leak regression) and\nidempotent built-in startup (P1). See docs/multi-replica-design.md.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(f6): wire leader lease into store + leader-gate autoscaling (Pha…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-14T03:15:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d12ac126e561655fe9ce1a33384870a84d5dd30d",
"body": "feat(f6): add Redis leader-lease primitive (Phase 0)\n\nAdds hypha/core/leader.py — a best-effort single-leader election over a\nshared Redis key, the \"exactly-one-runner\" primitive for the control-plane\nsingletons that must not run on every replica in a multi-replica deployment\n(autoscaling monitor, w\n[…]\na peer's lease, failover after expiry, end-to-end loop promotion, ttl/\nrenew-interval guard, key isolation. 10 tests, all passing.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(f6): Redis leader-lease primitive (Phase 0) (#964)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-14T01:57:53Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9388233d1c8548ae6e40e8716cce29cf492706a3",
"body": "Adds docs/multi-replica-design.md scoping F6 (multi-replica hypha-server):\ndata-plane already horizontally scalable; the work is control-plane\nhardening (leader-lease over autoscaling/activity-cleanup, idempotent\nstartup) + a config fix (HYPHA_RESET_REDIS) + sticky affinity for Phase 1.\n\nReconciles \n[…]\nHPA). Phased plan; Phase 1 targets zero-blip rollouts and\nfinally validates the shipped F4/F5 reconnection work on a warm replica.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(f6): scope multi-replica hypha-server design (#963)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-14T01:51:23Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "03110657f6dd7a575b1a427f0a6e9c0c80885169",
"body": "The PyPI publish job sets up a conda env via setup-miniconda, but that env\ncan resolve without pip, so the next step's `python -m pip install pip`\nfailed with \"No module named pip\" — blocking the 0.21.86 release publish.\n\nProvision pip via `conda install` first (mirrors the test-env fix in\n78855189), then upgrade it.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "ci(publish): provision pip in conda env before PyPI publish (#962)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-13T20:32:14Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9eea27d44752e0e06b57221c97e102c09696c8a9",
"body": "Release 0.21.86. Ships F4 (graceful WS + HTTP-stream connection draining on\nserver shutdown, merged in #960) and bumps the bundled hypha-rpc dependency\n0.21.38 -> 0.21.42.\n\nhypha-rpc 0.21.42 brings:\n- getService/wm proxy retarget to the new manager_id after reconnection\n (avoids a spurious 400 on g\n[…]\n in requirements.txt/setup.py/__init__.py) and refreshed the bundled\nhypha-rpc JS static assets via scripts/upgrade_rpc_assets.py.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(release): 0.21.86 + bump hypha-rpc to 0.21.42 (#961)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-13T19:35:36Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "21c039ded78f3bac437a22e3b9f15d6cfe2596da",
"body": "…n (#960)\n\nOn rollout/redeploy the old pod cut long-lived connections abruptly, so\nclients only detected the dead pod via their heartbeat/read timeout and\nall reconnected in the same window — a thundering-herd reconnection storm\non the new pod.\n\nRoot cause: RedisStore.teardown() closed only WebSocke\n[…]\nocks).\n\nTracked as F4 (svamp reliability audit). The companion k8s preStop drain\nlives in the deployment manifests, not this repo.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(shutdown): gracefully drain WS and HTTP-stream clients on teardow…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-13T16:21:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7e31b88a76f754dadcb74fae34acea6f8a9068ed",
"body": "…t (#958) (#959)\n\n* fix(auth): wildcard scope must not shadow stronger per-workspace grant (#958)\n\nA workspace owner who is not a global admin could not start a server-app in\ntheir own workspace: apps.start mints a per-app client token via\ngenerate_token, which requires admin on the target workspace\n[…]\nstall pip to make env provisioning\ndeterministic.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(auth): wildcard scope must not shadow stronger per-workspace gran…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-06-13T15:42:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a06f5cd23dd86b59c3e1edf4d9c4205ae354b04c",
"body": "…957)\n\nExternal report: 5 sequential GETs to /zip-files/data.zarr.zip/~/0/.zarray\non a 236 GB / 3.6M-entry ZIP64 archive each took 28–55 s and timed out\nVizarr's HTTP client. A 4.68 GB / 71k-entry archive on the same path took\n~0.7–1.3 s. The functional ZIP64 fix from 0.21.84 worked, but exposed a\np\n[…]\nget_zip_file_content_endpoint{,_large_scale,_very_large}`.\nZIP64 functional tests from #956 still pass.\n\nBumps version to 0.21.85.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(zip-files): memoize parsed central directory to fix perf cliff (#…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-05-02T12:26:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b307dfce71362c43a06a47598cb3feacfd124931",
"body": "…ies) (#956)\n\nReported by an external agent against artifact reef-imaging/poc-hpa-plate1-zip:\nGET .../zip-files/data.zarr.zip/~/.zattrs returned 500 with \"Corrupt zip64\nend of central directory locator\" on a 4.68 GB / 71308-entry ZIP64 archive\nthat python's zipfile validates correctly when given the\n[…]\numps version to 0.21.84 and syncs helm-charts / docker-compose tags\n(previously stuck at 0.21.78) per CLAUDE.md release checklist.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(zip-files): correctly handle ZIP64 archives (>4 GB or >65535 entr…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-05-02T08:26:09Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4e5342661fe76c17508767ee7605d8c94cba29c0",
"body": "…rom #938) (#955)\n\nfeat: add connection admission control to prevent reconnection storms\n\nWhen a server restarts, all connected clients reconnect simultaneously,\ntriggering heavy Redis SCAN/DELETE operations that saturate the event\nloop and cause cascading liveness probe failures. This adds a semaph\n[…]\nnection setup and random jitter\n(0-1s) for reconnecting clients to spread the load.\n\nConfigurable via HYPHA_MAX_CONCURRENT_CONNECTIONS env var.\n\nCo-authored-by: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: connection admission control for reconnection storms (rebased f…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-05-02T07:38:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a6c8bd9d971847c1efaf2a25d53e411a9eb9820a",
"body": "Adds docs/login.md — a focused, agent-friendly guide for client-side\nauthentication: Python and JavaScript login() flows, login_callback\npatterns, programmatic generate_token, expiration handling, logout, and\ntroubleshooting. Sourced from the actual hypha-rpc client signatures.\n\nAudits the agent-ski\n[…]\n the skills\n zip so offline agents see them.\n\nNo new behavior — purely documentation surfacing. All 56 test_skills.py\ntests pass.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(agent-skills): add login guide and audit guide cross-links (#954)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-04-28T14:39:11Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "dd38f63216f2cca74fea7f86ac746bdffa1a0c87",
"body": "…) (#953)\n\nA signed-in browser sending its access_token cookie to a public service\nURL in an arbitrary workspace was rejected with a workspace-level 403\nbefore the per-service visibility check ran, even though the same URL\nworked anonymously.\n\nNow the HTTP route only requires workspace read permissi\n[…]\nder and\naccess_token cookie auth paths, and verifying that protected services\nin unowned workspaces remain forbidden.\n\nCloses #952\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(http): defer workspace permission check for public services (#952…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-04-28T14:38:39Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "af7c20fc4df0e7a583c49bb24f361a4af64c0891",
"body": "…ts (#951)\n\nSome S3-compatible providers — notably Google Cloud Storage with scoped\nHMAC keys — return AccessDenied on CreateBucket even when the bucket\nalready exists and the key can read/write objects in it. This prevents\nhypha from starting after an image upgrade whenever the provisioning\nHMAC ke\n[…]\nObserved in production: a 0.21.82 rollout crash-looped for 14 days with\n>3900 restarts because CreateBucket returned AccessDenied instead of\nthe BucketNameUnavailable code the earlier fix anticipated.",
"is_bot": false,
"headline": "fix(s3): handle AccessDenied on CreateBucket when bucket already exis…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-04-26T22:03:58Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ddad7f37df61b21682ab90c10070dbc5cb81edd0",
"body": "Adds an optional ``email`` field to ``TokenConfig``. When set, ``generate_token``\nwrites it onto the newly-minted JWT's email claim. Restricted to callers\ncarrying the ``admin`` role so a workspace admin cannot forge emails for\nanother user.\n\nMotivation: downstream services that validate email on in\n[…]\nine tokens because admin ``generate_token``\ncalls produce tokens with ``email: null``. This lets operators mint\nuser-attributed tokens so those gateways can authenticate and attribute\nusage correctly.",
"is_bot": false,
"headline": "feat: allow admins to override email claim in generate_token (#950)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-04-26T22:00:12Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "56b63eb06ec918c4f6a93d42dc302f8c1f7e822b",
"body": "feat: support wildcard artifact-scoped tokens for get_file and put_file\n\nAdd wildcard `*` path support for artifact-scoped tokens, allowing a single\ntoken to grant access to all files within a specific artifact without\ngranting access to the entire workspace.\n\nTokens can now use `get_file:<artifact_\n[…]\norted.\n\nAlso adds `token` query parameter to the PUT upload endpoint for\nscoped token authentication on file uploads.\n\nCloses #948\n\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: support wildcard artifact-scoped tokens (#949)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-04-26T21:58:39Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b7f60031765a35c4e14e6c2bc33c8754ff41b5fd",
"body": "* fix: connection counter leak causing user lockout and memory drift\n\nThe resource limits manager's connection counters (per-user and\nper-workspace) were not properly decremented in several code paths,\ncausing counters to inflate over time. After 7 days in production,\ntracked connections reached 258\n[…]\n@anthropic.com>\n\n* chore: bump version to 0.21.82\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: connection counter leak causing user lockout (#947)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-19T06:54:00Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d9cd27acbfe7083e5f9f5c965265b762044abb8c",
"body": "* chore: upgrade hypha-rpc to 0.21.36 and bump hypha to 0.21.81\n\nIncorporates oeway/hypha-rpc#159 which fixes JS kwargs unpacking in\n_handle_method — Python→JS calls with keyword arguments now map correctly\nto named parameters instead of passing the kwargs dict as a positional arg.\n\nCo-Authored-By: \n[…]\n\n* fix(test): update numpy echo assertion for kwargs unpacking\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: upgrade hypha-rpc to 0.21.36 and bump hypha to 0.21.81 (#946)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-19T05:57:49Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8ed434869ac9c46112561ff2ecd8ec980b8cbbc2",
"body": "fix: use generation counter to prevent reconnection race in handle_disconnection\n\nWhen a client reconnects quickly, the old connection's handle_disconnection\ncan race with the new connection's service registration:\n\n1. Old connection closes → handle_disconnection starts\n2. Client reconnects → new co\n[…]\nck in case reconnection happened during\n earlier async work\n\nThis eliminates the 2/3 reconnection flake in test_multiple_clients_reconnection.\n\nCo-authored-by: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: prevent reconnection race in handle_disconnection (#942)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-19T03:58:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "56fea1ca090b8f5a34aca9f663db184085f1efc3",
"body": "…945)\n\n* feat: add resource limits, admin blocking, and HTTP rate limit improvements (#943)\n\n- Increase HTTP rate limits (20→100 req/s, 100→500 burst) to prevent\n daemon clients from being rate-limited during normal multi-session use\n- Add Retry-After header to 429 responses for proper client backo\n[…]\nONNECTIONS_PER_USER: 50 → 200\n- HYPHA_MAX_CLIENTS_PER_WORKSPACE: 200 → 1000\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: resource limits, admin blocking & HTTP rate limit fix (#943) (#…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-11T06:48:11Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "72f55174aced4a3e1217b434e4e1de0acbb93db0",
"body": "* fix: add per-client WebSocket rate limiting to prevent server crash loops\n\nAnonymous clients spamming RPC calls (65+ service registrations/sec) saturate\nthe event loop, causing liveness probe timeouts and a self-reinforcing\ncrash-restart cycle (28 restarts in 19 hours observed in production).\n\nAdd\n[…]\nuse pattern (sustained 65+ msg/sec\nservice registration spam over minutes).\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: per-client WebSocket rate limiting to prevent crash loops (#937)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-08T10:11:03Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1cd40f30d37ab46ce92caf523c2af79d43b21ca7",
"body": "…anup note\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(admin): update SKILL.md: 0.21.78 live, peak scale baselines, cle…",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-07T12:20:13Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "835a1167143b45dd5a1fcac7dcac4f51b6b0d44c",
"body": "Includes:\n- perf(workspace): batch Redis pipeline for list_services, list_clients,\n delete_workspace, cleanup_client (N HGETALL → 1 pipeline round-trip)\n- feat(admin): fast cleanup cmd + updated alert thresholds for 2000+ connections\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: bump hypha to 0.21.78 (#935)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-07T11:30:21Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9c412f5bfcd503ac376f8b3d64f09f937dd47b60",
"body": "…e (#934)\n\n* perf(workspace): batch HGETALL calls in list_services() using Redis pipeline\n\nReplace N sequential HGETALL Redis calls with a single pipeline round-trip.\nPreviously, list_services() scanned for matching keys (fast), then fetched\neach key's hash individually in a for loop — N+1 Redis rou\n[…]\n,\n cleanup timing note, _cleanup_orphaned_client_services scale gotcha\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "perf(workspace): batch HGETALL in list_services() using Redis pipelin…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-07T10:46:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "68619edbb381a711bea949b2aea9af66727d9d6d",
"body": "…ts fix\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(admin): update SKILL.md: 0.21.77 live, document limit_max_reques…",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-07T07:31:34Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "79b9390e4033e023155286da66a3a634867b990c",
"body": "Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: bump hypha to 0.21.77",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-07T07:04:44Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "70926abad3c15355ecde5a099bf57d79adb86ef4",
"body": "Includes: fix: remove limit_max_requests from uvicorn (#932)\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: bump hypha to 0.21.76",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-07T06:54:00Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "27202d9efdc5d407c3aa64b64197eadaa70df027",
"body": "… failures (#932)\n\nSetting limit_max_requests=10000 caused uvicorn to restart the worker\nprocess after 10k requests. During reconnection storms (server upgrade,\n100+ clients reconnecting), this limit was hit in ~12 minutes, causing\na brief window where the server stopped accepting TCP connections.\n\n\n[…]\n and GC fixes in\nrecent PRs (#920, #921, #923, #924, #925) provide proper memory management\nwithout needing periodic uvicorn worker respawns.\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: remove limit_max_requests from uvicorn to prevent liveness probe…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-07T06:53:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2c68cbeaa26628839c6727dd3554c57482bbc69e",
"body": "Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(admin): update SKILL.md: 0.21.75 live, Redis pool threshold 900",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-07T04:54:42Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "1a3fba32e1da15be24d4090fd0770135e2af7c87",
"body": "At 521+ active RPC connections, ~562 Redis clients is proportional\nand expected (ratio ~1.08 per connection). The old threshold of 500\nwas set for 80-130 active connections. 900 allows up to ~830 active\nconnections before alerting, appropriate alarm for a real pool explosion\nlike the 1218 pre-upgrade incident.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(admin): raise HIGH REDIS POOL threshold 500→900",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-07T04:53:24Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "06459f25ab47e570f9b121278d047427baca3eaa",
"body": "- Raise HIGH WS SERVICES threshold: 200 → 1000 for hypha-agents\n- Update health baselines to reflect current high-load operation\n (Active RPC 150-350, services 300-750, etc.)\n- Update hc-* known issue: 4Gi → 6Gi (bumped Mar 7 2026)\n- Update version notes: 0.21.74 LIVE, 0.21.75 building\n- Fix hypha-server memory note (currently ~2Gi RSS)\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(admin): update SKILL.md with current baselines and thresholds",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-07T04:31:08Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9f4c0f548ae55d1369829845535aa94e3cfb3da9",
"body": "The exec_py code was calling kickout_client(client_id, context=...)\nbut the actual signature is kickout_client(workspace, client_id, code, reason).\nFixed to pass all required positional args, no context kwarg.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(admin): fix kickout_client call signature",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-07T04:28:49Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "4a827639d68c0b02220a715d818202f3fe632ee3",
"body": "With hypha-agents running 600-750+ services (compute worker proxy\nregistrations), the 1000 threshold was firing as noise. 1500 gives\nheadroom while still catching real leaks.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(admin): raise HIGH SERVICES threshold to 1500",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-07T04:07:27Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f7ee0ad6ed048d3e91f00f15d77b8e5ea552511d",
"body": "Includes: fix(apps): preserve worker_managed sessions on client disconnect (#899) (#930)\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: bump hypha to 0.21.75 (#931)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-07T04:05:57Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "c6f401ff54e55ddaaba39cf96bdf8fdb9fce5de7",
"body": "- HIGH RPC threshold: 300 → 600 (369 is now normal with many hc-compute sandboxes)\n- HIGH WS SERVICES threshold for hypha-agents: 200 → 1000 (628 services is expected with many deployed apps)\n- HC POD HIGH MEM threshold: 60% → 75% (60% has lots of headroom, alert at true danger zone)\n- Add hc_pods.total/running/oom_killed summary counts to report JSON output\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(admin): tune thresholds and add hc_pods summary to report",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-07T03:50:41Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d6a2b726cdecf81857b6c0187a9e7a01ea69c1c0",
"body": "…9) (#930)\n\n* feat(admin): add version-check command to compare live vs latest GitHub release\n\nQuickly shows if the live server is behind the latest GitHub release.\nOutput: live version, latest release tag+date, UP TO DATE / UPGRADE AVAILABLE status.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthr\n[…]\npha-compute self-install pattern (installs from GitHub main at startup)\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(apps): preserve worker_managed sessions on client disconnect (#89…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-07T03:04:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c496a9d354d56cb642d3c0e104dbaf723e1fa797",
"body": "* chore: bump hypha to 0.21.74\n\nIncludes fixes merged to main since 0.21.73:\n- fix: clean up ghost _last_seen entries in idle cleanup loop (#925)\n- fix: propagate worker_id from install() through commit_app() to start() (#926)\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\n\n* feat: add s\n[…]\nte SKILL.md — 0.21.73 deployed, OOM detection note, known issues update\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: bump hypha to 0.21.74 (#928)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-07T02:15:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d9e8f02205ccb5b591349fe77574707d9f6d9499",
"body": "…ly ignoring them (#929)\n\n* fix: delete null session metadata fields from Redis instead of silently ignoring them\n\nWhen `_store_session_in_redis` encountered a key with value `None`, it\nsilently skipped it. This meant that if a caller set a field to `None`\nintending to clear it, the previous value f\n[…]\nelds are never written\n- multiple null fields in one update all deleted\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: delete null session metadata fields from Redis instead of silent…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-07T00:51:38Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c2105c796fbc70492ac8e295fe9cce5275703199",
"body": "feat(admin): add version-check command to compare live vs latest GitHub release\n\nQuickly shows if the live server is behind the latest GitHub release.\nOutput: live version, latest release tag+date, UP TO DATE / UPGRADE AVAILABLE status.\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(admin): add version-check command (#927)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-06T23:52:02Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "ca8216c1d0d66cff07bdc5542b286428139b77d4",
"body": "…() (#926)\n\nWhen apps.install(worker_id=...) was called with a cross-workspace\nworker (e.g. hypha-agents/hypha-compute-worker), the worker_id was\nused for the compilation step but silently dropped when calling\ncommit_app() for the verification run. commit_app() then fell back\nto get_server_app_worke\n[…]\n start() call. The worker selection logic in start() already\nhandles cross-workspace worker IDs correctly via get_worker_by_id().\n\nFixes #922\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: propagate worker_id from install() through commit_app() to start…",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-06T23:13:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e4389f27f6beb60f7b08236025bf0b61cef85405",
"body": "Read /sys/fs/cgroup/memory.current when available (cgroups v2) for\naccurate container memory reporting instead of summing psutil RSS values\nper-process, which overcounts shared memory pages.\n\nFalls back to proc_rss + children_mb on non-cgroup environments.\n\nCgroup reports ~1947 MB vs kubectl top 1703 Mi (working set, excludes\npage cache) — both are accurate; cgroup includes cached pages.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(admin): use cgroup memory.current for accurate container_mem_mb",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-06T21:53:34Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9b1c10d984671e4c90caaeb0e480b1dd76a6f498",
"body": "… pattern\n\n- Add pending_rpc_calls and top_types to Patterns & Gotchas section\n- Add pending_rpc_calls baseline row to Health Baselines table\n- Document memory growth ~2-3 MB per service (not a leak)\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(admin): document pending_rpc_calls, top_types, and memory growth…",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-06T21:23:16Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "cefde2b0c091ca395da6ce4b1aa1d131851474c2",
"body": "- Capture task snapshot once (_task_snap) to avoid calling all_tasks() 4x\n- Add top_types: top 8 task coroutine types by count — shows WS infra,\n heartbeats, Timer._job (pending RPC calls) and any accumulating patterns\n- Add pending_rpc_calls: count of Timer._job tasks (each active RPC call\n creat\n[…]\nis makes task bursts (e.g. 467 Timer._job during hypha-agents burst)\nvisible in the report without needing to run a separate 'tasks' command.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(admin): add top_types and pending_rpc_calls to report tasks section",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-06T21:22:39Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b7885c238e5e9dc772986b5c0a96a5510dffa33e",
"body": "Adds not_in_ws field to connections in the JSON report. This shows how\nmany clients have services registered in Redis but are not in the active\nWebSocket dict (potential HTTP transport clients or zombies). Also adds\nSUSPECT CLIENTS alert when not_in_ws > 5 to prompt running 'zombies'.\n\nThis avoids the need to run quick-zombies as a separate command in most\nroutine health check iterations.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(admin): add not_in_ws count to report connections section",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-06T21:03:06Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "b46bfad6ae6f75279a3d1f4c096746a30bc68fe3",
"body": "…weaviate new pod\n\nContainer memory baseline raised from 1200-1600 to 1400-1800 Mi to reflect\nhypha-agents running 120+ services (compute worker proxy registrations).\n\nhypha-weaviate pod replaced on Mar 6 2026; old pod had 85 OOM restarts.\nNew pod (58d9745f9) is stable at ~115 Mi with 0 restarts.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(admin): update baselines — container memory 1400-1800 Mi, hypha-…",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-06T20:47:37Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e39f3149b22ef7ac35b5f7d8c7c465339242c5b0",
"body": "…threshold\n\n- Add rpc_object_entries to report tasks section (gc scan for RPC._object_store);\n baseline 50K-80K; alert threshold 200K\n- Raise HIGH WS SERVICES alert threshold for hypha-agents to 200 (was 100);\n hypha-compute-worker legitimately registers 120+ proxy services\n- Update SKILL.md baselines: RSS 800-1200 MB, new rpc_object_entries row,\n updated hypha-agents service count documentation\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(admin): add rpc_object_entries metric and tune HIGH WS SERVICES …",
"author_name": "oeway",
"author_login": "oeway",
"committed_at": "2026-03-06T20:45:57Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "1896f72966095d7d2d0c7540143f8a43c65af43a",
"body": "The _do_idle_cleanup() method only removed _last_seen entries when an\nactive WebSocket was found. Ghost entries (in _last_seen but not in\n_websockets) were silently skipped and accumulated indefinitely.\n\nRoot cause: a client entry created during a reconnection race where the\nold connection's handler\n[…]\nalled.\n\nObserved live: ws-user-github|478667/r0u78ukody client persisted in\n_last_seen for 9+ hours with no active WebSocket and no services.\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: clean up ghost _last_seen entries in idle cleanup loop (#925)",
"author_name": "Wei Ouyang",
"author_login": "oeway",
"committed_at": "2026-03-06T20:05:58Z",
"body_truncated": true,
"is_coding_agent": true
}
],
"releases_count": 100,
"commits_last_year": 284,
"latest_release_at": "2026-07-31T03:07:38Z",
"latest_release_tag": "v0.21.127",
"releases_from_tags": false,
"days_since_last_push": 0,
"active_weeks_last_year": 30,
"days_since_latest_release": 0,
"mean_days_between_releases": 0.8
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 37,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "hypha",
"exists": true,
"license": "MIT",
"keywords": [],
"ecosystem": "pypi",
"matches_repo": true,
"registry_url": "https://pypi.org/project/hypha/",
"is_deprecated": false,
"latest_version": "0.21.127",
"repository_url": "http://github.com/amun-ai/hypha",
"versions_count": 401,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": 5442,
"first_published_at": "2021-10-16T20:02:42.140881Z",
"latest_published_at": "2026-07-31T03:07:33.519840Z",
"latest_version_yanked": null,
"days_since_latest_publish": 0
}
]
},
"popularity": {
"forks": 14,
"stars": 24,
"watchers": 2,
"fork_history": {
"days": [
{
"date": "2022-07-19",
"count": 1
},
{
"date": "2022-07-26",
"count": 1
},
{
"date": "2022-12-01",
"count": 1
},
{
"date": "2023-06-25",
"count": 1
},
{
"date": "2023-09-18",
"count": 1
},
{
"date": "2025-01-21",
"count": 1
},
{
"date": "2025-10-02",
"count": 1
},
{
"date": "2025-10-16",
"count": 1
},
{
"date": "2026-01-14",
"count": 1
},
{
"date": "2026-01-23",
"count": 1
},
{
"date": "2026-03-01",
"count": 1
},
{
"date": "2026-03-12",
"count": 1
}
],
"complete": true,
"collected": 12,
"total_forks": 14
},
"star_history": null,
"open_issues_and_prs": 20
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [
"notebooks"
],
"has_llms_txt": true,
"has_dockerfile": true,
"has_mcp_signal": true,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [],
"largest_source_bytes": 512705,
"source_files_sampled": 201,
"oversized_source_files": 25,
"agent_instruction_files": [
"CLAUDE.md"
],
"agent_instruction_max_bytes": 55402
},
"dependencies": {
"manifests": [
"requirements.txt",
"requirements_dev.txt",
"requirements_lint.txt",
"requirements_pypi.txt",
"requirements_test.txt",
"setup.cfg",
"setup.py"
],
"advisories": {
"error": null,
"scope": "repository_graph",
"source": "osv",
"findings": [
{
"name": "black",
"direct": false,
"version": "24.10.0",
"severity": "critical",
"ecosystem": "pypi",
"cvss_score": 9.8,
"advisory_ids": [
"GHSA-3936-cmfr-pm3m",
"PYSEC-2026-2120",
"PYSEC-2026-2121"
],
"fixed_version": "26.3.1",
"advisory_count": 3,
"oldest_advisory_days": 141
},
{
"name": "python-jose",
"direct": false,
"version": "3.3.0",
"severity": "critical",
"ecosystem": "pypi",
"cvss_score": 9.1,
"advisory_ids": [
"GHSA-6c5p-j8vq-pqhj",
"GHSA-cjwg-qfpm-7377",
"PYSEC-2024-232",
"PYSEC-2024-233",
"PYSEC-2025-185"
],
"fixed_version": "3.4.0",
"advisory_count": 5,
"oldest_advisory_days": 826
},
{
"name": "jinja2",
"direct": false,
"version": "3.1.4",
"severity": "high",
"ecosystem": "pypi",
"cvss_score": 8.8,
"advisory_ids": [
"GHSA-cpwx-vrp4-4pq7",
"GHSA-gmj6-6f8f-6699",
"GHSA-q2x7-8rv6-6q7h",
"PYSEC-2026-1471",
"PYSEC-2026-1472",
"PYSEC-2026-1475"
],
"fixed_version": "3.1.6",
"advisory_count": 6,
"oldest_advisory_days": 584
},
{
"name": "lxml",
"direct": false,
"version": "4.9.3",
"severity": "high",
"ecosystem": "pypi",
"cvss_score": 7.5,
"advisory_ids": [
"GHSA-vfmq-68hx-4jfw",
"PYSEC-2026-87"
],
"fixed_version": "6.1.0",
"advisory_count": 2,
"oldest_advisory_days": 100
},
{
"name": "mcp",
"direct": false,
"version": "1.11.0",
"severity": "high",
"ecosystem": "pypi",
"cvss_score": 7.1,
"advisory_ids": [
"GHSA-9h52-p55h-vw2f",
"GHSA-jpw9-pfvf-9f58",
"GHSA-vj7q-gjh5-988w",
"PYSEC-2026-1617",
"PYSEC-2026-3482",
"PYSEC-2026-3483"
],
"fixed_version": "1.28.1",
"advisory_count": 6,
"oldest_advisory_days": 240
},
{
"name": "msgpack",
"direct": false,
"version": "1.0.8",
"severity": "high",
"ecosystem": "pypi",
"cvss_score": 7.5,
"advisory_ids": [
"GHSA-6v7p-g79w-8964"
],
"fixed_version": "1.2.1",
"advisory_count": 1,
"oldest_advisory_days": 41
},
{
"name": "setuptools",
"direct": false,
"version": "69.0.3",
"severity": "high",
"ecosystem": "pypi",
"cvss_score": 8.8,
"advisory_ids": [
"GHSA-5rjg-fvgr-3xxf",
"GHSA-cx63-2mw6-8hw5",
"GHSA-h35f-9h28-mq5c",
"PYSEC-2025-49",
"PYSEC-2026-1918",
"PYSEC-2026-3447"
],
"fixed_version": "83.0.0",
"advisory_count": 6,
"oldest_advisory_days": 745
},
{
"name": "wheel",
"direct": false,
"version": "0.41.1",
"severity": "high",
"ecosystem": "pypi",
"cvss_score": 7.1,
"advisory_ids": [
"GHSA-8rrh-rw8j-w5fx",
"PYSEC-2026-2047"
],
"fixed_version": "0.46.2",
"advisory_count": 2,
"oldest_advisory_days": 189
},
{
"name": "pytest",
"direct": false,
"version": "7.4.0",
"severity": "moderate",
"ecosystem": "pypi",
"cvss_score": 6.8,
"advisory_ids": [
"GHSA-6w46-j5rx-g56g",
"PYSEC-2026-1845"
],
"fixed_version": "9.0.3",
"advisory_count": 2,
"oldest_advisory_days": 189
},
{
"name": "requests",
"direct": false,
"version": "2.31.0",
"severity": "moderate",
"ecosystem": "pypi",
"cvss_score": 5.6,
"advisory_ids": [
"GHSA-9hjg-9r4m-mvj7",
"GHSA-9wx4-h78v-vm56",
"GHSA-gc5v-m9x4-r6x2",
"PYSEC-2026-1872",
"PYSEC-2026-1873",
"PYSEC-2026-2275"
],
"fixed_version": "2.33.0",
"advisory_count": 6,
"oldest_advisory_days": 801
}
],
"collected": true,
"malicious": [],
"truncated": false,
"by_severity": {
"high": 6,
"critical": 2,
"moderate": 2
},
"advisory_count": 39,
"affected_count": 10,
"assessed_count": 63,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 54,
"direct_affected_count": 0
},
"ecosystems": [
"pypi"
],
"dependencies": [],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "a2a-sdk",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "a2a-sdk",
"direct": false,
"version": "0.3.0",
"ecosystem": "pypi"
},
{
"name": "aioboto3",
"direct": false,
"version": "13.2.0",
"ecosystem": "pypi"
},
{
"name": "aiobotocore",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "aiocache",
"direct": false,
"version": "0.12.2",
"ecosystem": "pypi"
},
{
"name": "aiofiles",
"direct": false,
"version": "23.2.1",
"ecosystem": "pypi"
},
{
"name": "aiortc",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "aiosqlite",
"direct": false,
"version": "0.20.0",
"ecosystem": "pypi"
},
{
"name": "alembic",
"direct": false,
"version": "1.14.0",
"ecosystem": "pypi"
},
{
"name": "apscheduler",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "asyncpg",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "azure-identity",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "azure-keyvault-secrets",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "azure-storage-blob",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "backoff",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "base58",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "base58",
"direct": false,
"version": "2.1.1",
"ecosystem": "pypi"
},
{
"name": "black",
"direct": false,
"version": "24.10.0",
"ecosystem": "pypi"
},
{
"name": "boto3",
"direct": false,
"version": "1.36.0",
"ecosystem": "pypi"
},
{
"name": "click",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "conda-pack",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "cryptography",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "diskcache",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "dulwich",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "fakeredis",
"direct": false,
"version": "2.24.1",
"ecosystem": "pypi"
},
{
"name": "fastapi",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "fastapi",
"direct": false,
"version": "0.115.2",
"ecosystem": "pypi"
},
{
"name": "fastapi-sso",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "fastembed",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "fastembed",
"direct": false,
"version": "0.4.2",
"ecosystem": "pypi"
},
{
"name": "fastuuid",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "fastuuid",
"direct": false,
"version": "0.14.0",
"ecosystem": "pypi"
},
{
"name": "flake8",
"direct": false,
"version": "7.1.1",
"ecosystem": "pypi"
},
{
"name": "flake8-docstrings",
"direct": false,
"version": "1.7.0",
"ecosystem": "pypi"
},
{
"name": "friendlywords",
"direct": false,
"version": "1.1.3",
"ecosystem": "pypi"
},
{
"name": "google-cloud-iam",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "google-cloud-kms",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "google-genai",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "greenlet",
"direct": false,
"version": "3.1.1",
"ecosystem": "pypi"
},
{
"name": "gunicorn",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "hrid",
"direct": false,
"version": "0.3.0",
"ecosystem": "pypi"
},
{
"name": "httpx",
"direct": false,
"version": "0.28.1",
"ecosystem": "pypi"
},
{
"name": "hypha-rpc",
"direct": false,
"version": "0.21.46",
"ecosystem": "pypi"
},
{
"name": "ipykernel",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "jinja2",
"direct": false,
"version": "3.1.4",
"ecosystem": "pypi"
},
{
"name": "jsonschema",
"direct": false,
"version": "4.24.0",
"ecosystem": "pypi"
},
{
"name": "jupyter-client",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "kubernetes",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "litellm-enterprise",
"direct": false,
"version": "0.1.20",
"ecosystem": "pypi"
},
{
"name": "litellm-proxy-extras",
"direct": false,
"version": "0.2.19",
"ecosystem": "pypi"
},
{
"name": "lxml",
"direct": false,
"version": "4.9.3",
"ecosystem": "pypi"
},
{
"name": "mcp",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "mcp",
"direct": false,
"version": "1.11.0",
"ecosystem": "pypi"
},
{
"name": "mlflow",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "msgpack",
"direct": false,
"version": "1.0.8",
"ecosystem": "pypi"
},
{
"name": "numcodecs",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "numcodecs",
"direct": false,
"version": "0.16.2",
"ecosystem": "pypi"
},
{
"name": "numpy",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "ollama",
"direct": false,
"version": "0.5.1",
"ecosystem": "pypi"
},
{
"name": "openai",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "orjson",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "playwright",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "playwright",
"direct": false,
"version": "1.51.0",
"ecosystem": "pypi"
},
{
"name": "polars",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "prisma",
"direct": false,
"version": "0.11.0",
"ecosystem": "pypi"
},
{
"name": "prometheus-client",
"direct": false,
"version": "0.21.1",
"ecosystem": "pypi"
},
{
"name": "prompt-toolkit",
"direct": false,
"version": "3.0.50",
"ecosystem": "pypi"
},
{
"name": "psutil",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "psycopg2-binary",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "psycopg2-binary",
"direct": false,
"version": "2.9.10",
"ecosystem": "pypi"
},
{
"name": "ptpython",
"direct": false,
"version": "3.0.29",
"ecosystem": "pypi"
},
{
"name": "ptyprocess",
"direct": false,
"version": "0.7.0",
"ecosystem": "pypi"
},
{
"name": "pydantic",
"direct": false,
"version": "2.11.3",
"ecosystem": "pypi"
},
{
"name": "pyjwt",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pylint",
"direct": false,
"version": "3.2.6",
"ecosystem": "pypi"
},
{
"name": "pymultihash",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pymultihash",
"direct": false,
"version": "0.8.2",
"ecosystem": "pypi"
},
{
"name": "pynacl",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pyotritonclient",
"direct": false,
"version": "0.2.6",
"ecosystem": "pypi"
},
{
"name": "pytest",
"direct": false,
"version": "7.4.0",
"ecosystem": "pypi"
},
{
"name": "pytest-asyncio",
"direct": false,
"version": "0.21.1",
"ecosystem": "pypi"
},
{
"name": "pytest-cov",
"direct": false,
"version": "4.1.0",
"ecosystem": "pypi"
},
{
"name": "pytest-timeout",
"direct": false,
"version": "2.3.1",
"ecosystem": "pypi"
},
{
"name": "python-dotenv",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "python-jose",
"direct": false,
"version": "3.3.0",
"ecosystem": "pypi"
},
{
"name": "python-multipart",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "pyyaml",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "redis",
"direct": false,
"version": "5.2.0",
"ecosystem": "pypi"
},
{
"name": "redis",
"direct": false,
"version": "6.2.0",
"ecosystem": "pypi"
},
{
"name": "requests",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "requests",
"direct": false,
"version": "2.31.0",
"ecosystem": "pypi"
},
{
"name": "resend",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "rich",
"direct": false,
"version": "13.7.1",
"ecosystem": "pypi"
},
{
"name": "rq",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "scikit-learn",
"direct": false,
"version": "1.7.1",
"ecosystem": "pypi"
},
{
"name": "semantic-router",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "setuptools",
"direct": false,
"version": "69.0.3",
"ecosystem": "pypi"
},
{
"name": "shortuuid",
"direct": false,
"version": "1.0.13",
"ecosystem": "pypi"
},
{
"name": "simpervisor",
"direct": false,
"version": "1.0.0",
"ecosystem": "pypi"
},
{
"name": "sqlalchemy",
"direct": false,
"version": "2.0.35",
"ecosystem": "pypi"
},
{
"name": "sqlmodel",
"direct": false,
"version": "0.0.34",
"ecosystem": "pypi"
},
{
"name": "starlette-compress",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "stream-zip",
"direct": false,
"version": "0.0.83",
"ecosystem": "pypi"
},
{
"name": "tiktoken",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tokenizers",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "tox",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "twine",
"direct": false,
"version": "4.0.2",
"ecosystem": "pypi"
},
{
"name": "uuid-utils",
"direct": false,
"version": "0.9.0",
"ecosystem": "pypi"
},
{
"name": "uvicorn",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "uvicorn",
"direct": false,
"version": "0.23.2",
"ecosystem": "pypi"
},
{
"name": "uvloop",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "websocket-client",
"direct": false,
"version": "1.6.1",
"ecosystem": "pypi"
},
{
"name": "websockets",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "websockets",
"direct": false,
"version": "15.0.1",
"ecosystem": "pypi"
},
{
"name": "wheel",
"direct": false,
"version": "0.41.1",
"ecosystem": "pypi"
},
{
"name": "zarr",
"direct": false,
"version": null,
"ecosystem": "pypi"
},
{
"name": "zarr",
"direct": false,
"version": "3.1.2",
"ecosystem": "pypi"
}
],
"collected": true,
"truncated": false,
"total_count": 117,
"direct_count": 0,
"indirect_count": 117
}
},
"maintainership": {
"issues": {
"open_prs": 20,
"merged_prs": 637,
"open_issues": 0,
"closed_ratio": 1,
"closed_issues": 30,
"closed_unmerged_prs": 351
},
"bus_factor": 1,
"bot_contributors": 1,
"top_contributors": [
{
"type": "User",
"login": "oeway",
"commits": 1387,
"avatar_url": "https://avatars.githubusercontent.com/u/478667?v=4"
},
{
"type": "User",
"login": "MartinHjelmare",
"commits": 43,
"avatar_url": "https://avatars.githubusercontent.com/u/3181692?v=4"
},
{
"type": "User",
"login": "aaristov",
"commits": 5,
"avatar_url": "https://avatars.githubusercontent.com/u/11408456?v=4"
},
{
"type": "User",
"login": "ctr26",
"commits": 4,
"avatar_url": "https://avatars.githubusercontent.com/u/15238739?v=4"
},
{
"type": "User",
"login": "supermanhuyu",
"commits": 3,
"avatar_url": "https://avatars.githubusercontent.com/u/24794811?v=4"
},
{
"type": "User",
"login": "muellerflorian",
"commits": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/10832779?v=4"
},
{
"type": "User",
"login": "avivbd",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/20915857?v=4"
},
{
"type": "User",
"login": "FynnBe",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/15139589?v=4"
},
{
"type": "User",
"login": "hugokallander",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/63727864?v=4"
},
{
"type": "User",
"login": "kmdouglass",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/3697676?v=4"
}
],
"contributors_sampled": 12,
"top_contributor_share": 0.957
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"draft-release.yml",
"labeler.yml",
"publish-container.yml",
"publish.yml",
"release.yml",
"test-helm-chart.yml",
"test.yml"
],
"has_docs_dir": true,
"linter_configs": [
"tox.ini"
],
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": true
},
"security_signals": {
"lockfiles": [],
"scorecard": null,
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": true
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-31T02:25:42Z",
"oldest_open_prs": [
{
"number": 994,
"created_at": "2026-06-26T10:22:18Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 995,
"created_at": "2026-06-26T10:22:21Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 996,
"created_at": "2026-06-26T10:22:25Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 997,
"created_at": "2026-06-26T10:22:28Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 998,
"created_at": "2026-06-26T10:22:30Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 999,
"created_at": "2026-06-26T10:22:33Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1000,
"created_at": "2026-06-26T10:22:36Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1001,
"created_at": "2026-06-26T10:22:40Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1002,
"created_at": "2026-06-26T10:22:43Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1003,
"created_at": "2026-06-26T10:22:46Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1004,
"created_at": "2026-06-29T10:22:34Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1005,
"created_at": "2026-06-29T10:22:37Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1006,
"created_at": "2026-06-29T10:22:41Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1007,
"created_at": "2026-06-29T10:22:48Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1008,
"created_at": "2026-06-29T10:22:53Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1009,
"created_at": "2026-06-29T10:22:55Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1010,
"created_at": "2026-06-29T10:22:59Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1011,
"created_at": "2026-06-29T10:23:04Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1012,
"created_at": "2026-06-29T10:23:10Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 1013,
"created_at": "2026-06-29T10:23:13Z",
"last_comment_at": null,
"last_comment_author": null
}
],
"last_merged_pr_at": "2026-07-31T02:24:00Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/amun-ai/hypha",
"host": "github.com",
"name": "hypha",
"owner": "amun-ai"
},
"metrics": {
"overall": {
"key": "overall",
"band": "excellent",
"name": "Overall health",
"note": "The weighted overall 68 is calibrated to 80 on the published index scale (record calibration 2026-08-02).",
"notes": [
{
"code": "overall_calibration",
"params": {
"raw": 68,
"calibrated": 80,
"calibration": "2026-08-02"
}
}
],
"value": 80,
"inputs": {
"security": 46,
"vitality": 90,
"community": 45,
"governance": 62,
"calibration": "2026-08-02",
"engineering": 91,
"ai_readiness": 72,
"weighted_overall_raw": 68
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "excellent",
"name": "Vitality",
"value": 90,
"weight": 0.21,
"metrics": [
{
"key": "development_activity",
"band": "excellent",
"name": "Development activity",
"note": null,
"notes": [],
"value": 83,
"inputs": {
"commits_last_year": 284,
"human_commit_share": 1,
"days_since_last_push": 0,
"active_weeks_last_year": 30
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "30/52 weeks with commits",
"points": 20.8,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 30
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "284 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 284
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "OpenSSF Scorecard unavailable",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "exceptional",
"name": "Release discipline",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"releases_count": 100,
"latest_release_tag": "v0.21.127",
"releases_from_tags": false,
"days_since_latest_release": 0,
"mean_days_between_releases": 0.8
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "100 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 100
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~0.8 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 0.8
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "OpenSSF Scorecard unavailable",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "exceptional",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "maintained",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": null,
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": 4,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 4 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 4
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "weak",
"name": "Community & Adoption",
"value": 45,
"weight": 0.17,
"metrics": [
{
"key": "popularity",
"band": "at_risk",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 31,
"inputs": {
"forks": 14,
"stars": 24,
"watchers": 2,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "24 stars",
"points": 22.1,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 24
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "14 forks",
"points": 9.3,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 14
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "2 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 2
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"has_readme": true,
"has_license": true,
"readme_badges": null,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": false,
"readme_badge_services": [],
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (MIT)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "MIT"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
},
{
"key": "ecosystem_adoption",
"band": "moderate",
"name": "Ecosystem adoption (downloads)",
"note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"registry_dependents"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 62,
"inputs": {
"packages": [
"hypha"
],
"dependents": null,
"ecosystems": "pypi",
"total_downloads": null,
"monthly_downloads": 5442
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "5,442 downloads/month across pypi",
"points": 49.8,
"status": "partial",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 5442,
"ecosystems": "pypi"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "not reported by this ecosystem",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_reported_by_this_ecosystem",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 62,
"weight": 0.23,
"metrics": [
{
"key": "maintainer_resilience",
"band": "at_risk",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 26,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 12,
"top_contributor_share": 0.957
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 96% of commits",
"points": 1,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 96
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "12 contributors",
"points": 13.5,
"status": "met",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 12
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "OpenSSF Scorecard unavailable",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "excellent",
"name": "Issue & PR responsiveness",
"note": "Excluded from scoring (no data or not applicable): Newcomer PR acceptance. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"newcomer_pr_acceptance"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 85,
"inputs": {
"merged_prs": 637,
"open_issues": 0,
"closed_issues": 30,
"prs_merged_7d": null,
"prs_decided_7d": null,
"prs_merged_30d": null,
"prs_decided_30d": null,
"issue_closed_ratio": 1,
"closed_unmerged_prs": 351,
"first_time_authors_30d": null,
"first_time_prs_merged_30d": null,
"first_time_prs_decided_30d": null
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "100% of issues closed",
"points": 42,
"status": "met",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 100
}
}
],
"max_points": 42
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "637/988 decided PRs merged",
"points": 19.3,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 637,
"decided": 988
}
}
],
"max_points": 30
},
{
"key": "newcomer_pr_acceptance",
"name": "Newcomer PR acceptance",
"detail": "no first-time contributor's PR decided in 30d",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_newcomer_prs",
"params": {
"days": 30
}
}
],
"max_points": 13
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "OpenSSF Scorecard unavailable",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 53,
"inputs": {
"followers": 4,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "amun-ai",
"public_repos": 8,
"account_age_days": 2047
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "organization-owned",
"points": 30,
"status": "met",
"details": [
{
"code": "owner_organization",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "4 followers of amun-ai",
"points": 5,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 4,
"login": "amun-ai"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "8 public repos, account ~5 yr old",
"points": 18.2,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 8
}
},
{
"code": "account_age_years",
"params": {
"years": 5
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "exceptional",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"hypha"
],
"ecosystems": "pypi",
"any_deprecated": false,
"min_days_since_publish": 0
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on pypi",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "pypi"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 0 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 0
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "401 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 401
}
}
],
"max_points": 20
},
{
"key": "not_deprecated",
"name": "Not deprecated",
"detail": "active, not deprecated or yanked",
"points": 20,
"status": "met",
"details": [
{
"code": "package_not_deprecated",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "excellent",
"name": "Engineering Quality",
"value": 91,
"weight": 0.19,
"metrics": [
{
"key": "engineering_practices",
"band": "excellent",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 92,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": true
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "7 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 7
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": "tox.ini",
"points": 16,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "tox.ini"
}
}
],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 9.6,
"status": "met",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "OpenSSF Scorecard unavailable",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "excellent",
"name": "Documentation",
"note": null,
"notes": [],
"value": 90,
"inputs": {
"topics": [],
"has_wiki": true,
"homepage": "https://docs.amun.ai",
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": "https://docs.amun.ai",
"points": 15,
"status": "met",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "weak",
"name": "Security",
"value": 46,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): Dependency lockfiles. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"dependency_lockfiles"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 33,
"inputs": {
"source": "file_signals",
"lockfiles": [],
"manifests": [
"requirements.txt",
"requirements_dev.txt",
"requirements_lint.txt",
"requirements_pypi.txt",
"requirements_test.txt",
"setup.cfg",
"setup.py"
],
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": true
},
"components": [
{
"key": "security_policy_security_md",
"name": "Security policy (SECURITY.md)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 30
},
{
"key": "dependabot_config",
"name": "Dependabot config",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "dependency_lockfiles",
"name": "Dependency lockfiles",
"detail": "published library — lockfiles are an application concern, not expected",
"points": 0,
"status": "excluded",
"details": [
{
"code": "lockfiles_not_expected",
"params": {}
}
],
"max_points": 25
},
{
"key": "codeql_workflow",
"name": "CodeQL workflow",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
}
]
},
{
"key": "dependency_advisories",
"band": "exceptional",
"name": "Dependency advisories",
"note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories, No advisories left outstanding. Remaining weights renormalized. Matched 63 resolved dependencies against OSV; 54 could not be assessed (no resolved version, an unsupported ecosystem, or beyond the reported package list). This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"indirect_dependencies_free_of_known_advisories",
"no_advisories_left_outstanding"
]
}
},
{
"code": "weights_renormalized",
"params": {}
},
{
"code": "advisories_scope_repository",
"params": {
"assessed": 63
}
},
{
"code": "advisories_unassessed",
"params": {
"count": 54
}
},
{
"code": "advisories_repo_graph_caveat",
"params": {}
},
{
"code": "advisories_reachability",
"params": {}
}
],
"value": 100,
"inputs": {
"source": "osv",
"advisories": 39,
"affected_packages": 10,
"assessed_packages": 63,
"unassessed_packages": 54,
"affected_by_severity": "critical 2, high 6, moderate 2",
"direct_affected_packages": 0
},
"components": [
{
"key": "direct_dependencies_free_of_known_advisories",
"name": "Direct dependencies free of known advisories",
"detail": "no direct dependency carries a known advisory",
"points": 35,
"status": "met",
"details": [
{
"code": "no_direct_advisories",
"params": {}
}
],
"max_points": 35
},
{
"key": "indirect_dependencies_free_of_known_advisories",
"name": "Indirect dependencies free of known advisories",
"detail": "transitive set not separable from development and test dependencies in this scope",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_scope_not_separable",
"params": {}
}
],
"max_points": 25
},
{
"key": "no_advisories_left_outstanding",
"name": "No advisories left outstanding",
"detail": "no advisory carries a publication date",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_no_publication_date",
"params": {}
}
],
"max_points": 40
}
]
},
{
"key": "malicious_dependencies",
"band": "exceptional",
"name": "Malicious dependencies",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"source": "osv",
"meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
"packages": [],
"red_flag": false,
"assessed_packages": 63,
"malicious_packages": 0,
"direct_malicious_packages": 0,
"withdrawn_malicious_packages": 0,
"installable_malicious_packages": 0
},
"components": [
{
"key": "no_dependency_reported_as_a_malicious_package",
"name": "No dependency reported as a malicious package",
"detail": "no dependency is reported as a malicious package",
"points": 100,
"status": "met",
"details": [
{
"code": "no_malicious_dependencies",
"params": {}
}
],
"max_points": 100
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "exceptional",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"commit_weight_rule": {
"min_commits": 50,
"min_commit_share": 0.1
},
"review_only_matches": 0,
"below_threshold_exposures": [],
"assessed_self_published_locations": 14
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "good",
"name": "AI Readiness",
"value": 72,
"weight": 0.04,
"metrics": [
{
"key": "ai_agent_context",
"band": "exceptional",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"has_llms_txt": true,
"legible_history_share": 1,
"agent_instruction_files": [
"CLAUDE.md"
],
"agent_instruction_max_bytes": 55402
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "CLAUDE.md",
"points": 45,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "CLAUDE.md"
}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": "llms.txt present",
"points": 15,
"status": "met",
"details": [
{
"code": "llms_txt_present",
"params": {}
}
],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "100 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 100,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "moderate",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 64,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [],
"has_dockerfile": true,
"typed_language": false,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": true,
"typecheck_configs": [],
"agent_commit_share": 0.96,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": "tox.ini",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "tox.ini"
}
}
],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "Dockerfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Dockerfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "96 of the last 100 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 96,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "dependency automation configured, none observed in the sampled commits",
"points": 5,
"status": "partial",
"details": [
{
"code": "dependency_bot_config_only",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "OpenSSF Scorecard unavailable",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "weak",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 48,
"inputs": {
"primary_language": "Python",
"largest_source_bytes": 512705,
"source_files_sampled": 201,
"oversized_source_files": 25
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Python without a type-check config",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_typecheck_config_language",
"params": {
"language": "Python"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "25/201 source files over 60KB",
"points": 48.2,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 201,
"oversized": 25
}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "moderate",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 60,
"inputs": {
"example_dirs": [
"notebooks"
],
"has_mcp_signal": true,
"api_schema_files": []
},
"components": [
{
"key": "api_schema_openapi_graphql_proto",
"name": "API schema (OpenAPI/GraphQL/proto)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 40
},
{
"key": "mcp_server",
"name": "MCP server",
"detail": null,
"points": 20,
"status": "met",
"details": [],
"max_points": 20
},
{
"key": "runnable_examples",
"name": "Runnable examples",
"detail": "notebooks",
"points": 40,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "notebooks"
}
}
],
"max_points": 40
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? Carries a deliberately small weight: agent tooling is a real maintenance signal, but its absence must never gate the top of the scale (calibration saturates at raw 91, so 100/100 remains reachable with AI Readiness at zero)."
}
],
"classification": {
"labels": [
"library"
],
"scores": {
"library": 6,
"framework": 2,
"mcp-server": 3
},
"primary": "library",
"evidence": [
{
"tier": "distribution",
"label": "library",
"source": "registry:pypi",
"weight": 6
},
{
"tier": "structure",
"label": "mcp-server",
"source": "mcp_signal",
"weight": 3
},
{
"tier": "description",
"label": "framework",
"source": "description:framework",
"weight": 2
}
],
"artifacts": [],
"confidence": "medium",
"host_extension": false,
"runs_as_process": false,
"consumed_by_code": true
},
"metrics_version": "2.3.2"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"deps.dev does not index pypi:hypha@0.21.127; advisories assessed against the repository dependency graph instead",
"OpenSSF Scorecard did not return a usable result (exit code -9); skipping Scorecard checks"
],
"report_type": "repository",
"generated_at": "2026-07-31T03:10:04.335070Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/a/amun-ai/hypha.svg",
"full_name": "amun-ai/hypha",
"license_state": "standard",
"license_spdx": "MIT"
}