5 May 2026 – 8 June 2026
The session began with a request to port the CWVA main server from Groovy/Jetty to Python, driven by three converging pressures: Apache Jena's JSON-LD 1.0→1.1 breaking change (requiring a Java upgrade the Groovy server couldn't easily absorb), the desire for an open-source publishable codebase, and GCP deployment simplification. The existing server was live at visualartsdna.org v4.0.4 throughout development, serving as a comparison baseline.
FastAPI + Uvicorn was chosen over Flask for async support and Claude Code compatibility. RDFLib + owlrl replaced Apache Jena for RDF storage and RDFS inferencing. The two-server architecture (main port 80 + function port 8080) was retained in concept but the Python port consolidated the main server as a standalone deliverable. The JSON-LD intermediate serialization used in the Groovy Browser page was replaced with a direct RDFLib graph → property/value dict approach via a new rdf2html.py module. Static assets served from the main server via FastAPI's StaticFiles mount — no CDN.
The SPARQL browser remained delegated to the function server (intentionally, as an abuse protection boundary), while all operational SPARQL queries run within the main server.
Five of the planned seven stages were completed in this session:
Stage 1 — Foundation: Server bootstrap, RSON config loading, GCP bucket sync, TTL folder loading into discrete stores, HTTP routing skeleton.
Stage 2 — Data Layer: Merged common store with owlrl RDFS inferencing, policy updates (license/copyright append, skos:Collection creation), URI rehosting for local/dev vs. production.
Stage 3 — Gallery & Browser: Gallery pagination and filtering, Browser page via rdf2html.py, JSON-LD replaced with direct RDFLib rendering.
Stage 4 — Concepts, Explore, About: Vocabulary tree, Cytoscape.js + dagre interactive ontology/thesaurus graphs (replacing static Graphviz SVGs), SPARQL browser proxy, metrics dashboard, About page.
Stage 5 — Hardening: Token-authenticated admin endpoints (/cmd, /status/os), GCP snapshot-on-shutdown, cross-language Java-to-Python token validation, logging.
Stages 6 (Ask page / AI agent) and 7 (formal open source release hardening) were scoped but deferred.
owlrl boolean expansion bug — the most involved diagnostic in the session. Four tensegrity properties declared rdfs:range xsd:int caused owlrl to materialize both xsd:integer and xsd:int shadow triples for every boolean value in the graph, massively inflating the store. Diagnosed through progressive testing before fix.
Metrics pipeline rewrite — original RDFLib/TTL approach took 24 minutes; replaced with pure Python aggregation running in 7.5 seconds. Extracted as standalone metricsCompiler.py.
WSL2 networking — root-relative URLs required throughout all generated HTML due to WSL2 port-proxy behavior.
RDFLib timezone grouping bug — str(?dt) cast required for correct date sorting in SPARQL.
Namespace prefix auto-generation (ns1/ns2) — fixed by copying namespace bindings from source graph to derived graphs before serialization.
JavaScript const redeclaration — SyntaxError in gallery JS, resolved during hardening.
Three successful smoke tests including a Windows bare-bones deployment. Sample data created with fictional artist "John van Gough." Published to GitHub at visualartsdna-org/cwvaServer-py under MIT license.
Content structure established: metacontent (model/vocab) in a separate cwvaMetacontent repository; user content in cwvaContent; images excluded via .gitignore.
CLAUDE.mdROADMAP.mdVISION.md — manifesto for a decentralized federated artist catalog networkDATA_GUIDE.mdDATABASE.md — Apache Jena Fuseki + TDB2 scale deployment pathDBTESTPLAN.mdinstallOptions.mdvisualartsdna.org/images/architecture.png, referenced from the System Documentation collection on the live serverThe final portion of the session scoped concept_agent.py — a curation and tagging pipeline querying Fuseki via SPARQL and calling the Anthropic API. Key design decisions: SKOS thesaurus integration, validation pipeline, RDF origin records for each tagged concept.
A vad:hasSummary document summary feature was added: a 100–150 word critical abstract generated in the same Claude API call as the tagging, stored as a datatype property in TTL, rendered by rdf2html.py as a styled block above the property table for criticism document instances. Two entries were written for concept_agent_design.md (Section 14) and ROADMAP.md capturing this design.
The port succeeded fully through Stage 5. The primary technical risk — the owlrl inferencing behavior with typed properties — was uncovered and resolved during development rather than in production. The metrics pipeline rewrite was an unplanned but significant improvement. The architecture is cleaner than the Groovy original: single framework, no Java version dependency, open-source ready, GCP-deployable. The concept agent work at the end of the session established the foundation for what became the extended concept_agent.py development arc in subsequent sessions.