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.
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
- Git; Python 3.11 or newer; uv.
- For GCS only: the Google Cloud CLI (
gcloud), a Google identity, and a consumer Cloud project with billing enabled. - For the private/requester-pays bucket: a maintainer must grant your exact identity read-only object access. This guide does not make the bucket public.
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
Security and read-only guarantees
- The server always binds to
127.0.0.1;0.0.0.0, LAN addresses, and IPv6-any are rejected. - Each launch creates a random local session token. Host and Origin are restricted to localhost.
- ADC and requester-pays configuration exist only in Python. No Google token, credential file, billing-project input, filesystem path, or bucket browser is exposed by the web API.
- There is no arbitrary SQL, file, path, URL, or bucket-proxy endpoint. The selected data root is fixed before the server starts.
- The application opens query sidecars read-only. It cannot promote canonical data or write GCS/LaminDB.
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.
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
Garanties et dépannage
- Bind strict sur
127.0.0.1, token aléatoire par session, validation Host/Origin. - Aucun credential ADC, projet de facturation, chemin, SQL ou proxy de bucket n’est exposé au navigateur.
- ADC expiré : relancer
gcloud auth application-default login. - Erreur requester-pays : vérifier facturation, API Storage JSON et rôle Service Usage Consumer sur votre projet.
- Erreur 403 : demander au mainteneur un droit objet en lecture pour l’identité ADC exacte ; ne jamais partager ses credentials.
- Demander au mainteneur l’ID exact et le SHA-256 du manifeste publié indépendamment ; ce digest externe bloque le remplacement cohérent du manifeste et de ses objets.
- Mismatch SHA de manifeste/snapshot/checksum : ne pas contourner le contrôle ; retélécharger le bundle immuable exact.
- Bundle incompatible : utiliser un URI
viewer-bundles/<id>revu, pas la racine canonique brute.
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.