# The Bunker Build Log: 42 Problems Fixed and 30 Decisions Recorded

> From one question on October 7 to version 1.2.1 on October 25, 2026: the timeline, the four releases, where 42 problems came from, and 30 decisions at a glance.

Canonical: https://nosistech.com/bunker-build-log-problems-decisions/
Published: 2026-10-27
Last updated: 2026-10-27
Author: Carlos Paredes, NosisTech LLC

On October 7, 2026, Bunker started with one question: which of my addresses show their public key? On October 25, version 1.2.1 shipped.

In those 18 days, the tool grew from one HTML page with one large function to a public project. Today it knows more than 100 networks, blocks 19 kinds of secrets, works in English and Spanish, and passes 71 tests.

Every step left a written record. The repository holds 42 problem reports and 30 decision records. Each problem report records what a test or a check found, and the fix. Each decision record names the options that I did not choose, and why.

This article is the map of that record. It shows the timeline, the releases, where the problems came from, and the 30 decisions at a glance. The other articles of this series take each area apart in detail.

---

## Two kinds of record

The project keeps two kinds of written record. Each kind answers a different question:

| Record | Question it answers | Parts | Count |
| --- | --- | --- | --- |
| Decision record | Why does the tool work this way? | Context, options with points for and against, decision, reasons, consequences | 30 |
| Problem report | What did a test or a check find, and what stops it now? | The problem with an example, and the fix. Larger reports add the options, the reason and the test. | 42 |

A decision record also has a status: Accepted, Proposed or Replaced. A replaced record stays in the repository, so a reader can follow how a choice changed.

Some problem reports are short, because the fix is small. Here is P-15 in full:

> **From docs/06-problems-and-fixes.md, P-15:**
>
> **Problem.** The Stacks burn address `SP000000000000000000002Q6VF78` is 29 characters. The rule required at least 30.
>
> **Fix.** In c32, each leading zero byte is one `0` character, so addresses can be short. The rule now accepts 7 to 43 characters. The checksum does the real work.

Larger reports add a table of options, with the points for and against each one. The hosting section below shows three of them.

## The timeline in seven phases

The build story in [docs/05-how-it-was-built.md](https://github.com/nosistech/nosis-bunker/blob/main/docs/05-how-it-was-built.md) has seven phases. The table links each phase to its records:

| Phase | Date | What happened | Records |
| --- | --- | --- | --- |
| 1. The question | October 7 to 9 | No simple tool answered the question. The first decision: the tool runs only on the device of the user. | ADR-001 |
| 2. The first prototype | From October 9 | One HTML page with one large function, first published as "Bunker Check". It knew Bitcoin, EVM, Solana and 11 more networks. | ADR-002, ADR-007, ADR-008, ADR-010 |
| 3. Real wallets, real gaps | October 25 | A real wallet app showed formats that the tool did not know. The goal grew to every network that holds real value. | P-01 to P-04, ADR-003, ADR-009 |
| 4. Checking our own claims | October 25 | Explorer links were tested against real explorer pages. The Liquid and Zcash rules came from their reference sources. | P-06 to P-09, ADR-014 |
| 5. The repository | October 25 | The prototype became 17 detectors, a page built without HTML strings, a strict policy for scripts, and tests with real addresses. | P-18 to P-20, ADR-005, ADR-006 |
| 6. The website | October 25 | The tool got its public home, an embedded font, a prebuilt website folder and a Node.js version gate. | P-23 to P-26, ADR-024 to ADR-026 |
| 7. Languages, agents and a full review | October 25 | Spanish, a command-line tool, an MCP server, accessibility work, and a review with four separate reviewers. | P-27 to P-42, ADR-027 to ADR-030 |

Seven of the 30 decisions date from October 9. The other 23 date from October 25. The build story calls the first decision the most important one. Many later records point back to it, for example ADR-008, ADR-009 and ADR-029.

## Four releases on October 25

The [changelog](https://github.com/nosistech/nosis-bunker/blob/main/CHANGELOG.md) lists four versions, all dated October 25, 2026. Each version has one theme:

| Version | Theme | Main contents |
| --- | --- | --- |
| 1.0.0 | The first release of the repository | 17 detectors, a guard for 16 kinds of secrets, 57 real test addresses, 23 decision records, and fixes P-01 to P-22 |
| 1.1.0 | A new page design for bunker.nosistech.com | A result sentence with a meter, one embedded font, a website folder with security headers, and a Node.js version gate |
| 1.2.0 | A new name, Bunker by NosisTech | English and Spanish, a light and dark switch, a CLI and an MCP server, a WCAG 2.2 AA target, and fixes P-27 to P-32 |
| 1.2.1 | A full review pass | Four separate reviewers, ten findings from P-33 to P-42, and a guard for 19 kinds of secrets |

The numbers show the growth. The guard went from 16 to 19 kinds of secrets. The decision records went from 23 to 30. The problem reports went from 22 to 42.

The repository became public on the same day, under the Apache License 2.0. On October 27, 2026, I ran the full check again from a fresh copy of the code. All 68 tests passed. The new build had the same SHA-256 hash as the page on the live site.

## Where the problems came from

Many problem reports also record how the problem was found. Most of these sources are checks that any project can copy:

| Source | Problems | Example |
| --- | --- | --- |
| A real wallet app | P-01, P-02 | A user pasted a Stacks address from a wallet app. The tool said "Not recognized". |
| A question from a user | P-14 | A user asked about QNT. Many people paste the QNT token contract instead of a wallet address. |
| A search of real explorer pages | P-08 | All indexed Mintscan account pages used `/account/`, not `/address/`. |
| The typo test | P-19, P-20 | The XRP genesis account with a typo still showed as valid. |
| The translation test | P-28 | A pattern took the wrong "and", so half of the text stayed in English. |
| A security release of Node.js | P-23, P-24 | The flaw CVE-2026-111497 in the Brotli decoder, fixed on October 21, 2026. |
| A check of the live site | P-31, P-32 | The download header was lost after a redirect on the live host. |
| The review pass of 1.2.1 | P-33 to P-42 | A Bech32 address with one typo could pass as a Solana address. |

The typo test deserves a closer look. It changes one character of each real address and expects a failure. It found P-19 first. After the fix for P-19, the same test found P-20. Article 5 of this series explains both.

## The 42 problems by area

I grouped the 42 reports of version 1.2.1 by the part of the tool that they touch. The last column shows where this series covers each group:

| Area | Count | Reports | Covered in |
| --- | --- | --- | --- |
| Network formats and checksums | 16 | P-01 to P-03, P-06, P-07, P-10, P-11, P-13 to P-17, P-19, P-20, P-37, P-41 | Articles 3, 5 and 9 |
| The secret guard | 6 | P-04, P-05, P-33, P-34, P-38, P-42 | Article 6 |
| Accessibility, design and Spanish | 5 | P-25, P-27 to P-30 | Article 11 |
| Agent interfaces and labels | 4 | P-35, P-36, P-39, P-40 | Article 10 |
| Build tools and supply chain | 3 | P-21, P-23, P-24 | Article 8 |
| Hosting | 3 | P-26, P-31, P-32 | This article |
| Page security | 2 | P-12, P-18 | Article 7 |
| Explorer links | 2 | P-08, P-09 | Article 9 |
| Documentation | 1 | P-22 | The problem log, P-22 |

Network formats lead the count with 16 reports. That fits the scope of the tool. It knows more than 100 networks, with many formats, prefixes and checksums.

## The review pass of version 1.2.1

Version 1.2.1 came from one review pass. Four separate reviewers each took one area: network rules, security, Spanish and documentation. Each reviewer worked from the sources, as the problem log says:

> **From docs/06-problems-and-fixes.md:**
>
> Each got the code and the specifications, not our conclusions, so the review did not grade our own work.

The review produced ten findings, from P-33 to P-42. Each finding has a severity:

| Severity | Count | Findings |
| --- | --- | --- |
| Critical | 1 | P-37: a Bech32 address with a typo could pass as a Solana address. |
| High | 3 | P-33, P-34 and P-42: seed phrases and key formats that passed the guard |
| Medium | 5 | P-35, P-38, P-39, P-40 and P-41: protocol versions, false alarms, report text, buffer size and encodings |
| Low | 1 | P-36: invisible direction marks in labels |

All ten are fixed, and each fix has a test. The critical finding shows why order matters in a pipeline. The Bech32 detector rejected the typo, as it should. Then a later detector saw 43 Base58 characters and called the text a Solana account. The fix stops the pipeline for any text with the shape of a Bech32 address and a wrong checksum. Article 5 covers it in detail.

## Three hosting lessons

The page itself is one static file. Even so, three problems came from the way a host delivers that file. Each one is a lesson for any static site.

### P-26: a host can change the page

Some hosts and CDNs change HTML on the way to the user. They minify scripts, add analytics or rewrite email addresses. The page allows only scripts with an exact SHA-256 hash. A changed script does not match its hash, so the browser blocks it, and the page stops working.

| Option | For | Against |
| --- | --- | --- |
| Allow `unsafe-inline` scripts | Never breaks | Removes the main protection against injected scripts |
| Send `Cache-Control: no-transform`, and list the host features to turn off (chosen) | Keeps the strict policy | One manual check for each host |

On Cloudflare, the checklist turns off Rocket Loader, Email Address Obfuscation, the automatic setup of Web Analytics, and Zaraz. The report states the principle in one line:

> **From docs/06-problems-and-fixes.md, P-26:**
>
> A broken page is safer than a page that runs changed code.

### P-31: a redirect lost the download header

The file `nosis-bunker.html` must download, not open, so that people can keep an offline copy. Cloudflare Pages sends `/nosis-bunker.html` to `/nosis-bunker` with a 308 redirect. The download rule covered only the first path, so the browser opened the file. A check of the live site after the first deploy found this.

### P-32: a cache rule for the whole zone served the old page

After the 1.2.0 deploy, the hosting preview showed the new page. But `bunker.nosistech.com` still served the old one from the edge cache, 44 minutes old. The cause was a cache rule for HTML pages in the nosistech.com zone. That rule matched every hostname in the zone, the Bunker site included.

| Option | For | Against |
| --- | --- | --- |
| Purge the cache after each release | No rule change | A manual step that is easy to forget. Users see old security text until then. |
| Change the existing rule | One rule | Changes the behavior for the whole zone |
| Add a bypass rule for the Bunker hostname, placed last, and send `Cache-Control: no-cache` (chosen) | Each release is live at once, and the rest of the zone does not change | One more rule in the zone |

The header part of each fix is in one file, [site/_headers](https://github.com/nosistech/nosis-bunker/blob/main/site/_headers). Cloudflare Pages reads this file and sends its lines as HTTP headers. Here is the end of the file:

```
  Cache-Control: no-cache, no-transform
  ! Access-Control-Allow-Origin

/nosis-bunker.html
  Content-Disposition: attachment; filename="nosis-bunker.html"

/nosis-bunker
  Content-Disposition: attachment; filename="nosis-bunker.html"
```

1. `no-cache` tells every cache to check for a new copy before it serves the page. This is the P-32 fix, together with the bypass rule.
2. `no-transform` asks every host and proxy on the way not to change the page. This is the P-26 fix.
3. The line that starts with `!` removes a header that Cloudflare Pages adds by default. With that header, scripts on any other site could read the page.
4. The two path blocks give the same download header to both addresses. This is the P-31 fix.

The script `tools/site.js` writes this file, and the file is not edited by hand. I checked the live site on October 27, 2026. Here are the relevant header lines from three requests:

```
$ curl -sI https://bunker.nosistech.com/
Cache-Control: no-cache, no-transform
cf-cache-status: DYNAMIC

$ curl -sI https://bunker.nosistech.com/nosis-bunker.html
HTTP/1.1 308 Permanent Redirect
Location: /nosis-bunker
Content-Disposition: attachment; filename="nosis-bunker.html"

$ curl -sI https://bunker.nosistech.com/nosis-bunker
HTTP/1.1 200 OK
Content-Disposition: attachment; filename="nosis-bunker.html"
```

The status `DYNAMIC` shows that the edge did not serve a stored copy. Both download paths carry the download header, before and after the redirect.

## Update: version 1.2.2 (October 27)

Two days after 1.2.1, a documentation review compared the docs, the decision records and the tests with the code, one claim at a time. It found three gaps in the code and one gap in a test. Each one is now a problem report with a fix and a test:

| Report | Problem | Fix |
| --- | --- | --- |
| P-43 | Litecoin advice named a Bitcoin address type (`bc1q`) and a Bitcoin proposal (BIP-360). | Litecoin advice names `ltc1q`. |
| P-44 | Starknet was offered for values above 2251. | The value is checked in both address forms. |
| P-45 | The plan asked two of the three provider questions of ADR-012. | The plan asks all three. |
| P-46 | The P-37 test used a typo that could not reach the Solana rule. | A real case with the Solana shape. |

The tests for P-43, P-44 and P-45 fail on the old code and pass on the new code. For P-46, I removed the P-37 rule in a copy of the code. The typo then showed as a Solana account, and the test failed. All 71 tests pass on version 1.2.2. The record now holds 46 problems.

## The 30 decisions at a glance

This table comes from the build story. Each row has a full record in [docs/decisions/](https://github.com/nosistech/nosis-bunker/blob/main/docs/decisions/README.md):

| # | Decision | Chosen | Main alternatives |
| --- | --- | --- | --- |
| 001 | Where the tool runs | User's device only | Server API; browser calls to public APIs |
| 002 | Language | JavaScript | TypeScript; Rust to WebAssembly; Python or Go |
| 003 | Libraries | None; own checksum code | npm crypto libraries; WebCrypto |
| 004 | Delivery | One HTML file | Website with many files; browser extension; mobile app |
| 005 | Build | Own script, about 190 lines | esbuild or Rollup; ES modules in the browser |
| 006 | Code structure | Ordered detector pipeline | One large function; table of regular expressions |
| 007 | Result model | Named categories | Yes or no; score from 0 to 100 |
| 008 | "Has it sent?" | Ask the user | Blockchain lookup; xpub scan |
| 009 | Typos | Verify every checksum | Shape only; external service |
| 010 | Secrets | Block and clear | Warn only; no guard |
| 011 | Shared formats | User picks the network | Guess; reject |
| 012 | Permissioned networks | Questions for the provider | Rate as visible; ignore |
| 013 | Zcash shielded | Rate by pool | No rating; rate by address |
| 014 | Explorer links | Verified only, checked weekly | Best guess; no links; one explorer for all |
| 015 | Fonts | System fonts (replaced by 024) | Google Fonts; embedded font files |
| 016 | Script policy | CSP with hashes and Trusted Types | No CSP; CSP with `unsafe-inline` |
| 017 | 64-bit math | BigInt | 32-bit pairs; WebAssembly |
| 018 | Tests | `node:test` with real addresses | Jest or Vitest; manual tests |
| 019 | Page building | DOM methods and `textContent` | `innerHTML` with escaping; a framework |
| 020 | Page design | Cards, plain labels, example data on first open | Table; empty first page |
| 021 | Writing | Strict house writing rules | Normal English; two languages |
| 022 | Token contracts | Short curated list | No list; full token list |
| 023 | Continuous integration | No third-party actions | Popular marketplace actions |
| 024 | Fonts, second version | One subset variable font in a data URL | System fonts; a font service; several files |
| 025 | Website | Commit a prebuilt `site/` folder | Build on the host; deploy from CI with a token |
| 026 | Node.js version | Gate script, exact pin and hash check in CI | Any version; `engines` only; `setup-node` action |
| 027 | Agent access | Local CLI and MCP server; llms.txt; no web API | Remote API or remote MCP; browser automation only |
| 028 | Languages | English engine, Spanish dictionary in the page | English only; two pages; message keys |
| 029 | Saved preferences | None; system settings and `#es` | localStorage; cookies |
| 030 | Accessibility | WCAG 2.2 AA with tests and a statement | No target; overlay widget; WCAG 2.1 only |

Only one record has the status Replaced. ADR-015 chose system fonts, after P-12 showed that a web font request reached Google on every visit. When the page moved to a public website, ADR-024 replaced it with one embedded open-license font. The new choice still makes no request, so the privacy promise stays true.

## Three rules behind the decisions

Read the 30 rows together, and three rules appear many times:

| Rule | Examples |
| --- | --- |
| Nothing leaves the device. | ADR-001 (device only), ADR-008 (ask the user), ADR-016 (all connections blocked), ADR-027 (no web API), ADR-029 (store nothing) |
| No outside code enters the page or the build. | ADR-003 (no libraries), ADR-005 (own build script), ADR-019 (no framework), ADR-023 (no third-party actions), ADR-026 (pinned Node.js) |
| Every claim has a check. | ADR-009 (every checksum), ADR-014 (verified links), ADR-018 (real addresses), ADR-030 (accessibility tests) |

The rules also explain the trade-offs. ADR-008 costs the user one click for each address. ADR-003 costs the project the work of writing and testing its own checksum code. In each case, the record names the cost and accepts it.

## What the record gives each reader

A written record is useful only if a reader can act on it. The Bunker record serves three kinds of reader:

| Reader | What the reader needs | Where to find it |
| --- | --- | --- |
| A user | Proof that the file is the real file | The published SHA-256 hash and the reproducible build |
| An auditor | The reason for each control, and its test | The OWASP mapping, the threat model and the 30 decision records |
| A contributor | A safe way to add a network | Seven steps in docs/04-architecture.md, from the official format to a test and a docs update |

The contributor steps follow the same rules as the decisions. Step 2 asks for a real address from an official test vector or a public explorer page. Step 4 allows an explorer link only if the contributor can verify it. Step 5 adds the address to the test fixtures with its source.

## Read the full record

- The build story: [docs/05-how-it-was-built.md](https://github.com/nosistech/nosis-bunker/blob/main/docs/05-how-it-was-built.md)
- All 42 problem reports: [docs/06-problems-and-fixes.md](https://github.com/nosistech/nosis-bunker/blob/main/docs/06-problems-and-fixes.md)
- All 30 decision records: [docs/decisions/](https://github.com/nosistech/nosis-bunker/blob/main/docs/decisions/README.md)
- The releases: [CHANGELOG.md](https://github.com/nosistech/nosis-bunker/blob/main/CHANGELOG.md)
- The hosting guide: [docs/security/hosting.md](https://github.com/nosistech/nosis-bunker/blob/main/docs/security/hosting.md)
- The tool: [bunker.nosistech.com](https://bunker.nosistech.com)

This article closes the Bunker series. To start from the beginning, read [Which of Your Crypto Addresses Show Their Public Key? Bunker Answers in 30 Seconds](https://nosistech.com/bunker-crypto-address-public-key-scanner/).

Have a question or feedback about Bunker? [Contact NosisTech](https://nosistech.com/connect/).

### Keep reading: Bunker by NosisTech

Previous article: [Designing Bunker for Phones, Screen Readers and Two Languages](https://nosistech.com/bunker-ux-accessibility-wcag-spanish/)

All articles: [NosisTech Writing](https://nosistech.com/blog/)

*This post is general information, not financial, legal or security advice. Bunker is an educational tool with no warranty. Examine each address on a block explorer, and send a small test amount before you move funds.*
