<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Noah Roberts&#39;s blog</title>
    <subtitle>Thoughts and musings</subtitle>
    <link href="https://noah-roberts.dev/feed.xml" rel="self"/>
    <link href="https://noah-roberts.dev/"/>
    <updated>2026-10-18T00:00:00Z</updated>
    <id>https://noah-roberts.dev/</id>
    <author>
      <name>Noah Roberts</name>
    </author>
    
        
        <entry>
            <title>Contact Form Project 05: Error Handling</title>
            <link href="https://noah-roberts.dev/blog/contact-form-project-05-error-handling/"/>
            <updated>2026-10-18T00:00:00Z</updated>
            <id>https://noah-roberts.dev/blog/contact-form-project-05-error-handling/</id>
            <content type="html">&lt;p&gt;&lt;a href=&quot;https://gitlab.com/noah.roberts.sse/contact-form/-/tree/a4a987ca472b000a5db12acc0f5fa8179d4466b4&quot;&gt;Current code state&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In the last installment I became disappointed with myself for not doing adequate error handling. It&#39;s early in the project so I became tempted to skip that and put it off for later. I decided while writing my blog entry that I&#39;d made a bad decision and one that could be used as a teaching moment. I&#39;ve since gone back and fixed that issue.&lt;/p&gt;&lt;h2&gt;Process error codes&lt;/h2&gt;&lt;p&gt;A lot of times the exit code that your process returns means more than just pass/fail. A great many projects stipulate codes for different conditions and if your program is meant to be used by an automated system it can be important. So I spent a lot of time learning how to do this in Rust.&lt;/p&gt;&lt;p&gt;This can be done if you make your own object that responds to the &lt;code&gt;Termination&lt;/code&gt; trait. I was able to follow much of &lt;a href=&quot;https://www.joshmcguigan.com/blog/custom-exit-status-codes-rust/&quot;&gt;this blog&lt;/a&gt; to get there. Unfortunately though I couldn&#39;t get as far as implementing &lt;code&gt;?&lt;/code&gt; from that blog entry because the interface to do so has changed from v1 to v2 and v2 is completely different from v1. The &lt;code&gt;Try&lt;/code&gt; trait now works with &amp;quot;Residuals&amp;quot; and I struggled to understand the setup. I tried just getting it done by using &amp;quot;try_v2&amp;quot; to get the derive macro but this didn&#39;t work immediately.&lt;/p&gt;&lt;p&gt;This can only be done by using &amp;quot;unstable&amp;quot; rust API. I decided I didn&#39;t want to do that and instead of learning this now anyway I&#39;ll pick it up later. I could either just not use &lt;code&gt;?&lt;/code&gt; in main or I could give up on the idea of error codes for each type of error. I decided on the latter so I just let rust report the error when it exits and return &lt;code&gt;ExitCode::FAILURE&lt;/code&gt; per the default behavior when you return a &lt;code&gt;Result&lt;/code&gt;.&lt;/p&gt;&lt;h2&gt;Error type scheme&lt;/h2&gt;&lt;p&gt;There are a bunch of different ways in which people handle errors in Rust. The most common ones obviously use &lt;code&gt;Result&lt;/code&gt; or &lt;code&gt;Optional&lt;/code&gt;, but there&#39;s also a lot of differences in the &lt;code&gt;Error&lt;/code&gt; type used and how rigorous the API is about what errors come out of what functions.&lt;/p&gt;&lt;p&gt;I decided that I don&#39;t really care that much for the conditions I have need ot dealing with so far. I already selected &lt;code&gt;axum&lt;/code&gt; for the server library and it makes sure all errors are handled, so I just need to handle the conditions that prevent me from handing off to this library by calling &lt;code&gt;serve&lt;/code&gt;. So I went with the &lt;a href=&quot;https://github.com/dtolnay/anyhow&quot;&gt;anyhow&lt;/a&gt; library. This just wraps up the errors in something dynamic I can hand up the change to the part that reports the condition to the user and exits. Rust has another method of dealing with these, &lt;code&gt;panic&lt;/code&gt;, but I&#39;m maybe too into the idea I should propagate up more expilicitly.&lt;/p&gt;&lt;p&gt;This &lt;code&gt;anyhow&lt;/code&gt; library lets me attach further context to the error so when it gets reported it provides additional information on top of whatever got discovered by the error generation part. Here&#39;s an example:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-{code}&quot;&gt;let listener = tokio::net::TcpListener::bind(&amp;amp;self.config.listen_address)
    .await
    .with_context(|| format!(&amp;quot;Could not bind network interface at `{}`&amp;quot;, &amp;amp;self.config.listen_address))?;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a little sloppier than I&#39;m usually comfortable with--just mashing all error types into one bucket-- but in this case I think I really need to silence that part of my brain and be good with this. There&#39;s no need to do more than this at this time and I don&#39;t think there ever will be.&lt;/p&gt;&lt;p&gt;So after a couple days of messing about coming up with ways to propagate the info up with explicit errors at each level, and not being happy with any of it, I decided that this &lt;code&gt;anyhow&lt;/code&gt; library is what I want. The same author makes another helpful library for custom errors but I don&#39;t think I&#39;m going to go that way.&lt;/p&gt;</content>
        </entry>
    
        
        <entry>
            <title>Contact Form Project 04: Beginning Implementation</title>
            <link href="https://noah-roberts.dev/blog/contact-form-project-04-beginning-implementation/"/>
            <updated>2026-10-06T00:00:00Z</updated>
            <id>https://noah-roberts.dev/blog/contact-form-project-04-beginning-implementation/</id>
            <content type="html">&lt;p&gt;The last installment was not really finished but I just published it anyway. I lost track of doing this blog as I advanced in the project. Last time I talked a bit about the testing. Since then I&#39;ve implemented the very first real behavior and checks. I also did a lot of work on the build system so that it can do partial rebuilds instead of recalculating all the certificates for each build.&lt;/p&gt;&lt;h2&gt;Using Rust&lt;/h2&gt;&lt;p&gt;The act of learning rust at the same time has proven to be a hurdle at times. It&#39;s going quite well, and the language&#39;s compiler is very helpful here, but there&#39;s still a bunch I don&#39;t know and I keep making mistakes that are difficult to resolve. I do really like the language so far, but if this was hard-engineered product I wouldn&#39;t have chosen Rust because I don&#39;t know enough about it. I&#39;m stumbling around until stuff works and though I&#39;m basing this on the documentation and I&#39;m picking up the reasons why things are broken--it&#39;s just impossible to anticipate how long stuff is going to take me and the end product is not going to have the sort of confidence that is necessary for tightly regulated software development.&lt;/p&gt;&lt;p&gt;I do feel I can do a good enough job with this though so I&#39;m not worried about that here. I understand the sorts of problems that come up in languages like Rust that are close to the machine and the compiler for this language really is very helpful. I&#39;m also confident that I&#39;m picking up what I need to so that I will understand better soon. It&#39;s like C++ but it&#39;s also very different. The patterns it encourages are patterns I&#39;ve used in C++ but are more difficult/complicated there. Traits are similar to &amp;quot;policies&amp;quot; in Alexandrescu&#39;s &amp;quot;Policy Based Design&amp;quot; constructs in his &amp;quot;Modern C++&amp;quot; book, for example. There&#39;s much more freedom with Traits though.&lt;/p&gt;&lt;h2&gt;Messing up rigor&lt;/h2&gt;&lt;p&gt;I moved past the step of &amp;quot;simple configuration&amp;quot; and accepted that as &amp;quot;done&amp;quot; before I should have. It still panics if you don&#39;t supply a file name. Still panics if there are parse errors I&#39;m sure but I don&#39;t know because I haven&#39;t tested that.&lt;/p&gt;&lt;p&gt;This step isn&#39;t a complete feature. The actual format of the configuration file is mostly irrelevant and is going to change significantly. How it&#39;s provided to the program isn&#39;t completely set either and may change. I was tempted by these facts, the desire to learn more and get more designed, and the desire to make more progress sooner. This is instant technical debt though and is just damn sloppy. Even though I&#39;m just sort of throwing this together to have a base, that base needs to be more solid than this. Yes, I need to waste my time making sure errors are handled that are just going to be impossible later. Yes, I need to waste my time testing to make sure those errors are handled.&lt;/p&gt;&lt;p&gt;You&#39;re not doing actual incremental development if you are postponing &amp;quot;finish&amp;quot; work for later. To adhere to agile principles in order to call this task &amp;quot;done&amp;quot; I need to make sure it follows the requirements of the system and one of those is that it handles errors correctly. Each feature should be &amp;quot;done&amp;quot; before it is said it is &amp;quot;done&amp;quot; even if &amp;quot;done&amp;quot; isn&#39;t anything like what it will be when everything is &amp;quot;done&amp;quot;. The reason is simple: if you don&#39;t then this stuff slips through the cracks to production.&lt;/p&gt;&lt;p&gt;If you do have some item that maybe can&#39;t be completed in this way or would be too expensive to or whatever then the exception needs to be made in the forefront. I did not plan it that way. If you do then you&#39;ll have the finishing of this created as a future item already. Or perhaps you call this a scaffold and it doesn&#39;t even label anything as completed in the plan but is instead part of the feature item it&#39;s needed by.&lt;/p&gt;&lt;p&gt;At any rate, you don&#39;t do what I did. Don&#39;t approve items that haven&#39;t been really reviewed and don&#39;t approve items as &#39;done&#39; if they fail to meet that definition. So I&#39;ll be going back to fix this before I continue with what I was going to do next: the &amp;quot;authentication&amp;quot; scheme.&lt;/p&gt;&lt;h2&gt;CMake meta build&lt;/h2&gt;&lt;p&gt;I got tired of having every image basically have to be rebuilt because the CA test keys got built every time. I wanted to have a system that knows dependencies and can do incremental builds. I picked CMake because I&#39;m fairly familiar with it and it does everything I need it to.&lt;/p&gt;&lt;p&gt;This area I feel I got pretty good but I have yet to see it tested by someone else or on systems that aren&#39;t basically my own setup. The combination of nix, docker, pytest, and cmake form a develop and test bench that should be pretty close to turn-key. I have a few kinks to work out I think but it&#39;s dialing in. You should be able to follow the README.md file to get a build and run the tests and there&#39;s only a couple base dependencies and commands you need to run.&lt;/p&gt;&lt;h2&gt;Moving forward&lt;/h2&gt;&lt;p&gt;This blog is probably going to continue to suffer. This project isn&#39;t going to so much serve as an example of how to do this but more a practice bench for myself to hone my processes. Then I can document those and maybe convert that into teaching material.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://gitlab.com/noah.roberts.sse/contact-form/-/tree/a5fbbb363747ab72aa3088691f7eb622bd1e1126&quot;&gt;Current code state&lt;/a&gt;&lt;/p&gt;</content>
        </entry>
    
        
        <entry>
            <title>Contact Form Project 03: A testing system</title>
            <link href="https://noah-roberts.dev/blog/contact-form-project-03-a-testing-system/"/>
            <updated>2026-09-24T00:00:00Z</updated>
            <id>https://noah-roberts.dev/blog/contact-form-project-03-a-testing-system/</id>
            <content type="html">&lt;p&gt;In the &lt;a href=&quot;https://noah-roberts.dev/blog/contact-form-project-02-project-beginnings&quot;&gt;previous installment&lt;/a&gt; I linked to a plan I&#39;d created that had the first set of tasks about designing a base test system that provides automation for testing. In this one I&#39;ll talk a bit about what I did to accomplish that and how to look it over and reproduce my work (run the test successfully).&lt;/p&gt;&lt;h2&gt;git-bug issues&lt;/h2&gt;&lt;p&gt;I also talked about modifying a couple requirements last time and that I needed to track issues somehow. I did decide to experiment with &lt;code&gt;git-bug&lt;/code&gt; and so that&#39;s become a part of the process here. Unfortunately, it looks to me like I didn&#39;t verify it was usable if I deleted my current working copy because it isn&#39;t in the copy I made to verify my test process can be recreated. So before I talk about how to use that system I have to figure out how to fix it and may be changing my mind about using it.&lt;/p&gt;&lt;p&gt;The issue is that my user identity doesn&#39;t seem to be available to adopt before I pull and I can&#39;t pull without adopting my identity. This is fixed in the version they just released a couple days ago but I haven&#39;t updated yet. I&#39;ve verified you can pull and review the issues if you want and have the latest &lt;a href=&quot;https://github.com/git-bug/git-bug&quot;&gt;git-bug&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git bug pull
git bug bug&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It&#39;s not really going to tell you a whole lot right now though.&lt;/p&gt;&lt;h2&gt;test design&lt;/h2&gt;&lt;p&gt;The &lt;a href=&quot;https://noah.roberts.sse.gitlab.io/-/contact-form/-/jobs/16718887914/artifacts/design/_build/html/design/test/index.html&quot;&gt;test design document&lt;/a&gt; describes how the tests are made to work. The system uses &lt;code&gt;docker&lt;/code&gt; for now but I have plans to switch to &lt;code&gt;podman&lt;/code&gt; to hopefully eliminate some issues with the setup, which reflect the fact that I&#39;m pretty lazy about the security of my own development docker environment. There are a couple things I really wanted out of this:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;testing takes place on a faked internet where the real thing can&#39;t be accessed.&lt;/li&gt;&lt;li&gt;tests can be fully automated including the setup/teardown of different faked internets.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The top diagram of the page describes the components. For now the implementation is just a &amp;quot;hello service&amp;quot; that returns &amp;quot;Hello, World!!!&amp;quot; when you do a get on its root resource.&lt;/p&gt;&lt;p&gt;A simple sort of certificate authority is made from shell scripts. The CA&#39;s certificate is registered as authoritative with the service and contact systems. The CA&#39;s certificate generation script is used to create keys and certificates for the form and service servers, which are used by them to be accepted by the service and contact systems and then encrypt traffic. I wanted to use ACME here but I&#39;m going to figure that out later.&lt;/p&gt;&lt;p&gt;With the certificates made and the service built, some docker images can be built that have the necessary software and components to make a fake deployment. There&#39;s some shell scripts to do this building that are all tied together into &lt;code&gt;/tools/build.sh&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Once that&#39;s done, networks can be created that have &lt;code&gt;dnsmask&lt;/code&gt; to resolve domain names (docker has its own but this is simulating real names), any number of form systems, and any number of services that can run behind nginx-proxy images. Within this network the contact system can be available or join and then access the form or service to test it.&lt;/p&gt;&lt;p&gt;One example was made in &lt;code&gt;single-form&lt;/code&gt; that just has one form system with one service system along with the dns resolver and a contact image that runs firefox such that it can be accessed from a browser on the localhost.&lt;/p&gt;&lt;p&gt;Automation is then added to this by having a &lt;code&gt;testnet&lt;/code&gt; isolated network available that a contact system running selenium can join on which can also run another image that has pytest and docker-in-docker to both start up the test network the contact system is in and also control that system&#39;s selenium through &lt;code&gt;webdriver.Remote&lt;/code&gt; in pytest scripts. An example test was created that starts up the &lt;code&gt;single-form&lt;/code&gt; test network and then fetches the service message to validate it. This &lt;code&gt;testnet&lt;/code&gt; is created by &lt;code&gt;nix develop&lt;/code&gt; on entry but it doesn&#39;t then get deleted until the developer does or the system resets.&lt;/p&gt;&lt;h2&gt;Why all of this?&lt;/h2&gt;&lt;p&gt;It&#39;s important to make test automation a first-class citizen in the project plan and design. I&#39;ve tried here to cover all the basic things I need from the test system. Namely that:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;I&#39;m able to automate most even if I can&#39;t use a free CI/CD server.&lt;/li&gt;&lt;li&gt;The system is tested in as close to the production environment as I can mimic.&lt;/li&gt;&lt;li&gt;My tests are isolated and aren&#39;t erroneously affected by the real world or visa-versa.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;By using virtualization I can simuulate a great deal about the production environment in a way that doesn&#39;t alter the way the system has to behave. It may be additionally useful or preferable to use a completely virtualized system image but containers can do a lot here and can do enough for now. The original plan I had did hope I&#39;d have an actual base system image I&#39;d start with and then install things on and set up in virtual networks with kvm instead, but this implementation still sufficiently serves the purpose of exercising the design.&lt;/p&gt;</content>
        </entry>
    
        
        <entry>
            <title>Contact Form Project 02: Project Beginnings</title>
            <link href="https://noah-roberts.dev/blog/contact-form-project-02-project-beginnings/"/>
            <updated>2026-09-17T00:00:00Z</updated>
            <id>https://noah-roberts.dev/blog/contact-form-project-02-project-beginnings/</id>
            <content type="html">&lt;p&gt;In this post I&#39;m going to go over the design a bit and some of the implementation I did yesterday. But first some things of note:&lt;/p&gt;&lt;h2&gt;Questionable requirements&lt;/h2&gt;&lt;p&gt;I think I still got a bit too much into my idea of what a secure form processing service will look like in my requirements. Two important examples are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The service shall encrypt recipient data at rest.&lt;/li&gt;&lt;li&gt;The service shall encrypt all communications.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There are two very important security requirements for anything you actually put out there as a service. That&#39;s my opinion anyway and I do believe these are also pretty much verbatim out of OWASP. But should this service be responsible for this?&lt;/p&gt;&lt;p&gt;The answer is actually a very certain, &amp;quot;Absolutely not!&amp;quot;&lt;/p&gt;&lt;p&gt;This should be done by the operating/init system in the first case and by a proxy like traefic, nginx, or caddy in the second.&lt;/p&gt;&lt;p&gt;I&#39;ve actually seen this mistake happen before and I just repeated it. Requirements to encrypt this or that got written in stone and then the implementation ended up being an utterly stupid response just to fulfill a requirement that maybe should not have been there to begin with.&lt;/p&gt;&lt;p&gt;If I were only using all of my &amp;quot;Design Manual&amp;quot; to help myself in creating the design, and yes I find all that diagram nonsense helpful, then I wouldn&#39;t bother going back and fixing this. I need to though. These requirements cannot stand as is and I intend a complete, coherent work package or as close as I can get without being reviewed (though good review is desired).&lt;/p&gt;&lt;p&gt;In a real SDLC, and especially one that needs to be compliant with 62304, 13485 and others, I would need to make sure this was traced in some way. This means that the reason why I was making the change is documented, what the actual change was, and that this change was approved all needs to be somewhere. The best way to do this is actually with an issue managment system that tracks an issue from creation, through commenting, approval, and to final resolution and acceptance.&lt;/p&gt;&lt;p&gt;In my final goal for my own process around all this these tickets are in git with the code. This is so the whole project everything is in one database and multiple forms of documents can be produced from it. There are projects that could form the basis of this such as &lt;a href=&quot;https://github.com/git-bug/git-bug&quot;&gt;git-bug&lt;/a&gt; and &lt;a href=&quot;https://radicle.dev/&quot;&gt;radicle&lt;/a&gt; that could help here. I may go ahead and pick up git-bug today to fix this problem just to have that record to work with even if it&#39;s not in perfect form--because I don&#39;t even know that that is yet.&lt;/p&gt;&lt;p&gt;What I need for these requirements is not part of the implementation but part of the deployment and thus the documentation. So there needs to be something to include those things because THAT is what I actually want: a documented (and hopefully scripted) process to delpoy the thing in a secure manner that encrypts data at rest and encryts traffic in/out of system nodes. I also need to add these deployment components to my architecture design.&lt;/p&gt;&lt;h2&gt;Design&lt;/h2&gt;&lt;p&gt;I worked on documenting a design that responded to requirements. It&#39;s only the very upper layers of architecture and process description that would form the documentation needed for a non-safety critical piece of medical software. You are expected to create a more detailed design but it doesn&#39;t need to be documented and submitted.&lt;/p&gt;&lt;p&gt;That&#39;s the idea I have anyway. I&#39;ve seen some of this process work and read a great deal about it but some of my involvement was further away and the certifications I actually saw completed were relatively easy to get and not &amp;quot;medical grade&amp;quot; such as a CE mark.&lt;/p&gt;&lt;p&gt;The design I have to date is &lt;a href=&quot;https://noah.roberts.sse.gitlab.io/-/contact-form/-/jobs/16568508382/artifacts/design/_build/html/design/index.html&quot;&gt;here&lt;/a&gt;. You&#39;ll note it&#39;s missing a response to one of the two requirements I flagged. The response I did for the other is flawed I think and should instead do the decryption in init and then pass the decrypted data to the service. I did consider that this means the service can&#39;t load the config in protected memory or something (with a crypt library maybe) but I think maybe that level of security here is unwarranted and impractical and may not even do anything beneficial. Deployment can then use an encrypted partition and/or some other secret management like maybe agenix.&lt;/p&gt;&lt;h2&gt;Planning&lt;/h2&gt;&lt;p&gt;I made a set of diagrams to help me plan out the project. I hope it&#39;s fairly accurate and adequately covers the documentation requirements I have set for myself, but it&#39;s possible that part could push me over. The dependency relationships between tasks already broke down considerably when it came to implementing but I believe everything is accounted for. Time will tell.&lt;/p&gt;&lt;p&gt;I&#39;m tracking progress in that &lt;a href=&quot;https://noah.roberts.sse.gitlab.io/-/contact-form/-/jobs/16568508382/artifacts/design/_build/html/plan.html&quot;&gt;page&lt;/a&gt; in the design document. This is a stupid and pointless way to do this but I wasn&#39;t going to use ticketing. I may have changed my mind though due to wanting to do the tracing of change reason and to experiment with git-bug (I have to be very weary here because I get distracted into these side things easily). With that in mind it could be easier and better to generate this sort of documentation out of that system. This is what the &lt;a href=&quot;https://www.tidepool.org/blog/tidepools-open-source-qms-gets-iso-13485-certified&quot;&gt;Tidepool Open Source QMS&lt;/a&gt; does for a lot of things--they generate many of their submitted documents from their JIRA issue system and you can see this in their SOPs.&lt;/p&gt;&lt;p&gt;The plan has me creating a bunch of test support code first and a skeleton service. The system includes a way to build a fake internet on the test system and perform automated tests with various environment and service setups. It&#39;s actually pretty amazing how easy this part is going to be through modern tooling. In the past this sort of thing would have been more difficult and maybe require a cluster of physical computers. I&#39;ve already got a lot of it running in docker.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://gitlab.com/noah.roberts.sse/contact-form/-/tree/b002beb8f85ad16fc99fa8d26d454256ce890948&quot;&gt;Project status now&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Next: Implementation&lt;/h2&gt;&lt;p&gt;I&#39;ve actually made some serious progress, but I don&#39;t like to have partial commits and I didn&#39;t quite finish yesterday. So you can&#39;t see it yet. But...&lt;/p&gt;&lt;p&gt;I did want to do this in nix or guix and may spend time on that if I have time, but decided to go with docker images for now. It&#39;s lighter and simple and I know a lot more about how to do it already. It might be better to use podman but I need to install it better in nix and don&#39;t want to mess with it right now. It makes little practical difference and will be easy to switch later.&lt;/p&gt;&lt;p&gt;What I have so far is a script that:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;creates a root CA key and self-signed certificate&lt;/li&gt;&lt;li&gt;[temporary] creates a test server key and certifies it&lt;/li&gt;&lt;li&gt;creates a docker image that includes the root CA cert in its ca-certificates&lt;/li&gt;&lt;li&gt;creates a version of the nginx image that publishes to ssl and uses the test server key by default&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I then have a couple compose setups that use dnsmasq and a private network with combinations of additional images that let me:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;verify I can make a private internet where I can lie about domain resolution.&lt;/li&gt;&lt;li&gt;verify my base image correctly accepts server certificates signed by the CA root.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;From here I intend to wire up my own &lt;a href=&quot;https://acmeprotocol.dev/acme/overview/&quot;&gt;ACME&lt;/a&gt; server to make dealing with the CA something I don&#39;t really have to think much about. This will be a fake &lt;a href=&quot;https://letsencrypt.org&quot;&gt;Let&#39;s Encrypt&lt;/a&gt; to automatically get certificates.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://gitlab.com/noah.roberts.sse/contact-form/-/tree/feat/base-test-system&quot;&gt;Working branch&lt;/a&gt;&lt;/p&gt;</content>
        </entry>
    
        
        <entry>
            <title>Contact Form Project 01: Project Initiation</title>
            <link href="https://noah-roberts.dev/blog/contact-form-project-01-project-initiation/"/>
            <updated>2026-09-17T00:00:00Z</updated>
            <id>https://noah-roberts.dev/blog/contact-form-project-01-project-initiation/</id>
            <content type="html">&lt;p&gt;I&#39;m very unhappy with the way I have contact set up here and at my business&#39;s website. One drawback of using static sites only is that I can&#39;t have any dynamic processing and so can&#39;t set up a form that sends an email--that option is sort of available but it&#39;s terrible and doesn&#39;t really work anymore.&lt;/p&gt;&lt;p&gt;There are other businesses I could pay to do this processing. These businesses set up a system whereby you can have your form content sent to your email in a more secure way. &lt;a href=&quot;https://web3forms.com/&quot;&gt;Web3Forms&lt;/a&gt; is an example. The objective being to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;hide your email address from wouldbe spammers&lt;/li&gt;&lt;li&gt;have a contact form that works if the user doesn&#39;t have an email client and/or email.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Web3Forms seems decent enough--I&#39;ve not tried myself--but I&#39;m also in need of a professional portfolio better than a work history in enterprise and medical. I also have to admit that that history doesn&#39;t have a lot of requirements analysis or planning in it and is mostly development, design, and mentorship. A contact form is a simple enough project to do some exercising of my own, play with some ideas in project management, maybe instruct a bit, and showcase what I can do in this area.&lt;/p&gt;&lt;h2&gt;What&#39;s the project going to be?&lt;/h2&gt;&lt;p&gt;I&#39;ve started a lot of work in requirements analysis and design that I&#39;ll be talking about in this entry later. The brief of it is though that this will be a secure contact form server that I can configure for myself and my website clients (when I get some) that offers the sort of guarantees I want from such services. In doing so I&#39;ll be leveraging some quality controls that are really just in my head for now but are meant to protect user data from any and all unauthorized access.&lt;/p&gt;&lt;p&gt;In this I want to document some of my thoughts on how to design such systems and ensure that they work the way you say they do to the best of your ability. I can&#39;t go so far as to guarantee a lot of things because I don&#39;t have the expertise to say things like whether or not the claim that this or that algorithm is quantum secure is true or not. I have to trust that the experts are telling the truth. I can do my best though to apply their work as intelligently as possible.&lt;/p&gt;&lt;p&gt;Some things I&#39;m doing the long way because I don&#39;t know of the right tool to do it the easy way. I&#39;m sure these tools exist and can be tied together the way I want, but so far I&#39;ve not found that solution and I need to get something done so--the size of this project makes it still possible to do what I want the way I want.&lt;/p&gt;&lt;h2&gt;Starting out - Design Inputs&lt;/h2&gt;&lt;p&gt;The 62304 process has &amp;quot;Design Inputs&amp;quot; feeding a &amp;quot;Design&amp;quot; process that results in &amp;quot;Design Outputs&amp;quot; that are then used as inputs to the next process in the Software Development Life Cycle (SDLC). Some managers and quality control people take this to mean that you have to do one, and then the other. I do not believe this to be the case, especially since the standards say so. What this tells us is that there&#39;s a dependency relationship here.&lt;/p&gt;&lt;p&gt;You indeed do have to start the process of requirements gathering before you can start designing anything.&lt;br&gt;Otherwise you&#39;re just desiging a whatever and don&#39;t even know if it has anything to do with your product. But this relationship can and should feed back on itself. So your Design process may have Design Outputs that are themselves Requirements that get fed into the Requirements Analysis process that creates the Design Inputs to begin with.&lt;/p&gt;&lt;p&gt;So it&#39;s an iterative thing. You do some requirements analysis and come up with some basic requirements and then you do some initial design work to come up with some architecture maybe, do some research into what some of the ramifications are, and then feed that back into requirements with your findings. Then this loops back on itself and at some point you actually start trying to implement the design, which will be changing but when you&#39;re here you know enough to start and see if your assumptions are correct. They won&#39;t be. This will feed back into design, and this may result in more requirements and these may in fact conflict with others.&lt;/p&gt;&lt;p&gt;At the end of this you need a correct implementation of a coherent design that responds to the requirements.&lt;/p&gt;&lt;p&gt;So I started out with some &amp;quot;Design Inputs&amp;quot;. Standards don&#39;t say what these are so I&#39;m borrowing a little from SysML and a little from some of the processes I saw when doing medical software development. I think maybe there should be more up-front test design than I&#39;m doing, which was just to jot down some &amp;quot;acceptance criteria&amp;quot; but when the whole thing is done and documented those criteria I think will translate into actual tests or at least be linked to them. The object here is so that those who desire the product have thoroughly thought out what they really want and how they&#39;ll tell if they got it. The more detail the better but generally you don&#39;t get to hash it all out and that has diminishing returns on quality and coherence of design.&lt;/p&gt;&lt;h2&gt;The Project&lt;/h2&gt;&lt;p&gt;The Project code is &lt;a href=&quot;https://gitlab.com/noah.roberts.sse/contact-form&quot;&gt;here&lt;/a&gt;. I&#39;d first like to discuss a couple of things I did here to help with quality. The first of these is a standard development environment that is easily installed and entered. The second is the assertion of commit checks in the form of &lt;a href=&quot;https://pre-commit.com/&quot;&gt;pre-commit&lt;/a&gt; hooks.&lt;/p&gt;&lt;p&gt;For the first, I&#39;m currently using the Nix package manager and devshells library along with a docker image to support some python utilities. The devshell setup lets me activate some commands on entry, pull in commands the developer may not currently have in their environment, and set up some aliases and commands of my own. In my case the main command I need at this time is Jupyter Book version 1 because that&#39;s what I&#39;m using to document my project.&lt;/p&gt;&lt;p&gt;For the second part I&#39;m using the previously mentioned &lt;code&gt;pre-commit&lt;/code&gt; plugin that I install with Nix. I do expect I may run into trouble here since it&#39;s Python based and Nix doesn&#39;t play well with Python but for now it&#39;s working. I add the &lt;a href=&quot;https://github.com/compilerla/conventional-pre-commit&quot;&gt;conventional-pre-commit&lt;/a&gt; plugin for it to make sure I always use &lt;a href=&quot;https://www.conventionalcommits.org/&quot;&gt;Conventional Commits&lt;/a&gt; when I commit. Why Conventional Commits? Because what the format is isn&#39;t as important as that there is one and it&#39;s not worth thinking about too much. That standard covers pretty much everything that needs covering so there you go.&lt;/p&gt;&lt;p&gt;Yes, the hook has already irritated me but I&#39;m keeping it. Using Conventional Commits will allow me to automate things like release numbering, changelog generation, etc... Having thoughtful commit comments is really important to keep an informative history. The Conventional Commit format gives you some reason to think about what the commit content is going to be and helps you with some basic things you really need to include while encouraging more. This is not something that should be forgotten about and it&#39;s going to be central to my own Quality Management System. My own comments may not be the best always, but with this in place I&#39;m at least giving it some consideration. Have a look:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://gitlab.com/noah.roberts.sse/contact-form/-/commits/main&quot;&gt;Full history of main&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://gitlab.com/noah.roberts.sse/contact-form/-/commit/08ba69e953e3fcd7acb2cea2edad75a5079abad5&quot;&gt;Example entry&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Let&#39;s see those Design Inputs&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://noah.roberts.sse.gitlab.io/-/contact-form/-/jobs/16454817865/artifacts/design/_build/html/requirements/index.html&quot;&gt;Here&lt;/a&gt; is the version I would have put forward as a first attempt, though there would have been more back and forth during this process with the actual client to come up with these. On my own I put on both hats a few different times.&lt;/p&gt;&lt;p&gt;As you&#39;ll note, there&#39;s really only one feature requirement in the entire thing: take form input and deliver to the user. The rest of the requirements are largely about the security features used to try limiting how much this thing costs me to run, how much it spams the user, and that it NEVER turns into a spam source for random people.&lt;/p&gt;&lt;p&gt;There was a few times when I really had a particular implementation in mind. I tried hard to discourage myself from most of these because, and this can be hard for a client to hear, how the thing does the thing isn&#39;t the important part for this process. The design process really does need the freedom to reach out and find the things that will best implement exactly what is desired, not a pre-concieved notion of what that will be. It&#39;s very difficult to do sometimes and it&#39;s not always clear you are focusing on an implementation rather than on what you actually want, but it&#39;s very worth making sure you think long and hard about it. In the end I ended up with quite a few less, much more manageable requirements that say exactly what I want done.&lt;/p&gt;&lt;p&gt;This is a first draft and I&#39;m not the best at making &lt;em&gt;clean&lt;/em&gt; documentation but it should at least be clear.&lt;/p&gt;&lt;h2&gt;Design and planning&lt;/h2&gt;&lt;p&gt;Next time I&#39;ll talk about the &lt;a href=&quot;https://noah.roberts.sse.gitlab.io/-/contact-form/-/jobs/16568508382/artifacts/design/_build/html/intro.html&quot;&gt;Design and Planning&lt;/a&gt; I&#39;ve done previous to writing this blog. In the meantime I&#39;m going to start on actual coding.&lt;/p&gt;</content>
        </entry>
    
        
        <entry>
            <title>Hello Again and First Client Website</title>
            <link href="https://noah-roberts.dev/blog/hello-again-and-first-client-website/"/>
            <updated>2026-08-14T00:00:00Z</updated>
            <id>https://noah-roberts.dev/blog/hello-again-and-first-client-website/</id>
            <content type="html">&lt;p&gt;I&#39;ve recreated my site yet again. I removed the &lt;em&gt;profile-esque&lt;/em&gt; front page I had for a standard introduction page. I also removed my photo and the funny stripe it had down the left for bigger screens. It&#39;s just a plain site now.&lt;/p&gt;&lt;p&gt;I also converted to &lt;a href=&quot;https://11ty.dev&quot;&gt;eleventy&lt;/a&gt; because I&#39;m going to start using it for website development from here on unless my client wants me to target something else. It gives me way more power and control. There&#39;s more to learn but less to fight with.&lt;/p&gt;&lt;p&gt;I also used stuff I learned from &lt;a href=&quot;https://every-layout.dev&quot;&gt;every layout&lt;/a&gt; though not a lot in this site. I used more from there at &lt;a href=&quot;https://coastalmovement.studio&quot;&gt;Coastal Movement Studio&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Finally, I removed the old blog articles that were just about me learning. That stuff was probably not actually useful for anyone but me. I&#39;m not sure if I&#39;m going to totally stop doing that kind of article, but for now I want to concentrate on other types of things for this site.&lt;/p&gt;&lt;h2&gt;First client website&lt;/h2&gt;&lt;p&gt;I recently published the first site I did for someone else. It went through a first iteration in which I used &lt;a href=&quot;https://gohugo.io&quot;&gt;Hugo&lt;/a&gt; to generate the site. I wasn&#39;t really happy with that code and there were some changes needed to the site so I redid it in &lt;a href=&quot;https://11ty.dev&quot;&gt;11ty&lt;/a&gt;. I had also bought Every Layout and redid all of the site css using things I learned from there. Finally, to get started on 11ty I leveraged &lt;a href=&quot;https://learneleventy.dev&quot;&gt;this tutorial&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Everyone is pretty happy with it as it is now. The layout works way better, especially on smaller displays that I&#39;d had trouble getting to behave before using the techniques in Every Layout.&lt;/p&gt;&lt;p&gt;I had her register her own domain name that I then configured to point at her website hosted on &lt;a href=&quot;https://docs.gitlab.com/user/project/pages/&quot;&gt;GitLab Pages&lt;/a&gt;. This is a free service that hosts a static website from a &lt;a href=&quot;https://git-scm.com&quot;&gt;git&lt;/a&gt; repository. This site is then configured to use &lt;a href=&quot;https://letsencrypt.org&quot;&gt;Let&#39;s Encrypt&lt;/a&gt; to serve over https--this is important even though she&#39;s not currently selling anything or keeping peoples&#39; information at that site.&lt;/p&gt;&lt;p&gt;The repository is configured to build the site any time I push changes to the main branch. The GitLab documentation on setting this all up is very well done and easy to follow so you don&#39;t need me for it, but I&#39;ve done it a few times now so can be a big help making sure it gets configured correctly and yes, you can mess things up. I help people through stuff like this too though and the objective here is really to empower my clients to be able to do more on their own with reduced expenses. In theory, she can edit the content of her site any time she wants and it&#39;ll get updated and I&#39;m not needed. This is going to require some training in things like git though, which is a developer tool but ties in with system tools and isn&#39;t THAT hard to understand--there&#39;s also a decent online editor that GitLab provides.&lt;/p&gt;&lt;p&gt;The cost for renewal of the domain is going to be much higher next year but still &amp;lt; $50 probably. So long as GitLab continues to offer this service that&#39;s the only ongoing cost required to keep the site up and it&#39;ll just stay that way as long as the domain is registered. The primary expense is in site development and changes. To have me create a site like it would cost something in the $1-2000 range and take 1-2 weeks. I work directly with you at your level so you get what you want.&lt;/p&gt;</content>
        </entry>
    
</feed>
