Until a little bit in the future from now, The Quantum Garden Vault has been split into two distinct sections. One section follows the ACE Framework and holds my personal notes, journal entries and private projects. The second section has everything that appears on The Quantum Garden Website under a top-level folder called public. This folder used by Quartz to generate the static website pages for https://quantumgardener.info.
I’m combining public and private notes into the same folder because it reduces a complexity problem I’m facing by having them split. This post outlines the thinking I’ve done from a software developer point of view in the hope it helps others understand a little better what needs to be considered when documents are public facing.
All weekend I’ve been working on moving all my notes to a single folder. I was likely leaning towards this from last weekend’s investigation into how I can provide my notes to AI for identification of patterns and themes (not to generate content, see my AI policy). At the same time fighting with how best to store sources and my notes on them. Then, during the week the Universe delivered and I came across. Steph Ango’s Obsidian Vault Template where they have a very flat structure of notes and references (items not created by them). My decision made, its no longer atlas/notes and public/notes but just atlas/notes.
Privacy first
For some background on the way I did this in the past see Protecting what’s published.
The separate of private and public notes provided a degree of privacy by default. Notes that were in the public folder would be displayed on The Quantum Garden Website and those outside the public folder would never be candidates. I added an extra level of protection by employing the Quartz ExplicitPublish plugin to only publish pages where the publish property was set to true.
For a page to appear online, it must be in both the public folder and have publish: true.
Even if I were to accidentally move my whole journal folder into public my most private thinking wouldn’t leak because publish was either undefined or false.
Why not two vaults?
If you’re asking why not have two separate vaults and keep everything separate, it’s because I often link from private notes to public notes and vice-versa. I’ve modified the back end of Quartz in such a way that a link from a public to a private note is completely hidden. The default Quartz doesn’t do this which I find poor design.
Improving the publish property
The publish property as a checkbox is a little too simple and prone to error because there is no state representing, “I’ve not made a conscious decision”. I replaced the two-state checkbox it with a three-state text field where the choices are:
deny: under no circumstances publish this pageundecided: default state for new pages, forcing me to make a decision to publish or notallow: publish this page
There is a hidden fourth-state that occurs when a note does not have the publish property at all, or it is blank. I treat this as an error and abort the site generation process until I’ve fixed it.
The filter rule (take 1)
Every note in
atlaswill be made public ifpublish = true. All other notes will remain private.
Class tags: a second line of defence
What happens if I accidentally move a private journal entry to the atlas folder? If a second accident has set publish = true it will be published. It is a case that is unlikely but may have high impact. I accept some level of risk by co-hosting private and public notes in the same vault so what can I do to minimise the likelihood. Software development is more about handling possible exceptions than anything else, so let’s use a second piece of important information I have attached to my notes.
Many of my notes have Quantum OS Class Tags for structural organisation. Just like this is. So I can employ them to double-down on privacy by filtering out those classes which should never be published.
My privacy filter has a list of classes which, not matter what the state of the publish property is, will never be published. It’s effectively saying, “I don’t care that your parents have given you permission to ride this roller-coaster, your head is not above the line so you’re out”.
Quantum OS Restricted Tags lists the tags that are filtered in this way.
The filter rule (take 2)
Every note in
atlaswill be made public ifpublish = trueAND it is not in a prohibited tag class. All other notes will remain private.
Folder filtering: a third line of defence
To structure The Quantum Garden Website properly under the hood, I need to have not just an atlas/notes folder but other supporting folders like atlas/assets which contains all images, etc. By inference, any folder under atlas might be copied to the web, even if it has nothing to do with the website. That’s the way Quartz operates by default and it makes sense, though is risky if you’re not accustomed to thinking about risks. Someone would have to type the path to get to the files, they are otherwise hidden, but it’s much better to not have them there.
For this we can use the ignorePatterns Configuration. Files and folders which should be ignored are not copied, and anything not ignored is.
deny, allow
There are 2 ways we can go with security. Allow everything and deny exceptions, or deny everything and allow exceptions. Of the two, deny first is the most secure. It requires you to make a decision about what is allowed. In the case of the Quartz
ignorePatternsfilter, the default is allow, deny which is not great. All it solves is the problem of the developer being hounded by new people not understanding why there are no files showing.
The relevant part of my Quartz quartz.config.ts file looks like this.
const config: QuartzConfig = {
configuration: {
ignorePatterns: ["atlas-unchecked","Home Life Index", "JDEX","maps","notes/sources
plugins: {
filters: [
Plugin.Portcullis()
],
}The filter rule (final take)
Every note in
atlaswill be made public ifpublish = trueAND it is not in a prohibited tag class AND it is not in an ignored folder. All other notes will remain private.
The code
Here is the code for my filter function. I called it Portcullis to represent the serious nature of the filter. The image reminds me nothing gets through without permission.
- Lines 1–2: Hook the filter into the Quartz system and include
chalkfor coloured log output - Lines 4–10: Create the list of Quantum OS Restricted Tags to be check against later
- Lines 12 onwards are the main function. Each file is checked in turn, and if it should be published return
trueotherwise returnfalse.- Lines 16–21: Check for the existence of the
publishproperty. If it is missing or not set, abort site generation with an error message. - Lines 24–26: Return false if the value of
publishisdeny. This version of the code outputs a notification to help debugging. Over more than a few deny files this should be removed because it’s too much noise. I’m using it for testing. Proceed to the next note. - Lines 27–29: Return false if the value of
publishisundecided. Here we are defaulting to a deny behaviour if no decision has been made. Proceed to the next note. - Lines 30–50: Handle an
allow. Further checks are required.- Lines 31–41: Check for the presence of illegal tags. If even one is found, deny publishing.
- Lines 43-49: I sometimes write blog posts with a future date. If a post is future dated, don’t publish it yet.
- Line 50: All checks are passed, this file is ok to publish. Proceed to the next note.
- Lines 51–54: Remember I said that software development was dealing with exceptions. Since the value of
publishhas to be typed it could be something other than “deny”, “undecided”, or “allow”. These lines capture that occurrence and abort with an error.
- Lines 16–21: Check for the existence of the
One final caution
My code is an extension of the base Quartz code. Upstream changes automatically incorporated into my own could overwrite or bypass my changes, thereby creating a security leak I wasn’t ready for.
This dependence. is problem with the software development industry as a whole and means I have to check each change before accepting it. That’s the price I pay for modifying code to do what I want where that differs from the original developer’s needs or intentions.
