Quarterly inventory – 2025 Q4

Dear FutureMe,

Today would be a good day to do a quarterly inventory.

How is your personal life going?

How is your work life going?

How is your Volunteer Service life going?

Future Me

Personal Life

This quarter gave me the opportunity to attend two weekend conferences out of town, and I enjoyed both of them.

I’m a little depressed because cold-and-overcast season is here again. I can see why people like living in the desert. I have relatives who live in the Pacific Northwest, on the coast, and man, that would be depressing nine months out of twelve.

A walk to remember

Mildly amusing, I needed to get some car work done, so I took it to the dealer I bought the car from. This is probably not the best idea because they don’t treat me as well as I would like. No matter, I dropped off the car first thing in the morning, went to a little cafe and got breakfast, and then texted a retired friend in town that I’m in town, and would he mind if I dropped by for a visit? He said, Sure, did I want a ride? No thank you, I’ll walk – I need the exercise; it will only be a 25 minute walk from downtown to his house.

I was about five minutes into the walk when the gastric distress kicked in.

I successfully did not poop my pants. Let’s get that said right up front. But man, it was an excruciating walk: go some number of feet, stop, pause, clamp down, and wait for the spasm to pass. Nowhere along the walk was a public park with a public restroom. I wasn’t going to walk up to a random house (if anyone is even home) and request to destroy their bathroom. Anyway, the mildly amusing part was that at some point, I paused, crossed the street, and paused again right behind a small pickup truck sitting in front of a house. I look up, and on the back of the pickup truck was a sticker that was essentially this:

 

(click the + sign to reveal the spoiler)

Thank you, God, for reminding me You have a sense of humor. 😉

Public sector Uber / Lyft

Another thing that happened is that I became miffed with the City of Visalia for using my tax dollars to play the big shot. Visalia Connect

You see, I have friends who supplement their income by driving for Uber and/or Lyft. I’m 100% in favor of people who want a side hustle getting out there and doing the work – in the private sector. I despise when the public sector tries to undermine them, because they are doing so with your and my tax dollars. If the city wants to spend tax dollars on police and fire, I’m 100% in favor of that. If the city wants to spend tax dollars on a bus system with fixed routes, okay, that’s not the worst spend of tax dollars. It’s not a great spend of tax dollars, but sure, when someone gets so elderly that they cannot drive anymore, that there is a bus system they can use is a public good. Walking would probably be better exercise for them, but sure, it’s not the worst spend of tax dollars.

But Uber and Lyft? Why the hell should the city be trying to compete with that?

WORSE – the City of Visalia contracted with a French company to provide the service.

You can barely make it out on the photograph, but the side of the van says “Operated by RATp Dev USA”. RATP Dev USA is the North American subsidiary of RATP Dev, the international arm of the Paris-based RATP Group that operates public transportation systems worldwide.

My USA tax dollars are enriching a French company to undermine local taxpayers trying to improve their lives with a side hustle.

What the hell

Microtransit is a luxury, not a necessity. Let the people who want to bask in luxury pay their own way at private sector prices. Let local people make some money. Let Uber and Lyft, both based in California, make some money. Don’t be taking money away from our local police and sending it off to Paris, France.

Cynical me thinks that really, some corrupt official at the City of Visalia pushed through the idea to get kickbacks. I have no proof of it, but it wouldn’t surprise me. We’ve had lots of corruption in other areas. But yeah, I wouldn’t mind seeing the officials and bureaucrats behind this tarred and feathered.

Amazon shopping this Christmas (not)

I did just about zero Christmas shopping with Amazon this year. Their “Black Friday” prices are not better value than the rest of the year. I did buy a large Christmas gift from Costco.

Personal mail server

For about nineteen months now, my personal mail server has been rebooting. I just replaced it with a different installation here the third week of December. I expect that it will be rock-solid now.

Way back when, I built it as a combination WordPress (this blog), Dovecot/Postfix, and Nextcloud server. On Ubuntu. Well, the machine I was renting was too small, so I started splitting things off. Nextcloud I moved in-house onto bare metal. WordPress I moved to a different machine, but on Debian. I left Dovecot and Postfix on the Ubuntu box, because it was probably going to be the most painful to move.

When I built my personal mail server before, I used the excellent guide by Christoph Haas (workaround.org) to build it. Back then, I’d struggled a little bit with the difference that Christoph’s instructions were for Debian, and I was installing on Ubuntu, but I made it work okay. Let’s Encrypt certbot was a little tough because I wanted a wildcard certificate for multiple domain names.

But then the server started running out of memory. I built a script that checked for an out-of-memory condition, and if so, I rebooted the box automatically.

That was twenty-seven months ago. Initially, it would go three or four days without rebooting. Nineteen months ago, it was rebooting one to three times per day. Last month, it was rebooting at least three times per day and up to six times per day. I knew I wanted to work on it, but I also expected it to be a big job. Being ruled by a hundred forms of fear, I made it into a larger problem than it was – go figure.

I’d scheduled some vacation time for Christmas and even took off the Friday before Christmas week. Then my mom called me and changed my plans on when we were going (to later). Suddenly I have four days off before I need to be on the road, and that should be plenty of time – no matter how hard the migration went. It actually took about a day.

One thing Christoph doesn’t go into is fail2ban for the webmail. I did have that on the original Ubuntu box, although it was more for WordPress than anything. But for all I know, that was the source of the memory leak. I had also done a sort of funky disk layout, so I was running Restic for local backups. Maybe Restic was the source of the memory leak? I don’t know. But the new box has the email-on-reboot script in place, so I’ll see if it doesn’t reboot on its own any time soon.1

Since I re-enabled comments on this blog with the spam protection coming from hCaptcha, I thought I’d try it with my webmail client. It is working great.

KDE Donation

I’ve donated to the EFF and Internet Archive for close to a decade now – I’m happy to support projects I think are worthwhile. I started donating to the Thunderbird project two years ago in November.

This quarter the KDE project did a request for donations, and I have really liked KDE, so I signed up for a small, $5 monthly contribution. Not very long later, over on the KDE mailing list, their community manager called everyone on X/Twitter Nazis. Maybe I’m the one off-kilter here, but I thought a community manager was supposed to grow their community. The exclusionary stance ends up alienating normal people and stunting the growth of the community instead. Later, the KDE community said they supported their community manager being a bigot.

Yeah, I’m out.

If these people are so infected with TDS that they don’t see the damage they are causing, I’m certainly not going to be an enabler and continue donating to their project. It is sad because I was first exposed to KDE back in 2006, and I like the desktop environment. But perverse behavior should not be rewarded. I’ve cancelled my donation going forward. If a different desktop environment shows up that is as good or better, I’ll switch.

Work Life

Well, I found out I’d miscalculated my retirement date; the pay period ends one week later than I’d thought.

It is mildly amusing to me that February 2026 has perfect alignment, with the first Sunday being on the 1st and the last Saturday being on the 28th. On the calendar, February takes the space of exactly four weeks. May and August 2026 have the worst alignment, spanning six weeks. I did a post this quarter about programming in RPG II under the heading Helping Sales make promises they could keep. May and August were the sorts of configurations that RPG II was not naturally a good fit for.

I got (probably my last ever) Performance Appraisal and my boss was kind. I’ve been feeling guilty about how much work I’m not doing, but my boss said this is a good thing. Proper succession planning means I must train everyone else what to do when I’m not here, and the best way to test my training is to let them do the work.

Volunteer Service Life

The Events Calendar Pro (TEC)

Well, I added TEC to the website for the fellowship, but it has bugs. I’m having to watch for errant behavior and then run a MySQL statement on the server:

DELETE FROM wp_options WHERE option_name LIKE '_transient_tribe_views_v2_cache_%';

DELETE FROM wp_options WHERE option_name LIKE '_site_transient_feed__%';

Still, TEC is remarkably better than Sugar Calendar, so overall it is a win. We might try out ticket sales next.

Flyers for events

One thing where AI has been a blessing and a danger is in adding events from outside sources. I uploaded a flyer for an event to an AI and asked it to convert the flyer into WordPress-compatible HTML. In one minute it did the job that would have taken me an hour or two. So that was great.

Then for another event, I pointed the AI at a series of pages the organizing committee had put up. That went great.

Then for a third event, I did the same, but the information was wildly off. I went to the web page, copied the URL, and prompted the AI to read that web page and create HTML from it suitable for pasting into WordPress. It looked okay, but… the event is at a Sheraton hotel, and this says Hilton… and the Hilton is 25 miles away! Oof. I asked where the information it gave me came from, and it said the web page, “This is what it says”. I put into the AI prompt “No it doesn’t” – and of course, then it apologized and actually read the website and created correct content. Apparently, it had pulled information from ten years ago and had simply run with that. AI is not intelligent (yet).

Contact Form 7 and Captcha

Our office manager is a part of a community of other office managers. One of them did a demo of their website, and that office had an email contact form. My office manager requested we do the same. I’d tried Contact Form 7 back in 2018, but the spam was immediate and incessant – I quickly deleted it.

So now I need to add it back in, but not subject my office manager to the onslaught of porn, supplements, and cheap junk email. The nature of the fellowship is not a great fit for ratting out people to Google as members of this fellowship. Well, if reCAPTCHA is off the table, how about hCaptcha?

I implemented hCaptcha for the contact forms on the website, and it has worked great. I was happy enough with it that I signed up for a personal account and added it to this blog’s login form for user comments. Later I used the same account to protect webmail on my rebuilt personal mail server.

The only thing I’d like better is if there were a pricing plan between Free and Pro. I do believe in paying my own way.2 But for the month of December, I’ve used it twenty times (their dashboard tells me this). I cannot justify the Pro membership at $99 per month ($1,200 per year). The fellowship also believes in paying its own way, but also, we cannot afford $1,200 per year. $60 per year would be ideal – and I don’t actually want any additional features. I know that serving up their images and comparing the results takes CPU cycles. I just don’t want to be a freeloader.

  1. 2026-01-13 addendum: it did finally run out of memory and need to be rebooted after 17 days. ↩︎
  2. Unless you’re going to be an asshole and call me a Nazi for my choice in social networks (duh!) ↩︎

My first programming job – Truline Corporation

[four minute read – longer than most of my posts]

Previously I talked about becoming the Work Order creator (“Engineer”) at Truline.

Opportunity Knocks

At some point, we needed room, and I was relocated to another office, which I shared with the president of the company, Jack Cederloff.

I got the idea to write a W.O. generator in dBASE II. I brought in my Osborne computer (what it looked like) and my trusty Okidata dot-matrix printer and showed my creation to Jack. He offered me a job as their in-house programmer – if I would learn to program their mini-mainframe.

I’m gonna be a professional programmer!!! Life is going to be fun!

Night School

I went to night school at the Tulare County Organization for Vocational Education (TCOVE) and learned RPG II on an IBM System/36. They had a Big 36 – the 5360, and Truline got the Compact 36 – the 5362.

The class was fun for two reasons. First was that I was never a very social person, so going to this class, I met new people. I was 23 or 24 years old at the time. That I recall, there were four or five other people in our class. I do not recall who the instructor was. But I enjoyed learning new things, and this time it was a computer language. The other fun thing was that there was a high school senior at Mt. Whitney who was the computer operator of the Big 36, and she was super cute. While we were learning RPG II, she was running jobs for Accounts Payable, Accounts Receivable, General Ledger, and the school district’s student grades and attendance application. She would hang around while we did our homework on the 5250 terminals. I was a fan.

Report Program Generator II (RPG II)

RPG II itself is a terrible language. Later, I would learn that computer languages were labeled by their generation: Assembly was a First Generation language, and FORTRAN and COBOL were Third Generation languages. SQL and MATLAB are Fifth Generation languages. RPG II was a Second Generation language. Sigh.

Later still, at SCT, I worked with a lady who had a plugboard in her office as an art piece or conversation piece, I suppose. She described how the programmer would plug wires in from the results side of an operation (the right side) and wire it down to the control side (the left side) of a later operation. The origins of RPG II were suddenly revealed to me: I could see where RPG II indicators came from and why they triggered later operations in the code. They were virtual replacements for physical wires!

But yes, RPG II is a language to try one’s soul. Well, it isn’t too bad if one is detail-oriented and patient. Thankfully, I am both, so it didn’t bother me.

If you look here, you see that each line of code had a type specification, and each type was required to be in a specific order: U, T, H, F, E, L, I, C, O. The last three were the meat of programming: Input, Calculation, and Output. The type specification went in column 6 of the source code.

Yes, RPG II is a column oriented programming language.

But back to indicators: Calc lines did calculations, but they also set indicators. If the result of the calc was greater than zero, an indicator (two digits) specified in column 54 would be turned on. If less than zero, the indicator in column 56 was set, and column 58 would hold the indicator if the result was exactly zero. Well, there’s your WHILE statement: when the result of the variable was exactly zero, the indicator named in column 58 would be turned on, and conditional logic would change the program flow. At the beginning of a line were (up to) three conditions (indicators). If the indicators were on, the calc line got executed. If not, it was skipped. Page 1-7 of this link shows the processing cycle in RPG II. The processing cycle in RPG II is absolute and will happen, whether you want it to or not. It takes a bit of humility to accept that. Today, we wouldn’t think of telling the programmer that they have no choice in how their program runs. Anyway….

Programming as my day job

Truline upgraded from a System/34 to a System/36, and I went back to my original engineer office, but as a programmer this time. Shortly after, we moved the factory from Visalia to Farmersville. During the design phase of the building, we decided that we needed a computer room, so that became my office.

Come to think of it, this was the only time in my life when I had my own office.1

For the next two and a half years, I was programming in RPG II on this mini-mainframe. I loved being a programmer.

Initial work orders

The first thing I wrote was the system for getting input from the engineer and creating the work order. Steve, who had replaced me when I was promoted to programmer, was our engineer. Steve would log in and create a new work order, and would then enter codes, like “S” for a single-sided board, “D” for double-sided, or “M” for multi-layer. Based on the codes, I’d add the series of tasks (departments) needed for this order.2 After he did his data entry, my program printed out the work order that looked like the previous hand-drafted sheet, but without the steps that were not needed. The greenbar report was folded and put into the same plastic envelopes we used for hand-crafted paper work orders from before.

Truline sent me to training

The good was that the weeklong training was taught by the gentleman who designed American Airlines’ SABRE airline reservation system. He clearly knew his stuff, and I did learn things from him.

The fun was that Truline paid for me to fly to Dallas (iirc), and I took my Osborne on the jet plane flight. The Osborne was designed to fit under an airline seat, and with a bit of heft and struggle, there it fit. And… it so happened that my seat was immediately next to an IBM mainframe salesman who wondered, What the heck is that? I told him it was a portable personal computer.3 He looked me straight in the eye and asked me, “What is it good for” I explained that when I got back to work, I’d owe my boss a report about the trip. In the evening, I could write the report in the hotel room, and Monday morning when I got back, all I’d have to do is print it. His eyes showed he was amazed. Here this 25-year-old twerp was already into the next generation of computing, and here he was, a salesman for the biggest computer company on the planet, just getting gobsmacked with the future.

The bad was that my training instructor asked me which computer we had, and when I told him a System/36, he said that was no good, and I needed to upgrade to a System/38. The System/38 came with a built-in database, and any computer without a database was a toy computer. I was barely a programmer yet, so I never asked Truline to spend a hundred grand on a new mainframe for me. But yes, a database would definitely have been the way to go.

Tracking jobs through the factory

Then, back at work, I wrote a couple of programs that updated the last completed step on the job, and produced a daily report of all the jobs in the factory, one line per W.O. sorted by W.O. number (oldest jobs first). The report ran every morning. Every day that a W.O. did not change position, I grew a counter. The end of a line on the printout was a crude graph: the number of asterisks for the number of days the job hadn’t moved. If a job had more than four or five asterisks, the production manager knew to go to that department and find out what the hold-up was. It might be, for example, that a customer wanted red soldermask instead of green, and we were waiting for the custom order to show up. But other times, it was simply that a large job was in front of it, and it would take a few days to process 800 panels through that department. It became Robin’s job to visit every department at the end of every day, and write down the W.O. numbers of the jobs sitting in that department. Then she’d log in and update every work order with its current location. The next morning, the production manager, John Morado (who was also one of the owners), would get the report and manage production.

If I’d stuck with it, I’d have gotten to the point of printing QR codes on the work order and having a barcode reading terminal in each department for registering incoming and outgoing jobs. Jack Cederloff and I had talked about that; printing barcodes and wiring up barcode scanner terminals. That was before the move to Farmersville.

Helping Sales make promises they could keep

My next program was for the sales department. I went through every order due this month or in the future and totaled the dollar amount of the order by day. Man, programming a calendar in RPG II was painful! I wanted the calendar printout to look like a calendar: a grid of days, seven wide and (however many) weeks deep.

The goal was that every day would list the orders and their dollar value. Then at the bottom of the day, the total value for the day. The week would have seven columns for seven days, and when this week was finished, the next week would be computed.

RPG II and that compute cycle are NOT friendly constructs for dealing with the 31st of the month being a Wednesday, and every six months, there are five Wednesdays that month. Most months have five week rows, but some have six. February could have four, if everything aligned. And yes, I programmed in that every four years, February has 29 days. Rolling from the 31st, 30th, or 28th/29th of the month to the first of the next month means finishing one month and setting up the next month; however, the RPG II processing cycle will be obeyed, and if the next record breaks control into a new month, welcome to the house of pain. Turns out it was best to copy the data to a new table (file), run a job to append a “week number” and sort on that. Then, the control-break was on week number, which made the programming manageable. The last work order of the month wasn’t the trigger for the bottom of the calendar; that was handled by the week change routine, which came after the day totals.

Did I mention that the System/36 had 64 KB of RAM?4 A memory array would have been fine, if I weren’t worried about running out of RAM. So all the work I did was based on files on disk, running through the RPG II process for chewing through records. My Osborne had 64 KB of RAM too. Primitive times.

Anyway, the sales department was able to use the dollar amounts as a proxy for capacity. When a customer asked when they could get their order done, Sales looked at the calendar and picked a day five or six weeks out with the lowest dollars on it. They also looked to make sure that there wasn’t a huge order that needed to ship the day or two before. But it worked well; once a day got to around the $14,000 mark, that day was full, and they’d start telling the customer we could finish the job and ship the day after. If the days before six weeks looked puny, they could promise a faster delivery date and fill in those days.

A month or two before the Consumer Electronics Show in Las Vegas every year, we would have customers who were willing to pay double the normal amount if we could build their small order in one week so they could have actual products to demo at the CES show. Sales could look at the calendar and tell them yes, we can, or no, we cannot, based on how full the factory was for the date they were asking.

Job costing / forecasting

The next programming project was forecasting. That was a big project. I did time studies and all that, measuring how many minutes a task of a certain size would take. I measured big jobs and small jobs and kept numbers for task setup and task piecework. The accountant gave me the average hourly wage number. I made a table of time per task per panel. Then I chewed through every W.O. (and every task in each) and generated an estimate of how much the job would cost to build. The accountant and I compared numbers. The accountant explained that my numbers were off because of overhead. Wow there was a lot of overhead. I got to add an adjustment factor to come up with an estimate of real-world costs every month. I was pretty happy that for the first three months in a row, my computed projected expenses were within 10% of actual expenses. We updated my adjustment factor and got to under 5% variance. Mind you, I had zero training in being a time and motion analyst. I just figured it out as I went along.

Then we had a large customer ask us to provide a quote for many large orders, and my job cost program was used to provide an educated guess. Jack Cederloff was worried we’d underbid the orders, but my job cost estimator said we would be okay. We won the bid, and after several months and all those orders, we made out fine. My job cost estimator was good. 🙂

RPG II and the System/36 were not enough

In my home life, I’m reading Byte Magazine and Dr. Dobbs Journal and helping my dad with a business. He learned of a new technology: ultraviolet-cured liquid polymer could be used to make rubber stamps. I should do an entire post on just that. But the short version is that my dad had a PC’s Limited5 286 (10 or 12 MHz with the touch of a switch) with a monochrome monitor. There was a guy out of the South who made a program: a WordStar post-processor that extended WordStar’s “dot commands” for changing print settings (bold, italics, and such). It could include TIFF files and output to an HP LaserJet. My dad bought a scanner and would compose a mask with these dot commands and scanned images. He would print the rubber stamp mask onto clear plastic and burn the polymer into a pad he could glue to the stamp handle. There are a few stories here. Anyway, it was clear to me that personal computers were the future, whereas mainframes were not.

I had gotten to 27 years old and was stuck. Truline had moved to Farmersville, and all our cash flow was gone, tied up in the move.

Oh, another thing I had done was to go back to night school to learn accounting. It wasn’t so much that I wanted to be an accountant as that I just wanted to understand words like “debit” and “credit” when the accounting people spoke them. One teacher was particularly good, and I learned about ROI and cash flow.

We had no free cash for computer upgrades. I was stuck.

I could see that the future was all about the Local Area Network (LAN) and PCs attached to it, and Truline wasn’t going to have enough money for upgrades for years. Well, a few years, but at 27 years old, I felt an urgency to keep improving. Programming in RPG II was not it.

One early spring day, as I was walking back from lunch, I was internally grousing that things weren’t great and wouldn’t get better. Then it struck me: things wouldn’t get better!

I decided to wait a month, in case I was being rash. A month later, the outcome was the same: no, I wasn’t being rash – I was stuck, and Truline wouldn’t be able to afford upgrades for at least a couple of years. I decided to save up a bunch of cash and resign from my programming job. I didn’t know where I was going to go, but I knew I didn’t want to stay here.

The C programming language was not my cup of tea

Although I liked computer programming, Dr. Dobb’s Journal had suggested that learning to program in C was the way the world would go. I looked at C and hated it.

I like COBOL because if I intelligently name my variables, the program code reads like English. Clearer is better, always, in my book. The new styles of programming seemed to try to create a wizard-class, to purposefully make programming difficult for mere mortals to understand. This is vain and stupid to me. C was my introduction to this, and with that introduction … I’m out.

First, the arrays in C were indexed starting at zero instead of starting at one, the way God intended.6 Also, RPG II, FORTRAN, and COBOL had one-indexed arrays, which makes for useful structures as 1 = January, and 12 = December. So now in C, I’m supposed to take a perfectly fine date like 20251203, extract the fifth and sixth characters7 as the month number, and subtract 1 from it

Why don’t I just create an array of month_numbers-to-month_names with 13 elements and make month[0] = “Dumb-ass-uary” ?

If the ancient programmers (FORTRAN, COBOL, and RPG) figured out how to make the compiler adapt arrays indexed from 1, why couldn’t the C compiler programmers do so too? I thought it must be because they think that zero indexed arrays are a feature instead of a semantic bug.

Second, in describing loops, the C index incrementer could be written two ways, with different effects. One way:

while (i++ <= 10)

and then another way:

while (++i <= 10)

And the difference matters.

When I read this, my mind instantly said, “This is stupid. There’s no way I want to learn a language with weirdness like this”.

So I’d opted out of learning C, and the other languages available at the time weren’t appealing to me either.

Next in my biography: how I ended up in operations, working for local government.


  1. Today, four days out of five, I work from home. I don’t think it is the same thing. My dream of the best possible work environment was in the office, but with a closable door to keep the noise out, but also the freedom to take a break and hang out with co-workers for a minute or ten, getting a cup of coffee and shooting the breeze. A cup of coffee here at home is fine, but I’m not going to bounce into Teams just to shoot the breeze with any of my co-workers. ↩︎
  2. See my previous post for the tasks on the work order. ↩︎
  3. IBM did not have any portable PCs yet. Heck, they barely had the IBM PC AT. Compaq would soon swoop in with a portable PC in the Osborne-like form factor. ↩︎
  4. IBM said it had 128 KB of RAM, but that is because the System/36 had two processors, of 64 KB each. As far as programming went, 64 KB was all I had. ↩︎
  5. Later to be known as Dell Computer Corporation ↩︎
  6. I should do a blog post about this. I’ve since learned the why of zero indexing, and I can see the point of the trick, but it is still bad in my not-so-humble opinion. That and $8 will get you a cup of coffee at Starshmucks…. ↩︎
  7. Notice I didn’t extract the characters at index positions 4 and 5 ! ↩︎