Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
6368d2a
docs(research): split graph work into tickets
devonxjz Aug 25, 2026
5fda9f3
chore(ai): pin graph and tracing packages
devonxjz Aug 25, 2026
4856687
feat(research): enforce deterministic evidence budgets
devonxjz Aug 25, 2026
d40785d
refactor(llm): use langchain model contracts
devonxjz Aug 25, 2026
6b587d9
feat(research): orchestrate sources with langgraph
devonxjz Aug 25, 2026
d40b517
fix(profile): isolate untrusted source evidence
devonxjz Aug 25, 2026
c8a213a
refactor(api): stream the research graph
devonxjz Aug 25, 2026
0fda0b9
feat(observability): trace research in langfuse
devonxjz Aug 25, 2026
dd1187e
docs(research): document graph operations
devonxjz Aug 25, 2026
d84caa0
fix(observability): use relative import in instrumentation hook
devonxjz Aug 25, 2026
dd72b42
feat(workflow): integrate LangGraph parallel pipeline and Langfuse ob…
devonxjz Aug 26, 2026
10a6612
Merge pull request #1 from devonxjz/codex/partneriq-langgraph-langfuse
devonxjz Aug 26, 2026
2dbb243
docs(cache): add research cache design
devonxjz Aug 26, 2026
7e16b16
docs(cache): split implementation into sprints
devonxjz Aug 26, 2026
f501aea
feat(cache): implement sprint 01 contracts and normalization
devonxjz Aug 26, 2026
762cca3
feat(storage): implement sprint 02 supabase schema and storage adapter
devonxjz Aug 26, 2026
40a1d2e
feat(cache): implement sprint 03 server read-through flow
devonxjz Aug 26, 2026
87efa4e
feat(ui): implement sprint 04 client suggestions and refresh ui
devonxjz Aug 26, 2026
ae0763a
fix(tests): fix ProfileDiff type in reducer unit test
devonxjz Aug 26, 2026
4f073d9
feat(telemetry): implement sprint 05 telemetry and release hardening
devonxjz Aug 26, 2026
760140e
refactor(ui): enhance accessibility semantics and unmount lifecycle s…
devonxjz Aug 26, 2026
ee4b9b8
feat(observability): add fingerprintCacheKey and updateResearchCacheO…
devonxjz Aug 26, 2026
d80e24f
feat(ui): add buildResearchRequest helper and test coverage
devonxjz Aug 26, 2026
e8709ee
fix(cache): enforce cache preflight, recoverable cache_invalid notice…
devonxjz Aug 26, 2026
4b3b4db
fix(observability): emit failed research scores on stream error
devonxjz Aug 26, 2026
edd30e0
fix(storage): fallback to SUPABASE_ANON_KEY and encapsulate preflight…
devonxjz Aug 26, 2026
fb66da8
fix(storage): add graceful fallback for unmigrated Supabase schemas
devonxjz Aug 26, 2026
d5990ea
feat(ui): add interactive evidence verification links to all profile …
devonxjz Aug 26, 2026
a28ddda
docs: rewrite README with light theme architecture diagram, LangChain…
devonxjz Aug 26, 2026
f34cb77
Merge pull request #2 from devonxjz/feat/server_caching
devonxjz Aug 26, 2026
dbdf462
docs: adjust README.md structure
devonxjz Aug 26, 2026
1025ecd
chore: sync with origin/dev PR merge
devonxjz Aug 26, 2026
8dbf140
fix(supabase): ensure migration contains complete base schema and RPC…
devonxjz Aug 26, 2026
b4a5ec4
docs: add light mode domain class diagram image to README
devonxjz Aug 26, 2026
f5aab8e
docs: replace class diagram with light mode sequence diagram image in…
devonxjz Aug 26, 2026
f23171d
docs: add light mode workflow diagram image to README
devonxjz Aug 26, 2026
3b4ad53
docs: replace all text/code diagrams with visual light mode images
devonxjz Aug 26, 2026
37935c2
feat(evidence): define provenance contracts
devonxjz Aug 28, 2026
f1affd0
feat(news): extract publication metadata
devonxjz Aug 28, 2026
1171b5f
feat(crawl): respect publisher fetch policy
devonxjz Aug 28, 2026
30779e3
feat(evidence): normalize citations and count independent sources
devonxjz Aug 28, 2026
a1bfc74
feat(profile): integrate field-level evidence and provenance citations
devonxjz Aug 28, 2026
f209d80
feat(analyst): resolve claim evidence for fit criteria and risk flags
devonxjz Aug 28, 2026
07059e2
feat(serialization): preserve rich provenance in cache and export pay…
devonxjz Aug 28, 2026
dcc0d0c
feat(ui): add in-app source preview dialog and field provenance
devonxjz Aug 28, 2026
5f8259e
docs(evidence): complete TASK-4 evidence provenance and in-app preview
devonxjz Aug 28, 2026
17eec21
docs(workflow): design native orchestration
devonxjz Aug 29, 2026
eea6e67
feat(evidence): finalize provenance ranking
devonxjz Aug 29, 2026
722530d
docs(workflow): plan native orchestration
devonxjz Aug 29, 2026
bd3fe44
refactor(llm): use native OpenAI responses
devonxjz Aug 29, 2026
846941e
refactor(workflow): use native concurrency
devonxjz Aug 29, 2026
4617afc
chore(deps): remove LangChain stack
devonxjz Aug 29, 2026
53d039c
Merge pull request #3 from devonxjz/codex/native-research-workflow
devonxjz Aug 29, 2026
57a4c83
Add Cloudflare research gateway migration
devonxjz Aug 30, 2026
345edcf
docs: update system architecture diagram and rewrite README
devonxjz Aug 30, 2026
5a78851
fix(worker): sync package-lock.json for esbuild and vitest dependencies
devonxjz Aug 30, 2026
e08f953
fix(ci): install worker dependencies without optional packages
devonxjz Aug 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Secrets and local configuration
.env*
!.env.example

# Dependencies and generated output
node_modules
.next
out
build
coverage

# Repository and agent tooling
.git
.github
.worktrees
.codegraph

# Local artifacts
tmp
*.log
47 changes: 45 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,65 @@ JINA_API_KEY=
TINYFISH_API_KEY=
SCRAPER_TIMEOUT_MS=8000
SCRAPER_MAX_RESPONSE_BYTES=1048576
SCRAPER_MAX_REDIRECTS=3
MAX_SCRAPE_PAGES_PER_RESEARCH=5

# Crawl Policy & News Extraction
CRAWL_USER_AGENT=PartnerIQBot
CRAWL_MIN_DOMAIN_INTERVAL_MS=1000
ROBOTS_CACHE_TTL_MS=86400000
ROBOTS_FAIL_MODE=metadata_only
NEWS_ARTICLE_EXTRACTION_ENABLED=true


# Registry
VIETQR_ENABLED=true

# Storage
STORAGE_PROVIDER=supabase # supabase | memory
SUPABASE_URL=https://xyz.supabase.co
SUPABASE_ANON_KEY=...
SUPABASE_SERVICE_ROLE_KEY=server-only-secret
# Browser Supabase Auth (publishable values; safe to expose to the client bundle)
NEXT_PUBLIC_SUPABASE_URL=https://xyz.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=public-anon-or-publishable-key

# Required when Langfuse telemetry is enabled; never use a public/default value.
LANGFUSE_SALT=server-only-telemetry-secret

# Research gateway (Cloudflare Worker + signed Cloud Run origin)
# Set real staging/production values in workers/research-gateway/wrangler.jsonc.
RESEARCH_GATEWAY_URL=https://research-gateway.example.workers.dev
ORIGIN_URL=https://partneriq-origin.example.run.app
SUPABASE_JWT_ISSUER=https://xyz.supabase.co/auth/v1
SUPABASE_JWT_AUDIENCE=authenticated
SUPABASE_TENANT_CLAIM=tenant_id
SUPABASE_MEMBERSHIP_RPC=resolve_research_tenant
SUPABASE_QUOTA_RPC=reserve_research_quota
GATEWAY_KEY_ID=current
REPLAY_WINDOW_SECONDS=60
# Worker secrets: configure per environment with Wrangler; leave empty here.
SUPABASE_API_KEY=
GATEWAY_SIGNING_KEY=
# Node origin secrets: current plus optional previous key during rotation.
GATEWAY_SIGNING_KEY_CURRENT=
GATEWAY_SIGNING_KEY_PREVIOUS=

# Rate limit guards (optional overrides)
MAX_CONCURRENT_RESEARCH=1
MAX_QUERIES_PER_RESEARCH=6
MAX_CONCURRENT_SOURCE_NODES=3
MAX_CONCURRENT_PROVIDER_CALLS=2
SOURCE_TIMEOUT_MS=60000
MAX_RESEARCH_PER_DAY=50
MAX_TOKENS_PER_DAY=500000

# Observability — Langfuse Cloud
LANGFUSE_ENABLED=false
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_BASE_URL=https://cloud.langfuse.com
LANGFUSE_TRACING_ENVIRONMENT=production
LANGFUSE_LOG_LEVEL=WARN

# App
NODE_ENV=development

31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ permissions:

jobs:
checks:
timeout-minutes: 20
runs-on: ubuntu-latest
steps:
- name: Checkout repository
Expand All @@ -25,6 +26,25 @@ jobs:
- name: Install dependencies
run: npm ci

- name: Detect research gateway Worker
id: worker
shell: bash
run: |
if [[ -f workers/research-gateway/package.json ]]; then
echo "enabled=true" >> "$GITHUB_OUTPUT"
else
echo "enabled=false" >> "$GITHUB_OUTPUT"
fi

- name: Install Worker dependencies
if: steps.worker.outputs.enabled == 'true'
working-directory: workers/research-gateway
run: npm ci --omit=optional

- name: Check Worker
if: steps.worker.outputs.enabled == 'true'
run: npm run worker:check

- name: Type check
run: npm run typecheck

Expand All @@ -34,5 +54,16 @@ jobs:
- name: Test
run: npm test

- name: Database integration tests
run: |
npx supabase start
eval "$(npx supabase status -o env)"
SUPABASE_TEST_URL="$API_URL" SUPABASE_TEST_SERVICE_ROLE_KEY="$SERVICE_ROLE_KEY" SUPABASE_TEST_ANON_KEY="$ANON_KEY" npm run test:db

- name: Stop Supabase
if: always()
run: npx supabase stop --no-backup

- name: Build
run: npm run build

59 changes: 59 additions & 0 deletions .github/workflows/deploy-worker-production.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Deploy research gateway (production)

on:
workflow_dispatch:
inputs:
ref:
description: Tested commit SHA to deploy
required: true

permissions:
contents: read

concurrency:
group: deploy-research-gateway-production
cancel-in-progress: false

jobs:
deploy:
environment: production
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- name: Checkout requested commit
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ inputs.ref }}

- name: Require an exact commit SHA
env:
DEPLOY_REF: ${{ inputs.ref }}
run: |
if [[ ! "$DEPLOY_REF" =~ ^[0-9a-fA-F]{40}$ ]]; then
echo "Production deployments require a full 40-character commit SHA." >&2
exit 1
fi

- name: Set up Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 22
cache: npm
cache-dependency-path: workers/research-gateway/package-lock.json

- name: Install Worker dependencies
working-directory: workers/research-gateway
run: npm ci --omit=optional

- name: Check Worker
run: npm run worker:check

- name: Validate deployment configuration
run: npm --prefix workers/research-gateway run predeploy

- name: Deploy production Worker
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
working-directory: workers/research-gateway
run: npm exec -- wrangler deploy --env production
51 changes: 51 additions & 0 deletions .github/workflows/deploy-worker-staging.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Deploy research gateway (staging)

on:
workflow_dispatch:
inputs:
ref:
description: Git ref or commit SHA to deploy
required: true
default: main

permissions:
contents: read

concurrency:
group: deploy-research-gateway-staging
cancel-in-progress: false

jobs:
deploy:
environment: staging
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- name: Checkout requested ref
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ inputs.ref }}

- name: Set up Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 22
cache: npm
cache-dependency-path: workers/research-gateway/package-lock.json

- name: Install Worker dependencies
working-directory: workers/research-gateway
run: npm ci --omit=optional

- name: Check Worker
run: npm run worker:check

- name: Validate deployment configuration
run: npm --prefix workers/research-gateway run predeploy

- name: Deploy staging Worker
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
working-directory: workers/research-gateway
run: npm exec -- wrangler deploy --env staging
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ concurrency:

jobs:
publish:
timeout-minutes: 20
if: >-
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'push'
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ next-env.d.ts

# temp fixtures
/tmp/
supabase/.temp/
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ Prefer single-file or single-test runs during iteration. Full suites are for the

When the user corrects your approach, append a one-line rule here before ending the session. Write it concretely ("Always use X for Y"), never abstractly ("be careful with Y"). If an existing line already covers the correction, tighten it instead of adding a new one. Remove lines when the underlying issue goes away (model upgrades, refactors, process changes).

- (empty)
- For external-content previews, separate source-quality signals from claim verification; default to metadata plus a short excerpt, respect paywalls and publisher controls, and treat jurisdiction-specific copyright review as a release requirement.

---

Expand All @@ -214,4 +214,4 @@ This boilerplate synthesizes:
- Community anti-sycophancy patterns (explicit banned phrases, direct-not-diplomatic).
- The AGENTS.md open standard (cross-tool portability via symlinks).

Read once. Edit sections 10 and 11 for your project. Prune the rest over time. This file gets better the more you use it.
Read once. Edit sections 10 and 11 for your project. Prune the rest over time. This file gets better the more you use it.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Dockerfile — PartnerIQ (Google Cloud Run / Production)
# ═══════════════════════════════════════════════════════

FROM node:20-alpine AS base
FROM node:22-alpine AS base

# Step 1: Install dependencies
FROM base AS deps
Expand Down
Loading
Loading