Doc SoC
Doc SoC Researcher (software architecture and service-oriented computing).

ADG: A Light Architectural Decision Guidance and Management Tool

(Updated: )
Reading time: 8 minutes
ADG: A Light Architectural Decision Guidance and Management Tool

ADG is a novel command-line tool for managing recurring architectural decisions. This blog post takes you through its core features. Two decisions regarding Enterprise Integration Patterns (EIP) and their realization serve as examples.

Overview and Background

ADG became available as a public GitHub repository last week. It has been developed in two master-level term thesis projects at OST, the Eastern Switzerland University of Applied Sciences. The project README positions the tool as this:

ADG (Architectural Decision Guidance) is a command-line tool written in Go for modeling, managing, and reusing architectural decisions in a lightweight and structured way.”

Why capture Architectural Decisions (ADs) anyway? To preserve design rationale.1 AD management supports Collaboration, Accountability, Learning and Management use cases, keeping you CALM.

Like other tools, ADG allows IT architects to record their ADs as Architecture Decision Records (ADRs). ADG can also support the decision making process:

“ADG allows you to create and edit ADRs, group them into models, and manage those models. A model can be created, copied, imported, or merged, providing guidance for recurring decisions.”

18 commands are available; adg --help lists them. Let’s go through the full lifecycle of an AD model and its two ADRs in this post. Two pattern categories from EIP will provide examples of recurring ADs: selecting an integration style such as messaging and deciding on a messaging channel type such as publish-subscribe.

Model Initialization

You can either work with one of the executables available for download in Release 1.0.0 or go and build one yourself (see instructions in README). 23

adg init initializes a new model:

1
adg init "EIP"

If the tool responds with “Successfully created model directory: EIP”, that’s a good sign. You might want to have a look inside the directory; a file called index.yaml should be present in it.

Tips: adg init --help and adg init -h explain the arguments and options, aka flags, of this command; the same instant help is available for all commands. The model name serves as the directory name; life gets easier if you avoid blanks in it. Use CamelCase names, a hyphen - or an underscore _ instead.

Identifying a Decision Required

Next up is decision creation, adding an AD to an existing model (EIP in our case):

1
adg add --model EIP --title "IntegrationStyle"

Expect a “Decision IntegrationStyle (0001) added successfully.” message. An ADR waiting to be populated now exists in a file called AD0001-integrationstyle.md. Can you find and display it, for instance in the Markdown editor of your choice?

Tip: ADG puts all added ADs in the root directory/folder of the model. To organize your decision model hierarchically, you can move them to subfolders manually; ADG will still be able to locate them.

It is time to add some content to the ADR (note that I added line breaks for clarity; if you copy-paste, make sure to copy into a single line or use the multi-line capability supported by your operating system and shell):

1
2
3
4
5
6
7
adg edit --model EIP --id 0001 
  --question "How should programs exchange information with each other?"
  --option "File Transfer" 
  --option "Shared Database" 
  --option "RPI" 
  --option "Messaging"
  --criteria "See <https://www.enterpriseintegrationpatterns.com/patterns/messaging/IntegrationStylesIntro.html>"

ADG responds with “Decision 0001 updated successfully.” to this command. The ADR now looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
---
adr_id: "0001"
title: IntegrationStyle
status: open
tags: []
links:
    precedes: []
    succeeds: []
comments: []
---

## <a name="question"></a> Question

How should programs exchange information with each other?

## <a name="options"></a> Options

1. <a name="option-1"></a> File Transfer
2. <a name="option-2"></a> Shared Database
3. <a name="option-3"></a> RPI
4. <a name="option-4"></a> Messaging

## <a name="criteria"></a> Criteria

See <https://www.enterpriseintegrationpatterns.com/patterns/messaging/IntegrationStylesIntro.html>

Take a look at the metadata and the sections identified by <a name="..."></a> anchors. The section heading names can be customized; a Nygardian ADR setup and a basic MADR configuration are available (as values of the --template flag).

Tip: You can also identify an AD by its title: adg edit --model EIP --title IntegrationStyle. If you get tired specifying the model as a flag, you may want to set a default model with adg set-config. And yes, the file can be edited manually!

Recording a Decision Made

The added and edited AD is ready to be decided:

1
adg decide --model EIP --id 0001 --option 4 --rationale "Loose coupling in time dimension required and throttling behavior of messaging channels appreciated."

“Decision 0001 has been marked as decided.” is the message reporting that the command succeeded.

Tip: Decision name and option name also work as values of the --id and --option flags, respectively.

Let’ have a look:

1
adg view --model EIP --id 0001

The view command output should look as this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
===== Decision 0001 =====

Question
How should programs exchange information with each other?

Options
1. <a name="option-1"></a> File Transfer
2. <a name="option-2"></a> Shared Database
3. <a name="option-3"></a> RPI
4. <a name="option-4"></a> Messaging

Criteria
See <https://www.enterpriseintegrationpatterns.com/patterns/messaging/IntegrationStylesIntro.html>

Outcome
We decided for [Option 4](#option-4) because: Loose coupling in time dimension required and throttling behavior of messaging channels appreciated.

Comments
<a name="comment-1"></a>1. (2025-07-17 23:59:00) : marked decision as decided

Note the comment keeping track of the state change, a pivotal event in the AD lifecycle.

Tip: An --author name can be configured or given as a flag to adg decide optionally.

Try to decide again, executing the same command. The tool checks the AD status in the metadata and rejects this invalid request.

Tip: On a real project, you might want to establish a definition of done such as ecADR for AD making. The D in ecADR stands for existence of AD documentation, by the way; the other four “done” criteria evidence, criteria, agreement, realization/review can be captured in the documentation ADR.

Tagging, Linking, Commenting, Revising

Tags group and categorize ADs, which is useful when listing them, when filtering models and so on:

1
adg tag --model EIP --id IntegrationStyle --tag "Messaging"

Note that we identified the AD by its title this time, still using the --id flag (the numeric id would have worked too, as we saw earlier). The specified “Messaging” tag becomes part of the metadata in the YAML header at the top of the AD file; this metadata is cached in the index.yaml file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
---
adr_id: "0001"
comments:
    - author: ""
      comment: "1"
      date: "2025-07-14 16:51:40"
links:
    precedes: []
    succeeds: []
status: decided
tags:
    - Messaging
title: IntegrationStyle
---

People can react with comments, which are appended at the end of the file:

1
adg comment --model EIP --id 0001 --author "Archie Tagged" --text "I disagree with the rationale, the criteria evaluation is not convincing enough."

You cannot decide an AD in status “decided” again, as we saw earlier. But you can revise it:

1
adg revise --model EIP --id IntegrationStyle 

“Successfully revised decision 0001 → new decision 0003” is the tool output this time. This command creates a new open AD. Note its unique id and the link to the revised AD in the metadata.

Links can also be created explicitly. To demonstrate that capability, we first add a second AD and then connect it to the already existing one:

1
2
adg add --model EIP --title "ChannelType" 
adg link --model EIP --from IntegrationStyle --to ChannelType

You should see the messages “Link added: 0001 →[precedes]→ 0002” and “Reverse link added: 0002 →[succeeds]→ 0001”. The metadata in the two AD files as well as in index.yaml have been updated accordingly.

The link names can be specified explicitly too. The ADG help explains how: adg link -h.

Tip: You can add content to AD 0002 manually, as long as the metadata and the section anchors remain valid. For instance, the ChannelType decision has two options Point-to-Point Channel and Publish-Subscribe Channel according to the EIP website and book. Hohpe and Woolf discuss many pattern selection criteria as well.

Finally, let’s get an overview of what we have, rendered as a JSON object (YAML, Markdown and a simple default format are available as well):

1
adg list --model EIP --format JSON

Tips: adg validate checks the model consistency (e.g., index vs. file content, AD identifiers, link structure, presence of anchors). You can rebuild the index at any time with adg rebuild.

Outlook: ADs do not have to reside on a conceptual or pattern level; they go all the way down to implementation (DevOps).4 Hence, selecting an implementation technology for our channel would be up next.

You may want to create a linked ADR for this decision now. Feel free to clone the EIP model created in the above steps with adg copy and then adg add this third AD to it!

Discussion (Pros and Cons)

ADG takes a best-of-both-worlds (modeling, plain text files) approach to tool design:

  • Markdown files serve as AD repositories. These files can be processed with other tools such as the Markdown to HTML renderers for instance at GitHub, Pandoc. And you can edit them with the Markdown or plain text tool of your choice (e.g., a Visual Studio Code extension).
  • Collaboration workflows and accountability come for free when the Markdown files and the model directory/folder that contains and indexes them are version-controlled with git.
  • The structured metadata headers and the hidden anchor tags allow ADG to identify ADs uniquely, to define and check links between ADs and to ensure that a chosen option exists (the -f flag forces the decision for a new option). Treating the status as a metadata element makes it possible to prevent certain state transitions.

More benefits of text-based AD capturing are listed under “Why ADRs and Why Markdown?” in “The Markdown ADR (MADR) Template Explained and Distilled”.

ADG makes some assumptions about the file and folder content:

  • Sections/headings recording questions, options, criteria sections have to be present. Anchors for them must exist (example: <a name="options"></a>). The adg add command creates these and other anchors, and the adg edit and adg decide look for them. These empty/hidden anchors must not be changed but their visible names can be configured. adg set-config -h tells you how.
  • Copying an existing AD works as long as its id is unique, and the file name meets the conventions enforced and expected by ADG.
  • Decision status management is quite primitive deliberately. Only the transition from open to decided and from decided to back to open (after revise) is actually enforced. Hence, a decided decision cannot be decided again but revised; an open decision can be revised too at present.

“Knob-less” usage (i.e., direct file editing) is possible. And ADG is compatible with the MADR 4.0 templates, with some change cases for future versions already identified.

Summary and Outlook

We used ten (out of 18) ADG commands to create a small EIP guidance model, made and recorded two ADs.5 An ADG Users Guide provides more information. An example model with 15 ADs recurring when employing “Clean Architecture” rings is available too.

ADG was designed and implemented by phi42 (a.k.a. Raphael Schellander) 🙏. Background information can be found in his thesis reports:

In the second thesis, you find a second usage example (workflow), tool design details as well as a validation experiment (PDF).

Feedback and contributions are welcome! ADG tool development is scheduled to resume in the fall term. Issues in the GitHub repository are a good way to communicate ideas and change requests.

– Olaf (a.k.a. socadk)

PS: Find all my blog posts on ADR(s) via their architectural decision tag.

Notes

  1. The post “Architectural Decisions — The Making Of” answers the question in more depth. Have you encountered provocative questions like those in the motivating story that opens the post? 

  2. Operating System (OS) and shell must be able to locate the executable; depending on the OS and shell that you use and how you have set it up, you might have to provide an absolute path, a relative path or set an environment variable accordingly. 

  3. Moreover, you need the right to execute the command. 

  4. This is the “engine room” in the IT Architect Elevator metaphor. 

  5. Note that I did not feature the model copying, merging, importing capabilities in this post that allow architects to create and reuse guidance models rather than keeping mere decision logs.