READ-ONLY · LOCALHOST · YOUR CLOUD IDENTITY

Browse a complete reviewed query bundle locally.

The public website is a small static demonstration. Complete local mode is a separate localhost application: Python reads one immutable, manifest-verified viewer bundle; the browser receives bounded JSON responses. Google Application Default Credentials stay in the host process and are never sent to browser JavaScript.

Bundle required. Raw gs://jouvencekb/kg/v2 is not a viewer bundle. The command refuses it rather than scanning 100M+ canonical rows on a laptop. Use an explicitly reviewed bundle URI published by the maintainers, or a locally generated compatible bundle.

Prerequisites

1. Clone and run the no-cloud smoke

git clone https://github.com/jkobject/jouvence-graph.git
cd jouvence-graph
uv sync --group dev
uv run jouvence-viewer --fixture-smoke

Expected output is one JSON object ending in "status": "pass". The command creates a temporary deterministic bundle, verifies its manifest and all checksums, resolves BRCA1, and removes the temporary directory. It needs no bucket access.

2. Launch a downloaded or generated local bundle

uv run jouvence-viewer \
  --data-root /absolute/path/to/viewer-bundle \
  --open

The root must contain viewer-manifest.json and exactly the supported manifest-declared query sidecars. Every relative path, object size, SHA-256 checksum, schema version, snapshot ID, and read-only declaration is checked before the server starts. Symlinks and manifest paths cannot escape the bundle root.

To exercise local mode with the repository fixture:

uv run python -c "from manage_db.viewer.bundle import build_fixture_bundle; build_fixture_bundle('viewer-fixture-bundle')"
uv run jouvence-viewer --data-root "$PWD/viewer-fixture-bundle" --open

3. Launch a reviewed requester-pays GCS bundle

Your consumer project must have billing enabled, the Cloud Storage JSON API enabled, and your identity must have serviceusage.services.use (normally roles/serviceusage.serviceUsageConsumer) on that consumer project. Separately, the same identity needs a read grant such as roles/storage.objectViewer on gs://jouvencekb.

export JOUVENCE_CONSUMER_PROJECT='your-billed-project'

gcloud services enable storage.googleapis.com \
  --project="$JOUVENCE_CONSUMER_PROJECT"
gcloud auth application-default login
gcloud auth application-default print-access-token >/dev/null

Ask the maintainers for both the exact reviewed bundle ID and its independently published manifest SHA-256. The external digest is the trust anchor: a replaced manifest is rejected even if all internal checksums were recomputed. Do not replace the URI with the raw canonical root.

export JOUVENCE_VIEWER_BUNDLE_URI='gs://jouvencekb/kg/v2/viewer-bundles/<reviewed-bundle-id>'
export JOUVENCE_VIEWER_MANIFEST_SHA256='<published-64-character-sha256>'

uv run jouvence-viewer \
  --data-root "$JOUVENCE_VIEWER_BUNDLE_URI" \
  --billing-project "$JOUVENCE_CONSUMER_PROJECT" \
  --manifest-sha256 "$JOUVENCE_VIEWER_MANIFEST_SHA256" \
  --open
Costs: requester-pays charges your consumer project for GCS requests, bytes read, and possible egress. The loader reads only the manifest and its bounded, checksum-declared objects, then reuses an immutable cache keyed by snapshot and bundle checksum. It never writes to GCS.

Security and read-only guarantees

Troubleshooting

ADC is missing or expired

gcloud auth application-default login
gcloud auth application-default print-access-token >/dev/null

Requester-pays or serviceusage error

Confirm --billing-project names your billed consumer project, the Storage JSON API is enabled there, and your identity has serviceusage.services.use. A project you can view is not necessarily a project you can bill.

403 / object access denied

Ask the maintainer to grant your exact ADC identity read-only object access to the bucket. Also request the manifest SHA-256 through the project's publication channel. Do not request or share maintainer credentials.

Manifest SHA, snapshot, checksum, or schema mismatch

Do not edit the bundle or bypass validation. Remove the affected cached snapshot and download the exact reviewed immutable bundle again. A mismatch can mean a partial download, wrong bundle version, or mutated object.

“Not a compatible viewer query bundle”

You pointed at raw canonical data or another directory. Use a reviewed viewer-bundles/<bundle-id> URI, a downloaded bundle root, or the fixture producer shown above. The viewer intentionally has no laptop raw-table fallback.


LECTURE SEULE · LOCALHOST · VOTRE IDENTITÉ CLOUD

Explorer localement un bundle complet et revu.

Le site public est une petite démonstration statique. Le mode local complet est une application localhost séparée : Python lit un bundle immuable vérifié par manifeste, puis le navigateur reçoit uniquement des réponses JSON bornées. Les Application Default Credentials Google restent dans le processus hôte et ne sont jamais transmises au JavaScript du navigateur.

Bundle obligatoire. Le chemin brut gs://jouvencekb/kg/v2 n’est pas un bundle viewer. La commande le refuse plutôt que de scanner plus de 100 millions de lignes canoniques sur un Mac.

Prérequis et smoke sans cloud

Git, Python 3.11+, uv ; et pour GCS uniquement, gcloud, une identité Google et un projet consommateur avec facturation activée.

git clone https://github.com/jkobject/jouvence-graph.git
cd jouvence-graph
uv sync --group dev
uv run jouvence-viewer --fixture-smoke

La sortie attendue contient "status": "pass". Le smoke construit un bundle temporaire, vérifie manifeste et checksums, résout BRCA1 puis supprime le répertoire.

Bundle local

uv run jouvence-viewer \
  --data-root /chemin/absolu/vers/viewer-bundle \
  --open

Le manifeste, les chemins relatifs, tailles, SHA-256, version de schéma, snapshot et contrat read-only sont vérifiés avant le démarrage. Aucun lien symbolique ne peut sortir de la racine.

Bundle GCS requester-pays revu

Votre projet consommateur doit avoir la facturation et l’API Cloud Storage JSON activées. Votre identité doit avoir serviceusage.services.use sur ce projet et un droit de lecture objet sur le bucket accordé séparément par le mainteneur.

export JOUVENCE_CONSUMER_PROJECT='votre-projet-facture'
gcloud services enable storage.googleapis.com \
  --project="$JOUVENCE_CONSUMER_PROJECT"
gcloud auth application-default login

export JOUVENCE_VIEWER_BUNDLE_URI='gs://jouvencekb/kg/v2/viewer-bundles/<id-bundle-revu>'
export JOUVENCE_VIEWER_MANIFEST_SHA256='<sha256-publie-sur-64-caracteres>'
uv run jouvence-viewer \
  --data-root "$JOUVENCE_VIEWER_BUNDLE_URI" \
  --billing-project "$JOUVENCE_CONSUMER_PROJECT" \
  --manifest-sha256 "$JOUVENCE_VIEWER_MANIFEST_SHA256" \
  --open
Coûts : les requêtes GCS, octets lus et un éventuel egress sont facturés à votre projet. Le chargeur ne lit que le manifeste et ses objets déclarés et bornés, puis réutilise un cache immuable indexé par snapshot et checksum. Il n’écrit jamais sur GCS.

Garanties et dépannage

Le sous-ensemble statique public reste utile pour découvrir l’interface. Seul le mode localhost avec un bundle compatible fournit le contenu complet de ce bundle.