<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nicola Lorenzini</title>
    <description>The latest articles on DEV Community by Nicola Lorenzini (@n4k48).</description>
    <link>https://dev.to/n4k48</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4109403%2F4a623210-d465-431a-96c5-7d7c164681f4.png</url>
      <title>DEV Community: Nicola Lorenzini</title>
      <link>https://dev.to/n4k48</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/n4k48"/>
    <language>en</language>
    <item>
      <title>From a Local MVP to an Independently Operated Node: N4K48 ↔ MyZubster Interoperability Is Now TESTED</title>
      <dc:creator>Nicola Lorenzini</dc:creator>
      <pubDate>Wed, 07 Oct 2026 16:29:01 +0000</pubDate>
      <link>https://dev.to/n4k48/from-a-local-mvp-to-an-independently-operated-node-n4k48-myzubster-interoperability-is-now-tested-3h4h</link>
      <guid>https://dev.to/n4k48/from-a-local-mvp-to-an-independently-operated-node-n4k48-myzubster-interoperability-is-now-tested-3h4h</guid>
      <description>&lt;h1&gt;
  
  
  From a Local MVP to an Independently Operated Node: N4K48 ↔ MyZubster Interoperability Is Now TESTED
&lt;/h1&gt;

&lt;p&gt;Over the last few weeks, I have been working on a question that sounds simple but becomes much more interesting once you try to prove it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can an independently operated MyZubster MVP communicate with the wider MyZubster ecosystem without sharing its filesystem, database, or local administrative control?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Today, I can document a concrete answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yes — for a bounded technical interoperability path, this has now been TESTED.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is not a claim that the architecture is fully decentralized.&lt;/p&gt;

&lt;p&gt;It is not yet direct peer-to-peer communication.&lt;/p&gt;

&lt;p&gt;It is not a production-readiness or security-certification claim.&lt;/p&gt;

&lt;p&gt;What we have instead is something I consider much more useful at this stage of development:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a reproducible technical checkpoint backed by code, hashes, tests, public evidence, and an explicit list of what remains unproven.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Where N4K48 started
&lt;/h2&gt;

&lt;p&gt;My independent development repository is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;N4K48 / MyZubster MVP&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The wider MyZubster ecosystem is developed here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MyZubster Ecosystem&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/MyZubster-Ecosystem/myzubster" rel="noopener noreferrer"&gt;https://github.com/MyZubster-Ecosystem/myzubster&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My local MVP has gradually evolved into an evidence-first experimental environment combining several components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;observation and provenance APIs;&lt;/li&gt;
&lt;li&gt;semantic retrieval with Qdrant;&lt;/li&gt;
&lt;li&gt;local AI through Ollama;&lt;/li&gt;
&lt;li&gt;an OpenAI-compatible RAG interface;&lt;/li&gt;
&lt;li&gt;Zorgax read-only interaction;&lt;/li&gt;
&lt;li&gt;a local experimental MYZ ledger;&lt;/li&gt;
&lt;li&gt;economic simulation;&lt;/li&gt;
&lt;li&gt;the Nicola Comics catalog;&lt;/li&gt;
&lt;li&gt;Docker-based service isolation;&lt;/li&gt;
&lt;li&gt;deterministic tests around evidence retrieval.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The principle behind the project has remained simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;retrieval is not truth, generation is not evidence, and a successful demo is not automatically proof of a larger architectural claim.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That principle became particularly important when we started working on interoperability.&lt;/p&gt;




&lt;h2&gt;
  
  
  The interoperability challenge
&lt;/h2&gt;

&lt;p&gt;Running software locally is one thing.&lt;/p&gt;

&lt;p&gt;Running two environments under different administrative boundaries and proving that they can exchange a bounded job and result is something else.&lt;/p&gt;

&lt;p&gt;The tested path is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MyZubster VPS&lt;br&gt;&lt;br&gt;
→ authenticated Bridge / broker&lt;br&gt;&lt;br&gt;
→ contributor-controlled N4K48 Docker agent&lt;br&gt;&lt;br&gt;
→ local MyZubster catalog&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The N4K48 environment remains independently administered.&lt;/p&gt;

&lt;p&gt;The Bridge does not receive access to my local filesystem or database.&lt;/p&gt;

&lt;p&gt;The agent communicates through a deliberately constrained interface and retrieves the required information from the local catalog API.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;The objective was not to simulate decentralization by putting several containers on one machine.&lt;/p&gt;

&lt;p&gt;The objective was to begin separating &lt;strong&gt;administrative control&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The live test
&lt;/h2&gt;

&lt;p&gt;A controlled interoperability test was performed between the MyZubster VPS infrastructure and my N4K48 environment.&lt;/p&gt;

&lt;p&gt;The remote Bridge created a bounded &lt;code&gt;gallery&lt;/code&gt; job.&lt;/p&gt;

&lt;p&gt;My independently running N4K48 agent received it, contacted the local catalog and returned four expected catalog entries.&lt;/p&gt;

&lt;p&gt;The observed titles were:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Dall’idea software al metaverso&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Il software prende forma&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Verso Neon Plaza&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Il ponte da costruire&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result reached the Bridge with:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;state: done&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Repeated reads during the permitted TTL returned the same result.&lt;/p&gt;

&lt;p&gt;After expiration, the Bridge returned:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{"error":"expired"}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That TTL behavior is important because interoperability is not only about obtaining a successful response.&lt;/p&gt;

&lt;p&gt;The lifecycle of the response must also behave predictably.&lt;/p&gt;

&lt;p&gt;The upstream MyZubster checkpoint is publicly documented here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/MyZubster-Ecosystem/myzubster/pull/1545#issuecomment-6041485188" rel="noopener noreferrer"&gt;https://github.com/MyZubster-Ecosystem/myzubster/pull/1545#issuecomment-6041485188&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My detailed N4K48 interoperability record is here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/docs/N4K48_INTEROPERABILITY_2026-10-07.md" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/docs/N4K48_INTEROPERABILITY_2026-10-07.md&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Verifying the software that actually ran
&lt;/h2&gt;

&lt;p&gt;I did not want the test to depend only on statements such as “the container was running” or “it looked correct.”&lt;/p&gt;

&lt;p&gt;The N4K48 agent used for the checkpoint has this SHA-256:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;75ab34d21f668fa48383ac7070c717b074c868694c3042928e4532b5ccd34fa1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The hash was verified inside the running Docker container.&lt;/p&gt;

&lt;p&gt;The agent ran without publishing network ports.&lt;/p&gt;

&lt;p&gt;The local catalog remained behind the contributor-controlled environment.&lt;/p&gt;

&lt;p&gt;This gives us a much more precise statement than simply saying two systems were “connected.”&lt;/p&gt;

&lt;p&gt;We can identify the artifact that ran and compare it against the expected artifact.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hardening the node after the interoperability test
&lt;/h2&gt;

&lt;p&gt;Passing the first test created another question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How should an independently operated node handle its Bridge credential?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first rule was straightforward:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;credentials do not belong in Git.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After the controlled live test, the plaintext token was removed.&lt;/p&gt;

&lt;p&gt;The encrypted credential was moved outside the repository.&lt;/p&gt;

&lt;p&gt;The test container was stopped.&lt;/p&gt;

&lt;p&gt;The host environment variables used for the Bridge session were cleared.&lt;/p&gt;

&lt;p&gt;The repository was then checked again to ensure that credential material had not accidentally become an untracked Git artifact.&lt;/p&gt;

&lt;p&gt;But I wanted to go further.&lt;/p&gt;




&lt;h2&gt;
  
  
  Moving the local credential to Windows DPAPI
&lt;/h2&gt;

&lt;p&gt;The N4K48 environment currently runs on Windows with Docker.&lt;/p&gt;

&lt;p&gt;For the next local hardening step, I migrated the node token to Windows DPAPI using the &lt;code&gt;CurrentUser&lt;/code&gt; protection scope.&lt;/p&gt;

&lt;p&gt;The resulting credential is stored outside the Git repository.&lt;/p&gt;

&lt;p&gt;The important boundary is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;the repository contains the launcher logic, not the credential.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The DPAPI-protected credential can be decrypted by the appropriate Windows user when the node needs to start.&lt;/p&gt;

&lt;p&gt;No plaintext token file needs to live inside the project.&lt;/p&gt;

&lt;p&gt;I then built a PowerShell launcher that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;retrieves the DPAPI-protected credential;&lt;/li&gt;
&lt;li&gt;decrypts it for the current user;&lt;/li&gt;
&lt;li&gt;keeps the plaintext credential in memory;&lt;/li&gt;
&lt;li&gt;starts the N4K48 Docker agent;&lt;/li&gt;
&lt;li&gt;passes the required Bridge configuration;&lt;/li&gt;
&lt;li&gt;verifies the SHA-256 of &lt;code&gt;/app/agent.py&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;clears the host environment variables afterward;&lt;/li&gt;
&lt;li&gt;clears the local byte buffer used for the decrypted credential;&lt;/li&gt;
&lt;li&gt;refuses to create a second agent when one already exists.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was tested end-to-end.&lt;/p&gt;

&lt;p&gt;The resulting node started successfully.&lt;/p&gt;

&lt;p&gt;The agent hash matched.&lt;/p&gt;

&lt;p&gt;No host port was published.&lt;/p&gt;

&lt;p&gt;After startup, the Bridge token, Bridge URL and local catalog configuration were no longer present as environment variables in the parent PowerShell session.&lt;/p&gt;

&lt;p&gt;The container was subsequently stopped and, because it runs with &lt;code&gt;--rm&lt;/code&gt;, removed automatically.&lt;/p&gt;

&lt;p&gt;This is not presented as the final secret-management architecture.&lt;/p&gt;

&lt;p&gt;The running Docker container still requires access to its authentication material.&lt;/p&gt;

&lt;p&gt;For a future persistent deployment I want explicit credential rotation, revocation and a more complete managed secret lifecycle.&lt;/p&gt;

&lt;p&gt;But compared with storing a token in the repository or leaving plaintext credentials on disk, this is a meaningful operational improvement.&lt;/p&gt;




&lt;h2&gt;
  
  
  Testing the checkpoint
&lt;/h2&gt;

&lt;p&gt;After the lifecycle changes, I reran the tests.&lt;/p&gt;

&lt;p&gt;N4K48 Bridge agent tests:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;13 / 13 passed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Complete MyZubster MVP test suite:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;77 / 77 passed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I also ran Git whitespace/diff validation before creating the checkpoint.&lt;/p&gt;

&lt;p&gt;The new checkpoint is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;89ca1b5 — feat: harden N4K48 bridge agent lifecycle&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bridge/Dockerfile&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bridge/agent.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bridge/test_agent.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scripts/start-n4k48-agent.ps1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The checkpoint is available on:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pilot/n4k48-tested-checkpoint&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What has actually been demonstrated?
&lt;/h2&gt;

&lt;p&gt;I think this is the most important section.&lt;/p&gt;

&lt;p&gt;Software projects — especially projects involving AI, distributed systems, blockchain or decentralization — can easily move from a successful experiment to claims much larger than the evidence supports.&lt;/p&gt;

&lt;p&gt;So here is the boundary.&lt;/p&gt;

&lt;h3&gt;
  
  
  TESTED
&lt;/h3&gt;

&lt;p&gt;We have tested technical interoperability between:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a MyZubster VPS-side Bridge and an independently administered N4K48 environment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The test crossed an administrative boundary.&lt;/p&gt;

&lt;p&gt;The N4K48 node processed an authenticated remote job.&lt;/p&gt;

&lt;p&gt;It retrieved information from its own local environment.&lt;/p&gt;

&lt;p&gt;It returned the expected result.&lt;/p&gt;

&lt;p&gt;The Bridge observed the result lifecycle through expiration.&lt;/p&gt;

&lt;p&gt;The agent artifact was hash-verified.&lt;/p&gt;

&lt;p&gt;The implementation has automated tests.&lt;/p&gt;

&lt;p&gt;The credential is not stored in the Git repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  NOT YET PROVEN
&lt;/h3&gt;

&lt;p&gt;This does &lt;strong&gt;not&lt;/strong&gt; prove:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;complete decentralization;&lt;/li&gt;
&lt;li&gt;direct contributor-to-contributor P2P networking;&lt;/li&gt;
&lt;li&gt;elimination of the central Bridge/broker;&lt;/li&gt;
&lt;li&gt;Byzantine fault tolerance;&lt;/li&gt;
&lt;li&gt;production readiness;&lt;/li&gt;
&lt;li&gt;security certification;&lt;/li&gt;
&lt;li&gt;general scientific or clinical validity;&lt;/li&gt;
&lt;li&gt;unrestricted interoperability with every MyZubster contributor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are separate checkpoints.&lt;/p&gt;

&lt;p&gt;And they should remain separate until they are actually tested.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I think the administrative boundary matters
&lt;/h2&gt;

&lt;p&gt;Docker alone does not make software decentralized.&lt;/p&gt;

&lt;p&gt;Running five containers on one administrator's server is still one administrative domain.&lt;/p&gt;

&lt;p&gt;For me, the more interesting transition begins when independently controlled environments can communicate using a defined protocol without requiring shared:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;filesystems;&lt;/li&gt;
&lt;li&gt;databases;&lt;/li&gt;
&lt;li&gt;operating-system privileges;&lt;/li&gt;
&lt;li&gt;administrator accounts;&lt;/li&gt;
&lt;li&gt;private infrastructure access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why I consider this interoperability checkpoint important.&lt;/p&gt;

&lt;p&gt;It is not the destination.&lt;/p&gt;

&lt;p&gt;It is evidence that we can start moving toward it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The next step: a second independent contributor
&lt;/h2&gt;

&lt;p&gt;The next major checkpoint is intentionally harder.&lt;/p&gt;

&lt;p&gt;I want to reproduce interoperability with a &lt;strong&gt;second independently administered contributor environment&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The proposed test is consent-gated.&lt;/p&gt;

&lt;p&gt;No contributor should be silently enrolled into an experiment simply because their GitHub account appears somewhere in an ecosystem.&lt;/p&gt;

&lt;p&gt;Before a second-node test, the participating contributor must explicitly opt in and the test must freeze:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;repository;&lt;/li&gt;
&lt;li&gt;branch;&lt;/li&gt;
&lt;li&gt;commit;&lt;/li&gt;
&lt;li&gt;protocol/fixture version;&lt;/li&gt;
&lt;li&gt;expected result;&lt;/li&gt;
&lt;li&gt;test commands;&lt;/li&gt;
&lt;li&gt;evidence format;&lt;/li&gt;
&lt;li&gt;limitations;&lt;/li&gt;
&lt;li&gt;rollback/stop procedure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The environment must genuinely be independently administered.&lt;/p&gt;

&lt;p&gt;It must not share the N4K48 filesystem, database or administrative privileges.&lt;/p&gt;

&lt;p&gt;The proposed second-contributor test plan is public here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/docs/SECOND_CONTRIBUTOR_INTEROPERABILITY_TEST_PLAN.md" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/docs/SECOND_CONTRIBUTOR_INTEROPERABILITY_TEST_PLAN.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The wider contributor discussion is here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/MyZubster-Ecosystem/myzubster/issues/1520" rel="noopener noreferrer"&gt;https://github.com/MyZubster-Ecosystem/myzubster/issues/1520&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Only after a reproducible second-node PASS should I describe that checkpoint as tested.&lt;/p&gt;




&lt;h2&gt;
  
  
  Toward Bridge Protocol v1
&lt;/h2&gt;

&lt;p&gt;There is another problem that becomes visible as soon as a second node enters the picture.&lt;/p&gt;

&lt;p&gt;If interoperability depends on undocumented assumptions, it does not scale.&lt;/p&gt;

&lt;p&gt;We therefore need to freeze the contract between Bridge and node.&lt;/p&gt;

&lt;p&gt;I have started a draft for:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;N4K48 Bridge Protocol v1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The current proposal covers concepts including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;protocol versioning;&lt;/li&gt;
&lt;li&gt;job envelopes;&lt;/li&gt;
&lt;li&gt;job IDs;&lt;/li&gt;
&lt;li&gt;leases;&lt;/li&gt;
&lt;li&gt;actions;&lt;/li&gt;
&lt;li&gt;payloads;&lt;/li&gt;
&lt;li&gt;expiration;&lt;/li&gt;
&lt;li&gt;result envelopes;&lt;/li&gt;
&lt;li&gt;capability negotiation;&lt;/li&gt;
&lt;li&gt;error semantics;&lt;/li&gt;
&lt;li&gt;authentication boundaries;&lt;/li&gt;
&lt;li&gt;conformance fixtures;&lt;/li&gt;
&lt;li&gt;credential lifecycle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The draft is here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/docs/N4K48_BRIDGE_PROTOCOL_V1_DRAFT.md" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/docs/N4K48_BRIDGE_PROTOCOL_V1_DRAFT.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the word &lt;strong&gt;DRAFT&lt;/strong&gt; matters.&lt;/p&gt;

&lt;p&gt;The exact wire contract still needs joint review and agreement before it should be called a stable protocol.&lt;/p&gt;




&lt;h2&gt;
  
  
  From interoperability toward federation
&lt;/h2&gt;

&lt;p&gt;My longer-term technical path now looks approximately like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local MVP&lt;br&gt;&lt;br&gt;
→ independently administered N4K48 node&lt;br&gt;&lt;br&gt;
→ authenticated Bridge interoperability — TESTED&lt;br&gt;&lt;br&gt;
→ stable Bridge protocol&lt;br&gt;&lt;br&gt;
→ second independent node&lt;br&gt;&lt;br&gt;
→ cross-node evidence verification&lt;br&gt;&lt;br&gt;
→ redundant delivery routes&lt;br&gt;&lt;br&gt;
→ broker failure testing&lt;br&gt;&lt;br&gt;
→ federation&lt;br&gt;&lt;br&gt;
→ measurable decentralization criteria&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a slower way to use the word “decentralized.”&lt;/p&gt;

&lt;p&gt;I think it is also a more useful one.&lt;/p&gt;

&lt;p&gt;Instead of starting with the claim and trying to justify it afterward, I want each architectural property to correspond to an observable test.&lt;/p&gt;

&lt;p&gt;If the broker remains a single point of dependency, document it.&lt;/p&gt;

&lt;p&gt;If nodes cannot discover each other, document it.&lt;/p&gt;

&lt;p&gt;If evidence cannot be independently verified, document it.&lt;/p&gt;

&lt;p&gt;If failure recovery has not been tested, document it.&lt;/p&gt;

&lt;p&gt;Then build the next experiment.&lt;/p&gt;




&lt;h2&gt;
  
  
  MyZubster and the evidence-first approach
&lt;/h2&gt;

&lt;p&gt;The wider MyZubster project is available here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/MyZubster-Ecosystem/myzubster" rel="noopener noreferrer"&gt;https://github.com/MyZubster-Ecosystem/myzubster&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The public repository describes an ecosystem involving evidence and provenance, Zorgax-assisted workflows, participant pilots, community infrastructure and several experimental technical paths.&lt;/p&gt;

&lt;p&gt;My N4K48 repository is an independently operated MVP and contributor-side experimentation environment:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The relationship I am trying to build between these environments is therefore not “trust everything because it belongs to the same project.”&lt;/p&gt;

&lt;p&gt;It is closer to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;produce → identify → exchange → verify → reproduce → then make the claim.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That distinction also matters for AI.&lt;/p&gt;

&lt;p&gt;An AI-generated answer is not automatically evidence.&lt;/p&gt;

&lt;p&gt;Semantic retrieval is not automatically truth.&lt;/p&gt;

&lt;p&gt;A hash proves integrity relative to some bytes; it does not automatically prove that the underlying real-world statement is true.&lt;/p&gt;

&lt;p&gt;A blockchain transaction proves that something was recorded according to the properties of that chain; it does not magically validate every semantic claim attached to it.&lt;/p&gt;

&lt;p&gt;And a successful distributed-system test proves the bounded behavior that was actually exercised — not every future property of the architecture.&lt;/p&gt;

&lt;p&gt;This is the engineering philosophy I want to continue applying to N4K48.&lt;/p&gt;




&lt;h2&gt;
  
  
  An open invitation to developers
&lt;/h2&gt;

&lt;p&gt;If you work on distributed systems, local-first software, agent interoperability, provenance, verifiable evidence, Docker isolation or decentralized architectures, I would be interested in technical review.&lt;/p&gt;

&lt;p&gt;In particular, I would value feedback on:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How should independently administered contributor nodes negotiate capabilities and verify results without turning the central broker into a permanent trust anchor?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is one of the questions behind the next phase.&lt;/p&gt;

&lt;p&gt;You can inspect the code and evidence directly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;N4K48 / MyZubster MVP&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MyZubster Ecosystem&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/MyZubster-Ecosystem/myzubster" rel="noopener noreferrer"&gt;https://github.com/MyZubster-Ecosystem/myzubster&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;N4K48 interoperability evidence&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/docs/N4K48_INTEROPERABILITY_2026-10-07.md" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/docs/N4K48_INTEROPERABILITY_2026-10-07.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Public VPS ↔ N4K48 PASS checkpoint&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/MyZubster-Ecosystem/myzubster/pull/1545#issuecomment-6041485188" rel="noopener noreferrer"&gt;https://github.com/MyZubster-Ecosystem/myzubster/pull/1545#issuecomment-6041485188&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bridge Protocol v1 draft&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/docs/N4K48_BRIDGE_PROTOCOL_V1_DRAFT.md" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/docs/N4K48_BRIDGE_PROTOCOL_V1_DRAFT.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second contributor interoperability test plan&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/docs/SECOND_CONTRIBUTOR_INTEROPERABILITY_TEST_PLAN.md" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/docs/SECOND_CONTRIBUTOR_INTEROPERABILITY_TEST_PLAN.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contributor interoperability discussion&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/MyZubster-Ecosystem/myzubster/issues/1520" rel="noopener noreferrer"&gt;https://github.com/MyZubster-Ecosystem/myzubster/issues/1520&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;This checkpoint is small compared with the architecture I ultimately want to test.&lt;/p&gt;

&lt;p&gt;But it is real.&lt;/p&gt;

&lt;p&gt;A remote authenticated job crossed from the MyZubster infrastructure into an independently administered N4K48 environment.&lt;/p&gt;

&lt;p&gt;The local agent processed it.&lt;/p&gt;

&lt;p&gt;The expected catalog result came back.&lt;/p&gt;

&lt;p&gt;The lifecycle behaved as expected.&lt;/p&gt;

&lt;p&gt;The artifact was hash-verified.&lt;/p&gt;

&lt;p&gt;The tests passed.&lt;/p&gt;

&lt;p&gt;The credential lifecycle was hardened afterward.&lt;/p&gt;

&lt;p&gt;And the remaining limitations are documented rather than hidden.&lt;/p&gt;

&lt;p&gt;That is enough for me to call this milestone:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TESTED.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not “fully decentralized.”&lt;/p&gt;

&lt;p&gt;Not “finished.”&lt;/p&gt;

&lt;p&gt;Not “production certified.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tested. Reproducible. Inspectable. Ready for the next experiment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And the next experiment is where things become even more interesting:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;one Bridge, multiple independently administered nodes — and eventually, no single Bridge that has to be trusted at all.&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  opensource #decentralization #distributedSystems #docker #ai #interoperability #buildinpublic #github #myzubster #n4k48
&lt;/h1&gt;

</description>
      <category>nicola</category>
      <category>myzubster</category>
      <category>zorgax</category>
      <category>docker</category>
    </item>
    <item>
      <title>From Comics to Code: Building MyZubster One Piece of Evidence at a Time</title>
      <dc:creator>Nicola Lorenzini</dc:creator>
      <pubDate>Sat, 03 Oct 2026 20:25:32 +0000</pubDate>
      <link>https://dev.to/n4k48/from-comics-to-code-building-myzubster-one-piece-of-evidence-at-a-time-489i</link>
      <guid>https://dev.to/n4k48/from-comics-to-code-building-myzubster-one-piece-of-evidence-at-a-time-489i</guid>
      <description>&lt;p&gt;From Comics to Code: Building MyZubster One Piece of Evidence at a Time&lt;br&gt;
It started with a comic.&lt;br&gt;
N4K48 visually represented a journey: a software idea taking shape and imagining its path into the MyZubster metaverse.&lt;br&gt;
Those panels were not screenshots of a finished product. They were not proof of a fully decentralized platform. They were a representation of something we wanted to build.&lt;br&gt;
Then we started turning that narrative into verifiable software.&lt;br&gt;
From Storytelling to Evidence&lt;br&gt;
One of the questions that emerged during development was surprisingly simple:&lt;br&gt;
How can an AI system distinguish between something that was actually recorded and something that merely sounds plausible?&lt;br&gt;
For MyZubster, the answer is increasingly becoming:&lt;br&gt;
Start with evidence.&lt;br&gt;
An observation enters the system with an identifier. It is persisted, indexed, and made searchable.&lt;br&gt;
Qdrant provides semantic retrieval. Ollama provides local AI inference. A RAG layer connects questions, retrieved sources, and generation.&lt;br&gt;
But while testing the system, we discovered something more important than simply proving that “RAG works.”&lt;br&gt;
We saw how easily a language model can take a correct source and still produce an incorrect answer.&lt;br&gt;
For example, MyZubster contains a real observation:&lt;br&gt;
ID: 21089771b2a73a9f&lt;br&gt;
Description: Test reale MyZubster RC2 - N4K48&lt;/p&gt;

&lt;p&gt;Semantic retrieval correctly found that observation.&lt;br&gt;
But when we asked the model to describe it, the model could still introduce additional statements that were not supported by the retrieved evidence.&lt;br&gt;
That changed the way we approached the problem.&lt;br&gt;
Retrieval Is Not the Same as Truth&lt;br&gt;
We started separating two problems that are often treated as if they were the same:&lt;br&gt;
Finding information and deciding what the system is allowed to claim based on that information.&lt;br&gt;
We introduced a deterministic path for observation IDs.&lt;br&gt;
If a request contains an existing observation ID, MyZubster prefers the exact observation over semantic similarity.&lt;br&gt;
If the ID looks valid but does not exist, the system does not silently search for something similar and use that as a substitute.&lt;br&gt;
Instead, it returns:&lt;br&gt;
Informazione non disponibile nelle fonti MyZubster.&lt;/p&gt;

&lt;p&gt;In English:&lt;br&gt;
Information is not available in the MyZubster sources.&lt;/p&gt;

&lt;p&gt;This sounds like a small behavior change.&lt;br&gt;
It is not.&lt;br&gt;
It means that absence of evidence is no longer treated as permission to generate a plausible substitute.&lt;br&gt;
Sometimes the AI Should Not Generate&lt;br&gt;
We found the same problem with descriptions.&lt;br&gt;
When a user explicitly asks for the description contained in the evidence, why should a language model rewrite it?&lt;br&gt;
We tested exactly that.&lt;br&gt;
The correct evidence was:&lt;br&gt;
Test reale MyZubster RC2 - N4K48&lt;/p&gt;

&lt;p&gt;Yet a small local model could turn it into a longer response containing claims that were never present in the source.&lt;br&gt;
So we changed the architecture.&lt;br&gt;
When MyZubster can answer an authoritative question directly from the retrieved evidence, it can bypass generation and return the evidence verbatim.&lt;br&gt;
The result becomes:&lt;br&gt;
Test reale MyZubster RC2 - N4K48&lt;/p&gt;

&lt;p&gt;Nothing added.&lt;br&gt;
Nothing “improved.”&lt;br&gt;
Nothing invented.&lt;br&gt;
That led us to an important design principle:&lt;br&gt;
When the software already knows the fact, we do not necessarily need AI to reinvent the answer.&lt;/p&gt;

&lt;p&gt;AI becomes useful where interpretation and synthesis are actually required—not as an unavoidable intermediary between the user and every piece of stored evidence.&lt;br&gt;
Local AI, Connected to Evidence&lt;br&gt;
The current prototype connects several components:&lt;br&gt;
User&lt;br&gt;
  ↓&lt;br&gt;
Open WebUI&lt;br&gt;
  ↓&lt;br&gt;
OpenAI-compatible MyZubster API&lt;br&gt;
  ↓&lt;br&gt;
Retrieval / deterministic evidence paths&lt;br&gt;
  ↓&lt;br&gt;
Qdrant&lt;br&gt;
  ↓&lt;br&gt;
MyZubster evidence&lt;br&gt;
  ↓&lt;br&gt;
Ollama when generation is actually needed&lt;br&gt;
  ↓&lt;br&gt;
Answer&lt;/p&gt;

&lt;p&gt;We exposed the MyZubster RAG system through an OpenAI-compatible API, allowing Open WebUI to use myzubster-rag as a model.&lt;br&gt;
That gave us a practical end-to-end environment in which we could test the entire path from the user interface to the underlying evidence.&lt;br&gt;
And the tests uncovered real architectural problems.&lt;br&gt;
At one point, an observation existed in persistent storage but was missing from Qdrant.&lt;br&gt;
That exposed another important distinction:&lt;br&gt;
stored data and searchable data are not automatically the same thing.&lt;br&gt;
So we added an explicit observation-index recovery mechanism capable of rebuilding the search index from persisted observations.&lt;br&gt;
Again, this is not primarily about making a chatbot answer questions.&lt;br&gt;
It is about being able to understand where an answer came from and whether the underlying evidence can be recovered.&lt;br&gt;
From Software to Decentralization&lt;br&gt;
This is where decentralization enters the story.&lt;br&gt;
And this distinction matters:&lt;br&gt;
MyZubster does not become decentralized simply because we use local AI, hashes, identifiers, or an internal ledger.&lt;br&gt;
A digitally recorded event is not automatically a blockchain event.&lt;br&gt;
A database entry is not automatically decentralized evidence.&lt;br&gt;
We have deliberately tried to preserve those distinctions in the prototype.&lt;br&gt;
The more interesting question is:&lt;br&gt;
If evidence originates inside MyZubster today, how could someone verify it tomorrow without having to blindly trust MyZubster itself?&lt;/p&gt;

&lt;p&gt;That is where decentralization becomes meaningful.&lt;br&gt;
Hashes, provenance, identities, attestations, and externally verifiable records can eventually allow evidence to move beyond the trust boundary of a single application.&lt;br&gt;
But before decentralizing evidence, we need to know exactly what is being attested.&lt;br&gt;
That is one reason we are building the evidence layer first.&lt;br&gt;
Decentralization without provenance can simply distribute uncertainty.&lt;br&gt;
From the Comic to the Commit History&lt;br&gt;
The N4K48 comic represented a vision.&lt;br&gt;
The software is slowly turning parts of that vision into properties we can actually test.&lt;br&gt;
Some of the latest checkpoints tell that story:&lt;br&gt;
16f0800  fix: add observation index recovery&lt;br&gt;
d1aa48f  fix: prefer exact observation ID retrieval&lt;br&gt;
8106276  fix: reject unknown observation IDs safely&lt;br&gt;
87a1021  fix: return authoritative descriptions verbatim&lt;/p&gt;

&lt;p&gt;The interesting part is not the commit count.&lt;br&gt;
It is the progression.&lt;br&gt;
First, recover the evidence.&lt;br&gt;
Then make sure an exact identifier retrieves the exact evidence.&lt;br&gt;
Then make sure a nonexistent identifier cannot silently become “something similar.”&lt;br&gt;
Then prevent the language model from rewriting an authoritative description when no generation is necessary.&lt;br&gt;
Each step removes a little ambiguity from the system.&lt;br&gt;
Evidence First, Generation Second&lt;br&gt;
This is gradually becoming one of the core ideas behind MyZubster:&lt;br&gt;
Observe&lt;br&gt;
   ↓&lt;br&gt;
Record&lt;br&gt;
   ↓&lt;br&gt;
Preserve&lt;br&gt;
   ↓&lt;br&gt;
Retrieve&lt;br&gt;
   ↓&lt;br&gt;
Verify&lt;br&gt;
   ↓&lt;br&gt;
Generate only when necessary&lt;/p&gt;

&lt;p&gt;Most AI systems are designed around the final step.&lt;br&gt;
We are increasingly interested in everything that happens before it.&lt;br&gt;
Because an eloquent answer is not necessarily a grounded answer.&lt;br&gt;
A semantically similar document is not necessarily the requested evidence.&lt;br&gt;
A model saying something confidently does not turn it into a recorded fact.&lt;br&gt;
And a decentralized record is only useful if we understand what that record actually proves.&lt;br&gt;
Where This Is Going&lt;br&gt;
The goal of MyZubster is not to build an AI that appears to know everything.&lt;br&gt;
The more interesting goal is to build a system that becomes increasingly capable of distinguishing between:&lt;br&gt;
what was observed,&lt;br&gt;
what was recorded,&lt;br&gt;
what can be retrieved,&lt;br&gt;
what can be verified,&lt;br&gt;
and what the AI generated.&lt;br&gt;
There is still a lot to solve.&lt;br&gt;
Generic semantic questions can still retrieve partially relevant context. Small local models can still infer things that the evidence does not say. Provenance can become stronger. Verification can extend beyond the boundaries of one application. And decentralization remains a direction to build and test rather than a label to attach prematurely.&lt;br&gt;
But that is exactly why this journey is interesting.&lt;br&gt;
It started with comic panels imagining a world.&lt;br&gt;
Now we are working on the less spectacular—but perhaps more important—part:&lt;br&gt;
giving that world a verifiable memory.&lt;br&gt;
From comics to evidence.&lt;br&gt;
From evidence to software.&lt;br&gt;
From software to verification.&lt;br&gt;
From verification toward decentralization.&lt;br&gt;
And this time, every step should leave evidence behind.&lt;/p&gt;

</description>
      <category>nicola</category>
      <category>n4k48</category>
      <category>myzubster</category>
      <category>ai</category>
    </item>
    <item>
      <title>Building Verifiable Knowledge in MyZubster: From Stable Evidence IDs to Proof v3</title>
      <dc:creator>Nicola Lorenzini</dc:creator>
      <pubDate>Wed, 30 Sep 2026 22:49:47 +0000</pubDate>
      <link>https://dev.to/n4k48/building-verifiable-knowledge-in-myzubster-from-stable-evidence-ids-to-proof-v3-kob</link>
      <guid>https://dev.to/n4k48/building-verifiable-knowledge-in-myzubster-from-stable-evidence-ids-to-proof-v3-kob</guid>
      <description>&lt;p&gt;Building Verifiable Knowledge in MyZubster: From Stable Evidence IDs to Proof v3&lt;br&gt;
Tonight I worked on a part of MyZubster that I find particularly interesting: making a Knowledge Card not only readable, but traceable and verifiable.&lt;br&gt;
The task started as a relatively focused frontend issue and ended up touching several important concepts: stable evidence identity, deduplication, versioned proofs, cryptographic digests, blockchain attestations, deployment verification, and contributor rewards.&lt;br&gt;
The result is now running in production.&lt;br&gt;
The starting point&lt;br&gt;
MyZubster has a Knowledge Graph where a Knowledge Card can be connected to multiple pieces of evidence.&lt;br&gt;
For the card used during this work:&lt;br&gt;
6abaaefb3a7460c4574a45fd&lt;br&gt;
the graph contains normal sources as well as cryptographic proof information.&lt;br&gt;
The first requirement was deceptively simple:&lt;br&gt;
When selecting the Proof filter, both Proof v2 and Proof v3 should appear as separate and independently identifiable attestations.&lt;/p&gt;

&lt;p&gt;But there were several constraints.&lt;br&gt;
Normal evidence had to remain normal evidence.&lt;br&gt;
Proof records had to be recognized separately.&lt;br&gt;
Proof v2 history could not be rewritten just to accommodate v3.&lt;br&gt;
Duplicate URLs could not produce duplicate nodes.&lt;br&gt;
And the stable IDs introduced in the previous work had to remain stable across refreshes and reimports.&lt;br&gt;
In other words, this wasn't simply:&lt;br&gt;
if label contains "proof":&lt;br&gt;
    show proof&lt;/p&gt;

&lt;p&gt;That would have been fragile.&lt;br&gt;
Stable evidence identity first&lt;br&gt;
Before working on Proof v3, the graph already had another important improvement: evidence nodes were given stable SRC-* identifiers.&lt;br&gt;
That matters more than it might initially appear.&lt;br&gt;
If a graph generates arbitrary node identities every time data is imported, refreshed or reordered, the visual representation may look correct while its identity model is unstable.&lt;br&gt;
For evidence systems, that's a problem.&lt;br&gt;
A source should remain the same source when the page reloads.&lt;br&gt;
So the model became conceptually:&lt;br&gt;
Knowledge Card&lt;br&gt;
    |&lt;br&gt;
    +-- SRC-...&lt;br&gt;
    +-- SRC-...&lt;br&gt;
    +-- SRC-...&lt;/p&gt;

&lt;p&gt;with deterministic identity rather than presentation-dependent identity.&lt;br&gt;
That foundation became important when introducing versioned proofs.&lt;br&gt;
Proof is not just another source&lt;br&gt;
The next problem was classification.&lt;br&gt;
A Knowledge Card can have ordinary evidence:&lt;br&gt;
source&lt;br&gt;
source&lt;br&gt;
source&lt;/p&gt;

&lt;p&gt;but it can also contain evidence describing an attestation:&lt;br&gt;
digest&lt;br&gt;
contract&lt;br&gt;
transaction&lt;br&gt;
documentation&lt;br&gt;
payload&lt;/p&gt;

&lt;p&gt;Those records collectively describe something different from a normal source.&lt;br&gt;
They describe a proof.&lt;br&gt;
The implementation therefore moved toward recognizing structured fields where available, such as concepts equivalent to:&lt;br&gt;
type: proof&lt;br&gt;
proofVersion: 3&lt;br&gt;
proofRole: digest&lt;/p&gt;

&lt;p&gt;rather than relying exclusively on human-readable labels.&lt;br&gt;
Textual detection remains useful as a fallback for legacy data, but structured metadata is considerably safer.&lt;br&gt;
The important distinction becomes:&lt;br&gt;
normal evidence → source&lt;/p&gt;

&lt;p&gt;versioned attestation evidence → proof&lt;/p&gt;

&lt;p&gt;Grouping evidence into versioned proofs&lt;br&gt;
Once proof evidence can be recognized, individual records can be grouped by version.&lt;br&gt;
Conceptually:&lt;br&gt;
Proof v2&lt;br&gt;
 ├── digest&lt;br&gt;
 ├── contract&lt;br&gt;
 ├── transaction&lt;br&gt;
 └── documentation&lt;/p&gt;

&lt;p&gt;Proof v3&lt;br&gt;
 ├── digest&lt;br&gt;
 ├── contract&lt;br&gt;
 ├── transaction&lt;br&gt;
 └── documentation&lt;/p&gt;

&lt;p&gt;This is much more useful to a reader than exposing every technical reference as an unrelated graph node.&lt;br&gt;
The graph can represent the attestation as an object, while still retaining the references required to inspect it.&lt;br&gt;
The Proof v3 attestation&lt;br&gt;
The Proof v3 used for this Knowledge Card includes a SHA-256 digest and an Ethereum Sepolia attestation.&lt;br&gt;
The digest is:&lt;br&gt;
d1c89d2a4157a159b56e92825ca59fdb&lt;br&gt;
1f0e84e003b05e022af67da69ed25ac4&lt;/p&gt;

&lt;p&gt;The Sepolia contract is:&lt;br&gt;
0x3233fA7f8c50Aa25d9B1263c25F28535B6eA59bF&lt;/p&gt;

&lt;p&gt;and the deployment/attestation references can be associated with the corresponding payload and documentation.&lt;br&gt;
The important idea isn't simply that "something is on a blockchain."&lt;br&gt;
The useful relationship is:&lt;br&gt;
Knowledge&lt;br&gt;
   ↓&lt;br&gt;
canonical payload&lt;br&gt;
   ↓&lt;br&gt;
SHA-256&lt;br&gt;
   ↓&lt;br&gt;
attestation&lt;br&gt;
   ↓&lt;br&gt;
independent verification&lt;/p&gt;

&lt;p&gt;The blockchain reference doesn't magically prove that the knowledge itself is true.&lt;br&gt;
What it can help establish is that a particular cryptographic commitment existed and can be compared against a particular payload.&lt;br&gt;
That distinction is essential in any serious provenance system.&lt;br&gt;
A bug that looked correct until the graph was inspected&lt;br&gt;
After the first implementation, the deployment built successfully, but visual verification revealed an interesting problem.&lt;br&gt;
The Proof filter showed something equivalent to:&lt;br&gt;
Proof v2&lt;br&gt;
Proof v2&lt;br&gt;
SRC-...&lt;br&gt;
SRC-...&lt;br&gt;
SRC-...&lt;/p&gt;

&lt;p&gt;while Proof v3 wasn't represented correctly.&lt;br&gt;
There were actually two different problems.&lt;br&gt;
The historical Proof v2 path already existed, while dynamically grouping evidence created another v2 representation.&lt;br&gt;
At the same time, raw evidence used to construct a proof remained visible as ordinary SRC-* nodes.&lt;br&gt;
So even though the underlying information existed, the semantic representation was wrong.&lt;br&gt;
That is why visual acceptance testing mattered here.&lt;br&gt;
Unit tests alone weren't enough.&lt;br&gt;
Deduplicating the graph&lt;br&gt;
Once evidence has been aggregated into a proof object, exposing the exact same evidence again as raw graph nodes creates noise and potentially misleading duplication.&lt;br&gt;
The graph therefore needed another rule:&lt;br&gt;
if evidence has already been consumed by a grouped proof:&lt;br&gt;
    don't render it again as an independent source&lt;/p&gt;

&lt;p&gt;The final Proof view became much cleaner:&lt;br&gt;
             PROOF V3&lt;br&gt;
                 |&lt;br&gt;
                 |&lt;br&gt;
             K-4A45FD&lt;br&gt;
              /     \&lt;br&gt;
             /       \&lt;br&gt;
       PROOF V2     SHA-256&lt;/p&gt;

&lt;p&gt;No duplicate Proof v2.&lt;br&gt;
No raw proof SRC-* nodes leaking into the Proof filter.&lt;br&gt;
And, importantly, Proof v3 is visibly connected to the Knowledge Card.&lt;br&gt;
The isolated-node problem&lt;br&gt;
One of the final bugs was purely structural.&lt;br&gt;
Proof v3 existed.&lt;br&gt;
It rendered correctly.&lt;br&gt;
Its metadata was correct.&lt;br&gt;
But visually it was floating above the Knowledge Card without an edge.&lt;br&gt;
That may sound cosmetic, but in a knowledge graph an edge carries meaning.&lt;br&gt;
A node that isn't connected to the card doesn't clearly communicate:&lt;br&gt;
this proof attests to this Knowledge Card&lt;/p&gt;

&lt;p&gt;So the edge construction was extended to include versioned proof nodes.&lt;br&gt;
After redeployment, the intended relationship became visible:&lt;br&gt;
K-4A45FD → PROOF V3&lt;/p&gt;

&lt;p&gt;while preserving the historical Proof v2 chain.&lt;br&gt;
CI also taught us something&lt;br&gt;
During the work, several repository-wide CI workflows failed.&lt;br&gt;
It would have been easy to interpret:&lt;br&gt;
red CI = my change is broken&lt;/p&gt;

&lt;p&gt;But inspecting the logs showed failures in existing Zorgax/Seller-related backend tests unrelated to the Knowledge Graph modification.&lt;br&gt;
That distinction matters.&lt;br&gt;
A contributor shouldn't ignore failing CI.&lt;br&gt;
But a contributor also shouldn't start modifying unrelated systems simply to turn every check green.&lt;br&gt;
The useful workflow was:&lt;br&gt;
CI fails&lt;br&gt;
   ↓&lt;br&gt;
inspect exact failing suites&lt;br&gt;
   ↓&lt;br&gt;
determine relationship to current diff&lt;br&gt;
   ↓&lt;br&gt;
fix regressions caused by the change&lt;br&gt;
   ↓&lt;br&gt;
keep unrelated failures separately tracked&lt;/p&gt;

&lt;p&gt;This prevented MYZ-209 from expanding into an unrelated backend repair project.&lt;br&gt;
Preview before merge&lt;br&gt;
Another useful part of the workflow was refusing to treat a successful build as final acceptance.&lt;br&gt;
The sequence was approximately:&lt;br&gt;
implementation&lt;br&gt;
     ↓&lt;br&gt;
tests&lt;br&gt;
     ↓&lt;br&gt;
Vercel preview&lt;br&gt;
     ↓&lt;br&gt;
visual graph verification&lt;br&gt;
     ↓&lt;br&gt;
fix&lt;br&gt;
     ↓&lt;br&gt;
new preview&lt;br&gt;
     ↓&lt;br&gt;
final verification&lt;br&gt;
     ↓&lt;br&gt;
merge&lt;/p&gt;

&lt;p&gt;Daniel Ioni performed the final preview verification and confirmed that the Proof filter contained the expected distinct nodes without duplicates.&lt;br&gt;
Only then was the PR merged.&lt;br&gt;
PR:&lt;/p&gt;

&lt;h1&gt;
  
  
  25
&lt;/h1&gt;

&lt;p&gt;MYZ-209: expose versioned Proof v3 in Knowledge Graph&lt;/p&gt;

&lt;p&gt;Merge commit:&lt;br&gt;
157fc5edf7440a732c489a918efe6be8e34888c3&lt;/p&gt;

&lt;p&gt;Production verification&lt;br&gt;
After the merge and production deployment, I performed another verification against the public Knowledge Card.&lt;br&gt;
The production Proof filter now shows:&lt;br&gt;
PROOF V3&lt;br&gt;
MyZubsterProof v3 · Sepolia&lt;/p&gt;

&lt;p&gt;SHA-256&lt;br&gt;
Digest del payload&lt;/p&gt;

&lt;p&gt;PROOF V2&lt;br&gt;
MyZubsterProof · Sepolia&lt;/p&gt;

&lt;p&gt;There are no duplicate raw proof sources in that filtered view.&lt;br&gt;
The Knowledge Card is visibly connected to Proof v3.&lt;br&gt;
And switching back to the complete graph shows Proof v2 and Proof v3 coexisting with the ordinary SRC-* evidence nodes.&lt;br&gt;
So the production result matches the verified preview.&lt;br&gt;
MYZ-209 is complete.&lt;br&gt;
What I learned from this&lt;br&gt;
The interesting part of this task wasn't adding another node to a React page.&lt;br&gt;
It was dealing with the boundary between data, evidence and proof.&lt;br&gt;
These concepts shouldn't be collapsed into one another.&lt;br&gt;
A source can support knowledge.&lt;br&gt;
A digest can identify a payload.&lt;br&gt;
An attestation can commit to a digest.&lt;br&gt;
A transaction can provide independently inspectable evidence that an attestation occurred.&lt;br&gt;
But none of those things, individually, should be described as magically proving that a statement is true.&lt;br&gt;
A more useful model is:&lt;br&gt;
KNOWLEDGE&lt;br&gt;
    |&lt;br&gt;
    +--- SOURCES&lt;br&gt;
    |&lt;br&gt;
    +--- PROVENANCE&lt;br&gt;
    |&lt;br&gt;
    +--- PAYLOAD&lt;br&gt;
             |&lt;br&gt;
             SHA-256&lt;br&gt;
             |&lt;br&gt;
         ATTESTATION&lt;br&gt;
             |&lt;br&gt;
       VERIFICATION&lt;/p&gt;

&lt;p&gt;That is the direction I want to keep exploring with MyZubster.&lt;br&gt;
Contributor rewards&lt;br&gt;
There was also another interesting outcome from this contribution.&lt;br&gt;
After MYZ-209 was accepted, I asked whether the contribution qualified for a MyZubster contributor reward.&lt;br&gt;
Daniel confirmed a reward of:&lt;br&gt;
250 MYZ&lt;/p&gt;

&lt;p&gt;for:&lt;br&gt;
N4K48 / nicolaususnicola-lgtm&lt;/p&gt;

&lt;p&gt;One important clarification: under the current MyZubster model, MYZ is an internal reward/accounting unit. It should not be confused with an on-chain token, fiat payment or guaranteed conversion into another asset.&lt;br&gt;
A ledger reference, MYZ-LEDGER-000002, was communicated for this contribution.&lt;br&gt;
At the time of writing, however, I have not yet independently located that entry in the public repository, so I'm treating the reward assignment as confirmed by the maintainer while the public ledger reference is still awaiting independent verification.&lt;br&gt;
I think that distinction is worth publishing rather than hiding.&lt;br&gt;
If we're building systems around verifiable knowledge, the same standard should apply to contributor rewards.&lt;br&gt;
Claim what the evidence supports. Clearly label what is still pending verification.&lt;br&gt;
What's next?&lt;br&gt;
The next step isn't simply adding more proofs.&lt;br&gt;
It's making the relationship between knowledge, evidence, provenance and attestations increasingly structured and independently inspectable.&lt;br&gt;
For me, that's the interesting question behind this work:&lt;br&gt;
Can a knowledge platform show not only what it knows, but also why a claim is present, where its evidence came from, which payload was attested, and how someone else can verify that history?&lt;/p&gt;

&lt;p&gt;Tonight's work moved MyZubster another step in that direction.&lt;br&gt;
Project: MyZubster&lt;br&gt;
Task: MYZ-209&lt;br&gt;
Contribution: Proof v3 visibility and versioned proof handling&lt;br&gt;
Contributor: N4K48 / nicolaususnicola-lgtm&lt;br&gt;
Status: merged and verified in production&lt;br&gt;
Reward: 250 MYZ confirmed; public ledger entry awaiting independent verification&lt;/p&gt;

&lt;h1&gt;
  
  
  opensource #react #web3 #blockchain #provenance #knowledgegraph #javascript #buildinpublic
&lt;/h1&gt;

</description>
      <category>myzubster</category>
      <category>github</category>
      <category>n4k48</category>
      <category>opensource</category>
    </item>
    <item>
      <title>From Local AI to Ethereum: Building a Verifiable Knowledge Proof with MyZubster</title>
      <dc:creator>Nicola Lorenzini</dc:creator>
      <pubDate>Wed, 30 Sep 2026 20:52:34 +0000</pubDate>
      <link>https://dev.to/n4k48/from-local-ai-to-ethereum-building-a-verifiable-knowledge-proof-with-myzubster-g1d</link>
      <guid>https://dev.to/n4k48/from-local-ai-to-ethereum-building-a-verifiable-knowledge-proof-with-myzubster-g1d</guid>
      <description>&lt;h1&gt;
  
  
  From Local AI to Ethereum: Building a Verifiable Knowledge Proof with MyZubster
&lt;/h1&gt;

&lt;p&gt;Over the last few weeks, I've been experimenting with a simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can the things I learn and build become verifiable evidence instead of just claims on a profile?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Together with the MyZubster project and with AI-assisted development, I built and tested a proof-of-concept that connects local software experiments, GitHub evidence, a Knowledge Card, cryptographic hashing and Ethereum Sepolia.&lt;/p&gt;

&lt;p&gt;The current flow looks like this:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
text
N4K48
  ↓
real work and local tests
  ↓
GitHub evidence
  ↓
MyZubster Knowledge Card
  ↓
canonical payload
  ↓
SHA-256
  ↓
Ethereum Sepolia
  ↓
Knowledge Proof Verifier
  ↓
Knowledge Graph

This is still an experiment, but we now have a complete reproducible path.
1. Starting locally: Docker + AI + RAG
The work started inside myzubster-mvp.
I built and tested a local environment involving:
- Docker / Docker Compose
- Ollama
- Qdrant
- Open WebUI
- Python / Flask APIs
- local knowledge ingestion
- RAG retrieval
One of the concrete improvements was changing the knowledge chunking and testing a new ingestion.
The resulting ingestion loaded 46 knowledge chunks into Qdrant while skipping one empty document.
I also tested retrieval through the API and adjusted the AI context limit so the expected GitHub context could be retrieved.
Repository:
https://github.com/nicolaususnicola-lgtm/myzubster-mvp
2. Turning the work into a Knowledge Card
Instead of describing this work only in a README or profile, I created a public MyZubster Knowledge Card:
https://www.myzubster.com/knowledge-card?id=6abaaefb3a7460c4574a45fd
The card connects the activity to supporting evidence such as:
- the repository;
- commits;
- local test descriptions;
- Proof documentation;
- Ethereum contracts;
- deployment transactions;
- the Knowledge Proof Verifier.
The important idea is that the profile claim and the evidence remain separate.
The evidence supports inspection.
It doesn't automatically certify the claim.
3. Proof v1: proving the URL
The first Ethereum experiment was intentionally simple.
I calculated a SHA-256 digest from the Knowledge Card URL and stored it in a small Solidity contract on Ethereum Sepolia.
That proved that I could create a public on-chain anchor.
But it also exposed an important limitation:
hashing the URL is not the same as hashing the content.
So we moved to a second version.
4. Proof v2: hashing the canonical payload
For Proof v2, I created a stable JSON representation of the Knowledge Card.
Instead of hashing the URL, the system hashes the exact payload bytes.
The SHA-256 was:
6097e05866bafceec24663d2638cb1dae5742ac78284abbfd45cc9c3b0bfb845

That value was stored as bytes32 in a new Sepolia contract.
The public knowledgeHash() value could then be read and compared with the locally calculated digest.
This was much closer to the model I wanted:
content
  → exact bytes
  → SHA-256
  → bytes32
  → public blockchain

5. Building a repeatable verifier
Manually comparing hashes is useful during an experiment, but it isn't a good verification interface.
So the next step was MYZ-213: a repeatable Knowledge Proof Verifier.
The verifier:
1. reads the exact saved payload bytes;
2. calculates SHA-256;
3. reads knowledgeHash() from the Sepolia contract;
4. compares the values;
5. reports one of the meaningful outcomes:
MATCH
NO_MATCH
ERROR

It also includes tests for an altered payload and an unavailable RPC endpoint.
The verifier was merged through PR #16:
https://github.com/nicolaususnicola-lgtm/myzubster-mvp/pull/16
No private key is required for verification.
No signature is required.
No transaction is required.
Verification uses public, read-only Ethereum RPC calls.
6. Proof v3: verifying the updated knowledge payload
After adding the new development evidence, I created a third payload.
The exact committed v3 payload is:
proofs/knowledge-card-6abaaefb3a7460c4574a45fd-v3.json

Size:
5083 bytes

SHA-256:
d1c89d2a4157a159b56e92825ca59fdb1f0e84e003b05e022af67da69ed25ac4

I reproduced this digest locally using both sha256sum and Python hashlib.
Then I deployed another MyZubsterProof contract to Ethereum Sepolia.
Contract:
0x3233fA7f8c50Aa25d9B1263c25F28535B6eA59bF

Deployment transaction:
0x5c7717be6dc70e6416f8053c72bb1e2bec2b7c5462b23fcb9c4b1077f907fed4

Reading the contract directly returned:
0xd1c89d2a4157a159b56e92825ca59fdb1f0e84e003b05e022af67da69ed25ac4

Exactly the same value as the locally calculated payload digest.
Then I ran the Knowledge Proof Verifier.
The result was:
{
  "status": "MATCH",
  "payload_sha256": "d1c89d2a4157a159b56e92825ca59fdb1f0e84e003b05e022af67da69ed25ac4",
  "calculated_bytes32": "0xd1c89d2a4157a159b56e92825ca59fdb1f0e84e003b05e022af67da69ed25ac4",
  "onchain_bytes32": "0xd1c89d2a4157a159b56e92825ca59fdb1f0e84e003b05e022af67da69ed25ac4",
  "payload_matches_onchain": true,
  "payload_matches_expected": true,
  "network": "Ethereum Sepolia",
  "chain_id": 11155111
}

That was the key milestone.
The same value existed in:
committed payload
      ↓
local SHA-256
      ↓
expected bytes32
      ↓
Sepolia knowledgeHash()

And the verifier returned:
MATCH

Proof v3 documentation:
https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/proofs/SEPOLIA_PROOF_V3.md
7. Connecting it to a Knowledge Graph
The next layer is the MyZubster Knowledge Graph.
The goal is to make this path navigable:
N4K48
 ↓
Knowledge Card
 ↓
contribution
 ↓
GitHub evidence
 ↓
payload
 ↓
SHA-256
 ↓
Ethereum proof

During testing we confirmed that the graph contains a single N4K48 node and a single node for the Knowledge Card.
We also found something useful:
after updating the Knowledge Card with the latest GitHub evidence, the new sources were not yet automatically reflected in the graph.
That's not something to hide.
It's exactly the kind of integration issue this pilot is designed to discover.
The automatic synchronization between updated Knowledge Cards and graph evidence still needs work.
8. What does MATCH actually prove?
This distinction is important.
A MATCH does not mean:
"Everything this person says is true."

It does not automatically certify a professional skill.
It does not automatically prove identity or ownership of every linked artifact.
What it does demonstrate is much narrower and more technically useful:
The exact payload bytes being verified produce the same cryptographic digest as the value stored in the referenced public blockchain contract.

That gives us integrity and provenance evidence.
Other forms of verification can be layered on top later.
9. What I learned
This project connected several areas that I had previously been testing separately:
- local AI and RAG;
- Docker environments;
- Ollama and Qdrant;
- Python APIs;
- GitHub commits and pull requests;
- CI;
- canonical data representation;
- SHA-256;
- Ethereum read-only verification;
- smart contracts;
- Knowledge Cards;
- Knowledge Graphs;
- AI-assisted development.
More importantly, it changed the way I think about a digital profile.
Instead of:
I say I know X

the model can move toward:
I say I know X
      ↓
here is what I did
      ↓
here is the source
      ↓
here is the artifact
      ↓
here is its fingerprint
      ↓
here is a public attestation
      ↓
verify it yourself

What's next?
There is still plenty to build.
The next steps include improving Knowledge Graph synchronization, finishing more end-to-end testing, simplifying the verification UX, and exploring interoperable attestation and credential standards.
The long-term goal isn't to put every piece of personal information on a blockchain.
It's to make useful evidence easier to inspect, reproduce and verify.
For me, this experiment has already reached an important milestone:
local work became documented evidence, the evidence became an exact payload, the payload became a cryptographic fingerprint, and that fingerprint became independently verifiable on a public network.
I'm building this publicly as N4K48.
GitHub:
https://github.com/nicolaususnicola-lgtm
MyZubster:
https://www.myzubster.com
Knowledge Card:
https://www.myzubster.com/knowledge-card?id=6abaaefb3a7460c4574a45fd
The project is experimental and under active development.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>blockchain</category>
      <category>docker</category>
      <category>opensource</category>
    </item>
    <item>
      <title>From Local RAG to a Verifiable Knowledge Proof on Ethereum Sepolia</title>
      <dc:creator>Nicola Lorenzini</dc:creator>
      <pubDate>Mon, 28 Sep 2026 23:39:54 +0000</pubDate>
      <link>https://dev.to/n4k48/from-local-rag-to-a-verifiable-knowledge-proof-on-ethereum-sepolia-1ble</link>
      <guid>https://dev.to/n4k48/from-local-rag-to-a-verifiable-knowledge-proof-on-ethereum-sepolia-1ble</guid>
      <description>&lt;p&gt;From Local RAG to a Verifiable Knowledge Proof on Ethereum Sepolia&lt;br&gt;
How I connected Docker, Ollama, Qdrant, GitHub, a MyZubster Knowledge Card and an on-chain SHA-256 proof&lt;br&gt;
Building an AI project is one thing.&lt;br&gt;
Being able to show what was actually built, what was tested, where the evidence is, and whether a documented artifact has changed is another.&lt;br&gt;
During the development of my myzubster-mvp project, I wanted to test a simple idea:&lt;br&gt;
Can we connect a person's documented technical activity to GitHub evidence, an AI/RAG system, a public Knowledge Card, and finally a cryptographic proof recorded on a blockchain?&lt;/p&gt;

&lt;p&gt;This experiment became a small end-to-end proof-of-concept involving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker and Docker Compose&lt;/li&gt;
&lt;li&gt;Ollama&lt;/li&gt;
&lt;li&gt;Qdrant&lt;/li&gt;
&lt;li&gt;Open WebUI&lt;/li&gt;
&lt;li&gt;a local RAG pipeline&lt;/li&gt;
&lt;li&gt;GitHub commits&lt;/li&gt;
&lt;li&gt;MyZubster Knowledge Cards&lt;/li&gt;
&lt;li&gt;SHA-256&lt;/li&gt;
&lt;li&gt;a Solidity smart contract&lt;/li&gt;
&lt;li&gt;Ethereum Sepolia&lt;/li&gt;
&lt;li&gt;a Knowledge Graph
The goal was not to put personal knowledge itself on a blockchain.
The goal was to build a verifiable chain between a documented knowledge artifact and a cryptographic commitment to that artifact.&lt;/li&gt;
&lt;li&gt;Starting point: my local AI/RAG environment
The experiment started inside my public project:
Repository:
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp&lt;/a&gt;
The local stack combines MyZubster's API with Docker, Ollama, Qdrant and Open WebUI.
At a simplified level:
Documents / observations
    ↓
Ingestion
    ↓
Embeddings
    ↓
Qdrant
    ↓
Relevant context
    ↓
Local LLM through Ollama
    ↓
MyZubster AI response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the important principles behind the project is evidence first.&lt;br&gt;
The AI should not simply generate plausible answers.&lt;br&gt;
Where authoritative structured information exists, that information should remain the source of truth. RAG and the local language model can then operate over the evidence retrieved from the system.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Improving the ingestion pipeline
During testing I found that document chunking could be improved.
Instead of blindly cutting text, I modified the ingestion process so that it tries to respect paragraph and line boundaries while maintaining overlap between chunks.
The change is documented here:
Chunking commit:
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/ea80799" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/ea80799&lt;/a&gt;
After the modification, I performed a new ingestion.
The local test resulted in:
46 knowledge chunks loaded into Qdrant
1 empty document skipped&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I also tested retrieval through the MyZubster AI endpoint:&lt;br&gt;
/api/ai/ask&lt;/p&gt;

&lt;p&gt;During this work I increased the amount of retrieved AI context from 1 to 5 so that the expected GitHub/project information could be recovered more reliably.&lt;br&gt;
This gave me the first part of the evidence chain:&lt;br&gt;
Technical activity&lt;br&gt;
        ↓&lt;br&gt;
GitHub commit&lt;br&gt;
        ↓&lt;br&gt;
Local ingestion&lt;br&gt;
        ↓&lt;br&gt;
Qdrant&lt;br&gt;
        ↓&lt;br&gt;
RAG retrieval&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Turning the work into a Knowledge Card
The next step was to describe the work in a public MyZubster Knowledge Card.
The card is:
“Prove Docker e chat AI del progetto myzubster-mvp”
Public Knowledge Card:
&lt;a href="https://www.myzubster.com/knowledge-card?id=6abaaefb3a7460c4574a45fd" rel="noopener noreferrer"&gt;https://www.myzubster.com/knowledge-card?id=6abaaefb3a7460c4574a45fd&lt;/a&gt;
The card connects the activity to evidence such as the repository, Docker tests, the chunking modification and the later blockchain experiments.
This creates another layer:
N4K48
↓
Technical activity
↓
GitHub evidence
↓
Knowledge Card&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But at this point there was still an interesting question.&lt;br&gt;
How could I create a cryptographic reference to the Knowledge Card?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Proof v1: anchoring the Knowledge Card URL
The first experiment was intentionally simple.
I calculated the SHA-256 of the Knowledge Card URL string.
That digest was passed to a small Solidity contract deployed on Ethereum Sepolia.
The contract was:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;contract MyZubsterProof {&lt;br&gt;
    bytes32 public knowledgeHash;&lt;br&gt;
    address public creator;&lt;br&gt;
    uint256 public timestamp;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(bytes32 _knowledgeHash) {
    knowledgeHash = _knowledgeHash;
    creator = msg.sender;
    timestamp = block.timestamp;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;The contract stores three values:&lt;br&gt;
knowledgeHash&lt;br&gt;
creator&lt;br&gt;
timestamp&lt;/p&gt;

&lt;p&gt;Proof v1 contract&lt;br&gt;
&lt;a href="https://sepolia.etherscan.io/address/0xabCF68e97a32eCa503942A563FF16F209ed45d11#code" rel="noopener noreferrer"&gt;https://sepolia.etherscan.io/address/0xabCF68e97a32eCa503942A563FF16F209ed45d11#code&lt;/a&gt;&lt;br&gt;
Deployment transaction&lt;br&gt;
&lt;a href="https://sepolia.etherscan.io/tx/0x09dddd29aca76c9a425ba9cb45cefb1bfbe203b9628f5f9526e4a281012d4f20" rel="noopener noreferrer"&gt;https://sepolia.etherscan.io/tx/0x09dddd29aca76c9a425ba9cb45cefb1bfbe203b9628f5f9526e4a281012d4f20&lt;/a&gt;&lt;br&gt;
GitHub evidence&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/2df5b39" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/2df5b39&lt;/a&gt;&lt;br&gt;
The recorded value was:&lt;br&gt;
0x15b21c4f189259f143f6c946ac866001d88f5bc7aa371cac7cbcc1ce66b43685&lt;/p&gt;

&lt;p&gt;The contract source for this first proof was publicly verified on Etherscan as an Exact Match.&lt;br&gt;
But there was an important limitation.&lt;br&gt;
Proof v1 did not hash the Knowledge Card content&lt;br&gt;
It hashed the URL string.&lt;br&gt;
That distinction matters.&lt;br&gt;
The first experiment therefore demonstrated that I could associate a blockchain record with the identifier/location of the Knowledge Card.&lt;br&gt;
It did not cryptographically commit to the complete contents of the card.&lt;br&gt;
So we moved to a second experiment.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Proof v2: anchoring the content
For Proof v2, the objective changed.
Instead of:
Knowledge Card URL
   ↓
SHA-256&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I wanted:&lt;br&gt;
Knowledge Card&lt;br&gt;
       ↓&lt;br&gt;
Canonical payload&lt;br&gt;
       ↓&lt;br&gt;
SHA-256&lt;br&gt;
       ↓&lt;br&gt;
Ethereum Sepolia&lt;/p&gt;

&lt;p&gt;The content used for the proof was stored in the GitHub repository so that the artifact being referenced is publicly inspectable.&lt;br&gt;
Canonical payload:&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/proofs/knowledge-card-6abaaefb3a7460c4574a45fd-v1.json" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/proofs/knowledge-card-6abaaefb3a7460c4574a45fd-v1.json&lt;/a&gt;&lt;br&gt;
The corresponding GitHub commit is:&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/ecefd81c5c9da0be15c99aeeb83878480abd60a8" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/ecefd81c5c9da0be15c99aeeb83878480abd60a8&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Calculating the SHA-256
The SHA-256 used for Proof v2 is:
6097e05866bafceec24663d2638cb1dae5742ac78284abbfd45cc9c3b0bfb845&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As a Solidity bytes32 value:&lt;br&gt;
0x6097e05866bafceec24663d2638cb1dae5742ac78284abbfd45cc9c3b0bfb845&lt;/p&gt;

&lt;p&gt;The important point is that the proof refers to the exact payload bytes committed to the repository.&lt;br&gt;
Anyone with those bytes can independently calculate their SHA-256 and compare the result with the value used in the proof.&lt;br&gt;
For example:&lt;br&gt;
sha256sum proofs/knowledge-card-6abaaefb3a7460c4574a45fd-v1.json&lt;/p&gt;

&lt;p&gt;Or with Python:&lt;br&gt;
import hashlibfrom pathlib import Pathdata = Path(    "proofs/knowledge-card-6abaaefb3a7460c4574a45fd-v1.json").read_bytes()print(hashlib.sha256(data).hexdigest())&lt;/p&gt;

&lt;p&gt;The expected result is:&lt;br&gt;
6097e05866bafceec24663d2638cb1dae5742ac78284abbfd45cc9c3b0bfb845&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Registering Proof v2 on Ethereum Sepolia
A new MyZubsterProof instance was deployed for Proof v2.
Contract
&lt;a href="https://sepolia.etherscan.io/address/0x21787249Df054132093FcF09bB914C0CCC539390" rel="noopener noreferrer"&gt;https://sepolia.etherscan.io/address/0x21787249Df054132093FcF09bB914C0CCC539390&lt;/a&gt;
Deployment transaction
&lt;a href="https://sepolia.etherscan.io/tx/0xc837ba3f3046f3712e3eba4b81107cb22939b61300f2cab3cfe5bbb7b3319ded" rel="noopener noreferrer"&gt;https://sepolia.etherscan.io/tx/0xc837ba3f3046f3712e3eba4b81107cb22939b61300f2cab3cfe5bbb7b3319ded&lt;/a&gt;
Network:
Ethereum Sepolia
Chain ID: 11155111&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After deployment I reconnected to the contract and called:&lt;br&gt;
knowledgeHash()&lt;/p&gt;

&lt;p&gt;The returned value was:&lt;br&gt;
0x6097e05866bafceec24663d2638cb1dae5742ac78284abbfd45cc9c3b0bfb845&lt;/p&gt;

&lt;p&gt;This matches the digest documented for the committed payload.&lt;br&gt;
That gives us the core verification relationship:&lt;br&gt;
GitHub payload&lt;br&gt;
      │&lt;br&gt;
      │ SHA-256&lt;br&gt;
      ▼&lt;br&gt;
6097e05866bafce...&lt;br&gt;
      │&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
MyZubsterProof&lt;br&gt;
Ethereum Sepolia&lt;br&gt;
      │&lt;br&gt;
      │ knowledgeHash()&lt;br&gt;
      ▼&lt;br&gt;
6097e05866bafce...&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Making the proof reproducible
A blockchain transaction by itself is not enough for a useful technical experiment.
Someone examining the project also needs to understand:&lt;/li&gt;
&lt;li&gt;what artifact was hashed;&lt;/li&gt;
&lt;li&gt;which digest was expected;&lt;/li&gt;
&lt;li&gt;where the artifact is stored;&lt;/li&gt;
&lt;li&gt;which contract contains the commitment;&lt;/li&gt;
&lt;li&gt;which transaction deployed it;&lt;/li&gt;
&lt;li&gt;how to reproduce the hash calculation.
For this reason I added dedicated Proof v2 documentation to GitHub:
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/proofs/SEPOLIA_PROOF_V2.md" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/proofs/SEPOLIA_PROOF_V2.md&lt;/a&gt;
Documentation commit:
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/405467e8d7b4e55ea9f18044a00aa66804f3ada3" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/405467e8d7b4e55ea9f18044a00aa66804f3ada3&lt;/a&gt;
This turns the blockchain experiment into something closer to a reproducible evidence record rather than an isolated transaction hash.&lt;/li&gt;
&lt;li&gt;Updating the main README
One problem remained.
The evidence existed, but somebody arriving on the repository homepage might never discover it.
So I added a dedicated section to the main README:
Knowledge Card → Ethereum Sepolia Proof v2
The README now exposes the verification path directly:
N4K48
↓
Knowledge Card
↓
canonical payload
↓
SHA-256
↓
Proof v2 Sepolia
↓
GitHub documentation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Repository:&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp&lt;/a&gt;&lt;br&gt;
README update commit:&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/a4b54b86fe1066684c8604a83b3e32656b7429d7" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/a4b54b86fe1066684c8604a83b3e32656b7429d7&lt;/a&gt;&lt;br&gt;
This is important from a usability perspective.&lt;br&gt;
Evidence that nobody can find is much less useful than evidence that can be navigated.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The complete evidence chain
At this stage the experiment can be represented as:
             N4K48
               │
               ▼
      Technical activity
               │
               ▼
         GitHub commits
               │
               ▼
      Local AI / RAG tests
      Docker + Ollama
      Qdrant + API
               │
               ▼
       Knowledge Card
               │
               ▼
      Canonical payload
               │
          SHA-256
               │
               ▼
   MyZubsterProof v2
    Ethereum Sepolia
               │
               ▼
   GitHub documentation
               │
               ▼
       Knowledge Graph&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the part of the experiment I find most interesting.&lt;br&gt;
The blockchain is only one component of the evidence chain.&lt;br&gt;
GitHub provides the development history and artifact.&lt;br&gt;
The Knowledge Card provides the human-readable description.&lt;br&gt;
The canonical payload provides the artifact to hash.&lt;br&gt;
SHA-256 provides the cryptographic fingerprint.&lt;br&gt;
Ethereum Sepolia provides a public location for the commitment.&lt;br&gt;
The Knowledge Graph can then provide navigation between those elements.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What did we actually prove?
This distinction is essential.
The experiment provides evidence that a particular payload corresponds to a particular SHA-256 digest and that this digest was used in the Sepolia proof.
It therefore creates a cryptographic link between:
documented artifact
    ↕
cryptographic digest
    ↕
on-chain record&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the bytes of the artifact are changed, recalculating SHA-256 will normally produce a different digest, so it will no longer match the recorded commitment.&lt;br&gt;
But this does not automatically prove that every statement inside the Knowledge Card is true.&lt;br&gt;
For example, putting the hash of a statement such as:&lt;br&gt;
"I am an expert in X"&lt;/p&gt;

&lt;p&gt;on a blockchain does not prove expertise in X.&lt;br&gt;
It proves something much narrower and more technically useful:&lt;br&gt;
this particular data can be associated with this cryptographic fingerprint and compared against the recorded commitment.&lt;/p&gt;

&lt;p&gt;That is why MyZubster keeps a distinction between:&lt;br&gt;
CLAIM&lt;br&gt;
EVIDENCE&lt;br&gt;
INTEGRITY&lt;br&gt;
VERIFICATION&lt;/p&gt;

&lt;p&gt;They are related concepts, but they are not the same thing.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Why not store the entire Knowledge Card on-chain?
Because that is not necessary for this experiment.
Instead of storing the whole document on Ethereum, we can store a fixed-size digest:
Knowledge Card content
    ↓
SHA-256
    ↓
32 bytes
    ↓
Blockchain&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The larger artifact can remain in an appropriate external repository or storage layer.&lt;br&gt;
The blockchain only needs the cryptographic commitment.&lt;br&gt;
This approach is simpler and avoids treating a blockchain as general-purpose document storage.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;From a Knowledge Card to a Knowledge Graph
The next stage is to make the relationship navigable.
The intended graph is:
N4K48
│
├── Knowledge Card
│       │
│       ├── GitHub evidence
│       │
│       └── Canonical payload
│                 │
│                 ▼
│              SHA-256
│                 │
│                 ▼
│          Proof v2 Sepolia
│                 │
│                 ├── Contract
│                 └── Transaction
│
└── Project: myzubster-mvp&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The idea is that a visitor should not simply see the statement:&lt;br&gt;
N4K48 worked on a local RAG system.&lt;/p&gt;

&lt;p&gt;They should be able to navigate from that statement toward the underlying evidence.&lt;br&gt;
This is the direction being tested with the MyZubster Knowledge Graph.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AI is useful here, but it is not the authority
Another lesson from this experiment concerns AI.
The local model is useful for:&lt;/li&gt;
&lt;li&gt;interpreting questions;&lt;/li&gt;
&lt;li&gt;summarizing retrieved context;&lt;/li&gt;
&lt;li&gt;navigating documentation;&lt;/li&gt;
&lt;li&gt;connecting relevant evidence;&lt;/li&gt;
&lt;li&gt;presenting information to a user.
But the language model should not become the authoritative source for facts already represented structurally.
For example:
GitHub commit → evidence
JSON payload → artifact
SHA-256 → fingerprint
Ethereum contract → commitment
Qdrant → retrieval
LLM → interpretation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The AI operates around the evidence, not instead of it.&lt;br&gt;
This is one of the central ideas behind the evidence-first architecture I am exploring in MyZubster.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What I learned
The most important lesson was that verifiability is not created simply by “using blockchain.”
A useful evidence system requires several layers to work together:
Human-readable description
+
source evidence
+
stable artifact
+
cryptographic digest
+
public commitment
+
reproducible verification
+
clear navigation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remove the documentation and the hash becomes difficult to interpret.&lt;br&gt;
Remove the original artifact and the digest becomes difficult to reproduce.&lt;br&gt;
Remove the distinction between claims and proofs and it becomes easy to overstate what the technology demonstrates.&lt;br&gt;
The interesting part is therefore not any single technology.&lt;br&gt;
It is the connection between them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Public references
Everything used for this experiment can be inspected through the following starting points:
MyZubster MVP repository
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp&lt;/a&gt;
Knowledge Card
&lt;a href="https://www.myzubster.com/knowledge-card?id=6abaaefb3a7460c4574a45fd" rel="noopener noreferrer"&gt;https://www.myzubster.com/knowledge-card?id=6abaaefb3a7460c4574a45fd&lt;/a&gt;
Chunking improvement
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/ea80799" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/ea80799&lt;/a&gt;
Proof v1 GitHub commit
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/2df5b39" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/2df5b39&lt;/a&gt;
Proof v1 Sepolia contract
&lt;a href="https://sepolia.etherscan.io/address/0xabCF68e97a32eCa503942A563FF16F209ed45d11#code" rel="noopener noreferrer"&gt;https://sepolia.etherscan.io/address/0xabCF68e97a32eCa503942A563FF16F209ed45d11#code&lt;/a&gt;
Canonical payload for Proof v2
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/proofs/knowledge-card-6abaaefb3a7460c4574a45fd-v1.json" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/proofs/knowledge-card-6abaaefb3a7460c4574a45fd-v1.json&lt;/a&gt;
Canonical payload commit
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/ecefd81c5c9da0be15c99aeeb83878480abd60a8" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/ecefd81c5c9da0be15c99aeeb83878480abd60a8&lt;/a&gt;
Proof v2 documentation
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/proofs/SEPOLIA_PROOF_V2.md" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/proofs/SEPOLIA_PROOF_V2.md&lt;/a&gt;
Proof v2 documentation commit
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/405467e8d7b4e55ea9f18044a00aa66804f3ada3" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/405467e8d7b4e55ea9f18044a00aa66804f3ada3&lt;/a&gt;
Proof v2 Ethereum Sepolia contract
&lt;a href="https://sepolia.etherscan.io/address/0x21787249Df054132093FcF09bB914C0CCC539390" rel="noopener noreferrer"&gt;https://sepolia.etherscan.io/address/0x21787249Df054132093FcF09bB914C0CCC539390&lt;/a&gt;
Proof v2 deployment transaction
&lt;a href="https://sepolia.etherscan.io/tx/0xc837ba3f3046f3712e3eba4b81107cb22939b61300f2cab3cfe5bbb7b3319ded" rel="noopener noreferrer"&gt;https://sepolia.etherscan.io/tx/0xc837ba3f3046f3712e3eba4b81107cb22939b61300f2cab3cfe5bbb7b3319ded&lt;/a&gt;
README integration commit
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/a4b54b86fe1066684c8604a83b3e32656b7429d7" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/a4b54b86fe1066684c8604a83b3e32656b7429d7&lt;/a&gt;
Conclusion
This started as a local Docker and AI/RAG test.
It gradually became something broader:
local development
  ↓
documented evidence
  ↓
Knowledge Card
  ↓
canonical artifact
  ↓
cryptographic fingerprint
  ↓
public blockchain commitment
  ↓
navigable Knowledge Graph&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The experiment does not turn a claim into truth simply because a hash exists on Ethereum.&lt;br&gt;
What it does demonstrate is a practical architecture for making digital knowledge records more traceable, reproducible and tamper-evident.&lt;br&gt;
And for me, that is the interesting direction:&lt;br&gt;
not replacing trust with blockchain or AI, but making the evidence behind a digital claim easier to inspect.&lt;br&gt;
N4K48 / Nicola&lt;br&gt;
Building and testing myzubster-mvp&lt;/p&gt;

&lt;h1&gt;
  
  
  ai #rag #ethereum #opensource
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>ethereum</category>
      <category>docker</category>
      <category>rag</category>
    </item>
    <item>
      <title>Building MyZubster: Docker, Local AI, RAG and the First On-Chain Proof on Ethereum Sepolia</title>
      <dc:creator>Nicola Lorenzini</dc:creator>
      <pubDate>Mon, 28 Sep 2026 22:29:17 +0000</pubDate>
      <link>https://dev.to/n4k48/building-myzubster-docker-local-ai-rag-and-the-first-on-chain-proof-on-ethereum-sepolia-3mj6</link>
      <guid>https://dev.to/n4k48/building-myzubster-docker-local-ai-rag-and-the-first-on-chain-proof-on-ethereum-sepolia-3mj6</guid>
      <description>&lt;p&gt;Building MyZubster: Docker, Local AI, RAG and the First On-Chain Proof on Ethereum Sepolia&lt;br&gt;
Today I reached an important milestone in the development of MyZubster.&lt;br&gt;
What started as a local experiment around AI-assisted knowledge retrieval has evolved into a working development stack combining Docker, Ollama, Qdrant, an API layer, Open WebUI, GitHub and Ethereum Sepolia.&lt;br&gt;
The interesting part wasn't simply getting the individual components running. The goal was to connect them into a system that could ingest knowledge, retrieve the correct context, expose it to an AI interface, and begin attaching independently verifiable proofs to knowledge artifacts.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Building the local AI stack
The first step was creating a reproducible local environment.
The development stack uses Docker Compose to orchestrate several components:&lt;/li&gt;
&lt;li&gt;Ollama for local language-model execution&lt;/li&gt;
&lt;li&gt;Qdrant as the vector database&lt;/li&gt;
&lt;li&gt;an API layer for retrieval and application logic&lt;/li&gt;
&lt;li&gt;Open WebUI as the user-facing AI interface&lt;/li&gt;
&lt;li&gt;the MyZubster application and knowledge-ingestion pipeline
This allowed the project to move from isolated scripts toward an actual integrated environment.
The repository containing the work is:
github.com/nicolaususnicola-lgtm/myzubster-mvp&lt;/li&gt;
&lt;li&gt;Building the RAG knowledge pipeline
The next challenge was knowledge ingestion.
Documents have to be transformed into chunks before embeddings can be stored in Qdrant and later retrieved by the AI system.
During testing, I found a problem in the original chunking logic: paragraph and line boundaries could produce poor chunks and potentially interfere with retrieval.
The ingestion script was therefore modified to improve the chunking strategy while:&lt;/li&gt;
&lt;li&gt;preserving useful overlap;&lt;/li&gt;
&lt;li&gt;respecting paragraph and line boundaries;&lt;/li&gt;
&lt;li&gt;avoiding loops;&lt;/li&gt;
&lt;li&gt;skipping empty documents;&lt;/li&gt;
&lt;li&gt;keeping chunks suitable for retrieval.
After the changes, the ingestion process completed successfully.
In one of the verification runs, 46 knowledge chunks were loaded into Qdrant and one empty document was skipped.
That gave us a concrete test that the modified ingestion pipeline was functioning.&lt;/li&gt;
&lt;li&gt;Testing retrieval through the API
Storing embeddings isn't enough. The important question is whether the system can retrieve the right knowledge when a user asks a question.
The RAG pipeline was therefore tested through the API endpoint.
One particularly useful discovery involved the amount of context supplied to the model.
By increasing AI_CONTEXT_LIMIT from 1 to 5, the system was able to recover the relevant context and return the expected GitHub repository information.
This was a small configuration change, but an important lesson: retrieval quality depends not only on embeddings and chunking, but also on how much retrieved context is actually made available downstream.&lt;/li&gt;
&lt;li&gt;Moving from AI knowledge to verifiable knowledge
The next experiment was more ambitious.
Instead of asking users to simply trust that a knowledge artifact existed at a particular moment, MyZubster needed a way to create an independently inspectable proof.
For this first experiment I created a Solidity smart contract called:
MyZubsterProof.sol
The contract records a bytes32 value representing a hash associated with a knowledge artifact.
The objective is deliberately simple:
the blockchain stores the proof, not the complete knowledge content.
This distinction matters.
Sensitive or large content does not need to be published on-chain. A cryptographic digest can instead provide a reference that can later be compared with the original artifact.&lt;/li&gt;
&lt;li&gt;First deployment on Ethereum Sepolia
The contract was deployed to the Ethereum Sepolia test network.
The deployment transaction is publicly inspectable through Etherscan, and the contract source was subsequently verified there with an Exact Match result.
That gives the project its first independently inspectable on-chain component.
For the development process, this was an important transition:
local experiment → public cryptographic evidence
The corresponding Solidity source and documentation were also committed to the project's GitHub repository.&lt;/li&gt;
&lt;li&gt;Connecting the evidence back to MyZubster
The next step was documenting the work as a MyZubster knowledge card.
The card contains references to:&lt;/li&gt;
&lt;li&gt;the project repository;&lt;/li&gt;
&lt;li&gt;the local Docker test;&lt;/li&gt;
&lt;li&gt;the chunking improvement commit;&lt;/li&gt;
&lt;li&gt;the Sepolia proof commit;&lt;/li&gt;
&lt;li&gt;the verified Sepolia contract;&lt;/li&gt;
&lt;li&gt;the Sepolia deployment transaction.
An interesting bug appeared here too.
The profile builder limits a knowledge card to 12 sources, and initially some sources had been entered using separate lines for title, URL and description.
The parser treated those lines as separate sources.
The expected format was actually:
name | URL | note
with one source per line.
After normalizing the source list, the card contained six sources and could be successfully saved as a private draft before publication.
It's a tiny implementation detail, but exactly the kind of thing that appears when a prototype starts becoming a real product.
What exists now
At this stage, MyZubster has demonstrated several pieces of the architecture working together:
Docker environment → knowledge ingestion → Qdrant → RAG retrieval → AI interface/API → GitHub evidence → Ethereum Sepolia proof → MyZubster knowledge card
There is still work to do.
In particular, the complete Open WebUI integration deserves additional end-to-end verification, and the relationship between knowledge cards and on-chain hashes can be automated further.
But the important milestone is that the project now has both a local AI knowledge pipeline and its first publicly inspectable blockchain proof.
Next steps
The next development phase will focus on tightening the connection between these layers.
Instead of manually creating blockchain proofs, the long-term flow could become:
Knowledge Card → canonical representation → SHA-256 → on-chain attestation → transaction reference → verification
That would allow a MyZubster knowledge artifact to carry not only sources and AI-readable context, but also a cryptographic proof that can be independently checked.
The goal isn't to put knowledge on a blockchain.
The goal is to make claims about digital knowledge more inspectable, attributable and verifiable.
And this first Sepolia deployment is a small but concrete step in that direction.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>ai</category>
      <category>docker</category>
      <category>ethereum</category>
      <category>rag</category>
    </item>
    <item>
      <title>Building a Local AI Knowledge System with Docker, Ollama, Qdrant and Open WebUI</title>
      <dc:creator>Nicola Lorenzini</dc:creator>
      <pubDate>Mon, 28 Sep 2026 18:27:45 +0000</pubDate>
      <link>https://dev.to/n4k48/building-a-local-ai-knowledge-system-with-docker-ollama-qdrant-and-open-webui-2odg</link>
      <guid>https://dev.to/n4k48/building-a-local-ai-knowledge-system-with-docker-ollama-qdrant-and-open-webui-2odg</guid>
      <description>&lt;h1&gt;
  
  
  Building a Local AI Knowledge System with Docker, Ollama, Qdrant and Open WebUI
&lt;/h1&gt;

&lt;p&gt;Today I continued experimenting with &lt;strong&gt;MyZubster&lt;/strong&gt;, an open-source project I'm working on while learning how local AI systems, knowledge retrieval and verifiable profiles can work together.&lt;/p&gt;

&lt;p&gt;The goal was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can a local AI answer questions using a personal knowledge base instead of relying only on what the language model already knows?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The stack we tested included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Ollama&lt;/li&gt;
&lt;li&gt;Qdrant&lt;/li&gt;
&lt;li&gt;Open WebUI&lt;/li&gt;
&lt;li&gt;a Python API&lt;/li&gt;
&lt;li&gt;Markdown knowledge files&lt;/li&gt;
&lt;li&gt;local embeddings&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Starting the local stack
&lt;/h2&gt;

&lt;p&gt;The project uses Docker Compose.&lt;/p&gt;

&lt;p&gt;After starting Docker Desktop, the services came online:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;api&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ollama&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;qdrant&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;open-webui&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The API reported healthy and Open WebUI became available locally.&lt;/p&gt;

&lt;p&gt;This gave us a completely local environment where we could experiment with AI retrieval without depending on a hosted LLM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the knowledge base
&lt;/h2&gt;

&lt;p&gt;The project contains Markdown documents inside a &lt;code&gt;knowledge&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;A Python ingestion script:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;reads the documents;&lt;/li&gt;
&lt;li&gt;splits them into chunks;&lt;/li&gt;
&lt;li&gt;creates embeddings using Ollama;&lt;/li&gt;
&lt;li&gt;stores the vectors and metadata in Qdrant.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The embedding model used during the experiment was:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nomic-embed-text&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After rebuilding the knowledge index, the ingestion completed with:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Loaded 40 knowledge chunks; skipped 1 empty documents&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So the pipeline itself was working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then we found an interesting problem
&lt;/h2&gt;

&lt;p&gt;We asked the AI:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the GitHub repository of N4K48? Give me the complete link without abbreviating it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The model answered confidently — but returned the wrong GitHub URL.&lt;/p&gt;

&lt;p&gt;That was useful.&lt;/p&gt;

&lt;p&gt;It showed an important distinction:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a working RAG pipeline does not automatically mean reliable answers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Docker was running.&lt;/p&gt;

&lt;p&gt;Qdrant contained the knowledge.&lt;/p&gt;

&lt;p&gt;Ollama was generating embeddings.&lt;/p&gt;

&lt;p&gt;Open WebUI could talk to the model.&lt;/p&gt;

&lt;p&gt;But somewhere between document ingestion, retrieval and generation, the information reaching the model was still not reliable enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Investigating document chunking
&lt;/h2&gt;

&lt;p&gt;The original ingestion system divided documents approximately every 1,000 characters with an overlap.&lt;/p&gt;

&lt;p&gt;That approach is simple, but arbitrary character boundaries can split meaningful information.&lt;/p&gt;

&lt;p&gt;URLs are a good example.&lt;/p&gt;

&lt;p&gt;A GitHub URL divided between chunks can become incomplete or lose the context that explains what the URL represents.&lt;/p&gt;

&lt;p&gt;So we inspected and modified the knowledge ingestion logic to make document segmentation more meaningful and reduce arbitrary cuts.&lt;/p&gt;

&lt;p&gt;Then we deleted the previous knowledge points and rebuilt the Qdrant index.&lt;/p&gt;

&lt;p&gt;The result was 40 newly generated knowledge chunks.&lt;/p&gt;

&lt;p&gt;The experiment isn't finished yet.&lt;/p&gt;

&lt;p&gt;The next step is to inspect the retrieval path between:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;question → embedding → Qdrant → retrieved knowledge → API → Ollama&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and determine exactly where the incorrect repository information is being introduced.&lt;/p&gt;

&lt;h2&gt;
  
  
  A second experiment: knowledge profiles
&lt;/h2&gt;

&lt;p&gt;At the same time, we tested the MyZubster &lt;strong&gt;Knowledge Profile Builder&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of treating every statement as verified knowledge, the Builder distinguishes between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;declared knowledge;&lt;/li&gt;
&lt;li&gt;external evidence;&lt;/li&gt;
&lt;li&gt;information still requiring verification.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We created three private knowledge drafts covering:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;professional transport experience;&lt;/li&gt;
&lt;li&gt;Docker and local AI experimentation;&lt;/li&gt;
&lt;li&gt;learning and collaboration during the MyZubster project.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The drafts were saved privately and remained available after reopening them.&lt;/p&gt;

&lt;p&gt;They are not public yet.&lt;/p&gt;

&lt;p&gt;Before publishing them, we're checking how evidence and verification should be attached to each claim.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;p&gt;The most interesting lesson wasn't that we managed to run an LLM locally.&lt;/p&gt;

&lt;p&gt;It was that &lt;strong&gt;running the model is the easy part&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The difficult part is building a trustworthy path from:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;human knowledge&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;documents&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;chunks&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;embeddings&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;retrieval&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LLM answer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Every step can change what the final model sees.&lt;/p&gt;

&lt;p&gt;And a model can produce a perfectly fluent answer even when one of those steps supplied the wrong information.&lt;/p&gt;

&lt;p&gt;That's why provenance and verification matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;The next experiments will focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inspecting Qdrant retrieval results;&lt;/li&gt;
&lt;li&gt;improving knowledge chunking;&lt;/li&gt;
&lt;li&gt;testing complete URLs and source metadata;&lt;/li&gt;
&lt;li&gt;distinguishing declared knowledge from verified evidence;&lt;/li&gt;
&lt;li&gt;testing the three Knowledge Profile drafts;&lt;/li&gt;
&lt;li&gt;improving the reliability of answers generated from the local knowledge base.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is still an experiment, and some parts are intentionally unfinished.&lt;/p&gt;

&lt;p&gt;I'll document what works — and what breaks — as the project develops.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;MyZubster / N4K48&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Building, testing and learning in public.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>docker</category>
      <category>opensource</category>
      <category>llm</category>
    </item>
    <item>
      <title>MyZubster MVP — Dev Update: dal Ledger al Revenue &amp; Cost Simulator</title>
      <dc:creator>Nicola Lorenzini</dc:creator>
      <pubDate>Fri, 18 Sep 2026 21:23:44 +0000</pubDate>
      <link>https://dev.to/n4k48/myzubster-mvp-dev-update-dal-ledger-al-revenue-cost-simulator-1djg</link>
      <guid>https://dev.to/n4k48/myzubster-mvp-dev-update-dal-ledger-al-revenue-cost-simulator-1djg</guid>
      <description>&lt;p&gt;MyZubster MVP — Dev Update: From Ledger to Revenue &amp;amp; Cost Simulation&lt;/p&gt;

&lt;p&gt;Today we took another important step in the evolution of MyZubster MVP: moving from recording economic events to a system that can also simulate revenue, costs, and margins without contaminating real accounting data.&lt;/p&gt;

&lt;p&gt;At the core is the MYZ Ledger, where economic events are recorded with explicit revenue sources, auditable allocation rules, and UTC timestamps. From these events, the system derives the MYZ Balance, while keeping internal accounting clearly separated from payments, wallets, custody, and on-chain activity.&lt;/p&gt;

&lt;p&gt;We have now introduced the Revenue &amp;amp; Cost Simulator.&lt;/p&gt;

&lt;p&gt;It allows us to model scenarios using variables such as transaction volume, average transaction value, Marketplace commission, Zorgax Pro and Developer users, payment processing assumptions, AI costs, hosting costs, and other operating costs.&lt;/p&gt;

&lt;p&gt;The calculation flow is straightforward:&lt;/p&gt;

&lt;p&gt;GMV → Marketplace + Zorgax revenue → Costs → Monthly Margin → Annualized Scenario&lt;/p&gt;

&lt;p&gt;The most important architectural rule is that a simulation never creates an economic event in the MYZ Ledger.&lt;/p&gt;

&lt;p&gt;A simulated result is not recorded revenue.&lt;br&gt;
It is not a payout.&lt;br&gt;
It is not wallet funds.&lt;br&gt;
It is not certified profit.&lt;br&gt;
And it is not a financial forecast.&lt;/p&gt;

&lt;p&gt;We verified this boundary at runtime: after running the simulator, the Ledger remained at 3 events, confirming that simulated economic data was not persisted.&lt;/p&gt;

&lt;p&gt;On the engineering side, the project has also reached 47 passing tests, covering revenue calculations, cost and margin calculations, negative-input validation, and the simulator API.&lt;/p&gt;

&lt;p&gt;The next layer is the UI: bringing the Revenue &amp;amp; Cost Simulator directly into the MyZubster dashboard alongside MYZ Balance, My Assets, Revenue History, and MYZ Ledger.&lt;/p&gt;

&lt;p&gt;The direction is becoming increasingly clear:&lt;/p&gt;

&lt;p&gt;Evidence first. Economics explicit.&lt;/p&gt;

&lt;p&gt;Don't ask AI to invent value.&lt;/p&gt;

&lt;p&gt;Record the facts.&lt;br&gt;
Declare the rules.&lt;br&gt;
Simulate the scenarios.&lt;br&gt;
Keep reality separate from projections.&lt;/p&gt;

&lt;p&gt;N4K48 × MyZubster — building in public.&lt;/p&gt;

&lt;h1&gt;
  
  
  MyZubster #N4K48 #BuildInPublic #DevLog #AI #SoftwareDevelopment #FinTech #Zorgax #MVP
&lt;/h1&gt;

</description>
      <category>ledger</category>
      <category>simulator</category>
      <category>revenue</category>
      <category>myzubster</category>
    </item>
    <item>
      <title>🛠️ MyZubster: Moving from Generative RAG to Evidence-First AI</title>
      <dc:creator>Nicola Lorenzini</dc:creator>
      <pubDate>Fri, 18 Sep 2026 19:36:21 +0000</pubDate>
      <link>https://dev.to/n4k48/myzubster-moving-from-generative-rag-to-evidence-first-ai-3of6</link>
      <guid>https://dev.to/n4k48/myzubster-moving-from-generative-rag-to-evidence-first-ai-3of6</guid>
      <description>&lt;p&gt;🛠️ MyZubster: Moving from Generative RAG to Evidence-First AI&lt;/p&gt;

&lt;p&gt;Today we made an important step forward in the MyZubster AI stack.&lt;/p&gt;

&lt;p&gt;During an end-to-end test, we found a concrete failure mode:&lt;/p&gt;

&lt;p&gt;The knowledge base clearly contained:&lt;/p&gt;

&lt;p&gt;status = RECORDED&lt;br&gt;
success = true&lt;br&gt;
paymentRequired = false&lt;br&gt;
onchainRecorded = false&lt;/p&gt;

&lt;p&gt;Yet when asked:&lt;/p&gt;

&lt;p&gt;“Is the handover recorded on blockchain?”&lt;/p&gt;

&lt;p&gt;the LLM could still answer incorrectly:&lt;/p&gt;

&lt;p&gt;“It is recorded on blockchain.”&lt;/p&gt;

&lt;p&gt;The problem wasn't Qdrant. The correct source was being retrieved.&lt;/p&gt;

&lt;p&gt;The problem was letting an LLM make the final decision about a structured boolean that the system already knows with certainty.&lt;/p&gt;

&lt;p&gt;🔎 The solution&lt;/p&gt;

&lt;p&gt;We introduced structured metadata into MyZubster observations:&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
  "status": "RECORDED",&lt;br&gt;
  "success": true,&lt;br&gt;
  "paymentRequired": false,&lt;br&gt;
  "onchainRecorded": false,&lt;br&gt;
  "handoverId": "6aab8faca70ce84f926d0b41",&lt;br&gt;
  "method": "HAND_DELIVERY"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;The metadata is preserved in the observation and indexed alongside the RAG content.&lt;/p&gt;

&lt;p&gt;We then changed the /api/ai/ask flow to:&lt;/p&gt;

&lt;p&gt;question&lt;br&gt;
   ↓&lt;br&gt;
Qdrant retrieval&lt;br&gt;
   ↓&lt;br&gt;
authoritative metadata?&lt;br&gt;
   ├── yes → deterministic answer&lt;br&gt;
   └── no  → LLM / RAG&lt;/p&gt;

&lt;p&gt;So questions such as:&lt;/p&gt;

&lt;p&gt;“What is the status?”&lt;br&gt;
“Is it recorded on blockchain?”&lt;br&gt;
“Is payment required?”&lt;br&gt;
“Was the operation successful?”&lt;/p&gt;

&lt;p&gt;can be answered directly from authoritative structured data.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Status: RECORDED.&lt;br&gt;
Blockchain recording: no.&lt;/p&gt;

&lt;p&gt;No interpretation by the model.&lt;br&gt;
No probability involved.&lt;br&gt;
No false accidentally becoming true.&lt;/p&gt;

&lt;p&gt;🤖 What about Ollama?&lt;/p&gt;

&lt;p&gt;We didn't remove the LLM.&lt;/p&gt;

&lt;p&gt;Ollama is still used when the question requires natural-language reasoning and there isn't enough structured metadata to answer deterministically.&lt;/p&gt;

&lt;p&gt;We also made the RAG context more explicit:&lt;/p&gt;

&lt;p&gt;[SOURCE 1]&lt;br&gt;
description=...&lt;br&gt;
metadata={"onchainRecorded": false, ...}&lt;/p&gt;

&lt;p&gt;and strengthened the prompt with an evidence-first approach: the model should use only facts explicitly present in the retrieved sources.&lt;/p&gt;

&lt;p&gt;⚙️ Local inference optimization&lt;/p&gt;

&lt;p&gt;For the local test environment we also moved to:&lt;/p&gt;

&lt;p&gt;qwen2.5:0.5b&lt;/p&gt;

&lt;p&gt;with:&lt;/p&gt;

&lt;p&gt;AI_CONTEXT_LIMIT=1&lt;/p&gt;

&lt;p&gt;This reduced unnecessary context and improved response time during the test.&lt;/p&gt;

&lt;p&gt;🧪 Testing&lt;/p&gt;

&lt;p&gt;We added coverage for:&lt;/p&gt;

&lt;p&gt;structured metadata persistence;&lt;br&gt;
metadata inclusion in the RAG prompt;&lt;br&gt;
authoritative metadata responses;&lt;br&gt;
existing AI API behavior.&lt;/p&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;27 passed&lt;/p&gt;

&lt;p&gt;The changes were committed and pushed to main:&lt;/p&gt;

&lt;p&gt;e680f54 Harden grounded AI metadata answers&lt;br&gt;
💡 The bigger lesson&lt;/p&gt;

&lt;p&gt;A RAG system shouldn't ask an LLM to interpret something the software already knows with certainty.&lt;/p&gt;

&lt;p&gt;If the database says:&lt;/p&gt;

&lt;p&gt;onchainRecorded = false&lt;/p&gt;

&lt;p&gt;the answer should come from that fact—not from the model's probability distribution.&lt;/p&gt;

&lt;p&gt;LLMs for interpretation.&lt;br&gt;
Structured data for authoritative decisions.&lt;br&gt;
RAG for evidence.&lt;/p&gt;

&lt;p&gt;That's the direction we're taking with MyZubster:&lt;/p&gt;

&lt;p&gt;AI that is not only grounded, but verifiable.&lt;/p&gt;

&lt;h1&gt;
  
  
  AI #RAG #LLM #Ollama #Qdrant #Python #Flask #Docker #SoftwareEngineering #AIEngineering #MyZubster
&lt;/h1&gt;

</description>
      <category>ollama</category>
      <category>ai</category>
      <category>myzubster</category>
      <category>docker</category>
    </item>
    <item>
      <title>🚀 **DEV UPDATE — MyZubster MVP: Local AI + RAG Knowledge Pipeline**</title>
      <dc:creator>Nicola Lorenzini</dc:creator>
      <pubDate>Fri, 18 Sep 2026 18:22:03 +0000</pubDate>
      <link>https://dev.to/n4k48/dev-update-myzubster-mvp-local-ai-rag-knowledge-pipeline-4p9c</link>
      <guid>https://dev.to/n4k48/dev-update-myzubster-mvp-local-ai-rag-knowledge-pipeline-4p9c</guid>
      <description>&lt;p&gt;🚀 &lt;strong&gt;DEV UPDATE — MyZubster MVP: Local AI + RAG Knowledge Pipeline&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Oggi ho completato un nuovo step del mio progetto &lt;strong&gt;MyZubster MVP / N4K48&lt;/strong&gt;: un sistema AI locale che può interrogare le osservazioni del progetto e una knowledge base versionata su GitHub.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Repository&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Commit del nuovo RAG&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/8da7435ddc1b9ae8b2f5c2eea5debd2df4bc5f47" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/commit/8da7435ddc1b9ae8b2f5c2eea5debd2df4bc5f47&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Come funziona
&lt;/h3&gt;

&lt;p&gt;La pipeline locale è:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Knowledge / Observations → Embeddings → Qdrant → Retrieval → Ollama → Mistral → risposta con fonti&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Il progetto usa:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ollama&lt;/strong&gt; per eseguire i modelli AI localmente;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;nomic-embed-text&lt;/strong&gt; per trasformare documenti e domande in embedding;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Qdrant&lt;/strong&gt; come vector database;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mistral&lt;/strong&gt; per generare la risposta finale;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flask API&lt;/strong&gt; come livello applicativo;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker Compose&lt;/strong&gt; per orchestrare API, Qdrant, Ollama e Open WebUI.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cosa abbiamo cambiato
&lt;/h3&gt;

&lt;p&gt;Prima, ogni domanda inviata all'AI poteva causare una nuova indicizzazione delle osservazioni.&lt;/p&gt;

&lt;p&gt;Ora abbiamo separato le due responsabilità:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WRITE&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;create observation → persist → embed → index in Qdrant&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;READ / ASK&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;question → embed question → search Qdrant → retrieve context → Mistral → answer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Questo evita di re-indicizzare tutto a ogni domanda e rende il RAG più vicino a una vera architettura di retrieval.&lt;/p&gt;

&lt;h3&gt;
  
  
  Knowledge Base
&lt;/h3&gt;

&lt;p&gt;Ho aggiunto anche una knowledge base Markdown versionata direttamente nel repository:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;knowledge/N4K48.md&lt;/code&gt;&lt;br&gt;
&lt;code&gt;knowledge/ROADMAP.md&lt;/code&gt;&lt;br&gt;
&lt;code&gt;knowledge/ZORGAX.md&lt;/code&gt;&lt;br&gt;
&lt;code&gt;knowledge/GALLERY.md&lt;/code&gt;&lt;br&gt;
&lt;code&gt;knowledge/PROFILE.md&lt;/code&gt;&lt;br&gt;
&lt;code&gt;knowledge/README.md&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Uno script dedicato:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;scripts/ingest_knowledge.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;divide i documenti in chunk, genera embedding locali e li registra in Qdrant usando ID deterministici.&lt;/p&gt;

&lt;p&gt;Nel test attuale:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;38 knowledge chunks + 4 observations = 42 vector points&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Test
&lt;/h3&gt;

&lt;p&gt;La suite locale è passata:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;25/25 tests ✅&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Abbiamo poi eseguito una vera richiesta RAG:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Qual è lo stato del collegamento tra Nicola Comics e il Zorgax pubblico?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Risultato:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTP 200 — 80.75 secondi&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Il sistema ha recuperato informazioni dalla knowledge base e ha correttamente mantenuto un confine importante: il collegamento pubblico Zorgax end-to-end &lt;strong&gt;non è ancora verificato&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Il retrieval in questo test ha selezionato due chunk di &lt;code&gt;ROADMAP.md&lt;/code&gt; invece di &lt;code&gt;ZORGAX.md&lt;/code&gt;: quindi il prossimo lavoro sarà migliorare ranking, chunking e pertinenza delle fonti, oltre alle prestazioni del modello locale.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evidence first
&lt;/h3&gt;

&lt;p&gt;Una regola importante del progetto resta:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;concept ≠ evidence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Un elemento viene dichiarato verificato solo quando esiste una prova tecnica concreta: test, commit, runtime, osservazione o altra evidenza controllabile.&lt;/p&gt;

&lt;p&gt;Per esempio, Nicola Comics può avere una tavola nello stato &lt;code&gt;NFT_CANDIDATE&lt;/code&gt;, ma questo &lt;strong&gt;non significa che sia stata mintata&lt;/strong&gt;. Allo stesso modo, l'adapter Zorgax locale esiste, ma il collegamento con il Zorgax pubblico deve ancora essere provato end-to-end.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next
&lt;/h3&gt;

&lt;p&gt;I prossimi step sono:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;better retrieval → smaller/faster context → Zorgax-specific retrieval → public E2E verification&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;L'obiettivo è costruire progressivamente un assistente MyZubster capace di lavorare sulle informazioni reali del progetto, mantenendo separate visione, storytelling e prove tecniche.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;MyZubster MVP&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;N4K48 knowledge&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/tree/main/knowledge" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/tree/main/knowledge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;RAG ingestion script&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/scripts/ingest_knowledge.py" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp/blob/main/scripts/ingest_knowledge.py&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  MyZubster #RAG #LocalAI #Ollama #Qdrant #Mistral #AI #OpenSource #Docker #Python #N4K48 #Zorgax #DevLog
&lt;/h1&gt;

</description>
      <category>n4k48</category>
      <category>myzubster</category>
      <category>mvp</category>
      <category>local</category>
    </item>
    <item>
      <title>🛠️ MyZubster Dev Update — Local AI + RAG</title>
      <dc:creator>Nicola Lorenzini</dc:creator>
      <pubDate>Fri, 18 Sep 2026 17:59:24 +0000</pubDate>
      <link>https://dev.to/n4k48/myzubster-dev-update-local-ai-rag-1pm6</link>
      <guid>https://dev.to/n4k48/myzubster-dev-update-local-ai-rag-1pm6</guid>
      <description>&lt;p&gt;🛠️ &lt;strong&gt;MyZubster Dev Update — Local AI + RAG&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Today we made an important step forward in MyZubster’s local AI infrastructure.&lt;/p&gt;

&lt;p&gt;We now have a local stack built around:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MyZubster API → Qdrant → Ollama → Mistral&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;with &lt;code&gt;nomic-embed-text&lt;/code&gt; generating embeddings and Mistral running locally to generate answers.&lt;/p&gt;

&lt;p&gt;🔗 MyZubster MVP&lt;br&gt;
&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp" rel="noopener noreferrer"&gt;https://github.com/nicolaususnicola-lgtm/myzubster-mvp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔗 Ollama&lt;br&gt;
&lt;a href="https://ollama.com/" rel="noopener noreferrer"&gt;https://ollama.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔗 Qdrant&lt;br&gt;
&lt;a href="https://qdrant.tech/" rel="noopener noreferrer"&gt;https://qdrant.tech/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What changed?
&lt;/h3&gt;

&lt;p&gt;The main work today was on the &lt;strong&gt;RAG — Retrieval-Augmented Generation — pipeline&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Previously, every AI question caused MyZubster to regenerate embeddings for all observations and upsert them into Qdrant again before searching.&lt;/p&gt;

&lt;p&gt;We separated &lt;strong&gt;indexing&lt;/strong&gt; from &lt;strong&gt;retrieval&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When an observation is recorded&lt;/strong&gt;&lt;br&gt;
→ MyZubster stores it&lt;br&gt;
→ its embedding is generated&lt;br&gt;
→ it is indexed in Qdrant&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When a question is asked&lt;/strong&gt;&lt;br&gt;
→ only the question embedding is generated&lt;br&gt;
→ Qdrant retrieves the most relevant information&lt;br&gt;
→ that context is passed to Mistral&lt;br&gt;
→ Mistral generates the answer&lt;/p&gt;

&lt;p&gt;This avoids repeatedly indexing the same observations and moves MyZubster toward a persistent, searchable local knowledge layer.&lt;/p&gt;

&lt;p&gt;We also worked on the &lt;strong&gt;Kefir &amp;amp; Knowledge / KF-006&lt;/strong&gt; data and made an important evidence distinction explicit:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;RECORDED&lt;/code&gt; = digitally recorded inside MyZubster&lt;br&gt;
&lt;code&gt;onchainRecorded=false&lt;/code&gt; = no blockchain registration is being claimed&lt;/p&gt;

&lt;p&gt;That distinction reflects one of the principles we are applying throughout development:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evidence first. Claim only what the available data can actually verify.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The backend refactor was validated with the automated test suite:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;25/25 tests passing&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Next step
&lt;/h3&gt;

&lt;p&gt;The next stage is to connect the broader MyZubster knowledge base — including N4K48, Zorgax, roadmap and project documentation — to the same RAG architecture, with a consistent data schema, deterministic indexing and duplicate control.&lt;/p&gt;

&lt;p&gt;The goal is not simply to build another chatbot.&lt;/p&gt;

&lt;p&gt;The goal is to build a &lt;strong&gt;local MyZubster AI that can retrieve and reason over the project’s own knowledge and evidence.&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  MyZubster #LocalAI #RAG #Ollama #Mistral #Qdrant #N4K48 #Zorgax #OpenSource #DevUpdate
&lt;/h1&gt;

</description>
      <category>local</category>
      <category>ai</category>
      <category>zorgax</category>
      <category>myzubster</category>
    </item>
    <item>
      <title>From Docker to Real Services: My Learning Journey with MyZubster</title>
      <dc:creator>Nicola Lorenzini</dc:creator>
      <pubDate>Fri, 18 Sep 2026 16:56:40 +0000</pubDate>
      <link>https://dev.to/n4k48/from-docker-to-real-services-my-learning-journey-with-myzubster-49hg</link>
      <guid>https://dev.to/n4k48/from-docker-to-real-services-my-learning-journey-with-myzubster-49hg</guid>
      <description>&lt;h1&gt;
  
  
  From Docker to Real Services: My Learning Journey with MyZubster
&lt;/h1&gt;

&lt;p&gt;What happens when a software project becomes a place to share your practical skills?&lt;/p&gt;

&lt;p&gt;I’m Nicola, also known as &lt;strong&gt;N4K48&lt;/strong&gt;. Through my work with Daniel Ioni and MyZubster, I’ve been learning how to connect GitHub documentation, Docker, APIs, Zorgax and real community activities.&lt;/p&gt;

&lt;p&gt;Now, two of my services are published on the MyZubster Marketplace.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚚 Need help with a move?
&lt;/h2&gt;

&lt;p&gt;I own a &lt;strong&gt;pickup with a tow hitch&lt;/strong&gt; and hold &lt;strong&gt;B, C and CE driving licences, plus CQC goods qualification&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;My listing covers small moves and bulky-item transport around Rimini. I’m also available as a driver when the customer already has a suitable vehicle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indicative driver rate: €20/hour.&lt;/strong&gt; Pickup use, fuel, tolls and any trailer costs are agreed separately.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.myzubster.com/marketplace" rel="noopener noreferrer"&gt;Open the Marketplace&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Look for:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Traslochi e trasporto ingombranti — pickup e autista disponibile”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then click &lt;strong&gt;“Richiedi”&lt;/strong&gt; to make a request.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Want to learn from my driving experience?
&lt;/h2&gt;

&lt;p&gt;My second service offers individual sessions to share practical experience with transport preparation, moving logistics and working as a driver.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Price: €20 for a one-hour session&lt;/strong&gt;, in Rimini by appointment.&lt;/p&gt;

&lt;p&gt;These are experience-sharing sessions; they do not include driving lessons, licence courses or certification.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.myzubster.com/marketplace" rel="noopener noreferrer"&gt;Find my knowledge service on MyZubster&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Look for:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Conoscenze pratiche da autista — patenti B, C, CE e CQC merci”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Marketplace currently opens as a shared listing page, so these links do not jump directly to an individual service.&lt;/p&gt;

&lt;h2&gt;
  
  
  💻 What I learned while building
&lt;/h2&gt;

&lt;p&gt;The practical work taught me lessons that go beyond publishing an announcement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker:&lt;/strong&gt; a working command-line client does not mean the Docker engine is running.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API testing:&lt;/strong&gt; a healthy container does not guarantee that every endpoint works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Packaging:&lt;/strong&gt; excluding runtime catalog files from a Docker image can break a feature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bug reporting:&lt;/strong&gt; the exact error message makes a failed test useful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marketplace testing:&lt;/strong&gt; currencies, prices and successful publication need checking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zorgax:&lt;/strong&gt; the comics adapter uses explicit catalog actions; its responses should remain tied to available records.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During the moving-service test, publication failed with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;E11000 duplicate key error
index: listingId_1
dup key: { listingId: null }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I reported that error and a missing EUR currency option to Daniel. After he reported deploying fixes, we repeated the flow and verified that the listings appeared.&lt;/p&gt;

&lt;p&gt;That is the learning cycle I want to keep using:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try → observe → report → fix → verify → share.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🥛 Where kefir fits in
&lt;/h2&gt;

&lt;p&gt;The Kefir &amp;amp; Knowledge pilot connects a physical exchange with documentation and learning.&lt;/p&gt;

&lt;p&gt;It also raises a useful engineering question: &lt;strong&gt;what does a digital record actually prove?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Delivery confirmation, receipt confirmation and a digital record are distinct steps. Scientific conclusions require their own observations, methods, data and review.&lt;/p&gt;

&lt;p&gt;My GitHub journey includes a kefir illustration and diagrams explaining this pathway. They describe the project and its next steps, rather than presenting completed scientific results.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔗 Choose your next step
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Interested in…&lt;/th&gt;
&lt;th&gt;Start here&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;My skills, services and projects&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/nicolaususnicola-lgtm" rel="noopener noreferrer"&gt;My GitHub profile&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requesting either service&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.myzubster.com/marketplace" rel="noopener noreferrer"&gt;MyZubster Marketplace&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker, the comics catalog and Zorgax adapter&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster-mvp" rel="noopener noreferrer"&gt;My MVP repository&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;My development fork&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/nicolaususnicola-lgtm/myzubster" rel="noopener noreferrer"&gt;MyZubster fork&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The learning journey and visuals&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/nicolaususnicola-lgtm/nicolaususnicola-lgtm/blob/main/docs/percorso-daniel-kefir-zorgax.md" rel="noopener noreferrer"&gt;Kefir, Docker, MyZubster and Zorgax&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  💬 Help me test the experience
&lt;/h2&gt;

&lt;p&gt;Open the Marketplace and try to find one of my listings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can you tell what the service includes, what it costs and how to request it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Leave a comment with the step that felt clear—or the point where you got stuck. Please submit a service request only if you are interested; usability feedback can stay here in the comments.&lt;/p&gt;

&lt;p&gt;And if you’re building something similar: &lt;strong&gt;what practical skill would you turn into a useful community service?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>services</category>
      <category>myzubster</category>
      <category>zorgax</category>
    </item>
  </channel>
</rss>
