Noema is ContextualWisdomLab's dedicated GitHub App token exchange service for an independent LLM pull request reviewer.
It runs as a Cloudflare Worker on the Free tier:
- GitHub Actions requests a GitHub OIDC token with audience
cwl-noema-review. - Noema verifies the OIDC issuer, audience, organization owner, and trusted central workflow identity.
- Noema exchanges the verified OIDC token for a GitHub App installation token scoped to the target repository.
- The central
.githubworkflow uses that installation token to submit an LLM review verdict from a GitHub App identity separate from OpenCode Agent. - The Project #1 review-bot roadmap keeps untrusted code/data analysis in a separate sandbox; see
docs/noema-agent-sandbox-plan.md.
The LLM call itself is configured in the central workflow with:
NOEMA_LLM_API_URL— the HTTPScontextual-orchestratorbase URL ending in/v1NOEMA_LLM_MODEL— normally the gateway routing aliascontextual-orchestratorNOEMA_LLM_API_KEY— a dedicated gateway inference token, never an upstream provider key
The product repository also owns the default-branch-only
central-review runtime. It accepts a
noema-review repository_dispatch event containing target_repository,
pr_number, and the exact pr_head_sha; branch-selected manual workflow code
cannot receive the App key. The runtime waits up to 90 minutes for non-OpenCode
checks, initializes and explores CodeGraph at the exact target head, permits a
single provider request to run for 90 minutes, and delegates upstream failover
to contextual-orchestrator before publishing an App-authored review. Before
sending the manifest it rejects known direct-provider URLs and verifies the
unauthenticated /healthz service identity. It rejects target symlinks, strips
credentials from the CodeGraph subprocess, and revalidates the live head
immediately before publication.
The production cutover is intentionally separate from the code change because
it creates organization variables and a secret. Follow the
contextual-orchestrator reviewer cutover runbook;
do not reuse OPENAI_API_KEY as Noema's gateway token.
Example dispatch (bind the SHA from a fresh PR read, never from stale local state):
gh api repos/ContextualWisdomLab/noema/dispatches -X POST --input - <<'JSON'
{"event_type":"noema-review","client_payload":{"target_repository":"ContextualWisdomLab/example","pr_number":1,"pr_head_sha":"0123456789abcdef0123456789abcdef01234567"}}
JSONRepository permissions:
- Pull requests: Read and write
- Checks: Read-only
- Contents: Read-only
Install the app on ContextualWisdomLab/.github and target repositories that use the central required workflow.
wrangler secret put GITHUB_APP_ID
wrangler secret put GITHUB_APP_PRIVATE_KEY_PEMOptional:
wrangler secret put GITHUB_APP_INSTALLATION_IDRuntime guardrail:
NOEMA_RATE_LIMIT_PER_MINUTEdefaults to60./exchangefirst applies a SQLite-backed Durable Object fixed-window limit coordinated across Worker isolates, then retains the original isolate-local limiter as defense in depth. Missing or malformed distributed decisions fail closed; see Distributed rate limiting.NOEMA_OIDC_JWKS_CACHE_TTL_SECONDSdefaults to300;NOEMA_INSTALLATION_CACHE_TTL_SECONDSdefaults to600to reduce repeated external lookups on hot paths./exchangeaccepts onlyPOST(Allow: POSTon 405), returns standard Bearer challenges on 401, bounds untrusted trace/client headers before reflection or rate-limit keying, validatestarget_repositoryas a string before GitHub token creation, refreshes OIDC JWKS when a new signingkidappears, returns no-store/nosniff response headers, and keeps issued/inbound tokens out of operational logs.
npm install
npm run deploySet NOEMA_EXCHANGE_URL in ContextualWisdomLab/.github variables to the deployed /exchange URL.
- API 명세
- 안정성 계약
- 온보딩 가이드
- 운영 Runbook
- Distributed Rate Limiting
- Hourly Commercial-Readiness Loop
- SLA/지원 정책
- 가격 초안
- 관측성 KPI
- 보안/위협 모델
- 이용약관 초안
- 배포 가이드
- 보안 검증 체크리스트
- 파일럿 온보딩 체크리스트
- 출시 준비 감사서
- Buyer Pitch Deck Outline
- 판매 가능 Goal 등록서
- 판매 가능 프로그램 Goal
- 목표 완료 감사서
- 20억 매각 가능성 Goal 등록서
- Buyer Due Diligence Index
- Transfer Readiness Plan
- Library Boundary Decision
npm run kpi:compute
npm run kpi:check
npm run kpi:alerts
npm run kpi:verify
NOEMA_KPI_TAIL_COMMAND='timeout 30s wrangler tail noema --env production --format json' \
NOEMA_KPI_LOG_PATH=exchange-30d.ndjson \
NOEMA_KPI_SOURCE_KIND=production \
NOEMA_KPI_SOURCE_ID=cloudflare-logpush:noema-production \
npm run kpi:collect
# 또는 Logpush/아카이브 URL 직접 사용
NOEMA_KPI_LOG_URL=https://.../exchange-30d.ndjson \
NOEMA_KPI_LOG_PATH=exchange-30d.ndjson \
NOEMA_KPI_SOURCE_KIND=production \
NOEMA_KPI_SOURCE_ID=cloudflare-logpush:noema-production \
npm run kpi:collect
NOEMA_KPI_REQUIRE_WINDOW_DAYS=30 npm run kpi:verify:strictexchange-30d.ndjson은 운영 30일 로그 집계용 파일입니다.
kpi:collect는 exchange-30d.ndjson.provenance.json을 함께 생성하며, strict KPI 게이트는 sourceKind=production, sourceId, records, collectedAt이 있는 provenance 파일을 요구합니다.
wrangler tail은 실시간 수집이므로, 30일 집계는 Logpush/외부 파이프라인 또는 임시 저장본을 exchange-30d.ndjson로 구성해야 합니다.
NOEMA_EXCHANGE_URL=https://.../exchange npm run smoke:checknpm run smoke:check는 /health와 /exchange의 스키마, 추적/지연 헤더, 401 Bearer challenge, no-store/nosniff 보안 헤더를 확인하고 실패 내역을 JSON으로 출력하며,
배포에서 NOEMA_SMOKE_EVIDENCE_PATH를 지정하면 noema-smoke-evidence.json 형태로 증빙을 저장할 수 있습니다.
CI/CD의 cd 워크플로우는 동일 스크립트를 실행해 /health//exchange 계약을 검증합니다.
운영 증빙 수집 전에는 다음 preflight로 production URL과 KPI 로그 수집 입력이 준비됐는지 확인합니다.
NOEMA_EXCHANGE_URL=https://.../exchange \
NOEMA_KPI_SOURCE_KIND=production \
NOEMA_KPI_SOURCE_ID=cloudflare-logpush:noema-production \
NOEMA_KPI_LOG_URL=https://.../exchange-30d.ndjson \
npm run production:preflightproduction:preflight는 증빙을 생성하지 않으며, smoke/KPI evidence 수집 전 누락된 입력을 fail-fast로 알려줍니다.
npm run readiness:audit
NOEMA_EXCHANGE_URL=https://.../exchange npm run readiness:auditnpm run readiness:audit는 기술게이트, 보안/테스트, KPI strict(가능한 경우), smoke 증빙(환경변수 지정 시), 파일럿 완료 증빙까지 한 번에 검사합니다.docs/security-validation-checklist.md의 미체크 항목은 readiness audit 실패로 처리됩니다.- 결과는
artifacts/saleable-readiness/<YYYYMMDD>/goal-audit.json에 저장됩니다. - 파일럿 완료 증빙은 production HTTPS
NOEMA URL,증빙 출처: production,계약/매출 증빙 경로가 있어야 인정됩니다. readiness-scan워크플로우(.github/workflows/readiness-scan.yml)는 UTC 01:00 기준으로 정기readiness:audit를 실행해 증빙을saleable-readiness-audit아티팩트로 보존합니다.- 정기
schedule실행은 누락된 production evidence를NOT_READYstatus, warning, artifact로 남기는 감시 작업이며,workflow_dispatch와 로컬npm run readiness:audit는 동일한 누락을 실패로 유지합니다.
npm run acquisition:manifest
npm run acquisition:auditnpm run acquisition:manifest는 buyer data room 파일, 명령, 외부 Figma 자산, 최종 evidence 경로를artifacts/acquisition-readiness/<YYYYMMDD>/data-room-manifest.json으로 해시/색인합니다.- manifest의 최종 evidence 항목은 파일 존재를 색인하며, 증빙 내용의 유효성은
validatedBy에 적힌npm run acquisition:audit통과로 판정합니다. npm run acquisition:audit는KRW 2,000,000,000매각 협상 기준의 실사 패키지를 검사합니다.npm run security:evidence는 보안 체크리스트와 reviewed security evidence만 단독 검증합니다.- 기본 evidence path는
artifacts/acquisition/revenue-evidence.json,artifacts/acquisition/transfer-evidence.json,docs/pilot-readiness-log.md, 그리고 가장 최신artifacts/saleable-readiness/<YYYYMMDD>/goal-audit.json입니다. NOEMA_PILOT_LOG_PATH로 별도 production 파일럿 로그를 지정할 수 있습니다.- ARR/LOI/weighted pipeline, production 유료 파일럿, IP/license/권한 이전성, saleable readiness가 모두 증빙되지 않으면 실패합니다.
- revenue/transfer evidence는
owner,source_documents, 기본 45일 이내updated_at메타데이터가 없으면 실패합니다. acquisition-readiness-audit워크플로우(.github/workflows/acquisition-readiness-scan.yml)는 매일acquisition:manifest와acquisition:audit를 실행하고 evidence artifact를 보존합니다.- 정기
schedule실행은 production/acquisition evidence 누락을NOT_READYstatus, warning, artifact로 남기는 감시 작업이며,workflow_dispatch와 로컬npm run acquisition:audit는 동일한 누락을 실패로 유지합니다. - submodule은 현재 사용하지 않으며,
docs/library-boundary-decision.md의 split trigger가 충족될 때 npm workspace package 분리를 검토합니다.
npm run release:verify운영/프로덕션 배포 경로는 .github/workflows/cd.yml에서 npm run release:verify:strict를 사용하며, 실패 시 KPI 증빙(noema-kpi-evidence.json)과 provenance(exchange-30d.ndjson.provenance.json)는 워크플로우 Artifact로 저장됩니다.