Публічний реєстр
Звіт про здоров'я програмного забезпеченнясхема 0.27.0 · метрики 1.13.0 · 2026-07-24 03:58 UTC

asyncdotengineering / porulle

Headless commerce framework for TypeScript. REST-only, security-hardened, self-host-first. Active development, alpha — straight out of the oven.

TypeScript · MDXMIT★ 0 зірок⑂ 0 форківз трав. 2026 р.Переглянути на GitHub ↗

asyncdotengineering/porulle має індекс здоров’я 54 зі 100, що відповідає смузі «Помірний». Найвищий показник — Vitality (74/100), найнижчий — Community & Adoption (35/100). Останнє оновлення було 5 днів тому. Більшість нещодавньої роботи виконує один учасник.

54
загалом / 100
Помірний

Індекс здоров'я програмного забезпечення

Метрики згруповано у зважені категорії на шкалі 1–100. Загальна оцінка починається як їхнє середнє; коли публічні дані активують Політику юрисдикцій високого ризику, рейтинг коригується й отримує верхню межу 49 («Під ризиком»). Готовність до ШІ не входить до індексу.

54
Відмінний85-100Зразковий; відповідає практично всім перевіреним критеріям
Добрий70-84Здоровий; незначні прогалини
Помірний50-69Прийнятний, але з помітними прогалинами; рекомендовано перевірку
У зоні ризику30-49Суттєві слабкі місця; впровадження потребує обережності
Критичний1-29Серйозні проблеми (покинутий, єдиний мейнтейнер, без базової гігієни)
ЖиттєздатністьСпільнота тавпровадженняСталість таврядуванняІнженернаякістьБезпекаГотовність доШІ

Профіль оцінок

Кожна вісь — окрема категорія. Форма важить більше, ніж середнє: здоровий об'єкт заповнює всю фігуру, тоді як профіль із піками та провалами означає, що сила в одному вимірі маскує ризик в іншому.

Власність

Asyncdot EngineeringОрганізація
0 підписників9 публічних репозиторіївз квіт. 2023 р.

За цим репозиторієм стоїть організація — спільна, підзвітна опіка, здатна пережити будь-якого окремого мейнтейнера.

Пакетні екосистеми

РеєстрПакетВерсіяЗавантажень / місВерсіїОстання публікація
npm@porulle/db0.10.41 409115 днів тому
npm@porulle/cli0.10.41 248115 днів тому
npm@porulle/sdk0.10.41 182115 днів тому
npm@porulle/core0.10.44 194115 днів тому
npm@porulle/jobs-inngest0.10.477865 днів тому
npm@porulle/jobs-pg-boss0.10.476665 днів тому
npm@porulle/jobs-trigger0.10.473865 днів тому
npm@porulle/jobs-cloudflare0.10.476365 днів тому

Метрики за категоріями

Життєздатність

Чи живий проєкт — чи пишеться код і чи виходять релізи?

74Добрий · 22% загального індексу
Як обчислюється оцінка
36/36Свіжість push — останній push 5 дн. тому
3.5/36Ритм комітів — 5/52 тижнів із комітами
17.8/18Обсяг комітів — 96 комітів за останній рік
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Використані вхідні дані
commits_last_year96
human_commit_share1
days_since_last_push5
active_weeks_last_year5
Як обчислюється оцінка
27/27Випускає релізи — опубліковано 2 релізів
36/36Свіжість релізів — останній реліз 39 дн. тому
27/27Ритм релізів — реліз кожні ~0 дн.
0/10OpenSSF Scorecard: Signed-Releases — немає даних
Використані вхідні дані
releases_count2
latest_release_tagv0.6.0
releases_from_tagsні
days_since_latest_release39
mean_days_between_releases0
Виключено з оцінювання (немає даних або не застосовно): OpenSSF Scorecard: Signed-Releases. Залишкові ваги перенормовано.

Спільнота та впровадження

Чи має проєкт користувачів, завантаження, увагу та влаштовані умови для контриб’юторів?

35У зоні ризику · 18% загального індексу
Як обчислюється оцінка
0/60Зірки — 0 зірок
0/25Форки — 0 форків
0/15Спостерігачі — 0 спостерігачів
Використані вхідні дані
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Як обчислюється оцінка
22.5/22.5README
22.5/22.5Ліцензія — визнана ліцензія (MIT)
0/18Настанови CONTRIBUTING
0/13.5Кодекс поведінки
0/7.2Шаблон issue
0/6.3Шаблон PR
Використані вхідні дані
has_readmeтак
has_licenseтак
has_contributingні
has_issue_templateні
has_code_of_conductні
has_pull_request_templateні
Як обчислюється оцінка
53.9/80Щомісячні завантаження — 11 078 завантажень/місяць у npm
0/20Залежні пакети в реєстрі — ця екосистема цього не повідомляє
Використані вхідні дані
packages@porulle/db, @porulle/cli, @porulle/sdk, @porulle/core, @porulle/jobs-inngest, @porulle/jobs-pg-boss, @porulle/jobs-trigger, @porulle/jobs-cloudflare
dependents
ecosystemsnpm
total_downloads
monthly_downloads11 078
Виключено з оцінювання (немає даних або не застосовно): Залежні пакети в реєстрі. Залишкові ваги перенормовано.

Сталість та врядування

Чи переживе проєкт своїх людей — бас-фактор, реактивність, хто за ним стоїть і як супроводжуються пакети?

56Помірний · 24% загального індексу
Як обчислюється оцінка
9/54Бас-фактор — на 1 контриб’ютор(ів) припадає половина всіх комітів
0/22.5Розподіл комітів — головний контриб’ютор — автор 100% комітів
1.4/13.5Широта контриб’юторів — 1 контриб’юторів
3/10OpenSSF Scorecard: Contributors — project has 1 contributing companies or organizations -- score normalized to 3
Використані вхідні дані
bus_factor1
contributors_sampled1
top_contributor_share1
Як обчислюється оцінка
46.8/46.8Вирішення issue — закрито 100% issue
38.2/38.3Прийняття PR — злито 13/13 вирішених PR
0/15OpenSSF Scorecard: Code-Review — Found 0/13 approved changesets -- score normalized to 0
Використані вхідні дані
merged_prs13
open_issues0
closed_issues55
issue_closed_ratio1
closed_unmerged_prs0

Власність та опіка

44У зоні ризику
Як обчислюється оцінка
30/30Підтримка власника — у власності організації
0/20Верифікований домен
0/25Охоплення власника — 0 підписників у asyncdotengineering
13.8/25Послужний список — 9 публічних репозиторіїв, вік облікового запису ~3 р.
Використані вхідні дані
followers0
owner_typeOrganization
is_verified
owner_loginasyncdotengineering
public_repos9
account_age_days1 197

Супровід пакетів

100Відмінний
Як обчислюється оцінка
25/25Опубліковано й доступно — 8 пакет(ів) у npm
35/35Свіжість публікацій — остання публікація 5 дн. тому
20/20Історія версій — 11 опублікованих версій
20/20Не застарілий — активний, не deprecated і не yanked
Використані вхідні дані
packages@porulle/db, @porulle/cli, @porulle/sdk, @porulle/core, @porulle/jobs-inngest, @porulle/jobs-pg-boss, @porulle/jobs-trigger, @porulle/jobs-cloudflare
ecosystemsnpm
any_deprecatedні
min_days_since_publish5

Інженерна якість

Чи наявні базові інженерні практики та документація?

60Помірний · 20% загального індексу

Інженерні практики

40У зоні ризику
Як обчислюється оцінка
0/24Процеси CI
24/24Наявні тести
16/16Конфігурація лінтера — eslint.config.js, eslint.config.mjs
0/9.6Pre-commit-хуки
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — 0 out of 9 merged PRs checked by a CI test -- score normalized to 0
Використані вхідні дані
has_ciні
has_testsтак
has_editorconfigні
has_linter_configтак
has_precommit_configні

Документація

90Відмінний
Як обчислюється оцінка
30/30README
25/25Каталог документації
15/15Сайт документації / домашня сторінка — https://porulle-docs.vercel.app
10/10Опис репозиторію
0/10Теми
10/10Wiki
Використані вхідні дані
topics
has_wikiтак
homepagehttps://porulle-docs.vercel.app
has_readmeтак
has_docs_dirтак
has_descriptionтак

Безпека

Чи міцні видимі практики безпеки й ланцюга постачання, без непослабленої пов’язаності з юрисдикціями високого ризику?

37У зоні ризику · 16% загального індексу

Стан безпеки

21Критичний
Як обчислюється оцінка
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — 0 out of 9 merged PRs checked by a CI test -- score normalized to 0
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/13 approved changesets -- score normalized to 0
0.8/2.5Contributors — project has 1 contributing companies or organizations -- score normalized to 3
0/10Dangerous-Workflow — немає даних
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Ліцензія — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
0/5Packaging — немає даних
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
5/5Security-Policy — security policy file detected
0/7.5Signed-Releases — немає даних
0/7.5Token-Permissions — немає даних
0/7.5Vulnerabilities — 54 existing vulnerabilities detected
Використані вхідні дані
sourceopenssf_scorecard
checks_evaluated14
scorecard_versionv5.5.0
checks_inconclusive4
scorecard_aggregate2,1
Виключено з оцінювання (немає даних або не застосовно): dangerous_workflow, packaging, signed_releases, token_permissions. Залишкові ваги перенормовано.
Як обчислюється оцінка
35/35Прямі залежності без відомих сповіщень — жодна пряма залежність не має відомих сповіщень
25/25Непрямі залежності без відомих сповіщень — жодна непряма залежність не має відомих сповіщень
0/40Немає задавнених сповіщень — жодне сповіщення не має дати публікації
Використані вхідні дані
sourceosv
advisories0
affected_packages0
assessed_packages57
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
Виключено з оцінювання (немає даних або не застосовно): Немає задавнених сповіщень. Залишкові ваги перенормовано. Звірено з runtime-замиканням залежностей npm:@porulle/db@0.10.4 — тим, що тягне за собою встановлення опублікованого пакета, — 57 пакетів. Досяжність не аналізується.

Готовність до ШІ

Наскільки репозиторій оснащений для розробки та супроводу за участі ШІ-агентів? Незалежний, експериментальний бейдж — вага 0.0, тож він подається окремо і не впливає на загальний індекс здоров'я.

69Помірний · 0% загального індексу
Як обчислюється оцінка
45/45Інструкції для агентів — .agents/factory/workers/claude.md, .archive/research/AGENTS.md, CLAUDE.md
0/15Машиночитана документація (llms.txt)
40/40Читабельна історія комітів — намір зазначено у 96 з 96 людських комітів (структурований заголовок або пояснювальний текст)
Використані вхідні дані
has_llms_txtні
legible_history_share1
agent_instruction_files.agents/factory/workers/claude.md, .archive/research/AGENTS.md, CLAUDE.md
agent_instruction_max_bytes13 046
Як обчислюється оцінка
0/18Розгортання однією командою
22/22Автоматизовані тести
11/11Конфігурація лінтера / форматера — eslint.config.js, eslint.config.mjs
11/11Статична перевірка типів — 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
10/10Відтворюване середовище — Dockerfile, lockfile
10/10Підтверджена практика роботи з агентами — 73 з останніх 96 комітів створено агентом або з його зазначенням
0/8Автоматизоване супроводження — автоматичних оновлень залежностей не виявлено
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Використані вхідні дані
has_nixні
has_testsтак
lockfilespnpm-lock.yaml
has_dockerfileтак
typed_languageтак
bootstrap_files
has_devcontainerні
has_linter_configтак
typecheck_configsapps/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_share0,76
toolchain_manifests
dependency_bot_commit_share0
Як обчислюється оцінка
45/45Типізований код — TypeScript (статично типізована)
55/55Керовані розміри файлів — 0/804 файлів вихідного коду понад 60 КБ
Використані вхідні дані
primary_languageTypeScript
largest_source_bytes59 740
source_files_sampled804
oversized_source_files0
Як обчислюється оцінка
0/40Схема API (OpenAPI/GraphQL/proto)
20/20Сервер MCP
0/40Придатні до запуску приклади
Використані вхідні дані
example_dirs
has_mcp_signalтак
api_schema_files

Ключові факти

0зірок GitHub
1контриб'юторів
96комітів за останні 12 місяців
5днів від останнього пушу
2релізів
1бас-фактор
0відкритих issue
npmпакетних екосистем

Попередження щодо збору даних

  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Докладніше

OpenSSF Scorecard 2.1 / 10
2.1сукупно

Незалежна, не прив'язана до інструментів оцінка безпеки від відкритого проєкту OpenSSF Scorecard. Кожна перевірка винагороджує практику безпеки, а не інструмент конкретного постачальника. Перевірки, які Scorecard не зміг визначити, позначено н/д і виключено з оцінки безпеки (вони ніколи не зараховуються як нуль).Scorecard v5.5.0 · 2026-07-24 03:58 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
0CI-Tests0 out of 9 merged PRs checked by a CI test -- score normalized to 0
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/13 approved changesets -- score normalized to 0
3Contributorsproject has 1 contributing companies or organizations -- score normalized to 3
н/дDangerous-Workflowno workflows found
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
н/дPackagingpackaging workflow not detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
10Security-Policysecurity policy file detected
н/дSigned-Releasesno releases found
н/дToken-PermissionsNo tokens found
0Vulnerabilities54 existing vulnerabilities detected
Прямі залежності 74
РеєстрПакетОбмеження версіїМаніфест
npm@hono/node-server^1.14.3apps/restaurant-example/package.json
npm@porulle/adapter-local-storageworkspace:*apps/restaurant-example/package.json
npm@porulle/adapter-postgresworkspace:*apps/restaurant-example/package.json
npm@porulle/coreworkspace:*apps/restaurant-example/package.json
npm@porulle/plugin-posworkspace:*apps/restaurant-example/package.json
npm@porulle/plugin-pos-restaurantworkspace:*apps/restaurant-example/package.json
npm@porulle/plugin-uomworkspace:*apps/restaurant-example/package.json
npm@porulle/plugin-procurementworkspace:*apps/restaurant-example/package.json
npm@porulle/plugin-warehouseworkspace:*apps/restaurant-example/package.json
npm@porulle/plugin-productionworkspace:*apps/restaurant-example/package.json
npm@porulle/plugin-notificationsworkspace:*apps/restaurant-example/package.json
npm@porulle/plugin-scheduled-ordersworkspace:*apps/restaurant-example/package.json
npm@porulle/plugin-reviewsworkspace:*apps/restaurant-example/package.json
npmhono^4.12.5apps/restaurant-example/package.json
npm@hono/node-server^1.19.6apps/saas-example/package.json
npm@porulle/adapter-local-storageworkspace:*apps/saas-example/package.json
npm@porulle/adapter-postgresworkspace:*apps/saas-example/package.json
npm@porulle/coreworkspace:*apps/saas-example/package.json
npm@faker-js/faker^10.3.0apps/store-example/package.json
npm@hono/node-server^1.19.6apps/store-example/package.json
npm@hono/zod-openapi^1.2.2apps/store-example/package.json
npmhono^4.9.8apps/store-example/package.json
npm@porulle/adapter-local-storageworkspace:*apps/store-example/package.json
npm@porulle/adapter-postgresworkspace:*apps/store-example/package.json
npm@porulle/coreworkspace:*apps/store-example/package.json
npm@porulle/plugin-loyaltyworkspace:*apps/store-example/package.json
npm@porulle/plugin-wishlistworkspace:*apps/store-example/package.json
npm@porulle/plugin-reviewsworkspace:*apps/store-example/package.json
npm@hono/node-server^1.14.3apps/tea-avenue/package.json
npm@porulle/adapter-local-storageworkspace:*apps/tea-avenue/package.json
npm@porulle/adapter-postgresworkspace:*apps/tea-avenue/package.json
npm@porulle/coreworkspace:*apps/tea-avenue/package.json
npm@porulle/plugin-posworkspace:*apps/tea-avenue/package.json
npm@porulle/plugin-pos-restaurantworkspace:*apps/tea-avenue/package.json
npm@porulle/plugin-uomworkspace:*apps/tea-avenue/package.json
npm@porulle/plugin-procurementworkspace:*apps/tea-avenue/package.json
npm@porulle/plugin-warehouseworkspace:*apps/tea-avenue/package.json
npm@porulle/plugin-productionworkspace:*apps/tea-avenue/package.json
npm@porulle/plugin-loyaltyworkspace:*apps/tea-avenue/package.json
npm@porulle/plugin-notificationsworkspace:*apps/tea-avenue/package.json
npm@porulle/plugin-scheduled-ordersworkspace:*apps/tea-avenue/package.json
npm@porulle/plugin-reviewsworkspace:*apps/tea-avenue/package.json
npm@porulle/plugin-wishlistworkspace:*apps/tea-avenue/package.json
npmhono^4.12.5apps/tea-avenue/package.json
npmnext16.1.5apps/web/package.json
npmreact^19.2.0apps/web/package.json
npmreact-dom^19.2.0apps/web/package.json
npmpostgres^3.4.7packages/cli/package.json
npmcitty^0.1.6packages/cli/package.json
npmconsola^3.4.2packages/cli/package.json
npmgiget^2.0.0packages/cli/package.json
npm@better-auth/api-key^1.3.8packages/core/package.json
npm@better-auth/drizzle-adapter^1.3.8packages/core/package.json
npm@hono/zod-openapi^1.2.2packages/core/package.json
npm@scalar/hono-api-reference^0.10.5packages/core/package.json
npmbetter-auth^1.3.8packages/core/package.json
npmdrizzle-orm^0.45.1packages/core/package.json
npmdrizzle-zod^0.8.3packages/core/package.json
npmhono^4.9.8packages/core/package.json
npmhono-rate-limiter^0.5.3packages/core/package.json
npmpino^10.3.1packages/core/package.json
npmzod^4.1.11packages/core/package.json
npm@porulle/coreworkspace:*packages/db/package.json
npmdrizzle-orm^0.45.1packages/db/package.json
npmpostgres^3.4.7packages/db/package.json
npm@porulle/coreworkspace:*packages/jobs-cloudflare/package.json
npm@porulle/coreworkspace:*packages/jobs-inngest/package.json
npminngest^4.13.0packages/jobs-inngest/package.json
npm@porulle/coreworkspace:*packages/jobs-pg-boss/package.json
npmpg-boss^12.26.1packages/jobs-pg-boss/package.json
npm@porulle/coreworkspace:*packages/jobs-trigger/package.json
npm@trigger.dev/sdk^4.5.4packages/jobs-trigger/package.json
npmopenapi-fetch^0.17.0packages/sdk/package.json
npmopenapi-typescript-helpers^0.1.0packages/sdk/package.json
Усі залежності не зібрано

Не вдалося зібрати розв'язаний набір залежностей для цього звіту: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Сповіщення про залежності 0

Встановлення npm:@porulle/db@0.10.4 тягне 57 пакетів, прямих і транзитивних: 0 мають відомі сповіщення, з них 0 — прямі залежності.

Жодне відоме сповіщення не стосується оцінених залежностей.

Сповіщення означає, що версія, записана в графі залежностей, потрапляє в уражений діапазон. Досяжність не аналізується, а граф містить піниї розробки й тестування — знахідка може стосуватися інструментів, а не поставленого коду.

Звіт у форматі 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"
}

Оцінки — це сигнали, а не гарантії. Вони відображають публічно видимі практики на GitHub — це не аудит коду й не гарантія безпеки.

Відсутні дані виключаються, а ваги перенормовуються — нуль за відсутність ніколи не ставиться. Методологія версіонована й відкрита: метрики v1.13.0, схема v0.27.0 — повна методологія · вікі метрик.

Як окремий результат виглядає на тлі всього реєстру: сукупна статистикаnpm.