Publish qsv profiles in the Fair Store, deploy it to Compute Engine, and manage it from Verikan - #16
Merged
Merged
Conversation
… Engine
Mirror (scripts/populate_fairstore.py):
- mirror every registered portal (CKAN and DCAT/Socrata) with --site all
- publish each qsv profile as dataset qsv_* fields plus a data dictionary,
stats and frequency DataStore tables (with table views) and the describegpt
JSON; only output that matches the profiled file's header is published
- fail closed: reads raise instead of returning {} (CKANClient.call), Socrata
enrichment is required under --apply, and one portal's failure no longer
stops the others
- reruns write only what changed (mirror_digest / qsv_digest), apply source
renames, and report records withdrawn at the source
- DataStore loads are verified by row count and rebuilt, never doubled
Deployment (deploy/fairstore): one VM running CKAN 2.11.6, Postgres, Solr,
Redis and Caddy (automatic HTTPS), with no service account, the metadata
server blocked from containers, security headers, Secure cookies, CSRF
checks on extension endpoints, daily disk snapshots and deletion protection.
Adds an Admin -> Fair Store page and the code behind it (gateway/fairstore.py): - Connection: the Fair Store URL and a sysadmin API token. The token is never returned to the browser and is bound to the origin it was saved for; a URL that is already a registered source portal is refused, so a mirror can never write into one. FAIRSTORE_URL / FAIRSTORE_API_KEY seed the settings. - Mirror runs: populate_fairstore runs under the onboarding job runner (one job at a time), with a live log, a per-portal summary and cancel. Running jobs heartbeat their record and use absolute log offsets, so any Cloud Run instance can show or cancel a run. - Runs on Cloud Run read qsv profiles from the storage backend (--qsv-source): sync_to_storage now writes sync_manifest.json (CSV headers, dataset directories, qsv outputs present) and stores JSON with API keys scrubbed, and staging from it produces the same writes as a local run. - Live status (reachability, token check, datasets per source portal) and the Fair Store's runtime site settings (title, about, logo, custom CSS). - Chat source: the agent searches the Fair Store's catalog and loads rows from the portal each dataset was mirrored from (CSV/TSV files only). Citations, agent-log sources and notebook code name the portal that served each call; the notebook editor shares the same per-call path. Also hardens the agent: numeric tool arguments sent as strings, a portal with DataStore SQL disabled, DCAT not-found answers counted as successes, and notebook cells for calls that fetched nothing.
The homepage simplification moved the admin shortcut into the sidebar, which is collapsed by default, so admins no longer saw it. The top bar gets it back (icon-only on phones); the sidebar link stays.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The Fair Store mirrored source metadata, but none of the qsv profiling behind Verikan's search — stats, frequency tables, AI descriptions — reached it. It also ran only locally. Deploying and verifying it against the full catalogs (WPRDC, data.dathere.com, data.pa.gov) exposed further problems:
Partial reads looked like empty results.
CKANClient.actionreturns{}for any failure. One 502 while paging a source's organizations would have moved the unseen organizations' datasets to the portal root on--apply. A failed Socrata Discovery call would have dropped every data.pa.gov agency.Retries could double DataStore rows. A retried insert, or a failed
datastore_deleteon a rerun, could append a table's rows a second time.Some qsv output described the wrong file. Onboarding writes qsv output once per dataset directory, so two WPRDC datasets carried stats, frequency and AI text computed from a different CSV. describegpt also sometimes answers
Tagswith a capital T, which dropped the AI tags from 21 datasets.describegpt's provenance block leaked into the summaries. Its command line and model details appeared in about a third of them; the API key was already redacted.
Running it needed a terminal. Mirroring, checking and configuring the Fair Store meant SSH, a token file and the CLI. Verikan's chat couldn't use it either: its records hold metadata only, so loading a mirrored resource from the Fair Store returns nothing.
The Admin button disappeared from the chat page. The homepage simplification moved it into the sidebar, which is collapsed by default.
Change
Mirror (
scripts/populate_fairstore.py)--site allmirrors every registered portal, CKAN and DCAT. The Socrata Discovery API supplies the owning agency (the hierarchy) and the column list.qsv_*dataset fields: the AI summary (prose only), AI tags, row and column counts, the profiled columns as a JSON list, model and version;qsv statsandqsv frequencytables (DataStore tables with table views), plus the describegpt JSON._vet_profile) publishes stats, frequency and describegpt output only when it matches the profiled file's header.CKANClient.call/CKANActionError, which distinguish transient from not-found errors (action()keeps its old contract for the app);--apply.mirror_digestandqsv_digest.FAIRSTORE_API_KEY/FAIRSTORE_URL, not the app'sCKAN_*settings.Container (
docker/fairstore)SameSite=Laxon the remember-me cookie.CKAN__CSRF_PROTECTION__IGNORE_EXTENSIONS=falseandCKAN__UPLOADS_ENABLED=trueare set explicitly.Deployment (
deploy/fairstore, new)PROJECT=<id> deploy/fairstore/deploy.shis idempotent. It runs one Compute Engine VM with CKAN on uwsgi, Postgres, Solr, Redis, and Caddy for automatic HTTPS (<ip>.sslip.iountil DNS is pointed at the VM).Verikan ↔ Fair Store (
gateway/fairstore.py, Admin → Fair Store)FAIRSTORE_URL/FAIRSTORE_API_KEY.--qsv-source):sync_to_storagenow writessync_manifest.json(CSV headers, dataset directories, qsv outputs present), last;Agent hardening found while testing
"limit": "100") crashed loads and were written raw into notebook code.Admin button
Validation
Ruff passes. The full suite passes: 1014 passed, 2 skipped. 35 new focused tests cover:
A deployed instance was mirrored from all three portals and checked against a local reference store, dataset by dataset:
Idempotency: a converged rerun plans 0 writes except genuine source drift, and takes about 2 minutes.
Resilience: a full VM reboot recovers by itself (site back in about 70 s, firewall rules re-applied, tokens still valid).
Several rounds of review and verification checked the code and the live deployment, with each finding re-checked by a second pass that tried to refute it. Everything confirmed is fixed here.
134 more tests (
tests/unit/test_fairstore_link.py) cover the Fair Store link:Local and storage-staged mirror runs of the 110 WPRDC profiles produced identical writes and digests, removals included. A dry run staged from the storage backend against the deployed Fair Store planned 0 qsv changes, the same as the local run.
Chat questions answered through the deployed Fair Store:
The admin pane was checked in a browser against the deployed Fair Store, and the Admin button on desktop and at phone width.
Not in this PR
_extract_qsv_tagspreviously missed.