Звіт у форматі JSON машиночитний
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 28769,
"has_wiki": true,
"homepage": null,
"languages": {
"Go": 2056534,
"HTML": 29605,
"Shell": 43048,
"Python": 40760,
"Makefile": 11798,
"Dockerfile": 5409,
"TypeScript": 4780,
"Go Template": 1482
},
"pushed_at": "2026-07-20T09:12:39Z",
"created_at": "2026-02-26T16:13:02Z",
"owner_type": "Organization",
"updated_at": "2026-07-20T09:11:40Z",
"description": "Enterprise-grade kubernetes native agent orchestrator",
"is_archived": false,
"is_disabled": false,
"license_spdx": null,
"default_branch": "main",
"license_spdx_raw": "NOASSERTION",
"primary_language": "Go",
"significant_languages": [
"Go"
]
},
"owner": {
"blog": "https://www.unitary.ai",
"name": "Unitary",
"type": "Organization",
"login": "unitaryai",
"company": null,
"location": null,
"followers": 21,
"avatar_url": "https://avatars.githubusercontent.com/u/73825999?v=4",
"created_at": "2020-11-02T10:26:38Z",
"is_verified": null,
"public_repos": 7,
"account_age_days": 2093
},
"license": {
"state": "custom",
"spdx_id": null,
"raw_spdx": "NOASSERTION",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "osmia-0.4.0",
"kind": "other",
"published_at": "2026-07-16T10:44:09Z"
},
{
"tag": "osmia-0.3.8",
"kind": "other",
"published_at": "2026-04-02T09:09:03Z"
},
{
"tag": "osmia-0.3.7",
"kind": "other",
"published_at": "2026-03-19T09:30:09Z"
},
{
"tag": "osmia-0.3.6",
"kind": "other",
"published_at": "2026-03-19T08:55:48Z"
},
{
"tag": "osmia-0.3.5",
"kind": "other",
"published_at": "2026-03-18T16:10:34Z"
},
{
"tag": "osmia-0.3.4",
"kind": "other",
"published_at": "2026-03-18T15:00:34Z"
},
{
"tag": "osmia-0.3.3",
"kind": "other",
"published_at": "2026-03-17T18:05:01Z"
},
{
"tag": "osmia-0.3.2",
"kind": "other",
"published_at": "2026-03-17T14:29:26Z"
},
{
"tag": "osmia-0.2.0",
"kind": "other",
"published_at": "2026-03-13T09:39:05Z"
},
{
"tag": "robodev-0.2.0",
"kind": "other",
"published_at": "2026-03-05T18:23:51Z"
},
{
"tag": "robodev-0.1.0",
"kind": "other",
"published_at": "2026-03-05T16:18:42Z"
}
],
"recent_commits": [
{
"oid": "66243d19c27d4d0751d0d4ce4018647f368e6b74",
"body": "…edentialHints (#65)",
"is_bot": false,
"headline": "refactor(controller): generalise engine auth merge via AuthFor and Cr…",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-20T09:10:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "45e1e6cc54a8c1ccd3d9210f31d54554f549765b",
"body": "Introduces a Translator interface in internal/agentstream that converts\none raw stdout line into zero or more stream events, so a future engine's\nnative output format (Codex JSONL) can be normalised into Osmia's NDJSON\nenvelopes without teaching the core package about engine-specific formats.\n\ninter\n[…]\never disagree.\n\nPassthrough-only: behaviour is byte-identical to before this change.\nNo Codex adapter is added yet (that follows in a later PR).\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(agentstream): add translator seam for engine stream formats (#64)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-17T13:18:53Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "050f098003533b4d7b5316d53df4e3254d393a64",
"body": "Adds internal/usecase (Definition/Gates/ResultHandler model, Registry)\nper docs/designs/use-case-abstraction.md, registers the ticketing and\nincident-triage Definitions at reconciler construction, and tags new\nTaskRuns with their use case at creation via newLaunchTaskRun.\n\nInert: nothing dispatches \n[…]\nfers the\nuse case for TaskRuns persisted before TaskRun.UseCase existed, from\nthe tr-incident- ID prefix; it is not consumed by dispatch either.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(controller): introduce use-case registry and TaskRun tagging (#63)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-17T12:40:20Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f2a86847543970cd0a1b1816b9091aee0848a18f",
"body": "ProcessTicket and ProcessIncidentEvent each ended with a near-identical\ntail: prepareSession, BuildExecutionSpec, JobBuilder.Build, the K8s Job\ncreate, transition to Running, taskRuns/engineChains bookkeeping, a\nre-save to the TaskRunStore, metrics, and the engineEmitsStream gate for\nthe stream read\n[…]\nuction and initial store save that both flows perform\nbefore their own gate/override logic runs.\n\nBehaviour-frozen: the incident-triage contract tests and the\nclaude-code golden tests pass unmodified.",
"is_bot": false,
"headline": "refactor(controller): extract shared task-launch pipeline (#62)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-17T11:47:54Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8c3d0acc3fe2e63dd851b662ad6a1aa3a7d9b072",
"body": "…nstead of engine name (#60)\n\nReplaces eight `engineName == \"claude-code\"` string comparisons that\ngated startStreamReader with a single Reconciler.engineEmitsStream\nhelper that type-asserts the resolved engine against the new\nengine.StreamEmitter capability interface (pkg/engine/capabilities.go).\nC\n[…]\nrom #54, stay\ngreen untouched.\n\nOther \"claude-code\" string comparisons (auth config merge, engine\nselector defaults, continuation config) are unrelated to stream\ngating and are left for follow-up PRs.",
"is_bot": false,
"headline": "refactor(engine): gate stream reading on a StreamEmitter capability i…",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-17T11:17:31Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "df48b3276e2835566c596592922697fa227aceeb",
"body": "Reads taskrun_store.backend at startup and constructs the matching\ntaskrun.TaskRunStore. The default (\"\" or \"memory\") leaves\ncontroller.WithTaskRunStore unset, so the reconciler still constructs its\nown taskrun.NewMemoryStore() exactly as before. \"sqlite\" opens\ntaskrun.NewSQLiteStore at taskrun_stor\n[…]\n absolute\npath when sqlite.path is set. Adds a commented Helm values example and a\ndocs section on durable TaskRun state, noting that startup recovery of\nin-flight TaskRuns is separate follow-up work.",
"is_bot": false,
"headline": "feat: wire taskrun_store config into controller startup (#61)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-17T11:00:18Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "36a12c77abb126af96f84525f56154790c11d3af",
"body": "…outcome (#57)",
"is_bot": false,
"headline": "docs: add ADR 0002, Managed Agents self-hosted sandbox interop spike …",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-17T09:45:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a2f5a696f0fc5ca14011a54bc0bc362e978e9c2a",
"body": "* feat(taskrun): add SQLite TaskRunStore backend and ADR 0001\n\nAdds a SQLiteStore implementing the existing TaskRunStore interface,\nfollowing the same modernc.org/sqlite pattern already used by\ninternal/memory, internal/routing, internal/estimator, and\ninternal/watchdog. Nothing constructs this stor\n[…]\nion before\njson.Unmarshal.\n\nAddresses PR #56 review comments from CodeRabbit.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(taskrun): add SQLite TaskRunStore backend and ADR 0001 (#56)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-17T09:32:22Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f1e6c93c1c62f387464aa6ba7c22dee320d043c0",
"body": "* test: backfill unit coverage for metrics and reviewpoller packages\n\nBoth packages had zero test files despite containing core controller\nlogic (Prometheus metric registration and the PR review comment\npoller/classifier). This adds white-box unit tests to close that gap\nwithout any production code \n[…]\no means\nclient_model no longer needs to be a direct dependency (go mod tidy).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "test: backfill unit coverage for metrics and reviewpoller packages (#53)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-17T09:18:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "cf82f44ff7ae60ed5683626a286b13977e874781",
"body": "Adds the design document that roadmap item 24 (Non-Standard Task Types)\nrequires before implementation: a Definition/Gates/ResultHandler model for\ngeneralising ProcessTicket and ProcessIncidentEvent behind a shared\ndispatch pipeline, an execution-mode taxonomy, a result-handler taxonomy\nthat also fi\n[…]\nlayers are\nhard controls today versus aspirational.\n\nNo code changes. Links the doc from the roadmap and mkdocs nav, and adds\na CHANGELOG entry.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add design doc for use-case abstraction and shadow mode (#52)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-17T07:28:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ab20636eea287dfba9e43206fd6f1d6f4825168c",
"body": "Several docs and comments claimed multi-tenancy, guardrails.md injection,\nand leader election were more complete than the actual implementation.\nThis adds roadmap links to existing \"on the roadmap\" mentions, an honest\nclause on the leases RBAC grant, an Experimental annotation on\nTenancyConfig, and redirects three dangling oss-prd.md references (removed\nin 259c4a8, before public launch) to oss-plan.md.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: align feature claims with implementation status (#51)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-16T18:33:50Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a2cf22bcb25404af689e8156cfbcdbef2c62a27b",
"body": "…g the repo-url gate (#59)\n\nProcessTicket now hard-gates on a resolvable repository URL (either\nticket.RepoURL or one extractable from the description) before\nprocessing a ticket, falling back to async Slack polling and then\nMarkFailed if neither is available. Nine integration tests built\ntickets be\n[…]\nler, fail a\nTaskRun directly from NeedsHuman), so asserting it as invalid was\nstale. Removed that case from the test's invalid-transition table.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(tests): populate repository URLs in integration fixtures predatin…",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-16T18:28:15Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "310785989f3e15b0150538456dc41f490d8784f0",
"body": "…d engine contracts (#58)\n\nThree tests in tests/integration were asserting stale expectations that\npredated deliberate production changes:\n\n- TestJobBuilderSecurityHardening expected RunAsUser 1000; production\n moved to 10000 (commit 8328473) and later paired it with fsGroup 10000\n (commit 22e5d70\n[…]\nuine compile break (NewServer's error return) that\notherwise prevents the whole tests/integration package from building\nunder -tags=integration.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(tests): align integration expectations with current jobbuilder an…",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-16T17:23:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0253465d243af70dea279b7bac77f12f74ab2fd8",
"body": "internal/webhook.NewServer started returning (*Server, error) in ce3b84c\n(Svix-style signature verification) so that malformed per-source secrets\nfail fast, but tests/integration/webhook_reconciler_test.go was never\nupdated and still did a single-value assignment. This broke compilation\nof the whole tests/integration package under the integration build tag.\n\nCapture and assert the error with require.NoError, matching the\nproduction call site in cmd/osmia/main.go.",
"is_bot": false,
"headline": "fix(tests): repair webhook reconciler integration test compilation (#55)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-16T17:15:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4c95376143e524bffda38e6a40e2142908f778ee",
"body": "…ments (#54)\n\nAdds unit and integration tests that pin the externally observable\nbehaviour of the incident.io webhook flow (ProcessIncidentEvent) ahead of\nthe planned use-case abstraction refactor, so an internal FirstResponder\ndeployment does not break silently. No production code is changed.\n\nCove\n[…]\nthe real claude-code engine and jobbuilder. Also\nadds a best-effort, non-CI local smoke test for setup-claude.sh's\nincident.io MCP registration.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "test: pin the incident-triage contract relied on by downstream deploy…",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-16T17:14:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "55158e89f056da41ea2df90e4fd274251e3de47b",
"body": "Stamps the incident-triage (FirstResponder) work shipped since v0.3.8:\nper-flow incident.io MCP credentials, richer incident context surfaced\nto the triage agent, quieter in-place Slack notifications, and the\nskill-layout discovery fix. Cutting this release gives downstream\ndeployments a stable chart to pin ahead of the upcoming refactor work.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: release v0.4.0",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-07-16T10:41:37Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "c7ca10d8abe64f9a565f8111ccd50020cc226971",
"body": "…e (#50)\n\nAdd a per-flow `incident_triage.incident_io_api_key_secret` config field\nthat mounts `INCIDENT_IO_API_KEY` onto incident-triage agent Jobs via\nSecretKeyRef. When the env var is present at job startup, setup-claude.sh\nregisters the incident.io remote MCP server (mcp.incident.io/mcp, HTTP\ntr\n[…]\n which has known bugs for\nHTTP MCP headers (anthropics/claude-code#51581, #6204).\n\nMirrors the per-flow config precedent from #46.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(controller): wire incident.io MCP credentials for incident triag…",
"author_name": "Sarah Jane Newnham",
"author_login": "sarahjanenewnham",
"committed_at": "2026-05-18T10:40:53Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7f8f7196e375dc355c119579b95505e95f835eca",
"body": "… (#49)\n\nProcessIncidentEvent was building the agent's engine.Task from only\nthree of the parsed IncidentV2 fields: name, summary, permalink. The\nclassifier then had to infer everything else — status, mode, the\noriginating alert — from the summary text, and operators on the\nreceiving side couldn't r\n[…]\non block,\nand explicitly noting which fields are intentionally not surfaced\nand why. CHANGELOG entry under [Unreleased] > Changed.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(controller): surface more incident.io fields to the triage agent…",
"author_name": "Sarah Jane Newnham",
"author_login": "sarahjanenewnham",
"committed_at": "2026-05-15T13:04:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "6b9d175d0e721d07df90c4ee507cfb6d55b1dc9d",
"body": "…iscovery (#48)\n\nPR #47 fixed the location of inline and path-based skills written by\nsetup-claude.sh to live under ${HOME}/.claude/skills/ unconditionally.\nThat matched Claude Code's HOME-relative discovery, but the file\nlayout was still wrong: the script wrote a flat\n${HOME}/.claude/skills/<name>.\n[…]\nom/docs/en/skills.md — documented layout\n- anthropics/claude-code#22902 — open feature request for relocating\n skills via env var\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(engine): write skills as <name>/SKILL.md to match Claude Code's d…",
"author_name": "Sarah Jane Newnham",
"author_login": "sarahjanenewnham",
"committed_at": "2026-05-15T12:57:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "64735466e3781678f56f3c1d3ed76a652c8e67e4",
"body": "… CLAUDE_CONFIG_DIR (#47)\n\nsetup-claude.sh writes per-pod settings.json, MCP config, custom\nskills, and sub-agents into either ${CLAUDE_CONFIG_DIR}/ (when set\nfor session persistence) or ${HOME}/.claude/ (when not). Claude Code\nrespects CLAUDE_CONFIG_DIR for the first two, but its slash-command\nskil\n[…]\nig (inline or ConfigMap-backed) rather than editing\nthe file inside the running pod, so this is closer to the documented\ncontract.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(engine): write skills/sub-agents to ${HOME}/.claude regardless of…",
"author_name": "Sarah Jane Newnham",
"author_login": "sarahjanenewnham",
"committed_at": "2026-05-14T11:19:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b741e67d6c8f40c1fd234f4f71b7aeac5974e0e9",
"body": "* feat(controller): add Slack channel/token overrides for incident triage\n\nProcessIncidentEvent spawns agent Jobs that inherit SLACK_CHANNEL_ID\nand SLACK_BOT_TOKEN from the first configured channel under\nconfig.notifications.channels — the same default that applies to\nticketing runs. There is no way\n[…]\nhannel deployments keep working\nwithout changes).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(controller): add per-flow Slack config for incident triage (#46)",
"author_name": "Sarah Jane Newnham",
"author_login": "sarahjanenewnham",
"committed_at": "2026-05-13T13:43:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2424fab5f31ab302ebff1e9d1d653455adc999c2",
"body": "…(#45)\n\n* feat(controller): restore incident.io dispatch path (Step 1b)\n\nPR #44 (Step 1a) shipped the receiver side of the incident.io webhook\nflow — endpoint, signature verification, parsing, server wiring,\nconfig schema, controller adapter — but deliberately omitted the\ndispatch body of Reconciler\n[…]\n\nidempotent re-apply form for subsequent updates.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(controller): dispatch agent runs for incident.io webhook events …",
"author_name": "Sarah Jane Newnham",
"author_login": "sarahjanenewnham",
"committed_at": "2026-05-12T10:57:44Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ef23a0d55814ea19259832fcf64b54e9b94621b8",
"body": "…path (#44)\n\n* feat(webhook): add IncidentEvent types and incident_triage config\n\nIntroduces typed incident.io webhook event model\n(internal/webhook/incident.go) with ParseIncidentEvent for the\nevent-namespaced wrapper key shape, an IncidentHandler interface, and\nconfiguration blocks (webhook.incide\n[…]\nency with the other code blocks in the same file.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(webhook): add incident.io webhook flow with parallel reconciler …",
"author_name": "Sarah Jane Newnham",
"author_login": "sarahjanenewnham",
"committed_at": "2026-05-08T14:01:36Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8704d1b32b2119c53b8ab0c564ecb263593ee7bd",
"body": "…or (#43)\n\n* feat(config): expand env var references in config + chart env wiring\n\nThe controller's config loader had no way to receive secret values from\nKubernetes Secrets — the values.yaml in the helm chart is rendered into\na ConfigMap as plain YAML, so any field placed under `config:` ends up\nin\n[…]\nching the webhook layer. Add `svix` to the accepted\nauth_mode set and update the surrounding error messages to list it.\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(config): expand env var references + accept svix in YAML validat…",
"author_name": "Sarah Jane Newnham",
"author_login": "sarahjanenewnham",
"committed_at": "2026-05-05T14:27:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c90aa849ae6349e2a15706b6de96587d639ee5dd",
"body": "The controller parsed `webhook.generic` from osmia-config.yaml into a\nGenericWebhookConfig struct, but main.go never read that field — so any\ngeneric-webhook configuration in YAML was silently ignored at startup.\nOnly the GitHub/GitLab/Slack/Shortcut sources had `whOpts` wiring; the\ngeneric source d\n[…]\neady exist in the runtime can now actually be configured from\nYAML.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\nCo-authored-by: Nicolas Fournier <nicolas.fournier3@gmail.com>",
"is_bot": false,
"headline": "fix(webhook): wire generic webhook config from YAML to runtime (#41)",
"author_name": "Sarah Jane Newnham",
"author_login": "sarahjanenewnham",
"committed_at": "2026-05-05T07:49:18Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ce3b84ce08bd9b46171f3ba13f695ebe677a9834",
"body": "Many SaaS providers (incident.io, Stripe, OpenAI, Linear, etc.) build\ntheir outbound webhooks on Svix or its conventions. The signature covers\n${id}.${timestamp}.${body} rather than just the body, the secret is\nwhsec_-prefixed and base64-encoded, and headers carry id/timestamp\nauxiliaries — all inco\n[…]\nse webhook-* header prefixes,\nconstant-time signature comparison, multi-signature key rotation, and\nthe five-minute replay window.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(webhook): add Svix-style signature verification (#39)",
"author_name": "Sarah Jane Newnham",
"author_login": "sarahjanenewnham",
"committed_at": "2026-05-04T13:25:57Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f397c04185f1faf30b4a3cbbaad89ab9d0eec95a",
"body": "The generic webhook handler resolves dot-notation paths into the JSON\npayload, but had no way to address keys that themselves contain dots.\nAdd backslash-escape support so sources like incident.io (whose webhook\npayloads use the event type as a wrapper key, e.g.\n\"public_alert.alert_created_v1\") can \n[…]\nessed via field_map:\n\n field_map:\n public_alert\\.alert_created_v1.id: id\n\nA literal backslash in a segment is written as `\\\\`.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(webhook): support escaped dots in generic field_map paths (#38)",
"author_name": "Sarah Jane Newnham",
"author_login": "sarahjanenewnham",
"committed_at": "2026-05-04T11:12:02Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4600a754660df9497c8d4f34583a3bf65a9930ab",
"body": "* fix: reply to correct thread for DiffNote review comments\n\nReplyToComment was fetching /notes (page 1 only) to look up the\ndiscussion ID for a comment, but DiffNotes (inline code review\ncomments) often weren't on page 1. This caused the function to fall\nback to posting a standalone note instead of\n[…]\nmatches when the controller zipped the two lists.\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: reply to correct thread for DiffNote review comments (#36)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-09T10:53:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "be64b2f048a908077906ee9417401e6237262bcb",
"body": "* feat: configurable teammate model for agent teams\n\nAgent team teammates default to Haiku. New teammate_model config field\nsets CLAUDE_CODE_SUBAGENT_MODEL env var in agent pods, overriding the\ndefault. Set to e.g. \"claude-sonnet-4-6\" for more capable teammates.\n\nCo-Authored-By: Claude Opus 4.6 (1M \n[…]\ned teammate_model to catch whitespace-only values\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": "feat: configurable teammate model for agent teams (#35)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-09T10:18:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "04a528b11eb225734184ff3c44bcfb56ea7bddef",
"body": "* feat: smart secret key resolution with well-known defaults\n\nBackends now try well-known key names (e.g. SHORTCUT_API_TOKEN,\nGITLAB_TOKEN, SLACK_BOT_TOKEN) before falling back to the generic\n\"token\" key. A single shared secret with descriptive keys works out\nof the box — no need for separate per-se\n[…]\n\ncancellation and timeouts on all I/O operations.\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: smart key resolution for Slack SecretKeyRef in agent pods (#34)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-08T18:25:35Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "75a41ed57b14d3ada486833dc39c0768e84cc335",
"body": "* feat: smart secret key resolution with well-known defaults\n\nBackends now try well-known key names (e.g. SHORTCUT_API_TOKEN,\nGITLAB_TOKEN, SLACK_BOT_TOKEN) before falling back to the generic\n\"token\" key. A single shared secret with descriptive keys works out\nof the box — no need for separate per-se\n[…]\nconfig field to AuthConfig for explicit override.\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": "feat: smart key resolution for SecretKeyRef (engine + SCM pod env) (#33)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-08T15:11:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4fce36aee139006593ca476cb15a2020ec1b715e",
"body": "Backends now try well-known key names (e.g. SHORTCUT_API_TOKEN,\nGITLAB_TOKEN, SLACK_BOT_TOKEN) before falling back to the generic\n\"token\" key. A single shared secret with descriptive keys works out\nof the box — no need for separate per-service secrets or explicit\ntoken_key configuration.\n\nResolution order:\n1. Explicit token_key from config (if set)\n2. Well-known keys for the specific backend\n3. Generic \"token\" fallback\n\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: smart secret key resolution with well-known defaults (#32)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-08T14:04:22Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "43efb7cf589b432277d61d33e0b0188ababcb431",
"body": "…on (#31)\n\n* fix: re-enable reply_broadcast on completion notifications\n\nThe completion reply in the thread should broadcast to the channel so\nthe summary, MR link, and cost are visible without opening the thread.\nThe original message is still updated in-place with the final status.\n\nCo-Authored-By:\n[…]\noise. Completion details stay in the thread only.\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: disable reply_broadcast and move status updates after job creati…",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-07T16:21:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "dd8df1ba84cd84889f563d7223047c3177c24ea5",
"body": "* feat: quiet Slack notifications with in-place message updates\n\nRedesign notifications to reduce channel noise:\n\n1. The original \"started working on\" message is updated in-place on\n state changes (retrying, switching engine, completed, failed) via\n Slack's chat.update API. No new messages in th\n[…]\nt external plugins declaring interface_version=3.\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": "feat: quiet Slack notifications with in-place message updates (#30)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-07T13:15:18Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "df4bcc3b49299abee16ceec37545dfe023bef03b",
"body": "* feat: configurable branch prefix for Shortcut VCS integration\n\nBranch names were hardcoded as osmia/<ticketID> which doesn't trigger\nShortcut's VCS integration (requires sc-<storyID> in the branch name).\n\nNew scm.branch_prefix config field (default \"osmia/\") is prepended to\nthe ticket ID for branc\n[…]\ny to avoid producing a bare prefix as the branch.\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": "feat: configurable branch prefix for Shortcut VCS integration (#29)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-07T12:13:39Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "259563cdb59254a00699c79dbe706dab5d5e0d8b",
"body": "* fix: add GitLab group bot pattern to built-in defaults\n\nGitLab group access tokens use usernames like\ngroup_123456_bot_abcdef... which don't match the built-in botUsernames\nlist. Users had to manually configure ignore_summary_authors to catch\nthem. Now the ^group_\\d+_bot_[0-9a-f]+$ pattern is comp\n[…]\nin username\nwas missing from the test's bot list.\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: add GitLab group bot pattern to built-in defaults (#28)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-03T18:50:36Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c8ff75cf649879fb63c3c34733a9211e382a0e72",
"body": "* feat: settling period and comment batching for review follow-ups\n\nTwo changes to reduce unnecessary follow-up jobs:\n\n1. Settling period: new settling_minutes config delays polling a PR after\n registration, giving review bots (e.g. CodeRabbit, which takes 8-10\n minutes) time to finish posting a\n[…]\nng, bot summary filtering, and all config fields.\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": "feat: settling period and comment batching for review follow-ups (#27)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-03T12:20:46Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8c00f67a07446b633bebf3863301f56a8d643635",
"body": "…es (#26)\n\n* fix: review follow-ups push to original MR instead of creating new ones\n\nReview follow-up tasks from the poller were creating new MRs because\nthey used a synthetic ticket ID (e.g. 28675-review-...) which produced\na different branch name. The follow-up now inherits the original\nticket's \n[…]\ntURL before\n assigning to PriorMergeRequestURL.\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: review follow-ups push to original MR instead of creating new on…",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-03T12:12:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "254f1b9de3b1026fa98b23ff9f695a2845b8ea24",
"body": "* fix: review poller ignores bot summary comments but acts on inline review\n\nThe classifier now only ignores bot comments that lack a file position\n(summaries, coverage reports, initial review messages). Inline diff\ncomments from bots like CodeRabbit are still evaluated as actionable\nreview feedback\n[…]\ngo is pre-existing and\nout of scope for this PR.)\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: review poller ignores bot summaries but acts on inline review (#25)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-03T11:14:57Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "aedaced8ae527ca0cc09e90810c592d2ab6e1a09",
"body": "* fix: prevent duplicate MRs on retry and continuation jobs\n\nWhen a diagnosis retry, engine fallback, or continuation job runs after\na prior attempt already opened an MR, the agent was unconditionally told\nto create a new MR — resulting in 3-4 duplicate MRs per ticket.\n\nNow the controller passes Pri\n[…]\nor placeholder value cannot suppress MR creation.\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: prevent duplicate MRs on retry and continuation jobs (#24)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-03T11:01:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f04966fee4ac736104ffb62ca4629817d4fd4177",
"body": "* feat: include ticket references in agent-raised merge requests\n\nThe agent prompt now instructs the agent to:\n- End the MR title with the ticket ID, e.g. `[sc-28671]`\n- Include a References line in the MR description linking to the ticket\n\nAdded TicketURL field to engine.Task and wired ticket.Exter\n[…]\nnnot break\n the quoted --description parameter.\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": "feat: include ticket references in agent-raised merge requests (#23)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-03T10:48:27Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8a1879bc5b65b897fe58e08d968c4bd2c1ad936c",
"body": "* fix: detect HTML responses in GitLab/GitHub SCM backends\n\nWhen a token lacks access to a resource, the API may redirect to a\nsign-in page that returns 200 OK with HTML. The doGet helper now checks\nthe Content-Type header and rejects non-JSON responses with a clear\ndiagnostic message instead of fai\n[…]\nnd, returning HTML sign-in pages instead of JSON.\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: detect HTML responses in GitLab/GitHub SCM backends (#22)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-03T09:37:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "35882c2bf5a2caf253e02cdb53a56d18e91074e5",
"body": "checkRunningJobs was deferred after the concurrent-limit early return,\nso when activeCount >= maxConcurrent the function returned before the\ndefer was registered. Completed K8s jobs were never reaped, the active\ncount never decreased, and the controller permanently stalled.\n\nMove the defer to the top of reconcileOnce so job reaping always runs.\n\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: reap completed jobs even when at concurrent limit (#21)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-03T09:10:52Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "fc4ab7c412699951bd7ce9fc4548ae8268e7758e",
"body": "GitHub Pages URLs are case-sensitive. The repo is lowercase osmia but\nall doc links used /Osmia/ which 404s.\n\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: fix GitHub Pages URL casing — /Osmia/ → /osmia/ (#20)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-02T12:37:19Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a062bb04431b95b91a599bfcdf4ed0c252732542",
"body": "…ies (#19)\n\n* fix: require bot @-mention in repo URL Slack replies\n\nThe repo URL poller was accepting any non-bot message containing a URL,\npicking up unrelated chatter in the thread. Now resolves the bot user ID\nvia auth.test at startup and requires <@BOT_USER_ID> in the reply — same\npattern as the\n[…]\nfix: add context with timeout to resolveBotUserID\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: parse structured_output and require bot mention in repo URL repl…",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-02T11:27:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3b44dd532c2d587168a1ed4b592240e2775b6d3c",
"body": "* feat: resolve missing repo URL from ticket description or Slack\n\nWhen a ticket has no RepoURL (e.g. Shortcut story with no external link),\nthe controller now:\n\n1. Extracts a GitHub/GitLab URL from the ticket description\n2. Falls back to asking on Slack (posts a question, polls thread for reply)\n3.\n[…]\nto\n ensure the question lands in the task thread\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": "feat: resolve missing repo URL from ticket description or Slack (#18)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-02T10:35:50Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "29aa69d2505b0d82f9335107b5d4cf82b1c08c23",
"body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: release v0.3.8",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-02T09:06:09Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "418cb12092e7356c90e78bd86934f6aca1c55048",
"body": "* fix: require bot @-mention in Slack thread replies before responding\n\nThe Slack MCP server was treating any non-bot message in a thread as a\nresponse directed at the agent, even when the message did not mention\nthe bot. This caused the agent to react to unrelated chatter.\n\nResolve the bot's own Sl\n[…]\ner\n- Update CHANGELOG entry to document the fallback behaviour when\n auth.test fails\n- Add test for network error path\n\n---------\n\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: require bot @-mention in Slack thread replies (#16)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-02T08:24:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a23e38b1db7a041cd5b4b6c425fe94adccd85877",
"body": "…t schema (#15)\n\nAgents were completing tasks (writing code, PRDs, tests) without opening\nmerge requests. Two root causes:\n\n1. The prompt presented MR creation as an ordinary numbered step that\n agents could skip — especially for non-code output like documentation\n or plans. Add a bold IMPORTANT\n[…]\nRL or register it with\n the review poller. Default to the built-in schema when none is\n configured.\n\nCloses sc-25531, sc-25533\n\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: enforce mandatory MR/PR creation and default to structured resul…",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-02T07:41:51Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "27a333282dcd509ec5ed7b78bf2394662fae17a9",
"body": "* docs: add AWS/EKS deployment examples and update Karpenter nodepool\n\nAdd examples/aws/ directory with EKS-specific Helm values overlay,\nExternalSecret manifests for ESO users, IRSA setup script, and README.\nThese support the community.aws blog article and give EKS users a\nconcrete starting point f\n[…]\ntore.\nAdd a note with instructions and a link to the ESO AWS auth docs.\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": "docs: add AWS/EKS deployment examples (#14)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-04-02T07:08:18Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c5372166a466e905dce816d5e424f16cd3456f16",
"body": "- Bump notifications.Channel interface to version 2:\n NotifyStart now returns (string, error) where the string is\n a thread reference (Slack message ts); Notify and NotifyComplete\n accept an optional threadRef parameter.\n\n- Slack backend posts NotifyStart as a top-level message and captures\n its\n[…]\nsent.\n\n- Telegram and Discord backends return an empty thread reference and\n silently ignore the threadRef parameter; no behavioural change.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: thread all Slack messages under initial task notification",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-19T12:12:49Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "296429b4b344993c1a2d67f012c471fcf0c51fd8",
"body": "The prompt told the agent to push a branch and write result.json with\nbranch_name, but never instructed it to create a merge request. The\ncontroller's review poller registration (controller.go:1009) was always\ndesigned to consume result.MergeRequestURL — the field was simply never\npopulated because \n[…]\non)\n- Add merge_request_url to the result.json format in both paths\n- Revert controller CreatePullRequest call added in previous commit\n\nglab and gh are both installed in the engine-claude-code image.",
"is_bot": false,
"headline": "fix: instruct agent to open MR and include URL in result.json",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-19T11:15:47Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "87224275b91dab6305c54e1f9063d7c95e21d738",
"body": "The controller success path never called CreatePullRequest. It only\nregistered an MR URL with the review poller if one was already present\nin the agent result — but agents push a branch and write result.json\nwith branch_name, they do not open MRs themselves.\n\nFix: after reading the agent result, if \n[…]\nll CreatePullRequest using\nthe ticket title and agent summary. Store the returned URL in\nresult.MergeRequestURL before MarkComplete and the review poller\nregistration, so both receive the correct URL.",
"is_bot": false,
"headline": "fix: open merge request after successful agent run",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-19T11:12:48Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "22e5d707f4f3cd6e62447ab08b5425366d15f0cb",
"body": "Agent containers run as UID 10000 (non-root). Without fsGroup, freshly\nformatted EBS volumes (and their subPath subdirs) are owned by root:root\nand the container cannot write to them. This caused setup-claude.sh to\nfail immediately with:\n\n cp: cannot create regular file '/session/settings.json': Permission denied\n\nFix: add PodSecurityContext.FSGroup = 10000 to the job builder so\nKubernetes chowns mounted volumes to be group-writable on pod start.\n\nCovered by TestBuild_PodSecurityContextFSGroup.",
"is_bot": false,
"headline": "fix: set fsGroup on pod security context so PVC volumes are writable",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-19T11:04:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ba36423364581cec2f6dc883b9108ae9d0de4193",
"body": "When the per-TaskRun session store mounts the same PVC at two paths\n(claude session dir + persisted workspace), buildVolumes was emitting\ntwo separate K8s Volume specs referencing the same PVC claim.\n\nThe kubelet volume manager deadlocks in this situation: it stages the\nvolume once but never calls N\n[…]\n existing Volume name\nin the VolumeMount rather than emitting a duplicate Volume spec.\n\nReproducer confirmed in production: tr-12387 pod stuck 13+ minutes.\nCovered by TestBuild_SharedPVCDeduplication.",
"is_bot": false,
"headline": "fix: deduplicate PVC volumes in jobbuilder to prevent kubelet deadlock",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-19T10:52:45Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "11883bcfee8681338271118241e28dcd73820468",
"body": "- Add helm-chart-dev job to images.yaml that packages and publishes\n the osmia chart as version 0.0.0-edge to gh-pages after all image\n jobs complete. appVersion is set to the full git SHA for traceability.\n- Add workflow_dispatch trigger so edge builds can be run manually.\n- Bump workflow permiss\n[…]\needed for gh-pages push).\n- Document dev release workflow in docs/contributing.md including how\n to switch ArgoCD between dev and release mode.\n- Add CHANGELOG entry for the new dev release pipeline.",
"is_bot": false,
"headline": "feat: publish 0.0.0-edge Helm chart on every push to main",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-19T10:13:28Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "783b4ff9839a959f8f396d835212bb3b1f7d705b",
"body": "…ode engine\n\nThe claudecode engine hardcoded `osmia-anthropic-key` as the secret name for\nthe Anthropic API key, causing agent pods to reference a non-existent secret\nand hang in ContainerCreating indefinitely.\n\n- Add `APIKeySecret` to `EngineConfig` so the secret name is configurable\n- Read `engine\n[…]\n controller\n- Use `baseEngineConfig` at all 8 job creation sites for consistency\n- Fall back to `osmia-anthropic-key` when no override is set\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: release v0.3.7 — fix hardcoded API key secret name in Claude C…",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-19T09:27:45Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0b1dd07f68df34d65b76813710fb06c8489005ac",
"body": "Controller currently requires manual intervention when a worker pod\nfails and the controller restarts — the stale Running task run blocks\nthe ticket from being retried. Captures the recovery strategy needed.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add orphaned TaskRun recovery to roadmap",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-19T09:10:54Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "552aeba81fadb7165882cea96383350627f19fd6",
"body": "The per-taskrun-pvc session store creates PVCs via the K8s API but the\nClusterRole did not grant this permission. Controller was failing with\n\"persistentvolumeclaims is forbidden\" on every ticket poll.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: add persistentvolumeclaims RBAC to controller service account",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-19T08:53:13Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "912adf3a6ae617cb7cf14284f19fcc21274458ab",
"body": "PerTaskRunPVCStore.Prepare was implemented but never called, so the\nper-TaskRun PVC was never created before the K8s Job referenced it.\nAgent pods were stuck in Pending with \"PVC not found\" errors.\n\nThe controller now holds a sessionStore reference (WithSessionStore)\nand calls prepareSession before every BuildExecutionSpec — covering\ninitial jobs, retries, continuations, fallbacks, review follow-ups,\nand tournament candidates.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: call sessionStore.Prepare before creating agent jobs",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-18T16:05:18Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f4913617b0520fa8ebbbf76ab1e5c2776123a722",
"body": "Default deploymentStrategy to Recreate to prevent Multi-Attach errors\nwhen rolling out new pods against a ReadWriteOnce PVC. RollingUpdate\nstarts the new pod before the old one is terminated, causing both to\ncompete for the volume. Recreate ensures the old pod is gone first.\n\nConfigurable via deploymentStrategy in values.yaml.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: release v0.3.4 — use Recreate deployment strategy for RWO PVC",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-18T14:57:49Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e4e06e0c6005ef769012a3f4b6c8e3c746c10649",
"body": "The chart defaulted leaderElection.enabled to true, passing\n--leader-elect=true to the controller binary which does not support that\nflag yet. This caused the pod to crash-loop on startup. Changed default\nto false with a note that leader election is not yet implemented.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: release v0.3.3 — fix leaderElection default in Helm chart",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-17T18:02:16Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "5cf01b0aa5f96a97f80691398ae851d5bcc3df42",
"body": "…ecture diagram\n\nRenamed the architecture image in the README from `Osmia-architecture.png` to `osmia_architecture.png` for consistency. Added the new architecture diagram file to the images directory.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: update architecture image filename in README and add new archit…",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-17T16:36:05Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "74171e6718b087763349fc2ebd40ee7b91036298",
"body": "Documents the full release process including the critical Chart.yaml\nbump step that caused v0.3.0 and v0.3.1 Helm charts to never publish.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add release checklist to contributing guide",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-17T14:29:58Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "09a6fc8092f126f2a4c5bf5ed4a14eaad43c7116",
"body": "Chart.yaml was stuck at 0.2.0; the chart-releaser action skipped\npublishing because it saw no version change. ArgoCD could not find\nchart versions 0.3.0 or 0.3.1 in the Helm repository.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: release v0.3.2 — bump Chart.yaml to fix Helm chart publishing",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-17T14:26:42Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "54f8f820e91fbd3185e97e6930db68158c9c8967",
"body": "Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: release v0.3.1",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-16T14:42:50Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "562abe67f44035e07b6e4629e16cf987b9961060",
"body": "…ing (#13)\n\n* chore: run gofmt on all unformatted files\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\n\n* fix: add K8s recommended labels to agent pods for NetworkPolicy matching (#12)\n\nThe agent NetworkPolicy selects on `app.kubernetes.io/component: agent`\nand `app.kubernetes.io/managed-b\n[…]\nrkPolicy paragraph with label details and\n cross-reference to security.md.\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: add K8s recommended labels to agent pods for NetworkPolicy match…",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-16T14:41:09Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c6eb55bdda2425bda2c412788fe16ff1a96510ef",
"body": "Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: release v0.3.0",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-13T09:36:52Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "aee2006d75d31cabeffc43552e76df5318c113d5",
"body": "* feat: user-prompted continuation on max-turns exhaustion\n\nWhen a Claude Code agent exhausts --max-turns, the controller can now\npause and ask the operator via Slack whether to continue or stop, rather\nthan auto-retrying or failing silently.\n\nDetection: handleJobComplete compares ToolCallsTotal aga\n[…]\n\n- CHANGELOG.md: fix engine key claude_code → claude-code in config snippet\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: user-prompted continuation on max-turns exhaustion (#8)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-13T09:35:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ab0677541dd1c10a583d7431ea3eb39b0f0ab33b",
"body": "* feat: add session persistence for agent continuations\n\nRetry pods can now resume Claude Code sessions with full conversation\nhistory via `--resume <session-id>` instead of starting fresh and\nrelying on git diffs alone.\n\n## What changed\n\n**Core types**\n- `VolumeMount.PVCName` — new field for PVC-ba\n[…]\nes its own\nsession ID from TaskRunID. Both fields can coexist on retries.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: session persistence for agent continuations (#5)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-12T21:57:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a0e4697c94f89ff8a9ea2ae7f6e5bf0547b871f5",
"body": "Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add Osmia name callout to README",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-12T15:41:41Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "c17b22076943c6ac950a8727871159495b2178e2",
"body": "Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add osmia banner image",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-12T15:40:34Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "3151d2c57ac0041f45d04d70c89e6888510f1d85",
"body": "Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add banner image to README",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-12T15:39:40Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "b799296860d2b2a36b70809dfe603aa0d2158f02",
"body": "* feat: rename project from RoboDev to Osmia\n\nFull project rename across all ~270 files. The project is now Osmia\n(the mason bee genus — solitary but incredibly efficient builders),\nreflecting the new repository at github.com/unitaryai/osmia.\n\nChanges:\n- Go module: github.com/unitaryai/robodev → git\n[…]\nand issue templates that were not\ncaught in the original rename commit.\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": "feat: rename project from RoboDev to Osmia (#4)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-12T15:24:30Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "35adc956e5b4fdcf9d97ea1fff974190bc6e376a",
"body": "* feat: add local ticketing backend and frontend\n\n* fix: address local ticketing review comments\n\n* docs: add local UI screenshots\n\n* revert: remove screenshot assets from repo\n\n* fix: harden local UI empty list handling\n\n* refactor: simplify local ticket board ui\n\n* refactor: separate local tracker\n[…]\n clearer error messages\n- Use t.Run subtests in noop backend lifecycle test\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: add local ticketing backend and frontend (#3)",
"author_name": "James Thewlis",
"author_login": "jamt9000",
"committed_at": "2026-03-12T14:05:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f89dfe6556ad648acc3e522a799c1cff5c6a3f20",
"body": "* feat: add built-in AWS Secrets Manager backend\n\nAdd a native aws-secrets-manager secrets backend that reads secrets\nfrom AWS Secrets Manager via the AWS SDK v2 default credential chain.\nOn EKS with IRSA, authentication is automatic with no static credentials.\n\nThe backend supports:\n- URI scheme aw\n[…]\nhe codebase,\ncausing context deadline exceeded errors on package loading.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: built-in AWS Secrets Manager backend (#1)",
"author_name": "Matt Camp",
"author_login": "mattcamp",
"committed_at": "2026-03-10T15:57:50Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f860e502382cb8243d5e2cc182e6796f947bce17",
"body": "* fix: make local kind bootstrap work out of the box\n\nAlign the local controller image tag with the Helm chart, default the dev overlay to noop ticketing for credential-free smoke tests, and document the split between local-up and live-up. Also link AGENTS.md to CLAUDE.md to keep the agent instructi\n[…]\nden.\n\nAlso clarify that localhost:30080 exposes the controller HTTP endpoints for local smoke checks.\n\nCo-Authored-By: Codex <noreply@openai.com>\n\n---------\n\nCo-authored-by: Codex <noreply@openai.com>",
"is_bot": false,
"headline": "fix: make local kind bootstrap work out of the box (#2)",
"author_name": "James Thewlis",
"author_login": "jamt9000",
"committed_at": "2026-03-09T11:01:52Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e9d445e3f0cf3f12a430e185a6b79a620f2b5ff6",
"body": "When a Claude Code pod hits --max-turns and exits, the emptyDir workspace\nis destroyed and any uncommitted work is lost. This change makes retries\nresumable by using git as a checkpoint.\n\n- Add Task.PriorBranchName field so the engine knows a prior attempt\n pushed work to a recoverable branch\n- Upd\n[…]\ncketID> for retries where\n the pod was killed before the stop hook wrote result.json\n- Add tests for all new prompt and controller behaviour\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: continue agent sessions across max-turns retries via git branch",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T18:23:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9fea68a7455c8ca71a190ebe092dc6d840b579c4",
"body": "The --max-turns flag was hard-coded to 50, causing task failures on\ncomplex multi-file changes. Users can now set max_turns in config:\n\n engines:\n claude_code:\n max_turns: 200\n\nWires through config → WithMaxTurns option → effectiveMaxTurns() helper\n→ --max-turns CLI flag. Defaults to 50 when unset.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add configurable max_turns for Claude Code engine",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T17:34:43Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "82f3c934369ef89c511fdfa1f80ea8375471de62",
"body": "The 'Each tenant receives' bullet list presented planned namespace isolation\nas active behaviour. Changed to 'will receive' and added an admonition noting\nthat the tenancy config block has no runtime effect today.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: clarify multi-tenancy in scaling guide is on the roadmap",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T12:24:30Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "550184b0918dc1d166d3b0352342de4b90aa72ea",
"body": "… engines\n\n- architecture.md, security.md, guardrails-overview.md, kubernetes.md:\n layers 3 (guardrails.md) and 4 (task profiles) now accurately described\n as advisory / on-roadmap rather than actively enforced by the controller\n- scaling.md: remove claim that leader election is active; note\n nam\n[…]\nthetic tickets\n- concepts/engines.md: tournament warning now says auto-rejection\n threshold, not approval gate, for max_predicted_cost_per_job\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: fix secondary doc overclaiming — guardrails, scaling, webhooks,…",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T12:22:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4cf53ed8ae18e469eb687a80804b59f5ff3d1a2b",
"body": "Five items were either missing from the roadmap or incorrectly marked\ncomplete:\n\n- Task-Scoped Secret References: item 10 was marked ✅ but the\n secretresolver is not wired into ProcessTicket; demoted to 🚧 and\n added as a proper roadmap item with specific gaps listed\n- Guardrails.md injection: not \n[…]\nLarge scope)\n\nAlso corrected \"12/13 complete\" to \"11/13\" and added an accuracy note\nfor item 11 (NetworkPolicy is opt-in, not on by default).\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: update roadmap to reflect unimplemented features",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T12:11:36Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1842a7000701a6f6b928dd349e722814c8980237",
"body": "Six areas where docs described behaviour that isn't wired at runtime:\n\n1. Estimator approval gate → auto-rejection\n The controller calls MarkFailed (auto-reject), not an approval hold.\n Docs said tasks were \"blocked until a human approves\". Fixed in\n estimator.md and README.md.\n\n2. Task-scoped\n[…]\n; stubs must\n be generated with `make sdk-gen`. sdks.md and README.md updated to\n describe what IS in the repo vs what must be generated.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: strip overclaiming — align docs with actual implementation",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T12:08:40Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "197908e4dea9dcb52c81205fada967dcd533bc61",
"body": "…althy\n\nOn an interface-version mismatch, LoadPlugin returns an error before creating\nany pluginInstance. No health state is recorded. Docs incorrectly said the\nplugin was \"marked permanently unhealthy\", implying a stored unhealthy instance.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: correct mismatch outcome — plugin is not loaded, not marked unhe…",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T11:45:05Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "2259db087e6577bf564f8484c923ce2e873e48a3",
"body": "The controller's version validation is two-level:\n1. Pre-spawn config check — compares the declared interface_version in config\n against knownInterfaceVersions; rejects mismatches before spawning.\n2. Transport handshake — hashicorp/go-plugin magic cookie confirms the binary\n is a valid RoboDev p\n[…]\ngins/writing-a-plugin.md: add admonition clarifying Handshake RPC\n is required for plugins to implement but not yet called by the controller\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: correct plugin handshake documentation and code comments",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T11:26:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "70f15a5276a33ea52892a5d100e8a3b56514cb3d",
"body": "Agent teams and sub-agents are two distinct Claude Code features that were\nincorrectly conflated. Agent teams spawn multiple independent Claude Code\ninstances with shared task lists and inter-agent messaging; sub-agents are\nlightweight helpers within a single session.\n\n- Remove BuildAgentFlags/Agent\n[…]\nve Agents field from AgentTeamsConfig\n- Rewrite integration tests for correct behaviour\n- Update docs to explain both features as complementary\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: un-deprecate agent teams and fix implementation",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T11:18:20Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0af1d28bd1f905c003a958123f379f3e0ff83c0f",
"body": "…lidation\n\nAddress three GPT review findings:\n\n[P1] proto/scm.proto now includes ListReviewComments, ReplyToComment,\nResolveThread, and GetDiff RPCs with their request/response messages,\nmatching the Go scm.Backend interface (v2). Third-party plugins written\nagainst the protobuf API can now implemen\n[…]\nThe plugin API\nreference, writing-a-plugin guide, and lifecycle description now\naccurately state per-interface versions instead of \"1 for all\".\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: sync proto/scm.proto with Go interface and add plugin version va…",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T11:09:50Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "31d69a6df8707116b2d074c867c8ba3851e792ee",
"body": "…olumes\n\nAdd three related features that improve Claude Code engine configurability:\n\n1. ConfigMap volume support in VolumeMount/jobbuilder — new SubPath,\n ConfigMapName, ConfigMapKey fields allow ConfigMap volume sources\n instead of emptyDir.\n\n2. ConfigMap-backed skills — skills can now be load\n[…]\nclaude/agents/ by setup-claude.sh.\n\nDeprecates agent_teams with a runtime warning. Full test coverage and\ndocumentation for all three features.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add ConfigMap-backed skills, sub-agent support, and ConfigMap v…",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T11:03:36Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9fe57fabff9ee84fca96dd34cb8a17f7736881d5",
"body": "The engine reference and configuration guide now document:\n- Custom skills (inline and image-bundled) with env var delivery\n- Agent teams (experimental) with default agents per task type\n- All Claude Code config fields: fallback_model, tool_whitelist,\n tool_blacklist, json_schema, no_session_persis\n[…]\nsh startup flow\n- Full volume mounts (home, tmp) and environment variables\n- Removed stale require_human_approval_before_mr from config example\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add skills, agent teams, and full Claude Code config reference",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T10:37:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a7b75849fe5e5ffcf09934204dd30097403e5ec5",
"body": "GetDiff was added to the scm.Backend interface without bumping\nInterfaceVersion, leaving external plugins with no signal that the\ncontract changed. Also adds tests for GitHub/GitLab GetDiff (including\nHEAD/default-branch resolution) and trigger label auto-derivation.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: bump scm.InterfaceVersion to 2 and add missing test coverage",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T10:31:04Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "68aaf0d429d3f388302b56509012dbb28866e408",
"body": "… retry\n\nFour issues from GPT's follow-up review:\n\n1. GetDiff no longer hardcodes \"main\" as base branch. The interface now\n accepts a baseBranch parameter; when empty, GitHub uses HEAD (resolves\n to the repo's default branch) and GitLab fetches the project's\n default_branch from the API.\n\n2. L\n[…]\nSlack approval callback failures now return HTTP 500 instead of 200,\n so Slack retries the delivery rather than silently losing the callback.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: address GPT review round 3 — default branch, live cost, callback…",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T10:22:49Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4d44e580c5d309b0d17f868f0fc8891e8c4d1fed",
"body": "…ost enforcement\n\nPhase 1 — Approval flow end-to-end (P0):\n- Fix Slack action ID mismatch: match robodev_approval_ prefix instead of\n robodev_approve_/robodev_reject_ which never matched the generated IDs\n- Add ApprovalHandler interface to webhook server, route approval callbacks\n to controller in\n[…]\nnt (P1):\n- Add MaxCostPerJob to watchdog RulesConfig with checkTotalCost rule\n- Wire guardrails.max_cost_per_job into watchdog rules in main.go\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: address code review findings round 2 — approval flow, routing, c…",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T10:07:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2b61addab13b0f9117b5bdd6345a73fbb1d8b36e",
"body": "- Slack approval callbacks (robodev_approve_* / robodev_reject_*) are\n now acknowledged and logged only; they are no longer forwarded to\n ProcessTicket, which was creating spurious TaskRuns with action IDs\n as ticket IDs.\n\n- GitHub polling backend filters out pull requests returned by the\n /issu\n[…]\nect wrong config key names in README and docs:\n max_cost_per_task_usd → max_cost_per_job,\n max_duration_minutes → max_job_duration_minutes.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: address code review findings — security and correctness bugs",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-06T09:06:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "41b19f60a57b74cad96b98e5b5b8c6d590596fa1",
"body": "Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: release v0.2.0",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-05T18:20:39Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "45a4d81cba2420f15e5acc6291d9c1f9b5b92993",
"body": null,
"is_bot": false,
"headline": "ci: add workflow_dispatch trigger to CI workflow",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-05T17:48:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "49b0f82407f20ba7fbc44155fa5ad2d75dfd403e",
"body": "- configuration.md: expand ticketing section with full config reference\n for GitHub, Shortcut, and Linear including all keys and a table of\n fields; fix stale note claiming intelligence subsystems are unwired\n- plugins/ticketing.md: add Shortcut and Linear built-in backend sections\n with configur\n[…]\nup guide for Linear + Slack\n- mkdocs.yml: add Linear + Slack guide to nav\n- index.md: fix broken anchor link to competitive execution section\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: complete ticketing backend documentation",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-05T17:25:29Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "07cf99bac7cb7dbf641d87c17c3a7876a3b45291",
"body": "Add WithCompletedStateName option to the Shortcut backend so MarkComplete\ncan transition stories to an arbitrary state (e.g. \"Ready for Review\")\nrather than always using the first done-type workflow state. Wire via\ncompleted_state_name config key.\n\nAdd info log when memory context is injected into a prompt so it is\nobservable in controller logs.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: configurable completed state and memory injection logging",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-05T17:14:59Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "aebf446a6e00c34e67b86f5934f9444713019015",
"body": "Add optional PVC for SQLite stores (memory, routing, watchdog) mounted\nat /data, controlled by persistence.enabled. Fix the ClusterRole to\ninclude pods/exec so PRM hint file injection can reach agent pods.\nAlso tidy roadmap: move item 20 to completed, mark docs CI/CD done.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: add persistence support and fix pods/exec RBAC in Helm chart",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-05T16:56:10Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d17976fdc53e9b54ea623c6272b3dea3358faab4",
"body": "After a task finishes, the Slack notification and Shortcut ticket\ncomment now include the actual cost (e.g. \"Cost: $0.0142\") and token\nusage (\"Tokens: 4821 in / 1203 out\") when the engine reports them.\nBoth fields are omitted silently when zero/nil so existing behaviour\nis unchanged for engines that do not report cost data.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: include cost and token usage in completion notifications",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-05T16:42:49Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "6169e72f3b16977d2f2effe3c93c410c75598319",
"body": "The default image.repository was missing the /controller path segment,\ncausing pulls to fail with 403 as ghcr.io/unitaryai/robodev does not\nexist — the actual image is ghcr.io/unitaryai/robodev/controller.\n\nBumps chart version to 0.1.1.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: correct controller image repository path in Helm chart",
"author_name": "matt",
"author_login": null,
"committed_at": "2026-03-05T16:23:32Z",
"body_truncated": false,
"is_coding_agent": true
}
],
"releases_count": 11,
"commits_last_year": 173,
"latest_release_at": "2026-07-16T10:44:09Z",
"latest_release_tag": "osmia-0.4.0",
"releases_from_tags": false,
"days_since_last_push": 7,
"active_weeks_last_year": 10,
"days_since_latest_release": 11,
"mean_days_between_releases": 14.7
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": true,
"health_percentage": 87,
"has_issue_template": false,
"has_code_of_conduct": true,
"has_pull_request_template": true
},
"ecosystem": {
"packages": [
{
"name": "github.com/unitaryai/osmia",
"exists": true,
"license": null,
"keywords": [],
"ecosystem": "go",
"matches_repo": true,
"registry_url": "https://pkg.go.dev/github.com/unitaryai/osmia",
"is_deprecated": false,
"latest_version": "v0.4.0",
"repository_url": "https://github.com/unitaryai/osmia",
"versions_count": 12,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": null,
"latest_published_at": "2026-07-16T10:41:37Z",
"latest_version_yanked": null,
"days_since_latest_publish": 11
}
]
},
"popularity": {
"forks": 2,
"stars": 14,
"watchers": 0,
"fork_history": {
"days": [
{
"date": "2026-03-30",
"count": 1
},
{
"date": "2026-04-30",
"count": 1
}
],
"complete": true,
"collected": 2,
"total_forks": 2
},
"star_history": null,
"open_issues_and_prs": 6
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [
"examples"
],
"has_llms_txt": false,
"has_dockerfile": true,
"has_mcp_signal": true,
"bootstrap_files": [
"Makefile"
],
"api_schema_files": [
"proto/approval.proto",
"proto/common.proto",
"proto/engine.proto",
"proto/notifications.proto",
"proto/review.proto",
"proto/scm.proto",
"proto/secrets.proto",
"proto/ticketing.proto"
],
"has_devcontainer": false,
"typecheck_configs": [
"examples/plugins/example-teams-ts/tsconfig.json",
"sdk/typescript/tsconfig.json"
],
"toolchain_manifests": [
"go.mod",
"hack/fake-agent/go.mod"
],
"largest_source_bytes": 121860,
"source_files_sampled": 286,
"oversized_source_files": 1,
"agent_instruction_files": [
"AGENTS.md",
"CLAUDE.md"
],
"agent_instruction_max_bytes": 5249
},
"dependencies": {
"manifests": [
"go.mod",
"requirements.txt"
],
"advisories": {
"error": null,
"scope": null,
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"go",
"pypi"
],
"dependencies": [
{
"name": "github.com/aws/aws-sdk-go-v2",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.41.3"
},
{
"name": "github.com/aws/aws-sdk-go-v2/config",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.32.11"
},
{
"name": "github.com/aws/aws-sdk-go-v2/credentials",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.19.11"
},
{
"name": "github.com/aws/aws-sdk-go-v2/service/secretsmanager",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.41.3"
},
{
"name": "github.com/aws/aws-sdk-go-v2/service/sts",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.41.8"
},
{
"name": "github.com/google/uuid",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.6.0"
},
{
"name": "github.com/hashicorp/go-plugin",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.7.0"
},
{
"name": "github.com/prometheus/client_golang",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.20.5"
},
{
"name": "github.com/stretchr/testify",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.10.0"
},
{
"name": "github.com/svix/svix-webhooks",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.92.2"
},
{
"name": "gopkg.in/yaml.v3",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v3.0.1"
},
{
"name": "k8s.io/api",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.31.0"
},
{
"name": "k8s.io/apimachinery",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.31.0"
},
{
"name": "k8s.io/client-go",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.31.0"
},
{
"name": "modernc.org/sqlite",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.46.1"
}
],
"all_dependencies": {
"error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"source": null,
"packages": [],
"collected": false,
"truncated": false,
"total_count": null,
"direct_count": null,
"indirect_count": null
}
},
"maintainership": {
"issues": {
"open_prs": 0,
"merged_prs": 55,
"open_issues": 6,
"closed_ratio": 0.143,
"closed_issues": 1,
"closed_unmerged_prs": 3
},
"bus_factor": 1,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "matt-wai",
"commits": 94,
"avatar_url": "https://avatars.githubusercontent.com/u/197967014?v=4"
},
{
"type": "User",
"login": "mattcamp",
"commits": 66,
"avatar_url": "https://avatars.githubusercontent.com/u/696909?v=4"
},
{
"type": "User",
"login": "sarahjanenewnham",
"commits": 11,
"avatar_url": "https://avatars.githubusercontent.com/u/115044290?v=4"
},
{
"type": "User",
"login": "jamt9000",
"commits": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/1186841?v=4"
}
],
"contributors_sampled": 4,
"top_contributor_share": 0.543
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"ci.yaml",
"docs.yaml",
"images.yaml",
"release.yaml"
],
"has_docs_dir": true,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"go.sum"
],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": null,
"reason": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 10,
"reason": "29 out of 29 merged PRs checked by a CI test -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 3,
"reason": "Found 11/30 approved changesets -- score normalized to 3",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 3,
"reason": "project has 1 contributing companies or organizations -- score normalized to 3",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 9,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "27 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": 10,
"reason": "packaging workflow detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "SAST tool is not run on all commits -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 10,
"reason": "security policy file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": 0,
"reason": "Project has not signed or included provenance with any releases.",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 0,
"reason": "17 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "66243d19c27d4d0751d0d4ce4018647f368e6b74",
"ran_at": "2026-07-28T08:52:11Z",
"aggregate_score": 4.4,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": true,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-20T09:12:43Z",
"oldest_open_prs": [],
"last_merged_pr_at": "2026-07-20T09:10:46Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 6,
"created_at": "2026-03-12T20:06:48Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 7,
"created_at": "2026-03-12T20:06:49Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 9,
"created_at": "2026-03-13T11:16:15Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 10,
"created_at": "2026-03-13T11:25:43Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 11,
"created_at": "2026-03-13T11:39:29Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 37,
"created_at": "2026-04-10T10:47:47Z",
"last_comment_at": null,
"last_comment_author": null
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/unitaryai/osmia",
"host": "github.com",
"name": "osmia",
"owner": "unitaryai"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 61,
"inputs": {
"security": 44,
"vitality": 79,
"community": 50,
"governance": 55,
"engineering": 71
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "good",
"name": "Vitality",
"value": 79,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "good",
"name": "Development activity",
"note": null,
"notes": [],
"value": 71,
"inputs": {
"commits_last_year": 173,
"human_commit_share": 1,
"days_since_last_push": 7,
"active_weeks_last_year": 10
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 7 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 7
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "10/52 weeks with commits",
"points": 6.9,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 10
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "173 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 173
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "27 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": null,
"notes": [],
"value": 90,
"inputs": {
"releases_count": 11,
"latest_release_tag": "osmia-0.4.0",
"releases_from_tags": false,
"days_since_latest_release": 11,
"mean_days_between_releases": 14.7
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "11 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 11
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 11 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 11
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~14.7 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 14.7
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "unverified",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": "repository_too_young",
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": null,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "maintenance record not established from the collected data",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_unverified",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "moderate",
"name": "Community & Adoption",
"value": 50,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 18,
"inputs": {
"forks": 2,
"stars": 14,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "14 stars",
"points": 18.1,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 14
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "2 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 2
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "0 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 0
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "excellent",
"name": "Community health",
"note": null,
"notes": [],
"value": 86,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": true,
"has_issue_template": false,
"has_code_of_conduct": true,
"has_pull_request_template": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "license file present, not a recognized license",
"points": 16.9,
"status": "partial",
"details": [
{
"code": "license_custom",
"params": {}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 18,
"status": "met",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 13.5,
"status": "met",
"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": 6.3,
"status": "met",
"details": [],
"max_points": 6.3
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 55,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 28,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 4,
"top_contributor_share": 0.543
},
"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 54% of commits",
"points": 10.3,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 54
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "4 contributors",
"points": 5.4,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 4
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 3,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "at_risk",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 48,
"inputs": {
"merged_prs": 55,
"open_issues": 6,
"closed_issues": 1,
"issue_closed_ratio": 0.143,
"closed_unmerged_prs": 3
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "14% of issues closed",
"points": 6.7,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 14
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "55/58 decided PRs merged",
"points": 36.3,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 55,
"decided": 58
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 11/30 approved changesets -- score normalized to 3",
"points": 4.5,
"status": "partial",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 58,
"inputs": {
"followers": 21,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "unitaryai",
"public_repos": 7,
"account_age_days": 2093
},
"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": "21 followers of unitaryai",
"points": 9.7,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 21,
"login": "unitaryai"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "7 public repos, account ~5 yr old",
"points": 18,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 7
}
},
{
"code": "account_age_years",
"params": {
"years": 5
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"github.com/unitaryai/osmia"
],
"ecosystems": "go",
"any_deprecated": false,
"min_days_since_publish": 11
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on go",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "go"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 11 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 11
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "12 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 12
}
}
],
"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": "good",
"name": "Engineering Quality",
"value": 71,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "moderate",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 68,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "4 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 4
}
}
],
"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": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"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": "29 out of 29 merged PRs checked by a CI test -- score normalized to 10",
"points": 20,
"status": "met",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "good",
"name": "Documentation",
"note": null,
"notes": [],
"value": 75,
"inputs": {
"topics": [],
"has_wiki": true,
"homepage": null,
"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": null,
"points": 0,
"status": "missed",
"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": "at_risk",
"name": "Security",
"value": 44,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): Branch-Protection. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"branch_protection"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 44,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 17,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 1,
"scorecard_aggregate": 4.4
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "29 out of 29 merged PRs checked by a CI test -- score normalized to 10",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 11/30 approved changesets -- score normalized to 3",
"points": 2.2,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 1 contributing companies or organizations -- score normalized to 3",
"points": 0.8,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.2,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "27 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "SAST tool is not run on all commits -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "17 existing vulnerabilities detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"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"
],
"review_only_matches": 0,
"assessed_self_published_locations": 1
},
"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": 84,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "excellent",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 1,
"agent_instruction_files": [
"AGENTS.md",
"CLAUDE.md"
],
"agent_instruction_max_bytes": 5249
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "AGENTS.md, CLAUDE.md",
"points": 45,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "AGENTS.md, CLAUDE.md"
}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"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": "good",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 71,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"go.sum"
],
"has_dockerfile": true,
"typed_language": true,
"bootstrap_files": [
"Makefile"
],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [
"examples/plugins/example-teams-ts/tsconfig.json",
"sdk/typescript/tsconfig.json"
],
"agent_commit_share": 0.87,
"toolchain_manifests": [
"go.mod",
"hack/fake-agent/go.mod"
],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "Makefile",
"points": 18,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Makefile"
}
}
],
"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": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "examples/plugins/example-teams-ts/tsconfig.json, sdk/typescript/tsconfig.json",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "examples/plugins/example-teams-ts/tsconfig.json, sdk/typescript/tsconfig.json"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "Dockerfile, lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Dockerfile, lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "87 of the last 100 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 87,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"primary_language": "Go",
"largest_source_bytes": 121860,
"source_files_sampled": 286,
"oversized_source_files": 1
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Go (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Go"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "1/286 source files over 60KB",
"points": 54.8,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 286,
"oversized": 1
}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "excellent",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"example_dirs": [
"examples"
],
"has_mcp_signal": true,
"api_schema_files": [
"proto/approval.proto",
"proto/common.proto",
"proto/engine.proto",
"proto/notifications.proto",
"proto/review.proto",
"proto/scm.proto",
"proto/secrets.proto",
"proto/ticketing.proto"
]
},
"components": [
{
"key": "api_schema_openapi_graphql_proto",
"name": "API schema (OpenAPI/GraphQL/proto)",
"detail": "proto/approval.proto, proto/common.proto, proto/engine.proto, proto/notifications.proto, proto/review.proto, proto/scm.proto, proto/secrets.proto, proto/ticketing.proto",
"points": 40,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "proto/approval.proto, proto/common.proto, proto/engine.proto, proto/notifications.proto, proto/review.proto, proto/scm.proto, proto/secrets.proto, proto/ticketing.proto"
}
}
],
"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": "examples",
"points": 40,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "examples"
}
}
],
"max_points": 40
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
],
"report_type": "repository",
"generated_at": "2026-07-28T08:52:31.735012Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/u/unitaryai/osmia.svg",
"full_name": "unitaryai/osmia",
"license_state": "custom",
"license_spdx": null
}