Clarify is an early-stage, local-first SaaS license audit prototype. It reads account inventory JSON, identifies inactive paid seats, and produces a reviewable findings file plus PDF or HTML reports.
Important
Clarify is a prototype, not a production-ready license-management service. It does not revoke accounts, its live connectors are experimental, and the included API/web dashboard is intended for local evaluation only until user authentication, tenant isolation, and a complete data-retention model are implemented.
- Audit one or more JSON inventory files with a configurable inactivity cutoff.
- Generate deterministic synthetic data for a safe local demo.
- Export findings as JSON and render PDF or HTML reports.
- Exercise policy, identity-resolution, integrity, connector-adapter, and reporting code through the Go test suite.
- Run an experimental Fastify API and React dashboard against PostgreSQL.
- Connector output is not enriched with authoritative product pricing, so connector-only runs do not calculate a credible savings opportunity.
- Connector toggles in the dashboard do not schedule or execute collection jobs.
- Findings generated by the CLI are not automatically persisted to the API.
- Authentication is a single development API key; putting
VITE_API_KEYin a browser bundle is not secure for a public deployment. - Multi-tenant/RLS, scheduler, notification, and some collector packages are scaffolding rather than an integrated runtime.
See Architecture and Data handling for the current boundaries.
Prerequisites: Go 1.26.1+ on macOS or Linux. Sensitive artifact writes fail closed on Windows because Go's POSIX mode bits cannot provide an equivalent owner-only ACL guarantee there.
cd apps/worker
go run . audit \
--generate 500 \
--license-cost 35 \
--cutoff 2026-06-01 \
--audit-date 2026-07-01 \
--out reports/demo.pdf \
--findings reports/findings.jsonThe command writes only synthetic data. Open apps/worker/reports/demo.pdf and inspect apps/worker/reports/findings.json.
To audit an existing inventory instead, supply one or more --input files. The included sample is synthetic and its prices are illustrative:
cd apps/worker
go run . audit \
--input sample_inputs/license_inventory_1.json \
--cutoff 2026-06-01 \
--out reports/inventory-audit.pdf \
--findings reports/inventory-findings.jsonInput records use this shape:
{
"user_email": "person@example.com",
"department": "Engineering",
"status": "ACTIVE",
"last_login": "2026-05-15T09:30:00Z",
"license_cost": 35,
"saas_product": "Example AI"
}Treat license_cost as a monthly estimate unless your source contract says otherwise. Clarify reports an estimated opportunity for human review; it does not prove that a seat can or should be removed.
The dashboard requires Node.js 22.13+, pnpm 11, PostgreSQL 15+, and the PostgreSQL client tools.
cp .env.example .env
# Edit .env and set API_KEY and VITE_API_KEY to the same random local-only value.
docker compose up -d postgres
./infra/migrate.sh
./tools/seed/seed_saas_catalog.sh
pnpm install --frozen-lockfileStart the API in one terminal:
set -a
source .env
set +a
pnpm --filter clarify-api devStart the dashboard in a second terminal:
set -a
source .env
set +a
pnpm --filter web devSet a non-empty API_KEY for the API and the same VITE_API_KEY for local dashboard development. Never use that browser-visible key to protect a public or customer-data deployment.
Older checkouts initialized the Compose volume with a restorer PostgreSQL role and database. PostgreSQL ignores changes to POSTGRES_USER and POSTGRES_DB after a volume has been initialized. To keep that volume and its data, continue using its original connection string instead of trying to reinitialize it:
sed -i.bak \
's#postgres://clarify:clarify@localhost:5432/clarify#postgres://restorer:restorer@localhost:5432/restorer#' \
.env
set -a
source .env
set +a
docker compose up -d postgres
./infra/migrate.sh
./tools/seed/seed_saas_catalog.shThe .env.bak file is ignored by Git; delete it after checking the updated .env. Do not use docker compose down --volumes unless you intentionally want to erase the local database and start over.
pnpm install --frozen-lockfile
make test
pnpm format:check
pnpm lint
pnpm buildDatabase-dependent tests use TEST_POSTGRES_DSN and skip when it is not set.
apps/worker— Go CLI, audit engine, connectors, policy evaluation, and reports.apps/api— experimental Fastify/PostgreSQL API.apps/web— experimental React dashboard.infra/migrations— local PostgreSQL schema.packages/saas-catalog— small illustrative catalog, not an authoritative pricing source.
Inventory files, reports, findings, connector payloads, and logs can contain employee identifiers and security metadata. Keep them out of Git, use least-privilege connector credentials, and review Data handling before using non-synthetic data. Report security concerns using SECURITY.md.
See CONTRIBUTING.md. Focused fixes and reproducible bug reports are welcome; roadmap features should start with an issue so product and data assumptions are explicit.
MIT. See LICENSE.