This repository builds hukukca.org: Hukukça, an index of Turkish legal opinion where every entry can be traced to its source. For contested court decisions and similar yes/no legal questions, it records who holds which position, from two kinds of records:
- public statements by named lawyers, bar associations, and institutions, each linked to the place it was published; and
- votes cast directly on the site by verified members of the profession, each carrying cryptographic proof — that the voter was eligible, what they signed, and that the vote was accepted and logged — which anyone can re-check without trusting the site.
Konsensus is the platform underneath: the country-agnostic engine, protocol, and tooling in this monorepo that could run the same kind of index for another country or profession.
Hukukça is not legal advice, a court, a representative opinion poll, or a substitute for independent research. Counts describe the records admitted under one published instance policy; they do not describe every member of a profession or the public.
This monorepo contains the Hukukça application and its production verification, release, backup, and monitoring controls. Only the current version of the voting protocol exists here — there are no legacy code paths. The reusable parts are published standalone: konsensus (the country-agnostic frontend), qualified-opinion-protocol (the V3 protocol and offline verifier), gcs-attested-registration-voting (the Confidential Space registration/voting reference), and confidential-space-verify (offline attestation-token verification).
For a direct Hukukça vote, the current V3 path links:
- presentation of a one-time code sent to the claimed email address, proven by a Google Confidential Space workload and bound to a passkey;
- a separately signed eligibility assertion based on a public bar-registry record and operator review, published in the current eligibility directory;
- a passkey-authorized request for one fresh P-256 key per question;
- a Confidential Space authorization that attests eligibility and emits a deterministic question nullifier without publishing the member identity;
- a user-confirmed vote event signed by that question-only key and bound to the exact question revision and deployment policies;
- signed acceptance; and
- narrow inclusion proofs in the RFC 6962 transparency tree.
The question-scoped public proof can be verified without an application session or database. Once bootstrapped, an independently operated witness can preserve signed tree heads so a later rollback is detectable after observation. Comparing separately operated witnesses can additionally expose a split view.
The boundaries matter:
- Confidential Space proves the attested workload accepted the one-time code in that transaction — not continuing mailbox control; email delivery and mailbox security remain trust assumptions.
- The signed eligibility decision proves which reviewed evidence the operator accepted; the qualification policy and reviewer authority remain visible trust inputs.
- The question authorization proves the pinned workload accepted the full eligibility and session chain, and deliberately omits the reusable identity links from its public form.
- The question-key signature proves the browser signed the exact ballot intent — not what a person saw on screen; that relies on the pinned verifier source, browser integrity, and the confirmation ceremony.
- A Merkle proof proves inclusion in one signed tree head; latest-state claims need a newer independently witnessed head.
- Private votes are question-scoped public pseudonymity, not anonymity from Hukukça, Google infrastructure, or traffic analysis. Name-and-email attribution is a separate, removable, opt-in projection.
The full model is documented in
docs/architecture.md,
docs/confidential-email-verification.md,
and docs/transparency-monitoring.md.
apps/web Hukukça Next.js application and public APIs
apps/worker queued crawl and recomputation worker
apps/confidential-email-verifier Confidential Space email/passkey service
apps/transparency-witness-* Cloudflare and GCP witness implementations
instances/hukukca signed Hukukça instance policy
instances/conformance-demo deliberately different portability fixture
packages/proof canonical protocol, signatures, Merkle, tally
packages/proof-verifier offline vote-proof verifier and CLI
packages/transparency-monitor append-only log monitor plus Hukukça adapter
packages/instance-profile validated, content-addressed instance profile
packages/domain Hukukça domain and attestation contracts
packages/db schema, migrations, queries, seed/import tools
packages/config Hukukça deployment environment adapter
packages/ai review-oriented classification scaffolding
packages/crawler conservative crawler/extractor
packages/ui shared UI primitives
infrastructure source-pinned infrastructure policies
release release schemas and example records
scripts release, database, witness, and audit tooling
docs architecture and operator runbooks
The machine-checked publication classification lives in
docs/module-boundaries.json. It distinguishes
portable cores from extraction candidates and instance/deployment adapters; it
does not label coupled code as white-label merely because it is in packages/.
- Bun 1.3.12 or a compatible Bun 1.3 release
- Docker with Docker Compose
bun install --frozen-lockfile
docker compose up -d --wait
cp .env.example .env
bun db:migrate
bun db:seed
bun devThe web app normally runs at http://localhost:3000. PostgreSQL is exposed at
localhost:55432 and Meilisearch at localhost:7700.
All application-specific environment variables use the HUKUKCA_ prefix. That
prefix is part of the current Hukukça deployment contract; a future generic
extraction should accept typed configuration and let each instance map its own
environment instead of silently aliasing these names.
Seeded users use HUKUKCA_SEED_ADMIN_PASSWORD, which defaults to password
for local databases only. The seeded local administrator is:
iletisim@hukukca.org / password
Open http://localhost:3000/giris and use those
credentials in the password form. The form is available only when development
authentication is enabled. Production always disables development
authentication and refuses insecure placeholder secrets.
Run the same non-database checks as CI:
bun repository:boundaries
bun typecheck
bun lint
bun test
bun auditBefore a public export, install the pinned Gitleaks 8.30.1 binary and run
bun repository:secrets, bun repository:publication-content, and
bun repository:licenses --out PATH. These checks cover the tracked
publication candidates with Gitleaks, an independent secret/PII/path scanner,
and a deterministic dependency-license inventory.
CI additionally provisions least-privilege database roles and exercises the
migration, schema, trust, signed-tally, transparency, and deletion contracts on
PostgreSQL 16 and 17. See .github/workflows/ci.yml.
Useful focused commands include:
bun test:db-integration
bun test:db-trust-integration
bun test:db-tally-integration
bun test:db-transparency-integration
bun transparency:monitorThe witness commands require explicit endpoint, witness-ID, and independently
obtained key-pin arguments; use the exact examples in
docs/transparency-witnesses.md.
@konsensus/instance-profile validates and canonically hashes an instance's
stable identity, jurisdiction, locales, routes, qualification policy, tally
groups, thresholds, and feature flags. instances/conformance-demo proves that
this contract can describe a non-Turkish, differently weighted deployment.
That profile is a policy boundary, not a complete theme or deployment system.
Today, apps/web, packages/db, packages/domain, packages/config, the
Confidential Space verifier, witnesses, and release infrastructure contain
deliberate Hukukça adapters. The extraction plan and evidence-based distinction
between internal modules and possible future repositories are in
docs/public-repository-readiness.md.
The core protocol package is dependency-free. Registration, ballots, and
question-scoped votes use the
qualified-opinion.question-voting-authorization.v3,
qualified-opinion.vote-event.v3, and V3 tally formats.
The package APIs and standalone command verify current V3 question proofs and signed question-only tally snapshots:
bun packages/proof-verifier/src/cli.ts \
--bundle vote-proof.json \
--policy verification-policy.json \
--expected-policy-sha256 64_LOWERCASE_HEX_CHARACTERSSee packages/proof/README.md and
packages/proof-verifier/README.md.
Do not infer a safe production configuration from .env.example. The hosted
Hukukça release uses separate runtime/migration/backup database roles,
non-exportable Cloud KMS signing keys, source-restricted workload identities,
an attested Confidential Space verifier, exact release manifests, guarded
promotion and rollback, retained backups, and a separately controlled GCP
transparency-witness deployment. Its current bootstrap status does not yet
establish independently witnessed checkpoint freshness. The source also
includes a Cloudflare witness implementation for a separately operated control
plane; production does not currently claim that second witness is active or
that strict cross-witness monitoring is ready.
Start with:
docs/deployment.mddocs/release-provenance.mddocs/infrastructure-bootstrap.mddocs/database-backups.mddocs/release-checklist.md
See CONTRIBUTING.md and CODE_OF_CONDUCT.md.
Report vulnerabilities privately according to SECURITY.md;
do not place private verification material or credentials in a public issue.
Source code is licensed under Apache-2.0. Original documentation and
project-authored dataset structure are licensed under CC BY 4.0 unless stated
otherwise. Third-party sources and media retain their original rights. See
LICENSE, LICENSE-DATA.md, and
NOTICE.md.