Build log: a week of guards, gates and a new project app
Part of Build Blog
This week I put Tailscale on the Spark, added a hook that catches an answer quoting a file it never opened, gave the AI Control Panel an agent page, and started a project app to replace ClickUp.
1. CopernicIQ got steadier
Nothing this week changed what CopernicIQ decides. It changed how the service stops and starts.
Two socket tests failed now and then, and I made them deterministic. A dead start now fails at once. The start limit was hit 49 seconds after the first try. Before, that took about 4.5 minutes.
The first probe of that fix proved nothing. A temporary unit had been unloaded, and its status read back as default values. I caught it at the gate, and the check now reads the journal instead.
I also planned a fix for refused requests that close with the body unread. The baseline on the box lost 0 answers in 400 refused requests, because a proxy sits in front of the service. So I kept the tests and dropped the fix.
The hard question was whether that is safe. My answer: "It is a deployment-specific decision, not proof the service handles every connection safely." And: "'Closed' must record the decision, not imply a drain was shipped."
Still open: a caller that skips the proxy can still hit the reset. Nothing calls CopernicIQ on a normal day yet.
2. Tailscale on the Spark
I want to use the Spark when I am away from home. I put Tailscale on the Spark itself, not on a Raspberry Pi. A Pi acting as a router would open the whole home network. Only my tagged PC and laptop can reach the box, and only two services. Everything else is refused.
The question was what a new tailnet does before I lock it down. My answer: "A new tailnet starts with allow-everything access. I save the restrictive policy first so the Spark never joins under that default." I also wrote down what the tag does not fix: "A lost tagged laptop could use Ollama without a login. It could run models, delete them or pull more until the disk fills. Memguard protects memory, not disk." And: "The tag restricts access, but it does not make a compromised device safe."
The review found a Low. The installer checked the signing key only after the package manager had already trusted it. My answer: "The later check can refuse, but only after apt has already trusted it and the install and service start have run. I would fix that now by checking the retained keyring before apt uses it." The fix went in that way.
Where it is: the policy is saved and reads back as exactly two rules, with no allow-all. The first install worked. Joining, reaching the box, the refusals and the undo are not proven yet. The pull request is still open. Logins for Ollama and vLLM are the next plan.
3. The harness: a hook that checks what the model did
In a real run on the Spark, the model made no tool call and invented both quotes in its answer. Its rules already said no fabrication.
My answer to why a rule was not enough: "The rule depended on the model obeying it. The Spark invented quotes without making a tool call, so I need a check on what it actually did. A Stop hook sees the completed answer and can send it back before the turn finishes." I was also clear on what it does not do: "The hook is still a guard, not proof every answer is true. It fails open if the check errors or CopernicIQ is unavailable."
On the Spark the hook blocks. On my main subscription it only logs for now, and I will read those logs before I turn on blocking. In the code review of that hook I found a real hole myself: claims were not being filtered. A later change closed it.
The same week:
- A three-layer secret scan now runs alongside the personal-data hooks.
- My writing rules now put the ask first and the explanation second. The old measurement of how I wrote stays on record. In my words: "The measurement records how I actually wrote. The new order records how I want to write now."
- Client data now needs a written policy before anything can send it off the machine. Paths on network shares are checked and never sent.
Still open: the Spark rerun of two checks, the laptop, and a prompt-injection hunter I planned on Sunday.
4. The AI Control Panel
My order for the panel is: "Function first, speed and low resources 2nd, and UI jaw dropping awsomeness 3rd."
Ten pull requests went in:
- a live view of each session's flow, with a cloud icon on any call that leaves the PC
- session cards with small flow maps
- a compact top strip with limit rings
- a universe view of everything at once
- a Settings page
- more coding tools tracked
- CopernicIQ and vLLM drawn on the Spark page
- an agent page with each agent's masked prompt, the calls it makes, and what it costs.
The agent page raised the question of whether to read prompts at all. My answer: "The strongest case against reading the prompt is that it creates another place a secret can appear. Masking reduces that risk, but cannot guarantee every secret shape is caught." And: "green tests only prove the cases they cover. The merge waits for my word so I explicitly accept that tradeoff."
I also caught a process miss. The checks for the Spark page had been run but never written down. All 11 rows still read unresolved, so in my words, "I cannot call those rows passed."
Next: a "leaves this PC" view per agent, and warnings in the panel when the personal-data or injection scans find something.
5. A project app of my own
I am tired of paying for ClickUp when I barely use it. So I started my own project app. It is database-driven, runs at logon, and my agents use it through a command-line tool and an API. My goal is for it to be as usable as the big project tools, with better reporting and APIs, and less confusing. It is getting a new name, so I am leaving the old one out.
On October 31 I did seven releases in one day, from 0.7.0 to 0.10.0: release notes, rich text, links, attachments, and web links that stay hidden from clients unless marked. Release notes went first, in my words, "since we will be doing more releases and don't want to have to backfill." I also re-imported my old ClickUp data, after a local session deleted the database earlier on.
In my words: "This is a useful project for me, but not going to hurt if it is broken, I still have the other systems for now as needed."
Still open: edits (0.11.0) are in review, and the MCP server is built but not pushed. After that come views, reports, a daily home page and a user guide.
6. The test hub
- Test runs now record video.
- I set 1280x720 as the one screen size. While doing that I found the old 1920x1080 setting had never applied, all the way back to September 7.
- A test that opened its own browser window left a 73-second white video, and the security recorders were watching a blank page. Windows a test opens itself are now recorded and watched too.
Still open: a flaky-test ticket and three Low findings from reviews.
7. TestProof
TestProof is where test runs become evidence a client can read.
- The UI was rebuilt: a sidebar, the new palette in light and dark, and a three-column run view that shows the step a run failed at.
- 1,567 test cases were re-filed under the product they actually test.
- An unreadable screenshot no longer says "none captured", and a bad listing is refused at import.
This week's rule is "no verdict, no export". My answer on where it lives: "HTML, PDF and the CLI all pass through it. Putting it only in the download endpoint would leave another export path able to bypass it." On bad data in the fixtures: "I refuse rather than silently mask because this is authored evidence: I should correct what I entered, not save altered fixture data that could mislead the client."
That change is still in review. Approval comes next.
8. databusiness.ai
- A new look. I said it plainly: "It is very Claude looking. We are doing more and more with different LLMs and models. We need to scrape the Claude coat off." The site has a new machined d logo, a home page that does not lean on one provider, and the Claude-specific claims are gone. On the logo: "I use the generated image to choose the direction, then redraw and check the mark as clean SVG."
- A privacy page. In my words: "My contact form collects names and email addresses, so […] I need a privacy policy even as a one-person firm with no ad pixels."
- The Review Replay and the TestProof walkthrough. One real review, three rounds, and a green test run, step by step. In my words: "Green checks do not replace my approval to publish them."
Still open: two mail aliases the site lists, the price on the review offer, and the next three showcases. The first is a tool that shows what my review would flag on a pasted snippet.
The next step
The next step is the review tool: a live sample of the review, with a spend cap, a rate limit and an updated privacy page in the same change.