Interfaces are Communications

Lately, I’ve been wondering if user interfaces might better be thought of communication and wondering if anyone had ever approached it that way. I was recently on Fiverr trying to set up a profile, and unable to find which link to click to describe a service that I would provide. After floundering around in frustration for several minutes I did a Google search and discovered that offered services are configured under a link called “gigs”. 

The problem was not that I had failed to see the word “gigs” in the interface. The word was pretty obvious. The problem was that the interface designers had used the word “gig” incorrectly. A “gig” is not a category of job. It’s a single job. The term comes from music. If I play guitar at wedding receptions, that’s a service I provide. If I play guitar at the Robinson wedding, that’s a gig. The word the designer should have used was “services”.

As a consequence of Fiverr’s mistake, I had assumed that “gigs” was a record of work that I had already completed and therefore I would have no reason to click it until after I had completed a gig. I don’t know if the UI designer was trying to be hip or clever, or whether they were a non-native speaker. Either way, this problem would have been avoided if the designer had followed one simple rule: use words only as they’re defined in a dictionary. 

What I hope this offers is a path for engineers who have to build interfaces without the help of UI designers or the benefit of user testing. Such an engineer can simply ask what do I need to get from the user and what do I need to provide in turn. I don’t think this is a panacea for bad interfaces, but I don’t see how it can hurt.

Lessons from AllBrowsers

My new project AllBrowsers is my way to explore using AI by doing. Here a couple of lessons I learned this week.

All Browsers?

I called my new project “AllBrowsers”. Then I found the list on webbrowserdirectory.com and learned that there are far more browsers than I realized. Do I cover them? Do I keep to the premise of the new blog or use a more impressionistic interpretation of “all browsers”.

If I were compiling my posts by hand, this would be a problem. When AI’s doing the compiling, there’s no reason to not add everything to my compilation list. If any of the obscure browsers are putting out regular content, I should be paying attention to them. If they’re not, the point is moot.

Testing

A note about my vibe coding. I’m often just doing what seems best to me. I may not be doing what engineers do. If anyone has resources on this subject to suggest, I’d appreciate it.

I always follow the Google method of writing unit tests which is to write a failing test first, then backfill the class to pass the test. The process in vibe coding is straight forward:

  1. Create an empty class with interfaces, but no code.
  2. Create the failing test.
  3. Backfill the class to pass the test.

When I added the second class to my app, Copilot created the test without my asking.

Something I really didn’t expect was an instance where the vibe code makes me a smarter coder. For functions that return strings, I would probably have tested a specific value that came back. Something like this, perhaps:

assert.strictEqual('Specific string', returnedValue);

Because Dammit, Jim. I’m a technical writer, not moon shuttle conductor. But copilot gave me this:

assert.strictEqual(typeof url, 'string');

I see that this is better, because my test verifies that my class returns the right kind of thing rather than a specific thing. If my underlying data source changes, my test doesn’t need to be touched. Why didn’t I think of that?

When Do I Start Writing?

A classic problem in software documentation is getting a clear signal about when to start. There are generally three ways to approach this. I call them human approaches, bureaucratic approaches, and technological approaches. 

Human approaches are engagement with the engineering team. My preference on a documentation project is to embed with the engineering team as much as I can. I attend standups and design meetings. I’m often able to spot documentation needs earlier than the engineers. A skilled writer will find opportunities to front load work that engineers miss. The advantage of human approaches is that writers learn of documentation needs early. This gives them more time to work on it, which improves its quality. 

There are several downsides to this approach. First it depends on the technical knowledge of the writer. The writer needs to understand the engineering and the technology as much as possible. 

On large applications this approach may not scale. Chrome has thousands of engineers on multiple continents. There wasn’t enough time for me to attend every meeting and standup. Many of them happened at times that were the middle of the night for me.

Bureaucratic approaches are the use of processes, often the same ones used to track engineering work. Tracking tickets are created for documentation tasks. They become part of the project’s burn down chart and the definition of ‘complete’ for a project includes documentation. Managers and higher-ups like this approach because it gives them a convenient list of what’s being worked on. 

A danger with this is that it can be overused. I had a boss a few years ago who insisted that even minor corrections be tracked with a ticket. If I found a misplaced comma, I couldn’t just fix it, I had to open a ticket and wait for the boss to assign it back. That this Byzantine absurdity was an inefficient use of time didn’t seem to matter.

These approaches work best when documentation tasks are tracked to run simultaneous to engineering tasks rather than as dependencies. This allows a skilled writer to frontload work, which improves quality. It also requires that writers be involved in planning meetings. Engineers will tend to set the starting points too late. I don’t criticize engineers for this because knowing when to start writing isn’t their job. They also think they’re doing me a favor by waiting for the work to solidify.

Technological approaches are the use of software to discover what needs to be done and notify writers. Since the only system for doing this is one that I built myself, many of my thoughts are speculative. 

When I was part of Chrome Developer Relations, I built MDNBanter to track changes to Chrome’s interface definition (IDL) files. I didn’t have server resources for this, so it was a local app I ran manually. Once a week I’d run a command to download the latest IDL files from source.chromium.org. The app would construct URLs for where the reference pages should be located on MDN and ping the URL. If the URL returned anything other than a 200 code, the name of the API was added to a list. 

Alternative ways to do the same thing would be to observe changes to header files, git commits, or unit and integration tests. I don’t recommend the latter unless the developers are following Google’s practice of writing tests first. Otherwise this would be too late in the process. Technological approaches are where AI is most likely to be useful, it seems to me. I’m still experimenting.

AI Legal Concerns

I hope this post doesn’t make me sound like a luddite. AI is here. People who don’t adapt to change tend to get left behind. This is probably more true in tech than in other fields. I’ve had some recent experiences with AI that are cause for concern. I’m sharing so that others may learn, comment, and advise.

A couple of months ago at work I was editing an internal blog post for an engineer. I like to have some background in the subject of works I edit. Otherwise I can’t tell you whether an opaque sentence is genuinely incomprehensible or merely incomprehensible to me. So I Googled the subject and discovered that the engineer had cribbed his introduction from the AI summary. That didn’t bother me. It was internal, and we’re all busy. 

When I get AI summaries, I click through to the AI’s sources. Given AI”s propensity for hallucinating, I don’t trust its answers any more than I trust rumors. My skepticism was justified. The ‘AI summary’ was taken nearly word for word from its source.

What if the blog post I was editing had been for external consumption? My employer might easily have committed inadvertent copyright infringement.

That wasn’t even the most concerning encounter I’ve had with AI recently. A few months earlier, I met with someone I had never worked with before. We spent a few minutes breaking the ice. We were hitting it off, so icebreaking went on a bit longer than I had intended. I don’t worry about that too much. You never know where you’re going to meet a new friend.

After the meeting I read the AI summary. To my horror, the AI summary, particularly the summary of the icebreaking, could be used to make false claims about either one of us to HR with no way to disprove those claims from the AI summary. What if some of those claims lead to legal consequences?

At the very least, it seems to me, AI summaries need to come with a disclaimer about their contents. So far, I haven’t seen one. I would also bet there’s no case law on AI summaries yet. Until there are disclaimers and case law on AI summaries, I’m choosing to say very little in meetings that use them.

Agents as Build Tools

In nearly every stage of my technical writing career, I’ve built some of my own tooling. Engineers have been aware of this, yet none of them has ever taken an interest, much less offered a suggestion. The DITA automation I built in Python for Zavers reduced a complicated command line to a title and a configuration file. Yet no engineer ever said to me, “Dude, there are these things called build systems. Stop rolling your own.” 

I know about build systems now. In fact, I know a lot more about engineering in general (as opposed to just coding) than I did when I was at Zavers. That made me wonder how I would approach my DITA stack now. 

The first thing that occurs to me is that an agent might take the place of the build tool (or at least parts of it). Allow me to explain. DITA takes a long sequence of command line flags to produce the proper output. I kept forgetting them. I kept typing them wrong. I wanted to simplify it so that all I needed to enter was a nickname for a particular reference or installation guide and the output format (html or pdf). I could have just put this information in a text file and used a command line incantation to concatenate it with the DITA compiler command, but I wanted logic around individual commands, and sometimes human decisions based on that logic. Hence, my Python code.

What if I could just ask an AI to do this for me? I need a language model that can turn human speech into bash command lines. In searching for a language model, I found an article that explains building an LLM-powered terminal assistant. More to come. Stay tuned.

Updating Information Architecture

Few technical writers have the opportunity to create an information architecture from scratch. Most of the time the job entails applying an IA to an existing document set. Even working for a startup years ago, I worked with content I inherited from engineers.  

Existing document sets have grown organically with content that may or may not have been written by good writers. This happens despite the skills and intentions of past writers. When creating an AI for such sets, most people’s first thought is to start moving existing content. This can be like rearranging the deck chairs on the Titanic.

Instead, begin with a list of what should be there, and create a structure that communicates about the content it contains. For example, I’ve seen content sorted by system that should have been organized chronologically. Such content has introductions analogous to, “Make sure you have built an airplane before attempting to fly.” Organizing this way forces the reader to construct what should be obvious from the table of contents. Frequently, the reader ends up with more open tabs than they can keep track of. Finally, make a list of what’s missing, what can be reused, and what needs to be replaced. Prioritize the list and begin writing.

The next trick is to maintain the IA through future updates. The process I’ve outlined is lengthy, so it would be best not to do this again. The primary tool for this is planning. Engineers like to throw new features over the wall late in the development process. They think they’re doing us a favor by keeping us from starting before functionality is locked down. There are multiple strategies for front-loading work so that writers have time to position new content carefully. One of the outcomes of my IA process is a master plan, which makes placement of new content easier. I also advocate (and practice) that writers become experts to the best of their abilities in the subjects they write about.  The best placement decisions are made when a well-informed writer works with an SME.

Overloaded Terms

Have you ever had to document a system where a component has the same name as a system? EnCorr has five components and one of them is named EnCorr. WonderWidget has three components and one of them is named WonderWidget. The documentation reads like an Abbott and Costello script. “Launch AWD.” “Which part of AWD?” “AWD.” “That’s what I’M ASKING!”

For years I struggled with a way to explain this problem to engineers and product managers who always want to keep product naming for themselves. Then I realized their world has a concept that exactly corresponds to this problem. It’s called overloading.

Overloading is when a programmer creates a variable, method, property, or class within the same name as another construct within the same context. (The engineering term is ‘scope’. That’s another post.) Overloading an identifier is considered a bad practice in computer programming. It’s why compilers and script interpreters warn against it. It’s why programming languages developed the concept of namespaces, which operate for computer code somewhat the way country and area codes operate for phone numbers. (Again, that’s another post.) 

To disambiguate the overloaded term the writer you’ll need to throw more words on the page. That just creates more opportunity for misunderstanding.

Search within Subdirectores

A command line incantation is a bash command that helps you do useful things. Bash is a command-line shell: a test-based user interface for interacting with an operating system. Bash commands work on Linux, mac, and Windows PowerShell. 

A previous post in this series showed the basics of using the grep command to search within files. That incantation had a serious limitation. It could only search within the current directory. As you know, most directories contain subdirectories. To search every subdirectory in addition to the current one, add the -r (recursion) flag. The following not only searches the subdirectories of the current directory. It searches in every subdirectory it finds. It does not follow shortcuts (‘symlinks’ in Linux terminology).

grep -r “find something” *

Where’s the Magic?

This adds much needed power to the basic grep command. Did the project lead change the name of a window or an interface last week? Hunting down every instance of a term can be a real pain. 

Additional Tricks

I know I’m repeating myself, but I provide here as additional tricks, the same flags offered in the previous incantation.

FlagDescription
-iMakes the search case insensitive.
-lOnly prints the name of the file where the match was found. This is the most like what you would get from a search box in a file explorer.
-nPrints the line number within a file where the match was found.
| moreStops the output when the screen is full. Pressing enter continues the output at your pace. This _must_ be placed at the end of the command because it’s technically a different set of commands. The vertical line is a pipe, not a letter ‘L’. It’s located on the same key as the back slash on North American keyboards.

Standards for Engineers

For the last year I’ve been on a contract job at a large company documenting internal processes on a wiki. The wiki is my employer’s choice, but it has become the bane of my existence because of the formatting freedom it gives to writers, most of whom are engineers by trade. Its contributors imitate the norms of technical writing, but they don’t really know how to do it. Every writer imitates it differently, sometimes badly. Learning all the rules of technical writing isn’t something an engineer is likely to do.

That has me pondering what should be in a minimal set of writing rules for engineers? This isn’t road tested. It’s just off the top of my head.

Look Around

Before committing anything to screen, look at the pages adjacent to where yours will be published and imitate their formatting. Look at the parent page and at the eventual siblings of your work. Over time content consistency manages expectations about content and will make it easier for readers to find information.

Write in Complete Sentences

I don’t know why I need to say this and I now have sympathy for all of the language teachers I had in school who sounded like a broken record.

A complete sentence is the complete expression of a thought. It avoids misinterpretation. In an age where many of your colleagues are likely to speak and read English as a second language, it gives such readers the best chance of understanding it.

Don’t Put Extra Formatting in Titles

The purpose of formatting in technical works requires a longer explanation than I can give here. One of its purposes is to make a document easy to scan so that a reader doesn’t need to read an entire page to find one item within. Generally, you only need one kind of formatting to make something scannable. Headings have three: they’re in bold type, in larger text and are generally set off with extra space.

Programming terms don’t need to also be in monospaced type. Yes, I know that’s inconsistent with what you do everywhere else. Get over it. Typical technical documentation already has a tendency to look like a ransom note from an old crime drama. This just cuts that down.

Don’t Put Links or Images in Titles

This is corollary to the previous guideline. The point of a link is to take your reader someplace else. A heading introduces text. You made it a heading to attract the reader’s attention. Instead of letting them read what you drew their attention to, you want to take them someplace else?

The images I’ve seen in titles are typically emojis. The Elements of Style has a rule to ‘omit needless words’. This means eliminating words that don’t add meaning to a sentence.

I have yet to see an emoji contribute meaning to a technical document. There’s no doubt that an emoji can add emotional nuance in a text to your best friend. You’re not texting your best friend. You’re writing about constructors or system architecture. Where’s the need for emotional nuance?

Take Screen Captures with Default settings

A picture is worth a thousand words, but not if it appears to show something other than what your text is describing. Readers are looking at your document because they don’t know how to do something. An illustration that looks different from their screen is potentially confusing and increases the cognitive load on someone who is already cognitively loaded.

Yes, the reader may have changed the settings in their installation. They’re a minority and have proven an above average level of comfort with technology merely by the fact that they’ve changed the settings. Write for the average reader.

Procedures

Here are a few guidelines for procedures.

  • Title the procedure with a gerund that describes what the procedure will accomplish. “Starting a car” is a good title. “How to start a car” is not. 
  • Always begin a step with a number.
  • A step is user action followed by the system’s response. The response never gets its own number.
  • Put interface elements in bold type and programming or command line elements in monospace type. 

Reference

Some places are claiming they’re using AI to document APIs. From what I’ve seen, they just write circumlocutions like “Use the Widget class to create and manage widgets.” Great! What’s a widget? 

  • Write an introduction that describes its intended use.
  • Begin definitions with a sentence fragment. This is a well established convention for definitions of any kind. If you don’t believe me, open your dictionary to any page and read any definition.
  • Use the same structure throughout.
  • DontInfoDumpTBD
  • Code examples should be short to illustrate characteristics of the API. Production code is often bad for this since it’s intention is to do work for humans not communicate information to humans.
  • Define all arguments and return values.
  • Don’t rely on the API’s source code.
  • Document all errors that it throws.