原始 JSON 报告 机器可读
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 3150,
"has_wiki": true,
"homepage": "https://porulle-docs.vercel.app",
"languages": {
"CSS": 8195,
"MDX": 521801,
"Astro": 11184,
"Shell": 31821,
"Dockerfile": 1387,
"JavaScript": 25805,
"TypeScript": 3862923
},
"pushed_at": "2026-07-18T18:05:46Z",
"created_at": "2026-05-11T21:13:08Z",
"owner_type": "Organization",
"updated_at": "2026-07-18T18:03:06Z",
"description": "Headless commerce framework for TypeScript. REST-only, security-hardened, self-host-first. Active development, alpha — straight out of the oven.",
"is_archived": false,
"is_disabled": false,
"license_spdx": "MIT",
"default_branch": "main",
"license_spdx_raw": "MIT",
"primary_language": "TypeScript",
"significant_languages": [
"TypeScript",
"MDX"
]
},
"owner": {
"blog": null,
"name": "Asyncdot Engineering",
"type": "Organization",
"login": "asyncdotengineering",
"company": null,
"location": null,
"followers": 0,
"avatar_url": "https://avatars.githubusercontent.com/u/130723569?v=4",
"created_at": "2023-04-14T02:52:53Z",
"is_verified": null,
"public_repos": 9,
"account_age_days": 1197
},
"license": {
"state": "standard",
"spdx_id": "MIT",
"raw_spdx": "MIT",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v0.6.0",
"kind": "minor",
"published_at": "2026-06-14T19:10:29Z"
},
{
"tag": "v0.5.0",
"kind": "minor",
"published_at": "2026-06-14T18:16:21Z"
}
],
"recent_commits": [
{
"oid": "017b18c2077d3e5401116ba6245b5b2d6183457e",
"body": "* docs(audit): round-3 adversarial findings (kernel, math, plugins, schema)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8\n\n* fix(core): capture full authorized amount, never record a $0 capture\n\nA full ca\n[…]\ne Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(release): version packages to 0.10.4 (#85)",
"author_name": "Mithushan Jalangan",
"author_login": "octalpixel",
"committed_at": "2026-07-18T18:03:01Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c6445828b4e8d4fb18ea7646a179997839f73030",
"body": "chore(release): 0.10.3 — order quote engine + checkout tax composition fixes",
"is_bot": false,
"headline": "Merge pull request #84 from asyncdotengineering/chore/release-0.10.3",
"author_name": "Mithushan Jalangan",
"author_login": "octalpixel",
"committed_at": "2026-07-18T15:47:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "da739df5cd7e1616115b4064d1c4ff845b9e17a9",
"body": "Order quote engine (POST /api/orders/quote) + checkout tax composition fixes.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "chore(release): version packages to 0.10.3",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T15:46:44Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a4f2fd53afaeb9e2f2fade6ae8a1c651479c7319",
"body": "… D / audit C1,C2a)\n\nNew computeOrderPricing() runs the SAME pricing hooks checkout runs — resolve →\npromotions → shipping → tax — with no cart/inventory/payment side effects, so a\nmanual/draft order quote equals what checkout charges (single source, no drift).\nExposed as POST /api/orders/quote (ord\n[…]\napters still ignore orderDiscount — tracked for follow-up.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "feat(core): order pricing quote engine + tax composition fixes (Slice…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T15:45:12Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "406404296b1aa20eb942c51eed9e55b137f832ad",
"body": "…lugins)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "docs(audit): round-2 adversarial findings (auth, async, supporting, p…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T15:45:12Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "30118910a4bf197b75f0c2a50c4b53d0a935a397",
"body": "…Vendure)\n\nSynthesis of an 8-agent parallel audit of the porulle engine. Verdict: primitives\nsound, composition mis-handles money. Convergent criticals (multi-agent + proven\nby porulle's own tests): tax computed before shipping (appliesToShipping dead),\nper-line discounts never attributed (tax over-\n[…]\ng.fulfillment. Full ranked findings + remediation roadmap.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "docs(audit): commerce-principles deviation report (vs Medusa/Shopify/…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T15:28:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e111e0f069c26143d4a3682e4702709b43d7ef80",
"body": "chore(release): 0.10.2 — promotions/validate returns authoritative cart discount",
"is_bot": false,
"headline": "Merge pull request #83 from asyncdotengineering/chore/release-0.10.2",
"author_name": "Mithushan Jalangan",
"author_login": "octalpixel",
"committed_at": "2026-07-18T13:55:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6b6f340ea852feb9d9dc4dd580b2d8993b6f4f49",
"body": "Patch: promotions/validate returns the authoritative cart discount (no client\nre-derivation → cart preview matches checkout).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "chore(release): version packages to 0.10.2",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T13:54:35Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "b920e7b19c2d2857ec0c8c90f42ef8abf1cbafda",
"body": "POST /api/promotions/validate took the full cart context but returned only the\npromotion, forcing every consumer to re-derive the discount amount — which drifts\nfrom the computation checkout actually runs and shows customers a wrong number in\nthe cart vs at checkout. The route now calls promotions.a\n[…]\nrts a 10%\ncode on a 10000 cart returns totalDiscount 1000.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "fix(core): promotions/validate returns the authoritative cart discount",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T13:54:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f4119430993dcc3727a4ecdde25f8588c76b1fc1",
"body": "chore(release): 0.10.1 — plugins work on zero-infra PGlite boot (U1)",
"is_bot": false,
"headline": "Merge pull request #82 from asyncdotengineering/chore/release-0.10.1",
"author_name": "Mithushan Jalangan",
"author_login": "octalpixel",
"committed_at": "2026-07-18T12:46:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ad22182e70eebc0e158d8d43679e6a1f8d537a39",
"body": "Patch: push merged plugin schema on zero-migration boot (U1) — @porulle plugins\n(gift cards, loyalty, …) now work on the zero-infra PGlite starter.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "chore(release): version packages to 0.10.1",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T12:44:44Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f91d25216b5b2e422d59fa18fb30323d28b24e8d",
"body": "… boot (U1)\n\nbuildSchema(config) — the only merge of plugin customSchemas into the schema —\nhad zero callers; pushSchema() pushed core-only getSchema(); nothing pushed the\nmerged schema at boot. Result: on a zero-migration (PGlite) boot, no plugin's\nown tables were ever created, so every plugin's ro\n[…]\now\nexists after createCommerce; migrate:false still skips.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "fix(core,adapter-pglite): push merged plugin schema on zero-migration…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T12:33:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8ea14030836a121da1b82685c122bc190eada079",
"body": "chore(release): version packages to 0.10.0",
"is_bot": false,
"headline": "Merge pull request #81 from asyncdotengineering/chore/release-0.10.0",
"author_name": "Mithushan Jalangan",
"author_login": "octalpixel",
"committed_at": "2026-07-18T10:50:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3aac1cb20ef71d962459aadadfadd980be0b0569",
"body": "Channel Connectors (Shopify/WooCommerce), cOAuth onboarding, app-level compliance\nwebhooks, job-engine hardening, security holistic-review follow-ups, and the new\n@porulle/adapter-pglite zero-infra database adapter.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "chore(release): version packages to 0.10.0",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T10:50:45Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "80ea718b2c730a17b89259dbc3caf2ff0552b4a1",
"body": "…ter-prep\n\nfeat(adapter-pglite,docs): zero-infra PGlite adapter + docs overhaul + agent scaffold",
"is_bot": false,
"headline": "Merge pull request #80 from asyncdotengineering/feat/docs-pglite-star…",
"author_name": "Mithushan Jalangan",
"author_login": "octalpixel",
"committed_at": "2026-07-18T10:46:01Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "efaf9d764aee10afabd02c0c511dda008d65a926",
"body": "…(llms.txt, agent scaffold, light theme)\n\n- packages/adapters/adapter-pglite: new zero-infra DatabaseAdapter (embedded\n WASM Postgres) — pushes core schema + seeds default org on boot; verified with\n a real createServer boot test (GET /api/health → 200). Swap-compatible with\n adapter-postgres. Id\n[…]\n.4.4 (6.4.6 dropped chunkToString and broke @astrojs/mdx).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "feat(adapter-pglite,docs): zero-infra PGlite adapter + docs overhaul …",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T10:45:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e3416fdcb9bec9efd136c3725d9584eab6a453f1",
"body": "…-followups\n\nfix(core): security holistic-review follow-ups (R-03–R-07)",
"is_bot": false,
"headline": "Merge pull request #79 from asyncdotengineering/fix/security-holistic…",
"author_name": "Mithushan Jalangan",
"author_login": "octalpixel",
"committed_at": "2026-07-18T08:16:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ff3d5e6e876f090119fd025aa6b5499f0dccd9fb",
"body": "Low-severity hardening from the holistic review; none was a live exploit.\n\n- R-03 (SEC-12): orders/changeStatus discriminated a tolerable \"missing\n inventory record\" by matching the message string. Add a typed\n CommerceInventoryRecordNotFoundError (code INVENTORY_RECORD_NOT_FOUND) emitted\n by the\n[…]\n: turbo test+check-types green — core 587 (+2), 1 skipped.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "fix(core): security holistic-review follow-ups R-03–R-07 (bf1f8053)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T08:15:43Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3d2f2ab116a69f477c8e0c33e6df88501b60729c",
"body": "…ecret-and-redact-fanout\n\nfix(channel-connectors): Shopify webhook app-secret verification + compliance redact fan-out",
"is_bot": false,
"headline": "Merge pull request #78 from asyncdotengineering/fix/shopify-webhook-s…",
"author_name": "Mithushan Jalangan",
"author_login": "octalpixel",
"committed_at": "2026-07-18T07:45:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bcd6751050133d3546d303f4f9a6b95ad716530a",
"body": "…shared shop_domain (d51ae76d)\n\nA shop_domain can map to multiple connected_stores rows (reconnect, or the same\nshop under two orgs). The compliance route resolved only the first via\ngetStoreByDomain, so a customers/redact / shop/redact erased PII on one store\nand left the others. Adds getStoresByDo\n[…]\npes green — plugin 40, core 585,\nadapters 6+6; docs build.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "fix(plugin-channel-connector): fan out compliance redaction across a …",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T07:45:09Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "92284bb44b019ffb95e751a028e58d941ec26fb3",
"body": "…2380508c)\n\nShopify signs every webhook for an app with the app client/API secret key —\nthere is no per-store secret (unlike WooCommerce). verifyWebhook was checking\nagainst store.webhookSecret (a random uuid), so real Shopify sync-webhook\ndeliveries would fail HMAC verification; offline tests only \n[…]\nerified: turbo test+check-types green (adapter-shopify 6).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "fix(adapter-shopify): verify webhooks against the app client secret (…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T07:44:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "55826cac7a3e56a8446517b2c81f221357b4931c",
"body": "feat: Channel Connectors — Shopify/WooCommerce connectors, OAuth onboarding + compliance",
"is_bot": false,
"headline": "Merge pull request #77 from asyncdotengineering/feat/channel-connectors",
"author_name": "Mithushan Jalangan",
"author_login": "octalpixel",
"committed_at": "2026-07-18T07:34:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "aa63b4266253f14727070711a9427830201176b6",
"body": "… (c3e5dcf5)\n\nThe mandatory GDPR webhooks (customers/data_request, customers/redact,\nshop/redact) are delivered to a single app-level URL, signed with the app\nclient secret, and route by shop_domain in the payload — not per-store. The\nfirst pass wired the (correct) redaction logic to the per-store w\n[…]\n 39,\nadapter-shopify 6, adapter-woocommerce 6; docs build.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "fix(channel-connectors): app-level Shopify compliance webhook ingress…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T07:13:12Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8f8c564deb399a86c50d27d8ca07e5334888bf30",
"body": "… compliance redaction groundwork\n\nAdds a second onboarding front door alongside credential-paste, converging on\nthe same connectStore pipeline (no store mode flag, no engine branching):\n\n- core: ChannelConnector gains optional buildAuthUrl + completeAuth\n- plugin: generic /api/channels/oauth/{provi\n[…]\n adapter-shopify (6), adapter-woocommerce (6); docs build.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "feat(channel-connectors): one-click OAuth store onboarding (cOAuth) +…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T06:59:32Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "22e0be4eca991f78aed7f458306a399c9dc7c8ce",
"body": "…engine hardening\n\nConnect external Shopify/WooCommerce stores, mirror catalog/inventory, sell through\none checkout, and inject paid orders back into the merchant's store. Standalone\nengine plugin + thin provider adapters, on the hardened order/refund core.\n\ncore:\n- sellable_entities.sourceStoreId p\n[…]\ntore-connector guide,\nreference/jobs + reference/adapters.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "feat(channel-connectors): Shopify/WooCommerce store connectors + job-…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-18T04:19:38Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "96da7640663ed952f2f1abd9d0ec52862b341117",
"body": "…tners to the private board\n\nWire Plan Desk into the repo and move two in-design features off public\nGitHub issues into the local Plan Desk board (project Porulle).\n\n- Setup: .mcp.json (MCP server), .plandesk/ (config, skill, workspace.db board),\n .agents/ + .codex/ factory+curator policy, CLAUDE.m\n[…]\nssues #60-76 deleted; both features now tracked privately.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "chore(plandesk): set up Plan Desk and migrate channel-connector + par…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-16T04:16:23Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4dfa8beb5cb3957418f5b2b7b28c35eadd55f288",
"body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "chore(release): version packages to 0.9.0",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-15T06:52:21Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "0d45e95eeb022adcd1162735d3d9a9ebf70411b7",
"body": "A creative red-team (deepseek-v4-pro) found that refundLines was never audited\nfor interplay with changeStatus refunds, the order lifecycle, and the payment\nlayer. The two refund paths tracked cumulative refunds independently. Fixes in\nOrderService:\n\n- R-01 (Critical) double payout: changeStatus(\"re\n[…]\ning) — no raw SQL / `as any`.\nturbo run test: 55/55 green.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "fix(security): close refund money-conservation cluster (deepseek VAPT)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-15T06:35:05Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4c94f20075d6417934c4d5beda763768ea738867",
"body": "…ut IDOR, gift-card tenancy\n\nA CVE-class VAPT (kimi-k2.7, real Postgres) proved 9 exploitable defects. Fixes:\n\n- Inventory broken-access-control (Critical/High): /api/inventory/warehouses,\n /reserve, /release had no authorization — a customer could configure warehouses\n and reserve/release stock, \n[…]\nd). kimi harness: 24 checks, 0 broken; turbo: 55/55 green.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "fix(security): close VAPT CVE-class cluster — inventory authz, checko…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-15T05:58:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d8c77db7634a1a4b58517cecaeedd16705b22094",
"body": "…t integrity, provenance\n\nA blind VAPT against a real Postgres instance proved two exploitable defects on\nthe order-creation surface, reachable by a customer-role actor over POST /api/orders:\n- money integrity: the primitive persisted client-supplied unitPrice/grandTotal\n verbatim, so a customer cr\n[…]\n 55/55 green; real-Postgres hostile-path\nmatrix: 8/8 safe.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0124euZZ7Qo6QyunCckprqA8",
"is_bot": false,
"headline": "fix(security): harden order creation — server-price by default, tenan…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-15T04:56:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "beaf78acbcc8dc9a164ac051cc2db95b806b5dac",
"body": "…2 (SEC-18)\n\nR-01 (Critical) — pin-login granted the operator an org `owner` membership on\nevery login (cashier -> owner escalation) because better-auth's\nreferences:\"organization\" key requires owner/admin to mint. Reworked: mint a\nUSER-referenced key that carries the operator's store in metadata (n\n[…]\n guard to both routes; regression test\nproves an admin cannot demote or revoke an owner.\n\nplugin-pos green (44), core green (552).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(security): resolve holistic-review blockers R-01 (SEC-16) and R-0…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T15:46:56Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "50146cd204afaa76fd483267b79551ce01a69899",
"body": "Add pos_pin_attempts table and lockout logic in verifyOperatorPin:\nafter 5 failed attempts within 15 minutes, block further PIN verification\nfor that operator until lockout expires. Counter resets on success.\nConfigurable via pinAuth.lockoutMaxAttempts and lockoutWindowMinutes.",
"is_bot": false,
"headline": "feat(pos): SEC-15 per-operator PIN brute-force lockout",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T15:02:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3757e48006ecb8dc14f0cbf3f568a3f93646c3e2",
"body": "…eanup\n\nSEC-17: validate timeDimensions against cube schema and build SELECT\naliases from canonical cube.member names instead of raw user strings.\n\nSEC-20: forward each stale order's organizationId via a system actor so\ncancel operates in the correct org instead of defaulting to org_default.\n\nRegression tests in packages/core/test/issue-SEC-17-* and issue-SEC-20-*.",
"is_bot": false,
"headline": "fix(security): SEC-17 analytics alias safety, SEC-20 per-org stale cl…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T14:01:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e9ab029ac737cda08933be0645f32155444fb520",
"body": "…t-in, pg-only\n\nSEC-18: Reject role assignments above the actor's privilege rank in\ncreateStaff and updateStaffRole (owner > admin > custom).\nSEC-19: Require config.auth.allowTestActor in addition to NODE_ENV=test\nfor x-test-actor header injection; enabled in test harness.\nSEC-05: Remove dead mysql/sqlite branches from auth/setup.ts.",
"is_bot": false,
"headline": "fix(security): SEC-18/19/05 auth hardening — role rank, test-actor op…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T13:47:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6aa0c0fc365de56e0589ed25391e6af1126b1a1d",
"body": "… SEC-04)\n\nChild tables now emit UNIQUE (col) instead of silently dropping unique: true.\nTop-level tables keep per-org UNIQUE (organization_id, col) for unique: true;\nunique: \"global\" renders UNIQUE (col). Docstrings corrected.",
"is_bot": false,
"headline": "fix(db): honor child-table unique + add global unique opt-in (SEC-03,…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T13:38:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d05a170c19457eedc28fb36261b3dcb3b866b44f",
"body": "…stomer\n\nThe checkout handler resolved a client-supplied customerId via getById/getByUserId\nwith no check that it belongs to the actor, so an authenticated customer could\nattribute an order to another customer. Extract resolveCheckoutCustomerUuid: a\nself-service actor only ever resolves to its OWN p\n[…]\ntomers:read. Guests\nunchanged. Helper is unit-tested (customer blocked, own honored, staff allowed).\n\nFull core suite green (545).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(core): SEC-07 don't let checkout attribute an order to another cu…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T13:36:29Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d0c9cf70c63d3dd665ebbf04aed3ab19760b24ad",
"body": "Thread organization_id through recipe-deduction raw SQL fallback (INSERT +\nUPDATE predicates) and add defense-in-depth org predicates to POS shift/txn\ncounters, loyalty redemption increments, and KDS ticket numbering. Add\nregression test proving inventory_movements inserts succeed and cross-org\ninventory_levels rows are untouched.",
"is_bot": false,
"headline": "fix(security): close tenant-scoping gaps in raw SQL writes (SEC-raw-sql)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T13:25:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "34b6e6edd1234969d8c105260b952bad7a7a5646",
"body": "Cancel/refund and fulfillment paths now release stock in the order's\norg and propagate real release failures. Add regression test for org-B\ncancel without creating a default-org warehouse.",
"is_bot": false,
"headline": "fix(SEC-12): pass actor/ctx into changeStatus inventory.release",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T13:13:18Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4f21bead99cbacfadecf090a9c6d19cf33a13237",
"body": "Reject cross-tenant GRN create attempts before any PO item updates.\nAdd regression test proving org-B quantity_received stays unchanged.",
"is_bot": false,
"headline": "fix(SEC-21): validate GRN poId/poItemId belong to actor org",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T13:13:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "820ec6ea59b8c883105a5cee048168a04c33a98f",
"body": "…the client\n\nPOST /pos/returns took items[].refundAmount straight from the body with no FK,\nno cap, no ledger and no idempotency — any cashier could complete a fabricated,\nunbounded cash refund against a foreign/fake order. Route the return through\norders.refundLines (the primitive the exchange flow\n[…]\nvers: server-derived amount, fabricated order rejected,\nover-refund rejected, double-refund rejected. plugin-pos suite green (42).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(plugin-pos): SEC-08 derive POS return refund from the order, not …",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T13:00:02Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "49db99dcd2c7e8ee61b51cbf6d7278ab08dba985",
"body": "Pass organizationId when minting shift credentials, register the POS\nscope with references:organization, wire Better Auth config forwarding,\nand resolve org-owned keys in auth middleware. Ensures operator org\nmembership before minting and adds a multi-org regression test.",
"is_bot": false,
"headline": "fix(SEC-16): bind pin-login API keys to operator organization",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T12:48:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6c3f01608be9b9c378c5e45a5a655f3e587dc106",
"body": "Exchange replacement lines now use pricing.resolve() per entity/variant\ninside the atomic transaction; client unitPrice is ignored. Adds a\nregression test and seeds catalog prices in exchanges.test.ts.",
"is_bot": false,
"headline": "fix(SEC-14): resolve exchange replacement prices server-side",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T12:47:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d4fafeb66aaeed57478ddf021795925599e2a385",
"body": "cart.addItem, pricing.setBasePrice and pricing.resolve fetched the entity via\nfindEntityById WITHOUT the actor's org, so another tenant's entity id could be\nadded to a cart or have a price stamped against it. Pass the resolved orgId so\nthe lookup is org-scoped (cross-org id -> not found). routes/pri\n[…]\ng.calculator) operate on already-org-resolved ids; making orgId globally\nrequired there is a follow-up (see IMPLEMENTATION-NOTES).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(core): SEC-10 scope user-facing findEntityById lookups by org",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T12:29:02Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3f0cd4870df9f88e55c3d129910a87901d43115d",
"body": "Adds a regression test proving anonymous storefront reads are scoped to the\nrequest's store: an org-bearing anonymous actor (as storeResolver middleware\nsets) reads its own store's product but not another store's. Confirms the\nSlice-2 getById fix is store-aware (kimi WBS R-03); no resolveOrgId change is\nneeded — the storeResolver already carries the store org.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "test(core): SEC-11 lock multi-store anonymous read isolation",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T12:22:01Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "dc2d119fa20cb1b31db114e5eb435fc59f233246",
"body": "createScopedDb previously intercepted only insert/select; update and delete\npassed through unscoped, so a scoped write filtered by a business key reached\nevery tenant (proven live against Postgres). Intercept update() and delete()\ntoo: pre-apply the org predicate (so a no-WHERE write can't sweep oth\n[…]\n.\n\nRegression test covers update/delete by business key across two orgs and the\nno-WHERE case. Full core suite green (537 passed).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(core): SEC-01 scope UPDATE/DELETE in the scoped-db proxy",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T12:02:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e206941c832c86e3cbd0417763d06f8682aba434",
"body": "…tion",
"is_bot": false,
"headline": "test(core): SEC-11 regression for anonymous catalog getById org isola…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T10:56:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5328bf856614f351ede9039b02e8b3982598da84",
"body": "…tions",
"is_bot": false,
"headline": "fix(core): SEC-09 assert org ownership on catalog option/variant muta…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T10:56:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4a11eb4cfa3decb63e4ec5ac0b2aba8098f02407",
"body": null,
"is_bot": false,
"headline": "fix(core): SEC-06 require customers:update on CustomerService.update",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-14T10:56:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "48d9eea33582b04bb7fc0b6fcad50cafad7b49ad",
"body": "Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(plugin-layaway): add package README",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-02T16:36:41Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "2c80a39139bf5f2709a0b5c417e0c195fca6c8d5",
"body": "New guides (building/): Store Settings, Receipts & Invoices, Tax Classes,\nRefunds & Exchanges, Layaway. Extended POS (PIN auth, order notes/timeline)\nand Analytics (retail reports) guides, the SDK guide (OfflineQueue), and the\nplugin contract (contributing api-key scopes). Reference updates: new\nend\n[…]\nthe v0.8.0 changelog entry and registered the new pages in the sidebar.\n\nVerified: astro build green (59 pages), all 271 internal links resolve.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: document the 0.8.0 retail-operations surface",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-02T16:30:09Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a52069c1c55372b629c43d33d8a5b58271ab7c2c",
"body": "Consumes 6 changesets (admin/operator gaps #40–#46, ordereka field-study\nbatches #47–#59, integrator quick wins) into the fixed @porulle/* line:\n0.7.0 → 0.8.0. plugin-layaway and adapter-neon join at 0.8.0.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(release): version packages to 0.8.0",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-02T16:13:00Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "ae7c329c8e6a40aa5a6a23141e909e6925339c45",
"body": "…yaway plugin, migration guide (#56–#59)\n\nFinal batch of the ordereka field-study roadmap.\n\n- #56 Order notes + activity timeline: POST/GET/DELETE /api/orders/{id}/notes\n (author, pinned-first ordering; new order_notes table) and\n GET /api/orders/{id}/timeline — one merged view of status history, \n[…]\n forfeit + reservation\nrollback). Full repo green (55/55 turbo test tasks), typecheck 38/38,\nbuild 36/36, lint clean, drizzle drift check clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core,plugin-layaway,docs): order notes/timeline, tax classes, la…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-02T10:01:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f40b3d1c624cfd5936086837074ee4c79ebbe5e7",
"body": "…1–#53)\n\nBatch three of the ordereka field-study roadmap.\n\n- #52 Core refund policy primitives: order_line_items.refunded_quantity is a\n real column enforced by POST /api/orders/{id}/refunds (per-line refundable\n quantity, 422 on over-refund); an optional per-operator daily cap read from\n setting\n[…]\npos pin-auth (4) + exchanges (3).\nFull repo green (54/54 turbo test tasks), typecheck 37/37, build 35/35,\nlint clean, drizzle drift check clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core,plugin-pos): refund policy, PIN auth runtime, exchanges (#5…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-02T09:39:21Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "df61d25c01130dc182545edd65efacd61bd89c16",
"body": "…er (#54, #55)\n\nBatch two of the ordereka field-study roadmap.\n\n- #54 @porulle/sdk OfflineQueue: persistent operation queue for POS clients\n that must sell through network drops. Pluggable storage (memoryStorage /\n webStorage for anything localStorage-shaped), idempotencyKey stamped into\n every b\n[…]\non (6 — fresh-pool-per-tx incl. throw path, Hyperdrive routing,\nexecute shape). check-types/lint/test green for both packages; repo build\ngreen.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(sdk,adapter-neon): offline sale queue + Workers-grade Neon adapt…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-02T09:02:55Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "157221c9fad2a6190b691878aee4fc95edebe0fe",
"body": "…e-call variants (#47–#50)\n\nBatch one of the ordereka field-study roadmap (first production adopter;\nevidence in .understanding/ordereka-porulle-usage.md).\n\n- #49 Settings: org-scoped runtime settings module — typed groups (general/\n branding/policies, custom groups allowed) with shallow-merge PATC\n[…]\n7→19.\nFull repo green (54/54 turbo test tasks; core 514 passed, 1 skipped),\ntypecheck 36/36, build 35/35, lint clean, drizzle drift check clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): retail operations pack — settings, documents, reports, on…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-02T08:58:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "230f405b9160c86f2626a900691bdc16444b73e1",
"body": "…c requirePerm, order/checkout idempotency\n\nFindings from studying ordereka-fashion-pos (first production adopter,\npinned to @porulle/core 0.1.0). Full evidence-grounded map committed at\n.understanding/ordereka-porulle-usage.md; remaining reconciled gaps filed\nas issues #47–#59.\n\n- config.routes(app\n[…]\nment-adapter\ncall-count proof). Full core suite green (494 passed, 1 skipped, 94 files);\ntypecheck clean; lint clean; drizzle drift check clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): ordereka field-study quick wins — auth in routes(), publi…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-01T23:07:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5c580c46bf9769e30e3a305ee74c1881c55cdf3f",
"body": "Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: changeset for admin/operator API gap fixes (#40–#46)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-01T22:35:28Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "8849231abbad6399046b48477cf8a1c0f57db11a",
"body": "Seven issues found while operating a store against @porulle/core 0.7.0.\n\n- #40 Fulfillment: POST /orders/{id}/fulfillments records a shipment for a\n subset of line items with carrier/trackingNumber/trackingUrl; supports\n partial + multiple fulfillments, validates against over-fulfillment, and\n re\n[…]\nsts). Full repo green\n(53/53 turbo test tasks; core 501 passed, 1 skipped), typecheck 36/36,\nbuild 34/34, lint clean, drizzle drift check clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: resolve admin/operator API gaps (#40–#46)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-01T22:34:06Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "fccd499054b0be7671b7d210c520dac932b7a993",
"body": null,
"is_bot": false,
"headline": "chore(release): version packages 0.7.0",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-01T19:52:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f2c20ec6ca43c5691a4794e2dbd45b065ca774c4",
"body": "fix: resolve admin-panel API gaps (#33–#38)",
"is_bot": false,
"headline": "Merge pull request #39 from asyncdotengineering/fix/triage-issues-33-38",
"author_name": "Mithushan Jalangan",
"author_login": "octalpixel",
"committed_at": "2026-07-01T19:50:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5dd324bc4a39d56a5c3b7daa07ee7e7453ba9abb",
"body": "Six issues found while building an admin panel against @porulle/core 0.6.0.\n\n- #33 Pricing: setBasePrice now upserts on the natural key instead of\n inserting a duplicate shadow row; ?include=pricing exposes id + createdAt\n so consumers can disambiguate the authoritative row.\n- #34 CSRF: the global\n[…]\nref.\n\nTests: 5 new issue regression suites (13 tests). Full core suite green\n(464 passed, 1 skipped); typecheck 36/36; lint clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: resolve admin-panel API gaps (#33–#38)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-07-01T17:02:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "332bd17feab9d4fe0259035a0af8a04c24bca422",
"body": "Cut by `changeset version`. Fixed @porulle/* group → 0.6.0; per-package\nCHANGELOGs generated. Headline change: fix(cli) scaffold version pinning (#32).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(release): version packages 0.6.0",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T19:08:36Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "dcc4fe98a476ae91d12a13495db20fe2e7d5dd2e",
"body": "The starter template carried static `^0.5.0` ranges that never tracked\nreleases; under 0.x caret semantics a project scaffolded by a newer CLI\nresolved a full minor behind. `init` now reads the running CLI's version\n(the @porulle/* fixed group's shared version) and rewrites every\n@porulle/* dependency in the scaffolded package.json to `^<that version>`.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(cli): pin scaffolded @porulle/* deps to the CLI's own version (#32)",
"author_name": "Mithushan Jalangan",
"author_login": "octalpixel",
"committed_at": "2026-06-14T19:07:00Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9915af04e41fad265c73d55416b6331a10143fcb",
"body": "pnpm strips the workspace: protocol to the depended-on package's *current*\npackage.json version at publish (workspace:* → 0.5.0), so internal deps can\nuse the workspace:* convention without the npm-leak (#24) or stale-lockfile\nfailure modes bun hit. Verified: pnpm pack of adapter-r2 emits\n\"@porulle/\n[…]\nEASING.md updated for pnpm.\n\nVerified under pnpm: check-types 36/36, build 34/34, core tests 451/1,\nfrozen-lockfile install clean.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(release): migrate package manager bun → pnpm (#31)",
"author_name": "Mithushan Jalangan",
"author_login": "octalpixel",
"committed_at": "2026-06-14T18:51:45Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "33a041b56bf2e7af670f2d25837b1873da66ec0c",
"body": "- release script: build filter ./packages/* → ./packages/** (the old filter\n matched only the 4 top-level packages and silently skipped every nested\n adapter/plugin/import, which would publish without a fresh dist). Also\n append `git push --follow-tags`.\n- version-packages: run `bun install` afte\n[…]\ne:; bun publish strips from a stale\n lockfile — both reproduced), the changeset version→publish flow, and the\n pnpm alternative.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(release): fix release scripts + document the proper flow",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T18:25:43Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d6c2f16efb82d07bdf07df9cd513d61a8972775a",
"body": "- Bump all @porulle/* publishable packages 0.1.0 → 0.5.0 (fixed-version group).\n- Rewrite internal @porulle/* deps (workspace:* / ^0.1.0 → ^0.5.0) so published\n manifests carry real ranges, not the workspace protocol npm can't resolve\n (the #24 class of bug). Includes the cli starter template.\n- CHANGELOG 0.5.0 entry; README de-alpha → beta (badge, tagline, Status).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: 0.5.0 — out of alpha",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T18:04:35Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "8e72faf5325eedbe62286b35283c0ab02f1b6226",
"body": "Close all 29 open issues + monorepo green sweep",
"is_bot": false,
"headline": "Merge pull request #30 from asyncdotengineering/triage/close-all-issues",
"author_name": "Mithushan Jalangan",
"author_login": "octalpixel",
"committed_at": "2026-06-14T17:52:52Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b2ec7d9922a59b00100d1b88485c8f183e8df3f2",
"body": "Under a full-monorepo `turbo run test`, ~6 PGlite (WASM Postgres) suites run\nin parallel and contend for CPU/memory, so a couple of core tests\nintermittently exceeded the 10s testTimeout (they finish in ~1-2s run alone,\nand the standalone core suite is consistently 451/1). The schema-push\nhookTimeou\n[…]\nder load. Not masking a perf regression — every affected test\npasses in isolation.\n\nAfter: full `turbo run test` is green (53/53).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "test(core): raise testTimeout to 30s for parallel-CI PGlite contention",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T17:47:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "89967f54e83d253170e86d2375be36a7394e9276",
"body": "…ripts\n\nseed.ts and full-flow.ts called catalog.addToCategory/addToBrand with only\n(entityId, categoryId) — but both require the authenticated actor as the 3rd\narg for the catalog:update permission check + org-scoping. Both scripts\nalready pass `staff` to every other catalog mutation (createCategory\n[…]\no\n`turbo run check-types` (the vitest gate doesn't type-check app scripts).\n\nAfter: the entire monorepo type-checks clean (36/36).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(store-example): pass actor to addToCategory/addToBrand in seed sc…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T17:39:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e8e251d053e9311b0fe8f42cab940c576b76eaae",
"body": "…ter (#12, #28)\n\nDocument the Workers deploy path end to end, tying together the seams that\nalready ship in @porulle/core:\n\n- #12: lazy per-isolate boot — build the config from env inside fetch() and\n memoize the server per isolate (createServer().runJobs() wired into\n scheduled()); BETTER_AUTH_SE\n[…]\nr\nhelpers are documented as recipes; the underlying config seams are all\nfirst-class, so no framework monkey-patching is required.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: Cloudflare Workers deploy recipe — lazy config + env-aware adap…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T17:23:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3d52e924d29275f679d85bf610cd10e6197c781b",
"body": "Capture the five day-one principles that prevent the most common app\nfoot-guns: cast-ban (parseJson), audit-on-mutation (auditMiddleware), no\nsilent money clamping, contract-named tests, and a single field-mappable\nerror envelope (err + mapApiErrorToFields). Each rule has a rationale, a\ncode example against the real @porulle/core / @porulle/sdk exports, and the\ncopy-pasteable cast-ban CI guard script. Linked from the README.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: day-one principles for Porulle apps (#19)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T17:23:37Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d2d5e010356cb6bd3aa7b507e378bdb5148b85cf",
"body": "The api-key create command already mints a long-lived key in-process (boots\nthe kernel, calls auth.api.createApiKey). Round it out to the make-key spec:\n\n- --ttl <seconds> → expiresIn, rejecting values below Better Auth's 1-day\n minExpiresIn with a clear message.\n- --user <id> → bind the key to a s\n[…]\n\n copy it now' note.\n\n(The command is , the CLI's canonical in-process\nkey minter — the make-key capability the issue describes.)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(cli): make-key flags (--ttl, --user) + curl/revoke output (#18)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T17:21:14Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e7865f4663974eb3d46c13b7420c79e842099038",
"body": "No way to record non-transactional customer interactions (visits, calls,\ninquiries, fittings, follow-ups) — the data that powers clienteling.\n\n- Schema: customer_interactions (org-scoped, customer_id FK cascade,\n actor_user_id, kind, notes, related_entity_id, metadata jsonb, at) +\n indexes. Auto-i\n[…]\n create → list → edit → delete round-trip; invalid kind rejected.\nFull core suite green (81 files / 451 passed); type-check clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): customer interaction log (clienteling notes) (#3)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T17:19:49Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "efe386a36272e09fde7bae9fdd5472897d972b3f",
"body": "…on (#5)\n\nPOS walk-ins have no Better Auth user, but the customer schema requires a\nuserId — forcing every integration to mint synthetic walk_* users.\n\n- CustomerService.createWalkIn(): userId is optional; when omitted, a\n synthetic anonymous_<uuid> id is generated and metadata.walkIn is set to\n t\n[…]\nta.walkIn=true;\ncreate with userId → bound to it, no walkIn flag. Full core suite green\n(80 files / 449 passed); type-check clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): POST /api/customers supports walk-in / userId-less creati…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T17:12:39Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "527c2b9507f84a71f01d05fac326133a01f994ae",
"body": "Categories had no status column, so consumers hacked metadata.archived;\nhard DELETE cascades entity_categories (products silently lose their\ncategory).\n\n- Schema: categories.status text NOT NULL DEFAULT 'active' (active|archived).\n Backwards-compatible — existing rows default to 'active'.\n- Categor\n[…]\n; DELETE works for\ncatalog:update; archive 403 without the scope. Full core suite green\n(79 files / 447 passed); type-check clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): category status + archive/restore endpoints (#22)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T17:08:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f0e1ddb0e9ac385d88f5a0410ea9f081fc191e09",
"body": "defineConfig already accepts ANY DatabaseAdapter (config.databaseAdapter),\nkernel.database.db is the generic adapter type (unknown — not pinned to\npostgres-js), and the PGlite adapter (a non-postgres-js driver) is injected\nacross the whole suite. Pin the contract with an explicit test: inject a\ncustom adapter, assert the kernel uses it (provider + driver flow through).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "test(core): pin custom DatabaseAdapter injection (#10)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T17:01:51Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "fa2aac76b27ffcdfd03be8c53b2e735a3fa76089",
"body": "The job-runner tick existed internally but wasn't reachable, so Workers\n(where in-process setInterval can't outlive a request) had no clean way to\ndrive the queue from scheduled().\n\n- createServer now returns runJobs(queue?, limit?), which runs the stale-job\n reaper then one runPendingJobs() pass a\n[…]\nr().runJobs() is callable and returns a processed/failed\nsummary. Full core suite green (77 files / 442 passed); type-check clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): expose server.runJobs() for serverless cron (#15)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T17:00:09Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ccada832952caecd7b6aa67720e7cc1a16d9b28e",
"body": "On Workers/edge, c.req.raw.socket.remoteAddress is always undefined, so\nevery client collapsed onto the rate-limit key 'unknown' — sharing one\nbucket globally (trivially DoS-able).\n\n- defineConfig({ runtime: { getClientIp, trustedProxyIp } }). The internal\n rate limiter resolves the client IP via c\n[…]\ne socket; X-Forwarded-For trusted only from the configured proxy.\nFull core suite green (76 files / 441 passed); type-check clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): injectable runtime.getClientIp for edge runtimes (#13)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T16:57:31Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b41a36b41e370694b2f2cc9c455ddf2b6cf15379",
"body": "Raw-SQL code that destructured db.execute(sql`...`) as an array worked on\npostgres-js but broke on neon-http / node-postgres / PGlite, which return\n{ rows, command, rowCount }.\n\n- createDatabaseConnection now wraps the adapter db (and transaction\n handles) in a Proxy that makes execute() always ret\n[…]\n keep their this-binding; unwrapDb round-trips to the raw driver.\nFull core suite green (75 files / 438 passed); type-check clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): normalize db.execute() result shape across drivers (#11)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T16:54:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "18512df3441c6e818489daaaa090a8b7f3c42e4f",
"body": "Receipt-less returns / support couldn't find an order from a phone or\nlast name. Add a fuzzy lookup that joins orders + customers.\n\n- OrdersRepository.lookup(): LEFT JOINs customers and ORs ILIKE matchers\n across order_number, customer email, first+last name, the walk-in label\n (metadata->>'custom\n[…]\nh-insensitive), by\npartial order number; <3 chars returns a hint. Full core suite green\n(74 files / 433 passed); type-check clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): fuzzy order lookup GET /api/orders/lookup (#4)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T16:46:18Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5be7f4274c6eb2523f1601e860da4f8b7183a24a",
"body": "The endpoint returned a flat order array; every customer-profile UI then\nre-fetched all rows to compute lifetime spend. Add an opt-in server-side\nrollup.\n\n- ?include=totals wraps the response as { data: { items, totals } } with\n totals = { count, lifetimeSpend, averageBasket }. lifetimeSpend exclud\n[…]\n, averageBasket:5000 } with a\nrefunded order excluded from spend. Full core suite green (73 files /\n429 passed); type-check clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): GET /api/customers/:id/orders ?include=totals rollup (#2)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T16:41:55Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1c7ade287e2cdbd05c501ed1b95efd45c9bad5bc",
"body": "… (#7)\n\nPOST /api/inventory/adjust only took a signed adjustment and returned an\nopaque level. Add ergonomic modes and a confirmable result.\n\n- Body gains optional mode (add|remove|set) on an unsigned amount; mode\n omitted ⇒ legacy signed adjustment (unchanged). remove clamps at 0; set\n writes the\n[…]\ny adjustment still works. Existing inventory suite\ngreen (12/12); full core suite green (72 files / 427 passed); type-check\nclean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): inventory adjust mode=add|remove|set + before/after/delta…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T16:38:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c6c3f981e738574b58555b28ed2582aa998f78f7",
"body": "PATCH replaced the whole metadata jsonb, so a single-key edit required a\nread-modify-write round-trip and could lose concurrent updates.\n\n- CustomerService.update() now shallow-merges top-level metadata keys with\n the existing blob by default; pass { replaceMetadata: true } to overwrite.\n- Route ho\n[…]\nover { a,b } yields { a,b',c }; ?metadataReplace=true\noverwrites. Full core suite green (71 files / 423 passed); type-check clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): PATCH /api/customers/:id shallow-merges metadata (#8)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T16:32:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "aad8d26419d565f404146f9466ff003f7ddd2608",
"body": "Promotions supported create/validate/deactivate but no general edit, so\nevery integration wrote raw SQL that bypassed the create-time validation.\n\n- PromotionService.update(orgId, id, input): edits any subset of the\n create body, re-running the same validation (value >= 0, type enum,\n code uniquen\n[…]\nions:manage (403). Existing promotions\nsuite still green (15/15); full core suite green (70 files / 421 passed);\ntype-check clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): PATCH /api/promotions/:id to edit promotions (#6)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T16:27:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ff2938d6f2a105667657f2898b355622dde5cc1a",
"body": "createKernel() hard-required storage and threw at boot when config.storage\nwas unset, forcing every catalog-only consumer (and every Workers deploy,\nwhich has no shipped storage adapter) to hand-roll a stub just to start.\n\n- Add noopStorageAdapter (providerId 'noop'): getUrl passes the key\n through\n[…]\nract (getUrl passthrough, upload unsupported);\nupload route returns 501 under noop. Full core suite green (69 files /\n417 passed).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): default to a no-op StorageAdapter when none configured (#27)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T16:21:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "685613b3a31f300555fc04aa022cfeb0c33a9e48",
"body": "server.ts hardcoded a global 1MB bodyLimit on \"*\", which blocked\nPOST /api/media/upload (phone photos are 3-8MB) before the request ever\nreached the route.\n\n- /api/media/upload gets its own bodyLimit (config.media.maxUploadSize,\n default 10MB) returning 413 FILE_TOO_LARGE on overflow.\n- The global \n[…]\nILE_TOO_LARGE; a 2MB POST to a non-media route still returns\n413 PAYLOAD_TOO_LARGE. Full core suite green (68 files / 414 passed).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(core): exempt media upload from global 1MB body limit (#21)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T16:16:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1d7b90489672425fbc0ee66d1d833e8dc49b9050",
"body": "Audit-row writes were scattered across handlers and easy to forget on new\nroutes. Add a Hono middleware that writes exactly one commerce_audit_log\nrow per successful (2xx) state-changing request.\n\n- auditMiddleware(kernel) exported from @porulle/core; one-line opt-in:\n app.use('*', auditMiddleware(\n[…]\nrites nothing; non-2xx writes nothing;\nhandler overrides honored. Full core suite green (67 files / 411 passed);\ntype-check clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): auditMiddleware() — audit-by-default on 2xx mutations (#16)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T16:12:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3314ee949a25da97e902c058744ce874b89a060b",
"body": "…ers (#17)\n\nReplace the unsafe (await c.req.json()) as T pattern with a validated,\nfield-mappable pipeline.\n\ncore:\n- parseJson<S>(c, schema): returns z.infer<S> or a 422 Response carrying\n { error: { code: VALIDATION_FAILED, message, details: { issues[] } } };\n malformed JSON returns 422 (not 500)\n[…]\nnvelope) and\nsdk errors (guard / flatten / no-issues). Full core suite green\n(66 files / 407 passed); core + sdk type-check clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core,sdk): parseJson() + details.issues[] envelope + client mapp…",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T16:08:22Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8760cd0673935843f366918b3ab104ae37e370cb",
"body": "…(#1)\n\nWhen auth.apiKeyScopes defines named scopes and none is 'default', every\nkey minted under a named scope failed the auth middleware with a silent\n401. The middleware called verifyApiKey without a configId; Better Auth's\napiKey plugin then (a) threw NO_DEFAULT_API_KEY_CONFIGURATION_FOUND in\nget\n[…]\n scope (no 'default' scope), and asserts it resolves to an api_key\nactor (was 401). Full core suite green (65 files / 403 passed).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(auth): forward configId in verifyApiKey so named-scope keys auth …",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T16:03:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7911c6c1068d85180165e2fb2727a00897df52dc",
"body": "The promotion type enum was duplicated three ways (inline z.enum in the\nbody schema, a hand-written union in service.ts, and a literal validTypes\narray) and exported from none of the public surfaces, so consumers\nguessed values and got 400s.\n\n- Extract promotionTypeEnum in promotions/schemas.ts as t\n[…]\n to avoid pulling the kernel into frontend bundles —\nthe issue allows 'or equivalent'; the OpenAPI enum feeds SDK-generated\ntypes.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): export PromotionType union + single-source the enum (#23)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T15:57:08Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "804bc26650c0354f06cc346a7d338f0d9b7cbde8",
"body": "The 'create your first product' SDK snippet posted to /api/admin/entities\nwith a {name, fields, variants[]} body — neither the route nor that body\nshape exists in the shipped server. Rewrite against the verified surface:\n\n- POST /api/catalog/entities with {type, slug, basePrice, currency,\n attribut\n[…]\nck\n- POST /api/catalog/entities/{id}/publish to publish\n- note that variants are created via the option/variant routes, not inline\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(readme): fix quick-start to real /api/catalog surface (#29)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T15:53:59Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ca728ff14a9b4f13e0446202ed57fe2ba2f1c75e",
"body": "mediaAssets, entityMedia and auditLog (commerce_audit_log) are already\nre-exported from @porulle/core/schema in current source (the gap reported\nagainst 0.1.0 was fixed before this commit). Add a regression test so the\npublic schema surface can't silently drop these tables again.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "test(core): pin media + audit schema re-exports from /schema (#20)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T15:50:47Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a1f24040a7ea48e850f4f0d0870527b88707f76b",
"body": "The migrate module's docstring promised npm consumers getSchemaFiles()\nand pushSchema(), but neither was implemented or exported — the public\nentry only re-exported getSchema/buildSchema/getTableNames, so the\ndocumented drizzle.config.ts recipe couldn't be written and there was no\nprogrammatic schem\n[…]\nontract test imports both from the package entry and verifies\n pushSchema() actually creates sellable_entities in a fresh PGlite.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(core): implement & export getSchemaFiles() and pushSchema() (#26)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T15:49:54Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "13505dd8d1faf66bedfb5893e0e62a0e4c14e686",
"body": "@porulle/cli declared @porulle/import-{flat,shopify,woocommerce} as\nworkspace:* dependencies. workspace:* must never appear in a published\nmanifest, so any registry install of the CLI failed to resolve — which\naborted the whole install, breaking the documented 'bunx @porulle/cli\ninit' path.\n\n- Move \n[…]\nots even when an adapter isn't installed; a missing adapter\n yields a clear 'bun add <pkg>' message instead of a load-time crash.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(cli): lazy-load import adapters; move to optionalDependencies (#24)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T15:47:32Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4a634ca779aaa60376a14d71d4e465c18565cc38",
"body": "@porulle/core imports @better-auth/api-key in auth/setup.ts but only\ndeclared it in devDependencies, so clean/isolated installs (bun default,\npnpm without hoisting, Yarn PnP) threw 'Cannot find module\n@better-auth/api-key' at createServer(). Move it to dependencies,\nversion-aligned with the better-auth ^1.3.8 range.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(core): declare @better-auth/api-key as a runtime dependency (#25)",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-06-14T15:43:55Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "df8788277123ba6578831c100a7ee82a9f1a1f3c",
"body": "Headless commerce framework for TypeScript. REST-only, security-hardened\n(post-VAPT), self-host-first. 32 packages published to @porulle/* on npm\n— core kernel, adapters (Postgres / Stripe / S3 / R2 / Resend / SES /\nMeilisearch / TaxJar / Tax-Manual), plugins (POS, gift cards, supply\nchain, marketpl\n[…]\nttps://porulle-docs.vercel.app\nnpm: https://www.npmjs.com/org/porulle\n\nActive development. Alpha-grade. Straight out of the oven.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Initial commit — Porulle v0.1.0 alpha",
"author_name": "octalpixel",
"author_login": "octalpixel",
"committed_at": "2026-05-11T21:13:06Z",
"body_truncated": true,
"is_coding_agent": true
}
],
"releases_count": 2,
"commits_last_year": 96,
"latest_release_at": "2026-06-14T19:10:29Z",
"latest_release_tag": "v0.6.0",
"releases_from_tags": false,
"days_since_last_push": 5,
"active_weeks_last_year": 5,
"days_since_latest_release": 39,
"mean_days_between_releases": 0
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 62,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "@porulle/db",
"exists": true,
"license": "MIT",
"keywords": [],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/@porulle/db",
"is_deprecated": false,
"latest_version": "0.10.4",
"repository_url": "https://github.com/asyncdotengineering/porulle",
"versions_count": 11,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 1409,
"first_published_at": "2026-05-10T20:48:09.900000Z",
"latest_published_at": "2026-07-18T18:05:36.560000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 5
},
{
"name": "@porulle/cli",
"exists": true,
"license": "MIT",
"keywords": [],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/@porulle/cli",
"is_deprecated": false,
"latest_version": "0.10.4",
"repository_url": "https://github.com/asyncdotengineering/porulle",
"versions_count": 11,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 1248,
"first_published_at": "2026-05-10T20:48:09.673000Z",
"latest_published_at": "2026-07-18T18:05:36.383000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 5
},
{
"name": "@porulle/sdk",
"exists": true,
"license": "MIT",
"keywords": [],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/@porulle/sdk",
"is_deprecated": false,
"latest_version": "0.10.4",
"repository_url": "https://github.com/asyncdotengineering/porulle",
"versions_count": 11,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 1182,
"first_published_at": "2026-05-10T20:48:19.033000Z",
"latest_published_at": "2026-07-18T18:05:43.070000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 5
},
{
"name": "@porulle/core",
"exists": true,
"license": "MIT",
"keywords": [],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/@porulle/core",
"is_deprecated": false,
"latest_version": "0.10.4",
"repository_url": "https://github.com/asyncdotengineering/porulle",
"versions_count": 11,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 4194,
"first_published_at": "2026-05-10T20:48:11.640000Z",
"latest_published_at": "2026-07-18T18:05:38.664000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 5
},
{
"name": "@porulle/jobs-inngest",
"exists": true,
"license": "MIT",
"keywords": [],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/@porulle/jobs-inngest",
"is_deprecated": false,
"latest_version": "0.10.4",
"repository_url": "https://github.com/asyncdotengineering/porulle",
"versions_count": 6,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 778,
"first_published_at": "2026-07-18T10:51:34.322000Z",
"latest_published_at": "2026-07-18T18:05:38.336000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 5
},
{
"name": "@porulle/jobs-pg-boss",
"exists": true,
"license": "MIT",
"keywords": [],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/@porulle/jobs-pg-boss",
"is_deprecated": false,
"latest_version": "0.10.4",
"repository_url": "https://github.com/asyncdotengineering/porulle",
"versions_count": 6,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 766,
"first_published_at": "2026-07-18T10:51:34.312000Z",
"latest_published_at": "2026-07-18T18:05:38.457000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 5
},
{
"name": "@porulle/jobs-trigger",
"exists": true,
"license": "MIT",
"keywords": [],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/@porulle/jobs-trigger",
"is_deprecated": false,
"latest_version": "0.10.4",
"repository_url": "https://github.com/asyncdotengineering/porulle",
"versions_count": 6,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 738,
"first_published_at": "2026-07-18T10:51:34.969000Z",
"latest_published_at": "2026-07-18T18:05:39.447000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 5
},
{
"name": "@porulle/jobs-cloudflare",
"exists": true,
"license": "MIT",
"keywords": [],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/@porulle/jobs-cloudflare",
"is_deprecated": false,
"latest_version": "0.10.4",
"repository_url": "https://github.com/asyncdotengineering/porulle",
"versions_count": 6,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 763,
"first_published_at": "2026-07-18T10:51:35.182000Z",
"latest_published_at": "2026-07-18T18:05:38.363000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 5
}
]
},
"popularity": {
"forks": 0,
"stars": 0,
"watchers": 0,
"fork_history": {
"days": [],
"complete": true,
"collected": 0,
"total_forks": 0
},
"star_history": {
"days": [],
"complete": true,
"collected": 0,
"total_stars": 0,
"collected_at": null
},
"open_issues_and_prs": 0
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": true,
"has_mcp_signal": true,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [
"apps/docs/public/scaffold/tsconfig.json",
"apps/docs/tsconfig.json",
"apps/restaurant-example/tsconfig.json",
"apps/saas-example/tsconfig.json",
"apps/store-example/tsconfig.json",
"apps/tea-avenue/tsconfig.json",
"apps/web/tsconfig.json",
"packages/adapters/adapter-local-storage/tsconfig.json",
"packages/adapters/adapter-meilisearch/tsconfig.json",
"packages/adapters/adapter-neon/tsconfig.json",
"packages/adapters/adapter-pg-search/tsconfig.json",
"packages/adapters/adapter-pglite/tsconfig.json",
"packages/adapters/adapter-postgres/tsconfig.json",
"packages/adapters/adapter-r2/tsconfig.json",
"packages/adapters/adapter-resend/tsconfig.json",
"packages/adapters/adapter-s3/tsconfig.json",
"packages/adapters/adapter-ses/tsconfig.json",
"packages/adapters/adapter-shopify/tsconfig.json",
"packages/adapters/adapter-stripe/tsconfig.json",
"packages/adapters/adapter-tax-manual/tsconfig.json",
"packages/adapters/adapter-taxjar/tsconfig.json",
"packages/adapters/adapter-woocommerce/tsconfig.json",
"packages/cli/templates/starter/tsconfig.json",
"packages/cli/tsconfig.json",
"packages/core/tsconfig.json",
"packages/db/tsconfig.json",
"packages/import/import-flat/tsconfig.json",
"packages/import/import-shopify/tsconfig.json",
"packages/import/import-woocommerce/tsconfig.json",
"packages/jobs-cloudflare/tsconfig.json",
"packages/jobs-inngest/tsconfig.json",
"packages/jobs-pg-boss/tsconfig.json",
"packages/jobs-trigger/tsconfig.json",
"packages/plugins/plugin-appointments/tsconfig.json",
"packages/plugins/plugin-channel-connector/tsconfig.json",
"packages/plugins/plugin-gift-cards/tsconfig.json",
"packages/plugins/plugin-layaway/tsconfig.json",
"packages/plugins/plugin-loyalty/tsconfig.json",
"packages/plugins/plugin-marketplace/tsconfig.json",
"packages/plugins/plugin-notifications/tsconfig.json",
"packages/plugins/plugin-pos-restaurant/tsconfig.json",
"packages/plugins/plugin-pos/tsconfig.json",
"packages/plugins/plugin-procurement/tsconfig.json",
"packages/plugins/plugin-production/tsconfig.json",
"packages/plugins/plugin-reviews/tsconfig.json",
"packages/plugins/plugin-scheduled-orders/tsconfig.json",
"packages/plugins/plugin-uom/tsconfig.json",
"packages/plugins/plugin-warehouse/tsconfig.json",
"packages/plugins/plugin-wishlist/tsconfig.json",
"packages/sdk/tsconfig.json"
],
"toolchain_manifests": [],
"largest_source_bytes": 59740,
"source_files_sampled": 804,
"oversized_source_files": 0,
"agent_instruction_files": [
".agents/factory/workers/claude.md",
".archive/research/AGENTS.md",
"CLAUDE.md"
],
"agent_instruction_max_bytes": 13046
},
"dependencies": {
"manifests": [
"package.json"
],
"advisories": {
"error": null,
"scope": "published_package",
"source": "osv",
"findings": [],
"collected": true,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 57,
"malicious_count": 0,
"assessed_package": "npm:@porulle/db@0.10.4",
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"npm"
],
"dependencies": [
{
"name": "@hono/node-server",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "^1.14.3"
},
{
"name": "@porulle/adapter-local-storage",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/adapter-postgres",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/core",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-pos",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-pos-restaurant",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-uom",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-procurement",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-warehouse",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-production",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-notifications",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-scheduled-orders",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-reviews",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "hono",
"manifest": "apps/restaurant-example/package.json",
"ecosystem": "npm",
"version_constraint": "^4.12.5"
},
{
"name": "@hono/node-server",
"manifest": "apps/saas-example/package.json",
"ecosystem": "npm",
"version_constraint": "^1.19.6"
},
{
"name": "@porulle/adapter-local-storage",
"manifest": "apps/saas-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/adapter-postgres",
"manifest": "apps/saas-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/core",
"manifest": "apps/saas-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@faker-js/faker",
"manifest": "apps/store-example/package.json",
"ecosystem": "npm",
"version_constraint": "^10.3.0"
},
{
"name": "@hono/node-server",
"manifest": "apps/store-example/package.json",
"ecosystem": "npm",
"version_constraint": "^1.19.6"
},
{
"name": "@hono/zod-openapi",
"manifest": "apps/store-example/package.json",
"ecosystem": "npm",
"version_constraint": "^1.2.2"
},
{
"name": "hono",
"manifest": "apps/store-example/package.json",
"ecosystem": "npm",
"version_constraint": "^4.9.8"
},
{
"name": "@porulle/adapter-local-storage",
"manifest": "apps/store-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/adapter-postgres",
"manifest": "apps/store-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/core",
"manifest": "apps/store-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-loyalty",
"manifest": "apps/store-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-wishlist",
"manifest": "apps/store-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-reviews",
"manifest": "apps/store-example/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@hono/node-server",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "^1.14.3"
},
{
"name": "@porulle/adapter-local-storage",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/adapter-postgres",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/core",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-pos",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-pos-restaurant",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-uom",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-procurement",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-warehouse",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-production",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-loyalty",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-notifications",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-scheduled-orders",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-reviews",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/plugin-wishlist",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "hono",
"manifest": "apps/tea-avenue/package.json",
"ecosystem": "npm",
"version_constraint": "^4.12.5"
},
{
"name": "next",
"manifest": "apps/web/package.json",
"ecosystem": "npm",
"version_constraint": "16.1.5"
},
{
"name": "react",
"manifest": "apps/web/package.json",
"ecosystem": "npm",
"version_constraint": "^19.2.0"
},
{
"name": "react-dom",
"manifest": "apps/web/package.json",
"ecosystem": "npm",
"version_constraint": "^19.2.0"
},
{
"name": "postgres",
"manifest": "packages/cli/package.json",
"ecosystem": "npm",
"version_constraint": "^3.4.7"
},
{
"name": "citty",
"manifest": "packages/cli/package.json",
"ecosystem": "npm",
"version_constraint": "^0.1.6"
},
{
"name": "consola",
"manifest": "packages/cli/package.json",
"ecosystem": "npm",
"version_constraint": "^3.4.2"
},
{
"name": "giget",
"manifest": "packages/cli/package.json",
"ecosystem": "npm",
"version_constraint": "^2.0.0"
},
{
"name": "@better-auth/api-key",
"manifest": "packages/core/package.json",
"ecosystem": "npm",
"version_constraint": "^1.3.8"
},
{
"name": "@better-auth/drizzle-adapter",
"manifest": "packages/core/package.json",
"ecosystem": "npm",
"version_constraint": "^1.3.8"
},
{
"name": "@hono/zod-openapi",
"manifest": "packages/core/package.json",
"ecosystem": "npm",
"version_constraint": "^1.2.2"
},
{
"name": "@scalar/hono-api-reference",
"manifest": "packages/core/package.json",
"ecosystem": "npm",
"version_constraint": "^0.10.5"
},
{
"name": "better-auth",
"manifest": "packages/core/package.json",
"ecosystem": "npm",
"version_constraint": "^1.3.8"
},
{
"name": "drizzle-orm",
"manifest": "packages/core/package.json",
"ecosystem": "npm",
"version_constraint": "^0.45.1"
},
{
"name": "drizzle-zod",
"manifest": "packages/core/package.json",
"ecosystem": "npm",
"version_constraint": "^0.8.3"
},
{
"name": "hono",
"manifest": "packages/core/package.json",
"ecosystem": "npm",
"version_constraint": "^4.9.8"
},
{
"name": "hono-rate-limiter",
"manifest": "packages/core/package.json",
"ecosystem": "npm",
"version_constraint": "^0.5.3"
},
{
"name": "pino",
"manifest": "packages/core/package.json",
"ecosystem": "npm",
"version_constraint": "^10.3.1"
},
{
"name": "zod",
"manifest": "packages/core/package.json",
"ecosystem": "npm",
"version_constraint": "^4.1.11"
},
{
"name": "@porulle/core",
"manifest": "packages/db/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "drizzle-orm",
"manifest": "packages/db/package.json",
"ecosystem": "npm",
"version_constraint": "^0.45.1"
},
{
"name": "postgres",
"manifest": "packages/db/package.json",
"ecosystem": "npm",
"version_constraint": "^3.4.7"
},
{
"name": "@porulle/core",
"manifest": "packages/jobs-cloudflare/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@porulle/core",
"manifest": "packages/jobs-inngest/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "inngest",
"manifest": "packages/jobs-inngest/package.json",
"ecosystem": "npm",
"version_constraint": "^4.13.0"
},
{
"name": "@porulle/core",
"manifest": "packages/jobs-pg-boss/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "pg-boss",
"manifest": "packages/jobs-pg-boss/package.json",
"ecosystem": "npm",
"version_constraint": "^12.26.1"
},
{
"name": "@porulle/core",
"manifest": "packages/jobs-trigger/package.json",
"ecosystem": "npm",
"version_constraint": "workspace:*"
},
{
"name": "@trigger.dev/sdk",
"manifest": "packages/jobs-trigger/package.json",
"ecosystem": "npm",
"version_constraint": "^4.5.4"
},
{
"name": "openapi-fetch",
"manifest": "packages/sdk/package.json",
"ecosystem": "npm",
"version_constraint": "^0.17.0"
},
{
"name": "openapi-typescript-helpers",
"manifest": "packages/sdk/package.json",
"ecosystem": "npm",
"version_constraint": "^0.1.0"
}
],
"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": 13,
"open_issues": 0,
"closed_ratio": 1,
"closed_issues": 55,
"closed_unmerged_prs": 0
},
"bus_factor": 1,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "octalpixel",
"commits": 96,
"avatar_url": "https://avatars.githubusercontent.com/u/30002284?v=4"
}
],
"contributors_sampled": 1,
"top_contributor_share": 1
},
"quality_signals": {
"has_ci": false,
"has_tests": true,
"ci_workflows": [],
"has_docs_dir": true,
"linter_configs": [
"eslint.config.js",
"eslint.config.mjs"
],
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"pnpm-lock.yaml"
],
"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": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 0,
"reason": "0 out of 9 merged PRs checked by a CI test -- score normalized to 0",
"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": 0,
"reason": "Found 0/13 approved changesets -- score normalized to 0",
"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": null,
"reason": "no workflows found",
"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": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 0,
"reason": "project was created within the last 90 days. Please review its contents carefully",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": null,
"reason": "packaging workflow not 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": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": null,
"reason": "No tokens found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 0,
"reason": "54 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "017b18c2077d3e5401116ba6245b5b2d6183457e",
"ran_at": "2026-07-24T03:58:43Z",
"aggregate_score": 2.1,
"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": null,
"oldest_open_prs": [],
"last_merged_pr_at": "2026-07-18T18:03:02Z",
"ci_last_conclusion": null,
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/asyncdotengineering/porulle",
"host": "github.com",
"name": "porulle",
"owner": "asyncdotengineering"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 54,
"inputs": {
"security": 37,
"vitality": 74,
"community": 35,
"governance": 56,
"engineering": 60
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "good",
"name": "Vitality",
"value": 74,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "moderate",
"name": "Development activity",
"note": null,
"notes": [],
"value": 57,
"inputs": {
"commits_last_year": 96,
"human_commit_share": 1,
"days_since_last_push": 5,
"active_weeks_last_year": 5
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 5 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 5
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "5/52 weeks with commits",
"points": 3.5,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 5
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "96 commits in the last year",
"points": 17.8,
"status": "partial",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 96
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 100,
"inputs": {
"releases_count": 2,
"latest_release_tag": "v0.6.0",
"releases_from_tags": false,
"days_since_latest_release": 39,
"mean_days_between_releases": 0
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "2 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 2
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 39 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 39
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~0 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 0
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"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": "at_risk",
"name": "Community & Adoption",
"value": 35,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 1,
"inputs": {
"forks": 0,
"stars": 0,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "0 stars",
"points": 0,
"status": "missed",
"details": [
{
"code": "stars",
"params": {
"count": 0
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "0 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 0
}
}
],
"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": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (MIT)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "MIT"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
},
{
"key": "ecosystem_adoption",
"band": "moderate",
"name": "Ecosystem adoption (downloads)",
"note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"registry_dependents"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 67,
"inputs": {
"packages": [
"@porulle/db",
"@porulle/cli",
"@porulle/sdk",
"@porulle/core",
"@porulle/jobs-inngest",
"@porulle/jobs-pg-boss",
"@porulle/jobs-trigger",
"@porulle/jobs-cloudflare"
],
"dependents": null,
"ecosystems": "npm",
"total_downloads": null,
"monthly_downloads": 11078
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "11,078 downloads/month across npm",
"points": 53.9,
"status": "partial",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 11078,
"ecosystems": "npm"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "not reported by this ecosystem",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_reported_by_this_ecosystem",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 56,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 13,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 1,
"top_contributor_share": 1
},
"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 100% of commits",
"points": 0,
"status": "missed",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 100
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "1 contributors",
"points": 1.4,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 1
}
}
],
"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": "excellent",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"merged_prs": 13,
"open_issues": 0,
"closed_issues": 55,
"issue_closed_ratio": 1,
"closed_unmerged_prs": 0
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "100% of issues closed",
"points": 46.8,
"status": "met",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 100
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "13/13 decided PRs merged",
"points": 38.2,
"status": "met",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 13,
"decided": 13
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/13 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "at_risk",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 44,
"inputs": {
"followers": 0,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "asyncdotengineering",
"public_repos": 9,
"account_age_days": 1197
},
"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": "0 followers of asyncdotengineering",
"points": 0,
"status": "missed",
"details": [
{
"code": "owner_followers",
"params": {
"count": 0,
"login": "asyncdotengineering"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "9 public repos, account ~3 yr old",
"points": 13.8,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 9
}
},
{
"code": "account_age_years",
"params": {
"years": 3
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"@porulle/db",
"@porulle/cli",
"@porulle/sdk",
"@porulle/core",
"@porulle/jobs-inngest",
"@porulle/jobs-pg-boss",
"@porulle/jobs-trigger",
"@porulle/jobs-cloudflare"
],
"ecosystems": "npm",
"any_deprecated": false,
"min_days_since_publish": 5
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "8 package(s) on npm",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 8,
"ecosystems": "npm"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 5 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 5
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "11 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 11
}
}
],
"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": "moderate",
"name": "Engineering Quality",
"value": 60,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "at_risk",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"has_ci": false,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": true,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"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": "eslint.config.js, eslint.config.mjs",
"points": 16,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "eslint.config.js, eslint.config.mjs"
}
}
],
"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": "0 out of 9 merged PRs checked by a CI test -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "excellent",
"name": "Documentation",
"note": null,
"notes": [],
"value": 90,
"inputs": {
"topics": [],
"has_wiki": true,
"homepage": "https://porulle-docs.vercel.app",
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": "https://porulle-docs.vercel.app",
"points": 15,
"status": "met",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "at_risk",
"name": "Security",
"value": 37,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "critical",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): Dangerous-Workflow, Packaging, Signed-Releases, Token-Permissions. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"dangerous_workflow",
"packaging",
"signed_releases",
"token_permissions"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 21,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 14,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 4,
"scorecard_aggregate": 2.1
},
"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": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "0 out of 9 merged PRs checked by a CI test -- score normalized to 0",
"points": 0,
"status": "missed",
"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 0/13 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"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 workflows found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"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.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow not detected",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"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": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "No tokens found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "54 existing vulnerabilities detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "dependency_advisories",
"band": "excellent",
"name": "Dependency advisories",
"note": "Excluded from scoring (no data or not applicable): No advisories left outstanding. Remaining weights renormalized. Matched the npm:@porulle/db@0.10.4 runtime dependency closure — what installing the published package pulls in — 57 packages. Reachability is not analyzed.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"no_advisories_left_outstanding"
]
}
},
{
"code": "weights_renormalized",
"params": {}
},
{
"code": "advisories_scope_published",
"params": {
"package": "npm:@porulle/db@0.10.4",
"assessed": 57
}
},
{
"code": "advisories_reachability",
"params": {}
}
],
"value": 100,
"inputs": {
"source": "osv",
"advisories": 0,
"affected_packages": 0,
"assessed_packages": 57,
"unassessed_packages": 0,
"affected_by_severity": "none",
"direct_affected_packages": 0
},
"components": [
{
"key": "direct_dependencies_free_of_known_advisories",
"name": "Direct dependencies free of known advisories",
"detail": "no direct dependency carries a known advisory",
"points": 35,
"status": "met",
"details": [
{
"code": "no_direct_advisories",
"params": {}
}
],
"max_points": 35
},
{
"key": "indirect_dependencies_free_of_known_advisories",
"name": "Indirect dependencies free of known advisories",
"detail": "no indirect dependency carries a known advisory",
"points": 25,
"status": "met",
"details": [
{
"code": "no_indirect_advisories",
"params": {}
}
],
"max_points": 25
},
{
"key": "no_advisories_left_outstanding",
"name": "No advisories left outstanding",
"detail": "no advisory carries a publication date",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_no_publication_date",
"params": {}
}
],
"max_points": 40
}
]
},
{
"key": "malicious_dependencies",
"band": "excellent",
"name": "Malicious dependencies",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"source": "osv",
"meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
"packages": [],
"red_flag": false,
"assessed_packages": 57,
"malicious_packages": 0,
"direct_malicious_packages": 0,
"withdrawn_malicious_packages": 0,
"installable_malicious_packages": 0
},
"components": [
{
"key": "no_dependency_reported_as_a_malicious_package",
"name": "No dependency reported as a malicious package",
"detail": "no dependency is reported as a malicious package",
"points": 100,
"status": "met",
"details": [
{
"code": "no_malicious_dependencies",
"params": {}
}
],
"max_points": 100
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "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": "moderate",
"name": "AI Readiness",
"value": 69,
"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/factory/workers/claude.md",
".archive/research/AGENTS.md",
"CLAUDE.md"
],
"agent_instruction_max_bytes": 13046
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": ".agents/factory/workers/claude.md, .archive/research/AGENTS.md, CLAUDE.md",
"points": 45,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": ".agents/factory/workers/claude.md, .archive/research/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": "96 of 96 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 96,
"sampled": 96
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "moderate",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 64,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"pnpm-lock.yaml"
],
"has_dockerfile": true,
"typed_language": true,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": true,
"typecheck_configs": [
"apps/docs/public/scaffold/tsconfig.json",
"apps/docs/tsconfig.json",
"apps/restaurant-example/tsconfig.json",
"apps/saas-example/tsconfig.json",
"apps/store-example/tsconfig.json",
"apps/tea-avenue/tsconfig.json",
"apps/web/tsconfig.json",
"packages/adapters/adapter-local-storage/tsconfig.json",
"packages/adapters/adapter-meilisearch/tsconfig.json",
"packages/adapters/adapter-neon/tsconfig.json",
"packages/adapters/adapter-pg-search/tsconfig.json",
"packages/adapters/adapter-pglite/tsconfig.json",
"packages/adapters/adapter-postgres/tsconfig.json",
"packages/adapters/adapter-r2/tsconfig.json",
"packages/adapters/adapter-resend/tsconfig.json",
"packages/adapters/adapter-s3/tsconfig.json",
"packages/adapters/adapter-ses/tsconfig.json",
"packages/adapters/adapter-shopify/tsconfig.json",
"packages/adapters/adapter-stripe/tsconfig.json",
"packages/adapters/adapter-tax-manual/tsconfig.json",
"packages/adapters/adapter-taxjar/tsconfig.json",
"packages/adapters/adapter-woocommerce/tsconfig.json",
"packages/cli/templates/starter/tsconfig.json",
"packages/cli/tsconfig.json",
"packages/core/tsconfig.json",
"packages/db/tsconfig.json",
"packages/import/import-flat/tsconfig.json",
"packages/import/import-shopify/tsconfig.json",
"packages/import/import-woocommerce/tsconfig.json",
"packages/jobs-cloudflare/tsconfig.json",
"packages/jobs-inngest/tsconfig.json",
"packages/jobs-pg-boss/tsconfig.json",
"packages/jobs-trigger/tsconfig.json",
"packages/plugins/plugin-appointments/tsconfig.json",
"packages/plugins/plugin-channel-connector/tsconfig.json",
"packages/plugins/plugin-gift-cards/tsconfig.json",
"packages/plugins/plugin-layaway/tsconfig.json",
"packages/plugins/plugin-loyalty/tsconfig.json",
"packages/plugins/plugin-marketplace/tsconfig.json",
"packages/plugins/plugin-notifications/tsconfig.json",
"packages/plugins/plugin-pos-restaurant/tsconfig.json",
"packages/plugins/plugin-pos/tsconfig.json",
"packages/plugins/plugin-procurement/tsconfig.json",
"packages/plugins/plugin-production/tsconfig.json",
"packages/plugins/plugin-reviews/tsconfig.json",
"packages/plugins/plugin-scheduled-orders/tsconfig.json",
"packages/plugins/plugin-uom/tsconfig.json",
"packages/plugins/plugin-warehouse/tsconfig.json",
"packages/plugins/plugin-wishlist/tsconfig.json",
"packages/sdk/tsconfig.json"
],
"agent_commit_share": 0.76,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": "eslint.config.js, eslint.config.mjs",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "eslint.config.js, eslint.config.mjs"
}
}
],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "apps/docs/public/scaffold/tsconfig.json, apps/docs/tsconfig.json, apps/restaurant-example/tsconfig.json, apps/saas-example/tsconfig.json, apps/store-example/tsconfig.json, apps/tea-avenue/tsconfig.json, apps/web/tsconfig.json, packages/adapters/adapter-local-storage/tsconfig.json, packages/adapters/adapter-meilisearch/tsconfig.json, packages/adapters/adapter-neon/tsconfig.json, packages/adapters/adapter-pg-search/tsconfig.json, packages/adapters/adapter-pglite/tsconfig.json, packages/adapters/adapter-postgres/tsconfig.json, packages/adapters/adapter-r2/tsconfig.json, packages/adapters/adapter-resend/tsconfig.json, packages/adapters/adapter-s3/tsconfig.json, packages/adapters/adapter-ses/tsconfig.json, packages/adapters/adapter-shopify/tsconfig.json, packages/adapters/adapter-stripe/tsconfig.json, packages/adapters/adapter-tax-manual/tsconfig.json, packages/adapters/adapter-taxjar/tsconfig.json, packages/adapters/adapter-woocommerce/tsconfig.json, packages/cli/templates/starter/tsconfig.json, packages/cli/tsconfig.json, packages/core/tsconfig.json, packages/db/tsconfig.json, packages/import/import-flat/tsconfig.json, packages/import/import-shopify/tsconfig.json, packages/import/import-woocommerce/tsconfig.json, packages/jobs-cloudflare/tsconfig.json, packages/jobs-inngest/tsconfig.json, packages/jobs-pg-boss/tsconfig.json, packages/jobs-trigger/tsconfig.json, packages/plugins/plugin-appointments/tsconfig.json, packages/plugins/plugin-channel-connector/tsconfig.json, packages/plugins/plugin-gift-cards/tsconfig.json, packages/plugins/plugin-layaway/tsconfig.json, packages/plugins/plugin-loyalty/tsconfig.json, packages/plugins/plugin-marketplace/tsconfig.json, packages/plugins/plugin-notifications/tsconfig.json, packages/plugins/plugin-pos-restaurant/tsconfig.json, packages/plugins/plugin-pos/tsconfig.json, packages/plugins/plugin-procurement/tsconfig.json, packages/plugins/plugin-production/tsconfig.json, packages/plugins/plugin-reviews/tsconfig.json, packages/plugins/plugin-scheduled-orders/tsconfig.json, packages/plugins/plugin-uom/tsconfig.json, packages/plugins/plugin-warehouse/tsconfig.json, packages/plugins/plugin-wishlist/tsconfig.json, packages/sdk/tsconfig.json",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "apps/docs/public/scaffold/tsconfig.json, apps/docs/tsconfig.json, apps/restaurant-example/tsconfig.json, apps/saas-example/tsconfig.json, apps/store-example/tsconfig.json, apps/tea-avenue/tsconfig.json, apps/web/tsconfig.json, packages/adapters/adapter-local-storage/tsconfig.json, packages/adapters/adapter-meilisearch/tsconfig.json, packages/adapters/adapter-neon/tsconfig.json, packages/adapters/adapter-pg-search/tsconfig.json, packages/adapters/adapter-pglite/tsconfig.json, packages/adapters/adapter-postgres/tsconfig.json, packages/adapters/adapter-r2/tsconfig.json, packages/adapters/adapter-resend/tsconfig.json, packages/adapters/adapter-s3/tsconfig.json, packages/adapters/adapter-ses/tsconfig.json, packages/adapters/adapter-shopify/tsconfig.json, packages/adapters/adapter-stripe/tsconfig.json, packages/adapters/adapter-tax-manual/tsconfig.json, packages/adapters/adapter-taxjar/tsconfig.json, packages/adapters/adapter-woocommerce/tsconfig.json, packages/cli/templates/starter/tsconfig.json, packages/cli/tsconfig.json, packages/core/tsconfig.json, packages/db/tsconfig.json, packages/import/import-flat/tsconfig.json, packages/import/import-shopify/tsconfig.json, packages/import/import-woocommerce/tsconfig.json, packages/jobs-cloudflare/tsconfig.json, packages/jobs-inngest/tsconfig.json, packages/jobs-pg-boss/tsconfig.json, packages/jobs-trigger/tsconfig.json, packages/plugins/plugin-appointments/tsconfig.json, packages/plugins/plugin-channel-connector/tsconfig.json, packages/plugins/plugin-gift-cards/tsconfig.json, packages/plugins/plugin-layaway/tsconfig.json, packages/plugins/plugin-loyalty/tsconfig.json, packages/plugins/plugin-marketplace/tsconfig.json, packages/plugins/plugin-notifications/tsconfig.json, packages/plugins/plugin-pos-restaurant/tsconfig.json, packages/plugins/plugin-pos/tsconfig.json, packages/plugins/plugin-procurement/tsconfig.json, packages/plugins/plugin-production/tsconfig.json, packages/plugins/plugin-reviews/tsconfig.json, packages/plugins/plugin-scheduled-orders/tsconfig.json, packages/plugins/plugin-uom/tsconfig.json, packages/plugins/plugin-warehouse/tsconfig.json, packages/plugins/plugin-wishlist/tsconfig.json, packages/sdk/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": "73 of the last 96 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 73,
"sampled": 96
}
}
],
"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": "TypeScript",
"largest_source_bytes": 59740,
"source_files_sampled": 804,
"oversized_source_files": 0
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "TypeScript (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "TypeScript"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "0/804 source files over 60KB",
"points": 55,
"status": "met",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 804,
"oversized": 0
}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "critical",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 20,
"inputs": {
"example_dirs": [],
"has_mcp_signal": true,
"api_schema_files": []
},
"components": [
{
"key": "api_schema_openapi_graphql_proto",
"name": "API schema (OpenAPI/GraphQL/proto)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 40
},
{
"key": "mcp_server",
"name": "MCP server",
"detail": null,
"points": 20,
"status": "met",
"details": [],
"max_points": 20
},
{
"key": "runnable_examples",
"name": "Runnable examples",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"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": [
"GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
],
"report_type": "repository",
"generated_at": "2026-07-24T03:58:56.481030Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/a/asyncdotengineering/porulle.svg",
"full_name": "asyncdotengineering/porulle",
"license_state": "standard",
"license_spdx": "MIT"
}